index.spec.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. 'use strict';
  2. var EPS = 1e-8;
  3. var _ = require('lodash');
  4. var rewire = require('rewire');
  5. var expect = require('chai').expect;
  6. var pdfast = rewire('../src');
  7. describe('statistic util', function () {
  8. context('create', function () {
  9. var arr = [1, 1, 1, 2, 3, 3, 6, 6, 6, 6, 6, 6, 9, 9, 9, 9, 12];
  10. context('triangle', function () {
  11. var expected = [
  12. { x: 1, y: 0.18627450980392157 },
  13. { x: 2.2222222222222223, y: 0.1372549019607843 },
  14. { x: 3.4444444444444446, y: 0.029411764705882353 },
  15. { x: 4.666666666666667, y: 0.08823529411764706 },
  16. { x: 5.888888888888889, y: 0.17647058823529413 },
  17. { x: 7.111111111111112, y: 0.14705882352941177 },
  18. { x: 8.333333333333334, y: 0.11764705882352941 },
  19. { x: 9.555555555555557, y: 0.058823529411764705 },
  20. { x: 10.777777777777779, y: 0.0196078431372549 },
  21. { x: 12, y: 0.0392156862745098 }
  22. ];
  23. it('should work', function () {
  24. var result = pdfast.create(arr, {
  25. width: 2,
  26. size: 10,
  27. min: 1,
  28. max: 12
  29. });
  30. var sum = _.reduce(result, function (acc, item) {
  31. return acc + item.y;
  32. }, 0);
  33. expect(sum).closeTo(1, EPS);
  34. result.forEach(function (item, i) {
  35. expect(item.x).closeTo(expected[i].x, EPS);
  36. expect(item.y).closeTo(expected[i].y, EPS);
  37. });
  38. });
  39. it('should return empty array for empty input', function () {
  40. var result = pdfast.create([], {width: 2, size: 10, fast: false});
  41. expect(result).to.deep.equal([]);
  42. });
  43. it('should return 100% accuracy pdf for homogen input', function () {
  44. expect(
  45. pdfast.create([12, 12, 12], {width: 2, size: 10, fast: false})
  46. ).to.deep.equal([{x: 12, y: 1}]);
  47. expect(
  48. pdfast.create([-1, -1, -1], {width: 2, size: 10, fast: false})
  49. ).to.deep.equal([{x: -1, y: 1}]);
  50. });
  51. });
  52. context('general corner cases', function () {
  53. context('pdf area is 0, because hit is always outside', function () {
  54. var expected = [
  55. { x: 101, y: 0 },
  56. { x: 102, y: 0 },
  57. { x: 103, y: 0 },
  58. { x: 104, y: 0 },
  59. { x: 105, y: 0 }
  60. ];
  61. it('should work', function () {
  62. var result = pdfast.create(arr, {
  63. width: 2,
  64. size: 5,
  65. min: 101,
  66. max: 105
  67. });
  68. result.forEach(function (item, i) {
  69. expect(item.x).closeTo(expected[i].x, EPS);
  70. expect(item.y).closeTo(expected[i].y, EPS);
  71. });
  72. });
  73. });
  74. });
  75. });
  76. context('getUnifiedMinMax', function () {
  77. context('min and max exist', function () {
  78. it('should return defined min max', function () {
  79. expect(pdfast.getUnifiedMinMax([1, 2, 3], {min: -10, max: 10, width: 2, size: 20})).deep.equal({min: -10, max: 10});
  80. expect(pdfast.getUnifiedMinMax([1, 2, 3], {min: -5, max: 15, width: 2, size: 20})).deep.equal({min: -5, max: 15});
  81. });
  82. });
  83. context('only min exist', function () {
  84. it('should return defined min and find the max', function () {
  85. expect(pdfast.getUnifiedMinMax([1, 2, 3], {min: 0, width: 2, size: 4})).deep.equal({min: 0, max: 7});
  86. expect(pdfast.getUnifiedMinMax([1, 2, 3, 4], {min: -1, width: 2, size: 5})).deep.equal({min: -1, max: 9});
  87. });
  88. });
  89. context('only max exist', function () {
  90. it('should return defined max and find the min', function () {
  91. expect(pdfast.getUnifiedMinMax([1, 2, 3], {max: 4, width: 2, size: 4})).deep.equal({min: -3, max: 4});
  92. expect(pdfast.getUnifiedMinMax([1, 2, 3, 4], {max: 6, width: 2, size: 5})).deep.equal({min: -4, max: 6});
  93. });
  94. });
  95. context('no min or max exist', function () {
  96. it('should return defined max and find the min', function () {
  97. expect(pdfast.getUnifiedMinMax([1, 2, 3], {width: 2, size: 3})).deep.equal({min: -3, max: 7});
  98. expect(pdfast.getUnifiedMinMax([1, 2, 3, 4], {width: 2, size: 5})).deep.equal({min: -2, max: 7});
  99. });
  100. });
  101. });
  102. context('getUnifiedMinMaxMulti', function () {
  103. context('min and max exist', function () {
  104. it('should return defined min max', function () {
  105. expect(pdfast.getUnifiedMinMaxMulti([[1, 2, 3], [2, 5]], {min: -10, max: 10, width: 2, size: 20})).deep.equal({min: -10, max: 10});
  106. expect(pdfast.getUnifiedMinMaxMulti([[1, 2, 3], [2, 5]], {min: -5, max: 15, width: 2, size: 20})).deep.equal({min: -5, max: 15});
  107. });
  108. });
  109. context('only min exist', function () {
  110. it('should return defined min and find the max', function () {
  111. expect(pdfast.getUnifiedMinMaxMulti([[1, 2, 3], [0, 1]], {min: 0, width: 2, size: 4})).deep.equal({min: 0, max: 7});
  112. expect(pdfast.getUnifiedMinMaxMulti([[1, 2, 3], [2, 3], [0, 4]], {min: -1, width: 2, size: 5})).deep.equal({min: -1, max: 9});
  113. });
  114. });
  115. context('only max exist', function () {
  116. it('should return defined max and find the min', function () {
  117. expect(pdfast.getUnifiedMinMaxMulti([[1, 2], [2, 3]], {max: 4, width: 2, size: 4})).deep.equal({min: -3, max: 4});
  118. expect(pdfast.getUnifiedMinMaxMulti([[3, 4], [1], [2, 6]], {max: 6, width: 2, size: 5})).deep.equal({min: -4, max: 6});
  119. });
  120. });
  121. context('no min or max exist', function () {
  122. it('should return defined max and find the min', function () {
  123. expect(pdfast.getUnifiedMinMaxMulti([[1], [2, 3], [2]], {width: 2, size: 3})).deep.equal({min: -3, max: 7});
  124. expect(pdfast.getUnifiedMinMaxMulti([[1, 4], [1, 2, 3, 4]], {width: 2, size: 5})).deep.equal({min: -2, max: 7});
  125. });
  126. });
  127. });
  128. context('generatePartialAreas', function () {
  129. var generatePartialAreas = pdfast.__get__('generatePartialAreas');
  130. var mockFunction = function (x) {
  131. return Math.abs(x);
  132. };
  133. it('should work', function () {
  134. var expected = {
  135. "-3": 1,
  136. "-2": 1.6666666666666665,
  137. "-1": 1.9999999999999998,
  138. "0": 1.9999999999999998,
  139. "1": 2.333333333333333,
  140. "2": 2.9999999999999996,
  141. "3": 3.9999999999999996
  142. };
  143. var result = generatePartialAreas(mockFunction, 3);
  144. _.keys(expected).forEach(function (key) {
  145. expect(result[key]).closeTo(expected[key], EPS);
  146. });
  147. });
  148. });
  149. context('getExpectedValueFromPdf', function () {
  150. it('should return undefined for empty pdf', function () {
  151. expect(
  152. pdfast.getExpectedValueFromPdf([])
  153. ).equal(undefined);
  154. });
  155. it('should return expected value for typical pdf', function () {
  156. expect(
  157. pdfast.getExpectedValueFromPdf([{x: 12, y: 1}])
  158. ).equal(12);
  159. expect(
  160. pdfast.getExpectedValueFromPdf([
  161. {x: 1, y: 0.2},
  162. {x: 2, y: 0.4},
  163. {x: 3, y: 0.3},
  164. {x: 4, y: 0.075},
  165. {x: 5, y: 0.025}
  166. ])
  167. ).closeTo(2.3249999999999997, EPS);
  168. });
  169. });
  170. context('getXWithLeftTailArea', function () {
  171. it('should return undefined for empty pdf', function () {
  172. expect(
  173. pdfast.getXWithLeftTailArea([], 12)
  174. ).equal(undefined);
  175. });
  176. it('should return the only x for any area for 100% accuracy pdf', function () {
  177. var pdf = [{x: 12, y: 1}];
  178. expect(pdfast.getXWithLeftTailArea(pdf, 0)).equal(12);
  179. expect(pdfast.getXWithLeftTailArea(pdf, 0.5)).equal(12);
  180. expect(pdfast.getXWithLeftTailArea(pdf, 0.8)).equal(12);
  181. expect(pdfast.getXWithLeftTailArea(pdf, 1)).equal(12);
  182. });
  183. it('should return x position where left tail area equals given param', function () {
  184. var pdf = [
  185. {x: 1, y: 0.2},
  186. {x: 2, y: 0.4},
  187. {x: 3, y: 0.3},
  188. {x: 4, y: 0.075},
  189. {x: 5, y: 0.025}
  190. ];
  191. expect(pdfast.getXWithLeftTailArea(pdf, 0)).equal(1);
  192. expect(pdfast.getXWithLeftTailArea(pdf, 0.12)).equal(1);
  193. expect(pdfast.getXWithLeftTailArea(pdf, 0.19)).equal(1);
  194. expect(pdfast.getXWithLeftTailArea(pdf, 0.21)).equal(2);
  195. expect(pdfast.getXWithLeftTailArea(pdf, 0.95)).equal(4);
  196. expect(pdfast.getXWithLeftTailArea(pdf, 1)).equal(5);
  197. });
  198. });
  199. context('getPerplexity', function () {
  200. it('should return undefined for empty pdf', function () {
  201. expect(pdfast.getPerplexity([])).equal(undefined);
  202. expect(pdfast.getPerplexity(undefined)).equal(undefined);
  203. expect(pdfast.getPerplexity(null)).equal(undefined);
  204. });
  205. it('should return correct perplexity', function () {
  206. expect(
  207. pdfast.getPerplexity([
  208. {x: 1, y: 0.2},
  209. {x: 2, y: 0.2},
  210. {x: 3, y: 0.2},
  211. {x: 4, y: 0.2},
  212. {x: 5, y: 0.2}
  213. ])
  214. ).closeTo(5, EPS);
  215. expect(
  216. pdfast.getPerplexity([
  217. {x: 1, y: 0.2},
  218. {x: 2, y: 0.4},
  219. {x: 3, y: 0.3},
  220. {x: 4, y: 0.075},
  221. {x: 5, y: 0.025}
  222. ])
  223. ).closeTo(3.8041316039860336, EPS);
  224. expect(
  225. pdfast.getPerplexity([
  226. {x: 1, y: 0},
  227. {x: 2, y: 0},
  228. {x: 3, y: 1},
  229. {x: 4, y: 0}
  230. ])
  231. ).closeTo(1, EPS);
  232. });
  233. });
  234. });