<?php
namespace 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()));
}
}
Service Section
Discover how our services are designed to enhance your NFC Pay experience with convenience, security, and innovative solutions. From managing transactions to secure payments, we are dedicated to providing seamless support every step of the way.
Easily save your credit and debit card details within our app for quick and secure transactions. This feature ensures that your payment information is protected with advanced encryption and can be used for future purchases with just a tap.
Transfer funds quickly and securely between users with our streamlined money transfer service. Simply select the recipient, enter the amount, and authorize the transaction for instant, hassle-free transfers.
Activate your merchant account effortlessly to start receiving payments. Our intuitive setup process ensures that you can begin accepting transactions smoothly, helping your business thrive with minimal setup time.
Keep track of all your transactions in real time through our app. Monitor payment statuses, view transaction history, and manage your account efficiently, ensuring complete control over your financial activities.
Our dedicated support team is available to assist you with any queries or issues. Whether you need help with setting up your account or resolving transaction-related questions, we’re here to provide prompt and reliable assistance.