logarithmic.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import { determination } from "./utils/determination";
  2. import { interpose } from "./utils/interpose";
  3. import { ols } from "./utils/ols";
  4. import { visitPoints } from "./utils/points";
  5. export default function() {
  6. let x = d => d[0],
  7. y = d => d[1],
  8. base = Math.E,
  9. domain;
  10. function logarithmic(data){
  11. let n = 0,
  12. X = 0,
  13. Y = 0,
  14. XY = 0,
  15. X2 = 0,
  16. xmin = domain ? +domain[0] : Infinity,
  17. xmax = domain ? +domain[1] : -Infinity,
  18. lb = Math.log(base);
  19. visitPoints(data, x, y, (dx, dy) => {
  20. const lx = Math.log(dx) / lb;
  21. ++n;
  22. X += (lx - X) / n;
  23. Y += (dy - Y) / n;
  24. XY += (lx * dy - XY) / n;
  25. X2 += (lx * lx - X2) / n;
  26. if (!domain){
  27. if (dx < xmin) xmin = dx;
  28. if (dx > xmax) xmax = dx;
  29. }
  30. });
  31. const [intercept, slope] = ols(X, Y, XY, X2),
  32. fn = x => slope * Math.log(x) / lb + intercept,
  33. out = interpose(xmin, xmax, fn);
  34. out.a = slope;
  35. out.b = intercept;
  36. out.predict = fn;
  37. out.rSquared = determination(data, x, y, Y, fn);
  38. return out;
  39. }
  40. logarithmic.domain = function(arr){
  41. return arguments.length ? (domain = arr, logarithmic) : domain;
  42. }
  43. logarithmic.x = function(fn){
  44. return arguments.length ? (x = fn, logarithmic) : x;
  45. }
  46. logarithmic.y = function(fn){
  47. return arguments.length ? (y = fn, logarithmic) : y;
  48. }
  49. logarithmic.base = function(n){
  50. return arguments.length ? (base = n, logarithmic) : base;
  51. }
  52. return logarithmic;
  53. }