389 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			389 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
| 
								 | 
							
								<?php
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Class for the management of Complex numbers
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @copyright  Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
							 | 
						||
| 
								 | 
							
								 * @license    https://opensource.org/licenses/MIT    MIT
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								namespace Complex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Complex Number object.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package Complex
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @method float abs()
							 | 
						||
| 
								 | 
							
								 * @method Complex acos()
							 | 
						||
| 
								 | 
							
								 * @method Complex acosh()
							 | 
						||
| 
								 | 
							
								 * @method Complex acot()
							 | 
						||
| 
								 | 
							
								 * @method Complex acoth()
							 | 
						||
| 
								 | 
							
								 * @method Complex acsc()
							 | 
						||
| 
								 | 
							
								 * @method Complex acsch()
							 | 
						||
| 
								 | 
							
								 * @method float argument()
							 | 
						||
| 
								 | 
							
								 * @method Complex asec()
							 | 
						||
| 
								 | 
							
								 * @method Complex asech()
							 | 
						||
| 
								 | 
							
								 * @method Complex asin()
							 | 
						||
| 
								 | 
							
								 * @method Complex asinh()
							 | 
						||
| 
								 | 
							
								 * @method Complex atan()
							 | 
						||
| 
								 | 
							
								 * @method Complex atanh()
							 | 
						||
| 
								 | 
							
								 * @method Complex conjugate()
							 | 
						||
| 
								 | 
							
								 * @method Complex cos()
							 | 
						||
| 
								 | 
							
								 * @method Complex cosh()
							 | 
						||
| 
								 | 
							
								 * @method Complex cot()
							 | 
						||
| 
								 | 
							
								 * @method Complex coth()
							 | 
						||
| 
								 | 
							
								 * @method Complex csc()
							 | 
						||
| 
								 | 
							
								 * @method Complex csch()
							 | 
						||
| 
								 | 
							
								 * @method Complex exp()
							 | 
						||
| 
								 | 
							
								 * @method Complex inverse()
							 | 
						||
| 
								 | 
							
								 * @method Complex ln()
							 | 
						||
| 
								 | 
							
								 * @method Complex log2()
							 | 
						||
| 
								 | 
							
								 * @method Complex log10()
							 | 
						||
| 
								 | 
							
								 * @method Complex negative()
							 | 
						||
| 
								 | 
							
								 * @method Complex pow(int|float $power)
							 | 
						||
| 
								 | 
							
								 * @method float rho()
							 | 
						||
| 
								 | 
							
								 * @method Complex sec()
							 | 
						||
| 
								 | 
							
								 * @method Complex sech()
							 | 
						||
| 
								 | 
							
								 * @method Complex sin()
							 | 
						||
| 
								 | 
							
								 * @method Complex sinh()
							 | 
						||
| 
								 | 
							
								 * @method Complex sqrt()
							 | 
						||
| 
								 | 
							
								 * @method Complex tan()
							 | 
						||
| 
								 | 
							
								 * @method Complex tanh()
							 | 
						||
| 
								 | 
							
								 * @method float theta()
							 | 
						||
| 
								 | 
							
								 * @method Complex add(...$complexValues)
							 | 
						||
| 
								 | 
							
								 * @method Complex subtract(...$complexValues)
							 | 
						||
| 
								 | 
							
								 * @method Complex multiply(...$complexValues)
							 | 
						||
| 
								 | 
							
								 * @method Complex divideby(...$complexValues)
							 | 
						||
| 
								 | 
							
								 * @method Complex divideinto(...$complexValues)
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Complex
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @constant    Euler's Number.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    const EULER = 2.7182818284590452353602874713526624977572;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @constant    Regexp to split an input string into real and imaginary components and suffix
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    const NUMBER_SPLIT_REGEXP =
							 | 
						||
| 
								 | 
							
								        '` ^
							 | 
						||
| 
								 | 
							
								            (                                   # Real part
							 | 
						||
| 
								 | 
							
								                [-+]?(\d+\.?\d*|\d*\.?\d+)          # Real value (integer or float)
							 | 
						||
| 
								 | 
							
								                ([Ee][-+]?[0-2]?\d{1,3})?           # Optional real exponent for scientific format
							 | 
						||
| 
								 | 
							
								            )
							 | 
						||
