Release of v3.2.5
Add [AllowDynamicProperties] in the base view class for J5. Move the _prepareDocument above the display call in the base view class. Remove all backward compatibility issues, so JCB will not need the [Backward Compatibility] plugin to run. Added new import powers for custom import of spreadsheets. Move the setDocument and _prepareDocument above the display in the site view and custom admin view. Update the trashhelper layout to work in Joomla 5. Add AllowDynamicProperties (Joomla 4+5) to view class to allow Custom Dynamic Get methods to work without issues. Fix Save failed issue in dynamicGet. #1148. Move all [TEXT, EDITOR, TEXTAREA] fields from [NOT NULL] to [NULL]. Add the DateHelper class and improve the date methods. Add simple SessionHelper class. Add first classes for the new import engine. Improve the [VDM Registry] to be Joomla Registry Compatible. Move all registries to the [VDM Registry] class. Fix Checked Out to be null and not 0. (#1194). Fix created_by, modified_by, checked_out fields in the compiler of the SQL. (#1194). Update all core date fields in table class. (#1188). Update created_by, modified_by, checked_out fields in table class. Implementation of the decentralized Super-Power CORE repository network. (#1190). Fix the noticeboard to display Llewellyn's Joomla Social feed.
This commit is contained in:
153
libraries/phpspreadsheet/vendor/markbaker/complex/.github/workflows/main.yml
vendored
Normal file
153
libraries/phpspreadsheet/vendor/markbaker/complex/.github/workflows/main.yml
vendored
Normal 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
libraries/phpspreadsheet/vendor/markbaker/complex/README.md
vendored
Normal file
173
libraries/phpspreadsheet/vendor/markbaker/complex/README.md
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
PHPComplex
|
||||
==========
|
||||
|
||||
---
|
||||
|
||||
PHP Class Library for working with Complex numbers
|
||||
|
||||
[](https://github.com/MarkBaker/PHPComplex/actions)
|
||||
[](https://packagist.org/packages/markbaker/complex)
|
||||
[](https://packagist.org/packages/markbaker/complex)
|
||||
[](https://packagist.org/packages/markbaker/complex)
|
||||
|
||||
|
||||
[](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);
|
||||
```
|
@@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
*
|
||||
* Autoloader for Complex classes
|
||||
*
|
||||
* @package Complex
|
||||
* @copyright Copyright (c) 2014 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
class Autoloader
|
||||
{
|
||||
/**
|
||||
* Register the Autoloader with SPL
|
||||
*
|
||||
*/
|
||||
public static function Register()
|
||||
{
|
||||
if (function_exists('__autoload')) {
|
||||
// Register any existing autoloader function with SPL, so we don't get any clashes
|
||||
spl_autoload_register('__autoload');
|
||||
}
|
||||
// Register ourselves with SPL
|
||||
return spl_autoload_register(['Complex\\Autoloader', 'Load']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Autoload a class identified by name
|
||||
*
|
||||
* @param string $pClassName Name of the object to load
|
||||
*/
|
||||
public static function Load($pClassName)
|
||||
{
|
||||
if ((class_exists($pClassName, false)) || (strpos($pClassName, 'Complex\\') !== 0)) {
|
||||
// Either already loaded, or not a Complex class request
|
||||
return false;
|
||||
}
|
||||
|
||||
$pClassFilePath = __DIR__ . DIRECTORY_SEPARATOR .
|
||||
'src' . DIRECTORY_SEPARATOR .
|
||||
str_replace(['Complex\\', '\\'], ['', '/'], $pClassName) .
|
||||
'.php';
|
||||
|
||||
if ((file_exists($pClassFilePath) === false) || (is_readable($pClassFilePath) === false)) {
|
||||
// Can't load
|
||||
return false;
|
||||
}
|
||||
require($pClassFilePath);
|
||||
}
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
include_once __DIR__ . '/Autoloader.php';
|
||||
|
||||
\Complex\Autoloader::Register();
|
||||
|
||||
|
||||
abstract class FilesystemRegexFilter extends RecursiveRegexIterator
|
||||
{
|
||||
protected $regex;
|
||||
public function __construct(RecursiveIterator $it, $regex)
|
||||
{
|
||||
$this->regex = $regex;
|
||||
parent::__construct($it, $regex);
|
||||
}
|
||||
}
|
||||
|
||||
class FilenameFilter extends FilesystemRegexFilter
|
||||
{
|
||||
// Filter files against the regex
|
||||
public function accept()
|
||||
{
|
||||
return (!$this->isFile() || preg_match($this->regex, $this->getFilename()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$srcFolder = __DIR__ . DIRECTORY_SEPARATOR . 'src';
|
||||
$srcDirectory = new RecursiveDirectoryIterator($srcFolder);
|
||||
|
||||
$filteredFileList = new FilenameFilter($srcDirectory, '/(?:php)$/i');
|
||||
$filteredFileList = new FilenameFilter($filteredFileList, '/^(?!.*(Complex|Exception)\.php).*$/i');
|
||||
|
||||
foreach (new RecursiveIteratorIterator($filteredFileList) as $file) {
|
||||
if ($file->isFile()) {
|
||||
include_once $file;
|
||||
}
|
||||
}
|
@@ -186,7 +186,7 @@ class Complex
|
||||
// Set parsed values in our properties
|
||||
$this->realPart = (float) $realPart;
|
||||
$this->imaginaryPart = (float) $imaginaryPart;
|
||||
$this->suffix = strtolower($suffix);
|
||||
$this->suffix = strtolower($suffix ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -194,7 +194,7 @@ class Complex
|
||||
*
|
||||
* @return Float
|
||||
*/
|
||||
public function getReal()
|
||||
public function getReal(): float
|
||||
{
|
||||
return $this->realPart;
|
||||
}
|
||||
@@ -204,7 +204,7 @@ class Complex
|
||||
*
|
||||
* @return Float
|
||||
*/
|
||||
public function getImaginary()
|
||||
public function getImaginary(): float
|
||||
{
|
||||
return $this->imaginaryPart;
|
||||
}
|
||||
@@ -214,7 +214,7 @@ class Complex
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public function getSuffix()
|
||||
public function getSuffix(): string
|
||||
{
|
||||
return $this->suffix;
|
||||
}
|
||||
@@ -224,7 +224,7 @@ class Complex
|
||||
*
|
||||
* @return Bool
|
||||
*/
|
||||
public function isReal()
|
||||
public function isReal(): bool
|
||||
{
|
||||
return $this->imaginaryPart == 0.0;
|
||||
}
|
||||
@@ -234,12 +234,12 @@ class Complex
|
||||
*
|
||||
* @return Bool
|
||||
*/
|
||||
public function isComplex()
|
||||
public function isComplex(): bool
|
||||
{
|
||||
return !$this->isReal();
|
||||
}
|
||||
|
||||
public function format()
|
||||
public function format(): string
|
||||
{
|
||||
$str = "";
|
||||
if ($this->imaginaryPart != 0.0) {
|
||||
@@ -262,7 +262,7 @@ class Complex
|
||||
return $str;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->format();
|
||||
}
|
||||
@@ -274,7 +274,7 @@ class Complex
|
||||
* @return Complex
|
||||
* @throws Exception If the argument isn't a Complex number or cannot be converted to one
|
||||
*/
|
||||
public static function validateComplexArgument($complex)
|
||||
public static function validateComplexArgument($complex): Complex
|
||||
{
|
||||
if (is_scalar($complex) || is_array($complex)) {
|
||||
$complex = new Complex($complex);
|
||||
@@ -290,7 +290,7 @@ class Complex
|
||||
*
|
||||
* @return Complex
|
||||
*/
|
||||
public function reverse()
|
||||
public function reverse(): Complex
|
||||
{
|
||||
return new Complex(
|
||||
$this->imaginaryPart,
|
||||
@@ -299,7 +299,7 @@ class Complex
|
||||
);
|
||||
}
|
||||
|
||||
public function invertImaginary()
|
||||
public function invertImaginary(): Complex
|
||||
{
|
||||
return new Complex(
|
||||
$this->realPart,
|
||||
@@ -308,7 +308,7 @@ class Complex
|
||||
);
|
||||
}
|
||||
|
||||
public function invertReal()
|
||||
public function invertReal(): Complex
|
||||
{
|
||||
return new Complex(
|
||||
$this->realPart * -1,
|
||||
@@ -376,15 +376,13 @@ class Complex
|
||||
$functionName = strtolower(str_replace('_', '', $functionName));
|
||||
|
||||
// Test for function calls
|
||||
if (in_array($functionName, self::$functions)) {
|
||||
$functionName = "\\" . __NAMESPACE__ . "\\{$functionName}";
|
||||
return $functionName($this, ...$arguments);
|
||||
if (in_array($functionName, self::$functions, true)) {
|
||||
return Functions::$functionName($this, ...$arguments);
|
||||
}
|
||||
// Test for operation calls
|
||||
if (in_array($functionName, self::$operations)) {
|
||||
$functionName = "\\" . __NAMESPACE__ . "\\{$functionName}";
|
||||
return $functionName($this, ...$arguments);
|
||||
if (in_array($functionName, self::$operations, true)) {
|
||||
return Operations::$functionName($this, ...$arguments);
|
||||
}
|
||||
throw new Exception('Function or Operation does not exist');
|
||||
throw new Exception('Complex Function or Operation does not exist');
|
||||
}
|
||||
}
|
||||
|
823
libraries/phpspreadsheet/vendor/markbaker/complex/classes/src/Functions.php
vendored
Normal file
823
libraries/phpspreadsheet/vendor/markbaker/complex/classes/src/Functions.php
vendored
Normal 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()));
|
||||
}
|
||||
}
|
210
libraries/phpspreadsheet/vendor/markbaker/complex/classes/src/Operations.php
vendored
Normal file
210
libraries/phpspreadsheet/vendor/markbaker/complex/classes/src/Operations.php
vendored
Normal 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;
|
||||
}
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex abs() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
function abs($complex)
|
||||
{
|
||||
return rho($complex);
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex acos() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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.
|
||||
*/
|
||||
function acos($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
$square = clone $complex;
|
||||
$square = multiply($square, $complex);
|
||||
$invsqrt = new Complex(1.0);
|
||||
$invsqrt = subtract($invsqrt, $square);
|
||||
$invsqrt = sqrt($invsqrt);
|
||||
$adjust = new Complex(
|
||||
$complex->getReal() - $invsqrt->getImaginary(),
|
||||
$complex->getImaginary() + $invsqrt->getReal()
|
||||
);
|
||||
$log = ln($adjust);
|
||||
|
||||
return new Complex(
|
||||
$log->getImaginary(),
|
||||
-1 * $log->getReal()
|
||||
);
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex acosh() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse hyperbolic cosine of a complex number.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
function acosh($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->isReal() && ($complex->getReal() > 1)) {
|
||||
return new Complex(\acosh($complex->getReal()));
|
||||
}
|
||||
|
||||
$acosh = acos($complex)
|
||||
->reverse();
|
||||
if ($acosh->getReal() < 0.0) {
|
||||
$acosh = $acosh->invertReal();
|
||||
}
|
||||
|
||||
return $acosh;
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex acot() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function acot($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return atan(inverse($complex));
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex acoth() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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
|
||||
*/
|
||||
function acoth($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return atanh(inverse($complex));
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex acsc() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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
|
||||
*/
|
||||
function acsc($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return INF;
|
||||
}
|
||||
|
||||
return asin(inverse($complex));
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex acsch() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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
|
||||
*/
|
||||
function acsch($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return INF;
|
||||
}
|
||||
|
||||
return asinh(inverse($complex));
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex argument() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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
|
||||
*/
|
||||
function argument($complex)
|
||||
{
|
||||
return theta($complex);
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex asec() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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
|
||||
*/
|
||||
function asec($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return INF;
|
||||
}
|
||||
|
||||
return acos(inverse($complex));
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex asech() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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
|
||||
*/
|
||||
function asech($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return INF;
|
||||
}
|
||||
|
||||
return acosh(inverse($complex));
|
||||
}
|
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex asin() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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.
|
||||
*/
|
||||
function asin($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
$square = multiply($complex, $complex);
|
||||
$invsqrt = new Complex(1.0);
|
||||
$invsqrt = subtract($invsqrt, $square);
|
||||
$invsqrt = sqrt($invsqrt);
|
||||
$adjust = new Complex(
|
||||
$invsqrt->getReal() - $complex->getImaginary(),
|
||||
$invsqrt->getImaginary() + $complex->getReal()
|
||||
);
|
||||
$log = ln($adjust);
|
||||
|
||||
return new Complex(
|
||||
$log->getImaginary(),
|
||||
-1 * $log->getReal()
|
||||
);
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex asinh() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
function asinh($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 = asin($asinh);
|
||||
return $asinh->reverse()
|
||||
->invertImaginary();
|
||||
}
|
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex atan() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
//include_once 'Math/Complex.php';
|
||||
//include_once 'Math/ComplexOp.php';
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function atan($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 = subtract($d1Value, $t1Value);
|
||||
$d2Value = add($t1Value, $uValue);
|
||||
$uResult = $d1Value->divideBy($d2Value);
|
||||
$uResult = ln($uResult);
|
||||
|
||||
return new Complex(
|
||||
(($uResult->getImaginary() == M_PI) ? -M_PI : $uResult->getImaginary()) * -0.5,
|
||||
$uResult->getReal() * 0.5,
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex atanh() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse hyperbolic tangent of a complex number.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
function atanh($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));
|
||||
}
|
||||
}
|
||||
|
||||
$iComplex = clone $complex;
|
||||
$iComplex = $iComplex->invertImaginary()
|
||||
->reverse();
|
||||
return atan($iComplex)
|
||||
->invertReal()
|
||||
->reverse();
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex conjugate() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
function conjugate($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return new Complex(
|
||||
$complex->getReal(),
|
||||
-1 * $complex->getImaginary(),
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex cos() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
function cos($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->isReal()) {
|
||||
return new Complex(\cos($complex->getReal()));
|
||||
}
|
||||
|
||||
return conjugate(
|
||||
new Complex(
|
||||
\cos($complex->getReal()) * \cosh($complex->getImaginary()),
|
||||
\sin($complex->getReal()) * \sinh($complex->getImaginary()),
|
||||
$complex->getSuffix()
|
||||
)
|
||||
);
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex cosh() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
function cosh($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()
|
||||
);
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex cot() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function cot($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return new Complex(INF);
|
||||
}
|
||||
|
||||
return inverse(tan($complex));
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex coth() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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
|
||||
*/
|
||||
function coth($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
return inverse(tanh($complex));
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex csc() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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
|
||||
*/
|
||||
function csc($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return INF;
|
||||
}
|
||||
|
||||
return inverse(sin($complex));
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex csch() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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
|
||||
*/
|
||||
function csch($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return INF;
|
||||
}
|
||||
|
||||
return inverse(sinh($complex));
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex exp() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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.
|
||||
*/
|
||||
function exp($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()
|
||||
);
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex inverse() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function inverse($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);
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex ln() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function ln($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if (($complex->getReal() == 0.0) && ($complex->getImaginary() == 0.0)) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
|
||||
return new Complex(
|
||||
\log(rho($complex)),
|
||||
theta($complex),
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex log10() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function log10($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 ln($complex)
|
||||
->multiply(\log10(Complex::EULER));
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex log2() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function log2($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 ln($complex)
|
||||
->multiply(\log(Complex::EULER, 2));
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex negative() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the negative of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return float The negative value of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*
|
||||
* @see rho
|
||||
*
|
||||
*/
|
||||
function negative($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return new Complex(
|
||||
-1 * $complex->getReal(),
|
||||
-1 * $complex->getImaginary(),
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex pow() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function pow($complex, $power)
|
||||
{
|
||||
$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());
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex rho() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
function rho($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return \sqrt(
|
||||
($complex->getReal() * $complex->getReal()) +
|
||||
($complex->getImaginary() * $complex->getImaginary())
|
||||
);
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex sec() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function sec($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return inverse(cos($complex));
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex sech() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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
|
||||
*/
|
||||
function sech($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return inverse(cosh($complex));
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex sin() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace 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.
|
||||
*/
|
||||
function sin($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()
|
||||
);
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex sinh() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
function sinh($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()
|
||||
);
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex sqrt() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
function sqrt($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
$theta = theta($complex);
|
||||
$delta1 = \cos($theta / 2);
|
||||
$delta2 = \sin($theta / 2);
|
||||
$rho = \sqrt(rho($complex));
|
||||
|
||||
return new Complex($delta1 * $rho, $delta2 * $rho, $complex->getSuffix());
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex tan() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function tan($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(sech($imaginary)->getReal(), 2) * \tan($real) / $divisor,
|
||||
\pow(sec($real)->getReal(), 2) * \tanh($imaginary) / $divisor,
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex tanh() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function tanh($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()
|
||||
);
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex theta() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
function theta($complex)
|
||||
{
|
||||
$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()));
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex addition operation
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Adds two or more complex numbers
|
||||
*
|
||||
* @param array of string|integer|float|Complex $complexValues The numbers to add
|
||||
* @return Complex
|
||||
*/
|
||||
function add(...$complexValues)
|
||||
{
|
||||
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;
|
||||
}
|
@@ -1,56 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex division operation
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Divides two or more complex numbers
|
||||
*
|
||||
* @param array of string|integer|float|Complex $complexValues The numbers to divide
|
||||
* @return Complex
|
||||
*/
|
||||
function divideby(...$complexValues)
|
||||
{
|
||||
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;
|
||||
}
|
@@ -1,56 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex division operation
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Divides two or more complex numbers
|
||||
*
|
||||
* @param array of string|integer|float|Complex $complexValues The numbers to divide
|
||||
* @return Complex
|
||||
*/
|
||||
function divideinto(...$complexValues)
|
||||
{
|
||||
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;
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex multiplication operation
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Multiplies two or more complex numbers
|
||||
*
|
||||
* @param array of string|integer|float|Complex $complexValues The numbers to multiply
|
||||
* @return Complex
|
||||
*/
|
||||
function multiply(...$complexValues)
|
||||
{
|
||||
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;
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex subtraction operation
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Subtracts two or more complex numbers
|
||||
*
|
||||
* @param array of string|integer|float|Complex $complexValues The numbers to subtract
|
||||
* @return Complex
|
||||
*/
|
||||
function subtract(...$complexValues)
|
||||
{
|
||||
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
libraries/phpspreadsheet/vendor/markbaker/complex/composer.json
vendored
Normal file
40
libraries/phpspreadsheet/vendor/markbaker/complex/composer.json
vendored
Normal 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"
|
||||
}
|
154
libraries/phpspreadsheet/vendor/markbaker/complex/examples/complexTest.php
vendored
Normal file
154
libraries/phpspreadsheet/vendor/markbaker/complex/examples/complexTest.php
vendored
Normal 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;
|
52
libraries/phpspreadsheet/vendor/markbaker/complex/examples/testFunctions.php
vendored
Normal file
52
libraries/phpspreadsheet/vendor/markbaker/complex/examples/testFunctions.php
vendored
Normal 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;
|
||||
}
|
||||
}
|
35
libraries/phpspreadsheet/vendor/markbaker/complex/examples/testOperations.php
vendored
Normal file
35
libraries/phpspreadsheet/vendor/markbaker/complex/examples/testOperations.php
vendored
Normal 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
libraries/phpspreadsheet/vendor/markbaker/complex/license.md
vendored
Normal file
25
libraries/phpspreadsheet/vendor/markbaker/complex/license.md
vendored
Normal 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.
|
124
libraries/phpspreadsheet/vendor/markbaker/matrix/.github/workflows/main.yaml
vendored
Normal file
124
libraries/phpspreadsheet/vendor/markbaker/matrix/.github/workflows/main.yaml
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
name: main
|
||||
on: [ push, pull_request ]
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
php-version:
|
||||
- '7.1'
|
||||
- '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 }}
|
||||
extensions: ctype, dom, gd, iconv, fileinfo, libxml, mbstring, simplexml, xml, xmlreader, xmlwriter, zip, zlib
|
||||
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: Test with PHPUnit
|
||||
run: ./vendor/bin/phpunit
|
||||
|
||||
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
|
||||
extensions: ctype, dom, gd, iconv, fileinfo, libxml, mbstring, simplexml, xml, xmlreader, xmlwriter, zip, zlib
|
||||
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 | cs2pr --graceful-warnings --colorize
|
||||
|
||||
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
|
||||
extensions: ctype, dom, gd, iconv, fileinfo, libxml, mbstring, simplexml, xml, xmlreader, xmlwriter, zip, zlib
|
||||
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: Coverage
|
||||
run: |
|
||||
./vendor/bin/phpunit --coverage-text
|
215
libraries/phpspreadsheet/vendor/markbaker/matrix/README.md
vendored
Normal file
215
libraries/phpspreadsheet/vendor/markbaker/matrix/README.md
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
PHPMatrix
|
||||
==========
|
||||
|
||||
---
|
||||
|
||||
PHP Class for handling Matrices
|
||||
|
||||
[](https://github.com/MarkBaker/PHPMatrix/actions)
|
||||
[](https://packagist.org/packages/markbaker/matrix)
|
||||
[](https://packagist.org/packages/markbaker/matrix)
|
||||
[](https://packagist.org/packages/markbaker/matrix)
|
||||
|
||||
|
||||
[](https://xkcd.com/184/)
|
||||
|
||||
Matrix Transform
|
||||
|
||||
---
|
||||
|
||||
This library currently provides the following operations:
|
||||
|
||||
- addition
|
||||
- direct sum
|
||||
- subtraction
|
||||
- multiplication
|
||||
- division (using [A].[B]<sup>-1</sup>)
|
||||
- division by
|
||||
- division into
|
||||
|
||||
together with functions for
|
||||
|
||||
- adjoint
|
||||
- antidiagonal
|
||||
- cofactors
|
||||
- determinant
|
||||
- diagonal
|
||||
- identity
|
||||
- inverse
|
||||
- minors
|
||||
- trace
|
||||
- transpose
|
||||
- solve
|
||||
|
||||
Given Matrices A and B, calculate X for A.X = B
|
||||
|
||||
and classes for
|
||||
|
||||
- Decomposition
|
||||
- LU Decomposition with partial row pivoting,
|
||||
|
||||
such that [P].[A] = [L].[U] and [A] = [P]<sup>|</sup>.[L].[U]
|
||||
- QR Decomposition
|
||||
|
||||
such that [A] = [Q].[R]
|
||||
|
||||
## TO DO
|
||||
|
||||
- power() function
|
||||
- Decomposition
|
||||
- Cholesky Decomposition
|
||||
- EigenValue Decomposition
|
||||
- EigenValues
|
||||
- EigenVectors
|
||||
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
```shell
|
||||
composer require markbaker/matrix:^3.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/PHPMatrixFunctions](https://github.com/MarkBaker/PHPMatrixFunctions) instead (available on packagist as [markbaker/matrix-functions](https://packagist.org/packages/markbaker/matrix-functions)).
|
||||
|
||||
You'll need to replace `markbaker/matrix`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 Matrix functions in the past, so no actual code changes are required.
|
||||
|
||||
```shell
|
||||
composer require markbaker/matrix-functions:^1.0
|
||||
```
|
||||
|
||||
You should not reference this library (`markbaker/matrix`) in your `composer.json`, composer wil take care of that for you.
|
||||
|
||||
# Usage
|
||||
|
||||
To create a new Matrix object, provide an array as the constructor argument
|
||||
|
||||
```php
|
||||
$grid = [
|
||||
[16, 3, 2, 13],
|
||||
[ 5, 10, 11, 8],
|
||||
[ 9, 6, 7, 12],
|
||||
[ 4, 15, 14, 1],
|
||||
];
|
||||
|
||||
$matrix = new Matrix\Matrix($grid);
|
||||
```
|
||||
The `Builder` class provides helper methods for creating specific matrices, specifically an identity matrix of a specified size; or a matrix of a specified dimensions, with every cell containing a set value.
|
||||
```php
|
||||
$matrix = Matrix\Builder::createFilledMatrix(1, 5, 3);
|
||||
```
|
||||
Will create a matrix of 5 rows and 3 columns, filled with a `1` in every cell; while
|
||||
```php
|
||||
$matrix = Matrix\Builder::createIdentityMatrix(3);
|
||||
```
|
||||
will create a 3x3 identity matrix.
|
||||
|
||||
|
||||
Matrix objects are immutable: whenever you call a method or pass a grid to a function that returns a matrix value, a new Matrix 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 Matrix result).
|
||||
|
||||
## Performing Mathematical Operations
|
||||
|
||||
To perform mathematical operations with Matrices, you can call the appropriate method against a matrix value, passing other values as arguments
|
||||
|
||||
```php
|
||||
$matrix1 = new Matrix\Matrix([
|
||||
[2, 7, 6],
|
||||
[9, 5, 1],
|
||||
[4, 3, 8],
|
||||
]);
|
||||
$matrix2 = new Matrix\Matrix([
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9],
|
||||
]);
|
||||
|
||||
var_dump($matrix1->multiply($matrix2)->toArray());
|
||||
```
|
||||
or pass all values to the appropriate static method
|
||||
```php
|
||||
$matrix1 = new Matrix\Matrix([
|
||||
[2, 7, 6],
|
||||
[9, 5, 1],
|
||||
[4, 3, 8],
|
||||
]);
|
||||
$matrix2 = new Matrix\Matrix([
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9],
|
||||
]);
|
||||
|
||||
var_dump(Matrix\Operations::multiply($matrix1, $matrix2)->toArray());
|
||||
```
|
||||
You can pass in the arguments as Matrix objects, or as arrays.
|
||||
|
||||
If you want to perform the same operation against multiple values (e.g. to add three or more matrices), then you can pass multiple arguments to any of the operations.
|
||||
|
||||
## Using functions
|
||||
|
||||
When calling any of the available functions for a matrix value, you can either call the relevant method for the Matrix object
|
||||
```php
|
||||
$grid = [
|
||||
[16, 3, 2, 13],
|
||||
[ 5, 10, 11, 8],
|
||||
[ 9, 6, 7, 12],
|
||||
[ 4, 15, 14, 1],
|
||||
];
|
||||
|
||||
$matrix = new Matrix\Matrix($grid);
|
||||
|
||||
echo $matrix->trace();
|
||||
```
|
||||
or you can call the static method, passing the Matrix object or array as an argument
|
||||
```php
|
||||
$grid = [
|
||||
[16, 3, 2, 13],
|
||||
[ 5, 10, 11, 8],
|
||||
[ 9, 6, 7, 12],
|
||||
[ 4, 15, 14, 1],
|
||||
];
|
||||
|
||||
$matrix = new Matrix\Matrix($grid);
|
||||
echo Matrix\Functions::trace($matrix);
|
||||
```
|
||||
```php
|
||||
$grid = [
|
||||
[16, 3, 2, 13],
|
||||
[ 5, 10, 11, 8],
|
||||
[ 9, 6, 7, 12],
|
||||
[ 4, 15, 14, 1],
|
||||
];
|
||||
|
||||
echo Matrix\Functions::trace($grid);
|
||||
```
|
||||
|
||||
## Decomposition
|
||||
|
||||
The library also provides classes for matrix decomposition. You can access these using
|
||||
```php
|
||||
$grid = [
|
||||
[1, 2],
|
||||
[3, 4],
|
||||
];
|
||||
|
||||
$matrix = new Matrix\Matrix($grid);
|
||||
|
||||
$decomposition = new Matrix\Decomposition\QR($matrix);
|
||||
$Q = $decomposition->getQ();
|
||||
$R = $decomposition->getR();
|
||||
```
|
||||
|
||||
or alternatively us the `Decomposition` factory, identifying which form of decomposition you want to use
|
||||
```php
|
||||
$grid = [
|
||||
[1, 2],
|
||||
[3, 4],
|
||||
];
|
||||
|
||||
$matrix = new Matrix\Matrix($grid);
|
||||
|
||||
$decomposition = Matrix\Decomposition\Decomposition::decomposition(Matrix\Decomposition\Decomposition::QR, $matrix);
|
||||
$Q = $decomposition->getQ();
|
||||
$R = $decomposition->getR();
|
||||
```
|
@@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
/**
|
||||
*
|
||||
* Autoloader for Matrix classes
|
||||
*
|
||||
* @package Matrix
|
||||
* @copyright Copyright (c) 2014 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
class Autoloader
|
||||
{
|
||||
/**
|
||||
* Register the Autoloader with SPL
|
||||
*
|
||||
*/
|
||||
public static function Register()
|
||||
{
|
||||
if (function_exists('__autoload')) {
|
||||
// Register any existing autoloader function with SPL, so we don't get any clashes
|
||||
spl_autoload_register('__autoload');
|
||||
}
|
||||
// Register ourselves with SPL
|
||||
return spl_autoload_register(['Matrix\\Autoloader', 'Load']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Autoload a class identified by name
|
||||
*
|
||||
* @param string $pClassName Name of the object to load
|
||||
*/
|
||||
public static function Load($pClassName)
|
||||
{
|
||||
if ((class_exists($pClassName, false)) || (strpos($pClassName, 'Matrix\\') !== 0)) {
|
||||
// Either already loaded, or not a Matrix class request
|
||||
return false;
|
||||
}
|
||||
|
||||
$pClassFilePath = __DIR__ . DIRECTORY_SEPARATOR .
|
||||
'src' . DIRECTORY_SEPARATOR .
|
||||
str_replace(['Matrix\\', '\\'], ['', '/'], $pClassName) .
|
||||
'.php';
|
||||
|
||||
if ((file_exists($pClassFilePath) === false) || (is_readable($pClassFilePath) === false)) {
|
||||
// Can't load
|
||||
return false;
|
||||
}
|
||||
require($pClassFilePath);
|
||||
}
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
include_once __DIR__ . '/Autoloader.php';
|
||||
|
||||
\Matrix\Autoloader::Register();
|
||||
|
||||
|
||||
abstract class FilesystemRegexFilter extends RecursiveRegexIterator
|
||||
{
|
||||
protected $regex;
|
||||
public function __construct(RecursiveIterator $it, $regex)
|
||||
{
|
||||
$this->regex = $regex;
|
||||
parent::__construct($it, $regex);
|
||||
}
|
||||
}
|
||||
|
||||
class FilenameFilter extends FilesystemRegexFilter
|
||||
{
|
||||
// Filter files against the regex
|
||||
public function accept()
|
||||
{
|
||||
return (!$this->isFile() || preg_match($this->regex, $this->getFilename()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$srcFolder = __DIR__ . DIRECTORY_SEPARATOR . 'src';
|
||||
$srcDirectory = new RecursiveDirectoryIterator($srcFolder);
|
||||
|
||||
$filteredFileList = new FilenameFilter($srcDirectory, '/(?:php)$/i');
|
||||
$filteredFileList = new FilenameFilter($filteredFileList, '/^(?!.*(Matrix|Exception)\.php).*$/i');
|
||||
|
||||
foreach (new RecursiveIteratorIterator($filteredFileList) as $file) {
|
||||
if ($file->isFile()) {
|
||||
include_once $file;
|
||||
}
|
||||
}
|
@@ -21,13 +21,13 @@ class Builder
|
||||
* Create a new matrix of specified dimensions, and filled with a specified value
|
||||
* If the column argument isn't provided, then a square matrix will be created
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param mixed $fillValue
|
||||
* @param int $rows
|
||||
* @param int|null $columns
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function createFilledMatrix($value, $rows, $columns = null)
|
||||
public static function createFilledMatrix($fillValue, $rows, $columns = null)
|
||||
{
|
||||
if ($columns === null) {
|
||||
$columns = $rows;
|
||||
@@ -43,7 +43,7 @@ class Builder
|
||||
array_fill(
|
||||
0,
|
||||
$columns,
|
||||
$value
|
||||
$fillValue
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -57,9 +57,9 @@ class Builder
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function createIdentityMatrix($dimensions)
|
||||
public static function createIdentityMatrix($dimensions, $fillValue = null)
|
||||
{
|
||||
$grid = static::createFilledMatrix(null, $dimensions)->toArray();
|
||||
$grid = static::createFilledMatrix($fillValue, $dimensions)->toArray();
|
||||
|
||||
for ($x = 0; $x < $dimensions; ++$x) {
|
||||
$grid[$x][$x] = 1;
|
||||
|
27
libraries/phpspreadsheet/vendor/markbaker/matrix/classes/src/Decomposition/Decomposition.php
vendored
Normal file
27
libraries/phpspreadsheet/vendor/markbaker/matrix/classes/src/Decomposition/Decomposition.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Matrix\Decomposition;
|
||||
|
||||
use Matrix\Exception;
|
||||
use Matrix\Matrix;
|
||||
|
||||
class Decomposition
|
||||
{
|
||||
const LU = 'LU';
|
||||
const QR = 'QR';
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function decomposition($type, Matrix $matrix)
|
||||
{
|
||||
switch (strtoupper($type)) {
|
||||
case self::LU:
|
||||
return new LU($matrix);
|
||||
case self::QR:
|
||||
return new QR($matrix);
|
||||
default:
|
||||
throw new Exception('Invalid Decomposition');
|
||||
}
|
||||
}
|
||||
}
|
260
libraries/phpspreadsheet/vendor/markbaker/matrix/classes/src/Decomposition/LU.php
vendored
Normal file
260
libraries/phpspreadsheet/vendor/markbaker/matrix/classes/src/Decomposition/LU.php
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
|
||||
namespace Matrix\Decomposition;
|
||||
|
||||
use Matrix\Exception;
|
||||
use Matrix\Matrix;
|
||||
|
||||
class LU
|
||||
{
|
||||
private $luMatrix;
|
||||
private $rows;
|
||||
private $columns;
|
||||
|
||||
private $pivot = [];
|
||||
|
||||
public function __construct(Matrix $matrix)
|
||||
{
|
||||
$this->luMatrix = $matrix->toArray();
|
||||
$this->rows = $matrix->rows;
|
||||
$this->columns = $matrix->columns;
|
||||
|
||||
$this->buildPivot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lower triangular factor.
|
||||
*
|
||||
* @return Matrix Lower triangular factor
|
||||
*/
|
||||
public function getL(): Matrix
|
||||
{
|
||||
$lower = [];
|
||||
|
||||
$columns = min($this->rows, $this->columns);
|
||||
for ($row = 0; $row < $this->rows; ++$row) {
|
||||
for ($column = 0; $column < $columns; ++$column) {
|
||||
if ($row > $column) {
|
||||
$lower[$row][$column] = $this->luMatrix[$row][$column];
|
||||
} elseif ($row === $column) {
|
||||
$lower[$row][$column] = 1.0;
|
||||
} else {
|
||||
$lower[$row][$column] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Matrix($lower);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get upper triangular factor.
|
||||
*
|
||||
* @return Matrix Upper triangular factor
|
||||
*/
|
||||
public function getU(): Matrix
|
||||
{
|
||||
$upper = [];
|
||||
|
||||
$rows = min($this->rows, $this->columns);
|
||||
for ($row = 0; $row < $rows; ++$row) {
|
||||
for ($column = 0; $column < $this->columns; ++$column) {
|
||||
if ($row <= $column) {
|
||||
$upper[$row][$column] = $this->luMatrix[$row][$column];
|
||||
} else {
|
||||
$upper[$row][$column] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Matrix($upper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return pivot permutation vector.
|
||||
*
|
||||
* @return Matrix Pivot matrix
|
||||
*/
|
||||
public function getP(): Matrix
|
||||
{
|
||||
$pMatrix = [];
|
||||
|
||||
$pivots = $this->pivot;
|
||||
$pivotCount = count($pivots);
|
||||
foreach ($pivots as $row => $pivot) {
|
||||
$pMatrix[$row] = array_fill(0, $pivotCount, 0);
|
||||
$pMatrix[$row][$pivot] = 1;
|
||||
}
|
||||
|
||||
return new Matrix($pMatrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return pivot permutation vector.
|
||||
*
|
||||
* @return array Pivot vector
|
||||
*/
|
||||
public function getPivot(): array
|
||||
{
|
||||
return $this->pivot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the matrix nonsingular?
|
||||
*
|
||||
* @return bool true if U, and hence A, is nonsingular
|
||||
*/
|
||||
public function isNonsingular(): bool
|
||||
{
|
||||
for ($diagonal = 0; $diagonal < $this->columns; ++$diagonal) {
|
||||
if ($this->luMatrix[$diagonal][$diagonal] === 0.0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function buildPivot(): void
|
||||
{
|
||||
for ($row = 0; $row < $this->rows; ++$row) {
|
||||
$this->pivot[$row] = $row;
|
||||
}
|
||||
|
||||
for ($column = 0; $column < $this->columns; ++$column) {
|
||||
$luColumn = $this->localisedReferenceColumn($column);
|
||||
|
||||
$this->applyTransformations($column, $luColumn);
|
||||
|
||||
$pivot = $this->findPivot($column, $luColumn);
|
||||
if ($pivot !== $column) {
|
||||
$this->pivotExchange($pivot, $column);
|
||||
}
|
||||
|
||||
$this->computeMultipliers($column);
|
||||
|
||||
unset($luColumn);
|
||||
}
|
||||
}
|
||||
|
||||
private function localisedReferenceColumn($column): array
|
||||
{
|
||||
$luColumn = [];
|
||||
|
||||
for ($row = 0; $row < $this->rows; ++$row) {
|
||||
$luColumn[$row] = &$this->luMatrix[$row][$column];
|
||||
}
|
||||
|
||||
return $luColumn;
|
||||
}
|
||||
|
||||
private function applyTransformations($column, array $luColumn): void
|
||||
{
|
||||
for ($row = 0; $row < $this->rows; ++$row) {
|
||||
$luRow = $this->luMatrix[$row];
|
||||
// Most of the time is spent in the following dot product.
|
||||
$kmax = min($row, $column);
|
||||
$sValue = 0.0;
|
||||
for ($kValue = 0; $kValue < $kmax; ++$kValue) {
|
||||
$sValue += $luRow[$kValue] * $luColumn[$kValue];
|
||||
}
|
||||
$luRow[$column] = $luColumn[$row] -= $sValue;
|
||||
}
|
||||
}
|
||||
|
||||
private function findPivot($column, array $luColumn): int
|
||||
{
|
||||
$pivot = $column;
|
||||
for ($row = $column + 1; $row < $this->rows; ++$row) {
|
||||
if (abs($luColumn[$row]) > abs($luColumn[$pivot])) {
|
||||
$pivot = $row;
|
||||
}
|
||||
}
|
||||
|
||||
return $pivot;
|
||||
}
|
||||
|
||||
private function pivotExchange($pivot, $column): void
|
||||
{
|
||||
for ($kValue = 0; $kValue < $this->columns; ++$kValue) {
|
||||
$tValue = $this->luMatrix[$pivot][$kValue];
|
||||
$this->luMatrix[$pivot][$kValue] = $this->luMatrix[$column][$kValue];
|
||||
$this->luMatrix[$column][$kValue] = $tValue;
|
||||
}
|
||||
|
||||
$lValue = $this->pivot[$pivot];
|
||||
$this->pivot[$pivot] = $this->pivot[$column];
|
||||
$this->pivot[$column] = $lValue;
|
||||
}
|
||||
|
||||
private function computeMultipliers($diagonal): void
|
||||
{
|
||||
if (($diagonal < $this->rows) && ($this->luMatrix[$diagonal][$diagonal] != 0.0)) {
|
||||
for ($row = $diagonal + 1; $row < $this->rows; ++$row) {
|
||||
$this->luMatrix[$row][$diagonal] /= $this->luMatrix[$diagonal][$diagonal];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function pivotB(Matrix $B): array
|
||||
{
|
||||
$X = [];
|
||||
foreach ($this->pivot as $rowId) {
|
||||
$row = $B->getRows($rowId + 1)->toArray();
|
||||
$X[] = array_pop($row);
|
||||
}
|
||||
|
||||
return $X;
|
||||
}
|
||||
|
||||
/**
|
||||
* Solve A*X = B.
|
||||
*
|
||||
* @param Matrix $B a Matrix with as many rows as A and any number of columns
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return Matrix X so that L*U*X = B(piv,:)
|
||||
*/
|
||||
public function solve(Matrix $B): Matrix
|
||||
{
|
||||
if ($B->rows !== $this->rows) {
|
||||
throw new Exception('Matrix row dimensions are not equal');
|
||||
}
|
||||
|
||||
if ($this->rows !== $this->columns) {
|
||||
throw new Exception('LU solve() only works on square matrices');
|
||||
}
|
||||
|
||||
if (!$this->isNonsingular()) {
|
||||
throw new Exception('Can only perform operation on singular matrix');
|
||||
}
|
||||
|
||||
// Copy right hand side with pivoting
|
||||
$nx = $B->columns;
|
||||
$X = $this->pivotB($B);
|
||||
|
||||
// Solve L*Y = B(piv,:)
|
||||
for ($k = 0; $k < $this->columns; ++$k) {
|
||||
for ($i = $k + 1; $i < $this->columns; ++$i) {
|
||||
for ($j = 0; $j < $nx; ++$j) {
|
||||
$X[$i][$j] -= $X[$k][$j] * $this->luMatrix[$i][$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Solve U*X = Y;
|
||||
for ($k = $this->columns - 1; $k >= 0; --$k) {
|
||||
for ($j = 0; $j < $nx; ++$j) {
|
||||
$X[$k][$j] /= $this->luMatrix[$k][$k];
|
||||
}
|
||||
for ($i = 0; $i < $k; ++$i) {
|
||||
for ($j = 0; $j < $nx; ++$j) {
|
||||
$X[$i][$j] -= $X[$k][$j] * $this->luMatrix[$i][$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Matrix($X);
|
||||
}
|
||||
}
|
191
libraries/phpspreadsheet/vendor/markbaker/matrix/classes/src/Decomposition/QR.php
vendored
Normal file
191
libraries/phpspreadsheet/vendor/markbaker/matrix/classes/src/Decomposition/QR.php
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
namespace Matrix\Decomposition;
|
||||
|
||||
use Matrix\Exception;
|
||||
use Matrix\Matrix;
|
||||
|
||||
class QR
|
||||
{
|
||||
private $qrMatrix;
|
||||
private $rows;
|
||||
private $columns;
|
||||
|
||||
private $rDiagonal = [];
|
||||
|
||||
public function __construct(Matrix $matrix)
|
||||
{
|
||||
$this->qrMatrix = $matrix->toArray();
|
||||
$this->rows = $matrix->rows;
|
||||
$this->columns = $matrix->columns;
|
||||
|
||||
$this->decompose();
|
||||
}
|
||||
|
||||
public function getHouseholdVectors(): Matrix
|
||||
{
|
||||
$householdVectors = [];
|
||||
for ($row = 0; $row < $this->rows; ++$row) {
|
||||
for ($column = 0; $column < $this->columns; ++$column) {
|
||||
if ($row >= $column) {
|
||||
$householdVectors[$row][$column] = $this->qrMatrix[$row][$column];
|
||||
} else {
|
||||
$householdVectors[$row][$column] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Matrix($householdVectors);
|
||||
}
|
||||
|
||||
public function getQ(): Matrix
|
||||
{
|
||||
$qGrid = [];
|
||||
|
||||
$rowCount = $this->rows;
|
||||
for ($k = $this->columns - 1; $k >= 0; --$k) {
|
||||
for ($i = 0; $i < $this->rows; ++$i) {
|
||||
$qGrid[$i][$k] = 0.0;
|
||||
}
|
||||
$qGrid[$k][$k] = 1.0;
|
||||
if ($this->columns > $this->rows) {
|
||||
$qGrid = array_slice($qGrid, 0, $this->rows);
|
||||
}
|
||||
|
||||
for ($j = $k; $j < $this->columns; ++$j) {
|
||||
if (isset($this->qrMatrix[$k], $this->qrMatrix[$k][$k]) && $this->qrMatrix[$k][$k] != 0.0) {
|
||||
$s = 0.0;
|
||||
for ($i = $k; $i < $this->rows; ++$i) {
|
||||
$s += $this->qrMatrix[$i][$k] * $qGrid[$i][$j];
|
||||
}
|
||||
$s = -$s / $this->qrMatrix[$k][$k];
|
||||
for ($i = $k; $i < $this->rows; ++$i) {
|
||||
$qGrid[$i][$j] += $s * $this->qrMatrix[$i][$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
array_walk(
|
||||
$qGrid,
|
||||
function (&$row) use ($rowCount) {
|
||||
$row = array_reverse($row);
|
||||
$row = array_slice($row, 0, $rowCount);
|
||||
}
|
||||
);
|
||||
|
||||
return new Matrix($qGrid);
|
||||
}
|
||||
|
||||
public function getR(): Matrix
|
||||
{
|
||||
$rGrid = [];
|
||||
|
||||
for ($row = 0; $row < $this->columns; ++$row) {
|
||||
for ($column = 0; $column < $this->columns; ++$column) {
|
||||
if ($row < $column) {
|
||||
$rGrid[$row][$column] = $this->qrMatrix[$row][$column] ?? 0.0;
|
||||
} elseif ($row === $column) {
|
||||
$rGrid[$row][$column] = $this->rDiagonal[$row] ?? 0.0;
|
||||
} else {
|
||||
$rGrid[$row][$column] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->columns > $this->rows) {
|
||||
$rGrid = array_slice($rGrid, 0, $this->rows);
|
||||
}
|
||||
|
||||
return new Matrix($rGrid);
|
||||
}
|
||||
|
||||
private function hypo($a, $b): float
|
||||
{
|
||||
if (abs($a) > abs($b)) {
|
||||
$r = $b / $a;
|
||||
$r = abs($a) * sqrt(1 + $r * $r);
|
||||
} elseif ($b != 0.0) {
|
||||
$r = $a / $b;
|
||||
$r = abs($b) * sqrt(1 + $r * $r);
|
||||
} else {
|
||||
$r = 0.0;
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* QR Decomposition computed by Householder reflections.
|
||||
*/
|
||||
private function decompose(): void
|
||||
{
|
||||
for ($k = 0; $k < $this->columns; ++$k) {
|
||||
// Compute 2-norm of k-th column without under/overflow.
|
||||
$norm = 0.0;
|
||||
for ($i = $k; $i < $this->rows; ++$i) {
|
||||
$norm = $this->hypo($norm, $this->qrMatrix[$i][$k]);
|
||||
}
|
||||
if ($norm != 0.0) {
|
||||
// Form k-th Householder vector.
|
||||
if ($this->qrMatrix[$k][$k] < 0.0) {
|
||||
$norm = -$norm;
|
||||
}
|
||||
for ($i = $k; $i < $this->rows; ++$i) {
|
||||
$this->qrMatrix[$i][$k] /= $norm;
|
||||
}
|
||||
$this->qrMatrix[$k][$k] += 1.0;
|
||||
// Apply transformation to remaining columns.
|
||||
for ($j = $k + 1; $j < $this->columns; ++$j) {
|
||||
$s = 0.0;
|
||||
for ($i = $k; $i < $this->rows; ++$i) {
|
||||
$s += $this->qrMatrix[$i][$k] * $this->qrMatrix[$i][$j];
|
||||
}
|
||||
$s = -$s / $this->qrMatrix[$k][$k];
|
||||
for ($i = $k; $i < $this->rows; ++$i) {
|
||||
$this->qrMatrix[$i][$j] += $s * $this->qrMatrix[$i][$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->rDiagonal[$k] = -$norm;
|
||||
}
|
||||
}
|
||||
|
||||
public function isFullRank(): bool
|
||||
{
|
||||
for ($j = 0; $j < $this->columns; ++$j) {
|
||||
if ($this->rDiagonal[$j] == 0.0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Least squares solution of A*X = B.
|
||||
*
|
||||
* @param Matrix $B a Matrix with as many rows as A and any number of columns
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return Matrix matrix that minimizes the two norm of Q*R*X-B
|
||||
*/
|
||||
public function solve(Matrix $B): Matrix
|
||||
{
|
||||
if ($B->rows !== $this->rows) {
|
||||
throw new Exception('Matrix row dimensions are not equal');
|
||||
}
|
||||
|
||||
if (!$this->isFullRank()) {
|
||||
throw new Exception('Can only perform this operation on a full-rank matrix');
|
||||
}
|
||||
|
||||
// Compute Y = transpose(Q)*B
|
||||
$Y = $this->getQ()->transpose()
|
||||
->multiply($B);
|
||||
// Solve R*X = Y;
|
||||
return $this->getR()->inverse()
|
||||
->multiply($Y);
|
||||
}
|
||||
}
|
13
libraries/phpspreadsheet/vendor/markbaker/matrix/classes/src/Div0Exception.php
vendored
Normal file
13
libraries/phpspreadsheet/vendor/markbaker/matrix/classes/src/Div0Exception.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Exception.
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Matrix;
|
||||
|
||||
class Div0Exception extends Exception
|
||||
{
|
||||
}
|
@@ -4,6 +4,25 @@ namespace Matrix;
|
||||
|
||||
class Functions
|
||||
{
|
||||
/**
|
||||
* Validates an array of matrix, converting an array to a matrix if required.
|
||||
*
|
||||
* @param Matrix|array $matrix Matrix or an array to treat as a matrix.
|
||||
* @return Matrix The new matrix
|
||||
* @throws Exception If argument isn't a valid matrix or array.
|
||||
*/
|
||||
private static function validateMatrix($matrix)
|
||||
{
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Must be Matrix or array');
|
||||
}
|
||||
|
||||
return $matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the adjoint of the matrix
|
||||
*
|
||||
@@ -25,12 +44,14 @@ class Functions
|
||||
* The adjugate has sometimes been called the "adjoint", but today the "adjoint" of a matrix normally refers
|
||||
* to its corresponding adjoint operator, which is its conjugate transpose.
|
||||
*
|
||||
* @param Matrix $matrix The matrix whose adjoint we wish to calculate
|
||||
* @param Matrix|array $matrix The matrix whose adjoint we wish to calculate
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
**/
|
||||
public static function adjoint(Matrix $matrix)
|
||||
public static function adjoint($matrix)
|
||||
{
|
||||
$matrix = self::validateMatrix($matrix);
|
||||
|
||||
if (!$matrix->isSquare()) {
|
||||
throw new Exception('Adjoint can only be calculated for a square matrix');
|
||||
}
|
||||
@@ -67,13 +88,15 @@ class Functions
|
||||
/**
|
||||
* Return the cofactors of this matrix
|
||||
*
|
||||
* @param Matrix $matrix The matrix whose cofactors we wish to calculate
|
||||
* @param Matrix|array $matrix The matrix whose cofactors we wish to calculate
|
||||
* @return Matrix
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function cofactors(Matrix $matrix)
|
||||
public static function cofactors($matrix)
|
||||
{
|
||||
$matrix = self::validateMatrix($matrix);
|
||||
|
||||
if (!$matrix->isSquare()) {
|
||||
throw new Exception('Cofactors can only be calculated for a square matrix');
|
||||
}
|
||||
@@ -141,12 +164,14 @@ class Functions
|
||||
/**
|
||||
* Return the determinant of this matrix
|
||||
*
|
||||
* @param Matrix $matrix The matrix whose determinant we wish to calculate
|
||||
* @param Matrix|array $matrix The matrix whose determinant we wish to calculate
|
||||
* @return float
|
||||
* @throws Exception
|
||||
**/
|
||||
public static function determinant(Matrix $matrix)
|
||||
public static function determinant($matrix)
|
||||
{
|
||||
$matrix = self::validateMatrix($matrix);
|
||||
|
||||
if (!$matrix->isSquare()) {
|
||||
throw new Exception('Determinant can only be calculated for a square matrix');
|
||||
}
|
||||
@@ -157,12 +182,14 @@ class Functions
|
||||
/**
|
||||
* Return the diagonal of this matrix
|
||||
*
|
||||
* @param Matrix $matrix The matrix whose diagonal we wish to calculate
|
||||
* @param Matrix|array $matrix The matrix whose diagonal we wish to calculate
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
**/
|
||||
public static function diagonal(Matrix $matrix)
|
||||
public static function diagonal($matrix)
|
||||
{
|
||||
$matrix = self::validateMatrix($matrix);
|
||||
|
||||
if (!$matrix->isSquare()) {
|
||||
throw new Exception('Diagonal can only be extracted from a square matrix');
|
||||
}
|
||||
@@ -181,12 +208,14 @@ class Functions
|
||||
/**
|
||||
* Return the antidiagonal of this matrix
|
||||
*
|
||||
* @param Matrix $matrix The matrix whose antidiagonal we wish to calculate
|
||||
* @param Matrix|array $matrix The matrix whose antidiagonal we wish to calculate
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
**/
|
||||
public static function antidiagonal(Matrix $matrix)
|
||||
public static function antidiagonal($matrix)
|
||||
{
|
||||
$matrix = self::validateMatrix($matrix);
|
||||
|
||||
if (!$matrix->isSquare()) {
|
||||
throw new Exception('Anti-Diagonal can only be extracted from a square matrix');
|
||||
}
|
||||
@@ -207,12 +236,14 @@ class Functions
|
||||
* The identity matrix, or sometimes ambiguously called a unit matrix, of size n is the n × n square matrix
|
||||
* with ones on the main diagonal and zeros elsewhere
|
||||
*
|
||||
* @param Matrix $matrix The matrix whose identity we wish to calculate
|
||||
* @param Matrix|array $matrix The matrix whose identity we wish to calculate
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
**/
|
||||
public static function identity(Matrix $matrix)
|
||||
public static function identity($matrix)
|
||||
{
|
||||
$matrix = self::validateMatrix($matrix);
|
||||
|
||||
if (!$matrix->isSquare()) {
|
||||
throw new Exception('Identity can only be created for a square matrix');
|
||||
}
|
||||
@@ -225,19 +256,21 @@ class Functions
|
||||
/**
|
||||
* Return the inverse of this matrix
|
||||
*
|
||||
* @param Matrix $matrix The matrix whose inverse we wish to calculate
|
||||
* @param Matrix|array $matrix The matrix whose inverse we wish to calculate
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
**/
|
||||
public static function inverse(Matrix $matrix)
|
||||
public static function inverse($matrix, string $type = 'inverse')
|
||||
{
|
||||
$matrix = self::validateMatrix($matrix);
|
||||
|
||||
if (!$matrix->isSquare()) {
|
||||
throw new Exception('Inverse can only be calculated for a square matrix');
|
||||
throw new Exception(ucfirst($type) . ' can only be calculated for a square matrix');
|
||||
}
|
||||
|
||||
$determinant = self::getDeterminant($matrix);
|
||||
if ($determinant == 0.0) {
|
||||
throw new Exception('Inverse can only be calculated for a matrix with a non-zero determinant');
|
||||
throw new Div0Exception(ucfirst($type) . ' can only be calculated for a matrix with a non-zero determinant');
|
||||
}
|
||||
|
||||
if ($matrix->rows == 1) {
|
||||
@@ -281,12 +314,14 @@ class Functions
|
||||
* calculating matrix cofactors, which in turn are useful for computing both the determinant and inverse of
|
||||
* square matrices.
|
||||
*
|
||||
* @param Matrix $matrix The matrix whose minors we wish to calculate
|
||||
* @param Matrix|array $matrix The matrix whose minors we wish to calculate
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
**/
|
||||
public static function minors(Matrix $matrix)
|
||||
public static function minors($matrix)
|
||||
{
|
||||
$matrix = self::validateMatrix($matrix);
|
||||
|
||||
if (!$matrix->isSquare()) {
|
||||
throw new Exception('Minors can only be calculated for a square matrix');
|
||||
}
|
||||
@@ -299,12 +334,14 @@ class Functions
|
||||
* The trace is defined as the sum of the elements on the main diagonal (the diagonal from the upper left to the lower right)
|
||||
* of the matrix
|
||||
*
|
||||
* @param Matrix $matrix The matrix whose trace we wish to calculate
|
||||
* @param Matrix|array $matrix The matrix whose trace we wish to calculate
|
||||
* @return float
|
||||
* @throws Exception
|
||||
**/
|
||||
public static function trace(Matrix $matrix)
|
||||
public static function trace($matrix)
|
||||
{
|
||||
$matrix = self::validateMatrix($matrix);
|
||||
|
||||
if (!$matrix->isSquare()) {
|
||||
throw new Exception('Trace can only be extracted from a square matrix');
|
||||
}
|
||||
@@ -321,11 +358,13 @@ class Functions
|
||||
/**
|
||||
* Return the transpose of this matrix
|
||||
*
|
||||
* @param Matrix $matrix The matrix whose transpose we wish to calculate
|
||||
* @param Matrix|\a $matrix The matrix whose transpose we wish to calculate
|
||||
* @return Matrix
|
||||
**/
|
||||
public static function transpose(Matrix $matrix)
|
||||
public static function transpose($matrix)
|
||||
{
|
||||
$matrix = self::validateMatrix($matrix);
|
||||
|
||||
$array = array_values(array_merge([null], $matrix->toArray()));
|
||||
$grid = call_user_func_array(
|
||||
'array_map',
|
||||
|
@@ -10,6 +10,10 @@
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
use Generator;
|
||||
use Matrix\Decomposition\LU;
|
||||
use Matrix\Decomposition\QR;
|
||||
|
||||
/**
|
||||
* Matrix object.
|
||||
*
|
||||
@@ -24,7 +28,6 @@ namespace Matrix;
|
||||
* @method Matrix diagonal()
|
||||
* @method Matrix identity()
|
||||
* @method Matrix inverse()
|
||||
* @method Matrix pseudoInverse()
|
||||
* @method Matrix minors()
|
||||
* @method float trace()
|
||||
* @method Matrix transpose()
|
||||
@@ -33,6 +36,7 @@ namespace Matrix;
|
||||
* @method Matrix multiply(...$matrices)
|
||||
* @method Matrix divideby(...$matrices)
|
||||
* @method Matrix divideinto(...$matrices)
|
||||
* @method Matrix directsum(...$matrices)
|
||||
*/
|
||||
class Matrix
|
||||
{
|
||||
@@ -55,7 +59,7 @@ class Matrix
|
||||
*
|
||||
* @param array $grid
|
||||
*/
|
||||
protected function buildFromArray(array $grid)
|
||||
protected function buildFromArray(array $grid): void
|
||||
{
|
||||
$this->rows = count($grid);
|
||||
$columns = array_reduce(
|
||||
@@ -86,7 +90,7 @@ class Matrix
|
||||
* @return int
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function validateRow($row)
|
||||
public static function validateRow(int $row): int
|
||||
{
|
||||
if ((!is_numeric($row)) || (intval($row) < 1)) {
|
||||
throw new Exception('Invalid Row');
|
||||
@@ -102,7 +106,7 @@ class Matrix
|
||||
* @return int
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function validateColumn($column)
|
||||
public static function validateColumn(int $column): int
|
||||
{
|
||||
if ((!is_numeric($column)) || (intval($column) < 1)) {
|
||||
throw new Exception('Invalid Column');
|
||||
@@ -118,7 +122,7 @@ class Matrix
|
||||
* @return int
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function validateRowInRange($row)
|
||||
protected function validateRowInRange(int $row): int
|
||||
{
|
||||
$row = static::validateRow($row);
|
||||
if ($row > $this->rows) {
|
||||
@@ -135,7 +139,7 @@ class Matrix
|
||||
* @return int
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function validateColumnInRange($column)
|
||||
protected function validateColumnInRange(int $column): int
|
||||
{
|
||||
$column = static::validateColumn($column);
|
||||
if ($column > $this->columns) {
|
||||
@@ -157,7 +161,7 @@ class Matrix
|
||||
* @return static
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getRows($row, $rowCount = 1)
|
||||
public function getRows(int $row, int $rowCount = 1): Matrix
|
||||
{
|
||||
$row = $this->validateRowInRange($row);
|
||||
if ($rowCount === 0) {
|
||||
@@ -179,7 +183,7 @@ class Matrix
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getColumns($column, $columnCount = 1)
|
||||
public function getColumns(int $column, int $columnCount = 1): Matrix
|
||||
{
|
||||
$column = $this->validateColumnInRange($column);
|
||||
if ($columnCount < 1) {
|
||||
@@ -207,7 +211,7 @@ class Matrix
|
||||
* @return static
|
||||
* @throws Exception
|
||||
*/
|
||||
public function dropRows($row, $rowCount = 1)
|
||||
public function dropRows(int $row, int $rowCount = 1): Matrix
|
||||
{
|
||||
$this->validateRowInRange($row);
|
||||
if ($rowCount === 0) {
|
||||
@@ -233,7 +237,7 @@ class Matrix
|
||||
* @return static
|
||||
* @throws Exception
|
||||
*/
|
||||
public function dropColumns($column, $columnCount = 1)
|
||||
public function dropColumns(int $column, int $columnCount = 1): Matrix
|
||||
{
|
||||
$this->validateColumnInRange($column);
|
||||
if ($columnCount < 1) {
|
||||
@@ -260,7 +264,7 @@ class Matrix
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getValue($row, $column)
|
||||
public function getValue(int $row, int $column)
|
||||
{
|
||||
$row = $this->validateRowInRange($row);
|
||||
$column = $this->validateColumnInRange($column);
|
||||
@@ -270,11 +274,11 @@ class Matrix
|
||||
|
||||
/**
|
||||
* Returns a Generator that will yield each row of the matrix in turn as a vector matrix
|
||||
* or the value of each cell if the matrix is a vector
|
||||
* or the value of each cell if the matrix is a column vector
|
||||
*
|
||||
* @return \Generator|Matrix[]|mixed[]
|
||||
* @return Generator|Matrix[]|mixed[]
|
||||
*/
|
||||
public function rows()
|
||||
public function rows(): Generator
|
||||
{
|
||||
foreach ($this->grid as $i => $row) {
|
||||
yield $i + 1 => ($this->columns == 1)
|
||||
@@ -285,11 +289,11 @@ class Matrix
|
||||
|
||||
/**
|
||||
* Returns a Generator that will yield each column of the matrix in turn as a vector matrix
|
||||
* or the value of each cell if the matrix is a vector
|
||||
* or the value of each cell if the matrix is a row vector
|
||||
*
|
||||
* @return \Generator|Matrix[]|mixed[]
|
||||
* @return Generator|Matrix[]|mixed[]
|
||||
*/
|
||||
public function columns()
|
||||
public function columns(): Generator
|
||||
{
|
||||
for ($i = 0; $i < $this->columns; ++$i) {
|
||||
yield $i + 1 => ($this->rows == 1)
|
||||
@@ -304,9 +308,9 @@ class Matrix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSquare()
|
||||
public function isSquare(): bool
|
||||
{
|
||||
return $this->rows == $this->columns;
|
||||
return $this->rows === $this->columns;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -315,9 +319,9 @@ class Matrix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isVector()
|
||||
public function isVector(): bool
|
||||
{
|
||||
return $this->rows == 1 || $this->columns == 1;
|
||||
return $this->rows === 1 || $this->columns === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,11 +329,29 @@ class Matrix
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->grid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Solve A*X = B.
|
||||
*
|
||||
* @param Matrix $B Right hand side
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return Matrix ... Solution if A is square, least squares solution otherwise
|
||||
*/
|
||||
public function solve(Matrix $B): Matrix
|
||||
{
|
||||
if ($this->columns === $this->rows) {
|
||||
return (new LU($this))->solve($B);
|
||||
}
|
||||
|
||||
return (new QR($this))->solve($B);
|
||||
}
|
||||
|
||||
protected static $getters = [
|
||||
'rows',
|
||||
'columns',
|
||||
@@ -342,7 +364,7 @@ class Matrix
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __get($propertyName)
|
||||
public function __get(string $propertyName)
|
||||
{
|
||||
$propertyName = strtolower($propertyName);
|
||||
|
||||
@@ -355,8 +377,8 @@ class Matrix
|
||||
}
|
||||
|
||||
protected static $functions = [
|
||||
'antidiagonal',
|
||||
'adjoint',
|
||||
'antidiagonal',
|
||||
'cofactors',
|
||||
'determinant',
|
||||
'diagonal',
|
||||
@@ -384,16 +406,17 @@ class Matrix
|
||||
* @return Matrix|float
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __call($functionName, $arguments)
|
||||
public function __call(string $functionName, $arguments)
|
||||
{
|
||||
$functionName = strtolower(str_replace('_', '', $functionName));
|
||||
|
||||
if (in_array($functionName, self::$functions) || in_array($functionName, self::$operations)) {
|
||||
$functionName = "\\" . __NAMESPACE__ . "\\{$functionName}";
|
||||
if (is_callable($functionName)) {
|
||||
$arguments = array_values(array_merge([$this], $arguments));
|
||||
return call_user_func_array($functionName, $arguments);
|
||||
}
|
||||
// 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('Function or Operation does not exist');
|
||||
}
|
||||
|
157
libraries/phpspreadsheet/vendor/markbaker/matrix/classes/src/Operations.php
vendored
Normal file
157
libraries/phpspreadsheet/vendor/markbaker/matrix/classes/src/Operations.php
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
use Matrix\Operators\Addition;
|
||||
use Matrix\Operators\DirectSum;
|
||||
use Matrix\Operators\Division;
|
||||
use Matrix\Operators\Multiplication;
|
||||
use Matrix\Operators\Subtraction;
|
||||
|
||||
class Operations
|
||||
{
|
||||
public static function add(...$matrixValues): Matrix
|
||||
{
|
||||
if (count($matrixValues) < 2) {
|
||||
throw new Exception('Addition operation requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$matrix = array_shift($matrixValues);
|
||||
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Addition arguments must be Matrix or array');
|
||||
}
|
||||
|
||||
$result = new Addition($matrix);
|
||||
|
||||
foreach ($matrixValues as $matrix) {
|
||||
$result->execute($matrix);
|
||||
}
|
||||
|
||||
return $result->result();
|
||||
}
|
||||
|
||||
public static function directsum(...$matrixValues): Matrix
|
||||
{
|
||||
if (count($matrixValues) < 2) {
|
||||
throw new Exception('DirectSum operation requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$matrix = array_shift($matrixValues);
|
||||
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('DirectSum arguments must be Matrix or array');
|
||||
}
|
||||
|
||||
$result = new DirectSum($matrix);
|
||||
|
||||
foreach ($matrixValues as $matrix) {
|
||||
$result->execute($matrix);
|
||||
}
|
||||
|
||||
return $result->result();
|
||||
}
|
||||
|
||||
public static function divideby(...$matrixValues): Matrix
|
||||
{
|
||||
if (count($matrixValues) < 2) {
|
||||
throw new Exception('Division operation requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$matrix = array_shift($matrixValues);
|
||||
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Division arguments must be Matrix or array');
|
||||
}
|
||||
|
||||
$result = new Division($matrix);
|
||||
|
||||
foreach ($matrixValues as $matrix) {
|
||||
$result->execute($matrix);
|
||||
}
|
||||
|
||||
return $result->result();
|
||||
}
|
||||
|
||||
public static function divideinto(...$matrixValues): Matrix
|
||||
{
|
||||
if (count($matrixValues) < 2) {
|
||||
throw new Exception('Division operation requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$matrix = array_pop($matrixValues);
|
||||
$matrixValues = array_reverse($matrixValues);
|
||||
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Division arguments must be Matrix or array');
|
||||
}
|
||||
|
||||
$result = new Division($matrix);
|
||||
|
||||
foreach ($matrixValues as $matrix) {
|
||||
$result->execute($matrix);
|
||||
}
|
||||
|
||||
return $result->result();
|
||||
}
|
||||
|
||||
public static function multiply(...$matrixValues): Matrix
|
||||
{
|
||||
if (count($matrixValues) < 2) {
|
||||
throw new Exception('Multiplication operation requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$matrix = array_shift($matrixValues);
|
||||
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Multiplication arguments must be Matrix or array');
|
||||
}
|
||||
|
||||
$result = new Multiplication($matrix);
|
||||
|
||||
foreach ($matrixValues as $matrix) {
|
||||
$result->execute($matrix);
|
||||
}
|
||||
|
||||
return $result->result();
|
||||
}
|
||||
|
||||
public static function subtract(...$matrixValues): Matrix
|
||||
{
|
||||
if (count($matrixValues) < 2) {
|
||||
throw new Exception('Subtraction operation requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$matrix = array_shift($matrixValues);
|
||||
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Subtraction arguments must be Matrix or array');
|
||||
}
|
||||
|
||||
$result = new Subtraction($matrix);
|
||||
|
||||
foreach ($matrixValues as $matrix) {
|
||||
$result->execute($matrix);
|
||||
}
|
||||
|
||||
return $result->result();
|
||||
}
|
||||
}
|
@@ -14,7 +14,7 @@ class Addition extends Operator
|
||||
* @throws Exception If the provided argument is not appropriate for the operation
|
||||
* @return $this The operation object, allowing multiple additions to be chained
|
||||
**/
|
||||
public function execute($value)
|
||||
public function execute($value): Operator
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$value = new Matrix($value);
|
||||
@@ -35,7 +35,7 @@ class Addition extends Operator
|
||||
* @param mixed $value The numeric value to add to the current base value
|
||||
* @return $this The operation object, allowing multiple additions to be chained
|
||||
**/
|
||||
protected function addScalar($value)
|
||||
protected function addScalar($value): Operator
|
||||
{
|
||||
for ($row = 0; $row < $this->rows; ++$row) {
|
||||
for ($column = 0; $column < $this->columns; ++$column) {
|
||||
@@ -53,7 +53,7 @@ class Addition extends Operator
|
||||
* @return $this The operation object, allowing multiple additions to be chained
|
||||
* @throws Exception If the provided argument is not appropriate for the operation
|
||||
**/
|
||||
protected function addMatrix(Matrix $value)
|
||||
protected function addMatrix(Matrix $value): Operator
|
||||
{
|
||||
$this->validateMatchingDimensions($value);
|
||||
|
||||
|
@@ -14,7 +14,7 @@ class DirectSum extends Operator
|
||||
* @return $this The operation object, allowing multiple additions to be chained
|
||||
* @throws Exception If the provided argument is not appropriate for the operation
|
||||
*/
|
||||
public function execute($value)
|
||||
public function execute($value): Operator
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$value = new Matrix($value);
|
||||
@@ -33,7 +33,7 @@ class DirectSum extends Operator
|
||||
* @param Matrix $value The numeric value to concatenate/direct sum with the current base value
|
||||
* @return $this The operation object, allowing multiple additions to be chained
|
||||
**/
|
||||
private function directSumMatrix($value)
|
||||
private function directSumMatrix($value): Operator
|
||||
{
|
||||
$originalColumnCount = count($this->matrix[0]);
|
||||
$originalRowCount = count($this->matrix);
|
||||
|
@@ -2,9 +2,10 @@
|
||||
|
||||
namespace Matrix\Operators;
|
||||
|
||||
use Matrix\Div0Exception;
|
||||
use Matrix\Exception;
|
||||
use \Matrix\Matrix;
|
||||
use \Matrix\Functions;
|
||||
use Matrix\Exception;
|
||||
|
||||
class Division extends Multiplication
|
||||
{
|
||||
@@ -15,22 +16,18 @@ class Division extends Multiplication
|
||||
* @throws Exception If the provided argument is not appropriate for the operation
|
||||
* @return $this The operation object, allowing multiple divisions to be chained
|
||||
**/
|
||||
public function execute($value)
|
||||
public function execute($value, string $type = 'division'): Operator
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$value = new Matrix($value);
|
||||
}
|
||||
|
||||
if (is_object($value) && ($value instanceof Matrix)) {
|
||||
try {
|
||||
$value = Functions::inverse($value);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception('Division can only be calculated using a matrix with a non-zero determinant');
|
||||
}
|
||||
$value = Functions::inverse($value, $type);
|
||||
|
||||
return $this->multiplyMatrix($value);
|
||||
return $this->multiplyMatrix($value, $type);
|
||||
} elseif (is_numeric($value)) {
|
||||
return $this->multiplyScalar(1 / $value);
|
||||
return $this->multiplyScalar(1 / $value, $type);
|
||||
}
|
||||
|
||||
throw new Exception('Invalid argument for division');
|
||||
|
@@ -5,6 +5,7 @@ namespace Matrix\Operators;
|
||||
use Matrix\Matrix;
|
||||
use \Matrix\Builder;
|
||||
use Matrix\Exception;
|
||||
use Throwable;
|
||||
|
||||
class Multiplication extends Operator
|
||||
{
|
||||
@@ -15,19 +16,19 @@ class Multiplication extends Operator
|
||||
* @throws Exception If the provided argument is not appropriate for the operation
|
||||
* @return $this The operation object, allowing multiple multiplications to be chained
|
||||
**/
|
||||
public function execute($value)
|
||||
public function execute($value, string $type = 'multiplication'): Operator
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$value = new Matrix($value);
|
||||
}
|
||||
|
||||
if (is_object($value) && ($value instanceof Matrix)) {
|
||||
return $this->multiplyMatrix($value);
|
||||
return $this->multiplyMatrix($value, $type);
|
||||
} elseif (is_numeric($value)) {
|
||||
return $this->multiplyScalar($value);
|
||||
return $this->multiplyScalar($value, $type);
|
||||
}
|
||||
|
||||
throw new Exception('Invalid argument for multiplication');
|
||||
throw new Exception("Invalid argument for $type");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,12 +37,16 @@ class Multiplication extends Operator
|
||||
* @param mixed $value The numeric value to multiply with the current base value
|
||||
* @return $this The operation object, allowing multiple mutiplications to be chained
|
||||
**/
|
||||
protected function multiplyScalar($value)
|
||||
protected function multiplyScalar($value, string $type = 'multiplication'): Operator
|
||||
{
|
||||
for ($row = 0; $row < $this->rows; ++$row) {
|
||||
for ($column = 0; $column < $this->columns; ++$column) {
|
||||
$this->matrix[$row][$column] *= $value;
|
||||
try {
|
||||
for ($row = 0; $row < $this->rows; ++$row) {
|
||||
for ($column = 0; $column < $this->columns; ++$column) {
|
||||
$this->matrix[$row][$column] *= $value;
|
||||
}
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
throw new Exception("Invalid argument for $type");
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -54,7 +59,7 @@ class Multiplication extends Operator
|
||||
* @return $this The operation object, allowing multiple mutiplications to be chained
|
||||
* @throws Exception If the provided argument is not appropriate for the operation
|
||||
**/
|
||||
protected function multiplyMatrix(Matrix $value)
|
||||
protected function multiplyMatrix(Matrix $value, string $type = 'multiplication'): Operator
|
||||
{
|
||||
$this->validateReflectingDimensions($value);
|
||||
|
||||
@@ -62,13 +67,17 @@ class Multiplication extends Operator
|
||||
$newColumns = $value->columns;
|
||||
$matrix = Builder::createFilledMatrix(0, $newRows, $newColumns)
|
||||
->toArray();
|
||||
for ($row = 0; $row < $newRows; ++$row) {
|
||||
for ($column = 0; $column < $newColumns; ++$column) {
|
||||
$columnData = $value->getColumns($column + 1)->toArray();
|
||||
foreach ($this->matrix[$row] as $key => $valueData) {
|
||||
$matrix[$row][$column] += $valueData * $columnData[$key][0];
|
||||
try {
|
||||
for ($row = 0; $row < $newRows; ++$row) {
|
||||
for ($column = 0; $column < $newColumns; ++$column) {
|
||||
$columnData = $value->getColumns($column + 1)->toArray();
|
||||
foreach ($this->matrix[$row] as $key => $valueData) {
|
||||
$matrix[$row][$column] += $valueData * $columnData[$key][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
throw new Exception("Invalid argument for $type");
|
||||
}
|
||||
$this->matrix = $matrix;
|
||||
|
||||
|
@@ -46,7 +46,7 @@ abstract class Operator
|
||||
* @param Matrix $matrix The second Matrix object on which the operation will be performed
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function validateMatchingDimensions(Matrix $matrix)
|
||||
protected function validateMatchingDimensions(Matrix $matrix): void
|
||||
{
|
||||
if (($this->rows != $matrix->rows) || ($this->columns != $matrix->columns)) {
|
||||
throw new Exception('Matrices have mismatched dimensions');
|
||||
@@ -59,7 +59,7 @@ abstract class Operator
|
||||
* @param Matrix $matrix The second Matrix object on which the operation will be performed
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function validateReflectingDimensions(Matrix $matrix)
|
||||
protected function validateReflectingDimensions(Matrix $matrix): void
|
||||
{
|
||||
if ($this->columns != $matrix->rows) {
|
||||
throw new Exception('Matrices have mismatched dimensions');
|
||||
@@ -71,7 +71,7 @@ abstract class Operator
|
||||
*
|
||||
* @return Matrix
|
||||
*/
|
||||
public function result()
|
||||
public function result(): Matrix
|
||||
{
|
||||
return new Matrix($this->matrix);
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ class Subtraction extends Operator
|
||||
* @throws Exception If the provided argument is not appropriate for the operation
|
||||
* @return $this The operation object, allowing multiple subtractions to be chained
|
||||
**/
|
||||
public function execute($value)
|
||||
public function execute($value): Operator
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$value = new Matrix($value);
|
||||
@@ -35,7 +35,7 @@ class Subtraction extends Operator
|
||||
* @param mixed $value The numeric value to subtracted from the current base value
|
||||
* @return $this The operation object, allowing multiple additions to be chained
|
||||
**/
|
||||
protected function subtractScalar($value)
|
||||
protected function subtractScalar($value): Operator
|
||||
{
|
||||
for ($row = 0; $row < $this->rows; ++$row) {
|
||||
for ($column = 0; $column < $this->columns; ++$column) {
|
||||
@@ -53,7 +53,7 @@ class Subtraction extends Operator
|
||||
* @return $this The operation object, allowing multiple subtractions to be chained
|
||||
* @throws Exception If the provided argument is not appropriate for the operation
|
||||
**/
|
||||
protected function subtractMatrix(Matrix $value)
|
||||
protected function subtractMatrix(Matrix $value): Operator
|
||||
{
|
||||
$this->validateMatchingDimensions($value);
|
||||
|
||||
|
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix adjoint() function
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
/**
|
||||
* Returns the adjoint of a matrix or an array.
|
||||
*
|
||||
* @param Matrix|array $matrix Matrix or an array to treat as a matrix.
|
||||
* @return Matrix The new matrix
|
||||
* @throws Exception If argument isn't a valid matrix or array.
|
||||
*/
|
||||
function adjoint($matrix)
|
||||
{
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Must be Matrix or array');
|
||||
}
|
||||
|
||||
return Functions::adjoint($matrix);
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix antidiagonal() function
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Matrix;
|
||||
|
||||
/**
|
||||
* Returns the antidiagonal of a matrix or an array.
|
||||
*
|
||||
* @param Matrix|array $matrix Matrix or an array to treat as a matrix.
|
||||
* @return Matrix The new matrix
|
||||
* @throws Exception If argument isn't a valid matrix or array.
|
||||
*/
|
||||
function antidiagonal($matrix)
|
||||
{
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Must be Matrix or array');
|
||||
}
|
||||
|
||||
return Functions::antidiagonal($matrix);
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix cofactors() function
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
/**
|
||||
* Returns the cofactors of a matrix or an array.
|
||||
*
|
||||
* @param Matrix|array $matrix Matrix or an array to treat as a matrix.
|
||||
* @return Matrix The new matrix
|
||||
* @throws Exception If argument isn't a valid matrix or array.
|
||||
*/
|
||||
function cofactors($matrix)
|
||||
{
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Must be Matrix or array');
|
||||
}
|
||||
|
||||
return Functions::cofactors($matrix);
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix determinant() function
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
/**
|
||||
* Returns the determinant of a matrix or an array.
|
||||
*
|
||||
* @param Matrix|array $matrix Matrix or an array to treat as a matrix.
|
||||
* @return float Matrix determinant
|
||||
* @throws Exception If argument isn't a valid matrix or array.
|
||||
*/
|
||||
function determinant($matrix)
|
||||
{
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Must be Matrix or array');
|
||||
}
|
||||
|
||||
return Functions::determinant($matrix);
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix diagonal() function
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
/**
|
||||
* Returns the diagonal of a matrix or an array.
|
||||
*
|
||||
* @param Matrix|array $matrix Matrix or an array to treat as a matrix.
|
||||
* @return Matrix The new matrix
|
||||
* @throws Exception If argument isn't a valid matrix or array.
|
||||
*/
|
||||
function diagonal($matrix)
|
||||
{
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Must be Matrix or array');
|
||||
}
|
||||
|
||||
return Functions::diagonal($matrix);
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix identity() function
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
/**
|
||||
* Returns the identity of a matrix or an array.
|
||||
*
|
||||
* @param Matrix|array $matrix Matrix or an array to treat as a matrix.
|
||||
* @return Matrix The identity matrix
|
||||
* @throws Exception If argument isn't a valid matrix or array.
|
||||
*/
|
||||
function identity($matrix)
|
||||
{
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Must be Matrix or array');
|
||||
}
|
||||
|
||||
return Functions::identity($matrix);
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix inverse() function
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
/**
|
||||
* Returns the inverse of a matrix or an array.
|
||||
*
|
||||
* @param Matrix|array $matrix Matrix or an array to treat as a matrix.
|
||||
* @return Matrix The new matrix
|
||||
* @throws Exception If argument isn't a valid matrix or array.
|
||||
*/
|
||||
function inverse($matrix)
|
||||
{
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Must be Matrix or array');
|
||||
}
|
||||
|
||||
return Functions::inverse($matrix);
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix minors() function
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
/**
|
||||
* Returns the minors of a matrix or an array.
|
||||
*
|
||||
* @param Matrix|array $matrix Matrix or an array to treat as a matrix.
|
||||
* @return Matrix The new matrix
|
||||
* @throws Exception If argument isn't a valid matrix or array.
|
||||
*/
|
||||
function minors($matrix)
|
||||
{
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Must be Matrix or array');
|
||||
}
|
||||
|
||||
return Functions::minors($matrix);
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix trace() function
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
/**
|
||||
* Returns the trace of a matrix or an array.
|
||||
*
|
||||
* @param Matrix|array $matrix Matrix or an array to treat as a matrix.
|
||||
* @return float The trace of the matrix
|
||||
* @throws Exception If argument isn't a valid matrix or array.
|
||||
*/
|
||||
function trace($matrix)
|
||||
{
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Must be Matrix or array');
|
||||
}
|
||||
|
||||
return Functions::trace($matrix);
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix transpose() function
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
/**
|
||||
* Returns the transpose of a matrix or an array.
|
||||
*
|
||||
* @param Matrix|array $matrix Matrix or an array to treat as a matrix.
|
||||
* @return Matrix The transposed matrix
|
||||
* @throws Exception If argument isn't a valid matrix or array.
|
||||
*/
|
||||
function transpose($matrix)
|
||||
{
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Must be Matrix or array');
|
||||
}
|
||||
|
||||
return Functions::transpose($matrix);
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix addition operation
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
use Matrix\Operators\Addition;
|
||||
|
||||
/**
|
||||
* Adds two or more matrices
|
||||
*
|
||||
* @param array<int, mixed> $matrixValues The matrices to add
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
*/
|
||||
function add(...$matrixValues)
|
||||
{
|
||||
if (count($matrixValues) < 2) {
|
||||
throw new Exception('Addition operation requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$matrix = array_shift($matrixValues);
|
||||
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Addition arguments must be Matrix or array');
|
||||
}
|
||||
|
||||
$result = new Addition($matrix);
|
||||
|
||||
foreach ($matrixValues as $matrix) {
|
||||
$result->execute($matrix);
|
||||
}
|
||||
|
||||
return $result->result();
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix direct sum operation
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
use Matrix\Operators\DirectSum;
|
||||
|
||||
/**
|
||||
* Adds two or more matrices
|
||||
*
|
||||
* @param array<int, mixed> $matrixValues The matrices to add
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
*/
|
||||
function directsum(...$matrixValues)
|
||||
{
|
||||
if (count($matrixValues) < 2) {
|
||||
throw new Exception('DirectSum operation requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$matrix = array_shift($matrixValues);
|
||||
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('DirectSum arguments must be Matrix or array');
|
||||
}
|
||||
|
||||
$result = new DirectSum($matrix);
|
||||
|
||||
foreach ($matrixValues as $matrix) {
|
||||
$result->execute($matrix);
|
||||
}
|
||||
|
||||
return $result->result();
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix division operation
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
use Matrix\Operators\Division;
|
||||
|
||||
/**
|
||||
* Divides two or more matrix numbers
|
||||
*
|
||||
* @param array<int, mixed> $matrixValues The matrices to divide
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
*/
|
||||
function divideby(...$matrixValues)
|
||||
{
|
||||
if (count($matrixValues) < 2) {
|
||||
throw new Exception('Division operation requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$matrix = array_shift($matrixValues);
|
||||
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Division arguments must be Matrix or array');
|
||||
}
|
||||
|
||||
$result = new Division($matrix);
|
||||
|
||||
foreach ($matrixValues as $matrix) {
|
||||
$result->execute($matrix);
|
||||
}
|
||||
|
||||
return $result->result();
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix division operation
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
use Matrix\Operators\Division;
|
||||
|
||||
/**
|
||||
* Divides two or more matrix numbers
|
||||
*
|
||||
* @param array<int, mixed> $matrixValues The numbers to divide
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
*/
|
||||
function divideinto(...$matrixValues)
|
||||
{
|
||||
if (count($matrixValues) < 2) {
|
||||
throw new Exception('Division operation requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$matrix = array_shift($matrixValues);
|
||||
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Division arguments must be Matrix or array');
|
||||
}
|
||||
|
||||
$result = new Division($matrix);
|
||||
|
||||
foreach ($matrixValues as $matrix) {
|
||||
$result->execute($matrix);
|
||||
}
|
||||
|
||||
return $result->result();
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix multiplication operation
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
use Matrix\Operators\Multiplication;
|
||||
|
||||
/**
|
||||
* Multiplies two or more matrices
|
||||
*
|
||||
* @param array<int, mixed> $matrixValues The matrices to multiply
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
*/
|
||||
function multiply(...$matrixValues)
|
||||
{
|
||||
if (count($matrixValues) < 2) {
|
||||
throw new Exception('Multiplication operation requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$matrix = array_shift($matrixValues);
|
||||
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Multiplication arguments must be Matrix or array');
|
||||
}
|
||||
|
||||
$result = new Multiplication($matrix);
|
||||
|
||||
foreach ($matrixValues as $matrix) {
|
||||
$result->execute($matrix);
|
||||
}
|
||||
|
||||
return $result->result();
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the matrix subtraction operation
|
||||
*
|
||||
* @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
namespace Matrix;
|
||||
|
||||
use Matrix\Operators\Subtraction;
|
||||
|
||||
/**
|
||||
* Subtracts two or more matrices
|
||||
*
|
||||
* @param array<int, mixed> $matrixValues The matrices to subtract
|
||||
* @return Matrix
|
||||
* @throws Exception
|
||||
*/
|
||||
function subtract(...$matrixValues)
|
||||
{
|
||||
if (count($matrixValues) < 2) {
|
||||
throw new Exception('Subtraction operation requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$matrix = array_shift($matrixValues);
|
||||
|
||||
if (is_array($matrix)) {
|
||||
$matrix = new Matrix($matrix);
|
||||
}
|
||||
if (!$matrix instanceof Matrix) {
|
||||
throw new Exception('Subtraction arguments must be Matrix or array');
|
||||
}
|
||||
|
||||
$result = new Subtraction($matrix);
|
||||
|
||||
foreach ($matrixValues as $matrix) {
|
||||
$result->execute($matrix);
|
||||
}
|
||||
|
||||
return $result->result();
|
||||
}
|
52
libraries/phpspreadsheet/vendor/markbaker/matrix/composer.json
vendored
Normal file
52
libraries/phpspreadsheet/vendor/markbaker/matrix/composer.json
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "markbaker/matrix",
|
||||
"type": "library",
|
||||
"description": "PHP Class for working with matrices",
|
||||
"keywords": ["matrix", "vector", "mathematics"],
|
||||
"homepage": "https://github.com/MarkBaker/PHPMatrix",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"email": "mark@demon-angel.eu"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||
"phpdocumentor/phpdocumentor": "2.*",
|
||||
"phpmd/phpmd": "2.*",
|
||||
"sebastian/phpcpd": "^4.0",
|
||||
"phploc/phploc": "^4.0",
|
||||
"squizlabs/php_codesniffer": "^3.7",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-master"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Matrix\\": "classes/src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"MatrixTest\\": "unitTests/classes/src/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"style": "phpcs --report-width=200 --standard=PSR2 --report=summary,full classes/src/ unitTests/classes/src -n",
|
||||
"test": "phpunit -c phpunit.xml.dist",
|
||||
"mess": "phpmd classes/src/ xml codesize,unusedcode,design,naming -n",
|
||||
"lines": "phploc classes/src/ -n",
|
||||
"cpd": "phpcpd classes/src/ -n",
|
||||
"versions": "phpcs --report-width=200 --standard=PHPCompatibility --report=summary,full classes/src/ --runtime-set testVersion 7.2- -n",
|
||||
"coverage": "phpunit -c phpunit.xml.dist --coverage-text --coverage-html ./build/coverage"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
}
|
||||
}
|
||||
}
|
33
libraries/phpspreadsheet/vendor/markbaker/matrix/examples/test.php
vendored
Normal file
33
libraries/phpspreadsheet/vendor/markbaker/matrix/examples/test.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Matrix\Matrix;
|
||||
use Matrix\Decomposition\QR;
|
||||
|
||||
include __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
$grid = [
|
||||
[0, 1],
|
||||
[-1, 0],
|
||||
];
|
||||
|
||||
$targetGrid = [
|
||||
[-1],
|
||||
[2],
|
||||
];
|
||||
|
||||
$matrix = new Matrix($grid);
|
||||
$target = new Matrix($targetGrid);
|
||||
|
||||
$decomposition = new QR($matrix);
|
||||
|
||||
$X = $decomposition->solve($target);
|
||||
|
||||
echo 'X', PHP_EOL;
|
||||
var_export($X->toArray());
|
||||
echo PHP_EOL;
|
||||
|
||||
$resolve = $matrix->multiply($X);
|
||||
|
||||
echo 'Resolve', PHP_EOL;
|
||||
var_export($resolve->toArray());
|
||||
echo PHP_EOL;
|
17
libraries/phpspreadsheet/vendor/markbaker/matrix/infection.json.dist
vendored
Normal file
17
libraries/phpspreadsheet/vendor/markbaker/matrix/infection.json.dist
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"timeout": 1,
|
||||
"source": {
|
||||
"directories": [
|
||||
"classes\/src"
|
||||
]
|
||||
},
|
||||
"logs": {
|
||||
"text": "build/infection/text.log",
|
||||
"summary": "build/infection/summary.log",
|
||||
"debug": "build/infection/debug.log",
|
||||
"perMutator": "build/infection/perMutator.md"
|
||||
},
|
||||
"mutators": {
|
||||
"@default": true
|
||||
}
|
||||
}
|
25
libraries/phpspreadsheet/vendor/markbaker/matrix/license.md
vendored
Normal file
25
libraries/phpspreadsheet/vendor/markbaker/matrix/license.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
The MIT License (MIT)
|
||||
=====================
|
||||
|
||||
Copyright © `2018` `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.
|
6
libraries/phpspreadsheet/vendor/markbaker/matrix/phpstan.neon
vendored
Normal file
6
libraries/phpspreadsheet/vendor/markbaker/matrix/phpstan.neon
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
- '#Property [A-Za-z\\]+::\$[A-Za-z]+ has no typehint specified#'
|
||||
- '#Method [A-Za-z\\]+::[A-Za-z]+\(\) has no return typehint specified#'
|
||||
- '#Method [A-Za-z\\]+::[A-Za-z]+\(\) has parameter \$[A-Za-z0-9]+ with no typehint specified#'
|
||||
checkMissingIterableValueType: false
|
Reference in New Issue
Block a user