quadratic.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import { determination } from "./utils/determination";
  2. import { interpose } from "./utils/interpose";
  3. import { points, visitPoints } from "./utils/points";
  4. export default function(){
  5. let x = d => d[0],
  6. y = d => d[1],
  7. domain;
  8. function quadratic(data){
  9. const [xv, yv, ux, uy] = points(data, x, y),
  10. n = xv.length;
  11. let X2 = 0,
  12. X3 = 0,
  13. X4 = 0,
  14. XY = 0,
  15. X2Y = 0,
  16. i, dx, dy, x2;
  17. for (i = 0; i < n;) {
  18. dx = xv[i];
  19. dy = yv[i++];
  20. x2 = dx * dx;
  21. X2 += (x2 - X2) / i;
  22. X3 += (x2 * dx - X3) / i;
  23. X4 += (x2 * x2 - X4) / i;
  24. XY += (dx * dy - XY) / i;
  25. X2Y += (x2 * dy - X2Y) / i;
  26. }
  27. let Y = 0,
  28. n0 = 0,
  29. xmin = domain ? +domain[0] : Infinity,
  30. xmax = domain ? +domain[1] : -Infinity;
  31. visitPoints(data, x, y, (dx, dy) => {
  32. n0++;
  33. Y += (dy - Y) / n0;
  34. if (!domain){
  35. if (dx < xmin) xmin = dx;
  36. if (dx > xmax) xmax = dx;
  37. }
  38. });
  39. const X2X2 = X4 - (X2 * X2),
  40. d = (X2 * X2X2 - X3 * X3),
  41. a = (X2Y * X2 - XY * X3) / d,
  42. b = (XY * X2X2 - X2Y * X3) / d,
  43. c = -a * X2,
  44. fn = x => {
  45. x = x - ux;
  46. return a * x * x + b * x + c + uy;
  47. };
  48. const out = interpose(xmin, xmax, fn);
  49. out.a = a;
  50. out.b = b - 2 * a * ux;
  51. out.c = c - b * ux + a * ux * ux + uy;
  52. out.predict = fn;
  53. out.rSquared = determination(data, x, y, Y, fn);
  54. return out;
  55. }
  56. quadratic.domain = function(arr){
  57. return arguments.length ? (domain = arr, quadratic) : domain;
  58. }
  59. quadratic.x = function(fn){
  60. return arguments.length ? (x = fn, quadratic) : x;
  61. }
  62. quadratic.y = function(fn){
  63. return arguments.length ? (y = fn, quadratic) : y;
  64. }
  65. return quadratic;
  66. }