KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > JSci > maths > EngineerMath


1 package JSci.maths;
2
3 /**
4 * This class is dedicated to engineering methods applied to arrays including
5 * signal processing.
6 * All methods here are safe, that is, they create copies of arrays whenever
7 * necessary.
8 * This makes for slower methods, but the programmer can always
9 * define his own methods optimized for performance.
10 * @author Daniel Lemire
11 */

12 public final class EngineerMath extends AbstractMath {
13         private EngineerMath() {}
14
15         /**
16         * Return a running average over the data.
17         * The returned array has the same size as the input array.
18         * It is often used in signal processing to estimate the baseline.
19         * @param v the data.
20         * @param width width of the average.
21         * @exception IllegalArgumentException if v.length < width
22         * @exception IllegalArgumentException if width is even
23         * @exception IllegalArgumentException if v.length = 0
24         */

25         public static double[] runningAverage(double[] v, int width) {
26     if(v.length<width)
27       throw new IllegalArgumentException JavaDoc("Array must be at least as long as the required width : "+v.length+" < "+width);
28     if((width&1)==0)
29       throw new IllegalArgumentException JavaDoc("The parameter 'width' must be odd : "+width);
30     if(v.length==0)
31       throw new IllegalArgumentException JavaDoc("Empty array, nothing to compute!");
32     int halfsize=width >> 1;
33     double[] ans=new double[v.length];
34     ans[0]=ArrayMath.mean(ArrayMath.extract(0,width-1,v));
35     for(int k=1;k<halfsize;k++) {
36        ans[k]=ans[0];
37     }
38     for(int k=halfsize;k<v.length-halfsize-1;k++) {
39       ans[k]=ArrayMath.mean(ArrayMath.extract(k-halfsize,k+halfsize,v));
40     }
41
42     ans[v.length-halfsize-1]=ArrayMath.mean(ArrayMath.extract(v.length-1-width+1,v.length-1,v));
43     for(int k=v.length-halfsize;k<v.length;k++) {
44       ans[k]=ans[v.length-halfsize-1];
45     }
46     return(ans);
47   }
48         /**
49         * Return a running median over the data.
50         * The returned array has the same size as the input array.
51         * It is often used in signal processing to estimate the baseline.
52         * Safer than the running average, but somewhat more costly computationally.
53         * @param v the data
54         * @param width width of the average
55         * @exception IllegalArgumentException if v.length < width
56         * @exception IllegalArgumentException if width is even
57         */

58         public static double[] runningMedian(double[] v, int width) {
59     if(v.length<width)
60       throw new IllegalArgumentException JavaDoc("Array must be at least as long as the required width : "+v.length+" < "+width);
61     if((width&1)==0)
62       throw new IllegalArgumentException JavaDoc("The parameter 'width' must be odd : "+width);
63     if(v.length==0)
64       throw new IllegalArgumentException JavaDoc("Empty array, nothing to compute!");
65     int halfsize=width >> 1;
66     double[] ans=new double[v.length];
67     ans[0]=ArrayMath.median(ArrayMath.extract(0,width-1,v));
68     for(int k=1;k<halfsize;k++) {
69        ans[k]=ans[0];
70     }
71     for(int k=halfsize;k<v.length-halfsize-1;k++) {
72       ans[k]=ArrayMath.median(ArrayMath.extract(k-halfsize,k+halfsize,v));
73     }
74
75     ans[v.length-halfsize-1]=ArrayMath.median(ArrayMath.extract(v.length-1-width+1,v.length-1,v));
76     for(int k=v.length-halfsize;k<v.length;k++) {
77       ans[k]=ans[v.length-halfsize-1];
78     }
79     return(ans);
80   }
81
82     /**
83     * Shannon entropy of an array.
84         * Please check that the mass of the array is 1 before using this method.
85         * Use the method "entropy" otherwise.
86         * @jsci.planetmath ShannonsTheoremEntropy
87         */

88     public static double icf(double[] v) {
89         double ans=0;
90         for(int j=0;j<v.length;j++) {
91             if(v[j]!=0) {
92                 if (v[j]<0) {
93                     throw new IllegalArgumentException JavaDoc("You cannot take the ICF of a array having negative components : v ["+j+"] = "+v[j]+" < 0");
94                 }
95                 ans-=v[j]*Math.log(v[j]);
96             }
97         }
98         return(ans);
99     }
100
101     /**
102     * Compute the entropy of an array.
103         * The entropy as defined using the absolute value.
104         */

105     public static double entropy(double[] v) {
106         double[] temp=ArrayMath.abs(v);
107         double m=ArrayMath.mass(temp);
108         if(m==0) return(0);
109         temp=ArrayMath.scalarMultiply(1/m, temp);
110         return(icf(temp));
111
112     }
113
114     /**
115     * Compute the entropy of an array.
116         * The entropy as defined using the absolute value.
117         */

118     public static double entropy(int[] v) {
119         int[] temp=ArrayMath.abs(v);
120         int m=ArrayMath.mass(temp);
121         if(m==0) return(0);
122         double[] t2=ArrayMath.scalarMultiply(1.0/m, temp);
123         return(icf(t2));
124     }
125     /**
126     * Set an array to the specified length resampling using linear interpolation.
127         */

128     public static double[] resample(double[] data, final int newLength) {
129                 if(newLength<=0)
130                         throw new IllegalArgumentException JavaDoc("New length must be strictly positive : "+newLength+" <=0 ");
131                 double[] ans=new double[newLength];
132                 for(int k=0;k<newLength;k++) {
133             double pos = ((double)k/(double)(newLength-1))*(data.length-1);
134                         int base1 = (int) Math.floor(pos);
135                         int base2 = (int) Math.ceil(pos);
136                         double mod = pos-base1;
137                         ans[k]=data[base1]*mod+data[base2]*(1.0-mod);
138                 }
139         return(ans);
140     }
141 }
142
143
Popular Tags