package be.tarsos.dsp.wavelet.lift; /** * <p> * HaarWavelet (flat LineWavelet) wavelet. * </p> * * <p> * As with all Lifting scheme wavelet transform functions, the first stage of a * transform step is the split stage. The split step moves the even element to * the first half of an N element region and the odd elements to the second half * of the N element region. * </p> * * <p> * The Lifting Scheme version of the HaarWavelet transform uses a wavelet * function (predict stage) that "predicts" that an odd element will have the * same value as it preceeding even element. Stated another way, the odd element * is "predicted" to be on a flat (zero slope LineWavelet) shared with the even * point. The difference between this "prediction" and the actual odd value * replaces the odd element. * </p> * * <p> * The wavelet scaling function (a.k.a. smoothing function) used in the update * stage calculates the average between an even and an odd element. * </p> * * <p> * The merge stage at the end of the inverse transform interleaves odd and even * elements from the two halves of the array (e.g., ordering them * even<sub>0</sub>, odd<sub>0</sub>, even<sub>1</sub>, odd<sub>1</sub>, ...) * </p> * * <h4> * Copyright and Use</h4> * * <p> * You may use this source code without limitation and without fee as long as * you include: * </p> * <blockquote> This software was written and is copyrighted by Ian Kaplan, Bear * Products International, www.bearcave.com, 2001. </blockquote> * <p> * This software is provided "as is", without any warrenty or claim as to its * usefulness. Anyone who uses this source code uses it at their own risk. Nor * is any support provided by Ian Kaplan and Bear Products International. * <p> * Please send any bug fixes or suggested source changes to: * * <pre> * iank@bearcave.com * </pre> * * @author Ian Kaplan */ public class HaarWavelet extends LiftingSchemeBaseWavelet { /** * HaarWavelet predict step */ protected void predict(float[] vec, int N, int direction) { int half = N >> 1; for (int i = 0; i < half; i++) { float predictVal = vec[i]; int j = i + half; if (direction == forward) { vec[j] = vec[j] - predictVal; } else if (direction == inverse) { vec[j] = vec[j] + predictVal; } else { System.out.println("HaarWavelet::predict: bad direction value"); } } } public void forwardTransOne(float[] vec) { final int N = vec.length; split(vec, N); predict(vec, N, forward); update(vec, N, forward); } // forwardTrans /** * <p> * Update step of the HaarWavelet wavelet transform. * </p> * <p> * The wavelet transform calculates a set of detail or difference * coefficients in the predict step. These are stored in the upper half of * the array. The update step calculates an average from the even-odd * element pairs. The averages will replace the even elements in the lower * half of the array. * </p> * <p> * The HaarWavelet wavelet calculation used in the Lifting Scheme is * </p> * * <pre> * d<sub>j+1, i</sub> = odd<sub>j+1, i</sub> = odd<sub>j, i</sub> - even<sub>j, i</sub> * a<sub>j+1, i</sub> = even<sub>j, i</sub> = (even<sub>j, i</sub> + odd<sub>j, i</sub>)/2 * </pre> * <p> * Note that the Lifting Scheme uses an in-place algorithm. The odd elements * have been replaced by the detail coefficients in the predict step. With a * little algebra we can substitute the coefficient calculation into the * average calculation, which gives us * </p> * * <pre> * a<sub>j+1, i</sub> = even<sub>j, i</sub> = even<sub>j, i</sub> + (odd<sub>j, i</sub>/2) * </pre> */ protected void update(float[] vec, int N, int direction) { int half = N >> 1; for (int i = 0; i < half; i++) { int j = i + half; float updateVal = vec[j] / 2.0f; if (direction == forward) { vec[i] = vec[i] + updateVal; } else if (direction == inverse) { vec[i] = vec[i] - updateVal; } else { System.out.println("update: bad direction value"); } } } } // HaarWavelet