Math/Statistics.js

  1. /** A helper class containing statistics methods. */
  2. Lore.Statistics = class Statistics {
  3. /**
  4. * Returns a normally distributed (pseudo) random number.
  5. *
  6. * @returns {Number} A normally distributed (pseudo) random number.
  7. */
  8. static randomNormal() {
  9. let val, u, v, s, mul;
  10. if (Lore.Statistics.spareRandomNormal !== null) {
  11. val = Lore.Statistics.spareRandomNormal;
  12. Lore.Statistics.spareRandomNormal = null;
  13. } else {
  14. do {
  15. u = Math.random() * 2 - 1;
  16. v = Math.random() * 2 - 1;
  17. s = u * u + v * v;
  18. } while (s === 0 || s >= 1);
  19. mul = Math.sqrt(-2 * Math.log(s) / s);
  20. val = u * mul;
  21. Lore.Statistics.spareRandomNormal = v * mul;
  22. }
  23. return val / 14;
  24. }
  25. /**
  26. * Returns a normally distributed (pseudo) random number within a range.
  27. *
  28. * @param {Number} a The start of the range.
  29. * @param {Number} b The end of the range.
  30. * @returns {Number} A normally distributed (pseudo) random number within a range.
  31. */
  32. static randomNormalInRange(a, b) {
  33. let val;
  34. do {
  35. val = Lore.Statistics.randomNormal();
  36. } while (val < a || val > b);
  37. return val;
  38. }
  39. /**
  40. * Returns a normally distributed (pseudo) random number around a mean with a standard deviation.
  41. *
  42. * @param {Number} mean The mean.
  43. * @param {Number} sd The standard deviation.
  44. * @returns {Number} A normally distributed (pseudo) random number around a mean with a standard deviation.
  45. */
  46. static randomNormalScaled(mean, sd) {
  47. let r = Lore.Statistics.randomNormalInRange(-1, 1);
  48. return r * sd + mean;
  49. }
  50. /**
  51. * Normalize / scale an array between 0 and 1.
  52. *
  53. * @param {Number[]} arr An array.
  54. * @returns {Number[]} The normalized / scaled array.
  55. */
  56. static normalize(arr) {
  57. let newArr = arr.slice();
  58. let max = Number.NEGATIVE_INFINITY;
  59. let min = Number.POSITIVE_INFINITY;
  60. for (let i = 0; i < newArr.length; i++) {
  61. let val = newArr[i];
  62. if (val > max) max = val;
  63. if (val < min) min = val;
  64. }
  65. let diff = max - min;
  66. for (let i = 0; i < newArr.length; i++) {
  67. newArr[i] = (newArr[i] - min) / diff;
  68. }
  69. return newArr;
  70. }
  71. /**
  72. * Scales a number to within a given scale.
  73. *
  74. * @param {Number} value The number.
  75. * @param {Number} oldMin The current minimum.
  76. * @param {Number} oldMax The current maximum.
  77. * @param {Number} newMin The cnew minimum.
  78. * @param {Number} newMax The new maximum.
  79. * @returns {Number} The scaled number.
  80. */
  81. static scale(value, oldMin, oldMax, newMin, newMax) {
  82. return (newMax - newMin) * (value - oldMin) / (oldMax - oldMin) + newMin;
  83. }
  84. }
  85. Lore.Statistics.spareRandomNormal = null;