| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823 | <?phpnamespace Complex;use InvalidArgumentException;class Functions{    /**     * Returns the absolute value (modulus) of a complex number.     * Also known as the rho of the complex number, i.e. the distance/radius     *   from the centrepoint to the representation of the number in polar coordinates.     *     * This function is a synonym for rho()     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    float            The absolute (or rho) value of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     *     * @see    rho     *     */    public static function abs($complex): float    {        return self::rho($complex);    }    /**     * Returns the inverse cosine of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The inverse cosine of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function acos($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        $invsqrt = self::sqrt(Operations::subtract(1, Operations::multiply($complex, $complex)));        $adjust = new Complex(            $complex->getReal() - $invsqrt->getImaginary(),            $complex->getImaginary() + $invsqrt->getReal()        );        $log = self::ln($adjust);        return new Complex(            $log->getImaginary(),            -1 * $log->getReal()        );    }    /**     * Returns the inverse hyperbolic cosine of a complex number.     *     * Formula from Wolfram Alpha:     *   cosh^(-1)z = ln(z + sqrt(z + 1) sqrt(z - 1)).     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The inverse hyperbolic cosine of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function acosh($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->isReal() && ($complex->getReal() > 1)) {            return new Complex(\acosh($complex->getReal()));        }        $acosh = self::ln(            Operations::add(                $complex,                Operations::multiply(                    self::sqrt(Operations::add($complex, 1)),                    self::sqrt(Operations::subtract($complex, 1))                )            )        );        return $acosh;    }    /**     * Returns the inverse cotangent of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The inverse cotangent of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function acot($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        return self::atan(self::inverse($complex));    }    /**     * Returns the inverse hyperbolic cotangent of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The inverse hyperbolic cotangent of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function acoth($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        return self::atanh(self::inverse($complex));    }    /**     * Returns the inverse cosecant of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The inverse cosecant of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function acsc($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {            return new Complex(INF);        }        return self::asin(self::inverse($complex));    }    /**     * Returns the inverse hyperbolic cosecant of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The inverse hyperbolic cosecant of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function acsch($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {            return new Complex(INF);        }        return self::asinh(self::inverse($complex));    }    /**     * Returns the argument of a complex number.     * Also known as the theta of the complex number, i.e. the angle in radians     *   from the real axis to the representation of the number in polar coordinates.     *     * This function is a synonym for theta()     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    float            The argument (or theta) value of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     *     * @see    theta     */    public static function argument($complex): float    {        return self::theta($complex);    }    /**     * Returns the inverse secant of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The inverse secant of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function asec($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {            return new Complex(INF);        }        return self::acos(self::inverse($complex));    }    /**     * Returns the inverse hyperbolic secant of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The inverse hyperbolic secant of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function asech($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {            return new Complex(INF);        }        return self::acosh(self::inverse($complex));    }    /**     * Returns the inverse sine of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The inverse sine of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function asin($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        $invsqrt = self::sqrt(Operations::subtract(1, Operations::multiply($complex, $complex)));        $adjust = new Complex(            $invsqrt->getReal() - $complex->getImaginary(),            $invsqrt->getImaginary() + $complex->getReal()        );        $log = self::ln($adjust);        return new Complex(            $log->getImaginary(),            -1 * $log->getReal()        );    }    /**     * Returns the inverse hyperbolic sine of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The inverse hyperbolic sine of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function asinh($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->isReal() && ($complex->getReal() > 1)) {            return new Complex(\asinh($complex->getReal()));        }        $asinh = clone $complex;        $asinh = $asinh->reverse()            ->invertReal();        $asinh = self::asin($asinh);        return $asinh->reverse()            ->invertImaginary();    }    /**     * Returns the inverse tangent of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The inverse tangent of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function atan($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->isReal()) {            return new Complex(\atan($complex->getReal()));        }        $t1Value = new Complex(-1 * $complex->getImaginary(), $complex->getReal());        $uValue = new Complex(1, 0);        $d1Value = clone $uValue;        $d1Value = Operations::subtract($d1Value, $t1Value);        $d2Value = Operations::add($t1Value, $uValue);        $uResult = $d1Value->divideBy($d2Value);        $uResult = self::ln($uResult);        $realMultiplier = -0.5;        $imaginaryMultiplier = 0.5;        if (abs($uResult->getImaginary()) === M_PI) {            // If we have an imaginary value at the max or min (PI or -PI), then we need to ensure            //    that the primary is assigned for the correct quadrant.            $realMultiplier = (                ($uResult->getImaginary() === M_PI && $uResult->getReal() > 0.0) ||                ($uResult->getImaginary() === -M_PI && $uResult->getReal() < 0.0)            ) ? 0.5 : -0.5;        }        return new Complex(            $uResult->getImaginary() * $realMultiplier,            $uResult->getReal() * $imaginaryMultiplier,            $complex->getSuffix()        );    }    /**     * Returns the inverse hyperbolic tangent of a complex number.     *     * Formula from Wolfram Alpha:     *  tanh^(-1)z = 1/2 [ln(1 + z) - ln(1 - z)].     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The inverse hyperbolic tangent of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function atanh($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->isReal()) {            $real = $complex->getReal();            if ($real >= -1.0 && $real <= 1.0) {                return new Complex(\atanh($real));            } else {                return new Complex(\atanh(1 / $real), (($real < 0.0) ? M_PI_2 : -1 * M_PI_2));            }        }        $atanh = Operations::multiply(            Operations::subtract(                self::ln(Operations::add(1.0, $complex)),                self::ln(Operations::subtract(1.0, $complex))            ),            0.5        );        return $atanh;    }    /**     * Returns the complex conjugate of a complex number     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The conjugate of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function conjugate($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        return new Complex(            $complex->getReal(),            -1 * $complex->getImaginary(),            $complex->getSuffix()        );    }    /**     * Returns the cosine of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The cosine of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function cos($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->isReal()) {            return new Complex(\cos($complex->getReal()));        }        return self::conjugate(            new Complex(                \cos($complex->getReal()) * \cosh($complex->getImaginary()),                \sin($complex->getReal()) * \sinh($complex->getImaginary()),                $complex->getSuffix()            )        );    }    /**     * Returns the hyperbolic cosine of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The hyperbolic cosine of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function cosh($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->isReal()) {            return new Complex(\cosh($complex->getReal()));        }        return new Complex(            \cosh($complex->getReal()) * \cos($complex->getImaginary()),            \sinh($complex->getReal()) * \sin($complex->getImaginary()),            $complex->getSuffix()        );    }    /**     * Returns the cotangent of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The cotangent of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function cot($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {            return new Complex(INF);        }        return self::inverse(self::tan($complex));    }    /**     * Returns the hyperbolic cotangent of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The hyperbolic cotangent of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function coth($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        return self::inverse(self::tanh($complex));    }    /**     * Returns the cosecant of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The cosecant of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function csc($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {            return new Complex(INF);        }        return self::inverse(self::sin($complex));    }    /**     * Returns the hyperbolic cosecant of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The hyperbolic cosecant of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function csch($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {            return new Complex(INF);        }        return self::inverse(self::sinh($complex));    }    /**     * Returns the exponential of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The exponential of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function exp($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if (($complex->getReal() == 0.0) && (\abs($complex->getImaginary()) == M_PI)) {            return new Complex(-1.0, 0.0);        }        $rho = \exp($complex->getReal());        return new Complex(            $rho * \cos($complex->getImaginary()),            $rho * \sin($complex->getImaginary()),            $complex->getSuffix()        );    }    /**     * Returns the inverse of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The inverse of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    InvalidArgumentException    If function would result in a division by zero     */    public static function inverse($complex): Complex    {        $complex = clone Complex::validateComplexArgument($complex);        if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {            throw new InvalidArgumentException('Division by zero');        }        return $complex->divideInto(1.0);    }    /**     * Returns the natural logarithm of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The natural logarithm of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    InvalidArgumentException  If the real and the imaginary parts are both zero     */    public static function ln($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if (($complex->getReal() == 0.0) && ($complex->getImaginary() == 0.0)) {            throw new InvalidArgumentException();        }        return new Complex(            \log(self::rho($complex)),            self::theta($complex),            $complex->getSuffix()        );    }    /**     * Returns the base-2 logarithm of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The base-2 logarithm of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    InvalidArgumentException  If the real and the imaginary parts are both zero     */    public static function log2($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if (($complex->getReal() == 0.0) && ($complex->getImaginary() == 0.0)) {            throw new InvalidArgumentException();        } elseif (($complex->getReal() > 0.0) && ($complex->getImaginary() == 0.0)) {            return new Complex(\log($complex->getReal(), 2), 0.0, $complex->getSuffix());        }        return self::ln($complex)            ->multiply(\log(Complex::EULER, 2));    }    /**     * Returns the common logarithm (base 10) of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The common logarithm (base 10) of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    InvalidArgumentException  If the real and the imaginary parts are both zero     */    public static function log10($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if (($complex->getReal() == 0.0) && ($complex->getImaginary() == 0.0)) {            throw new InvalidArgumentException();        } elseif (($complex->getReal() > 0.0) && ($complex->getImaginary() == 0.0)) {            return new Complex(\log10($complex->getReal()), 0.0, $complex->getSuffix());        }        return self::ln($complex)            ->multiply(\log10(Complex::EULER));    }    /**     * Returns the negative of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The negative value of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     *     * @see    rho     *     */    public static function negative($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        return new Complex(            -1 * $complex->getReal(),            -1 * $complex->getImaginary(),            $complex->getSuffix()        );    }    /**     * Returns a complex number raised to a power.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @param     float|integer    $power      The power to raise this value to     * @return    Complex          The complex argument raised to the real power.     * @throws    Exception        If the power argument isn't a valid real     */    public static function pow($complex, $power): Complex    {        $complex = Complex::validateComplexArgument($complex);        if (!is_numeric($power)) {            throw new Exception('Power argument must be a real number');        }        if ($complex->getImaginary() == 0.0 && $complex->getReal() >= 0.0) {            return new Complex(\pow($complex->getReal(), $power));        }        $rValue = \sqrt(($complex->getReal() * $complex->getReal()) + ($complex->getImaginary() * $complex->getImaginary()));        $rPower = \pow($rValue, $power);        $theta = $complex->argument() * $power;        if ($theta == 0) {            return new Complex(1);        }        return new Complex($rPower * \cos($theta), $rPower * \sin($theta), $complex->getSuffix());    }    /**     * Returns the rho of a complex number.     * This is the distance/radius from the centrepoint to the representation of the number in polar coordinates.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    float            The rho value of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function rho($complex): float    {        $complex = Complex::validateComplexArgument($complex);        return \sqrt(            ($complex->getReal() * $complex->getReal()) +            ($complex->getImaginary() * $complex->getImaginary())        );    }    /**     * Returns the secant of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The secant of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function sec($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        return self::inverse(self::cos($complex));    }    /**     * Returns the hyperbolic secant of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The hyperbolic secant of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function sech($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        return self::inverse(self::cosh($complex));    }    /**     * Returns the sine of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The sine of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function sin($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->isReal()) {            return new Complex(\sin($complex->getReal()));        }        return new Complex(            \sin($complex->getReal()) * \cosh($complex->getImaginary()),            \cos($complex->getReal()) * \sinh($complex->getImaginary()),            $complex->getSuffix()        );    }    /**     * Returns the hyperbolic sine of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The hyperbolic sine of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function sinh($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->isReal()) {            return new Complex(\sinh($complex->getReal()));        }        return new Complex(            \sinh($complex->getReal()) * \cos($complex->getImaginary()),            \cosh($complex->getReal()) * \sin($complex->getImaginary()),            $complex->getSuffix()        );    }    /**     * Returns the square root of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The Square root of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function sqrt($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        $theta = self::theta($complex);        $delta1 = \cos($theta / 2);        $delta2 = \sin($theta / 2);        $rho = \sqrt(self::rho($complex));        return new Complex($delta1 * $rho, $delta2 * $rho, $complex->getSuffix());    }    /**     * Returns the tangent of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The tangent of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    InvalidArgumentException    If function would result in a division by zero     */    public static function tan($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->isReal()) {            return new Complex(\tan($complex->getReal()));        }        $real = $complex->getReal();        $imaginary = $complex->getImaginary();        $divisor = 1 + \pow(\tan($real), 2) * \pow(\tanh($imaginary), 2);        if ($divisor == 0.0) {            throw new InvalidArgumentException('Division by zero');        }        return new Complex(            \pow(self::sech($imaginary)->getReal(), 2) * \tan($real) / $divisor,            \pow(self::sec($real)->getReal(), 2) * \tanh($imaginary) / $divisor,            $complex->getSuffix()        );    }    /**     * Returns the hyperbolic tangent of a complex number.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    Complex          The hyperbolic tangent of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     * @throws    \InvalidArgumentException    If function would result in a division by zero     */    public static function tanh($complex): Complex    {        $complex = Complex::validateComplexArgument($complex);        $real = $complex->getReal();        $imaginary = $complex->getImaginary();        $divisor = \cos($imaginary) * \cos($imaginary) + \sinh($real) * \sinh($real);        if ($divisor == 0.0) {            throw new InvalidArgumentException('Division by zero');        }        return new Complex(            \sinh($real) * \cosh($real) / $divisor,            0.5 * \sin(2 * $imaginary) / $divisor,            $complex->getSuffix()        );    }    /**     * Returns the theta of a complex number.     *   This is the angle in radians from the real axis to the representation of the number in polar coordinates.     *     * @param     Complex|mixed    $complex    Complex number or a numeric value.     * @return    float            The theta value of the complex argument.     * @throws    Exception        If argument isn't a valid real or complex number.     */    public static function theta($complex): float    {        $complex = Complex::validateComplexArgument($complex);        if ($complex->getReal() == 0.0) {            if ($complex->isReal()) {                return 0.0;            } elseif ($complex->getImaginary() < 0.0) {                return M_PI / -2;            }            return M_PI / 2;        } elseif ($complex->getReal() > 0.0) {            return \atan($complex->getImaginary() / $complex->getReal());        } elseif ($complex->getImaginary() < 0.0) {            return -(M_PI - \atan(\abs($complex->getImaginary()) / \abs($complex->getReal())));        }        return M_PI - \atan($complex->getImaginary() / \abs($complex->getReal()));    }}
 |