[α₁⁰ α₁¹ α₁² ⋯ α₁ⁿ⁻¹] [α₂⁰ α₂¹ α₂² ⋯ α₂ⁿ⁻¹] [α₃⁰ α₃¹ α₃² ⋯ α₃ⁿ⁻¹] [ ⋮ ⋮ ⋮ ⋱ ⋮ ] [αm⁰ αm¹ αm² ⋯ αmⁿ⁻¹] Ex: M = [1, 2, 3], n = 4 [1⁰ 1¹ 1² 1³] [1 1 1 1 ] V = [2⁰ 2¹ 2² 2³] = [1 2 4 8 ] [3⁰ 3¹ 3² 3³] [1 3 9 27] https://en.wikipedia.org/wiki/Vandermonde_matrix
Inheritance: extends Matrix
 /**
  * Weighted linear least squares fitting using Matrix algebra (Polynomial).
  *
  * Generalizing from a straight line (first degree polynomial) to a kᵗʰ degree polynomial:
  *  y = a₀ + a₁x + ⋯ + akxᵏ
  *
  * Leads to equations in matrix form:
  *  [n    Σxᵢ   ⋯  Σxᵢᵏ  ] [a₀]   [Σyᵢ   ]
  *  [Σxᵢ  Σxᵢ²  ⋯  Σxᵢᵏ⁺¹] [a₁]   [Σxᵢyᵢ ]
  *  [ ⋮     ⋮    ⋱  ⋮    ] [ ⋮ ] = [ ⋮    ]
  *  [Σxᵢᵏ Σxᵢᵏ⁺¹ ⋯ Σxᵢ²ᵏ ] [ak]   [Σxᵢᵏyᵢ]
  *
  * This is a Vandermonde matrix:
  *  [1 x₁ ⋯ x₁ᵏ] [a₀]   [y₁]
  *  [1 x₂ ⋯ x₂ᵏ] [a₁]   [y₂]
  *  [⋮  ⋮  ⋱ ⋮ ] [ ⋮ ] = [ ⋮]
  *  [1 xn ⋯ xnᵏ] [ak]   [yn]
  *
  * Can write as equation:
  *  y = Xa
  *
  * Solve by premultiplying by transpose Xᵀ:
  *  XᵀWy = XᵀWXa
  *
  * Invert to yield vector solution:
  *  a = (XᵀWX)⁻¹XᵀWy
  *
  * (http://mathworld.wolfram.com/LeastSquaresFittingPolynomial.html)
  *
  * For reference, the traditional way to do least squares:
  *        _ _   __
  *        x y - xy        _    _
  *   m = _________    b = y - mx
  *        _     __
  *       (x)² - x²
  *
  * @param  array $ys y values
  * @param  array $xs x values
  * @param  array $ws weight values
  *
  * @return Matrix [[m], [b]]
  */
 public function leastSquares(array $ys, array $xs, array $ws, int $order = 1) : Matrix
 {
     // y = Xa
     $X = new VandermondeMatrix($xs, $order + 1);
     $y = new ColumnVector($ys);
     $W = new DiagonalMatrix($ws);
     // a = (XᵀWX)⁻¹XᵀWy
     $Xᵀ = $X->transpose();
     $beta_hat = $Xᵀ->multiply($W)->multiply($X)->inverse()->multiply($Xᵀ)->multiply($W)->multiply($y);
     return $beta_hat;
 }
Example #2
0
 /**
  * Evaluate for x
  * Use the smoothness parameter α to determine the subset of data to consider for
  * local regression. Perform a weighted least squares regression and evaluate x.
  *
  * @param  number $x
  *
  * @return number
  */
 public function evaluate($x)
 {
     $α = $this->α;
     $λ = $this->λ;
     $n = $this->n;
     // The number of points considered in the local regression
     $Δx = Single::abs(Single::subtract($this->xs, $x));
     $αᵗʰΔx = Average::kthSmallest($Δx, $this->number_of_points - 1);
     $arg = Single::min(Single::divide($Δx, $αᵗʰΔx * max($α, 1)), 1);
     // Kernel function: tricube = (1-arg³)³
     $tricube = Single::cube(Single::multiply(Single::subtract(Single::cube($arg), 1), -1));
     $weights = $tricube;
     // Local Regression Parameters
     $parameters = $this->leastSquares($this->ys, $this->xs, $weights, $λ);
     $X = new VandermondeMatrix([$x], $λ + 1);
     return $X->multiply($parameters)[0][0];
 }