From 2c5c00f88bcae5f5543d73c18b3f6e4d3dc8aa64 Mon Sep 17 00:00:00 2001 From: Jeff Moser Date: Wed, 1 Sep 2010 22:17:00 -0400 Subject: [PATCH] Added equals test and fixed some bugs --- PHPSkills/Numerics/Matrix.php | 58 +++++++++++++++++++++++++++---- UnitTests/Numerics/MatrixTest.php | 43 +++++++++++++++++++++-- 2 files changed, 92 insertions(+), 9 deletions(-) diff --git a/PHPSkills/Numerics/Matrix.php b/PHPSkills/Numerics/Matrix.php index e3f5ccf..568f867 100644 --- a/PHPSkills/Numerics/Matrix.php +++ b/PHPSkills/Numerics/Matrix.php @@ -16,6 +16,24 @@ class Matrix $this->_matrixRowData = $matrixData; } + public static function fromRowsColumns() + { + $args = \func_get_args(); + $rows = $args[0]; + $cols = $args[1]; + $result = new Matrix($rows, $cols); + $currentIndex = 2; + + for($currentRow = 0; $currentRow < $rows; $currentRow++) + { + for($currentCol = 0; $currentCol < $cols; $currentCol++) + { + $result->setValue($currentRow, $currentCol, $args[$currentIndex++]); + } + } + + return $result; + } public function getRowCount() { @@ -46,9 +64,6 @@ class Matrix $currentRowTransposeMatrix < $this->_columnCount; $currentRowTransposeMatrix++) { - $transposeMatrixCurrentRowColumnValues = array(); - $transposeMatrix[] = $transposeMatrixCurrentRowColumnValues; - for ($currentColumnTransposeMatrix = 0; $currentColumnTransposeMatrix < $this->_rowCount; $currentColumnTransposeMatrix++) @@ -58,7 +73,7 @@ class Matrix } } - return new Matrix($transposeMatrix); + return new Matrix($this->_columnCount, $this->_rowCount, $transposeMatrix); } private function isSquare() @@ -152,7 +167,7 @@ class Matrix } } - return new Matrix($result); + return new Matrix($this->_columnCount, $this->_rowCount, $result); } public function getInverse() @@ -288,7 +303,7 @@ class Matrix return new Matrix($this->_rowCount - 1, $this->_columnCount - 1, $result); } - private function getCofactor($rowToRemove, $columnToRemove) + public function getCofactor($rowToRemove, $columnToRemove) { // See http://en.wikipedia.org/wiki/Cofactor_(linear_algebra) for details // REVIEW: should things be reversed since I'm 0 indexed? @@ -304,6 +319,37 @@ class Matrix return -1.0*$this->getMinorMatrix($rowToRemove, $columnToRemove)->getDeterminant(); } } + + public function equals($otherMatrix) + { + // If one is null, but not both, return false. + if ($otherMatrix == null) + { + return false; + } + + if (($this->_rowCount != $otherMatrix->getRowCount()) || ($this->_columnCount != $otherMatrix->getColumnCount())) + { + return false; + } + + for ($currentRow = 0; $currentRow < $this->_rowCount; $currentRow++) + { + for ($currentColumn = 0; $currentColumn < $this->_columnCount; $currentColumn++) + { + $delta = + abs($this->_matrixRowData[$currentRow][$currentColumn] - + $otherMatrix->getValue($currentRow, $currentColumn)); + + if ($delta > self::ERROR_TOLERANCE) + { + return false; + } + } + } + + return true; + } } class Vector extends Matrix diff --git a/UnitTests/Numerics/MatrixTest.php b/UnitTests/Numerics/MatrixTest.php index 19ee9c8..c351d39 100644 --- a/UnitTests/Numerics/MatrixTest.php +++ b/UnitTests/Numerics/MatrixTest.php @@ -5,6 +5,7 @@ require_once 'PHPUnit/TextUI/TestRunner.php'; require_once(dirname(__FILE__) . '/../../PHPSkills/Numerics/Matrix.php'); use \PHPUnit_Framework_TestCase; +use Moserware\Numerics\Matrix; use Moserware\Numerics\SquareMatrix; class MatrixTest extends PHPUnit_Framework_TestCase @@ -90,12 +91,48 @@ class MatrixTest extends PHPUnit_Framework_TestCase // Verified against http://www.wolframalpha.com/input/?i=det+%7B%7B3%2C1%2C4%2C1%2C5%2C9%2C2%2C6%7D%2C%7B5%2C3%2C5%2C8%2C9%2C7%2C9%2C3%7D%2C%7B2%2C3%2C8%2C4%2C6%2C2%2C6%2C4%7D%2C%7B3%2C3%2C8%2C3%2C2%2C7%2C9%2C5%7D%2C%7B0%2C2%2C8%2C8%2C4%2C1%2C9%2C7%7D%2C%7B1%2C6%2C9%2C3%2C9%2C9%2C3%2C7%7D%2C%7B5%2C1%2C0%2C5%2C8%2C2%2C0%2C9%7D%2C%7B7%2C4%2C9%2C4%2C4%2C5%2C9%2C2%7D%7D $this->assertEquals(1378143, $pi->getDeterminant()); } + + public function testEquals() + { + $a = new SquareMatrix(1, 2, + 3, 4); + + $b = new SquareMatrix(1, 2, + 3, 4); + + $this->assertTrue($a->equals($b)); + + $c = Matrix::fromRowsColumns(2, 3, + 1, 2, 3, + 4, 5, 6); + + $d = Matrix::fromRowsColumns(2, 3, + 1, 2, 3, + 4, 5, 6); + + $this->assertTrue($c->equals($d)); + + $e = Matrix::fromRowsColumns(3, 2, + 1, 4, + 2, 5, + 3, 6); + + $f = $e->getTranspose(); + $this->assertTrue($d->equals($f)); + + // Test rounding (thanks to nsp on GitHub for finding this case) + $g = new SquareMatrix(1, 2.00000000000001, + 3, 4); + + $h = new SquareMatrix(1, 2, + 3, 4); + + $this->assertTrue($g->equals($h)); + } } $testSuite = new \PHPUnit_Framework_TestSuite(); -$testSuite->addTest( new MatrixTest("testFourByFourDeterminant")); -$testSuite->addTest( new MatrixTest("testEightByEightDeterminant")); - +$testSuite->addTest( new MatrixTest("testEquals")); \PHPUnit_TextUI_TestRunner::run($testSuite); ?>