public function testCanEvaluateLog() { $this->assertResult('log(-1)', new Complex(0, pi())); $this->assertResult('log(x)', Complex::log($this->variables['x'])); }
/** * 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) { $z = $node->getOperand()->accept($this); $a = $z->r(); $b = $z->i(); switch ($node->getName()) { // Trigonometric functions case 'sin': return Complex::sin($z); case 'cos': return Complex::cos($z); case 'tan': return Complex::tan($z); case 'cot': return Complex::cot($z); // Inverse trigonometric functions // Inverse trigonometric functions case 'arcsin': return Complex::arcsin($z); case 'arccos': return Complex::arccos($z); case 'arctan': return Complex::arctan($z); case 'arccot': return Complex::arccot($z); case 'sinh': return Complex::sinh($z); case 'cosh': return Complex::cosh($z); case 'tanh': return Complex::tanh($z); case 'coth': return Complex::div(1, Complex::tanh($z)); case 'arsinh': return Complex::arsinh($z); case 'arcosh': return Complex::arcosh($z); case 'artanh': return Complex::artanh($z); case 'arcoth': return Complex::div(1, Complex::artanh($z)); case 'exp': return Complex::exp($z); case 'log': return Complex::log($z); case 'lg': return Complex::div(Complex::log($z), M_LN10); case 'sqrt': return Complex::sqrt($z); case 'abs': return new Complex($z->abs(), 0); case 'arg': return new Complex($z->arg(), 0); case 're': return new Complex($z->r(), 0); case 'im': return new Complex($z->i(), 0); case 'conj': return new Complex($z->r(), -$z->i()); default: throw new UnknownFunctionException($node->getName()); } return new FunctionNode($node->getName(), $inner); }
public function testCanComputeTranscendentals() { $z = new Complex(1, 2); $accuracy = 1.0E-9; $this->assertEquals(new Complex(1.27201965, 0.7861513778), Complex::sqrt($z), 'sqrt', $accuracy); $this->assertEquals(new Complex(3.165778513, 1.959601041), Complex::sin($z), 'sin', $accuracy); $this->assertEquals(new Complex(2.032723007, -3.051897799), Complex::cos($z), 'cos', $accuracy); $this->assertEquals(new Complex(0.03381282608, 1.014793616), Complex::tan($z), 'tan', $accuracy); $this->assertEquals(new Complex(0.03279775553, -0.9843292265), Complex::cot($z), 'cot', $accuracy); $this->assertEquals(new Complex(0.4270785864, 1.528570919), Complex::arcsin($z), 'arcsin', $accuracy); $this->assertEquals(new Complex(1.14371774, -1.528570919), Complex::arccos($z), 'arccos', $accuracy); $this->assertEquals(new Complex(1.338972522, 0.4023594781), Complex::arctan($z), 'arctan', $accuracy); $this->assertEquals(new Complex(0.2318238045, -0.4023594781), Complex::arccot($z), 'arccot', $accuracy); $this->assertEquals(new Complex(-1.131204384, 2.471726672), Complex::exp($z), 'exp', $accuracy); $this->assertEquals(new Complex(0.8047189562, 1.107148718), Complex::log($z), 'log', $accuracy); $this->assertEquals(new Complex(-0.489056259, 1.403119251), Complex::sinh($z), 'sinh', $accuracy); $this->assertEquals(new Complex(-0.6421481247, 1.068607421), Complex::cosh($z), 'cosh', $accuracy); $this->assertEquals(new Complex(1.166736257, -0.2434582012), Complex::tanh($z), 'tanh', $accuracy); $this->assertEquals(new Complex(1.469351744, 1.063440024), Complex::arsinh($z), 'arsinh', $accuracy); $this->assertEquals(new Complex(1.528570919, 1.14371774), Complex::arcosh($z), 'arcosh', $accuracy); $this->assertEquals(new Complex(0.1732867951, 1.178097245), Complex::artanh($z), 'artanh', $accuracy); }