_base.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.math._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.math._base"] = true;
  8. dojo.provide("dojox.math._base");
  9. dojo.getObject("math", true, dojox);
  10. (function(){
  11. var m = dojox.math;
  12. dojo.mixin(dojox.math, {
  13. toRadians: function(/* Number */n){
  14. // summary:
  15. // Convert the passed number to radians.
  16. return (n*Math.PI)/180; // Number
  17. },
  18. toDegrees: function(/* Number */n){
  19. // summary:
  20. // Convert the passed number to degrees.
  21. return (n*180)/Math.PI; // Number
  22. },
  23. degreesToRadians: function(/* Number */n){
  24. // summary:
  25. // Deprecated. Use dojox.math.toRadians.
  26. return m.toRadians(n); // Number
  27. },
  28. radiansToDegrees: function(/* Number */n){
  29. // summary:
  30. // Deprecated. Use dojox.math.toDegrees.
  31. return m.toDegrees(n); // Number
  32. },
  33. _gamma: function(z){
  34. // summary:
  35. // Compute the gamma function for the passed number.
  36. // Approximately 14 dijits of precision with non-integers.
  37. var answer = 1; // 0!
  38. // gamma(n+1) = n * gamma(n)
  39. while (--z >= 1){
  40. answer *= z;
  41. }
  42. if(z == 0){ return answer; } // normal integer quick return
  43. if(Math.floor(z) == z){ return NaN; } // undefined at nonpositive integers since sin() below will return 0
  44. // assert: z < 1, remember this z is really z-1
  45. if(z == -0.5){ return Math.sqrt(Math.PI); } // popular gamma(1/2)
  46. if(z < -0.5){ // remember this z is really z-1
  47. return Math.PI / (Math.sin(Math.PI * (z + 1)) * this._gamma(-z)); // reflection
  48. }
  49. // assert: -0.5 < z < 1
  50. // Spouge approximation algorithm
  51. var a = 13;
  52. // c[0] = sqrt(2*PI) / exp(a)
  53. // var kfact = 1
  54. // for (var k=1; k < a; k++){
  55. // c[k] = pow(-k + a, k - 0.5) * exp(-k) / kfact
  56. // kfact *= -k // (-1)^(k-1) * (k-1)!
  57. // }
  58. var c = [ // precomputed from the above algorithm
  59. 5.6658056015186327e-6,
  60. 1.2743717663379679,
  61. -4.9374199093155115,
  62. 7.8720267032485961,
  63. -6.6760503749436087,
  64. 3.2525298444485167,
  65. -9.1852521441026269e-1,
  66. 1.4474022977730785e-1,
  67. -1.1627561382389853e-2,
  68. 4.0117980757066622e-4,
  69. -4.2652458386405744e-6,
  70. 6.6651913290336086e-9,
  71. -1.5392547381874824e-13
  72. ];
  73. var sum = c[0];
  74. for (var k=1; k < a; k++){
  75. sum += c[k] / (z + k);
  76. }
  77. return answer * Math.pow(z + a, z + 0.5) / Math.exp(z) * sum;
  78. },
  79. factorial: function(/* Number */n){
  80. // summary:
  81. // Return the factorial of n
  82. return this._gamma(n+1); // Number
  83. },
  84. permutations: function(/* Number */n, /* Number */k){
  85. // summary:
  86. // TODO
  87. if(n==0 || k==0){
  88. return 1; // Number
  89. }
  90. return this.factorial(n) / this.factorial(n-k);
  91. },
  92. combinations: function(/* Number */n, /* Number */r){
  93. // summary:
  94. // TODO
  95. if(n==0 || r==0){
  96. return 1; // Number
  97. }
  98. return this.factorial(n) / (this.factorial(n-r) * this.factorial(r)); // Number
  99. },
  100. bernstein: function(/* Number */t, /* Number */n, /* Number */ i){
  101. // summary:
  102. // TODO
  103. return this.combinations(n, i) * Math.pow(t, i) * Math.pow(1-t, n-i); // Number
  104. },
  105. gaussian: function(){
  106. // summary:
  107. // Return a random number based on the Gaussian algo.
  108. var k=2;
  109. do{
  110. var i=2*Math.random()-1;
  111. var j=2*Math.random()-1;
  112. k = i*i+j*j;
  113. }while(k>=1);
  114. return i * Math.sqrt((-2*Math.log(k))/k); // Number
  115. },
  116. // create a range of numbers
  117. range: function(/* Number */a, /* Number? */b, /* Number? */step){
  118. // summary:
  119. // Create a range of numbers based on the parameters.
  120. if(arguments.length<2){
  121. b=a,a=0;
  122. }
  123. var range=[], s=step||1, i;
  124. if(s>0){
  125. for(i=a; i<b; i+=s){
  126. range.push(i);
  127. }
  128. }else{
  129. if(s<0){
  130. for(i=a; i>b; i+=s){
  131. range.push(i);
  132. }
  133. }else{
  134. throw new Error("dojox.math.range: step must not be zero.");
  135. }
  136. }
  137. return range; // Array
  138. },
  139. distance: function(/* Array */a, /* Array */b){
  140. // summary:
  141. // Calculate the distance between point A and point B
  142. return Math.sqrt(Math.pow(b[0]-a[0],2)+Math.pow(b[1]-a[1],2)); // Number
  143. },
  144. midpoint: function(/* Array */a, /* Array */b){
  145. // summary:
  146. // Calculate the midpoint between points A and B. A and B may be multidimensional.
  147. if(a.length!=b.length){
  148. console.error("dojox.math.midpoint: Points A and B are not the same dimensionally.", a, b);
  149. }
  150. var m=[];
  151. for(var i=0; i<a.length; i++){
  152. m[i]=(a[i]+b[i])/2;
  153. }
  154. return m; // Array
  155. }
  156. });
  157. })();
  158. }