PageRenderTime 174ms CodeModel.GetById 80ms app.highlight 11ms RepoModel.GetById 80ms app.codeStats 0ms

/timeplot/scripts/math.js

http://showslow.googlecode.com/
JavaScript | 193 lines | 122 code | 26 blank | 45 comment | 25 complexity | 98d7235133c0db594ed82c074f3dbfdf MD5 | raw file
  1/**
  2 * Math Utility functions
  3 * 
  4 * @fileOverview Math Utility functions
  5 * @name Math
  6 */
  7
  8Timeplot.Math = { 
  9
 10    /**
 11     * Evaluates the range (min and max values) of the given array
 12     */
 13    range: function(f) {
 14        var F = f.length;
 15        var min = Number.MAX_VALUE;
 16        var max = Number.MIN_VALUE;
 17
 18        for (var t = 0; t < F; t++) {
 19            var value = f[t];
 20            if (value < min) {
 21                min = value;
 22            }
 23            if (value > max) {
 24                max = value;
 25            }    
 26        }
 27
 28        return {
 29            min: min,
 30            max: max
 31        }
 32    },
 33
 34    /**
 35     * Evaluates the windows average of a given array based on the
 36     * given window size
 37     */
 38    movingAverage: function(f, size) {
 39        var F = f.length;
 40        var g = new Array(F);
 41        for (var n = 0; n < F; n++) {
 42            var value = 0;
 43            for (var m = n - size; m < n + size; m++) {
 44                if (m < 0) {
 45                    var v = f[0];
 46                } else if (m >= F) {
 47                    var v = g[n-1];
 48                } else {
 49                    var v = f[m];
 50                }
 51                value += v;
 52            }
 53            g[n] = value / (2 * size);
 54        }
 55        return g;
 56    },
 57
 58    /**
 59     * Returns an array with the integral of the given array
 60     */
 61    integral: function(f) {
 62        var F = f.length;
 63
 64        var g = new Array(F);
 65        var sum = 0;
 66
 67        for (var t = 0; t < F; t++) {
 68           sum += f[t];
 69           g[t] = sum;  
 70        }
 71
 72        return g;
 73    },
 74
 75    /**
 76     * Normalizes an array so that its complete integral is 1.
 77     * This is useful to obtain arrays that preserve the overall
 78     * integral of a convolution. 
 79     */
 80    normalize: function(f) {
 81        var F = f.length;
 82        var sum = 0.0;
 83
 84        for (var t = 0; t < F; t++) {
 85            sum += f[t];
 86        }
 87
 88        for (var t = 0; t < F; t++) {
 89            f[t] /= sum;
 90        }
 91
 92        return f;
 93    },
 94
 95    /**
 96     * Calculates the convolution between two arrays
 97     */
 98    convolution: function(f,g) {
 99        var F = f.length;
100        var G = g.length;
101
102        var c = new Array(F);
103
104        for (var m = 0; m < F; m++) {
105            var r = 0;
106            var end = (m + G < F) ? m + G : F;
107            for (var n = m; n < end; n++) {
108                var a = f[n - G];
109                var b = g[n - m];
110                r += a * b;
111            }
112            c[m] = r;
113        }
114
115        return c;
116    },
117
118    // ------ Array generators ------------------------------------------------- 
119    // Functions that generate arrays based on mathematical functions
120    // Normally these are used to produce operators by convolving them with the input array
121    // The returned arrays have the property of having 
122
123    /**
124     * Generate the heavyside step function of given size
125     */
126    heavyside: function(size) {
127        var f =  new Array(size);
128        var value = 1 / size;
129        for (var t = 0; t < size; t++) {
130            f[t] = value;
131        }
132        return f;
133    },
134
135    /**
136     * Generate the gaussian function so that at the given 'size' it has value 'threshold'
137     * and make sure its integral is one.
138     */
139    gaussian: function(size, threshold) {
140        with (Math) {
141            var radius = size / 2;
142            var variance = radius * radius / log(threshold); 
143            var g = new Array(size);
144            for (var t = 0; t < size; t++) {
145                var l = t - radius;
146                g[t] = exp(-variance * l * l);
147            }
148        }
149
150        return this.normalize(g);
151    },
152
153    // ---- Utility Methods --------------------------------------------------
154
155    /**
156     * Return x with n significant figures 
157     */
158    round: function(x,n) {
159        with (Math) {
160            if (abs(x) > 1) {
161                var l = floor(log(x)/log(10));
162                var d = round(exp((l-n+1)*log(10)));
163                var y = round(round(x / d) * d);
164                return y;
165            } else {
166                log("FIXME(SM): still to implement for 0 < abs(x) < 1");
167                return x;
168            }
169        }
170    },
171    
172    /**
173     * Return the hyperbolic tangent of x
174     */
175    tanh: function(x) {
176        if (x > 5) {
177            return 1;
178        } else if (x < 5) {
179            return -1;
180        } else {
181            var expx2 = Math.exp(2 * x);
182            return (expx2 - 1) / (expx2 + 1);
183        }
184    },
185    
186    /** 
187     * Returns true if |a.x - b.x| < value && | a.y - b.y | < value
188     */
189    isClose: function(a,b,value) {
190        return (a && b && Math.abs(a.x - b.x) < value && Math.abs(a.y - b.y) < value);
191    }
192
193}