/** * Tests NumArray::__toString with matrix */ public function testToString3x4() { $numArray = NumPHP::arange(1, 12)->reshape(3, 4); $expectedOutput = "NumArray([\n [1, 2, 3, 4],\n [5, 6, 7, 8],\n [9, 10," . " 11, 12]\n])\n"; $this->expectOutputString($expectedOutput); echo $numArray; }
public function testSetMatrixSlice() { $matrix = NumPHP::arange(-20, -1)->reshape(4, 5); $subMatrix = NumPHP::arange(1, 6)->reshape(2, 3); $expectedNumArray = new NumArray([[-20, -19, -18, -17, -16], [-15, -14, 1, 2, 3], [-10, -9, 4, 5, 6], [-5, -4, -3, -2, -1]]); $this->assertNumArrayEquals($expectedNumArray, $matrix->set('1:3', '2:5', $subMatrix)); }
/** * Tests NumArray::sub with scalar and vector */ public function testSubVectorSingle() { $numArray1 = new NumArray(45); $numArray2 = NumPHP::arange(3, 8); $expectedNumArray = NumPHP::arange(42, 37); $this->assertNumArrayEquals($expectedNumArray, $numArray1->sub($numArray2)); }
/** * Calculates lower triangular matrix L of given symmetric positive definite matrix * * @param NumArray $squareMatrix symmetric positive definite matrix * * @return NumArray * * @throws InvalidArgumentException will be thrown, when `$squareMatrix` is not positive definite * @throws NoSquareMatrixException will be thrown, when `$squareMatrix` is not square * @throws NoSymmetricMatrixException will be thrown, when `$squareMatrix` is not symmetric * * @since 1.0.2 */ public static function cholesky(NumArray $squareMatrix) { if (!Helper::isSquareMatrix($squareMatrix)) { throw new NoSquareMatrixException(sprintf("Matrix with shape (%s) given, matrix has to be square", implode(', ', $squareMatrix->getShape()))); } $shape = $squareMatrix->getShape(); $size = $shape[0]; $aMatrix = clone $squareMatrix; $lMatrix = NumPHP::zerosLike($aMatrix); for ($k = 0; $k < $size; $k++) { $diaElem = $aMatrix->get($k, $k)->getData(); if ($diaElem <= 0) { throw new InvalidArgumentException("Matrix is not positive definite"); } $diaElem = sqrt($diaElem); $lMatrix->set($k, $k, $diaElem); for ($i = $k + 1; $i < $size; $i++) { if ($squareMatrix->get($i, $k) != $squareMatrix->get($k, $i)) { throw new NoSymmetricMatrixException("Matrix is not symmetric"); } $lMatrix->set($i, $k, $aMatrix->get($i, $k)->div($diaElem)); for ($j = $k + 1; $j <= $i; $j++) { $aMatrix->set($i, $j, $aMatrix->get($i, $j)->sub($lMatrix->get($i, $k)->mult($lMatrix->get($j, $k)))); } } } return $lMatrix; }
/** * Tests NumArray::getNDim */ public function testNDim() { $numArray = new NumArray(1); $this->assertSame(0, $numArray->getNDim()); $numArray = NumPHP::arange(1, 2); $this->assertSame(1, $numArray->getNDim()); $numArray = NumPHP::arange(1, 6)->reshape(2, 3); $this->assertSame(2, $numArray->getNDim()); }
/** * @return array */ public function run() { $result = []; for ($i = 100; $i <= 1000; $i += 100) { $numArray = NumPHP::ones($i, $i); $time = microtime(true); $numArray->abs(); $timeDiff = microtime(true) - $time; $result[$i] = new TestRun($i, $timeDiff); } return $result; }
/** * Tests NumPHP::randLike with vector */ public function testRandLike() { $numArray = new NumArray([1, 2, 3]); $rand = NumPHP::randLike($numArray); $this->assertInstanceOf('\\NumPHP\\Core\\NumArray', $rand); $this->assertSame([3], $rand->getShape()); $randData = $rand->getData(); $this->assertCount(3, $randData); foreach ($randData as $entry) { $this->assertInternalType('float', $entry); } }
/** * Build the lower triangular matrix from given matrix * * @param NumArray $numArray given matrix * * @return NumArray * * @since 1.0.0 */ protected static function buildLMatrix(NumArray $numArray) { $shape = $numArray->getShape(); $numArray->add(NumPHP::eye($shape[0], $shape[1])); return $numArray; }
/** * Tests if InvalidArgumentException will be thrown, when using NumArray::add with vectors of different size * * @expectedException \NumPHP\Core\Exception\InvalidArgumentException * @expectedExceptionMessage Size 5 is different from size 4 */ public function testAddDifferentShape() { $numArray1 = NumPHP::arange(1, 5); $numArray2 = NumPHP::arange(1, 4); $numArray1->add($numArray2); }
/** * Tests if cache will be flushed after NumArray::reshape */ public function testReshapeCache() { $numArray = NumPHP::arange(1, 4); $numArray->setCache('key', 6); $numArray->reshape(2, 2); $this->assertFalse($numArray->inCache('key')); }
/** * Tests NumPHP::identity with argument 3 */ public function testIdentity() { $numArray = NumPHP::identity(3); $expectedNumArray = NumPHP::eye(3, 3); $this->assertNumArrayEquals($expectedNumArray, $numArray); }
/** * Tests if InvalidArgumentException will be thrown by using NumArray::min and a * wrong axis on a matrix * * @expectedException \NumPHP\Core\Exception\InvalidArgumentException * @expectedExceptionMessage Axis 2 out of bounds */ public function testNimMatrixAxis2() { $numArray = NumPHP::arange(1, 9)->reshape(3, 3); $numArray->min(2); }
/** * Tests if DivideByZeroException will be thrown, when using NumArray::div with zero value in divisor * * @expectedException \NumPHP\Core\Exception\DivideByZeroException * @expectedExceptionMessage Dividing by zero is forbidden */ public function testDivZero() { $numArray1 = NumPHP::arange(1, 5); $numArray2 = NumPHP::arange(-2, 2); $numArray1->div($numArray2); }
/** * Tests NumArray::abs with a matrix */ public function testAbsMatrix() { $numArray = new NumArray([[1, -2, -3], [-4, -5, 6]]); $expectedNumArray = NumPHP::arange(1, 6)->reshape(2, 3); $this->assertNumArrayEquals($expectedNumArray, $numArray->abs()); }
/** * Tests if InvalidArgumentException will be thrown by using NumArray::max and a * wrong axis on a matrix * * @expectedException \NumPHP\Core\Exception\InvalidArgumentException * @expectedExceptionMessage Axis 2 out of bounds */ public function testMaxMatrixAxis2() { $numArray = NumPHP::arange(1, 4)->reshape(2, 2); $numArray->max(2); }
/** * Tests NumArray::get with negative slicing argument `:-1` on vector */ public function testGet4ArgsSliceMinus1() { $numArray = NumPHP::arange(1, 4); $expectedNumArray = NumPHP::arange(1, 3); $this->assertNumArrayEquals($expectedNumArray, $numArray->get(':-1')); }
/** * Test if InvalidArgumentException will be thrown, when using NumPHP::linspace * with negative `$number` * * @expectedException \NumPHP\Core\Exception\InvalidArgumentException * @expectedExceptionMessage Number has to be a positive value */ public function testLinspaceInvalidArgumentException() { NumPHP::linspace(1.5, 4.5, -1); }
/** * Tests if NoSquareMatrixException will be thrown, when using LinAlg::det with * 2x3 matrix * * @expectedException \NumPHP\LinAlg\Exception\NoSquareMatrixException * @expectedExceptionMessage Matrix with shape (2, 3) given, matrix has to be square */ public function testDet2x3() { $numArray = NumPHP::arange(1, 6)->reshape(2, 3); LinAlg::det($numArray); }
/** * Tests if Helper::isNotSingularMatrix works with invalid not singular matrix */ public function testCheckNotSingularMatrixInvalid() { $numArray = NumPHP::identity(4); $numArray->set(2, 2, 0); $this->assertFalse(Helper::isNotSingularMatrix($numArray)); }
/** * Tests NumArray::getSize on a 2x3x4 matrix */ public function getSize2x3x4() { $numArray = NumPHP::zeros(2, 3, 4); $this->assertSame(24, $numArray->getSize()); }
/** * Tests NumArray::sum with a 2x3x4 matrix and argument 2 */ public function testSumMatrix2x3x4Axis2() { $numArray = NumPHP::arange(1, 24)->reshape(2, 3, 4); $expectedNumArray = NumPHP::arange(10, 90, 16)->reshape(2, 3); $this->assertNumArrayEquals($expectedNumArray, $numArray->sum(2)); }
/** * @param NumArray $matrix * @param NumArray $vector * @return NumArray */ protected static function backSubstitution(NumArray $matrix, NumArray $vector) { $shape = $matrix->getShape(); $xVector = \NumPHP\Core\NumPHP::zeros($shape[0]); for ($i = $shape[0] - 1; $i >= 0; $i--) { $sum = 0; for ($j = $i + 1; $j < $shape[0]; $j++) { $sum += $matrix->get($i, $j)->dot($xVector->get($j))->getData(); } $xVector->set($i, ($vector->get($i)->getData() - $sum) / $matrix->get($i, $i)->getData()); } return $xVector; }
/** * Tests if InvalidArgumentException will be thrown, when using NumArray::mult with vectors of different size * * @expectedException \NumPHP\Core\Exception\InvalidArgumentException * @expectedExceptionMessage Size 5 is different from size 4 */ public function testMultDifferentShape() { $numArray1 = NumPHP::arange(1, 5); $numArray2 = NumPHP::arange(1, 4); $numArray1->mult($numArray2); }
/** * Calculates the inverse of a not singular square matrix * * @param mixed $squareMatrix not singular matrix * * @throws SingularMatrixException will be thrown, when `$squareMatrix` is singular * * @api * @since 1.0.0 * * @return NumArray */ public static function inv($squareMatrix) { if (!$squareMatrix instanceof NumArray) { $squareMatrix = new NumArray($squareMatrix); } elseif ($squareMatrix->inCache(self::CACHE_KEY_INVERSE)) { return $squareMatrix->getCache(self::CACHE_KEY_INVERSE); } if (!Helper::isNotSingularMatrix($squareMatrix)) { throw new SingularMatrixException("Matrix is singular"); } $shape = $squareMatrix->getShape(); $inv = self::solve($squareMatrix, NumPHP::identity($shape[0])); $squareMatrix->setCache(self::CACHE_KEY_INVERSE, $inv); return self::inv($squareMatrix); }
/** * Tests if NoSquareMatrixException will be thrown, when using LinAlg::cholesky with not square matrix * * @expectedException \NumPHP\LinAlg\Exception\NoSquareMatrixException * @expectedExceptionMessage Matrix with shape (2, 3) given, matrix has to be square */ public function testCholeskyNotSquare() { $matrix = NumPHP::arange(1, 6)->reshape(2, 3); LinAlg::cholesky($matrix); }
/** * Tests NumArray::getTranspose on a 2x3x4 matrix */ public function testTranspose2x3x4() { $numArray = NumPHP::arange(1, 24)->reshape(2, 3, 4); $expectedNumArray = new NumArray([[[1, 13], [5, 17], [9, 21]], [[2, 14], [6, 18], [10, 22]], [[3, 15], [7, 19], [11, 23]], [[4, 16], [8, 20], [12, 24]]]); $this->assertNumArrayEquals($expectedNumArray, $numArray->getTranspose()); }
/** * Tests if InvalidArgumentException will be thrown, when using NumArray::dot * with two matrices that are not align * * @expectedException \NumPHP\Core\Exception\InvalidArgumentException * @expectedExceptionMessage Matrix with shape (3, 4) and matrix with shape (3, 3) are not align. */ public function testDotMatrix3x4Matrix3x3() { $numArray1 = NumPHP::arange(1, 12)->reshape(3, 4); $numArray2 = NumPHP::arange(1, 9)->reshape(3, 3); $numArray1->dot($numArray2); }
/** * Tests if InvalidArgumentException will be thrown, when using LinAlg::solve with not align matrix and vector * * @expectedException \NumPHP\LinAlg\Exception\InvalidArgumentException * @expectedExceptionMessage Can not solve a linear system with matrix (4, 4) and matrix (3) */ public function testSolveNotAlign() { $matrix = NumPHP::identity(4); $vector = NumPHP::ones(3); LinAlg::solve($matrix, $vector); }
/** * Tests NumArray::sum with a 2x3x4 matrix and argument 0 */ public function testMeanMatrix2x3x4Axis0() { $numArray = NumPHP::arange(1, 24)->reshape(2, 3, 4); $expectedNumArray = NumPHP::arange(7, 18)->reshape(3, 4); $this->assertNumArrayEquals($expectedNumArray, $numArray->mean(0)); }
/** * Tests if NoMatrixException will be thrown, when using LinAlg::lud a vector * * @expectedException \NumPHP\LinAlg\Exception\NoMatrixException * @expectedExceptionMessage NumArray with dimension 1 given, NumArray should have 2 dimensions */ public function testLUDecompositionVector() { $numArray = NumPHP::arange(1, 2); LinAlg::lud($numArray); }