/** * Build the polynom based on the given points. * * @return void */ protected function buildPolynom() { $points = array(); foreach ($this->source as $key => $value) { if (!is_numeric($key)) { throw new ezcGraphDatasetAverageInvalidKeysException(); } if ($this->min === false || $this->min > $key) { $this->min = (double) $key; } if ($this->max === false || $this->max < $key) { $this->max = (double) $key; } $points[] = new ezcGraphCoordinate((double) $key, (double) $value); } // Build transposed and normal Matrix out of coordiantes $a = new ezcGraphMatrix(count($points), $this->polynomOrder + 1); $b = new ezcGraphMatrix(count($points), 1); for ($i = 0; $i <= $this->properties['polynomOrder']; ++$i) { foreach ($points as $nr => $point) { $a->set($nr, $i, pow($point->x, $i)); $b->set($nr, 0, $point->y); } } $at = clone $a; $at->transpose(); $left = $at->multiply($a); $right = $at->multiply($b); $this->polynom = $left->solveNonlinearEquatation($right); }
public function testSolveNonlinearEquatation() { if (version_compare(phpversion(), '5.2.1', '<')) { $this->markTestSkipped("This test is only for PHP after 5.2.1. See PHP bug #40482."); } $a = new ezcGraphMatrix(3, 3, array(array(5, 4, 7), array(2, 12, 8), array(3, 6, 10))); $b = new ezcGraphMatrix(3, 1, array(array(1, 2, 3))); $polynom = $a->solveNonlinearEquatation($b); $this->assertEquals('-1.15e-1 x^2 + 1.92e-2 x + 3.46e-1', $polynom->__toString()); }
/** * Build LR decomposition from matrix * * Use Cholesky-Crout algorithm to get LR decomposition of the current * matrix. * * Will return an array with two matrices: * array( * 'l' => (ezcGraphMatrix) $left, * 'r' => (ezcGraphMatrix) $right, * ) * * @return array( ezcGraphMatrix ) */ public function LRdecomposition() { /** * Use Cholesky-Crout algorithm to get LR decomposition * * Input: Matrix A ($this) * * For i = 1 To n * For j = i To n * R(i,j)=A(i,j) * For k = 1 TO i-1 * R(i,j)-=L(i,k)*R(k,j) * end * end * For j=i+1 To n * L(j,i)= A(j,i) * For k = 1 TO i-1 * L(j,i)-=L(j,k)*R(k,i) * end * L(j,i)/=R(i,i) * end * end * * Output: matrices L,R */ $l = new ezcGraphMatrix($this->columns, $this->rows); $r = new ezcGraphMatrix($this->columns, $this->rows); for ($i = 0; $i < $this->columns; ++$i) { for ($j = $i; $j < $this->rows; ++$j) { $r->set($i, $j, $this->matrix[$i][$j]); for ($k = 0; $k <= $i - 1; ++$k) { $r->set($i, $j, $r->get($i, $j) - $l->get($i, $k) * $r->get($k, $j)); } } for ($j = $i + 1; $j < $this->rows; ++$j) { $l->set($j, $i, $this->matrix[$j][$i]); for ($k = 0; $k <= $i - 1; ++$k) { $l->set($j, $i, $l->get($j, $i) - $l->get($j, $k) * $r->get($k, $i)); } $l->set($j, $i, $l->get($j, $i) / $r->get($i, $i)); } } return array('l' => $l, 'r' => $r); }
/** * Transform a coordinate with the current transformation matrix. * * @param ezcGraphCoordinate $coordinate * @return ezcGraphCoordinate */ public function transformCoordinate(ezcGraphCoordinate $coordinate) { $vector = new ezcGraphMatrix(3, 1, array(array($coordinate->x), array($coordinate->y), array(1))); $vector = parent::multiply($vector); return new ezcGraphCoordinate($vector->get(0, 0), $vector->get(1, 0)); }