175 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
Object.defineProperty(exports, '__esModule', { value: true });
 | 
						|
 | 
						|
/**
 | 
						|
 * @copyright 2013 Sonia Keys
 | 
						|
 * @copyright 2016 commenthol
 | 
						|
 * @license MIT
 | 
						|
 * @module fit
 | 
						|
 */
 | 
						|
/**
 | 
						|
 * Fit: Chapter 4, Curve Fitting.
 | 
						|
 */
 | 
						|
 | 
						|
/**
 | 
						|
 * Linear fits a line to sample data.
 | 
						|
 *
 | 
						|
 * Argument p is a list of data points.  Results a and b are coefficients
 | 
						|
 * of the best fit line y = ax + b.
 | 
						|
 */
 | 
						|
function linear (points) { // (p []struct{ X, Y float64 })  (a, b float64)
 | 
						|
  let sx = 0;
 | 
						|
  let sy = 0;
 | 
						|
  let sx2 = 0;
 | 
						|
  let sxy = 0;
 | 
						|
  for (const p of points) {
 | 
						|
    const x = p.x;
 | 
						|
    const y = p.y;
 | 
						|
    sx += x;
 | 
						|
    sy += y;
 | 
						|
    sx2 += x * x;
 | 
						|
    sxy += x * y;
 | 
						|
  }
 | 
						|
  const n = points.length;
 | 
						|
  const d = n * sx2 - sx * sx;
 | 
						|
  // (4.2) p. 36
 | 
						|
  const a = (n * sxy - sx * sy) / d;
 | 
						|
  const b = (sy * sx2 - sx * sxy) / d;
 | 
						|
  return [a, b]
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * CorrelationCoefficient returns a correlation coefficient for sample data.
 | 
						|
 */
 | 
						|
function correlationCoefficient (points) { // (p []struct{ X, Y float64 })  float64
 | 
						|
  let sx = 0;
 | 
						|
  let sy = 0;
 | 
						|
  let sx2 = 0;
 | 
						|
  let sy2 = 0;
 | 
						|
  let sxy = 0;
 | 
						|
  for (const p of points) {
 | 
						|
    const x = p.x;
 | 
						|
    const y = p.y;
 | 
						|
    sx += x;
 | 
						|
    sy += y;
 | 
						|
    sx2 += x * x;
 | 
						|
    sy2 += y * y;
 | 
						|
    sxy += x * y;
 | 
						|
  }
 | 
						|
  const n = points.length;
 | 
						|
  // (4.3) p. 38
 | 
						|
  return (n * sxy - sx * sy) / (Math.sqrt(n * sx2 - sx * sx) * Math.sqrt(n * sy2 - sy * sy))
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Quadratic fits y = ax² + bx + c to sample data.
 | 
						|
 *
 | 
						|
 * Argument p is a list of data points.  Results a, b, and c are coefficients
 | 
						|
 * of the best fit quadratic y = ax² + bx + c.
 | 
						|
 */
 | 
						|
function quadratic (points) {
 | 
						|
  let P = 0;
 | 
						|
  let Q = 0;
 | 
						|
  let R = 0;
 | 
						|
  let S = 0;
 | 
						|
  let T = 0;
 | 
						|
  let U = 0;
 | 
						|
  let V = 0;
 | 
						|
  for (const p of points) {
 | 
						|
    const x = p.x;
 | 
						|
    const y = p.y;
 | 
						|
    const x2 = x * x;
 | 
						|
    P += x;
 | 
						|
    Q += x2;
 | 
						|
    R += x * x2;
 | 
						|
    S += x2 * x2;
 | 
						|
    T += y;
 | 
						|
    U += x * y;
 | 
						|
    V += x2 * y;
 | 
						|
  }
 | 
						|
  const N = points.length;
 | 
						|
  // (4.5) p. 43
 | 
						|
  const D = N * Q * S + 2 * P * Q * R - Q * Q * Q - P * P * S - N * R * R;
 | 
						|
  // (4.6) p. 43
 | 
						|
  const a = (N * Q * V + P * R * T + P * Q * U - Q * Q * T - P * P * V - N * R * U) / D;
 | 
						|
  const b = (N * S * U + P * Q * V + Q * R * T - Q * Q * U - P * S * T - N * R * V) / D;
 | 
						|
  const c = (Q * S * T + Q * R * U + P * R * V - Q * Q * V - P * S * U - R * R * T) / D;
 | 
						|
  return [a, b, c]
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Func3 implements multiple linear regression for a linear combination
 | 
						|
 * of three functions.
 | 
						|
 *
 | 
						|
 * Given sample data and three functions in x, Func3 returns coefficients
 | 
						|
 * a, b, and c fitting y = aƒ₀(x) + bƒ₁(x) + cƒ₂(x) to sample data.
 | 
						|
 */
 | 
						|
function func3 (points, f0, f1, f2) {
 | 
						|
  let M = 0;
 | 
						|
  let P = 0;
 | 
						|
  let Q = 0;
 | 
						|
  let R = 0;
 | 
						|
  let S = 0;
 | 
						|
  let T = 0;
 | 
						|
  let U = 0;
 | 
						|
  let V = 0;
 | 
						|
  let W = 0;
 | 
						|
  for (const p of points) {
 | 
						|
    const x = p.x;
 | 
						|
    const y = p.y;
 | 
						|
    const y0 = f0(x);
 | 
						|
    const y1 = f1(x);
 | 
						|
    const y2 = f2(x);
 | 
						|
    M += y0 * y0;
 | 
						|
    P += y0 * y1;
 | 
						|
    Q += y0 * y2;
 | 
						|
    R += y1 * y1;
 | 
						|
    S += y1 * y2;
 | 
						|
    T += y2 * y2;
 | 
						|
    U += y * y0;
 | 
						|
    V += y * y1;
 | 
						|
    W += y * y2;
 | 
						|
  }
 | 
						|
  // (4.7) p. 44
 | 
						|
  const D = M * R * T + 2 * P * Q * S - M * S * S - R * Q * Q - T * P * P;
 | 
						|
  const a = (U * (R * T - S * S) + V * (Q * S - P * T) + W * (P * S - Q * R)) / D;
 | 
						|
  const b = (U * (S * Q - P * T) + V * (M * T - Q * Q) + W * (P * Q - M * S)) / D;
 | 
						|
  const c = (U * (P * S - R * Q) + V * (P * Q - M * S) + W * (M * R - P * P)) / D;
 | 
						|
  return [a, b, c]
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Func1 fits a linear multiple of a function to sample data.
 | 
						|
 *
 | 
						|
 * Given sample data and a function in x, Func1 returns coefficient
 | 
						|
 * a fitting y = aƒ(x).
 | 
						|
 */
 | 
						|
function func1 (points, f) {
 | 
						|
  let syf = 0;
 | 
						|
  let sf2 = 0;
 | 
						|
  // (4.8) p. 45
 | 
						|
  for (const p of points) {
 | 
						|
    const fx = f(p.x);
 | 
						|
    const y = p.y;
 | 
						|
    syf += y * fx;
 | 
						|
    sf2 += fx * fx;
 | 
						|
  }
 | 
						|
  return syf / sf2
 | 
						|
}
 | 
						|
 | 
						|
var fit = {
 | 
						|
  linear,
 | 
						|
  correlationCoefficient,
 | 
						|
  quadratic,
 | 
						|
  func3,
 | 
						|
  func1
 | 
						|
};
 | 
						|
 | 
						|
exports.correlationCoefficient = correlationCoefficient;
 | 
						|
exports["default"] = fit;
 | 
						|
exports.func1 = func1;
 | 
						|
exports.func3 = func3;
 | 
						|
exports.linear = linear;
 | 
						|
exports.quadratic = quadratic;
 |