<?php
require_once dirname(__DIR__) . '/base/regression.php';
require_once dirname(dirname(__DIR__)) . '/zendasmath/regression/polynomial.php';
require_once __DIR__ . '/regressionMatrix.php';

class Polynomial extends RegressionBase
{
    public $degree;

    public $points;

    public $analysis;

    public $dataframe;

    public function __construct($dataframe, $points, $degree)
    {
        $this->degree = $degree;
        $this->points = $points;

        $this->analysis = new PolynomialRegression($degree, $points[0], $points[1]);

        parent::__construct($dataframe);
    }

    /**
     * 构建回归方程公式。
     *
     * @param  string    $xaxis
     * @param  string    $yaxis
     * @access public
     * @return void
     */
    public function getFormula($xaxis, $yaxis)
    {
        $coeff   = $this->analysis->coeff;
        $formula = array();

        if(!$coeff) return '' . $yaxis . ' = ' . implode('', $formula);

        $formula[] = $this->dataframe->roundDigit($coeff->K);

        $mark  = $coeff->A >= 0 ? ' + ' : ' - ';
        $param = abs($coeff->A);
        $formula[] = $mark . $this->dataframe->roundDigit($param) . ' ' . $xaxis;

        if($this->degree >= 2)
        {
            $mark  = $coeff->B >= 0 ? ' + ' : ' - ';
            $param = abs($coeff->B);
            $formula[] = $mark . $this->dataframe->rounddigit($param) . ' ' . $xaxis . '^2';
        }

        if($this->degree == 3)
        {
            $mark  = $coeff->C >= 0 ? ' + ' : ' - ';
            $param = abs($coeff->C);
            $formula[] = $mark . $this->dataframe->rounddigit($param) . ' ' . $xaxis . '^3';
        }

        return '' . $yaxis . ' = ' . implode('', $formula);
    }

    /**
     * 根据x拟合y。
     *
     * @param  float    $point
     * @access public
     * @return void
     */
    public function evaluate($point)
    {
        $k = isset($this->analysis->coeff->K) ? $this->analysis->coeff->K : 0;
        $a = isset($this->analysis->coeff->A) ? $this->analysis->coeff->A : 0;
        $b = isset($this->analysis->coeff->B) ? $this->analysis->coeff->B : 0;
        $c = isset($this->analysis->coeff->C) ? $this->analysis->coeff->C : 0;

        return $k + $a * $point + $b * pow($point, 2) + $c * pow($point, 3);
    }

    /**
     * 模型汇总结果。
     *
     * @access public
     * @return void
     */
    public function getModel()
    {
        $result  = new stdclass();
        $rsq     = isset($this->analysis->model->RSquared) ?  $this->analysis->model->RSquared: null;
        $req     = isset($this->analysis->model->RSquaredAdjusted) ? $this->analysis->model->RSquaredAdjusted : null;
        $n       = count($this->analysis->x);
        $freedom = $this->degree;
        $errorSd = isset($this->analysis->model->S) ? $this->analysis->model->S : null;

        $result->rsq     = $this->dataframe->roundDigit($rsq * 100);
        $result->n       = $n;
        $result->freedom = $freedom;
        $result->req     = $this->dataframe->roundDigit($req * 100);
        $result->errorSd = $this->dataframe->roundDigit($errorSd);

        return $result;
    }

    /**
     * 方差分析结果。
     *
     * @param  int    $degree
     * @access public
     * @return void
     */
    public function getAnova($degree)
    {
        $result = new stdclass();

        $freedom = isset($this->analysis->anova->DfRegression) ? $this->analysis->anova->DfRegression : null;
        $ss      = isset($this->analysis->anova->RegressionSS) ? $this->analysis->anova->RegressionSS : null;
        $ms      = isset($this->analysis->anova->RegressionMS) ? $this->analysis->anova->RegressionMS : null;
        $f       = isset($this->analysis->anova->F) ? $this->analysis->anova->F : null;
        $p       = isset($this->analysis->anova->P) ? $this->analysis->anova->P : null;

        $freedomError = isset($this->analysis->anova->DfError) ? $this->analysis->anova->DfError : null;
        $ssError      = isset($this->analysis->anova->ErrorSS) ? $this->analysis->anova->ErrorSS : null;
        $msError      = isset($this->analysis->anova->ErrorMS) ? $this->analysis->anova->ErrorMS : null;

        $freedomTotal = isset($this->analysis->anova->DfTotal) ? $this->analysis->anova->DfTotal : null;
        $ssTotal      = isset($this->analysis->anova->TotalSS) ? $this->analysis->anova->TotalSS : null;

        $result->freedom = $this->dataframe->roundDigit($freedom);
        $result->ss      = $this->dataframe->roundDigit($ss);
        $result->ms      = $this->dataframe->roundDigit($ms);
        $result->f       = $this->dataframe->roundDigit($f);
        $result->p       = $this->dataframe->roundDigit($p);

        $result->freedomError = $this->dataframe->roundDigit($freedomError);
        $result->ssError      = $this->dataframe->roundDigit($ssError);
        $result->msError      = $this->dataframe->roundDigit($msError);

        $result->freedomTotal = $this->dataframe->roundDigit($freedomTotal);
        $result->ssTotal      = $this->dataframe->roundDigit($ssTotal);

        return $result;
    }
}


