From 17bc4ba52590099a3c98635ecf7dfade6cb56a3e Mon Sep 17 00:00:00 2001 From: Vincent LaBella Date: Mon, 18 Apr 2022 07:49:14 -0400 Subject: [PATCH] addition of several trig functions csch, sech, cscd, secd, csc, sec, arccsch arcsech, arcsind, arccosd, arctand, arccotd, arccscd, arcsecd, arccsc, arcsec, todeeg, torad --- src/MathParser/Interpreting/Evaluator.php | 125 ++++++++++++++++++++-- src/MathParser/Lexing/StdMathLexer.php | 20 ++++ 2 files changed, 136 insertions(+), 9 deletions(-) diff --git a/src/MathParser/Interpreting/Evaluator.php b/src/MathParser/Interpreting/Evaluator.php index 67e3d5c..bb4ff43 100644 --- a/src/MathParser/Interpreting/Evaluator.php +++ b/src/MathParser/Interpreting/Evaluator.php @@ -205,12 +205,28 @@ public function visitFunctionNode(FunctionNode $node) return tan($inner); case 'cot': - $tan_inner = tan($inner); - if ($tan_inner == 0) { + $_inner = tan($inner); + if ($_inner == 0) { return NAN; } - return 1 / $tan_inner; + return 1 / $_inner; + + case 'sec': + $_inner = cos($inner); + if ($_inner == 0) { + return NAN; + } + + return 1 / $_inner; + + case 'csc': + $_inner = sin($inner); + if ($_inner == 0) { + return NAN; + } + + return 1 / $_inner; // Trigonometric functions, argument in degrees case 'sind': @@ -223,12 +239,28 @@ public function visitFunctionNode(FunctionNode $node) return tan(deg2rad($inner)); case 'cotd': - $tan_inner = tan(deg2rad($inner)); - if ($tan_inner == 0) { + $_inner = tan(deg2rad($inner)); + if ($_inner == 0) { + return NAN; + } + + return 1 / $_inner; + + case 'secd': + $_inner = cos(deg2rad($inner)); + if ($_inner == 0) { return NAN; } - return 1 / $tan_inner; + return 1 / $_inner; + + case 'cscd': + $_inner = sin(deg2rad($inner)); + if ($_inner == 0) { + return NAN; + } + + return 1 / $_inner; // Inverse trigonometric functions case 'arcsin': @@ -243,6 +275,50 @@ public function visitFunctionNode(FunctionNode $node) case 'arccot': return pi() / 2 - atan($inner); + case 'arcsec': + if ($inner == 0) { + return NAN; + } + return acos(1/$inner); + + case 'arccsc': + if ($inner == 0) { + return NAN; + } + return asin(1/$inner); + + // Inverse trigonometric functions - returns answer in degrees + case 'arcsind': + return rad2deg(asin($inner)); + + case 'arccosd': + return rad2deg(acos($inner)); + + case 'arctand': + return rad2deg(atan($inner)); + + case 'arccotd': + return rad2deg(pi() / 2 - atan($inner)); + + case 'arcsecd': + if ($inner == 0) { + return NAN; + } + return rad2deg(acos(1/$inner)); + + case 'arccscd': + if ($inner == 0) { + return NAN; + } + return rad2deg(asin(1/$inner)); + + // radians to degree conversion functions + case 'torad': + return deg2rad($inner); + + case 'todeg': + return rad2deg($inner); + // Exponentials and logarithms case 'exp': return exp($inner); @@ -269,12 +345,28 @@ public function visitFunctionNode(FunctionNode $node) return tanh($inner); case 'coth': - $tanh_inner = tanh($inner); - if ($tanh_inner == 0) { + $_inner = tanh($inner); + if ($_inner == 0) { + return NAN; + } + + return 1 / $_inner; + + case 'sech': + $_inner = cosh($inner); + if ($_inner == 0) { return NAN; } - return 1 / $tanh_inner; + return 1 / $_inner; + + case 'csch': + $_inner = sinh($inner); + if ($_inner == 0) { + return NAN; + } + + return 1 / $_inner; // Inverse hyperbolic functions case 'arsinh': @@ -287,8 +379,23 @@ public function visitFunctionNode(FunctionNode $node) return atanh($inner); case 'arcoth': + if ($inner == 0) { + return NAN; + } return atanh(1 / $inner); + case 'arcsch': + if ($inner == 0) { + return NAN; + } + return asinh(1 / $inner); + + case 'arcsech': + if ($inner == 0) { + return NAN; + } + return acosh(1 / $inner); + case 'abs': return abs($inner); diff --git a/src/MathParser/Lexing/StdMathLexer.php b/src/MathParser/Lexing/StdMathLexer.php index afef4be..8a6babe 100644 --- a/src/MathParser/Lexing/StdMathLexer.php +++ b/src/MathParser/Lexing/StdMathLexer.php @@ -83,26 +83,46 @@ public function __construct() $this->add(new TokenDefinition('/cosh/', TokenType::FunctionName)); $this->add(new TokenDefinition('/tanh/', TokenType::FunctionName)); $this->add(new TokenDefinition('/coth/', TokenType::FunctionName)); + $this->add(new TokenDefinition('/csch/', TokenType::FunctionName)); + $this->add(new TokenDefinition('/sech/', TokenType::FunctionName)); $this->add(new TokenDefinition('/sind/', TokenType::FunctionName)); $this->add(new TokenDefinition('/cosd/', TokenType::FunctionName)); $this->add(new TokenDefinition('/tand/', TokenType::FunctionName)); $this->add(new TokenDefinition('/cotd/', TokenType::FunctionName)); + $this->add(new TokenDefinition('/cscd/', TokenType::FunctionName)); + $this->add(new TokenDefinition('/secd/', TokenType::FunctionName)); $this->add(new TokenDefinition('/sin/', TokenType::FunctionName)); $this->add(new TokenDefinition('/cos/', TokenType::FunctionName)); $this->add(new TokenDefinition('/tan/', TokenType::FunctionName)); $this->add(new TokenDefinition('/cot/', TokenType::FunctionName)); + $this->add(new TokenDefinition('/csc/', TokenType::FunctionName)); + $this->add(new TokenDefinition('/sec/', TokenType::FunctionName)); $this->add(new TokenDefinition('/arsinh|arcsinh|asinh/', TokenType::FunctionName, 'arsinh')); $this->add(new TokenDefinition('/arcosh|arccosh|acosh/', TokenType::FunctionName, 'arcosh')); $this->add(new TokenDefinition('/artanh|arctanh|atanh/', TokenType::FunctionName, 'artanh')); $this->add(new TokenDefinition('/arcoth|arccoth|acoth/', TokenType::FunctionName, 'arcoth')); + $this->add(new TokenDefinition('/arcsch|arccsch|acsch/', TokenType::FunctionName, 'arcsch')); + $this->add(new TokenDefinition('/arsech|arcsech|asech/', TokenType::FunctionName, 'arcsec')); + + $this->add(new TokenDefinition('/arcsind|asind/', TokenType::FunctionName, 'arcsind')); + $this->add(new TokenDefinition('/arccosd|acosd/', TokenType::FunctionName, 'arccosd')); + $this->add(new TokenDefinition('/arctand|atand/', TokenType::FunctionName, 'arctand')); + $this->add(new TokenDefinition('/arccotd|acotd/', TokenType::FunctionName, 'arccotd')); + $this->add(new TokenDefinition('/arccscd|acscd/', TokenType::FunctionName, 'arccscd')); + $this->add(new TokenDefinition('/arcsecd|asecd/', TokenType::FunctionName, 'arcsecd')); $this->add(new TokenDefinition('/arcsin|asin/', TokenType::FunctionName, 'arcsin')); $this->add(new TokenDefinition('/arccos|acos/', TokenType::FunctionName, 'arccos')); $this->add(new TokenDefinition('/arctan|atan/', TokenType::FunctionName, 'arctan')); $this->add(new TokenDefinition('/arccot|acot/', TokenType::FunctionName, 'arccot')); + $this->add(new TokenDefinition('/arccsc|acsc/', TokenType::FunctionName, 'arccsc')); + $this->add(new TokenDefinition('/arcsec|asec/', TokenType::FunctionName, 'arcsec')); + + $this->add(new TokenDefinition('/torad|deg2rad/', TokenType::FunctionName, 'torad')); + $this->add(new TokenDefinition('/todeg|rad2deg/', TokenType::FunctionName, 'todeg')); $this->add(new TokenDefinition('/exp/', TokenType::FunctionName)); $this->add(new TokenDefinition('/log10|lg/', TokenType::FunctionName, 'lg'));