001: package JSci.maths.wavelet.daubechies3;
002:
003: import JSci.maths.wavelet.*;
004: import JSci.maths.*;
005:
006: /******************************************
007: * Daubechies wavelets adapted to the
008: * interval by Meyer. Thanks to Pierre Vial
009: * for the filters.
010: * @author Daniel Lemire
011: *****************************************/
012: public final class Daubechies3 extends Multiresolution implements
013: Filter, NumericalConstants {
014: protected final static int filtretype = 4;
015: protected final static int minlength = 8;
016:
017: /****************************************
018: * This method is used to compute
019: * how the number of scaling functions
020: * changes from on scale to the other.
021: * Basically, if you have k scaling
022: * function and a Filter of type t, you'll
023: * have 2*k+t scaling functions at the
024: * next scale (dyadic case).
025: * Notice that this method assumes
026: * that one is working with the dyadic
027: * grid while the method "previousDimension"
028: * define in the interface "Filter" doesn't.
029: ******************************************/
030: public int getFilterType() {
031: return (filtretype);
032: }
033:
034: public MultiscaleFunction primaryScaling(int n0, int k) {
035: return (new Scaling3(n0, k));
036: }
037:
038: public MultiscaleFunction dualScaling(int n0, int k) {
039: return (new Scaling3(n0, k));
040: }
041:
042: public MultiscaleFunction primaryWavelet(int n0, int k) {
043: return (new Wavelet3(n0, k));
044: }
045:
046: public MultiscaleFunction dualWavelet(int n0, int k) {
047: return (new Wavelet3(n0, k));
048: }
049:
050: final static double[] vgtemp = { .332670552950, .806891509311,
051: .459877502118, -.135011020010, -.085441273882,
052: .035226291882 };
053:
054: final static double[] v0temp = { 0.689047760315, 0.724715933318 };
055:
056: final static double[] v1temp = { 0.0306457241755, -0.0291374408035,
057: -0.986047279405, 0.161005005859 };
058: final static double[] v2temp = { 0.0172802631418, -0.0164297845102,
059: 0.00443452721664, 0.0208960300827, -0.924034270866,
060: 0.380966943247 };
061: final static double[] v3temp = { 0.027026368393, -0.0256962180001,
062: 0.0639688879804, 0.381971870809, 0.176750229211,
063: 0.404677356783, -0.747429432607, 0.308155135811 };
064:
065: final static double[] vd0temp = { 0.889500699418, 0.456933808921 };
066: final static double[] vd1temp = { -0.198411021088, 0.386241373662,
067: 0.832668382346, 0.343677222149 };
068: final static double[] vd2temp = { 0.0390630495665,
069: -0.0760429831027, -0.143921176769, 0.456707890812,
070: 0.807766275151, 0.33303120718 };
071: final static double[] vd3temp = { -0.000276799784313,
072: 0.000538838660959, 0.0349752642807, -0.085504178774,
073: -0.134969198046, 0.459895243878, 0.806892290508,
074: 0.332670875027 };
075:
076: final static double[] vg = ArrayMath.scalarMultiply(SQRT2, vgtemp);
077: final static double[] vd0 = ArrayMath.scalarMultiply(SQRT2,
078: ArrayMath.invert(vd0temp));
079: final static double[] vd1 = ArrayMath.scalarMultiply(SQRT2,
080: ArrayMath.invert(vd1temp));
081: final static double[] vd2 = ArrayMath.scalarMultiply(SQRT2,
082: ArrayMath.invert(vd2temp));
083: final static double[] vd3 = ArrayMath.scalarMultiply(SQRT2,
084: ArrayMath.invert(vd3temp));
085: final static double[] v0 = ArrayMath.scalarMultiply(SQRT2, v0temp);
086: final static double[] v1 = ArrayMath.scalarMultiply(SQRT2, v1temp);
087: final static double[] v2 = ArrayMath.scalarMultiply(SQRT2, v2temp);
088: final static double[] v3 = ArrayMath.scalarMultiply(SQRT2, v3temp);
089:
090: /********************************************
091: * On définit ici le filtre comme tel par le
092: * vecteur phvg (filtre passe-haut).
093: *********************************************/
094: final static double[] phvg = WaveletMath.lowToHigh(vgtemp);
095:
096: final static double[] phv0 = { 0.720522830617, -0.685061028561,
097: 0.0259917491699, -0.101939535681, 0.0200641216304,
098: -0.00827216838973 };
099:
100: final static double[] phv1 = { 0.0639675079235, -0.0608192341872,
101: 0.151405112504, 0.904072212264, -0.0510574707719,
102: -0.18071490589, 0.315790060572, -0.130196008824 };
103:
104: final static double[] phvd0temp = { -0.409742284317,
105: 0.797634233593, -0.419058128916, -0.117669342504,
106: 0.0741631890253, 0.0305764886814 };
107:
108: final static double[] phvd0 = ArrayMath.invert(phvd0temp);
109:
110: final static double[] phvd1temp = { -0.00261427398522,
111: 0.00508913652903, 0.330328738376, -0.807556085169,
112: 0.460310974517, 0.13519444871, -0.0854338960798,
113: -0.0352232501168 };
114:
115: final static double[] phvd1 = ArrayMath.invert(phvd1temp);
116:
117: /****************************************
118: * This method return the number of "scaling"
119: * functions at the previous scale given a
120: * number of scaling functions. The answer
121: * is always smaller than the provided value
122: * (about half since this is a dyadic
123: * implementation). This relates to the same idea
124: * as the "Filter type". It is used by
125: * the interface "Filter".
126: *****************************************/
127: public int previousDimension(int k) {
128: return (Cascades.previousDimension(filtretype, k));
129:
130: }
131:
132: public Daubechies3() {
133: }
134:
135: /****************************************
136: * This is the implementation of the lowpass
137: * Filter. It is used by the interface
138: * "Filter". Lowpass filters are normalized
139: * so that they preserve constants away from
140: * the boundaries.
141: *****************************************/
142: public double[] lowpass(double[] v, double[] param) {
143: return (lowpass(v));
144: }
145:
146: /****************************************
147: * This is the implementation of the highpass
148: * Filter. It is used by the interface
149: * "Filter". Highpass filters are normalized
150: * in order to get L2 orthonormality of the
151: * resulting wavelets (when it applies).
152: * See the class DiscreteHilbertSpace for
153: * an implementation of the L2 integration.
154: *****************************************/
155: public double[] highpass(double[] v, double[] param) {
156: return (highpass(v));
157: }
158:
159: /****************************************
160: * This is the implementation of the lowpass
161: * Filter. It is used by the interface
162: * "Filter". Lowpass filters are normalized
163: * so that they preserve constants away from
164: * the boundaries.
165: *****************************************/
166: public double[] lowpass(double[] gete) {
167: if (gete.length < minlength) {
168: throw new IllegalScalingException(
169: "The array is not long enough : " + gete.length
170: + " < " + minlength);
171: }
172: double[] sortie = new double[2 * gete.length - filtretype];
173: int dl0 = gete.length - 1;
174: for (int k = 4; k <= dl0 - 4; k++) {
175: for (int L = -3; L < 3; L++) {
176: sortie[2 * k + L - 1] += vg[L + 3] * gete[k];
177: }
178: }
179: sortie = ArrayMath.add(sortie, gete[0], v0, 0);
180: sortie = ArrayMath.add(sortie, gete[1], v1, 0);
181: sortie = ArrayMath.add(sortie, gete[2], v2, 0);
182: sortie = ArrayMath.add(sortie, gete[3], v3, 0);
183: int p0 = sortie.length - vd0.length;
184: int p1 = sortie.length - vd1.length;
185: int p2 = sortie.length - vd2.length;
186: int p3 = sortie.length - vd3.length;
187: sortie = ArrayMath.add(sortie, gete[dl0], vd0, p0);
188: sortie = ArrayMath.add(sortie, gete[dl0 - 1], vd1, p1);
189: sortie = ArrayMath.add(sortie, gete[dl0 - 2], vd2, p2);
190: sortie = ArrayMath.add(sortie, gete[dl0 - 3], vd3, p3);
191: return (sortie);
192: }
193:
194: /****************************************
195: * This is the implementation of the highpass
196: * Filter. It is used by the interface
197: * "Filter". Highpass filters are normalized
198: * in order to get L2 orthonormality of the
199: * resulting wavelets (when it applies).
200: * See the class DiscreteHilbertSpace for
201: * an implementation of the L2 integration.
202: *****************************************/
203: public double[] highpass(double[] gete) {
204: double[] sortie = new double[2 * gete.length + filtretype];
205: int dl0 = gete.length - 1;
206: for (int k = 2; k <= dl0 - 2; k++) {
207: for (int L = -3; L < 3; L++) {
208: sortie[2 * k + L + 3] += phvg[L + 3] * gete[k];
209: }
210: }
211: sortie = ArrayMath.add(sortie, gete[0], phv0, 0);
212: int p0 = sortie.length - phvd0.length;
213: sortie = ArrayMath.add(sortie, gete[dl0], phvd0, p0);
214: sortie = ArrayMath.add(sortie, gete[1], phv1, 0);
215: int p1 = sortie.length - phvd1.length;
216: sortie = ArrayMath.add(sortie, gete[dl0 - 1], phvd1, p1);
217:
218: return (sortie);
219: }
220:
221: public double[] evalScaling(int n0, int k, int j1) {
222: return (Cascades.evalScaling(this , n0, j1, k));
223: }
224:
225: public double[] evalWavelet(int n0, int k, int j1) {
226: return (Cascades.evalWavelet(this, filtretype, n0, j1, k));
227: }
228:
229: }
|