plectrum

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

HaarWithPolynomialInterpolationWavelet.java (7096B)


      1 package be.tarsos.dsp.wavelet.lift;
      2 
      3 /**
      4  * <p>
      5  * HaarWavelet transform extended with a polynomial interpolation step
      6  * </p>
      7  * <p>
      8  * This wavelet transform extends the HaarWavelet transform with a polynomial
      9  * wavelet function.
     10  * </p>
     11  * <p>
     12  * The polynomial wavelet uses 4-point polynomial interpolation to "predict" an
     13  * odd point from four even point values.
     14  * </p>
     15  * <p>
     16  * This class extends the HaarWavelet transform with an interpolation stage
     17  * which follows the predict and update stages of the HaarWavelet transform. The
     18  * predict value is calculated from the even points, which in this case are the
     19  * smoothed values calculated by the scaling function (e.g., the averages of the
     20  * even and odd values).
     21  * </p>
     22  * 
     23  * <p>
     24  * The predict value is subtracted from the current odd value, which is the
     25  * result of the HaarWavelet wavelet function (e.g., the difference between the
     26  * odd value and the even value). This tends to result in large odd values after
     27  * the interpolation stage, which is a weakness in this algorithm.
     28  * </p>
     29  * 
     30  * <p>
     31  * This algorithm was suggested by Wim Sweldens' tutorial <i>Building Your Own
     32  * Wavelets at Home</i>.
     33  * </p>
     34  * 
     35  * </p>
     36  * 
     37  * <pre>
     38  *   <a href="http://www.bearcave.com/misl/misl_tech/wavelets/lifting/index.html">
     39  *   http://www.bearcave.com/misl/misl_tech/wavelets/lifting/index.html</a>
     40  * </pre>
     41  * 
     42  * <h4>
     43  * Copyright and Use</h4>
     44  * 
     45  * <p>
     46  * You may use this source code without limitation and without fee as long as
     47  * you include:
     48  * </p>
     49  * <blockquote> This software was written and is copyrighted by Ian Kaplan, Bear
     50  * Products International, www.bearcave.com, 2001. </blockquote>
     51  * <p>
     52  * This software is provided "as is", without any warrenty or claim as to its
     53  * usefulness. Anyone who uses this source code uses it at their own risk. Nor
     54  * is any support provided by Ian Kaplan and Bear Products International.
     55  * <p>
     56  * Please send any bug fixes or suggested source changes to:
     57  * 
     58  * <pre>
     59  *      iank@bearcave.com
     60  * </pre>
     61  * 
     62  * @author Ian Kaplan
     63  */
     64 public class HaarWithPolynomialInterpolationWavelet extends HaarWavelet {
     65 	final static int numPts = 4;
     66 	private PolynomialInterpolation fourPt;
     67 
     68 	/**
     69 	 * HaarWithPolynomialInterpolationWavelet class constructor
     70 	 */
     71 	public HaarWithPolynomialInterpolationWavelet() {
     72 		fourPt = new PolynomialInterpolation();
     73 	}
     74 
     75 	/**
     76 	 * <p>
     77 	 * Copy four points or <i>N</i> (which ever is less) data points from
     78 	 * <i>vec</i> into <i>d</i> These points are the "known" points used in the
     79 	 * polynomial interpolation.
     80 	 * </p>
     81 	 * 
     82 	 * @param vec
     83 	 *            the input data set on which the wavelet is calculated
     84 	 * @param d
     85 	 *            an array into which <i>N</i> data points, starting at
     86 	 *            <i>start</i> are copied.
     87 	 * @param N
     88 	 *            the number of polynomial interpolation points
     89 	 * @param start
     90 	 *            the index in <i>vec</i> from which copying starts
     91 	 */
     92 	private void fill(float vec[], float d[], int N, int start) {
     93 		int n = numPts;
     94 		if (n > N)
     95 			n = N;
     96 		int end = start + n;
     97 		int j = 0;
     98 
     99 		for (int i = start; i < end; i++) {
    100 			d[j] = vec[i];
    101 			j++;
    102 		}
    103 	} // fill
    104 
    105 	/**
    106 	 * <p>
    107 	 * Predict an odd point from the even points, using 4-point polynomial
    108 	 * interpolation.
    109 	 * </p>
    110 	 * <p>
    111 	 * The four points used in the polynomial interpolation are the even points.
    112 	 * We pretend that these four points are located at the x-coordinates
    113 	 * 0,1,2,3. The first odd point interpolated will be located between the
    114 	 * first and second even point, at 0.5. The next N-3 points are located at
    115 	 * 1.5 (in the middle of the four points). The last two points are located
    116 	 * at 2.5 and 3.5. For complete documentation see
    117 	 * </p>
    118 	 * 
    119 	 * <pre>
    120 	 *   <a href="http://www.bearcave.com/misl/misl_tech/wavelets/lifting/index.html">
    121 	 *   http://www.bearcave.com/misl/misl_tech/wavelets/lifting/index.html</a>
    122 	 * </pre>
    123 	 * 
    124 	 * <p>
    125 	 * The difference between the predicted (interpolated) value and the actual
    126 	 * odd value replaces the odd value in the forward transform.
    127 	 * </p>
    128 	 * 
    129 	 * <p>
    130 	 * As the recursive steps proceed, N will eventually be 4 and then 2. When N
    131 	 * = 4, linear interpolation is used. When N = 2, HaarWavelet interpolation
    132 	 * is used (the prediction for the odd value is that it is equal to the even
    133 	 * value).
    134 	 * </p>
    135 	 * 
    136 	 * @param vec
    137 	 *            the input data on which the forward or inverse transform is
    138 	 *            calculated.
    139 	 * @param N
    140 	 *            the area of vec over which the transform is calculated
    141 	 * @param direction
    142 	 *            forward or inverse transform
    143 	 */
    144 	protected void interp(float[] vec, int N, int direction) {
    145 		int half = N >> 1;
    146 		float d[] = new float[numPts];
    147 
    148 		// int k = 42;
    149 
    150 		for (int i = 0; i < half; i++) {
    151 			float predictVal;
    152 
    153 			if (i == 0) {
    154 				if (half == 1) {
    155 					// e.g., N == 2, and we use HaarWavelet interpolation
    156 					predictVal = vec[0];
    157 				} else {
    158 					fill(vec, d, N, 0);
    159 					predictVal = fourPt.interpPoint(0.5f, half, d);
    160 				}
    161 			} else if (i == 1) {
    162 				predictVal = fourPt.interpPoint(1.5f, half, d);
    163 			} else if (i == half - 2) {
    164 				predictVal = fourPt.interpPoint(2.5f, half, d);
    165 			} else if (i == half - 1) {
    166 				predictVal = fourPt.interpPoint(3.5f, half, d);
    167 			} else {
    168 				fill(vec, d, N, i - 1);
    169 				predictVal = fourPt.interpPoint(1.5f, half, d);
    170 			}
    171 
    172 			int j = i + half;
    173 			if (direction == forward) {
    174 				vec[j] = vec[j] - predictVal;
    175 			} else if (direction == inverse) {
    176 				vec[j] = vec[j] + predictVal;
    177 			} else {
    178 				System.out
    179 						.println("PolynomialWavelets::predict: bad direction value");
    180 			}
    181 		}
    182 	} // interp
    183 
    184 	/**
    185 	 * <p>
    186 	 * HaarWavelet transform extened with polynomial interpolation forward
    187 	 * transform.
    188 	 * </p>
    189 	 * <p>
    190 	 * This version of the forwardTrans function overrides the function in the
    191 	 * LiftingSchemeBaseWavelet base class. This function introduces an extra
    192 	 * polynomial interpolation stage at the end of the transform.
    193 	 * </p>
    194 	 */
    195 	public void forwardTrans(float[] vec) {
    196 		final int N = vec.length;
    197 
    198 		for (int n = N; n > 1; n = n >> 1) {
    199 			split(vec, n);
    200 			predict(vec, n, forward);
    201 			update(vec, n, forward);
    202 			interp(vec, n, forward);
    203 		} // for
    204 	} // forwardTrans
    205 
    206 	/**
    207 	 * <p>
    208 	 * HaarWavelet transform extened with polynomial interpolation inverse
    209 	 * transform.
    210 	 * </p>
    211 	 * <p>
    212 	 * This version of the inverseTrans function overrides the function in the
    213 	 * LiftingSchemeBaseWavelet base class. This function introduces an inverse
    214 	 * polynomial interpolation stage at the start of the inverse transform.
    215 	 * </p>
    216 	 */
    217 	public void inverseTrans(float[] vec) {
    218 		final int N = vec.length;
    219 
    220 		for (int n = 2; n <= N; n = n << 1) {
    221 			interp(vec, n, inverse);
    222 			update(vec, n, inverse);
    223 			predict(vec, n, inverse);
    224 			merge(vec, n);
    225 		}
    226 	} // inverseTrans
    227 
    228 } // HaarWithPolynomialInterpolationWavelet
    229