001: package JSci.maths.wavelet;
002:
003: import JSci.maths.wavelet.*;
004: import JSci.maths.*;
005:
006: /**********************************************
007: * This class is used to be able to mix the wavelet
008: * and sine transforms. It is in fact a normalised
009: * sine.
010: * @author Daniel Lemire
011: *************************************************/
012: public final class Sine extends MultiscaleFunction implements
013: NumericalConstants, Cloneable {
014:
015: private int n0;
016: private int freq;
017: private double normalisation;
018:
019: /*******************************
020: * Return a String representation
021: * of the object
022: ********************************/
023: public String toString() {
024: String ans = new String("[n0=");
025: ans.concat(Integer.toString(n0));
026: ans.concat("][freq=");
027: ans.concat(Integer.toString(freq));
028: ans.concat("]");
029: return (ans);
030: }
031:
032: public Sine(int N0, int FREQ) {
033: if (N0 < 0) {
034: throw new IllegalArgumentException("The length paramenter "
035: + N0 + " must be positive");
036: }
037: if ((FREQ < 0) || (FREQ >= N0)) {
038: throw new IllegalArgumentException(
039: "The frequency parameter " + FREQ
040: + " must be between " + 0 + " and "
041: + (N0 - 1));
042: }
043: n0 = N0;
044: freq = FREQ;
045: normalisation = Math.sqrt(n0 / 2d);
046:
047: }
048:
049: /*****************************************
050: * Check if another object is equal to this
051: * Sine object
052: ******************************************/
053: public boolean equals(Object a) {
054: if ((a != null) && (a instanceof Sine)) {
055: Sine iv = (Sine) a;
056: return (this .dimension(0) == iv.dimension(0))
057: && (this .getFrequency() == iv.getFrequency());
058: }
059: return false;
060: }
061:
062: public int getFrequency() {
063: return (freq);
064: }
065:
066: /************************************************
067: * Return as an array the sampled values
068: * of the function
069: *************************************************/
070: public double[] evaluate() {
071: return (ArrayMath.scalarMultiply(1.0 / normalisation, evaluate(
072: n0, freq)));
073: }
074:
075: private static double[] evaluate(int N0, int FREQ) {
076: double[] ans = new double[N0];
077: for (int k = 0; k < ans.length; k++) {
078: ans[k] = Math.sin(TWO_PI * k * FREQ / N0);
079: }
080: return (ans);
081: }
082:
083: /*****************************************
084: * Tells you how many samples you'll get
085: * from this function (will not depend
086: * on the parameter)
087: ******************************************/
088: public int dimension(int jfin) {
089: return (n0);
090: }
091:
092: /*****************************************
093: * Tells you how many samples you'll get
094: * from this function
095: ******************************************/
096: public int dimension() {
097: return (n0);
098: }
099:
100: /********************************************
101: * Return a copy of this object
102: *********************************************/
103: public Object clone() {
104: Sine s = (Sine) super .clone();
105: s.n0 = n0;
106: s.freq = freq;
107: return (s);
108: }
109:
110: /************************************************
111: * Return as an array the sampled values
112: * of the function
113: * @param j number of iterations (doesn't do anything)
114: *************************************************/
115: public double[] evaluate(int j) {
116: return (evaluate());
117: }
118:
119: /******************************************
120: * Compute the mass (integral)
121: * @param a left boundary of the interval
122: * @param b right boundary of the interval
123: * @param jfin number of iterations to consider
124: * (precision)
125: **********************************************/
126: public double mass(double a, double b, int jfin) {
127: double somme = 0.0;
128: double[] values = evaluate(jfin);
129: for (int k = 0; k < values.length; k++) {
130: somme += values[k];
131: }
132: somme = somme / (values.length - 1) * Math.abs(b - a);
133: return (somme);
134: }
135:
136: /****************************************
137: * This method is used to compute
138: * how the number of scaling functions
139: * changes from on scale to the other.
140: * Basically, if you have k scaling
141: * function and a filter of type t, you'll
142: * have 2*k+t scaling functions at the
143: * next scale (dyadic case).
144: * Notice that this method assumes
145: * that one is working with the dyadic
146: * grid while the method "previousDimension"
147: * define in the interface "filter" doesn't.
148: ******************************************/
149: public int getFilterType() {
150: return (n0);
151: }
152: }
|