Example #1
0
 public function testSemiFactorial()
 {
     $this->assertEquals(1, Math::SemiFactorial(0));
     $this->assertEquals(1, Math::SemiFactorial(1));
     $this->assertEquals(2, Math::SemiFactorial(2));
     $this->assertEquals(3, Math::SemiFactorial(3));
     $this->assertEquals(8, Math::SemiFactorial(4));
     $this->assertEquals(15, Math::SemiFactorial(5));
     $this->assertEquals(48, Math::SemiFactorial(6));
     $this->assertEquals(105, Math::SemiFactorial(7));
 }
Example #2
0
 /**
  * Normalize, i.e. make sure the denominator is positive and that
  * the numerator and denominator have no common factors
  */
 private function normalize()
 {
     $gcd = Math::gcd($this->p, $this->q);
     if ($gcd == 0) {
         throw new DivisionByZeroException();
     }
     $this->p = $this->p / $gcd;
     $this->q = $this->q / $gcd;
     if ($this->q < 0) {
         $this->p = -$this->p;
         $this->q = -$this->q;
     }
 }
 /**
  * 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':
         case 'cos':
         case 'tan':
         case 'cot':
         case 'arcsin':
         case 'arccos':
         case 'arctan':
         case 'arccot':
         case 'exp':
         case 'log':
         case 'lg':
         case 'sinh':
         case 'cosh':
         case 'tanh':
         case 'coth':
         case 'arsinh':
         case 'arcosh':
         case 'artanh':
         case 'arcoth':
             throw new \UnexpectedValueException("Expecting rational expression");
         case 'abs':
             return new RationalNode(abs($inner->getNumerator()), $inner->getDenominator());
         case 'sgn':
             if ($inner->getNumerator() >= 0) {
                 return new RationalNode(1, 0);
             } else {
                 return new RationalNode(-1, 0);
             }
             // Powers
         // Powers
         case 'sqrt':
             return $this->rpow($inner, new RationalNode(1, 2));
         case '!':
             if ($inner->getDenominator() == 1 && $inner->getNumerator() >= 0) {
                 return new RationalNode(Math::Factorial($inner->getNumerator()), 1);
             }
             throw new \UnexpectedValueException("Expecting positive integer (factorial)");
         case '!!':
             if ($inner->getDenominator() == 1 && $inner->getNumerator() >= 0) {
                 return new RationalNode(Math::SemiFactorial($inner->getNumerator()), 1);
             }
             throw new \UnexpectedValueException("Expecting positive integer (factorial)");
         default:
             throw new UnknownFunctionException($node->getName());
     }
 }
Example #4
0
 /**
  * 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());
     }
 }