Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 116 additions & 9 deletions src/MathParser/Interpreting/Evaluator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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':
Expand All @@ -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':
Expand All @@ -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);
Expand All @@ -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':
Expand All @@ -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);

Expand Down
20 changes: 20 additions & 0 deletions src/MathParser/Lexing/StdMathLexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'));
Expand Down