001: package JSci.maths.wavelet.daubechies2;
002:
003: import JSci.maths.wavelet.FWT;
004:
005: /************************
006: * This is a very fast implementation of the
007: * Fast Wavelet Transform. It uses in-place computations
008: * for less memory usage. Data length should be
009: * a power of 2 a be at least of length 4.
010: * Handles boundaries by assuming periodicity.
011: * Ideal for image processing or processing large
012: * amount of data. Uses floats for more performance.
013: * Safety is minimal, so be careful!
014: * @author Daniel Lemire
015: *************************/
016: public final class FastDaubechies2 extends FWT {
017: static final private float root3 = (float) (Math.sqrt(3.0));
018: static final private float normalizer = (float) (Math.pow(2d, -.5d));
019: static final float[] scale = { (1f + (root3)) * normalizer / 4f,
020: (3f + (root3)) * normalizer / 4f,
021: (3f + (-1 * (root3))) * normalizer / 4f,
022: (1f + (-1 * (root3))) * normalizer / 4f };
023: static final float[] wavelet = {
024: -(1f + (-1 * (root3))) * normalizer / 4f,
025: (3f + (-1 * (root3))) * normalizer / 4f,
026: -(3f + (root3)) * normalizer / 4f,
027: (1f + (root3)) * normalizer / 4f };
028:
029: public FastDaubechies2() {
030: }
031:
032: public static void transform(float[] v, int last) {
033: float[] ans = new float[last];
034: final int half = last / 2;
035: try {
036: for (int k = 0;/*k<half*/; k++) {
037: ans[k + half] = v[(2 * k + 0)] * wavelet[0]
038: + v[(2 * k + 1)] * wavelet[1] + v[(2 * k + 2)]
039: * wavelet[2] + v[(2 * k + 3)] * wavelet[3];
040: ans[k] = v[(2 * k + 0)] * scale[0] + v[(2 * k + 1)]
041: * scale[1] + v[(2 * k + 2)] * scale[2]
042: + v[(2 * k + 3)] * scale[3];
043: }
044: } catch (IndexOutOfBoundsException e) {
045: }
046: ans[last - 1] = v[last - 2] * wavelet[0] + v[last - 1]
047: * wavelet[1] + v[0] * wavelet[2] + v[1] * wavelet[3];
048: ans[half - 1] = v[last - 2] * scale[0] + v[last - 1] * scale[1]
049: + v[0] * scale[2] + v[1] * scale[3];
050:
051: System.arraycopy(ans, 0, v, 0, last);
052: }
053:
054: public void transform(float[] v) {
055: int last;
056: for (last = v.length; last > 4; last /= 2) {
057: transform(v, last);
058: }
059: if (last != 4)
060: System.err
061: .println("Careful! this should be a power of 2 : "
062: + v.length);
063: }
064:
065: public void invTransform(float[] v) {
066: int last;
067: for (last = 4; 2 * last <= v.length; last *= 2) {
068: invTransform(v, last);
069: }
070: if (last != v.length)
071: System.err
072: .println("Careful! this should be a power of 2 : "
073: + v.length);
074:
075: }
076:
077: public static void invTransform(float[] v, int last) {
078: int ResultingLength = 2 * last;
079: float[] ans = new float[ResultingLength];
080: try {
081: for (int k = 0;/*k<last*/; k++) {
082: ans[(2 * k + 3)] += scale[3] * v[k] + wavelet[3]
083: * v[k + last];
084: ans[(2 * k + 2)] += scale[2] * v[k] + wavelet[2]
085: * v[k + last];
086: ans[(2 * k + 1)] += scale[1] * v[k] + wavelet[1]
087: * v[k + last];
088: ans[(2 * k + 0)] += scale[0] * v[k] + wavelet[0]
089: * v[k + last];
090: }
091: } catch (IndexOutOfBoundsException e) {
092: }
093: ans[ResultingLength - 2] += scale[0] * v[last - 1] + wavelet[0]
094: * v[ResultingLength - 1];
095: ans[ResultingLength - 1] += scale[1] * v[last - 1] + wavelet[1]
096: * v[ResultingLength - 1];
097: ans[0] += scale[2] * v[last - 1] + wavelet[2]
098: * v[ResultingLength - 1];
099: ans[1] += scale[3] * v[last - 1] + wavelet[3]
100: * v[ResultingLength - 1];
101: System.arraycopy(ans, 0, v, 0, ans.length);
102: }
103: }
|