From 291ea88a6cf148b7030a0e3ada404ec8b13e47a9 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 9 Feb 2022 15:12:54 +0100 Subject: [PATCH] Initial work enabling Excel function implementations for handling arrays as arguments when used in "array formulae". (#2562) * Initial work enabling Excel function implementations for handling arrays as aguments when used in "array formulae". So far: - handling for single argument functions - for functions where only one of the arguments is an array (a matrix or a row/column vector) - for when there are two array arguments, and one is a row vector, the other a column vector - for when there are either 2 row vectors, or 2 column vectors - for a matrix and either a row or column vector Will work ok, as long as there are no more than two array arguments; still need to identify the logic to apply when there are more than two arrays; or there are two that aren't an already supported row vector/column vector pairing (ie two matrices). * Throw an exception if we have three or more array arguments (after flattening) passed to a supported function until we can identify the abstruse non-euclidian logic behind how Excel handles building, using and presenting those n-dimensional result arrays * Implement array arguments for the DATE() function so that we can verify that paired arrays/vectors work with functions that support more than 2 arguments * Implement array arguments for the many of the Math/Trig functions * Update change log --- CHANGELOG.md | 3 + phpstan-baseline.neon | 93 ++++---- .../Calculation/ArrayEnabled.php | 190 ++++++++++++++++ .../Calculation/DateTimeExcel/Date.php | 15 +- .../Engine/ArrayArgumentHelper.php | 202 ++++++++++++++++++ src/PhpSpreadsheet/Calculation/MathTrig.php | 166 +++++++------- .../Calculation/MathTrig/Absolute.php | 13 +- .../Calculation/MathTrig/Angle.php | 23 +- .../Calculation/MathTrig/Arabic.php | 13 +- .../Calculation/MathTrig/Combinations.php | 35 ++- .../Calculation/MathTrig/Exp.php | 13 +- .../Calculation/MathTrig/Factorial.php | 23 +- .../Calculation/MathTrig/IntClass.php | 13 +- .../Calculation/MathTrig/Round.php | 71 ++++-- .../Calculation/MathTrig/Sign.php | 13 +- .../Calculation/MathTrig/Sqrt.php | 23 +- .../Calculation/MathTrig/Trig/Cosecant.php | 23 +- .../Calculation/MathTrig/Trig/Cosine.php | 43 +++- .../Calculation/MathTrig/Trig/Cotangent.php | 43 +++- .../Calculation/MathTrig/Trig/Secant.php | 23 +- .../Calculation/MathTrig/Trig/Sine.php | 43 +++- .../Calculation/MathTrig/Trig/Tangent.php | 56 ++++- .../Functions/DateTime/DateTest.php | 93 ++++++++ .../Functions/MathTrig/AbsTest.php | 23 ++ .../Functions/MathTrig/AcosTest.php | 23 ++ .../Functions/MathTrig/AcoshTest.php | 23 ++ .../Functions/MathTrig/AcotTest.php | 23 ++ .../Functions/MathTrig/AcothTest.php | 23 ++ .../Functions/MathTrig/ArabicTest.php | 23 ++ .../Functions/MathTrig/AsinTest.php | 23 ++ .../Functions/MathTrig/AsinhTest.php | 23 ++ .../Functions/MathTrig/Atan2Test.php | 70 ++++++ .../Functions/MathTrig/AtanTest.php | 23 ++ .../Functions/MathTrig/AtanhTest.php | 23 ++ .../Functions/MathTrig/CombinATest.php | 70 ++++++ .../Functions/MathTrig/CombinTest.php | 70 ++++++ .../Functions/MathTrig/CosTest.php | 23 ++ .../Functions/MathTrig/CoshTest.php | 23 ++ .../Functions/MathTrig/CotTest.php | 23 ++ .../Functions/MathTrig/CothTest.php | 23 ++ .../Functions/MathTrig/CscTest.php | 23 ++ .../Functions/MathTrig/CschTest.php | 23 ++ .../Functions/MathTrig/DegreesTest.php | 23 ++ .../Functions/MathTrig/EvenTest.php | 23 ++ .../Functions/MathTrig/ExpTest.php | 23 ++ .../Functions/MathTrig/FactDoubleTest.php | 23 ++ .../Functions/MathTrig/FactTest.php | 23 ++ .../Functions/MathTrig/IntTest.php | 23 ++ .../Functions/MathTrig/MRoundTest.php | 70 ++++++ .../Functions/MathTrig/OddTest.php | 23 ++ .../Functions/MathTrig/RadiansTest.php | 23 ++ .../Functions/MathTrig/RoundDownTest.php | 70 ++++++ .../Functions/MathTrig/RoundTest.php | 147 +++++++++++++ .../Functions/MathTrig/RoundUpTest.php | 70 ++++++ .../Functions/MathTrig/SecTest.php | 23 ++ .../Functions/MathTrig/SechTest.php | 23 ++ .../Functions/MathTrig/SignTest.php | 23 ++ .../Functions/MathTrig/SinTest.php | 23 ++ .../Functions/MathTrig/SinhTest.php | 23 ++ .../Functions/MathTrig/SqrtPiTest.php | 23 ++ .../Functions/MathTrig/SqrtTest.php | 23 ++ .../Functions/MathTrig/TanTest.php | 23 ++ .../Functions/MathTrig/TanhTest.php | 23 ++ 63 files changed, 2339 insertions(+), 220 deletions(-) create mode 100644 src/PhpSpreadsheet/Calculation/ArrayEnabled.php create mode 100644 src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentHelper.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 9616dc01..08a0937e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org). ### Added +- Improved support for passing of array arguments to Excel function implementations to return array results (where appropriate). [PR #2562](https://github.com/PHPOffice/PhpSpreadsheet/pull/2562) + + This is the first stage in an ongoing process of adding array support to all appropriate function implementations, - Support for the Excel365 Math/Trig SEQUENCE() function [PR #2536](https://github.com/PHPOffice/PhpSpreadsheet/pull/2536) - Support for the Excel365 Math/Trig RANDARRAY() function [PR #2540](https://github.com/PHPOffice/PhpSpreadsheet/pull/2540) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 7d9bd63a..25f0fc47 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -66,8 +66,13 @@ parameters: path: src/PhpSpreadsheet/Calculation/Calculation.php - - message: "#^Cannot access offset int(<0, max>)? on mixed\\.$#" - count: 16 + message: "#^Cannot access offset int on mixed\\.$#" + count: 10 + path: src/PhpSpreadsheet/Calculation/Calculation.php + + - + message: "#^Cannot access offset int\\<0, max\\> on mixed\\.$#" + count: 6 path: src/PhpSpreadsheet/Calculation/Calculation.php - @@ -1461,7 +1466,7 @@ parameters: path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php - - message: "#^Parameter \\#1 \\$array_arg of function uasort expects array()?, mixed given\\.$#" + message: "#^Parameter \\#1 \\$array_arg of function uasort expects array\\, mixed given\\.$#" count: 1 path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php @@ -1471,55 +1476,35 @@ parameters: path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php - - message: "#^Parameter \\#2 \\$callback of function uasort expects callable\\((mixed|T), (mixed|T)\\)\\: int, array\\{'self', 'vlookupSort'\\} given\\.$#" + message: "#^Parameter \\#2 \\$callback of function uasort expects callable\\(T, T\\)\\: int, array\\{'self', 'vlookupSort'\\} given\\.$#" count: 1 path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php - - - message: "#^Parameter \\#1 \\$number of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Trig\\\\Cosine\\:\\:acos\\(\\) expects float, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/MathTrig.php - - - - message: "#^Parameter \\#1 \\$number of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Trig\\\\Cosine\\:\\:acosh\\(\\) expects float, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/MathTrig.php - - - - message: "#^Parameter \\#1 \\$number of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Trig\\\\Sine\\:\\:asin\\(\\) expects float, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/MathTrig.php - - - - message: "#^Parameter \\#1 \\$number of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Trig\\\\Sine\\:\\:asinh\\(\\) expects float, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/MathTrig.php - - - - message: "#^Parameter \\#1 \\$number of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Trig\\\\Tangent\\:\\:atan\\(\\) expects float, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/MathTrig.php - - - - message: "#^Parameter \\#1 \\$number of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Trig\\\\Tangent\\:\\:atanh\\(\\) expects float, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/MathTrig.php - - message: "#^Cannot cast mixed to string\\.$#" count: 1 path: src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php - - message: "#^Binary operation \"/\" between float\\|int\\|string and float\\|int\\|string results in an error\\.$#" + message: "#^Binary operation \"/\" between array\\|float\\|int\\|string and array\\|float\\|int\\|string results in an error\\.$#" count: 2 path: src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php - - message: "#^Binary operation \"/\" between float\\|int\\|string and float\\|int results in an error\\.$#" + message: "#^Parameter \\#1 \\$factVal of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Factorial\\:\\:fact\\(\\) expects array\\|float, int\\\\|int\\<0, max\\> given\\.$#" + count: 1 + path: src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php + + - + message: "#^Binary operation \"/\" between array\\|float\\|int\\|string and float\\|int results in an error\\.$#" count: 1 path: src/PhpSpreadsheet/Calculation/MathTrig/Factorial.php + - + message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\IntClass\\:\\:evaluate\\(\\) should return array\\|string but returns int\\.$#" + count: 1 + path: src/PhpSpreadsheet/Calculation/MathTrig/IntClass.php + - message: "#^Cannot call method getWorksheet\\(\\) on mixed\\.$#" count: 4 @@ -1810,6 +1795,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/Normal.php + - + message: "#^Parameter \\#1 \\$factVal of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Factorial\\:\\:fact\\(\\) expects array\\|float, int\\<0, max\\> given\\.$#" + count: 1 + path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/Poisson.php + - message: "#^Binary operation \"\\-\" between float\\|string and float\\|int\\|numeric\\-string results in an error\\.$#" count: 1 @@ -1841,7 +1831,7 @@ parameters: path: src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php - - message: "#^Binary operation \"/\" between float\\|int\\|string and float\\|int\\|string results in an error\\.$#" + message: "#^Binary operation \"/\" between array\\|float\\|int\\|string and array\\|float\\|int\\|string results in an error\\.$#" count: 1 path: src/PhpSpreadsheet/Calculation/Statistical/Permutations.php @@ -6046,8 +6036,13 @@ parameters: path: src/PhpSpreadsheet/Worksheet/Worksheet.php - - message: "#^Parameter \\#1 \\$row of method PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Cells\\:\\:removeRow\\(\\) expects string, int(<1, max>)? given\\.$#" - count: 2 + message: "#^Parameter \\#1 \\$row of method PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Cells\\:\\:removeRow\\(\\) expects string, int given\\.$#" + count: 1 + path: src/PhpSpreadsheet/Worksheet/Worksheet.php + + - + message: "#^Parameter \\#1 \\$row of method PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Cells\\:\\:removeRow\\(\\) expects string, int\\<1, max\\> given\\.$#" + count: 1 path: src/PhpSpreadsheet/Worksheet/Worksheet.php - @@ -6996,7 +6991,7 @@ parameters: path: src/PhpSpreadsheet/Writer/Xlsx.php - - message: "#^Cannot access offset int(<0, max>)? on mixed\\.$#" + message: "#^Cannot access offset int\\<0, max\\> on mixed\\.$#" count: 2 path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php @@ -7161,7 +7156,7 @@ parameters: path: src/PhpSpreadsheet/Writer/Xlsx/DocProps.php - - message: "#^Parameter \\#1 \\$index of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:getChartByIndex\\(\\) expects string, int(<0, max>)? given\\.$#" + message: "#^Parameter \\#1 \\$index of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:getChartByIndex\\(\\) expects string, int\\<0, max\\> given\\.$#" count: 1 path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php @@ -7401,7 +7396,7 @@ parameters: path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - message: "#^Offset int(<1, max>)? on array\\\\> in isset\\(\\) does not exist\\.$#" + message: "#^Offset int\\<1, max\\> on array\\\\> in isset\\(\\) does not exist\\.$#" count: 2 path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -7436,8 +7431,18 @@ parameters: path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, (int|int\\<(0|1), max\\>) given\\.$#" - count: 27 + message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#" + count: 15 + path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php + + - + message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<0, max\\> given\\.$#" + count: 3 + path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php + + - + message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<1, max\\> given\\.$#" + count: 9 path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - diff --git a/src/PhpSpreadsheet/Calculation/ArrayEnabled.php b/src/PhpSpreadsheet/Calculation/ArrayEnabled.php new file mode 100644 index 00000000..bc852415 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/ArrayEnabled.php @@ -0,0 +1,190 @@ +initialise($arguments); + } + + protected static function evaluateSingleArgumentArray(callable $method, array $values): array + { + $result = []; + foreach ($values as $value) { + $result[] = $method($value); + } + + return $result; + } + + /** + * @param mixed ...$arguments + */ + protected static function evaluateArrayArguments(callable $method, ...$arguments): array + { + self::initialiseHelper($arguments); + $arguments = self::$arrayArgumentHelper->arguments(); + + if (self::$arrayArgumentHelper->hasArrayArgument() === false) { + return [$method(...$arguments)]; + } + + if (self::$arrayArgumentHelper->arrayArguments() === 1) { + $nthArgument = self::$arrayArgumentHelper->getFirstArrayArgumentNumber(); + + return self::evaluateNthArgumentAsArray($method, $nthArgument, ...$arguments); + } + + $singleRowVectorIndex = self::$arrayArgumentHelper->getSingleRowVector(); + $singleColumnVectorIndex = self::$arrayArgumentHelper->getSingleColumnVector(); + if ($singleRowVectorIndex !== null && $singleColumnVectorIndex !== null) { + // Basic logic for a single row vector and a single column vector + return self::evaluateVectorPair($method, $singleRowVectorIndex, $singleColumnVectorIndex, ...$arguments); + } + + $matrixPair = self::$arrayArgumentHelper->getMatrixPair(); + if ($matrixPair !== []) { + if ( + (self::$arrayArgumentHelper->isVector($matrixPair[0]) === true && + self::$arrayArgumentHelper->isVector($matrixPair[1]) === false) || + (self::$arrayArgumentHelper->isVector($matrixPair[0]) === false && + self::$arrayArgumentHelper->isVector($matrixPair[1]) === true) + ) { + // Logic for a matrix and a vector (row or column) + return self::evaluateVectorMatrixPair($method, $matrixPair, ...$arguments); + } + // Logic for matrix/matrix, column vector/column vector or row vector/row vector + return self::evaluateMatrixPair($method, $matrixPair, ...$arguments); + } + + // Still need to work out the logic for more than two array arguments, + // For the moment, we're throwing an Exception when we initialise the ArrayArgumentHelper + return ['#VALUE!']; + } + + /** + * @param mixed ...$arguments + */ + private static function evaluateVectorMatrixPair(callable $method, array $matrixIndexes, ...$arguments): array + { + $matrix2 = array_pop($matrixIndexes); + /** @var array $matrixValues2 */ + $matrixValues2 = $arguments[$matrix2]; + $matrix1 = array_pop($matrixIndexes); + /** @var array $matrixValues1 */ + $matrixValues1 = $arguments[$matrix1]; + + $rows = min(array_map([self::$arrayArgumentHelper, 'rowCount'], [$matrix1, $matrix2])); + $columns = min(array_map([self::$arrayArgumentHelper, 'columnCount'], [$matrix1, $matrix2])); + + if ($rows === 1) { + $rows = max(array_map([self::$arrayArgumentHelper, 'rowCount'], [$matrix1, $matrix2])); + } + if ($columns === 1) { + $columns = max(array_map([self::$arrayArgumentHelper, 'columnCount'], [$matrix1, $matrix2])); + } + + $result = []; + for ($rowIndex = 0; $rowIndex < $rows; ++$rowIndex) { + for ($columnIndex = 0; $columnIndex < $columns; ++$columnIndex) { + $rowIndex1 = self::$arrayArgumentHelper->isRowVector($matrix1) ? 0 : $rowIndex; + $columnIndex1 = self::$arrayArgumentHelper->isColumnVector($matrix1) ? 0 : $columnIndex; + $value1 = $matrixValues1[$rowIndex1][$columnIndex1]; + $rowIndex2 = self::$arrayArgumentHelper->isRowVector($matrix2) ? 0 : $rowIndex; + $columnIndex2 = self::$arrayArgumentHelper->isColumnVector($matrix2) ? 0 : $columnIndex; + $value2 = $matrixValues2[$rowIndex2][$columnIndex2]; + $arguments[$matrix1] = $value1; + $arguments[$matrix2] = $value2; + + $result[$rowIndex][$columnIndex] = $method(...$arguments); + } + } + + return $result; + } + + /** + * @param mixed ...$arguments + */ + private static function evaluateMatrixPair(callable $method, array $matrixIndexes, ...$arguments): array + { + $matrix2 = array_pop($matrixIndexes); + /** @var array $matrixValues2 */ + $matrixValues2 = $arguments[$matrix2]; + $matrix1 = array_pop($matrixIndexes); + /** @var array $matrixValues1 */ + $matrixValues1 = $arguments[$matrix1]; + + $result = []; + foreach ($matrixValues1 as $rowIndex => $row) { + foreach ($row as $columnIndex => $value1) { + if (isset($matrixValues2[$rowIndex][$columnIndex]) === false) { + continue; + } + + $value2 = $matrixValues2[$rowIndex][$columnIndex]; + $arguments[$matrix1] = $value1; + $arguments[$matrix2] = $value2; + + $result[$rowIndex][$columnIndex] = $method(...$arguments); + } + } + + return $result; + } + + /** + * @param mixed ...$arguments + */ + private static function evaluateVectorPair(callable $method, int $rowIndex, int $columnIndex, ...$arguments): array + { + $rowVector = Functions::flattenArray($arguments[$rowIndex]); + $columnVector = Functions::flattenArray($arguments[$columnIndex]); + + $result = []; + foreach ($columnVector as $column) { + $rowResults = []; + foreach ($rowVector as $row) { + $arguments[$rowIndex] = $row; + $arguments[$columnIndex] = $column; + + $rowResults[] = $method(...$arguments); + } + $result[] = $rowResults; + } + + return $result; + } + + /** + * Note, offset is from 1 (for the first argument) rather than from 0. + * + * @param mixed ...$arguments + */ + private static function evaluateNthArgumentAsArray(callable $method, int $nthArgument, ...$arguments): array + { + $values = array_slice($arguments, $nthArgument - 1, 1); + /** @var array $values */ + $values = array_pop($values); + + $result = []; + foreach ($values as $value) { + $arguments[$nthArgument - 1] = $value; + $result[] = $method(...$arguments); + } + + return $result; + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Date.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Date.php index d18e2371..188eebc5 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Date.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Date.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper; @@ -9,6 +10,8 @@ use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Date { + use ArrayEnabled; + /** * DATE. * @@ -24,7 +27,7 @@ class Date * A Month name or abbreviation (English only at this point) such as 'January' or 'Jan' will still be accepted, * as will a day value with a suffix (e.g. '21st' rather than simply 21); again only English language. * - * @param int $year The value of the year argument can include one to four digits. + * @param array|int $year The value of the year argument can include one to four digits. * Excel interprets the year argument according to the configured * date system: 1900 or 1904. * If year is between 0 (zero) and 1899 (inclusive), Excel adds that @@ -35,7 +38,7 @@ class Date * 2008. * If year is less than 0 or is 10000 or greater, Excel returns the * #NUM! error value. - * @param int $month A positive or negative integer representing the month of the year + * @param array|int $month A positive or negative integer representing the month of the year * from 1 to 12 (January to December). * If month is greater than 12, month adds that number of months to * the first month in the year specified. For example, DATE(2008,14,2) @@ -44,7 +47,7 @@ class Date * number of months, plus 1, from the first month in the year * specified. For example, DATE(2008,-3,2) returns the serial number * representing September 2, 2007. - * @param int $day A positive or negative integer representing the day of the month + * @param array|int $day A positive or negative integer representing the day of the month * from 1 to 31. * If day is greater than the number of days in the month specified, * day adds that number of days to the first day in the month. For @@ -57,9 +60,15 @@ class Date * * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function fromYMD($year, $month, $day) { + if (is_array($year) || is_array($month) || is_array($day)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $year, $month, $day); + } + $baseYear = SharedDateHelper::getExcelCalendar(); try { diff --git a/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentHelper.php b/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentHelper.php new file mode 100644 index 00000000..df413f20 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentHelper.php @@ -0,0 +1,202 @@ +rows = $this->rows($arguments); + $this->columns = $this->columns($arguments); + + $this->argumentCount = count($arguments); + $this->arguments = $this->flattenSingleCellArrays($arguments, $this->rows, $this->columns); + + $this->rows = $this->rows($arguments); + $this->columns = $this->columns($arguments); + + if ($this->arrayArguments() > 2) { + throw new Exception('Formulae with more than two array arguments are not supported'); + } + } + + public function arguments(): array + { + return $this->arguments; + } + + public function hasArrayArgument(): bool + { + return $this->arrayArguments() > 0; + } + + public function getFirstArrayArgumentNumber(): int + { + $rowArrays = $this->filterArray($this->rows); + $columnArrays = $this->filterArray($this->columns); + + for ($index = 0; $index < $this->argumentCount; ++$index) { + if (isset($rowArrays[$index]) || isset($columnArrays[$index])) { + return ++$index; + } + } + + return 0; + } + + public function getSingleRowVector(): ?int + { + $rowVectors = $this->getRowVectors(); + + return count($rowVectors) === 1 ? array_pop($rowVectors) : null; + } + + private function getRowVectors(): array + { + $rowVectors = []; + for ($index = 0; $index < $this->argumentCount; ++$index) { + if ($this->rows[$index] === 1 && $this->columns[$index] > 1) { + $rowVectors[] = $index; + } + } + + return $rowVectors; + } + + public function getSingleColumnVector(): ?int + { + $columnVectors = $this->getColumnVectors(); + + return count($columnVectors) === 1 ? array_pop($columnVectors) : null; + } + + private function getColumnVectors(): array + { + $columnVectors = []; + for ($index = 0; $index < $this->argumentCount; ++$index) { + if ($this->rows[$index] > 1 && $this->columns[$index] === 1) { + $columnVectors[] = $index; + } + } + + return $columnVectors; + } + + public function getMatrixPair(): array + { + for ($i = 0; $i < ($this->argumentCount - 1); ++$i) { + for ($j = $i + 1; $j < $this->argumentCount; ++$j) { + if (isset($this->rows[$i], $this->rows[$j])) { + return [$i, $j]; + } + } + } + + return []; + } + + public function isVector(int $argument): bool + { + return $this->rows[$argument] === 1 || $this->columns[$argument] === 1; + } + + public function isRowVector(int $argument): bool + { + return $this->rows[$argument] === 1; + } + + public function isColumnVector(int $argument): bool + { + return $this->columns[$argument] === 1; + } + + public function rowCount(int $argument): int + { + return $this->rows[$argument]; + } + + public function columnCount(int $argument): int + { + return $this->columns[$argument]; + } + + private function rows(array $arguments): array + { + return array_map( + function ($argument) { + return is_countable($argument) ? count($argument) : 1; + }, + $arguments + ); + } + + private function columns(array $arguments): array + { + return array_map( + function ($argument) { + return is_array($argument) && is_array($argument[array_keys($argument)[0]]) + ? count($argument[array_keys($argument)[0]]) + : 1; + }, + $arguments + ); + } + + public function arrayArguments(): int + { + $count = 0; + foreach (array_keys($this->arguments) as $argument) { + if ($this->rows[$argument] > 1 || $this->columns[$argument] > 1) { + ++$count; + } + } + + return $count; + } + + private function flattenSingleCellArrays(array $arguments, array $rows, array $columns): array + { + foreach ($arguments as $index => $argument) { + if ($rows[$index] === 1 && $columns[$index] === 1) { + while (is_array($argument)) { + $argument = array_pop($argument); + } + $arguments[$index] = $argument; + } + } + + return $arguments; + } + + private function filterArray(array $array): array + { + return array_filter( + $array, + function ($value) { + return $value > 1; + } + ); + } +} diff --git a/src/PhpSpreadsheet/Calculation/MathTrig.php b/src/PhpSpreadsheet/Calculation/MathTrig.php index ec251f6d..cfd67338 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig.php @@ -20,9 +20,9 @@ class MathTrig * @See MathTrig\Arabic::evaluate() * Use the evaluate method in the MathTrig\Arabic class instead * - * @param string $roman + * @param array|string $roman * - * @return int|string the arabic numberal contrived from the roman numeral + * @return array|int|string the arabic numberal contrived from the roman numeral */ public static function ARABIC($roman) { @@ -50,10 +50,10 @@ class MathTrig * @See MathTrig\Trig\Tangent::atan2() * Use the atan2 method in the MathTrig\Trig\Tangent class instead * - * @param float $xCoordinate the x-coordinate of the point - * @param float $yCoordinate the y-coordinate of the point + * @param array|float $xCoordinate the x-coordinate of the point + * @param array|float $yCoordinate the y-coordinate of the point * - * @return float|string the inverse tangent of the specified x- and y-coordinates, or a string containing an error + * @return array|float|string the inverse tangent of the specified x- and y-coordinates, or a string containing an error */ public static function ATAN2($xCoordinate = null, $yCoordinate = null) { @@ -124,10 +124,10 @@ class MathTrig * @see MathTrig\Combinations::withoutRepetition() * Use the withoutRepetition() method in the MathTrig\Combinations class instead * - * @param int $numObjs Number of different objects - * @param int $numInSet Number of objects in each combination + * @param array|int $numObjs Number of different objects + * @param array|int $numInSet Number of objects in each combination * - * @return float|int|string Number of combinations, or a string containing an error + * @return array|float|int|string Number of combinations, or a string containing an error */ public static function COMBIN($numObjs, $numInSet) { @@ -151,9 +151,9 @@ class MathTrig * @see MathTrig\Round::even() * Use the even() method in the MathTrig\Round class instead * - * @param float $number Number to round + * @param array|float $number Number to round * - * @return float|int|string Rounded Number, or a string containing an error + * @return array|float|int|string Rounded Number, or a string containing an error */ public static function EVEN($number) { @@ -184,9 +184,9 @@ class MathTrig * * @Deprecated 1.18.0 * - * @param float $factVal Factorial Value + * @param array|float $factVal Factorial Value * - * @return float|int|string Factorial, or a string containing an error + * @return array|float|int|string Factorial, or a string containing an error * *@see MathTrig\Factorial::fact() * Use the fact() method in the MathTrig\Factorial class instead @@ -206,9 +206,9 @@ class MathTrig * * @Deprecated 1.18.0 * - * @param float $factVal Factorial Value + * @param array|float $factVal Factorial Value * - * @return float|int|string Double Factorial, or a string containing an error + * @return array|float|int|string Double Factorial, or a string containing an error * *@see MathTrig\Factorial::factDouble() * Use the factDouble() method in the MathTrig\Factorial class instead @@ -301,9 +301,9 @@ class MathTrig * @see MathTrig\IntClass::evaluate() * Use the evaluate() method in the MathTrig\IntClass class instead * - * @param float $number Number to cast to an integer + * @param array|float $number Number to cast to an integer * - * @return int|string Integer value, or a string containing an error + * @return array|int|string Integer value, or a string containing an error */ public static function INT($number) { @@ -470,9 +470,9 @@ class MathTrig * @Deprecated 1.17.0 * * @param float $number Number to round - * @param int $multiple Multiple to which you want to round $number + * @param array|int $multiple Multiple to which you want to round $number * - * @return float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error * *@see MathTrig\Round::multiple() * Use the multiple() method in the MathTrig\Mround class instead @@ -511,9 +511,9 @@ class MathTrig * @See MathTrig\Round::odd() * Use the odd method in the MathTrig\Round class instead * - * @param float $number Number to round + * @param array|float $number Number to round * - * @return float|int|string Rounded Number, or a string containing an error + * @return array|float|int|string Rounded Number, or a string containing an error */ public static function ODD($number) { @@ -634,10 +634,10 @@ class MathTrig * @See MathTrig\Round::up() * Use the up() method in the MathTrig\Round class instead * - * @param float $number Number to round - * @param int $digits Number of digits to which you want to round $number + * @param array|float $number Number to round + * @param array|int $digits Number of digits to which you want to round $number * - * @return float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error */ public static function ROUNDUP($number, $digits) { @@ -654,10 +654,10 @@ class MathTrig * @See MathTrig\Round::down() * Use the down() method in the MathTrig\Round class instead * - * @param float $number Number to round - * @param int $digits Number of digits to which you want to round $number + * @param array|float $number Number to round + * @param array|int $digits Number of digits to which you want to round $number * - * @return float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error */ public static function ROUNDDOWN($number, $digits) { @@ -697,9 +697,9 @@ class MathTrig * @See MathTrig\Sign::evaluate() * Use the evaluate method in the MathTrig\Sign class instead * - * @param float $number Number to round + * @param array|float $number Number to round * - * @return int|string sign value, or a string containing an error + * @return array|int|string sign value, or a string containing an error */ public static function SIGN($number) { @@ -729,9 +729,9 @@ class MathTrig * @See MathTrig\Sqrt::sqrt() * Use the pi method in the MathTrig\Sqrt class instead * - * @param float $number Number + * @param array|float $number Number * - * @return float|string Square Root of Number * Pi, or a string containing an error + * @return array|float|string Square Root of Number * Pi, or a string containing an error */ public static function SQRTPI($number) { @@ -958,9 +958,9 @@ class MathTrig * @See MathTrig\Trig\Secant::sec() * Use the sec method in the MathTrig\Trig\Secant class instead * - * @param float $angle Number + * @param array|float $angle Number * - * @return float|string The secant of the angle + * @return array|float|string The secant of the angle */ public static function SEC($angle) { @@ -977,9 +977,9 @@ class MathTrig * @See MathTrig\Trig\Secant::sech() * Use the sech method in the MathTrig\Trig\Secant class instead * - * @param float $angle Number + * @param array|float $angle Number * - * @return float|string The hyperbolic secant of the angle + * @return array|float|string The hyperbolic secant of the angle */ public static function SECH($angle) { @@ -996,9 +996,9 @@ class MathTrig * @See MathTrig\Trig\Cosecant::csc() * Use the csc method in the MathTrig\Trig\Cosecant class instead * - * @param float $angle Number + * @param array|float $angle Number * - * @return float|string The cosecant of the angle + * @return array|float|string The cosecant of the angle */ public static function CSC($angle) { @@ -1015,9 +1015,9 @@ class MathTrig * @See MathTrig\Trig\Cosecant::csch() * Use the csch method in the MathTrig\Trig\Cosecant class instead * - * @param float $angle Number + * @param array|float $angle Number * - * @return float|string The hyperbolic cosecant of the angle + * @return array|float|string The hyperbolic cosecant of the angle */ public static function CSCH($angle) { @@ -1034,9 +1034,9 @@ class MathTrig * @See MathTrig\Trig\Cotangent::cot() * Use the cot method in the MathTrig\Trig\Cotangent class instead * - * @param float $angle Number + * @param array|float $angle Number * - * @return float|string The cotangent of the angle + * @return array|float|string The cotangent of the angle */ public static function COT($angle) { @@ -1053,9 +1053,9 @@ class MathTrig * @See MathTrig\Trig\Cotangent::coth() * Use the coth method in the MathTrig\Trig\Cotangent class instead * - * @param float $angle Number + * @param array|float $angle Number * - * @return float|string The hyperbolic cotangent of the angle + * @return array|float|string The hyperbolic cotangent of the angle */ public static function COTH($angle) { @@ -1072,9 +1072,9 @@ class MathTrig * @See MathTrig\Trig\Cotangent::acot() * Use the acot method in the MathTrig\Trig\Cotangent class instead * - * @param float $number Number + * @param array|float $number Number * - * @return float|string The arccotangent of the number + * @return array|float|string The arccotangent of the number */ public static function ACOT($number) { @@ -1108,9 +1108,9 @@ class MathTrig * @See MathTrig\Trig\Cotangent::acoth() * Use the acoth method in the MathTrig\Trig\Cotangent class instead * - * @param float $number Number + * @param array|float $number Number * - * @return float|string The hyperbolic arccotangent of the number + * @return array|float|string The hyperbolic arccotangent of the number */ public static function ACOTH($number) { @@ -1127,10 +1127,10 @@ class MathTrig * @See MathTrig\Round::round() * Use the round() method in the MathTrig\Round class instead * - * @param mixed $number Should be numeric - * @param mixed $precision Should be int + * @param array|mixed $number Should be numeric + * @param array|mixed $precision Should be int * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinROUND($number, $precision) { @@ -1147,9 +1147,9 @@ class MathTrig * @See MathTrig\Absolute::evaluate() * Use the evaluate method in the MathTrig\Absolute class instead * - * @param mixed $number Should be numeric + * @param array|mixed $number Should be numeric * - * @return float|int|string Rounded number + * @return array|float|int|string Rounded number */ public static function builtinABS($number) { @@ -1166,9 +1166,9 @@ class MathTrig * * Returns the result of builtin function acos after validating args. * - * @param mixed $number Should be numeric + * @param array|float $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinACOS($number) { @@ -1185,9 +1185,9 @@ class MathTrig * @See MathTrig\Trig\Cosine::acosh() * Use the acosh method in the MathTrig\Trig\Cosine class instead * - * @param mixed $number Should be numeric + * @param array|float $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinACOSH($number) { @@ -1204,9 +1204,9 @@ class MathTrig * @See MathTrig\Trig\Sine::asin() * Use the asin method in the MathTrig\Trig\Sine class instead * - * @param mixed $number Should be numeric + * @param array|float $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinASIN($number) { @@ -1223,9 +1223,9 @@ class MathTrig * @See MathTrig\Trig\Sine::asinh() * Use the asinh method in the MathTrig\Trig\Sine class instead * - * @param mixed $number Should be numeric + * @param array|float $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinASINH($number) { @@ -1242,9 +1242,9 @@ class MathTrig * @See MathTrig\Trig\Tangent::atan() * Use the atan method in the MathTrig\Trig\Tangent class instead * - * @param mixed $number Should be numeric + * @param array|float $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinATAN($number) { @@ -1261,9 +1261,9 @@ class MathTrig * @See MathTrig\Trig\Tangent::atanh() * Use the atanh method in the MathTrig\Trig\Tangent class instead * - * @param mixed $number Should be numeric + * @param array|float $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinATANH($number) { @@ -1280,9 +1280,9 @@ class MathTrig * @See MathTrig\Trig\Cosine::cos() * Use the cos method in the MathTrig\Trig\Cosine class instead * - * @param mixed $number Should be numeric + * @param array|mixed $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinCOS($number) { @@ -1299,9 +1299,9 @@ class MathTrig * @See MathTrig\Trig\Cosine::cosh() * Use the cosh method in the MathTrig\Trig\Cosine class instead * - * @param mixed $number Should be numeric + * @param array|mixed $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinCOSH($number) { @@ -1318,9 +1318,9 @@ class MathTrig * @See MathTrig\Angle::toDegrees() * Use the toDegrees method in the MathTrig\Angle class instead * - * @param mixed $number Should be numeric + * @param array|mixed $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinDEGREES($number) { @@ -1337,9 +1337,9 @@ class MathTrig * @See MathTrig\Exp::evaluate() * Use the evaluate method in the MathTrig\Exp class instead * - * @param mixed $number Should be numeric + * @param array|mixed $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinEXP($number) { @@ -1394,9 +1394,9 @@ class MathTrig * @See MathTrig\Angle::toRadians() * Use the toRadians method in the MathTrig\Angle class instead * - * @param mixed $number Should be numeric + * @param array|mixed $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinRADIANS($number) { @@ -1413,9 +1413,9 @@ class MathTrig * @See MathTrig\Trig\Sine::evaluate() * Use the sin method in the MathTrig\Trig\Sine class instead * - * @param mixed $number Should be numeric + * @param array|mixed $number Should be numeric * - * @return float|string sine + * @return array|float|string sine */ public static function builtinSIN($number) { @@ -1432,9 +1432,9 @@ class MathTrig * @See MathTrig\Trig\Sine::sinh() * Use the sinh method in the MathTrig\Trig\Sine class instead * - * @param mixed $number Should be numeric + * @param array|mixed $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinSINH($number) { @@ -1451,9 +1451,9 @@ class MathTrig * @See MathTrig\Sqrt::sqrt() * Use the sqrt method in the MathTrig\Sqrt class instead * - * @param mixed $number Should be numeric + * @param array|mixed $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinSQRT($number) { @@ -1470,9 +1470,9 @@ class MathTrig * @See MathTrig\Trig\Tangent::tan() * Use the tan method in the MathTrig\Trig\Tangent class instead * - * @param mixed $number Should be numeric + * @param array|mixed $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinTAN($number) { @@ -1489,9 +1489,9 @@ class MathTrig * @See MathTrig\Trig\Tangent::tanh() * Use the tanh method in the MathTrig\Trig\Tangent class instead * - * @param mixed $number Should be numeric + * @param array|mixed $number Should be numeric * - * @return float|string Rounded number + * @return array|float|string Rounded number */ public static function builtinTANH($number) { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Absolute.php b/src/PhpSpreadsheet/Calculation/MathTrig/Absolute.php index 9f1bd804..f21c6b73 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Absolute.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Absolute.php @@ -2,21 +2,30 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; class Absolute { + use ArrayEnabled; + /** * ABS. * * Returns the result of builtin function abs after validating args. * - * @param mixed $number Should be numeric + * @param mixed $number Should be numeric, or can be an array of numbers * - * @return float|int|string Rounded number + * @return array|float|int|string rounded number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function evaluate($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Angle.php b/src/PhpSpreadsheet/Calculation/MathTrig/Angle.php index 3062481f..cbeec6f4 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Angle.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Angle.php @@ -2,21 +2,30 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; class Angle { + use ArrayEnabled; + /** * DEGREES. * * Returns the result of builtin function rad2deg after validating args. * - * @param mixed $number Should be numeric + * @param mixed $number Should be numeric, or can be an array of numbers * - * @return float|string Rounded number + * @return array|float|string Rounded number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function toDegrees($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { @@ -31,12 +40,18 @@ class Angle * * Returns the result of builtin function deg2rad after validating args. * - * @param mixed $number Should be numeric + * @param mixed $number Should be numeric, or can be an array of numbers * - * @return float|string Rounded number + * @return array|float|string Rounded number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function toRadians($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php b/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php index b852eeac..b8b66829 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php @@ -2,11 +2,14 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class Arabic { + use ArrayEnabled; + private const ROMAN_LOOKUP = [ 'M' => 1000, 'D' => 500, @@ -70,12 +73,18 @@ class Arabic * Excel Function: * ARABIC(text) * - * @param string $roman + * @param mixed $roman Should be a string, or can be an array of strings * - * @return int|string the arabic numberal contrived from the roman numeral + * @return array|int|string the arabic numberal contrived from the roman numeral + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function evaluate($roman) { + if (is_array($roman)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $roman); + } + // An empty string should return 0 $roman = substr(trim(strtoupper((string) Functions::flattenSingleValue($roman))), 0, 255); if ($roman === '') { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php b/src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php index 97508bb1..5a652da0 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php @@ -2,10 +2,13 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; class Combinations { + use ArrayEnabled; + /** * COMBIN. * @@ -15,13 +18,19 @@ class Combinations * Excel Function: * COMBIN(numObjs,numInSet) * - * @param mixed $numObjs Number of different objects - * @param mixed $numInSet Number of objects in each combination + * @param mixed $numObjs Number of different objects, or can be an array of numbers + * @param mixed $numInSet Number of objects in each combination, or can be an array of numbers * - * @return float|int|string Number of combinations, or a string containing an error + * @return array|float|int|string Number of combinations, or a string containing an error + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function withoutRepetition($numObjs, $numInSet) { + if (is_array($numObjs) || is_array($numInSet)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $numObjs, $numInSet); + } + try { $numObjs = Helpers::validateNumericNullSubstitution($numObjs, null); $numInSet = Helpers::validateNumericNullSubstitution($numInSet, null); @@ -35,21 +44,27 @@ class Combinations } /** - * COMBIN. + * COMBINA. * * Returns the number of combinations for a given number of items. Use COMBIN to * determine the total possible number of groups for a given number of items. * * Excel Function: - * COMBIN(numObjs,numInSet) + * COMBINA(numObjs,numInSet) * - * @param mixed $numObjs Number of different objects - * @param mixed $numInSet Number of objects in each combination + * @param mixed $numObjs Number of different objects, or can be an array of numbers + * @param mixed $numInSet Number of objects in each combination, or can be an array of numbers * - * @return float|int|string Number of combinations, or a string containing an error + * @return array|float|int|string Number of combinations, or a string containing an error + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function withRepetition($numObjs, $numInSet) { + if (is_array($numObjs) || is_array($numInSet)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $numObjs, $numInSet); + } + try { $numObjs = Helpers::validateNumericNullSubstitution($numObjs, null); $numInSet = Helpers::validateNumericNullSubstitution($numInSet, null); @@ -69,6 +84,8 @@ class Combinations return $e->getMessage(); } - return round(Factorial::fact($numObjs + $numInSet - 1) / Factorial::fact($numObjs - 1)) / Factorial::fact($numInSet); + return round( + Factorial::fact($numObjs + $numInSet - 1) / Factorial::fact($numObjs - 1) + ) / Factorial::fact($numInSet); } } diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Exp.php b/src/PhpSpreadsheet/Calculation/MathTrig/Exp.php index ce930a83..f65c2c18 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Exp.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Exp.php @@ -2,21 +2,30 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; class Exp { + use ArrayEnabled; + /** * EXP. * * Returns the result of builtin function exp after validating args. * - * @param mixed $number Should be numeric + * @param mixed $number Should be numeric, or can be an array of numbers * - * @return float|string Rounded number + * @return array|float|string Rounded number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function evaluate($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Factorial.php b/src/PhpSpreadsheet/Calculation/MathTrig/Factorial.php index f443f8e5..b6883e29 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Factorial.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Factorial.php @@ -2,12 +2,15 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; class Factorial { + use ArrayEnabled; + /** * FACT. * @@ -17,12 +20,18 @@ class Factorial * Excel Function: * FACT(factVal) * - * @param float $factVal Factorial Value + * @param array|float $factVal Factorial Value, or can be an array of numbers * - * @return float|int|string Factorial, or a string containing an error + * @return array|float|int|string Factorial, or a string containing an error + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function fact($factVal) { + if (is_array($factVal)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $factVal); + } + try { $factVal = Helpers::validateNumericNullBool($factVal); Helpers::validateNotNegative($factVal); @@ -53,12 +62,18 @@ class Factorial * Excel Function: * FACTDOUBLE(factVal) * - * @param float $factVal Factorial Value + * @param array|float $factVal Factorial Value, or can be an array of numbers * - * @return float|int|string Double Factorial, or a string containing an error + * @return array|float|int|string Double Factorial, or a string containing an error + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function factDouble($factVal) { + if (is_array($factVal)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $factVal); + } + try { $factVal = Helpers::validateNumericNullSubstitution($factVal, 0); Helpers::validateNotNegative($factVal); diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/IntClass.php b/src/PhpSpreadsheet/Calculation/MathTrig/IntClass.php index 7aa3d06a..f7f7764b 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/IntClass.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/IntClass.php @@ -2,10 +2,13 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; class IntClass { + use ArrayEnabled; + /** * INT. * @@ -14,12 +17,18 @@ class IntClass * Excel Function: * INT(number) * - * @param float $number Number to cast to an integer + * @param array|float $number Number to cast to an integer, or can be an array of numbers * - * @return int|string Integer value, or a string containing an error + * @return array|string Integer value, or a string containing an error + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function evaluate($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Round.php b/src/PhpSpreadsheet/Calculation/MathTrig/Round.php index 2ddde900..c419ca4d 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Round.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Round.php @@ -2,23 +2,32 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class Round { + use ArrayEnabled; + /** * ROUND. * * Returns the result of builtin function round after validating args. * - * @param mixed $number Should be numeric - * @param mixed $precision Should be int + * @param mixed $number Should be numeric, or can be an array of numbers + * @param mixed $precision Should be int, or can be an array of numbers * - * @return float|string Rounded number + * @return array|float|string Rounded number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function round($number, $precision) { + if (is_array($number) || is_array($precision)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $precision); + } + try { $number = Helpers::validateNumericNullBool($number); $precision = Helpers::validateNumericNullBool($precision); @@ -34,13 +43,19 @@ class Round * * Rounds a number up to a specified number of decimal places * - * @param float $number Number to round - * @param int $digits Number of digits to which you want to round $number + * @param array|float $number Number to round, or can be an array of numbers + * @param array|int $digits Number of digits to which you want to round $number, or can be an array of numbers * - * @return float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function up($number, $digits) { + if (is_array($number) || is_array($digits)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $digits); + } + try { $number = Helpers::validateNumericNullBool($number); $digits = (int) Helpers::validateNumericNullSubstitution($digits, null); @@ -64,13 +79,19 @@ class Round * * Rounds a number down to a specified number of decimal places * - * @param float $number Number to round - * @param int $digits Number of digits to which you want to round $number + * @param array|float $number Number to round, or can be an array of numbers + * @param array|int $digits Number of digits to which you want to round $number, or can be an array of numbers * - * @return float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function down($number, $digits) { + if (is_array($number) || is_array($digits)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $digits); + } + try { $number = Helpers::validateNumericNullBool($number); $digits = (int) Helpers::validateNumericNullSubstitution($digits, null); @@ -94,13 +115,19 @@ class Round * * Rounds a number to the nearest multiple of a specified value * - * @param mixed $number Expect float. Number to round. - * @param mixed $multiple Expect int. Multiple to which you want to round. + * @param mixed $number Expect float. Number to round, or can be an array of numbers + * @param mixed $multiple Expect int. Multiple to which you want to round, or can be an array of numbers. * - * @return float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function multiple($number, $multiple) { + if (is_array($number) || is_array($multiple)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $multiple); + } + try { $number = Helpers::validateNumericNullSubstitution($number, 0); $multiple = Helpers::validateNumericNullSubstitution($multiple, null); @@ -132,12 +159,18 @@ class Round * Excel Function: * EVEN(number) * - * @param float $number Number to round + * @param array|float $number Number to round, or can be an array of numbers * - * @return float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function even($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { @@ -152,12 +185,18 @@ class Round * * Returns number rounded up to the nearest odd integer. * - * @param float $number Number to round + * @param array|float $number Number to round, or can be an array of numbers * - * @return float|string Rounded Number, or a string containing an error + * @return array|float|string Rounded Number, or a string containing an error + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function odd($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Sign.php b/src/PhpSpreadsheet/Calculation/MathTrig/Sign.php index a48cf0f9..e40e1f6d 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Sign.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Sign.php @@ -2,22 +2,31 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; class Sign { + use ArrayEnabled; + /** * SIGN. * * Determines the sign of a number. Returns 1 if the number is positive, zero (0) * if the number is 0, and -1 if the number is negative. * - * @param float $number Number to round + * @param array|float $number Number to round, or can be an array of numbers * - * @return int|string sign value, or a string containing an error + * @return array|int|string sign value, or a string containing an error + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function evaluate($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Sqrt.php b/src/PhpSpreadsheet/Calculation/MathTrig/Sqrt.php index 8ead578e..b81c54c9 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Sqrt.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Sqrt.php @@ -2,21 +2,30 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; class Sqrt { + use ArrayEnabled; + /** * SQRT. * * Returns the result of builtin function sqrt after validating args. * - * @param mixed $number Should be numeric + * @param mixed $number Should be numeric, or can be an array of numbers * - * @return float|string square roor + * @return array|float|string square roor + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function sqrt($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { @@ -31,12 +40,18 @@ class Sqrt * * Returns the square root of (number * pi). * - * @param float $number Number + * @param array|float $number Number, or can be an array of numbers * - * @return float|string Square Root of Number * Pi, or a string containing an error + * @return array|float|string Square Root of Number * Pi, or a string containing an error + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function pi($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullSubstitution($number, 0); Helpers::validateNotNegative($number); diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosecant.php b/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosecant.php index 3038e6cc..845b6c14 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosecant.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosecant.php @@ -2,22 +2,31 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Helpers; class Cosecant { + use ArrayEnabled; + /** * CSC. * * Returns the cosecant of an angle. * - * @param float $angle Number + * @param array|float $angle Number, or can be an array of numbers * - * @return float|string The cosecant of the angle + * @return array|float|string The cosecant of the angle + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function csc($angle) { + if (is_array($angle)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle); + } + try { $angle = Helpers::validateNumericNullBool($angle); } catch (Exception $e) { @@ -32,12 +41,18 @@ class Cosecant * * Returns the hyperbolic cosecant of an angle. * - * @param float $angle Number + * @param array|float $angle Number, or can be an array of numbers * - * @return float|string The hyperbolic cosecant of the angle + * @return array|float|string The hyperbolic cosecant of the angle + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function csch($angle) { + if (is_array($angle)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle); + } + try { $angle = Helpers::validateNumericNullBool($angle); } catch (Exception $e) { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosine.php b/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosine.php index 6c69e126..c06f04df 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosine.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosine.php @@ -2,22 +2,31 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Helpers; class Cosine { + use ArrayEnabled; + /** * COS. * * Returns the result of builtin function cos after validating args. * - * @param mixed $number Should be numeric + * @param mixed $number Should be numeric, or can be an array of numbers * - * @return float|string cosine + * @return array|float|string cosine + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function cos($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { @@ -32,12 +41,18 @@ class Cosine * * Returns the result of builtin function cosh after validating args. * - * @param mixed $number Should be numeric + * @param mixed $number Should be numeric, or can be an array of numbers * - * @return float|string hyperbolic cosine + * @return array|float|string hyperbolic cosine + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function cosh($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { @@ -52,12 +67,18 @@ class Cosine * * Returns the arccosine of a number. * - * @param float $number Number + * @param array|float $number Number, or can be an array of numbers * - * @return float|string The arccosine of the number + * @return array|float|string The arccosine of the number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function acos($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { @@ -72,12 +93,18 @@ class Cosine * * Returns the arc inverse hyperbolic cosine of a number. * - * @param float $number Number + * @param array|float $number Number, or can be an array of numbers * - * @return float|string The inverse hyperbolic cosine of the number, or an error string + * @return array|float|string The inverse hyperbolic cosine of the number, or an error string + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function acosh($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cotangent.php b/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cotangent.php index 1b796f50..eeedef9b 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cotangent.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Cotangent.php @@ -2,22 +2,31 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Helpers; class Cotangent { + use ArrayEnabled; + /** * COT. * * Returns the cotangent of an angle. * - * @param float $angle Number + * @param array|float $angle Number, or can be an array of numbers * - * @return float|string The cotangent of the angle + * @return array|float|string The cotangent of the angle + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function cot($angle) { + if (is_array($angle)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle); + } + try { $angle = Helpers::validateNumericNullBool($angle); } catch (Exception $e) { @@ -32,12 +41,18 @@ class Cotangent * * Returns the hyperbolic cotangent of an angle. * - * @param float $angle Number + * @param array|float $angle Number, or can be an array of numbers * - * @return float|string The hyperbolic cotangent of the angle + * @return array|float|string The hyperbolic cotangent of the angle + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function coth($angle) { + if (is_array($angle)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle); + } + try { $angle = Helpers::validateNumericNullBool($angle); } catch (Exception $e) { @@ -52,12 +67,18 @@ class Cotangent * * Returns the arccotangent of a number. * - * @param float $number Number + * @param array|float $number Number, or can be an array of numbers * - * @return float|string The arccotangent of the number + * @return array|float|string The arccotangent of the number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function acot($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { @@ -72,12 +93,18 @@ class Cotangent * * Returns the hyperbolic arccotangent of a number. * - * @param float $number Number + * @param array|float $number Number, or can be an array of numbers * - * @return float|string The hyperbolic arccotangent of the number + * @return array|float|string The hyperbolic arccotangent of the number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function acoth($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Secant.php b/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Secant.php index 70299cb7..2d26e5dd 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Secant.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Secant.php @@ -2,22 +2,31 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Helpers; class Secant { + use ArrayEnabled; + /** * SEC. * * Returns the secant of an angle. * - * @param float $angle Number + * @param array|float $angle Number, or can be an array of numbers * - * @return float|string The secant of the angle + * @return array|float|string The secant of the angle + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function sec($angle) { + if (is_array($angle)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle); + } + try { $angle = Helpers::validateNumericNullBool($angle); } catch (Exception $e) { @@ -32,12 +41,18 @@ class Secant * * Returns the hyperbolic secant of an angle. * - * @param float $angle Number + * @param array|float $angle Number, or can be an array of numbers * - * @return float|string The hyperbolic secant of the angle + * @return array|float|string The hyperbolic secant of the angle + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function sech($angle) { + if (is_array($angle)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle); + } + try { $angle = Helpers::validateNumericNullBool($angle); } catch (Exception $e) { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Sine.php b/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Sine.php index 2c6a8a07..6af568ce 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Sine.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Sine.php @@ -2,22 +2,31 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Helpers; class Sine { + use ArrayEnabled; + /** * SIN. * * Returns the result of builtin function sin after validating args. * - * @param mixed $angle Should be numeric + * @param mixed $angle Should be numeric, or can be an array of numbers * - * @return float|string sine + * @return array|float|string sine + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function sin($angle) { + if (is_array($angle)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle); + } + try { $angle = Helpers::validateNumericNullBool($angle); } catch (Exception $e) { @@ -32,12 +41,18 @@ class Sine * * Returns the result of builtin function sinh after validating args. * - * @param mixed $angle Should be numeric + * @param mixed $angle Should be numeric, or can be an array of numbers * - * @return float|string hyperbolic sine + * @return array|float|string hyperbolic sine + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function sinh($angle) { + if (is_array($angle)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle); + } + try { $angle = Helpers::validateNumericNullBool($angle); } catch (Exception $e) { @@ -52,12 +67,18 @@ class Sine * * Returns the arcsine of a number. * - * @param float $number Number + * @param array|float $number Number, or can be an array of numbers * - * @return float|string The arcsine of the number + * @return array|float|string The arcsine of the number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function asin($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { @@ -72,12 +93,18 @@ class Sine * * Returns the inverse hyperbolic sine of a number. * - * @param float $number Number + * @param array|float $number Number, or can be an array of numbers * - * @return float|string The inverse hyperbolic sine of the number + * @return array|float|string The inverse hyperbolic sine of the number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function asinh($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Tangent.php b/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Tangent.php index 6cd235fb..26bd44f7 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Tangent.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Trig/Tangent.php @@ -2,23 +2,32 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Helpers; class Tangent { + use ArrayEnabled; + /** * TAN. * * Returns the result of builtin function tan after validating args. * - * @param mixed $angle Should be numeric + * @param mixed $angle Should be numeric, or can be an array of numbers * - * @return float|string tangent + * @return array|float|string tangent + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function tan($angle) { + if (is_array($angle)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle); + } + try { $angle = Helpers::validateNumericNullBool($angle); } catch (Exception $e) { @@ -33,12 +42,18 @@ class Tangent * * Returns the result of builtin function sinh after validating args. * - * @param mixed $angle Should be numeric + * @param mixed $angle Should be numeric, or can be an array of numbers * - * @return float|string hyperbolic tangent + * @return array|float|string hyperbolic tangent + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function tanh($angle) { + if (is_array($angle)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle); + } + try { $angle = Helpers::validateNumericNullBool($angle); } catch (Exception $e) { @@ -53,12 +68,18 @@ class Tangent * * Returns the arctangent of a number. * - * @param float $number Number + * @param array|float $number Number, or can be an array of numbers * - * @return float|string The arctangent of the number + * @return array|float|string The arctangent of the number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function atan($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { @@ -73,12 +94,18 @@ class Tangent * * Returns the inverse hyperbolic tangent of a number. * - * @param float $number Number + * @param array|float $number Number, or can be an array of numbers * - * @return float|string The inverse hyperbolic tangent of the number + * @return array|float|string The inverse hyperbolic tangent of the number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function atanh($number) { + if (is_array($number)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { @@ -104,13 +131,20 @@ class Tangent * Excel Function: * ATAN2(xCoordinate,yCoordinate) * - * @param mixed $xCoordinate should be float, the x-coordinate of the point - * @param mixed $yCoordinate should be float, the y-coordinate of the point + * @param mixed $xCoordinate should be float, the x-coordinate of the point, or can be an array of numbers + * @param mixed $yCoordinate should be float, the y-coordinate of the point, or can be an array of numbers * - * @return float|string the inverse tangent of the specified x- and y-coordinates, or a string containing an error + * @return array|float|string + * The inverse tangent of the specified x- and y-coordinates, or a string containing an error + * If an array of numbers is passed as one of the arguments, then the returned result will also be an array + * with the same dimensions */ public static function atan2($xCoordinate, $yCoordinate) { + if (is_array($xCoordinate) || is_array($yCoordinate)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $xCoordinate, $yCoordinate); + } + try { $xCoordinate = Helpers::validateNumericNullBool($xCoordinate); $yCoordinate = Helpers::validateNumericNullBool($yCoordinate); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php index 5e884707..95266409 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php @@ -2,7 +2,9 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Date; +use PhpOffice\PhpSpreadsheet\Calculation\Exception; class DateTest extends AllSetupTeardown { @@ -56,4 +58,95 @@ class DateTest extends AllSetupTeardown $result = Date::fromYMD(1901, 1, 31); self::assertEquals($result, '#NUM!'); } + + /** + * @dataProvider providerDateArray + */ + public function testDateArray(array $expectedResult, string $year, string $month, string $day): void + { + $calculation = Calculation::getInstance(); + + $formula = "=DATE({$year}, {$month}, {$day})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerDateArray(): array + { + return [ + 'row vector year' => [[[44197, 44562, 44927]], '{2021,2022,2023}', '1', '1'], + 'column vector year' => [[[44197], [44562], [44927]], '{2021;2022;2023}', '1', '1'], + 'matrix year' => [[[43831.00, 44197], [44562, 44927]], '{2020,2021;2022,2023}', '1', '1'], + 'row vector month' => [[[44562, 44652, 44743, 44835]], '2022', '{1, 4, 7, 10}', '1'], + 'column vector month' => [[[44562], [44652], [44743], [44835]], '2022', '{1; 4; 7; 10}', '1'], + 'matrix month' => [[[44562, 44652], [44743, 44835]], '2022', '{1, 4; 7, 10}', '1'], + 'row vector day' => [[[44561, 44562]], '2022', '1', '{0,1}'], + 'column vector day' => [[[44561], [44562]], '2022', '1', '{0;1}'], + 'vectors year and month' => [ + [ + [44197, 44287, 44378, 44470], + [44562, 44652, 44743, 44835], + [44927, 45017, 45108, 45200], + ], + '{2021;2022;2023}', + '{1, 4, 7, 10}', + '1', + ], + 'vectors year and day' => [ + [ + [44196, 44197], + [44561, 44562], + [44926, 44927], + ], + '{2021;2022;2023}', + '1', + '{0,1}', + ], + 'vectors month and day' => [ + [ + [44561, 44562], + [44651, 44652], + [44742, 44743], + [44834, 44835], + ], + '2022', + '{1; 4; 7; 10}', + '{0,1}', + ], + 'matrices year and month' => [ + [ + [43831, 44287], + [44743, 45200], + ], + '{2020, 2021; 2022, 2023}', + '{1, 4; 7, 10}', + '1', + ], + ]; + } + + /** + * @dataProvider providerDateArrayException + */ + public function testDateArrayException(string $year, string $month, string $day): void + { + $calculation = Calculation::getInstance(); + + $this->expectException(Exception::class); + $this->expectExceptionMessage('Formulae with more than two array arguments are not supported'); + + $formula = "=DATE({$year}, {$month}, {$day})"; + $calculation->_calculateFormulaValue($formula); + } + + public function providerDateArrayException(): array + { + return [ + 'matrix arguments with 3 array values' => [ + '{2020, 2021; 2022, 2023}', + '{1, 4; 7, 10}', + '{0,1}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AbsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AbsTest.php index b6871905..fda464ed 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AbsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AbsTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class AbsTest extends AllSetupTeardown { /** @@ -28,4 +30,25 @@ class AbsTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ABS.php'; } + + /** + * @dataProvider providerAbsArray + */ + public function testAbsoluteArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ABS({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerAbsArray(): array + { + return [ + 'row vector' => [[[1, 0, 1]], '{-1, 0, 1}'], + 'column vector' => [[[1], [0], [1]], '{-1; 0; 1}'], + 'matrix' => [[[1, 0], [1, 1.4]], '{-1, 0; 1, -1.4}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcosTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcosTest.php index 4b71a541..ebdc9130 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcosTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcosTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class AcosTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class AcosTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ACOS.php'; } + + /** + * @dataProvider providerAcosArray + */ + public function testAcosArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ACOS({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerAcosArray(): array + { + return [ + 'row vector' => [[[0.0, 1.04719755119660, 3.14159265358979]], '{1, 0.5, -1}'], + 'column vector' => [[[0.0], [1.04719755119660], [3.14159265358979]], '{1; 0.5; -1}'], + 'matrix' => [[[0.0, 1.04719755119660], [1.57079632679490, 3.14159265358979]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcoshTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcoshTest.php index c2116009..f9ee3ef4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcoshTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcoshTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class AcoshTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class AcoshTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ACOSH.php'; } + + /** + * @dataProvider providerAcoshArray + */ + public function testAcoshArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ACOSH({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerAcoshArray(): array + { + return [ + 'row vector' => [[[0.0, 1.31695789692482, 1.76274717403909]], '{1, 2, 3}'], + 'column vector' => [[[0.0], [1.31695789692482], [1.76274717403909]], '{1; 2; 3}'], + 'matrix' => [[[0.0, 1.31695789692482], [1.76274717403909, 2.06343706889556]], '{1, 2; 3, 4}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcotTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcotTest.php index 8aa5541f..9f63ac9d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcotTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcotTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class AcotTest extends AllSetupTeardown { /** @@ -27,4 +29,25 @@ class AcotTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ACOT.php'; } + + /** + * @dataProvider providerAcotArray + */ + public function testAcotArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ACOT({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerAcotArray(): array + { + return [ + 'row vector' => [[[0.78539816339745, 1.10714871779409, 2.35619449019234]], '{1, 0.5, -1}'], + 'column vector' => [[[0.78539816339745], [1.10714871779409], [2.35619449019234]], '{1; 0.5; -1}'], + 'matrix' => [[[0.78539816339745, 1.10714871779409], [1.57079632679490, 2.35619449019234]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcothTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcothTest.php index 173d27b5..8e2555e0 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcothTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcothTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class AcothTest extends AllSetupTeardown { /** @@ -27,4 +29,25 @@ class AcothTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ACOTH.php'; } + + /** + * @dataProvider providerAcothArray + */ + public function testAcothArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ACOTH({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerAcothArray(): array + { + return [ + 'row vector' => [[[-0.20273255405408, 0.54930614433406, 0.13413199329734]], '{-5, 2, 7.5}'], + 'column vector' => [[[-0.20273255405408], [0.54930614433406], [0.13413199329734]], '{-5; 2; 7.5}'], + 'matrix' => [[[-0.20273255405408, 0.54930614433406], ['#NUM!', 0.13413199329734]], '{-5, 2; 0, 7.5}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ArabicTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ArabicTest.php index 7921e85d..57f2717f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ArabicTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ArabicTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class ArabicTest extends AllSetupTeardown { /** @@ -24,4 +26,25 @@ class ArabicTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ARABIC.php'; } + + /** + * @dataProvider providerArabicArray + */ + public function testArabicArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ARABIC({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerArabicArray(): array + { + return [ + 'row vector' => [[[49, 2022, 499]], '{"XLIX", "MMXXII", "VDIV"}'], + 'column vector' => [[[49], [2022], [499]], '{"XLIX"; "MMXXII"; "VDIV"}'], + 'matrix' => [[[49, 2022], [-499, 499]], '{"XLIX", "MMXXII"; "-ID", "VDIV"}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinTest.php index 73500d9a..87a6da39 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class AsinTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class AsinTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ASIN.php'; } + + /** + * @dataProvider providerAsinArray + */ + public function testAsinArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ASIN({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerAsinArray(): array + { + return [ + 'row vector' => [[[1.57079632679490, 0.52359877559830, -1.57079632679490]], '{1, 0.5, -1}'], + 'column vector' => [[[1.57079632679490], [0.52359877559830], [-1.57079632679490]], '{1; 0.5; -1}'], + 'matrix' => [[[1.57079632679490, 0.52359877559830], [0.0, -1.57079632679490]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinhTest.php index 4337a394..c6fb5f32 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinhTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinhTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class AsinhTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class AsinhTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ASINH.php'; } + + /** + * @dataProvider providerAsinhArray + */ + public function testAsinhArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ASINH({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerAsinhArray(): array + { + return [ + 'row vector' => [[[0.88137358701954, 0.48121182505960, -0.88137358701954]], '{1, 0.5, -1}'], + 'column vector' => [[[0.88137358701954], [0.48121182505960], [-0.88137358701954]], '{1; 0.5; -1}'], + 'matrix' => [[[0.88137358701954, 0.48121182505960], [0.0, -0.88137358701954]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Atan2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Atan2Test.php index dcf35ad1..2ff47b3b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Atan2Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Atan2Test.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class Atan2Test extends AllSetupTeardown { /** @@ -24,4 +26,72 @@ class Atan2Test extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ATAN2.php'; } + + /** + * @dataProvider providerAtan2Array + */ + public function testAtan2Array(array $expectedResult, string $argument1, string $argument2): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ATAN2({$argument1},{$argument2})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerAtan2Array(): array + { + return [ + 'first argument row vector' => [ + [[1.81577498992176, 1.17600520709514]], + '{-0.75, 1.25}', + '3', + ], + 'first argument column vector' => [ + [[1.17600520709514], [0.98279372324733]], + '{1.25; 2}', + '3', + ], + 'first argument matrix' => [ + [[2.03444393579570, 1.48765509490646], [1.57079632679490, 1.24904577239825]], + '{-1.5, 0.25; 0, 1}', + '3', + ], + 'second argument row vector' => [ + [[-0.24497866312686, 0.39479111969976]], + '3', + '{-0.75, 1.25}', + ], + 'second argument column vector' => [ + [[0.39479111969976], [0.58800260354757]], + '3', + '{1.25; 2}', + ], + 'second argument matrix' => [ + [[-0.46364760900081, 0.08314123188844], [0.0, 0.32175055439664]], + '3', + '{-1.5, 0.25; 0, 1}', + ], + 'A row and a column vector' => [ + [ + [-2.21429743558818, 2.81984209919315, 2.55359005004223, 1.92956699706547], + [-1.69515132134166, 2.03444393579570, 1.81577498992176, 1.63321513679085], + [-1.01219701145133, 0.38050637711237, 0.67474094222355, 1.26791145841993], + [-0.51914611424652, 0.14189705460416, 0.27829965900511, 0.85196632717327], + ], + '{-1.5; -0.25; 1.25; 3.5}', + '{-2, 0.5, 1, 4}', + ], + 'Two row vectors' => [ + [[-2.21429743558818, 2.03444393579570, 0.67474094222355, 0.85196632717327]], + '{-1.5, -0.25, 1.25, 3.5}', + '{-2, 0.5, 1, 4}', + ], + 'Two column vectors' => [ + [[-2.21429743558818], [2.03444393579570], [0.67474094222355], [0.85196632717327]], + '{-1.5; -0.25; 1.25; 3.5}', + '{-2; 0.5; 1; 4}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanTest.php index 4eefd922..d79c8576 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class AtanTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class AtanTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ATAN.php'; } + + /** + * @dataProvider providerAtanArray + */ + public function testAtanArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ATAN({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerAtanArray(): array + { + return [ + 'row vector' => [[[0.78539816339745, 0.46364760900081, -0.78539816339745]], '{1, 0.5, -1}'], + 'column vector' => [[[0.78539816339745], [0.46364760900081], [-0.78539816339745]], '{1; 0.5; -1}'], + 'matrix' => [[[0.78539816339745, 0.46364760900081], [0.0, -0.78539816339745]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanhTest.php index d790b526..dad09ba2 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanhTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanhTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class AtanhTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class AtanhTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ATANH.php'; } + + /** + * @dataProvider providerAtanhArray + */ + public function testAtanhArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ATANH({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerAtanhArray(): array + { + return [ + 'row vector' => [[[1.83178082306482, 0.54930614433406, -1.83178082306482]], '{0.95, 0.5, -0.95}'], + 'column vector' => [[[1.83178082306482], [0.54930614433406], [-1.83178082306482]], '{0.95; 0.5; -0.95}'], + 'matrix' => [[[1.83178082306482, 0.54930614433406], [0.0, -1.83178082306482]], '{0.95, 0.5; 0, -0.95}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinATest.php index 0bc70de1..7c2200a0 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinATest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class CombinATest extends AllSetupTeardown { /** @@ -30,4 +32,72 @@ class CombinATest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/COMBINA.php'; } + + /** + * @dataProvider providerCombinAArray + */ + public function testCombinAArray(array $expectedResult, string $argument1, string $argument2): void + { + $calculation = Calculation::getInstance(); + + $formula = "=COMBINA({$argument1},{$argument2})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerCombinAArray(): array + { + return [ + 'first argument row vector' => [ + [[120, 35]], + '{8, 5}', + '3', + ], + 'first argument column vector' => [ + [[120], [35]], + '{8; 5}', + '3', + ], + 'first argument matrix' => [ + [[120, 35], [10, 84]], + '{8, 5; 3, 7}', + '3', + ], + 'second argument row vector' => [ + [[455, 18564]], + '13', + '{3, 6}', + ], + 'second argument column vector' => [ + [[455], [18564]], + '13', + '{3; 6}', + ], + 'second argument matrix' => [ + [[455, 18564], [1820, 125970]], + '13', + '{3, 6; 4, 8}', + ], + 'A row and a column vector' => [ + [ + [4368, 1365, 364, 78], + [2002, 715, 220, 55], + [792, 330, 120, 36], + [252, 126, 56, 21], + ], + '{12; 10; 8; 6}', + '{5, 4, 3, 2}', + ], + 'Two row vectors' => [ + [[4368, 715, 120, 21]], + '{12, 10, 8, 6}', + '{5, 4, 3, 2}', + ], + 'Two column vectors' => [ + [[4368], [715], [120], [21]], + '{12; 10; 8; 6}', + '{5; 4; 3; 2}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinTest.php index 8680dee6..18e3eed6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class CombinTest extends AllSetupTeardown { /** @@ -30,4 +32,72 @@ class CombinTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/COMBIN.php'; } + + /** + * @dataProvider providerCombinArray + */ + public function testCombinArray(array $expectedResult, string $argument1, string $argument2): void + { + $calculation = Calculation::getInstance(); + + $formula = "=COMBIN({$argument1},{$argument2})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerCombinArray(): array + { + return [ + 'first argument row vector' => [ + [[56, 10]], + '{8, 5}', + '3', + ], + 'first argument column vector' => [ + [[56], [10]], + '{8; 5}', + '3', + ], + 'first argument matrix' => [ + [[56, 10], [1, 35]], + '{8, 5; 3, 7}', + '3', + ], + 'second argument row vector' => [ + [[286, 1716]], + '13', + '{3, 6}', + ], + 'second argument column vector' => [ + [[286], [1716]], + '13', + '{3; 6}', + ], + 'second argument matrix' => [ + [[286, 1716], [715, 1287]], + '13', + '{3, 6; 4, 8}', + ], + 'A row and a column vector' => [ + [ + [792, 495, 220, 66], + [252, 210, 120, 45], + [56, 70, 56, 28], + [6, 15, 20, 15], + ], + '{12; 10; 8; 6}', + '{5, 4, 3, 2}', + ], + 'Two row vectors' => [ + [[792, 210, 56, 15]], + '{12, 10, 8, 6}', + '{5, 4, 3, 2}', + ], + 'Two column vectors' => [ + [[792], [210], [56], [15]], + '{12; 10; 8; 6}', + '{5; 4; 3; 2}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CosTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CosTest.php index 2024c6b2..5b51fb0f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CosTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CosTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class CosTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class CosTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/COS.php'; } + + /** + * @dataProvider providerCosArray + */ + public function testCosArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=COS({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerCosArray(): array + { + return [ + 'row vector' => [[[0.54030230586814, 0.87758256189037, 0.54030230586814]], '{1, 0.5, -1}'], + 'column vector' => [[[0.54030230586814], [0.87758256189037], [0.54030230586814]], '{1; 0.5; -1}'], + 'matrix' => [[[0.54030230586814, 0.87758256189037], [1.0, 0.54030230586814]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CoshTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CoshTest.php index 1a87f72e..f4135cc2 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CoshTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CoshTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class CoshTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class CoshTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/COSH.php'; } + + /** + * @dataProvider providerCoshArray + */ + public function testCoshArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=COSH({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerCoshArray(): array + { + return [ + 'row vector' => [[[1.54308063481524, 1.12762596520638, 1.54308063481524]], '{1, 0.5, -1}'], + 'column vector' => [[[1.54308063481524], [1.12762596520638], [1.54308063481524]], '{1; 0.5; -1}'], + 'matrix' => [[[1.54308063481524, 1.12762596520638], [1.0, 1.54308063481524]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CotTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CotTest.php index db9c17d1..d2d1c4e2 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CotTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CotTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class CotTest extends AllSetupTeardown { /** @@ -27,4 +29,25 @@ class CotTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/COT.php'; } + + /** + * @dataProvider providerCotArray + */ + public function testCotArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=COT({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerCotArray(): array + { + return [ + 'row vector' => [[[0.64209261593433, 1.83048772171245, -0.64209261593433]], '{1, 0.5, -1}'], + 'column vector' => [[[0.64209261593433], [1.83048772171245], [-0.64209261593433]], '{1; 0.5; -1}'], + 'matrix' => [[[0.64209261593433, 1.83048772171245], ['#DIV/0!', -0.64209261593433]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CothTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CothTest.php index ed0bf13e..ec203a78 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CothTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CothTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class CothTest extends AllSetupTeardown { /** @@ -27,4 +29,25 @@ class CothTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/COTH.php'; } + + /** + * @dataProvider providerCothArray + */ + public function testCothArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=COTH({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerCothArray(): array + { + return [ + 'row vector' => [[[1.31303528549933, 2.16395341373865, -1.31303528549933]], '{1, 0.5, -1}'], + 'column vector' => [[[1.31303528549933], [2.16395341373865], [-1.31303528549933]], '{1; 0.5; -1}'], + 'matrix' => [[[1.31303528549933, 2.16395341373865], ['#DIV/0!', -1.31303528549933]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CscTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CscTest.php index ff4067a7..73ff086e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CscTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CscTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class CscTest extends AllSetupTeardown { /** @@ -27,4 +29,25 @@ class CscTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/CSC.php'; } + + /** + * @dataProvider providerCscArray + */ + public function testCscArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=CSC({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerCscArray(): array + { + return [ + 'row vector' => [[[1.18839510577812, 2.08582964293349, -1.18839510577812]], '{1, 0.5, -1}'], + 'column vector' => [[[1.18839510577812], [2.08582964293349], [-1.18839510577812]], '{1; 0.5; -1}'], + 'matrix' => [[[1.18839510577812, 2.08582964293349], ['#DIV/0!', -1.18839510577812]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CschTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CschTest.php index 9f6a87e7..8ffb408a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CschTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CschTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class CschTest extends AllSetupTeardown { /** @@ -27,4 +29,25 @@ class CschTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/CSCH.php'; } + + /** + * @dataProvider providerCschArray + */ + public function testCschArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=CSCH({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerCschArray(): array + { + return [ + 'row vector' => [[[0.85091812823932, 1.91903475133494, -0.85091812823932]], '{1, 0.5, -1}'], + 'column vector' => [[[0.85091812823932], [1.91903475133494], [-0.85091812823932]], '{1; 0.5; -1}'], + 'matrix' => [[[0.85091812823932, 1.91903475133494], ['#DIV/0!', -0.85091812823932]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/DegreesTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/DegreesTest.php index c931be2b..20d52853 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/DegreesTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/DegreesTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class DegreesTest extends AllSetupTeardown { /** @@ -28,4 +30,25 @@ class DegreesTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/DEGREES.php'; } + + /** + * @dataProvider providerDegreesArray + */ + public function testDegreesArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=DEGREES({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); + } + + public function providerDegreesArray(): array + { + return [ + 'row vector' => [[[143.23944878270600, 7.16197243913529, -183.34649444186300]], '{2.5, 0.125, -3.2}'], + 'column vector' => [[[143.23944878270600], [7.16197243913529], [-183.34649444186300]], '{2.5; 0.125; -3.2}'], + 'matrix' => [[[143.23944878270600, 7.16197243913529], [429.71834634811700, -183.34649444186300]], '{2.5, 0.125; 7.5, -3.2}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/EvenTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/EvenTest.php index 933737b4..1dab09f2 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/EvenTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/EvenTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class EvenTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class EvenTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/EVEN.php'; } + + /** + * @dataProvider providerEvenArray + */ + public function testEvenArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=EVEN({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerEvenArray(): array + { + return [ + 'row vector' => [[[-4, 2, 4]], '{-3, 1, 4}'], + 'column vector' => [[[-4], [2], [4]], '{-3; 1; 4}'], + 'matrix' => [[[-4, 2], [4, 2]], '{-3, 1; 4, 1.5}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ExpTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ExpTest.php index c1c88bb1..07014bd4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ExpTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ExpTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class ExpTest extends AllSetupTeardown { /** @@ -30,4 +32,25 @@ class ExpTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/EXP.php'; } + + /** + * @dataProvider providerExpArray + */ + public function testExpArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=EXP({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerExpArray(): array + { + return [ + 'row vector' => [[[1.0, 2.718281828459045, 12.182493960703473]], '{0, 1, 2.5}'], + 'column vector' => [[[1.0], [2.718281828459045], [12.182493960703473]], '{0; 1; 2.5}'], + 'matrix' => [[[1.0, 2.718281828459045], [12.182493960703473, 0.0820849986239]], '{0, 1; 2.5, -2.5}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactDoubleTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactDoubleTest.php index 7a620655..34c92251 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactDoubleTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactDoubleTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class FactDoubleTest extends AllSetupTeardown { /** @@ -24,4 +26,25 @@ class FactDoubleTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/FACTDOUBLE.php'; } + + /** + * @dataProvider providerFactDoubleArray + */ + public function testFactDoubleArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=FACTDOUBLE({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerFactDoubleArray(): array + { + return [ + 'row vector' => [[['#NUM!', 48, 945]], '{-2, 6, 9}'], + 'column vector' => [[['#NUM!'], [48], [945]], '{-2; 6; 9}'], + 'matrix' => [[['#NUM!', 48], [945, 3]], '{-2, 6; 9, 3.5}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactTest.php index 5dca45ff..328773e0 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class FactTest extends AllSetupTeardown { /** @@ -58,4 +60,25 @@ class FactTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/FACTGNUMERIC.php'; } + + /** + * @dataProvider providerFactArray + */ + public function testFactArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=FACT({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerFactArray(): array + { + return [ + 'row vector' => [[['#NUM!', 120, 362880]], '{-2, 5, 9}'], + 'column vector' => [[['#NUM!'], [120], [362880]], '{-2; 5; 9}'], + 'matrix' => [[['#NUM!', 120], [362880, 6]], '{-2, 5; 9, 3.5}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/IntTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/IntTest.php index e121decb..42a24af5 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/IntTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/IntTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class IntTest extends AllSetupTeardown { /** @@ -27,4 +29,25 @@ class IntTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/INT.php'; } + + /** + * @dataProvider providerIntArray + */ + public function testIntArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=INT({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerIntArray(): array + { + return [ + 'row vector' => [[[-2, 0, 0]], '{-1.5, 0, 0.3}'], + 'column vector' => [[[-2], [0], [0]], '{-1.5; 0; 0.3}'], + 'matrix' => [[[-2, 0], [0, 12]], '{-1.5, 0; 0.3, 12.5}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MRoundTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MRoundTest.php index 80a3d4ba..b9e48b90 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MRoundTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MRoundTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class MRoundTest extends AllSetupTeardown { /** @@ -27,4 +29,72 @@ class MRoundTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/MROUND.php'; } + + /** + * @dataProvider providerMRoundArray + */ + public function testMRoundArray(array $expectedResult, string $argument1, string $argument2): void + { + $calculation = Calculation::getInstance(); + + $formula = "=MROUND({$argument1},{$argument2})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerMRoundArray(): array + { + return [ + 'first argument row vector' => [ + [[0.15, 1.375, 931.675, 3.15]], + '{0.14527, 1.3725, 931.6829, 3.14159265}', + '0.025', + ], + 'first argument column vector' => [ + [[0.15], [1.375], [931.675], [3.15]], + '{0.14527; 1.3725; 931.6829; 3.14159265}', + '0.025', + ], + 'first argument matrix' => [ + [[0.15, 1.375], [931.675, 3.15]], + '{0.14527, 1.3725; 931.6829, 3.14159265}', + '0.025', + ], + 'second argument row vector' => [ + [[123.125, 123.125, 123.1, 123.2, 125]], + '123.12345', + '{0.005, 0.025, 0.1, 0.2, 5}', + ], + 'second argument column vector' => [ + [[123.125], [123.125], [123.1], [123.2], [125]], + '123.12345', + '{0.005; 0.025; 0.1; 0.2; 5}', + ], + 'second argument matrix' => [ + [[123.125, 123.125], [123.2, 125.0]], + '123.12345', + '{0.005, 0.025; 0.2, 5}', + ], + 'A row and a column vector' => [ + [ + [0.145, 0.15, 0.2, 0.0], + [1.375, 1.375, 1.4, 0.0], + [931.685, 931.675, 931.6, 930.0], + [3.14, 3.15, 3.2, 5.0], + ], + '{0.14527; 1.37250; 931.68290; 3.14159265}', + '{0.005, 0.025, 0.2, 5}', + ], + 'Two row vectors' => [ + [[0.145, 1.375, 931.6, 5.0]], + '{0.14527, 1.3725, 931.6, 3.14159265}', + '{0.005, 0.025, 0.2, 5}', + ], + 'Two column vectors' => [ + [[0.145], [1.375], [931.6], [5.0]], + '{0.14527; 1.37250; 931.6; 5}', + '{0.005; 0.025; 0.2; 5}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/OddTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/OddTest.php index 4f6b0cab..8ef0e0f3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/OddTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/OddTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class OddTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class OddTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ODD.php'; } + + /** + * @dataProvider providerOddArray + */ + public function testOddArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ODD({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerOddArray(): array + { + return [ + 'row vector' => [[[-3, 1, 5]], '{-3, 1, 4}'], + 'column vector' => [[[-3], [1], [5]], '{-3; 1; 4}'], + 'matrix' => [[[-3, 1], [5, 3]], '{-3, 1; 4, 1.5}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RadiansTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RadiansTest.php index 82df95f4..5468528f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RadiansTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RadiansTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class RadiansTest extends AllSetupTeardown { /** @@ -28,4 +30,25 @@ class RadiansTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/RADIANS.php'; } + + /** + * @dataProvider providerRadiansArray + */ + public function testRadiansArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=RADIANS({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerRadiansArray(): array + { + return [ + 'row vector' => [[[1.48352986419518, 3.92699081698724, -0.26179938779915]], '{85, 225, -15}'], + 'column vector' => [[[1.48352986419518], [3.92699081698724], [-0.26179938779915]], '{85; 225; -15}'], + 'matrix' => [[[1.48352986419518, 3.92699081698724], [7.85398163397448, -0.26179938779915]], '{85, 225; 450, -15}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundDownTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundDownTest.php index 7adc8258..76ad3015 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundDownTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundDownTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class RoundDownTest extends AllSetupTeardown { /** @@ -27,4 +29,72 @@ class RoundDownTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ROUNDDOWN.php'; } + + /** + * @dataProvider providerRoundDownArray + */ + public function testRoundDownArray(array $expectedResult, string $argument1, string $argument2): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ROUNDDOWN({$argument1},{$argument2})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerRoundDownArray(): array + { + return [ + 'first argument row vector' => [ + [[0.145, 1.372, -931.682, 3.141]], + '{0.14527, 1.3725, -931.6829, 3.14159265}', + '3', + ], + 'first argument column vector' => [ + [[0.145], [1.372], [-931.682], [3.141]], + '{0.14527; 1.3725; -931.6829; 3.14159265}', + '3', + ], + 'first argument matrix' => [ + [[0.145, 1.372], [-931.682, 3.141]], + '{0.14527, 1.3725; -931.6829, 3.14159265}', + '3', + ], + 'second argument row vector' => [ + [[0.1, 0.14, 0.145, 0.1452, 0.14527]], + '0.14527', + '{1, 2, 3, 4, 5}', + ], + 'second argument column vector' => [ + [[0.1], [0.14], [0.145], [0.1452], [0.14527]], + '0.14527', + '{1; 2; 3; 4; 5}', + ], + 'second argument matrix' => [ + [[0.1, 0.14], [0.145, 0.1452]], + '0.14527', + '{1, 2; 3, 4}', + ], + 'A row and a column vector' => [ + [ + [0.1, 0.14, 0.145, 0.1452], + [1.3, 1.37, 1.372, 1.3725], + [-931.6, -931.68, -931.682, -931.6829], + [3.1, 3.14, 3.141, 3.1415], + ], + '{0.14527; 1.37250; -931.68290; 3.14159265}', + '{1, 2, 3, 4}', + ], + 'Two row vectors' => [ + [[0.1, 1.37, -931.682, 3.1415]], + '{0.14527, 1.37250, -931.68290, 3.14159265}', + '{1, 2, 3, 4}', + ], + 'Two column vectors' => [ + [[0.1], [1.37], [-931.682], [3.1415]], + '{0.14527; 1.37250; -931.68290; 3.14159265}', + '{1; 2; 3; 4}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundTest.php index 72f57580..710d5b00 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class RoundTest extends AllSetupTeardown { /** @@ -27,4 +29,149 @@ class RoundTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ROUND.php'; } + + /** + * @dataProvider providerRoundArray + */ + public function testRoundArray(array $expectedResult, string $argument1, string $argument2): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ROUND({$argument1},{$argument2})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerRoundArray(): array + { + return [ + 'first argument row vector' => [ + [[0.145, 1.373, -931.683, 3.142]], + '{0.14527, 1.3725, -931.6829, 3.14159265}', + '3', + ], + 'first argument column vector' => [ + [[0.145], [1.373], [-931.683], [3.142]], + '{0.14527; 1.3725; -931.6829; 3.14159265}', + '3', + ], + 'first argument matrix' => [ + [[0.145, 1.373], [-931.683, 3.142]], + '{0.14527, 1.3725; -931.6829, 3.14159265}', + '3', + ], + 'second argument row vector' => [ + [[0.1, 0.12, 0.123, 0.1235, 0.12345]], + '0.12345', + '{1, 2, 3, 4, 5}', + ], + 'second argument column vector' => [ + [[0.1], [0.12], [0.123], [0.1235], [0.12345]], + '0.12345', + '{1; 2; 3; 4; 5}', + ], + 'second argument matrix' => [ + [[0.1, 0.12], [0.123, 0.1235]], + '0.12345', + '{1, 2; 3, 4}', + ], + 'A row and a column vector' => [ + [ + [0.1, 0.15, 0.145, 0.1453], + [1.4, 1.37, 1.373, 1.3725], + [-931.7, -931.68, -931.683, -931.6829], + [3.1, 3.14, 3.142, 3.1416], + ], + '{0.14527; 1.37250; -931.68290; 3.14159265}', + '{1, 2, 3, 4}', + ], + 'Two row vectors' => [ + [[0.1, 1.37, -931.683, 3.1416]], + '{0.14527, 1.37250, -931.68290, 3.14159265}', + '{1, 2, 3, 4}', + ], + 'Two different size row vectors' => [ + [[0.1, 1.37]], + '{0.14527, 1.37250, -931.68290, 3.14159265}', + '{1, 2}', + ], + 'Two column vectors' => [ + [[0.1], [1.37], [-931.683], [3.1416]], + '{0.14527; 1.37250; -931.68290; 3.14159265}', + '{1; 2; 3; 4}', + ], + 'Two matching square matrices' => [ + [ + [10000, 46000, 78900], + [23460, 56789, 89012.3], + [34567.89, 67890.123, 90123.4568], + ], + '{12345.67890, 45678.90123, 78901.23456; 23456.78901, 56789.01234, 89012.34567; 34567.89012, 67890.12345, 90123.45678}', + '{-4, -3, -2; -1, 0, 1; 2, 3, 4}', + ], + 'Two paired 2x3 matrices' => [ + [ + [10000, 46000, 78900], + [23460, 56789, 89012.3], + ], + '{12345.67890, 45678.90123, 78901.23456; 23456.78901, 56789.01234, 89012.34567}', + '{-4, -3, -2; -1, 0, 1}', + ], + 'Two paired 3x2 matrices' => [ + [ + [10000, 46000], + [23460, 56789], + [34567.89, 67890.123], + ], + '{12345.67890, 45678.90123; 23456.78901, 56789.01234; 34567.89012, 67890.12345}', + '{-4, -3; -1, 0; 2, 3}', + ], + 'Two mismatched matrices (2x3 and 2x2)' => [ + [ + [10000, 46000], + [23460, 56789], + ], + '{12345.67890, 45678.90123, 78901.23456; 23456.78901, 56789.01234, 89012.34567}', + '{-4, -3; -1, 0}', + ], + 'Two mismatched matrices (3x2 and 2x1 vector)' => [ + [ + [10000, 50000], + [23460, 56790], + ], + '{12345.67890, 45678.90123; 23456.78901, 56789.01234; 34567.89012, 67890.12345}', + '{-4; -1}', + ], + 'Two mismatched matrices (3x1 vector and 2x2)' => [ + [ + [10000, 12000], + [23460, 23457], + ], + '{12345.67890; 23456.78901; 34567.89012}', + '{-4, -3; -1, 0}', + ], + 'Two mismatched matrices (1x3 vector and 2x2)' => [ + [ + [10000, 46000], + [12350, 45679], + ], + '{12345.67890, 45678.90123, 78901.23456}', + '{-4, -3; -1, 0}', + ], + 'Larger mismatched matrices (5x1 vector and 3x3)' => [ + [ + [3.1, 6.28, 9.425], + [12.6, 15.71, 18.85], + [22, 25.13, 28.274], + ], + '{3.14159265, 6.2831853, 9.424777959; 12.5663706, 15.70796325, 18.8495559; 21.99114855, 25.1327412, 28.27433385}', + '{1, 2, 3, 4, 5}', + ], + 'Two different sized column vectors' => [ + [[0.1], [1.37]], + '{0.14527; 1.37250}', + '{1; 2; 3; 4}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundUpTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundUpTest.php index b12ddec4..d204a1fb 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundUpTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundUpTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class RoundUpTest extends AllSetupTeardown { /** @@ -27,4 +29,72 @@ class RoundUpTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/ROUNDUP.php'; } + + /** + * @dataProvider providerRoundUpArray + */ + public function testRoundUpArray(array $expectedResult, string $argument1, string $argument2): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ROUNDUP({$argument1},{$argument2})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerRoundUpArray(): array + { + return [ + 'first argument row vector' => [ + [[0.146, 1.373, -931.683, 3.142]], + '{0.14527, 1.3725, -931.6829, 3.14159265}', + '3', + ], + 'first argument column vector' => [ + [[0.146], [1.373], [-931.683], [3.142]], + '{0.14527; 1.3725; -931.6829; 3.14159265}', + '3', + ], + 'first argument matrix' => [ + [[0.146, 1.373], [-931.683, 3.142]], + '{0.14527, 1.3725; -931.6829, 3.14159265}', + '3', + ], + 'second argument row vector' => [ + [[0.2, 0.15, 0.146, 0.1453, 0.14527]], + '0.14527', + '{1, 2, 3, 4, 5}', + ], + 'second argument column vector' => [ + [[0.2], [0.15], [0.146], [0.1453], [0.14527]], + '0.14527', + '{1; 2; 3; 4; 5}', + ], + 'second argument matrix' => [ + [[0.2, 0.15], [0.146, 0.1453]], + '0.14527', + '{1, 2; 3, 4}', + ], + 'A row and a column vector' => [ + [ + [0.2, 0.15, 0.146, 0.1453], + [1.4, 1.38, 1.373, 1.3725], + [-931.7, -931.69, -931.683, -931.6829], + [3.2, 3.15, 3.142, 3.1416], + ], + '{0.14527; 1.37250; -931.68290; 3.14159265}', + '{1, 2, 3, 4}', + ], + 'Two row vectors' => [ + [[0.2, 1.38, -931.683, 3.1416]], + '{0.14527, 1.37250, -931.68290, 3.14159265}', + '{1, 2, 3, 4}', + ], + 'Two column vectors' => [ + [[0.2], [1.38], [-931.683], [3.1416]], + '{0.14527; 1.37250; -931.68290; 3.14159265}', + '{1; 2; 3; 4}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SecTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SecTest.php index 395a2fee..c7af031d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SecTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SecTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class SecTest extends AllSetupTeardown { /** @@ -27,4 +29,25 @@ class SecTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/SEC.php'; } + + /** + * @dataProvider providerSecArray + */ + public function testSecArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=SEC({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerSecArray(): array + { + return [ + 'row vector' => [[[1.85081571768093, 1.13949392732455, 1.85081571768093]], '{1, 0.5, -1}'], + 'column vector' => [[[1.85081571768093], [1.13949392732455], [1.85081571768093]], '{1; 0.5; -1}'], + 'matrix' => [[[1.85081571768093, 1.13949392732455], [1.0, 1.85081571768093]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SechTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SechTest.php index 51b5ff6e..402adf30 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SechTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SechTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class SechTest extends AllSetupTeardown { /** @@ -27,4 +29,25 @@ class SechTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/SECH.php'; } + + /** + * @dataProvider providerSechArray + */ + public function testSechArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=SECH({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerSechArray(): array + { + return [ + 'row vector' => [[[0.64805427366389, 0.88681888397007, 0.64805427366389]], '{1, 0.5, -1}'], + 'column vector' => [[[0.64805427366389], [0.88681888397007], [0.64805427366389]], '{1; 0.5; -1}'], + 'matrix' => [[[0.64805427366389, 0.88681888397007], [1.0, 0.64805427366389]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SignTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SignTest.php index d5f65f4a..bef03503 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SignTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SignTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class SignTest extends AllSetupTeardown { /** @@ -26,4 +28,25 @@ class SignTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/SIGN.php'; } + + /** + * @dataProvider providerSignArray + */ + public function testSignArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=SIGN({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerSignArray(): array + { + return [ + 'row vector' => [[[-1, 0, 1]], '{-1.5, 0, 0.3}'], + 'column vector' => [[[-1], [0], [1]], '{-1.5; 0; 0.3}'], + 'matrix' => [[[-1, 0], [1, 1]], '{-1.5, 0; 0.3, 12.5}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinTest.php index 24f6ea78..ce7b29c3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class SinTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class SinTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/SIN.php'; } + + /** + * @dataProvider providerSinArray + */ + public function testSinArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=SIN({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerSinArray(): array + { + return [ + 'row vector' => [[[0.84147098480790, 0.47942553860420, -0.84147098480790]], '{1, 0.5, -1}'], + 'column vector' => [[[0.84147098480790], [0.47942553860420], [-0.84147098480790]], '{1; 0.5; -1}'], + 'matrix' => [[[0.84147098480790, 0.47942553860420], [0.0, -0.84147098480790]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinhTest.php index d25560f5..1f64d182 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinhTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinhTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class SinhTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class SinhTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/SINH.php'; } + + /** + * @dataProvider providerSinhArray + */ + public function testSinhArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=SINH({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerSinhArray(): array + { + return [ + 'row vector' => [[[1.17520119364380, 0.52109530549375, -1.17520119364380]], '{1, 0.5, -1}'], + 'column vector' => [[[1.17520119364380], [0.52109530549375], [-1.17520119364380]], '{1; 0.5; -1}'], + 'matrix' => [[[1.17520119364380, 0.52109530549375], [0.0, -1.17520119364380]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtPiTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtPiTest.php index 8dd66f5f..1eac2329 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtPiTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtPiTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class SqrtPiTest extends AllSetupTeardown { /** @@ -30,4 +32,25 @@ class SqrtPiTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/SQRTPI.php'; } + + /** + * @dataProvider providerSqrtPiArray + */ + public function testSqrtPiArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=SQRTPI({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); + } + + public function providerSqrtPiArray(): array + { + return [ + 'row vector' => [[[5.317361552716, 6.2665706865775, 8.6832150546992]], '{9, 12.5, 24}'], + 'column vector' => [[[5.3173615527166], [6.2665706865775], [8.6832150546992]], '{9; 12.5; 24}'], + 'matrix' => [[[5.3173615527166, 6.2665706865775], [8.6832150546992, 14.1796308072441]], '{9, 12.5; 24, 64}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtTest.php index 733de874..1068afc8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class SqrtTest extends AllSetupTeardown { /** @@ -28,4 +30,25 @@ class SqrtTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/SQRT.php'; } + + /** + * @dataProvider providerSqrtArray + */ + public function testSqrtArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=SQRT({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerSqrtArray(): array + { + return [ + 'row vector' => [[[3, 3.5355339059327378, 4.898979485566356]], '{9, 12.5, 24}'], + 'column vector' => [[[3], [3.5355339059327378], [4.898979485566356]], '{9; 12.5; 24}'], + 'matrix' => [[[3, 3.5355339059327378], [4.898979485566356, 8]], '{9, 12.5; 24, 64}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanTest.php index c34a756c..75993f62 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class TanTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class TanTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/TAN.php'; } + + /** + * @dataProvider providerTanArray + */ + public function testTanArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=TAN({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerTanArray(): array + { + return [ + 'row vector' => [[[1.55740772465490, 0.54630248984379, -1.55740772465490]], '{1, 0.5, -1}'], + 'column vector' => [[[1.55740772465490], [0.54630248984379], [-1.55740772465490]], '{1; 0.5; -1}'], + 'matrix' => [[[1.55740772465490, 0.54630248984379], [0.0, -1.55740772465490]], '{1, 0.5; 0, -1}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanhTest.php index d9d2741a..b75a0457 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanhTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanhTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class TanhTest extends AllSetupTeardown { /** @@ -23,4 +25,25 @@ class TanhTest extends AllSetupTeardown { return require 'tests/data/Calculation/MathTrig/TANH.php'; } + + /** + * @dataProvider providerTanhArray + */ + public function testTanhArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=TANH({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerTanhArray(): array + { + return [ + 'row vector' => [[[0.76159415595577, 0.46211715726001, -0.76159415595577]], '{1, 0.5, -1}'], + 'column vector' => [[[0.76159415595577], [0.46211715726001], [-0.76159415595577]], '{1; 0.5; -1}'], + 'matrix' => [[[0.76159415595577, 0.46211715726001], [0.0, -0.76159415595577]], '{1, 0.5; 0, -1}'], + ]; + } }