commitall

This commit is contained in:
Sampanna Rimal
2024-07-10 18:28:19 +05:45
parent 140abda4e6
commit 9cd05ef3cb
15723 changed files with 4818733 additions and 0 deletions

View File

@ -0,0 +1,153 @@
name: main
on: [ push, pull_request ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
experimental:
- false
php-version:
- '7.2'
- '7.3'
- '7.4'
- '8.0'
- '8.1'
- '8.2'
include:
- php-version: 'nightly'
experimental: true
name: PHP ${{ matrix.php-version }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup PHP, with composer and extensions
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
coverage: none
- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache composer dependencies
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Delete composer lock file
id: composer-lock
if: ${{ matrix.php-version == '8.0' || matrix.php-version == '8.1' || matrix.php-version == '8.2' || matrix.php-version == 'nightly' }}
run: |
rm composer.lock
echo "::set-output name=flags::--ignore-platform-reqs"
- name: Install dependencies
run: composer update --no-progress --prefer-dist --optimize-autoloader ${{ steps.composer-lock.outputs.flags }}
- name: Setup problem matchers for PHP
run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"
- name: Setup problem matchers for PHPUnit
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
- name: "Run PHPUnit tests (Experimental: ${{ matrix.experimental }})"
env:
FAILURE_ACTION: "${{ matrix.experimental == true }}"
run: vendor/bin/phpunit --verbose || $FAILURE_ACTION
phpcs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup PHP, with composer and extensions
uses: shivammathur/setup-php@v2
with:
php-version: 7.4
coverage: none
tools: cs2pr
- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache composer dependencies
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install dependencies
run: composer install --no-progress --prefer-dist --optimize-autoloader
- name: Code style with PHP_CodeSniffer
run: ./vendor/bin/phpcs -q --report=checkstyle classes/src/ | cs2pr
versions:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup PHP, with composer and extensions
uses: shivammathur/setup-php@v2
with:
php-version: 7.4
coverage: none
tools: cs2pr
- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache composer dependencies
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install dependencies
run: composer install --no-progress --prefer-dist --optimize-autoloader
- name: Code Version Compatibility check with PHP_CodeSniffer
run: ./vendor/bin/phpcs -q --report-width=200 --report=summary,full classes/src/ --standard=PHPCompatibility --runtime-set testVersion 7.2-
coverage:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup PHP, with composer and extensions
uses: shivammathur/setup-php@v2
with:
php-version: 7.4
coverage: pcov
- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache composer dependencies
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install dependencies
run: composer install --no-progress --prefer-dist --optimize-autoloader
- name: Test Coverage
run: ./vendor/bin/phpunit --verbose --coverage-text

173
vendor/markbaker/complex/README.md vendored Normal file
View File

@ -0,0 +1,173 @@
PHPComplex
==========
---
PHP Class Library for working with Complex numbers
[![Build Status](https://github.com/MarkBaker/PHPComplex/workflows/main/badge.svg)](https://github.com/MarkBaker/PHPComplex/actions)
[![Total Downloads](https://img.shields.io/packagist/dt/markbaker/complex)](https://packagist.org/packages/markbaker/complex)
[![Latest Stable Version](https://img.shields.io/github/v/release/MarkBaker/PHPComplex)](https://packagist.org/packages/markbaker/complex)
[![License](https://img.shields.io/github/license/MarkBaker/PHPComplex)](https://packagist.org/packages/markbaker/complex)
[![Complex Numbers](https://imgs.xkcd.com/comics/complex_numbers_2x.png)](https://xkcd.com/2028/)
---
The library currently provides the following operations:
- addition
- subtraction
- multiplication
- division
- division by
- division into
together with functions for
- theta (polar theta angle)
- rho (polar distance/radius)
- conjugate
* negative
- inverse (1 / complex)
- cos (cosine)
- acos (inverse cosine)
- cosh (hyperbolic cosine)
- acosh (inverse hyperbolic cosine)
- sin (sine)
- asin (inverse sine)
- sinh (hyperbolic sine)
- asinh (inverse hyperbolic sine)
- sec (secant)
- asec (inverse secant)
- sech (hyperbolic secant)
- asech (inverse hyperbolic secant)
- csc (cosecant)
- acsc (inverse cosecant)
- csch (hyperbolic secant)
- acsch (inverse hyperbolic secant)
- tan (tangent)
- atan (inverse tangent)
- tanh (hyperbolic tangent)
- atanh (inverse hyperbolic tangent)
- cot (cotangent)
- acot (inverse cotangent)
- coth (hyperbolic cotangent)
- acoth (inverse hyperbolic cotangent)
- sqrt (square root)
- exp (exponential)
- ln (natural log)
- log10 (base-10 log)
- log2 (base-2 log)
- pow (raised to the power of a real number)
---
# Installation
```shell
composer require markbaker/complex:^1.0
```
# Important BC Note
If you've previously been using procedural calls to functions and operations using this library, then from version 3.0 you should use [MarkBaker/PHPComplexFunctions](https://github.com/MarkBaker/PHPComplexFunctions) instead (available on packagist as [markbaker/complex-functions](https://packagist.org/packages/markbaker/complex-functions)).
You'll need to replace `markbaker/complex`in your `composer.json` file with the new library, but otherwise there should be no difference in the namespacing, or in the way that you have called the Complex functions in the past, so no actual code changes are required.
```shell
composer require markbaker/complex-functions:^3.0
```
You should not reference this library (`markbaker/complex`) in your `composer.json`, composer wil take care of that for you.
# Usage
To create a new complex object, you can provide either the real, imaginary and suffix parts as individual values, or as an array of values passed passed to the constructor; or a string representing the value. e.g
```php
$real = 1.23;
$imaginary = -4.56;
$suffix = 'i';
$complexObject = new Complex\Complex($real, $imaginary, $suffix);
```
or as an array
```php
$real = 1.23;
$imaginary = -4.56;
$suffix = 'i';
$arguments = [$real, $imaginary, $suffix];
$complexObject = new Complex\Complex($arguments);
```
or as a string
```php
$complexString = '1.23-4.56i';
$complexObject = new Complex\Complex($complexString);
```
Complex objects are immutable: whenever you call a method or pass a complex value to a function that returns a complex value, a new Complex object will be returned, and the original will remain unchanged.
This also allows you to chain multiple methods as you would for a fluent interface (as long as they are methods that will return a Complex result).
## Performing Mathematical Operations
To perform mathematical operations with Complex values, you can call the appropriate method against a complex value, passing other values as arguments
```php
$complexString1 = '1.23-4.56i';
$complexString2 = '2.34+5.67i';
$complexObject = new Complex\Complex($complexString1);
echo $complexObject->add($complexString2);
```
or use the static Operation methods
```php
$complexString1 = '1.23-4.56i';
$complexString2 = '2.34+5.67i';
echo Complex\Operations::add($complexString1, $complexString2);
```
If you want to perform the same operation against multiple values (e.g. to add three or more complex numbers), then you can pass multiple arguments to any of the operations.
You can pass these arguments as Complex objects, or as an array, or string that will parse to a complex object.
## Using functions
When calling any of the available functions for a complex value, you can either call the relevant method for the Complex object
```php
$complexString = '1.23-4.56i';
$complexObject = new Complex\Complex($complexString);
echo $complexObject->sinh();
```
or use the static Functions methods
```php
$complexString = '1.23-4.56i';
echo Complex\Functions::sinh($complexString);
```
As with operations, you can pass these arguments as Complex objects, or as an array or string that will parse to a complex object.
In the case of the `pow()` function (the only implemented function that requires an additional argument) you need to pass both arguments when calling the function
```php
$complexString = '1.23-4.56i';
$complexObject = new Complex\Complex($complexString);
echo Complex\Functions::pow($complexObject, 2);
```
or pass the additional argument when calling the method
```php
$complexString = '1.23-4.56i';
$complexObject = new Complex\Complex($complexString);
echo $complexObject->pow(2);
```

View File

@ -0,0 +1,388 @@
<?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');
}
}

View File

@ -0,0 +1,13 @@
<?php
/**
* Exception.
*
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
* @license https://opensource.org/licenses/MIT MIT
*/
namespace Complex;
class Exception extends \Exception
{
}

View File

@ -0,0 +1,823 @@
<?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()));
}
}

View File

@ -0,0 +1,210 @@
<?php
namespace Complex;
use InvalidArgumentException;
class Operations
{
/**
* Adds two or more complex numbers
*
* @param array of string|integer|float|Complex $complexValues The numbers to add
* @return Complex
*/
public static function add(...$complexValues): Complex
{
if (count($complexValues) < 2) {
throw new \Exception('This function requires at least 2 arguments');
}
$base = array_shift($complexValues);
$result = clone Complex::validateComplexArgument($base);
foreach ($complexValues as $complex) {
$complex = Complex::validateComplexArgument($complex);
if ($result->isComplex() && $complex->isComplex() &&
$result->getSuffix() !== $complex->getSuffix()) {
throw new Exception('Suffix Mismatch');
}
$real = $result->getReal() + $complex->getReal();
$imaginary = $result->getImaginary() + $complex->getImaginary();
$result = new Complex(
$real,
$imaginary,
($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix())
);
}
return $result;
}
/**
* Divides two or more complex numbers
*
* @param array of string|integer|float|Complex $complexValues The numbers to divide
* @return Complex
*/
public static function divideby(...$complexValues): Complex
{
if (count($complexValues) < 2) {
throw new \Exception('This function requires at least 2 arguments');
}
$base = array_shift($complexValues);
$result = clone Complex::validateComplexArgument($base);
foreach ($complexValues as $complex) {
$complex = Complex::validateComplexArgument($complex);
if ($result->isComplex() && $complex->isComplex() &&
$result->getSuffix() !== $complex->getSuffix()) {
throw new Exception('Suffix Mismatch');
}
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
throw new InvalidArgumentException('Division by zero');
}
$delta1 = ($result->getReal() * $complex->getReal()) +
($result->getImaginary() * $complex->getImaginary());
$delta2 = ($result->getImaginary() * $complex->getReal()) -
($result->getReal() * $complex->getImaginary());
$delta3 = ($complex->getReal() * $complex->getReal()) +
($complex->getImaginary() * $complex->getImaginary());
$real = $delta1 / $delta3;
$imaginary = $delta2 / $delta3;
$result = new Complex(
$real,
$imaginary,
($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix())
);
}
return $result;
}
/**
* Divides two or more complex numbers
*
* @param array of string|integer|float|Complex $complexValues The numbers to divide
* @return Complex
*/
public static function divideinto(...$complexValues): Complex
{
if (count($complexValues) < 2) {
throw new \Exception('This function requires at least 2 arguments');
}
$base = array_shift($complexValues);
$result = clone Complex::validateComplexArgument($base);
foreach ($complexValues as $complex) {
$complex = Complex::validateComplexArgument($complex);
if ($result->isComplex() && $complex->isComplex() &&
$result->getSuffix() !== $complex->getSuffix()) {
throw new Exception('Suffix Mismatch');
}
if ($result->getReal() == 0.0 && $result->getImaginary() == 0.0) {
throw new InvalidArgumentException('Division by zero');
}
$delta1 = ($complex->getReal() * $result->getReal()) +
($complex->getImaginary() * $result->getImaginary());
$delta2 = ($complex->getImaginary() * $result->getReal()) -
($complex->getReal() * $result->getImaginary());
$delta3 = ($result->getReal() * $result->getReal()) +
($result->getImaginary() * $result->getImaginary());
$real = $delta1 / $delta3;
$imaginary = $delta2 / $delta3;
$result = new Complex(
$real,
$imaginary,
($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix())
);
}
return $result;
}
/**
* Multiplies two or more complex numbers
*
* @param array of string|integer|float|Complex $complexValues The numbers to multiply
* @return Complex
*/
public static function multiply(...$complexValues): Complex
{
if (count($complexValues) < 2) {
throw new \Exception('This function requires at least 2 arguments');
}
$base = array_shift($complexValues);
$result = clone Complex::validateComplexArgument($base);
foreach ($complexValues as $complex) {
$complex = Complex::validateComplexArgument($complex);
if ($result->isComplex() && $complex->isComplex() &&
$result->getSuffix() !== $complex->getSuffix()) {
throw new Exception('Suffix Mismatch');
}
$real = ($result->getReal() * $complex->getReal()) -
($result->getImaginary() * $complex->getImaginary());
$imaginary = ($result->getReal() * $complex->getImaginary()) +
($result->getImaginary() * $complex->getReal());
$result = new Complex(
$real,
$imaginary,
($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix())
);
}
return $result;
}
/**
* Subtracts two or more complex numbers
*
* @param array of string|integer|float|Complex $complexValues The numbers to subtract
* @return Complex
*/
public static function subtract(...$complexValues): Complex
{
if (count($complexValues) < 2) {
throw new \Exception('This function requires at least 2 arguments');
}
$base = array_shift($complexValues);
$result = clone Complex::validateComplexArgument($base);
foreach ($complexValues as $complex) {
$complex = Complex::validateComplexArgument($complex);
if ($result->isComplex() && $complex->isComplex() &&
$result->getSuffix() !== $complex->getSuffix()) {
throw new Exception('Suffix Mismatch');
}
$real = $result->getReal() - $complex->getReal();
$imaginary = $result->getImaginary() - $complex->getImaginary();
$result = new Complex(
$real,
$imaginary,
($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix())
);
}
return $result;
}
}

40
vendor/markbaker/complex/composer.json vendored Normal file
View File

@ -0,0 +1,40 @@
{
"name": "markbaker/complex",
"type": "library",
"description": "PHP Class for working with complex numbers",
"keywords": ["complex", "mathematics"],
"homepage": "https://github.com/MarkBaker/PHPComplex",
"license": "MIT",
"authors": [
{
"name": "Mark Baker",
"email": "mark@lange.demon.co.uk"
}
],
"config": {
"sort-packages": true,
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true,
"markbaker/ukraine": true
}
},
"require": {
"php": "^7.2 || ^8.0"
},
"require-dev": {
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"squizlabs/php_codesniffer": "^3.7",
"phpcompatibility/php-compatibility": "^9.3",
"dealerdirect/phpcodesniffer-composer-installer": "dev-master"
},
"autoload": {
"psr-4": {
"Complex\\": "classes/src/"
}
},
"scripts": {
"style": "phpcs --report-width=200 --standard=PSR2 --report=summary,full classes/src/ unitTests/classes/src -n",
"versions": "phpcs --report-width=200 --standard=PHPCompatibility --report=summary,full classes/src/ --runtime-set testVersion 7.2- -n"
},
"minimum-stability": "dev"
}

View File

@ -0,0 +1,154 @@
<?php
use Complex\Complex as Complex;
include(__DIR__ . '/../vendor/autoload.php');
echo 'Create', PHP_EOL;
$x = new Complex(123);
echo $x, PHP_EOL;
$x = new Complex(123, 456);
echo $x, PHP_EOL;
$x = new Complex(array(123,456,'j'));
echo $x, PHP_EOL;
$x = new Complex('1.23e-4--2.34e-5i');
echo $x, PHP_EOL;
echo PHP_EOL, 'Add', PHP_EOL;
$x = new Complex(123);
$x->add(456);
echo $x, PHP_EOL;
$x = new Complex(123.456);
$x->add(789.012);
echo $x, PHP_EOL;
$x = new Complex(123.456, 78.90);
$x->add(new Complex(-987.654, -32.1));
echo $x, PHP_EOL;
$x = new Complex(123.456, 78.90);
$x->add(-987.654);
echo $x, PHP_EOL;
$x = new Complex(-987.654, -32.1);
$x->add(new Complex(0, 1));
echo $x, PHP_EOL;
$x = new Complex(-987.654, -32.1);
$x->add(new Complex(0, -1));
echo $x, PHP_EOL;
echo PHP_EOL, 'Subtract', PHP_EOL;
$x = new Complex(123);
$x->subtract(456);
echo $x, PHP_EOL;
$x = new Complex(123.456);
$x->subtract(789.012);
echo $x, PHP_EOL;
$x = new Complex(123.456, 78.90);
$x->subtract(new Complex(-987.654, -32.1));
echo $x, PHP_EOL;
$x = new Complex(123.456, 78.90);
$x->subtract(-987.654);
echo $x, PHP_EOL;
$x = new Complex(-987.654, -32.1);
$x->subtract(new Complex(0, 1));
echo $x, PHP_EOL;
$x = new Complex(-987.654, -32.1);
$x->subtract(new Complex(0, -1));
echo $x, PHP_EOL;
echo PHP_EOL, 'Multiply', PHP_EOL;
$x = new Complex(123);
$x->multiply(456);
echo $x, PHP_EOL;
$x = new Complex(123.456);
$x->multiply(789.012);
echo $x, PHP_EOL;
$x = new Complex(123.456, 78.90);
$x->multiply(new Complex(-987.654, -32.1));
echo $x, PHP_EOL;
$x = new Complex(123.456, 78.90);
$x->multiply(-987.654);
echo $x, PHP_EOL;
$x = new Complex(-987.654, -32.1);
$x->multiply(new Complex(0, 1));
echo $x, PHP_EOL;
$x = new Complex(-987.654, -32.1);
$x->multiply(new Complex(0, -1));
echo $x, PHP_EOL;
echo PHP_EOL, 'Divide By', PHP_EOL;
$x = new Complex(123);
$x->divideBy(456);
echo $x, PHP_EOL;
$x = new Complex(123.456);
$x->divideBy(789.012);
echo $x, PHP_EOL;
$x = new Complex(123.456, 78.90);
$x->divideBy(new Complex(-987.654, -32.1));
echo $x, PHP_EOL;
$x = new Complex(123.456, 78.90);
$x->divideBy(-987.654);
echo $x, PHP_EOL;
$x = new Complex(-987.654, -32.1);
$x->divideBy(new Complex(0, 1));
echo $x, PHP_EOL;
$x = new Complex(-987.654, -32.1);
$x->divideBy(new Complex(0, -1));
echo $x, PHP_EOL;
echo PHP_EOL, 'Divide Into', PHP_EOL;
$x = new Complex(123);
$x->divideInto(456);
echo $x, PHP_EOL;
$x = new Complex(123.456);
$x->divideInto(789.012);
echo $x, PHP_EOL;
$x = new Complex(123.456, 78.90);
$x->divideInto(new Complex(-987.654, -32.1));
echo $x, PHP_EOL;
$x = new Complex(123.456, 78.90);
$x->divideInto(-987.654);
echo $x, PHP_EOL;
$x = new Complex(-987.654, -32.1);
$x->divideInto(new Complex(0, 1));
echo $x, PHP_EOL;
$x = new Complex(-987.654, -32.1);
$x->divideInto(new Complex(0, -1));
echo $x, PHP_EOL;

View File

@ -0,0 +1,52 @@
<?php
namespace Complex;
include(__DIR__ . '/../vendor/autoload.php');
echo 'Function Examples', PHP_EOL;
$functions = array(
'abs',
'acos',
'acosh',
'acsc',
'acsch',
'argument',
'asec',
'asech',
'asin',
'asinh',
'conjugate',
'cos',
'cosh',
'csc',
'csch',
'exp',
'inverse',
'ln',
'log2',
'log10',
'rho',
'sec',
'sech',
'sin',
'sinh',
'sqrt',
'theta'
);
for ($real = -3.5; $real <= 3.5; $real += 0.5) {
for ($imaginary = -3.5; $imaginary <= 3.5; $imaginary += 0.5) {
foreach ($functions as $function) {
$complexFunction = __NAMESPACE__ . '\\Functions::' . $function;
$complex = new Complex($real, $imaginary);
try {
echo $function, '(', $complex, ') = ', $complexFunction($complex), PHP_EOL;
} catch (\Exception $e) {
echo $function, '(', $complex, ') ERROR: ', $e->getMessage(), PHP_EOL;
}
}
echo PHP_EOL;
}
}

View File

@ -0,0 +1,35 @@
<?php
use Complex\Complex as Complex;
use Complex\Operations;
include(__DIR__ . '/../vendor/autoload.php');
$values = [
new Complex(123),
new Complex(456, 123),
new Complex(0.0, 456),
];
foreach ($values as $value) {
echo $value, PHP_EOL;
}
echo 'Addition', PHP_EOL;
$result = Operations::add(...$values);
echo '=> ', $result, PHP_EOL;
echo PHP_EOL;
echo 'Subtraction', PHP_EOL;
$result = Operations::subtract(...$values);
echo '=> ', $result, PHP_EOL;
echo PHP_EOL;
echo 'Multiplication', PHP_EOL;
$result = Operations::multiply(...$values);
echo '=> ', $result, PHP_EOL;

25
vendor/markbaker/complex/license.md vendored Normal file
View File

@ -0,0 +1,25 @@
The MIT License (MIT)
=====================
Copyright © `2017` `Mark Baker`
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the “Software”), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.