public function testLogGamma() { $this->assertEquals(857.9336698, Math::logGamma(200), '', 3.0E-7); $this->assertEquals(log(120), Math::logGamma(6), '', 3.0E-9); $this->assertEquals(3.9578139676187, Math::logGamma(5.5), '', 3.0E-9); }
/** * Evaluate a FunctionNode * * Computes the value of a FunctionNode `f(x)`, where f is * an elementary function recognized by StdMathLexer and StdMathParser. * * @see \MathParser\Lexer\StdMathLexer StdMathLexer * @see \MathParser\StdMathParser StdMathParser * @throws UnknownFunctionException if the function respresented by the * FunctionNode is *not* recognized. * * @param FunctionNode $node AST to be evaluated * @retval float */ public function visitFunctionNode(FunctionNode $node) { $inner = $node->getOperand()->accept($this); switch ($node->getName()) { // Trigonometric functions case 'sin': return sin($inner); case 'cos': return cos($inner); case 'tan': return tan($inner); case 'cot': return 1 / tan($inner); // Trigonometric functions, argument in degrees // Trigonometric functions, argument in degrees case 'sind': return sin(deg2rad($inner)); case 'cosd': return cos(deg2rad($inner)); case 'tand': return tan(deg2rad($inner)); case 'cotd': return 1 / tan(deg2rad($inner)); // Inverse trigonometric functions // Inverse trigonometric functions case 'arcsin': return asin($inner); case 'arccos': return acos($inner); case 'arctan': return atan($inner); case 'arccot': return pi() / 2 - atan($inner); // Exponentials and logarithms // Exponentials and logarithms case 'exp': return exp($inner); case 'log': return log($inner); case 'lg': return log10($inner); // Powers // Powers case 'sqrt': return sqrt($inner); // Hyperbolic functions // Hyperbolic functions case 'sinh': return sinh($inner); case 'cosh': return cosh($inner); case 'tanh': return tanh($inner); case 'coth': return 1 / tanh($inner); // Inverse hyperbolic functions // Inverse hyperbolic functions case 'arsinh': return asinh($inner); case 'arcosh': return acosh($inner); case 'artanh': return atanh($inner); case 'arcoth': return atanh(1 / $inner); case 'abs': return abs($inner); case 'sgn': return $inner >= 0 ? 1 : 0; case '!': $logGamma = Math::logGamma(1 + $inner); return exp($logGamma); case '!!': if (round($inner) != $inner) { throw new \UnexpectedValueException("Expecting positive integer (semifactorial)"); } return Math::SemiFactorial($inner); default: throw new UnknownFunctionException($node->getName()); } }