comparison geotemco/lib/simile/timeplot/scripts/math.js @ 0:b12c99b7c3f0

commit for previous development
author Zoe Hong <zhong@mpiwg-berlin.mpg.de>
date Mon, 19 Jan 2015 17:13:49 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:b12c99b7c3f0
1 /**
2 * Math Utility functions
3 *
4 * @fileOverview Math Utility functions
5 * @name Math
6 */
7
8 Timeplot.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 }