| 
								 | 
							
								            (                                   # Imaginary part
							 | 
						||
| 
								 | 
							
								                [-+]?(\d+\.?\d*|\d*\.?\d+)          # Imaginary value (integer or float)
							 | 
						||
| 
								 | 
							
								                ([Ee][-+]?[0-2]?\d{1,3})?           # Optional imaginary exponent for scientific format
							 | 
						||
| 
								 | 
							
								            )?
							 | 
						||
| 
								 | 
							
								            (                                   # Imaginary part is optional
							 | 
						||
| 
								 | 
							
								                ([-+]?)                             # Imaginary (implicit 1 or -1) only
							 | 
						||
| 
								 | 
							
								                ([ij]?)                             # Imaginary i or j - depending on whether mathematical or engineering
							 | 
						||
| 
								 | 
							
								            )
							 | 
						||
| 
								 | 
							
								        $`uix';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @var    float    $realPart    The value of of this complex number on the real plane.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected $realPart = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @var    float    $imaginaryPart    The value of of this complex number on the imaginary plane.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected $imaginaryPart = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @var    string    $suffix    The suffix for this complex number (i or j).
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected $suffix;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Validates whether the argument is a valid complex number, converting scalar or array values if possible
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param     mixed    $complexNumber   The value to parse
							 | 
						||
| 
								 | 
							
								     * @return    array
							 | 
						||
| 
								 | 
							
								     * @throws    Exception    If the argument isn't a Complex number or cannot be converted to one
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    private static function parseComplex($complexNumber)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // Test for real number, with no imaginary part
							 | 
						||
| 
								 | 
							
								        if (is_numeric($complexNumber)) {
							 | 
						||
| 
								 | 
							
								            return [$complexNumber, 0, null];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Fix silly human errors
							 | 
						||
| 
								 | 
							
								        $complexNumber = str_replace(
							 | 
						||
| 
								 | 
							
								            ['+-', '-+', '++', '--'],
							 | 
						||
| 
								 | 
							
								            ['-', '-', '+', '+'],
							 | 
						||
| 
								 | 
							
								            $complexNumber
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Basic validation of string, to parse out real and imaginary parts, and any suffix
							 | 
						||
| 
								 | 
							
								        $validComplex = preg_match(
							 | 
						||
| 
								 | 
							
								            self::NUMBER_SPLIT_REGEXP,
							 | 
						||
| 
								 | 
							
								            $complexNumber,
							 | 
						||
| 
								 | 
							
								            $complexParts
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!$validComplex) {
							 | 
						||
| 
								 | 
							
								            // Neither real nor imaginary part, so test to see if we actually have a suffix
							 | 
						||
| 
								 | 
							
								            $validComplex = preg_match('/^([\-\+]?)([ij])$/ui', $complexNumber, $complexParts);
							 | 
						||
| 
								 | 
							
								            if (!$validComplex) {
							 | 
						||
| 
								 | 
							
								                throw new Exception('Invalid complex number');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            // We have a suffix, so set the real to 0, the imaginary to either 1 or -1 (as defined by the sign)
							 | 
						||
| 
								 | 
							
								            $imaginary = 1;
							 | 
						||
| 
								 | 
							
								            if ($complexParts[1] === '-') {
							 | 
						||
| 
								 | 
							
								                $imaginary = 0 - $imaginary;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return [0, $imaginary, $complexParts[2]];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // If we don't have an imaginary part, identify whether it should be +1 or -1...
							 | 
						||
| 
								 | 
							
								        if (($complexParts[4] === '') && ($complexParts[9] !== '')) {
							 | 
						||
| 
								 | 
							
								            if ($complexParts[7] !== $complexParts[9]) {
							 | 
						||
| 
								 | 
							
								                $complexParts[4] = 1;
							 | 
						||
| 
								 | 
							
								                if ($complexParts[8] === '-') {
							 | 
						||
| 
								 | 
							
								                    $complexParts[4] = -1;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                // ... or if we have only the real and no imaginary part
							 | 
						||
| 
								 | 
							
								                //  (in which case our real should be the imaginary)
							 | 
						||
| 
								 | 
							
								                $complexParts[4] = $complexParts[1];
							 | 
						||
| 
								 | 
							
								                $complexParts[1] = 0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Return real and imaginary parts and suffix as an array, and set a default suffix if user input lazily
							 | 
						||
| 
								 | 
							
								        return [
							 | 
						||
| 
								 | 
							
								            $complexParts[1],
							 | 
						||
| 
								 | 
							
								            $complexParts[4],
							 | 
						||
| 
								 | 
							
								            !empty($complexParts[9]) ? $complexParts[9] : 'i'
							 | 
						||
| 
								 | 
							
								        ];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function __construct($realPart = 0.0, $imaginaryPart = null, $suffix = 'i')
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ($imaginaryPart === null) {
							 | 
						||
| 
								 | 
							
								            if (is_array($realPart)) {
							 | 
						||
| 
								 | 
							
								                // We have an array of (potentially) real and imaginary parts, and any suffix
							 | 
						||
| 
								 | 
							
								                list ($realPart, $imaginaryPart, $suffix) = array_values($realPart) + [0.0, 0.0, 'i'];
							 | 
						||
| 
								 | 
							
								            } elseif ((is_string($realPart)) || (is_numeric($realPart))) {
							 | 
						||
| 
								 | 
							
								                // We've been given a string to parse to extract the real and imaginary parts, and any suffix
							 | 
						||
| 
								 | 
							
								                list($realPart, $imaginaryPart, $suffix) = self::parseComplex($realPart);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($imaginaryPart != 0.0 && empty($suffix)) {
							 | 
						||
| 
								 | 
							
								            $suffix = 'i';
							 | 
						||
| 
								 | 
							
								        } elseif ($imaginaryPart == 0.0 && !empty($suffix)) {
							 | 
						||
| 
								 | 
							
								            $suffix = '';
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Set parsed values in our properties
							 | 
						||
| 
								 | 
							
								        $this->realPart = (float) $realPart;
							 | 
						||
| 
								 | 
							
								        $this->imaginaryPart = (float) $imaginaryPart;
							 | 
						||
| 
								 | 
							
								        $this->suffix = strtolower($suffix ?? '');
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Gets the real part of this complex number
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return Float
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function getReal(): float
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->realPart;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Gets the imaginary part of this complex number
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return Float
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function getImaginary(): float
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->imaginaryPart;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Gets the suffix of this complex number
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return String
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function getSuffix(): string
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->suffix;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Returns true if this is a real value, false if a complex value
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return Bool
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function isReal(): bool
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->imaginaryPart == 0.0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Returns true if this is a complex value, false if a real value
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return Bool
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function isComplex(): bool
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return !$this->isReal();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function format(): string
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $str = "";
							 | 
						||
| 
								 | 
							
								        if ($this->imaginaryPart != 0.0) {
							 | 
						||
| 
								 | 
							
								            if (\abs($this->imaginaryPart) != 1.0) {
							 | 
						||
| 
								 | 
							
								                $str .= $this->imaginaryPart . $this->suffix;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                $str .= (($this->imaginaryPart < 0.0) ? '-' : '') . $this->suffix;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if ($this->realPart != 0.0) {
							 | 
						||
| 
								 | 
							
								            if (($str) && ($this->imaginaryPart > 0.0)) {
							 | 
						||
| 
								 | 
							
								                $str = "+" . $str;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            $str = $this->realPart . $str;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (!$str) {
							 | 
						||
| 
								 | 
							
								            $str = "0.0";
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $str;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function __toString(): string
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->format();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Validates whether the argument is a valid complex number, converting scalar or array values if possible
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param     mixed    $complex   The value to validate
							 | 
						||
| 
								 | 
							
								     * @return    Complex
							 | 
						||
| 
								 | 
							
								     * @throws    Exception    If the argument isn't a Complex number or cannot be converted to one
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static function validateComplexArgument($complex): Complex
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (is_scalar($complex) || is_array($complex)) {
							 | 
						||
| 
								 | 
							
								            $complex = new Complex($complex);
							 | 
						||
| 
								 | 
							
								        } elseif (!is_object($complex) || !($complex instanceof Complex)) {
							 | 
						||
| 
								 | 
							
								            throw new Exception('Value is not a valid complex number');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $complex;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Returns the reverse of this complex number
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return    Complex
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function reverse(): Complex
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return new Complex(
							 | 
						||
| 
								 | 
							
								            $this->imaginaryPart,
							 | 
						||
| 
								 | 
							
								            $this->realPart,
							 | 
						||
| 
								 | 
							
								            ($this->realPart == 0.0) ? null : $this->suffix
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function invertImaginary(): Complex
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return new Complex(
							 | 
						||
| 
								 | 
							
								            $this->realPart,
							 | 
						||
| 
								 | 
							
								            $this->imaginaryPart * -1,
							 | 
						||
| 
								 | 
							
								            ($this->imaginaryPart == 0.0) ? null : $this->suffix
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function invertReal(): Complex
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return new Complex(
							 | 
						||
| 
								 | 
							
								            $this->realPart * -1,
							 | 
						||
| 
								 | 
							
								            $this->imaginaryPart,
							 | 
						||
| 
								 | 
							
								            ($this->imaginaryPart == 0.0) ? null : $this->suffix
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    protected static $functions = [
							 | 
						||
| 
								 | 
							
								        'abs',
							 | 
						||
| 
								 | 
							
								        'acos',
							 | 
						||
| 
								 | 
							
								        'acosh',
							 | 
						||
| 
								 | 
							
								        'acot',
							 | 
						||
| 
								 | 
							
								        'acoth',
							 | 
						||
| 
								 | 
							
								        'acsc',
							 | 
						||
| 
								 | 
							
								        'acsch',
							 | 
						||
| 
								 | 
							
								        'argument',
							 | 
						||
| 
								 | 
							
								        'asec',
							 | 
						||
| 
								 | 
							
								        'asech',
							 | 
						||
| 
								 | 
							
								        'asin',
							 | 
						||
| 
								 | 
							
								        'asinh',
							 | 
						||
| 
								 | 
							
								        'atan',
							 | 
						||
| 
								 | 
							
								        'atanh',
							 | 
						||
| 
								 | 
							
								        'conjugate',
							 | 
						||
| 
								 | 
							
								        'cos',
							 | 
						||
| 
								 | 
							
								        'cosh',
							 | 
						||
| 
								 | 
							
								        'cot',
							 | 
						||
| 
								 | 
							
								        'coth',
							 | 
						||
| 
								 | 
							
								        'csc',
							 | 
						||
| 
								 | 
							
								        'csch',
							 | 
						||
| 
								 | 
							
								        'exp',
							 | 
						||
| 
								 | 
							
								        'inverse',
							 | 
						||
| 
								 | 
							
								        'ln',
							 | 
						||
| 
								 | 
							
								        'log2',
							 | 
						||
| 
								 | 
							
								        'log10',
							 | 
						||
| 
								 | 
							
								        'negative',
							 | 
						||
| 
								 | 
							
								        'pow',
							 | 
						||
| 
								 | 
							
								        'rho',
							 | 
						||
| 
								 | 
							
								        'sec',
							 | 
						||
| 
								 | 
							
								        'sech',
							 | 
						||
| 
								 | 
							
								        'sin',
							 | 
						||
| 
								 | 
							
								        'sinh',
							 | 
						||
| 
								 | 
							
								        'sqrt',
							 | 
						||
| 
								 | 
							
								        'tan',
							 | 
						||
| 
								 | 
							
								        'tanh',
							 | 
						||
| 
								 | 
							
								        'theta',
							 | 
						||
| 
								 | 
							
								    ];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    protected static $operations = [
							 | 
						||
| 
								 | 
							
								        'add',
							 | 
						||
| 
								 | 
							
								        'subtract',
							 | 
						||
| 
								 | 
							
								        'multiply',
							 | 
						||
| 
								 | 
							
								        'divideby',
							 | 
						||
| 
								 | 
							
								        'divideinto',
							 | 
						||
| 
								 | 
							
								    ];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Returns the result of the function call or operation
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return    Complex|float
							 | 
						||
| 
								 | 
							
								     * @throws    Exception|\InvalidArgumentException
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function __call($functionName, $arguments)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $functionName = strtolower(str_replace('_', '', $functionName));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Test for function calls
							 | 
						||
| 
								 | 
							
								        if (in_array($functionName, self::$functions, true)) {
							 | 
						||
| 
								 | 
							
								            return Functions::$functionName($this, ...$arguments);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        // Test for operation calls
							 | 
						||
| 
								 | 
							
								        if (in_array($functionName, self::$operations, true)) {
							 | 
						||
| 
								 | 
							
								            return Operations::$functionName($this, ...$arguments);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        throw new Exception('Complex Function or Operation does not exist');
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |