/** * Calculate the regression parameters by least squares on linearized data * x / y = x / V + K / V */ public function calculate() { // Linearize the relationship by dividing x by y $y’ = Multi::divide($this->xs, $this->ys); // Perform Least Squares Fit $linear_parameters = $this->leastSquares($y’, $this->xs)->getColumn(0); $V = 1 / $linear_parameters[1]; $K = $linear_parameters[0] * $V; $this->parameters = [$V, $K]; }
/** * Get the regression residuals * eᵢ = yᵢ - ŷᵢ * or in matrix form * e = (I - H)y * * @return array */ public function residuals() : array { return Multi::subtract($this->reg_ys, $this->reg_Yhat); }
/** * Weighted n-point moving average (WMA) * * Similar to simple n-point moving average, * however, each n-point has a weight associated with it, * and instead of dividing by n, we divide by the sum of the weights. * * Each weighted average = ∑(weighted values) / ∑(weights) * * @param array $numbers * @param int $n n-point moving average * @param array $weights Weights for each n points * * @return array of averages * * @throws BadDataException if number of weights is not equal to number of n-points */ public static function weightedMovingAverage(array $numbers, int $n, array $weights) : array { if (count($weights) !== $n) { throw new Exception\BadDataException('Number of weights must equal number of n-points'); } $m = count($numbers); $∑w = array_sum($weights); $WMA = []; for ($i = 0; $i <= $m - $n; $i++) { $∑wp = array_sum(Map\Multi::multiply(array_slice($numbers, $i, $n), $weights)); $WMA[] = $∑wp / $∑w; } return $WMA; }
/** * Subtract (A - B) * * A = [a₁, a₂, a₃] * B = [b₁, b₂, b₃] * A - B = [a₁ - b₁, a₂ - b₂, a₃ - b₃] * * @param Vector $B * * @return Vector */ public function subtract(Vector $B) : Vector { if ($B->getN() !== $this->n) { throw new Exception\VectorException('Vectors must be the same length for subtraction'); } $R = Map\Multi::subtract($this->A, $B->getVector()); return new Vector($R); }