/** * Solve nonlinear equatation * * Tries to solve equatation given by two matrices, with assumption, that: * A * x = B * where $this is A, and the paramenter B. x is cosnidered as a vector * x = ( x^n, x^(n-1), ..., x^2, x, 1 ) * * Will return a polynomial solution for x. * * See: http://en.wikipedia.org/wiki/Gauss-Newton_algorithm * * @param ezcGraphMatrix $matrix B * @return ezcGraphPolygon Solution of equatation */ public function solveNonlinearEquatation(ezcGraphMatrix $matrix) { // Build complete equatation $equatation = new ezcGraphMatrix($this->rows, $columns = $this->columns + 1); for ($i = 0; $i < $this->rows; ++$i) { for ($j = 0; $j < $this->columns; ++$j) { $equatation->set($i, $j, $this->matrix[$i][$j]); } $equatation->set($i, $this->columns, $matrix->get($i, 0)); } // Compute upper triangular matrix on left side of equatation for ($i = 0; $i < $this->rows - 1; ++$i) { for ($j = $i + 1; $j < $this->rows; ++$j) { if ($equatation->get($j, $i) !== 0) { if ($equatation->get($j, $i) == 0) { continue; } else { $factor = -($equatation->get($i, $i) / $equatation->get($j, $i)); } for ($k = $i; $k < $columns; ++$k) { $equatation->set($j, $k, $equatation->get($i, $k) + $factor * $equatation->get($j, $k)); } } } } // Normalize values on left side matrix diagonale for ($i = 0; $i < $this->rows; ++$i) { if (($value = $equatation->get($i, $i)) != 1 && $value != 0) { $factor = 1 / $value; for ($k = $i; $k < $columns; ++$k) { $equatation->set($i, $k, $equatation->get($i, $k) * $factor); } } } // Build up solving polynom $polynom = new ezcGraphPolynom(); for ($i = $this->rows - 1; $i >= 0; --$i) { for ($j = $i + 1; $j < $this->columns; ++$j) { $equatation->set($i, $this->columns, $equatation->get($i, $this->columns) + -$equatation->get($i, $j) * $polynom->get($j)); $equatation->set($i, $j, 0); } $polynom->set($i, $equatation->get($i, $this->columns)); } return $polynom; }
/** * Adds polynom to current polynom * * @param ezcGraphPolynom $polynom Polynom to add * @return ezcGraphPolynom Modified polynom */ public function add(ezcGraphPolynom $polynom) { $order = max($this->getOrder(), $polynom->getOrder()); for ($i = 0; $i <= $order; ++$i) { $this->set($i, $this->get($i) + $polynom->get($i)); } return $this; }