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