/** * Find and return the roots of a Quartic Polynomial (degree 4) with the Quartic formula * * @see Math_PolynomialOp::getRoots() * * @access public * * @param object $p * @return array */ function getRootsQuartic($p) { if (!is_a($p, 'Math_Polynomial')) { $p = new Math_Polynomial($p); } if ($p->degree() == 4) { $arr = array(); // Array of roots // Simplify it a bit first $a_term = $p->getTerm(0); $p = Math_PolynomialOp::div($p, $a_term->getCoefficient()); $a = 0; $b = 0; $c = 0; $d = 0; $e = 0; $num_terms = $p->numTerms(); for ($i = 0; $i < $num_terms; $i++) { $term = $p->getTerm($i); if ($term->getExponent() == 4) { $a = $term->getCoefficient(); } else { if ($term->getExponent() == 3) { $b = $term->getCoefficient(); } else { if ($term->getExponent() == 2) { $c = $term->getCoefficient(); } else { if ($term->getExponent() == 1) { $d = $term->getCoefficient(); } else { if ($term->getExponent() == 0) { $e = $term->getCoefficient(); } } } } } } $f = $c - 3 * $b * $b / 8; $g = $d + pow($b, 3) / 8 - $b * $c / 2; $h = $e - 3 * pow($b, 4) / 256 + $b * $b * ($c / 16) - $b * $d / 4; $cubic = new Math_Polynomial('x^3 + ' . $f / 2 . 'x^2 + ' . (pow($f, 2) - 4 * $h) / 16 . 'x - ' . pow($g, 2) / 64); $p = 0; $q = 0; foreach (Math_PolynomialOp::getRootsCubic($cubic) as $p_or_q) { if ($p == 0 && $p_or_q != 0) { $p = sqrt($p_or_q); } else { if ($q == 0 && $p_or_q != 0) { $q = sqrt($p_or_q); } } } if ($p != 0 && $q != 0) { $r = -1 * $g / (8 * $p * $q); $s = $b / (4 * $a); $arr[] = $p + $q + $r - $s; $arr[] = $p - $q - $r - $s; $arr[] = -1 * $p + $q - $r - $s; $arr[] = -1 * $p - $q + $r - $s; } return Math_PolynomialOp::_round($arr); } else { return PEAR::raiseError('Parameter to Math_PolynomialOp::getRootsQuartic() is not quartic.'); } }
function testGetRootsCubic() { $p = new Math_Polynomial('x - 6'); $p = Math_PolynomialOp::mul($p, 'x + 1'); $p = Math_PolynomialOp::mul($p, 'x - 3'); $roots = Math_PolynomialOp::getRootsCubic($p); $this->assertEquals(array(6, -1, 3), $roots); }