001: package JSci.maths;
002:
003: /**
004: * The wavelet math library.
005: * This class cannot be subclassed or instantiated because all methods are static.
006: * @version 1.0
007: * @author Daniel Lemire
008: */
009: public final class WaveletMath extends AbstractMath {
010: private WaveletMath() {
011: }
012:
013: /**
014: * Part of the Fast Wavelet Scheme.
015: * Downsampling of a set of data points in base 2
016: * with an arbitrary filter using zero-padding
017: * at the boundaries in 1D.
018: * @return an array half the length of the input data[]
019: * as long as data.length was even.
020: */
021: public static Complex[] downsample(Complex filter[], Complex data[]) {
022: int loc = filter.length;
023: int demiloc = Math.round(loc / 2f - 0.5f);
024: int Nombre = data.length;
025: int DemiNombre = Math.round(Nombre / 2f - 0.5f);
026: Complex answer[] = new Complex[DemiNombre];
027: for (int i = 0; i < DemiNombre; i++) {
028: answer[i] = Complex.ZERO;
029: for (int j = Math.max(0, 2 * i - demiloc + 1); j < Math
030: .min(Nombre, 2 * i + loc - demiloc + 1); j++)
031: answer[i] = answer[i].add(data[j].multiply(filter[j - 2
032: * i + demiloc - 1]));
033: }
034: return answer;
035: }
036:
037: /**
038: * Part of the Fast Wavelet Scheme.
039: * Downsampling of a set of data points in base 2
040: * with an arbitrary filter using zero-padding
041: * at the boundaries in 1D.
042: * @return an array half the length of the input data[]
043: * as long as data.length was even.
044: */
045: public static double[] downsample(double filter[], double data[]) {
046: int loc = filter.length;
047: int demiloc = Math.round(loc / 2f - 0.5f);
048: int Nombre = data.length;
049: int DemiNombre = Math.round(Nombre / 2f - 0.5f);
050: double answer[] = new double[DemiNombre];
051: for (int i = 0; i < DemiNombre; i++) {
052: answer[i] = 0.0;
053: for (int j = Math.max(0, 2 * i - demiloc + 1); j < Math
054: .min(Nombre, 2 * i + loc - demiloc + 1); j++)
055: answer[i] += data[j] * filter[j - 2 * i + demiloc - 1];
056: }
057: return answer;
058: }
059:
060: /**
061: * Insertion of zeros between every other data point in 1D.
062: * @return an array twice as long as the input data[].
063: */
064: public static Complex[] upsample(Complex data[]) {
065: int Nombre = data.length;
066: Complex answer[] = new Complex[2 * Nombre];
067: for (int i = 0; i < Nombre; i++) {
068: answer[2 * i] = data[i];
069: answer[2 * i + 1] = Complex.ZERO;
070: }
071: return answer;
072: }
073:
074: /**
075: * Insertion of zeros between every other data point in 1D.
076: * @return an array twice as long as the input data[].
077: */
078: public static double[] upsample(double data[]) {
079: int Nombre = data.length;
080: double answer[] = new double[2 * Nombre];
081: for (int i = 0; i < Nombre; i++) {
082: answer[2 * i] = data[i];
083: answer[2 * i + 1] = 0.0;
084: }
085: return answer;
086: }
087:
088: /**
089: * Part of the Fast Wavelet Scheme.
090: * Upsampling of a set of data points in base 2
091: * with an arbitrary filter using zero-padding
092: * at the boundaries in 1D.
093: * @return an array twice as long as the input data[].
094: */
095: public static Complex[] upsample(Complex filter[], Complex data[]) {
096: int loc = filter.length;
097: int demiloc = Math.round(loc / 2f - 0.5f);
098: int Nombre = data.length;
099: Complex answer[] = new Complex[2 * Nombre];
100: Complex tmp[] = new Complex[2 * Nombre];
101: tmp = upsample(data);
102: for (int i = 0; i < 2 * Nombre; i++) {
103: answer[i] = Complex.ZERO;
104: for (int j = Math.max(0, i - demiloc); j < Math.min(
105: 2 * Nombre, i + loc - demiloc); j++)
106: answer[i] = answer[i].add(tmp[j].multiply(filter[i
107: + loc - demiloc - j - 1]));
108: }
109: return answer;
110: }
111:
112: /**
113: * Part of the Fast Wavelet Scheme.
114: * Upsampling of a set of data points in base 2
115: * with an arbitrary filter using zero-padding
116: * at the boundaries in 1D.
117: * @return an array twice as long as the input data[].
118: */
119: public static double[] upsample(double filter[], double data[]) {
120: int loc = filter.length;
121: int demiloc = Math.round(loc / 2f - 0.5f);
122: int Nombre = data.length;
123: double answer[] = new double[2 * Nombre];
124: double tmp[] = new double[2 * Nombre];
125: tmp = upsample(data);
126: for (int i = 0; i < 2 * Nombre; i++) {
127: answer[i] = 0.0;
128: for (int j = Math.max(0, i - demiloc); j < Math.min(
129: 2 * Nombre, i + loc - demiloc); j++)
130: answer[i] += tmp[j] * filter[i + loc - demiloc - j - 1];
131: }
132: return answer;
133: }
134:
135: /**
136: * Returns the highpass filter from the lowpass filter
137: * using Cohen's formula.
138: */
139: public static double[] lowToHigh(double v[]) {
140: double ans[] = ArrayMath.invert(v);
141: int b = 1;
142: for (int k = 0; k < ans.length; k++) {
143: ans[k] = b * ans[k];
144: b = -b;
145: }
146: return ans;
147: }
148: }
|