plectrum

Plectrum: instrument tuner for Android
Log | Files | Refs | README | LICENSE

PolynomialInterpolation.java (4871B)


      1 package be.tarsos.dsp.wavelet.lift;
      2 
      3 /**
      4 * 
      5 * @author Ian Kaplan
      6 */
      7 class PolynomialInterpolation {
      8 	/** number of polynomial interpolation ponts */
      9 	private final static int numPts = 4;
     10 
     11 	/** Table for 4-point interpolation coefficients */
     12 	private float fourPointTable[][];
     13 
     14 	/** Table for 2-point interpolation coefficients */
     15 	private float twoPointTable[][];
     16 
     17 	/**
     18 	 * <p>
     19 	 * The polynomial interpolation algorithm assumes that the known points are
     20 	 * located at x-coordinates 0, 1,.. N-1. An interpolated point is calculated
     21 	 * at <b><i>x</i></b>, using N coefficients. The polynomial coefficients for
     22 	 * the point <b><i>x</i></b> can be calculated staticly, using the Lagrange
     23 	 * method.
     24 	 * </p>
     25 	 * 
     26 	 * @param x
     27 	 *            the x-coordinate of the interpolated point
     28 	 * @param N
     29 	 *            the number of polynomial points.
     30 	 * @param c
     31 	 *            an array for returning the coefficients
     32 	 */
     33 	private void lagrange(float x, int N, float c[]) {
     34 		float num, denom;
     35 
     36 		for (int i = 0; i < N; i++) {
     37 			num = 1;
     38 			denom = 1;
     39 			for (int k = 0; k < N; k++) {
     40 				if (i != k) {
     41 					num = num * (x - k);
     42 					denom = denom * (i - k);
     43 				}
     44 			} // for k
     45 			c[i] = num / denom;
     46 		} // for i
     47 	} // lagrange
     48 
     49 	/**
     50 	 * <p>
     51 	 * For a given N-point polynomial interpolation, fill the coefficient table,
     52 	 * for points 0.5 ... (N-0.5).
     53 	 * </p>
     54 	 */
     55 	private void fillTable(int N, float table[][]) {
     56 		float x;
     57 		float n = N;
     58 		int i = 0;
     59 
     60 		for (x = 0.5f; x < n; x = x + 1.0f) {
     61 			lagrange(x, N, table[i]);
     62 			i++;
     63 		}
     64 	} // fillTable
     65 
     66 	/**
     67 	 * <p>
     68 	 * PolynomialWavelets constructor
     69 	 * </p>
     70 	 * <p>
     71 	 * Build the 4-point and 2-point polynomial coefficient tables.
     72 	 * </p>
     73 	 */
     74 	public PolynomialInterpolation() {
     75 
     76 		// Fill in the 4-point polynomial interplation table
     77 		// for the points 0.5, 1.5, 2.5, 3.5
     78 		fourPointTable = new float[numPts][numPts];
     79 
     80 		fillTable(numPts, fourPointTable);
     81 
     82 		// Fill in the 2-point polynomial interpolation table
     83 		// for 0.5 and 1.5
     84 		twoPointTable = new float[2][2];
     85 
     86 		fillTable(2, twoPointTable);
     87 	} // PolynomialWavelets constructor
     88 
     89 	/**
     90 	 * Print an N x N table polynomial coefficient table
     91 	 */
     92 	private void printTable(float table[][], int N) {
     93 		System.out.println(N + "-point interpolation table:");
     94 		double x = 0.5;
     95 		for (int i = 0; i < N; i++) {
     96 			System.out.print(x + ": ");
     97 			for (int j = 0; j < N; j++) {
     98 				System.out.print(table[i][j]);
     99 				if (j < N - 1)
    100 					System.out.print(", ");
    101 			}
    102 			System.out.println();
    103 			x = x + 1.0;
    104 		}
    105 	}
    106 
    107 	/**
    108 	 * Print the 4-point and 2-point polynomial coefficient tables.
    109 	 */
    110 	public void printTables() {
    111 		printTable(fourPointTable, numPts);
    112 		printTable(twoPointTable, 2);
    113 	} // printTables
    114 
    115 	/**
    116 	 * <p>
    117 	 * For the polynomial interpolation point x-coordinate <b><i>x</i></b>,
    118 	 * return the associated polynomial interpolation coefficients.
    119 	 * </p>
    120 	 * 
    121 	 * @param x
    122 	 *            the x-coordinate for the interpolated pont
    123 	 * @param n
    124 	 *            the number of polynomial interpolation points
    125 	 * @param c
    126 	 *            an array to return the polynomial coefficients
    127 	 */
    128 	private void getCoef(float x, int n, float c[]) {
    129 		float table[][] = null;
    130 
    131 		int j = (int) x;
    132 		if (j < 0 || j >= n) {
    133 			System.out.println("PolynomialWavelets::getCoef: n = " + n
    134 					+ ", bad x value");
    135 		}
    136 
    137 		if (n == numPts) {
    138 			table = fourPointTable;
    139 		} else if (n == 2) {
    140 			table = twoPointTable;
    141 			c[2] = 0.0f;
    142 			c[3] = 0.0f;
    143 		} else {
    144 			System.out.println("PolynomialWavelets::getCoef: bad value for N");
    145 		}
    146 
    147 		if (table != null) {
    148 			for (int i = 0; i < n; i++) {
    149 				c[i] = table[j][i];
    150 			}
    151 		}
    152 	} // getCoef
    153 
    154 	/**
    155 	 * <p>
    156 	 * Given four points at the x,y coordinates {0,d<sub>0</sub>},
    157 	 * {1,d<sub>1</sub>}, {2,d<sub>2</sub>}, {3,d<sub>3</sub>} return the
    158 	 * y-coordinate value for the polynomial interpolated point at
    159 	 * <b><i>x</i></b>.
    160 	 * </p>
    161 	 * 
    162 	 * @param x
    163 	 *            the x-coordinate for the point to be interpolated
    164 	 * @param N
    165 	 *            the number of interpolation points
    166 	 * @param d
    167 	 *            an array containing the y-coordinate values for the known
    168 	 *            points (which are located at x-coordinates 0..N-1).
    169 	 * @return the y-coordinate value for the polynomial interpolated point at
    170 	 *         <b><i>x</i></b>.
    171 	 */
    172 	public float interpPoint(float x, int N, float d[]) {
    173 		float c[] = new float[numPts];
    174 		float point = 0;
    175 
    176 		int n = numPts;
    177 		if (N < numPts)
    178 			n = N;
    179 
    180 		getCoef(x, n, c);
    181 
    182 		if (n == numPts) {
    183 			point = c[0] * d[0] + c[1] * d[1] + c[2] * d[2] + c[3] * d[3];
    184 		} else if (n == 2) {
    185 			point = c[0] * d[0] + c[1] * d[1];
    186 		}
    187 
    188 		return point;
    189 	} // interpPoint
    190 
    191 } // PolynomialInterpolation