001: package JSci.maths.wavelet.symmlet8;
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 8.
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 FastSymmlet8 extends FWT {
017:
018: public FastSymmlet8() {
019: }
020:
021: static final float[] scale = { 0.0322231006040782f,
022: -0.0126039672622638f, -0.0992195435769564f,
023: 0.297857795605605f, 0.803738751805386f, 0.497618667632563f,
024: -0.0296355276459604f, -0.0757657147893567f };
025: static final float[] wavelet = { -scale[7], scale[6], -scale[5],
026: scale[4], -scale[3], scale[2], -scale[1], scale[0] };
027:
028: public static void transform(float[] v, int last) {
029: float[] ans = new float[last];
030: final int half = last / 2;
031: try {
032: for (int k = 0;/*k<half*/; k++) {
033: ans[k + half] = v[(2 * k + 0)] * wavelet[0]
034: + v[(2 * k + 1)] * wavelet[1] + v[(2 * k + 2)]
035: * wavelet[2] + v[(2 * k + 3)] * wavelet[3]
036: + v[(2 * k + 4)] * wavelet[4] + v[(2 * k + 5)]
037: * wavelet[5] + v[(2 * k + 6)] * wavelet[6]
038: + v[(2 * k + 7)] * wavelet[7];
039: ans[k] = v[(2 * k + 0)] * scale[0] + v[(2 * k + 1)]
040: * scale[1] + v[(2 * k + 2)] * scale[2]
041: + v[(2 * k + 3)] * scale[3] + v[(2 * k + 4)]
042: * scale[4] + v[(2 * k + 5)] * scale[5]
043: + v[(2 * k + 6)] * scale[6] + v[(2 * k + 7)]
044: * scale[7];
045: }
046: } catch (IndexOutOfBoundsException e) {
047: }
048: ans[last - 3] = v[last - 6] * wavelet[0] + v[last - 5]
049: * wavelet[1] + v[last - 4] * wavelet[2] + v[last - 3]
050: * wavelet[3] + v[last - 2] * wavelet[4] + v[last - 1]
051: * wavelet[5] + v[0] * wavelet[6] + v[1] * wavelet[7];
052: ans[half - 3] = v[last - 6] * scale[0] + v[last - 5] * scale[1]
053: + v[last - 4] * scale[2] + v[last - 3] * scale[3]
054: + v[last - 2] * scale[4] + v[last - 1] * scale[5]
055: + v[0] * scale[6] + v[1] * scale[7];
056: ans[last - 2] = v[last - 4] * wavelet[0] + v[last - 3]
057: * wavelet[1] + v[last - 2] * wavelet[2] + v[last - 1]
058: * wavelet[3] + v[0] * wavelet[4] + v[1] * wavelet[5]
059: + v[2] * wavelet[6] + v[3] * wavelet[7];
060: ans[half - 2] = v[last - 4] * scale[0] + v[last - 3] * scale[1]
061: + v[last - 2] * scale[2] + v[last - 1] * scale[3]
062: + v[0] * scale[4] + v[1] * scale[5] + v[2] * scale[6]
063: + v[3] * scale[7];
064: ans[last - 1] = v[last - 2] * wavelet[0] + v[last - 1]
065: * wavelet[1] + v[0] * wavelet[2] + v[1] * wavelet[3]
066: + v[2] * wavelet[4] + v[3] * wavelet[5] + v[4]
067: * wavelet[6] + v[5] * wavelet[7];
068: ans[half - 1] = v[last - 2] * scale[0] + v[last - 1] * scale[1]
069: + v[0] * scale[2] + v[1] * scale[3] + v[2] * scale[4]
070: + v[3] * scale[5] + v[4] * scale[6] + v[5] * scale[7];
071: System.arraycopy(ans, 0, v, 0, last);
072: }
073:
074: public void transform(float[] v) {
075: int last;
076: for (last = v.length; last > 8; last /= 2) {
077: transform(v, last);
078: }
079: if (last != 8)
080: System.err
081: .println("Careful! this should be a power of 2 : "
082: + v.length);
083: }
084:
085: public void invTransform(float[] v) {
086: int last;
087: for (last = 8; 2 * last <= v.length; last *= 2) {
088: invTransform(v, last);
089: }
090: if (last != v.length)
091: System.err
092: .println("Careful! this should be a power of 2 : "
093: + v.length);
094: }
095:
096: public static void invTransform(float[] v, int last) {
097: final int ResultingLength = 2 * last;
098: float[] ans = new float[ResultingLength];
099: try {
100: for (int k = 0;/*k<last*/; k++) {
101: ans[(2 * k + 7)] += scale[7] * v[k] + wavelet[7]
102: * v[k + last];
103: ans[(2 * k + 6)] += scale[6] * v[k] + wavelet[6]
104: * v[k + last];
105: ans[(2 * k + 5)] += scale[5] * v[k] + wavelet[5]
106: * v[k + last];
107: ans[(2 * k + 4)] += scale[4] * v[k] + wavelet[4]
108: * v[k + last];
109: ans[(2 * k + 3)] += scale[3] * v[k] + wavelet[3]
110: * v[k + last];
111: ans[(2 * k + 2)] += scale[2] * v[k] + wavelet[2]
112: * v[k + last];
113: ans[(2 * k + 1)] += scale[1] * v[k] + wavelet[1]
114: * v[k + last];
115: ans[(2 * k + 0)] += scale[0] * v[k] + wavelet[0]
116: * v[k + last];
117: }
118: } catch (IndexOutOfBoundsException e) {
119: }
120: ans[ResultingLength - 6] += scale[0] * v[last - 3] + wavelet[0]
121: * v[ResultingLength - 3];
122: ans[ResultingLength - 5] += scale[1] * v[last - 3] + wavelet[1]
123: * v[ResultingLength - 3];
124: ans[ResultingLength - 4] += scale[2] * v[last - 3] + wavelet[2]
125: * v[ResultingLength - 3];
126: ans[ResultingLength - 3] += scale[3] * v[last - 3] + wavelet[3]
127: * v[ResultingLength - 3];
128: ans[ResultingLength - 2] += scale[4] * v[last - 3] + wavelet[4]
129: * v[ResultingLength - 3];
130: ans[ResultingLength - 1] += scale[5] * v[last - 3] + wavelet[5]
131: * v[ResultingLength - 3];
132: ans[0] += scale[6] * v[last - 3] + wavelet[6]
133: * v[ResultingLength - 3];
134: ans[1] += scale[7] * v[last - 3] + wavelet[7]
135: * v[ResultingLength - 3];
136: ans[ResultingLength - 4] += scale[0] * v[last - 2] + wavelet[0]
137: * v[ResultingLength - 2];
138: ans[ResultingLength - 3] += scale[1] * v[last - 2] + wavelet[1]
139: * v[ResultingLength - 2];
140: ans[ResultingLength - 2] += scale[2] * v[last - 2] + wavelet[2]
141: * v[ResultingLength - 2];
142: ans[ResultingLength - 1] += scale[3] * v[last - 2] + wavelet[3]
143: * v[ResultingLength - 2];
144: ans[0] += scale[4] * v[last - 2] + wavelet[4]
145: * v[ResultingLength - 2];
146: ans[1] += scale[5] * v[last - 2] + wavelet[5]
147: * v[ResultingLength - 2];
148: ans[2] += scale[6] * v[last - 2] + wavelet[6]
149: * v[ResultingLength - 2];
150: ans[3] += scale[7] * v[last - 2] + wavelet[7]
151: * v[ResultingLength - 2];
152: ans[ResultingLength - 2] += scale[0] * v[last - 1] + wavelet[0]
153: * v[ResultingLength - 1];
154: ans[ResultingLength - 1] += scale[1] * v[last - 1] + wavelet[1]
155: * v[ResultingLength - 1];
156: ans[0] += scale[2] * v[last - 1] + wavelet[2]
157: * v[ResultingLength - 1];
158: ans[1] += scale[3] * v[last - 1] + wavelet[3]
159: * v[ResultingLength - 1];
160: ans[2] += scale[4] * v[last - 1] + wavelet[4]
161: * v[ResultingLength - 1];
162: ans[3] += scale[5] * v[last - 1] + wavelet[5]
163: * v[ResultingLength - 1];
164: ans[4] += scale[6] * v[last - 1] + wavelet[6]
165: * v[ResultingLength - 1];
166: ans[5] += scale[7] * v[last - 1] + wavelet[7]
167: * v[ResultingLength - 1];
168: System.arraycopy(ans, 0, v, 0, ans.length);
169: }
170: }
|