Fix sizing adjustments for reflective matrices (vectors increase to match as a square matrix, non-vectors reduce to a minimum matching square)

This commit is contained in:
MarkBaker
2022-03-10 14:42:03 +01:00
parent 53aab72fe4
commit 96ac7169b9
4 changed files with 78 additions and 81 deletions
-50
View File
@@ -60,26 +60,6 @@ parameters:
count: 6
path: src/PhpSpreadsheet/Calculation/Calculation.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToEnglish\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Calculation/Calculation.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToEnglish\\(\\) has parameter \\$formula with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Calculation/Calculation.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToLocale\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Calculation/Calculation.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToLocale\\(\\) has parameter \\$formula with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Calculation/Calculation.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:dataTestReference\\(\\) has no return type specified\\.$#"
count: 1
@@ -90,41 +70,11 @@ parameters:
count: 1
path: src/PhpSpreadsheet/Calculation/Calculation.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:getTokensAsString\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Calculation/Calculation.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:getTokensAsString\\(\\) has parameter \\$tokens with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Calculation/Calculation.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:localeFunc\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Calculation/Calculation.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:localeFunc\\(\\) has parameter \\$function with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Calculation/Calculation.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:validateBinaryOperand\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Calculation/Calculation.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:validateBinaryOperand\\(\\) has parameter \\$operand with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Calculation/Calculation.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:validateBinaryOperand\\(\\) has parameter \\$stack with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Calculation/Calculation.php
-
message: "#^Offset 'type' does not exist on array\\|null\\.$#"
count: 3
+21 -30
View File
@@ -2872,7 +2872,7 @@ class Calculation
*
* @return bool Success or failure
*/
public static function setArrayReturnType($returnType)
public static function setArrayReturnType(string $returnType): bool
{
if (
($returnType == self::RETURN_ARRAY_AS_VALUE) ||
@@ -2892,17 +2892,15 @@ class Calculation
*
* @return string $returnType Array return type
*/
public static function getArrayReturnType()
public static function getArrayReturnType(): string
{
return self::$returnArrayAsType;
}
/**
* Is calculation caching enabled?
*
* @return bool
*/
public function getCalculationCacheEnabled()
public function getCalculationCacheEnabled(): bool
{
return $this->calculationCacheEnabled;
}
@@ -2944,10 +2942,8 @@ class Calculation
/**
* Clear calculation cache for a specified worksheet.
*
* @param string $worksheetName
*/
public function clearCalculationCacheForWorksheet($worksheetName): void
public function clearCalculationCacheForWorksheet(string $worksheetName): void
{
if (isset($this->calculationCache[$worksheetName])) {
unset($this->calculationCache[$worksheetName]);
@@ -2956,13 +2952,10 @@ class Calculation
/**
* Rename calculation cache for a specified worksheet.
*
* @param string $fromWorksheetName
* @param string $toWorksheetName
*/
public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName): void
public function renameCalculationCacheForWorksheet(?string $fromWorksheetName, string $toWorksheetName): void
{
if (isset($this->calculationCache[$fromWorksheetName])) {
if ($fromWorksheetName !== null && isset($this->calculationCache[$fromWorksheetName])) {
$this->calculationCache[$toWorksheetName] = &$this->calculationCache[$fromWorksheetName];
unset($this->calculationCache[$fromWorksheetName]);
}
@@ -2971,7 +2964,7 @@ class Calculation
/**
* Enable/disable calculation cache.
*
* @param mixed $enabled
* @param bool $enabled
*/
public function setBranchPruningEnabled($enabled): void
{
@@ -2991,10 +2984,8 @@ class Calculation
/**
* Get the currently defined locale code.
*
* @return string
*/
public function getLocale()
public function getLocale(): string
{
return self::$localeLanguage;
}
@@ -3018,10 +3009,8 @@ class Calculation
* Set the locale code.
*
* @param string $locale The locale to use for formula translation, eg: 'en_us'
*
* @return bool
*/
public function setLocale(string $locale)
public function setLocale(string $locale): bool
{
// Identify our locale and language
$language = $locale = strtolower($locale);
@@ -3191,7 +3180,7 @@ class Calculation
private static $functionReplaceToLocale;
public function _translateFormulaToLocale($formula)
public function _translateFormulaToLocale(string $formula): string
{
// Build list of function names and constants for translation
if (self::$functionReplaceFromExcel === null) {
@@ -3227,7 +3216,7 @@ class Calculation
private static $functionReplaceToExcel;
public function _translateFormulaToEnglish($formula)
public function _translateFormulaToEnglish(string $formula): string
{
if (self::$functionReplaceFromLocale === null) {
self::$functionReplaceFromLocale = [];
@@ -3252,7 +3241,7 @@ class Calculation
return self::translateFormula(self::$functionReplaceFromLocale, self::$functionReplaceToExcel, $formula, self::$localeArgumentSeparator, ',');
}
public static function localeFunc($function)
public static function localeFunc(string $function): string
{
if (self::$localeLanguage !== 'en_us') {
$functionName = trim($function, '(');
@@ -3596,7 +3585,7 @@ class Calculation
* 1 = shrink to fit
* 2 = extend to fit
*
* @return array
* @return array<int, int>
*/
private static function checkMatrixOperands(&$operand1, &$operand2, $resize = 1)
{
@@ -3615,7 +3604,9 @@ class Calculation
[$matrix1Rows, $matrix1Columns] = self::getMatrixDimensions($operand1);
[$matrix2Rows, $matrix2Columns] = self::getMatrixDimensions($operand2);
if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) {
$resize = 2;
// Vectors increase size to match to build a square matrix;
// Non-vectors reduce size to a square that reflects min(rows1, rows2) and min(cols1, cols2)
$resize = ($matrix1Rows === 1 || $matrix2Rows === 1) ? 2 : 1;
}
if ($resize == 2) {
@@ -3634,7 +3625,7 @@ class Calculation
*
* @param array $matrix matrix operand
*
* @return int[] An array comprising the number of rows, and number of columns
* @return array<int, int> An array comprising the number of rows, and number of columns
*/
public static function getMatrixDimensions(array &$matrix)
{
@@ -3747,7 +3738,7 @@ class Calculation
/**
* Format details of an operand for display in the log (based on operand type).
*
* @param mixed $value First matrix operand
* @param mixed $value Operand value
*
* @return mixed
*/
@@ -3787,7 +3778,7 @@ class Calculation
/**
* Format type and details of an operand for display in the log (based on operand type).
*
* @param mixed $value First matrix operand
* @param mixed $value Operand value
*
* @return null|string
*/
@@ -4889,7 +4880,7 @@ class Calculation
return $output;
}
private function validateBinaryOperand(&$operand, &$stack)
private function validateBinaryOperand(&$operand, Stack &$stack): bool
{
if (is_array($operand)) {
if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) {
@@ -5357,7 +5348,7 @@ class Calculation
return $args;
}
private function getTokensAsString($tokens)
private function getTokensAsString(array $tokens): string
{
$tokensStr = array_map(function ($token) {
$value = $token['value'] ?? 'no value';
+1 -1
View File
@@ -839,7 +839,7 @@ class Worksheet implements IComparable
*
* @return $this
*/
public function setTitle($title, $updateFormulaCellReferences = true, $validate = true)
public function setTitle(string $title, bool $updateFormulaCellReferences = true, bool $validate = true)
{
// Is this a 'rename' or not?
if ($this->getTitle() == $title) {
@@ -125,6 +125,14 @@ class ArrayFormulaTest extends TestCase
'={1,4;2,5;3,6} + {7,10;8,11;9,12}',
[[8, 14], [10, 16], [12, 18]],
],
'Addition: matrix 3x2 + 2x3' => [
'={1,2,3;4,5,6} + {7,10;8,11;9,12}',
[[8, 12], [12, 16]],
],
'Addition: matrix 2x3 + 3x2' => [
'={7,10;8,11;9,12} + {1,2,3;4,5,6}',
[[8, 12], [12, 16]],
],
// Subtraction
'Subtraction: row vector 2 - column vector 2' => [
'={2,3} - {4;5}',
@@ -162,6 +170,14 @@ class ArrayFormulaTest extends TestCase
'={1,4;2,5;3,6} - {7,10;8,11;9,12}',
[[-6, -6], [-6, -6], [-6, -6]],
],
'Subtraction: matrix 3x2 - 2x3' => [
'={1,2,3;4,5,6} - {7,10;8,11;9,12}',
[[-6, -8], [-4, -6]],
],
'Subtraction: matrix 2x3 - 3x2' => [
'={7,10;8,11;9,12} - {1,2,3;4,5,6}',
[[6, 8], [4, 6]],
],
// Multiplication
'Multiplication: square matrix 2x2 * 2x2' => [
'={1,2;3,4} * {-2,4;-6,8}',
@@ -199,6 +215,14 @@ class ArrayFormulaTest extends TestCase
'={2,3} * {4;5}',
[[8, 12], [10, 15]],
],
'Multiplication: matrix 3x2 * 2x3' => [
'={1,2,3;4,5,6} * {7,10;8,11;9,12}',
[[7, 20], [32, 55]],
],
'Multiplication: matrix 2x3 * 3x2' => [
'={7,10;8,11;9,12} * {1,2,3;4,5,6}',
[[7, 20], [32, 55]],
],
// Division
'Division: square matrix 2x2 / 2x2' => [
'={1,2;3,4} / {-2,4;-6,8}',
@@ -236,6 +260,14 @@ class ArrayFormulaTest extends TestCase
'={2,3} / {4;5}',
[[0.5, 0.75], [0.4, 0.6]],
],
'Division: matrix 3x2 / 2x3' => [
'={1,2,3;4,5,6} / {7,10;8,11;9,12}',
[[0.14285714285714, 0.2], [0.5, 0.45454545454545]],
],
'Division: matrix 2x3 / 3x2' => [
'={7,10;8,11;9,12} / {1,2,3;4,5,6}',
[[7, 5], [2, 2.2]],
],
// Power
'Power: square matrix 2x2 ^ 2x2' => [
'={1,2;3,4} ^ {-2,4;-6,8}',
@@ -273,11 +305,27 @@ class ArrayFormulaTest extends TestCase
'={2,3} ^ {4;5}',
[[16, 81], [32, 243]],
],
'Power: matrix 3x2 ^ 2x3' => [
'={1,2,3;4,5,6} ^ {7,10;8,11;9,12}',
[[1, 1024], [65536, 48828125]],
],
'Power: matrix 2x3 ^ 3x2' => [
'={7,10;8,11;9,12} ^ {1,2,3;4,5,6}',
[[7, 100], [4096, 161051]],
],
// Concatenation
'Concatenation: row vector 2 & column vector 2' => [
'={"A",",B"} & {"C";";D"}',
[['AC', ',BC'], ['A;D', ',B;D']],
],
'Concatenation: matrix 3x2 & 3x2' => [
'={"A","B","C";"D","E","F"} & {"G","H","I";"J","K","L"}',
[['AG', 'BH', 'CI'], ['DJ', 'EK', 'FL']],
],
'Concatenation: matrix 2x3 & 2x3' => [
'={"A","B";"C","D";"E","F"} & {"G","H";"I","J";"K","L"}',
[['AG', 'BH'], ['CI', 'DJ'], ['EK', 'FL']],
],
'Concatenation: 2x2 matrix & scalar' => [
'={"A","B";"C","D"} & "E"',
[['AE', 'BE'], ['CE', 'DE']],
@@ -286,6 +334,14 @@ class ArrayFormulaTest extends TestCase
'="E" & {"A","B";"C","D"}',
[['EA', 'EB'], ['EC', 'ED']],
],
'Concatenation: 2x2 & 2x1 vector' => [
'={"A","B";"C","D"} & {"E","F"}',
[['AE', 'BF'], ['CE', 'DF']],
],
'Concatenation: 2x2 & 1x2 vector' => [
'={"A","B";"C","D"} & {"E";"F"}',
[['AE', 'BE'], ['CF', 'DF']],
],
// Unary Negation
'Unary Negation: square matrix - 2x2' => [