From 71dba49fffff1e42529f4ea72fbc487d9b5ed3fe Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 23 Jan 2015 23:44:32 +0000 Subject: [PATCH] Improvements to array arithmetic (MMULT) Better setup of calculation function tests to ensure consistent environment --- Classes/PHPExcel/Calculation/MathTrig.php | 38 ++++++++++--------- Classes/PHPExcel/Shared/JAMA/Matrix.php | 4 +- .../PHPExcel/Calculation/DateTimeTest.php | 2 + .../PHPExcel/Calculation/EngineeringTest.php | 2 + .../PHPExcel/Calculation/FinancialTest.php | 2 + .../PHPExcel/Calculation/FunctionsTest.php | 2 + .../PHPExcel/Calculation/LogicalTest.php | 2 + .../PHPExcel/Calculation/LookupRefTest.php | 2 + .../PHPExcel/Calculation/MathTrigTest.php | 2 + .../PHPExcel/Calculation/TextDataTest.php | 2 + .../Classes/PHPExcel/CalculationTest.php | 4 +- .../Calculation/MathTrig/MINVERSE.data | 7 +++- .../Calculation/MathTrig/MMULT.data | 19 +++++----- 13 files changed, 56 insertions(+), 32 deletions(-) diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index f3ae111e..689d59ff 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -316,14 +316,17 @@ class PHPExcel_Calculation_MathTrig { } if ((is_numeric($number)) && (is_numeric($significance))) { - if (($number == 0.0 ) || ($significance == 0.0)) { + if ($significance == 0.0) { + return PHPExcel_Calculation_Functions::DIV0(); + } elseif ($number == 0.0) { return 0.0; } elseif (self::SIGN($number) == self::SIGN($significance)) { return floor($number / $significance) * $significance; } else { return PHPExcel_Calculation_Functions::NaN(); } - } + } else + return PHPExcel_Calculation_Functions::VALUE(); } // function FLOOR() @@ -606,27 +609,27 @@ class PHPExcel_Calculation_MathTrig { if (!is_array($matrixData1)) { $matrixData1 = array(array($matrixData1)); } if (!is_array($matrixData2)) { $matrixData2 = array(array($matrixData2)); } - $rowA = 0; - foreach($matrixData1 as $matrixRow) { - if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } - $columnA = 0; - foreach($matrixRow as $matrixCell) { - if ((is_string($matrixCell)) || ($matrixCell === null)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $matrixAData[$rowA][$columnA] = $matrixCell; - ++$columnA; - } - ++$rowA; - } try { + $rowA = 0; + foreach($matrixData1 as $matrixRow) { + if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + $columnA = 0; + foreach($matrixRow as $matrixCell) { + if ((!is_numeric($matrixCell)) || ($matrixCell === null)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $matrixAData[$rowA][$columnA] = $matrixCell; + ++$columnA; + } + ++$rowA; + } $matrixA = new PHPExcel_Shared_JAMA_Matrix($matrixAData); $rowB = 0; foreach($matrixData2 as $matrixRow) { if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } $columnB = 0; foreach($matrixRow as $matrixCell) { - if ((is_string($matrixCell)) || ($matrixCell === null)) { + if ((!is_numeric($matrixCell)) || ($matrixCell === null)) { return PHPExcel_Calculation_Functions::VALUE(); } $matrixBData[$rowB][$columnB] = $matrixCell; @@ -636,12 +639,13 @@ class PHPExcel_Calculation_MathTrig { } $matrixB = new PHPExcel_Shared_JAMA_Matrix($matrixBData); - if (($rowA != $columnB) || ($rowB != $columnA)) { + if ($columnA != $rowB) { return PHPExcel_Calculation_Functions::VALUE(); } return $matrixA->times($matrixB)->getArray(); } catch (PHPExcel_Exception $ex) { + var_dump($ex->getMessage()); return PHPExcel_Calculation_Functions::VALUE(); } } // function MMULT() diff --git a/Classes/PHPExcel/Shared/JAMA/Matrix.php b/Classes/PHPExcel/Shared/JAMA/Matrix.php index b893a447..1e7c334a 100644 --- a/Classes/PHPExcel/Shared/JAMA/Matrix.php +++ b/Classes/PHPExcel/Shared/JAMA/Matrix.php @@ -1028,7 +1028,7 @@ class PHPExcel_Shared_JAMA_Matrix { $LU = new PHPExcel_Shared_JAMA_LUDecomposition($this); return $LU->solve($B); } else { - $QR = new QRDecomposition($this); + $QR = new PHPExcel_Shared_JAMA_QRDecomposition($this); return $QR->solve($B); } } // function solve() @@ -1054,6 +1054,4 @@ class PHPExcel_Shared_JAMA_Matrix { $L = new PHPExcel_Shared_JAMA_LUDecomposition($this); return $L->det(); } // function det() - - } // class PHPExcel_Shared_JAMA_Matrix diff --git a/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php index 57692a34..d4bdc5ab 100644 --- a/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php @@ -13,6 +13,8 @@ class DateTimeTest extends PHPUnit_Framework_TestCase define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** diff --git a/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php b/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php index 647da09f..1f511ffa 100644 --- a/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php @@ -17,6 +17,8 @@ class EngineeringTest extends PHPUnit_Framework_TestCase define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** diff --git a/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php b/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php index b27a6a7d..f5689c95 100644 --- a/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php @@ -13,6 +13,8 @@ class FinancialTest extends PHPUnit_Framework_TestCase define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** diff --git a/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php b/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php index 5e6ef962..01333294 100644 --- a/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php @@ -13,6 +13,8 @@ class FunctionsTest extends PHPUnit_Framework_TestCase define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } public function testDUMMY() diff --git a/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php b/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php index 46749d12..cc8f8b33 100644 --- a/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php @@ -13,6 +13,8 @@ class LogicalTest extends PHPUnit_Framework_TestCase define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } public function testTRUE() diff --git a/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php b/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php index 454422a1..6450b082 100644 --- a/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php @@ -13,6 +13,8 @@ class LookupRefTest extends PHPUnit_Framework_TestCase define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** diff --git a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php index e3d8c9d9..0059ed08 100644 --- a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php @@ -13,6 +13,8 @@ class MathTrigTest extends PHPUnit_Framework_TestCase define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** diff --git a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php index ea7882b6..4b1caf51 100644 --- a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php @@ -13,6 +13,8 @@ class TextDataTest extends PHPUnit_Framework_TestCase define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** diff --git a/unitTests/Classes/PHPExcel/CalculationTest.php b/unitTests/Classes/PHPExcel/CalculationTest.php index 1a510a02..1de827ca 100644 --- a/unitTests/Classes/PHPExcel/CalculationTest.php +++ b/unitTests/Classes/PHPExcel/CalculationTest.php @@ -11,6 +11,8 @@ class CalculationTest extends PHPUnit_Framework_TestCase define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** @@ -25,8 +27,6 @@ class CalculationTest extends PHPUnit_Framework_TestCase PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE); $resultOpenOffice = \PHPExcel_Calculation::getInstance()->_calculateFormulaValue($formula); $this->assertEquals($expectedResultOpenOffice, $resultOpenOffice, 'should be OpenOffice compatible'); - - PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } public function providerBinaryComparisonOperation() diff --git a/unitTests/rawTestData/Calculation/MathTrig/MINVERSE.data b/unitTests/rawTestData/Calculation/MathTrig/MINVERSE.data index 47586b22..40ee4284 100644 --- a/unitTests/rawTestData/Calculation/MathTrig/MINVERSE.data +++ b/unitTests/rawTestData/Calculation/MathTrig/MINVERSE.data @@ -1,4 +1,4 @@ -{1|2|3;4|5|6;7|8|9}, {-4.50359962737050E+15|9.00719925474099E+15|-4.50359962737050E+15;9.00719925474100E+15|-1.80143985094820E+16|9.00719925474099E+15;-4.50359962737050E+15|9.00719925474099E+15|-4.50359962737050E+15} +{1|2|3;4|5|6;7|8|9}, {-4.50359962737050E+15|9.00719925474099E+15|-4.50359962737050E+15;9.00719925474100E+15|-1.80143985094820E+16|9.00719925474099E+15;-4.50359962737050E+15|9.00719925474099E+15|-4.50359962737050E+15} {10|20|30;40|50|60;70|80|90}, {7.03687441776639E+13|-1.40737488355328E+14|7.03687441776640E+13;-1.40737488355328E+14|2.81474976710656E+14|-1.40737488355328E+14;7.03687441776641E+13|-1.40737488355328E+14|7.03687441776640E+13} {8|1|6;3|5|7;4|9|2}, {1.47222222222222E-01|-1.44444444444444E-01|6.38888888888889E-02;-6.11111111111111E-02|2.22222222222222E-02|1.05555555555556E-01;-1.94444444444444E-02|1.88888888888889E-01|-1.02777777777778E-01} {4|-1;2|0}, {0|0.5;-1|2} @@ -8,3 +8,8 @@ {0.2|1|-0.9;0.35|10.8|4;-3.15|5}, "#VALUE!" {1|2;3|4}, {-2|1;1.5|-0.5} {1|2|1;3|4|2;1|1|2}, {-2|1|0;1.33333333333333|-0.33333333333333|-0.33333333333333;0.33333333333333|-0.33333333333333|0.66666666666667} +{2|3;4|5}, {-2.5|1.5;2|-1} +{5|8;7|9}, {-0.818181818181818|0.727272727272727;0.636363636363636|-0.454545454545455} +{45|78;17|50}, {0.054112554112554|-0.084415584415584;-0.018398268398268|0.048701298701299} +{2|2;2|1}, {-0.5|1.0;1|-1} +{1|4|6;7|4|10;15|16|20}, {-0.2941176470588230|0.0588235294117647|0.0588235294117647;0.0367647058823529|-0.2573529411764710|0.1176470588235290;0.1911764705882350|0.1617647058823530|-0.0882352941176471} \ No newline at end of file diff --git a/unitTests/rawTestData/Calculation/MathTrig/MMULT.data b/unitTests/rawTestData/Calculation/MathTrig/MMULT.data index 430dd88d..06af83a0 100644 --- a/unitTests/rawTestData/Calculation/MathTrig/MMULT.data +++ b/unitTests/rawTestData/Calculation/MathTrig/MMULT.data @@ -1,11 +1,12 @@ {1|2;3|4}, {1|2;3|4}, {7|10;15|22} {1|2|3;4|5|6;7|8|9}, {1|2|3;4|5|6;7|8|9}, {30|36|42;66|81|96;102|126|150} -{1|2;3|4}, 2, {2|4;6|8} -{1|2;3|4}, {2}, {2|4;6|8} -2, {1|2;3|4}, {2|4;6|8} -{2}, {1|2;3|4}, {2|4;6|8} -{1|2;3|4}, {2|4}, {2|4;6|8} -{1|2;3|4}, {2;4}, {2|4;6|8} -{2|4}, {1|2;3|4}, {2|4;6|8} -{2;4}, {1|2;3|4}, {2|4;6|8} -{1|2;3|4;5|6}, {1|2|3;4|5|6}, {1|2|3;4|5|6;7|8|9} +{1|2;3|4}, 2, "#VALUE!" // Mismatched dimensions +{1|2;3|4}, {2}, "#VALUE!" // Mismatched dimensions +{1.2;2.4}, {3.6|4.5}, {14.43|14.43;14.43|14.43} +2, {1|2;3|4}, "#VALUE!" // Mismatched dimensions +{2}, {1|2;3|4}, "#VALUE!" // Mismatched dimensions +{1|2;3|4}, {2|4}, "#VALUE!" +{1|2;3|4}, {2;4}, {{10};{22}} +{2|4}, {1|2;3|4}, {14|20} +{2;4}, {1|2;3|4}, "#VALUE!" // Mismatched dimensions +{1|2;3|4;5|6}, {1|2|3;4|5|6}, {9|12|15;19|26|33;29|40|51}