hypothesis.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. 'use strict';
  2. const OneDataSet = require('./hypothesis/one-data-set.js');
  3. const TwoDataSet = require('./hypothesis/two-data-set.js');
  4. const Welch = require('./hypothesis/welch.js');
  5. const Summary = require('summary');
  6. const ALTERNATIVE_MAP = Object.assign(Object.create(null), {
  7. 'not equal': 0,
  8. 'less': -1,
  9. 'greater': 1
  10. });
  11. function isSummary(data) {
  12. return data && (typeof data.mean === 'function' &&
  13. typeof data.variance === 'function' &&
  14. typeof data.size === 'function');
  15. }
  16. function isCalculated(data) {
  17. return data && (typeof data.mean === 'number' &&
  18. typeof data.variance === 'number' &&
  19. typeof data.size === 'number');
  20. }
  21. function isCompatible(structure) {
  22. return Array.isArray(structure) ||
  23. isSummary(structure) ||
  24. isCalculated(structure);
  25. }
  26. function toData(data) {
  27. if (Array.isArray(data) || isSummary(data)) {
  28. const summary = isSummary(data) ? data : new Summary(data);
  29. return {
  30. mean: summary.mean(),
  31. variance: summary.variance(),
  32. size: summary.size()
  33. };
  34. } else {
  35. return data;
  36. }
  37. }
  38. function hypothesis(left, right, options) {
  39. // Vertify required arguments
  40. if (!isCompatible(left)) {
  41. throw new TypeError(
  42. 'left value in hypothesis test must be an array or data summary'
  43. );
  44. }
  45. if (!isCompatible(right)) {
  46. options = right;
  47. right = undefined;
  48. }
  49. // Set the default options
  50. options = Object.assign({
  51. mu: 0,
  52. varEqual: false,
  53. alpha: 0.05,
  54. alternative: 'not equal'
  55. }, options);
  56. // Convert alternative value
  57. options.alternative = ALTERNATIVE_MAP[options.alternative];
  58. // Vertify mu option
  59. if (typeof options.mu !== 'number') {
  60. throw new TypeError('mu option must be a number');
  61. }
  62. // Vertify varEqual option
  63. if (typeof options.varEqual !== 'boolean') {
  64. throw new TypeError('varEqual option must be a boolean');
  65. }
  66. // Vertify alpha option
  67. if (typeof options.alpha !== 'number') {
  68. throw new TypeError('alpha option must be a number');
  69. }
  70. if (options.alpha >= 1) {
  71. throw new RangeError('alpha must be below 1.0');
  72. }
  73. // Vertify alternative option
  74. if (typeof options.alternative === 'undefined') {
  75. throw new Error('alternative must be either "not equal", "less" or "greater"');
  76. }
  77. // Perform the student's t test
  78. if (isCompatible(right)) {
  79. if (options.varEqual) {
  80. return new TwoDataSet(toData(left), toData(right), options);
  81. } else {
  82. return new Welch(toData(left), toData(right), options);
  83. }
  84. } else {
  85. return new OneDataSet(toData(left), options);
  86. }
  87. }
  88. module.exports = hypothesis;