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