Skip to content

Commit

Permalink
Add row/columnAddVector to NumericMatrix (#462)
Browse files Browse the repository at this point in the history
  • Loading branch information
Aweptimum authored Dec 31, 2022
1 parent dbc2d1d commit c97386d
Show file tree
Hide file tree
Showing 3 changed files with 315 additions and 1 deletion.
64 changes: 64 additions & 0 deletions src/LinearAlgebra/NumericMatrix.php
Original file line number Diff line number Diff line change
Expand Up @@ -2366,6 +2366,7 @@ public function rank(): int
* - rowDivide
* - rowAdd
* - rowAddScalar
* - rowAddVector
* - rowSubtract
* - rowSubtractScalar
**************************************************************************/
Expand Down Expand Up @@ -2493,6 +2494,37 @@ public function rowAddScalar(int $mᵢ, float $k): NumericMatrix
return MatrixFactory::createNumeric($R, $this->ε);
}

/**
* Add components of vector v to row mᵢ
*
* @param Vector $v Vector to add to row mᵢ
* @param int $mᵢ Row to add vector $v to
*
* @return NumericMatrix
*
* @throws Exception\MatrixException if row to add does not exist
* @throws Exception\BadParameterException if the vector has a different # of components to the # of columns
* @throws Exception\IncorrectTypeException
*/
public function rowAddVector(Vector $v, int $mᵢ): NumericMatrix
{
if ($mᵢ < 0 || $mᵢ >= $this->m) {
throw new Exception\MatrixException('Row to add does not exist');
}
if ($v->count() !== $this->m) {
throw new Exception\BadParameterException('Vector is not the same length as matrix columns');
}

$n = $this->n;
$R = $this->A;

for ($j = 0; $j < $n; $j++) {
$R[$mᵢ][$j] += $v[$j];
}

return MatrixFactory::createNumeric($R, $this->ε);
}

/**
* Subtract k times row mᵢ to row mⱼ
*
Expand Down Expand Up @@ -2554,6 +2586,7 @@ public function rowSubtractScalar(int $mᵢ, float $k): NumericMatrix
* COLUMN OPERATIONS - Return a Matrix
* - columnMultiply
* - columnAdd
* - columnAddVector
**************************************************************************/

/**
Expand Down Expand Up @@ -2617,6 +2650,37 @@ public function columnAdd(int $nᵢ, int $nⱼ, float $k): NumericMatrix
return MatrixFactory::createNumeric($R, $this->ε);
}

/**
* Add components of vector v to column nᵢ
*
* @param Vector $v Vector to add to column nᵢ
* @param int $nᵢ Column to add vector $v to
*
* @return NumericMatrix
*
* @throws Exception\MatrixException if column to add does not exist
* @throws Exception\BadParameterException if the vector has a different # of components to the # of rows
* @throws Exception\IncorrectTypeException
*/
public function columnAddVector(Vector $v, int $nᵢ): NumericMatrix
{
if ($nᵢ < 0 || $nᵢ >= $this->n) {
throw new Exception\MatrixException('Column to add does not exist');
}
if ($v->count() !== $this->m) {
throw new Exception\BadParameterException('Vector is not the same length as matrix rows');
}

$m = $this->m;
$R = $this->A;

for ($i = 0; $i < $m; $i++) {
$R[$i][$nᵢ] += $v[$i];
}

return MatrixFactory::createNumeric($R, $this->ε);
}

/**************************************************************************
* MATRIX REDUCTIONS - Return a Matrix in a reduced form
* - ref (row echelon form)
Expand Down
127 changes: 126 additions & 1 deletion tests/LinearAlgebra/Matrix/Numeric/MatrixColumnOperationsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use MathPHP\LinearAlgebra\MatrixFactory;
use MathPHP\Exception;
use MathPHP\LinearAlgebra\Vector;

class MatrixColumnOperationsTest extends \PHPUnit\Framework\TestCase
{
Expand Down Expand Up @@ -237,4 +238,128 @@ public function testColumnAddExceptionKIsZero()
// When
$A->columnAdd(1, 2, 0);
}
}

/**
* @test columnAddVector
* @dataProvider dataProviderForColumnAddVector
* @param array $A
* @param int $nᵢ
* @param array $v
* @param array $expectedMatrix
* @throws \Exception
*/
public function testColumnAddVector(array $A, int $nᵢ, array $v, array $expectedMatrix)
{
// Given
$A = MatrixFactory::createNumeric($A);
$v = new Vector($v);
$expectedMatrix = MatrixFactory::createNumeric($expectedMatrix);

// When
$R = $A->columnAddVector($v, $nᵢ);

// Then
$this->assertEquals($expectedMatrix, $R);
}

/**
* @return array
*/
public function dataProviderForColumnAddVector(): array
{
return [
[
[
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
], 0, [1,2,3],
[
[2, 2, 3],
[4, 3, 4],
[6, 4, 5],
]
],
[
[
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
], 2, [6,9,12],
[
[1, 2, 9],
[2, 3, 13],
[3, 4, 17],
]
],
[
[
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
], 2, [4,8,12],
[
[1, 2, 7],
[2, 3, 12],
[3, 4, 17],
]
],
[
[
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
], 1, [2.2,3.3,4.4],
[
[1, 4.2, 3],
[2, 6.3, 4],
[3, 8.4, 5],
]
],
];
}

/**
* @test columnAddVector test column n exists
* @throws \Exception
*/
public function testColumnAddVectorExceptionColumnExists()
{
// Given
$A = MatrixFactory::createNumeric([
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
]);

$b = new Vector([1,2,3]);

// Then
$this->expectException(Exception\MatrixException::class);

// When
$A->columnAddVector($b, 4);
}

/**
* @test columnAddVector test Vector->count() === matrix->m
* @throws \Exception
*/
public function testColumnAddVectorExceptionElementMismatch()
{
// Given
$A = MatrixFactory::createNumeric([
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
]);

$b = new Vector([1,2,3,4]);

// Then
$this->expectException(Exception\BadParameterException::class);

// When
$A->columnAddVector($b, 1);
}
}
125 changes: 125 additions & 0 deletions tests/LinearAlgebra/Matrix/Numeric/MatrixRowOperationsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use MathPHP\LinearAlgebra\MatrixFactory;
use MathPHP\Exception;
use MathPHP\LinearAlgebra\Vector;

class MatrixRowOperationsTest extends \PHPUnit\Framework\TestCase
{
Expand Down Expand Up @@ -408,6 +409,130 @@ public function testRowAddScalarExceptionRowGreaterThanM()
$A->rowAddScalar(4, 5);
}

/**
* @test rowAddVector
* @dataProvider dataProviderForrowAddVector
* @param array $A
* @param int $mᵢ
* @param array $v
* @param array $expectedMatrix
* @throws \Exception
*/
public function testRowAddVector(array $A, int $mᵢ, array $v, array $expectedMatrix)
{
// Given
$A = MatrixFactory::createNumeric($A);
$v = new Vector($v);
$expectedMatrix = MatrixFactory::createNumeric($expectedMatrix);

// When
$R = $A->rowAddVector($v, $mᵢ);

// Then
$this->assertEquals($expectedMatrix, $R);
}

/**
* @return array
*/
public function dataProviderForRowAddVector(): array
{
return [
[
[
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
], 0, [1,2,3],
[
[2, 4, 6],
[2, 3, 4],
[3, 4, 5],
]
],
[
[
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
], 2, [6,9,12],
[
[1, 2, 3],
[2, 3, 4],
[9, 13, 17],
]
],
[
[
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
], 2, [4,8,12],
[
[1, 2, 3],
[2, 3, 4],
[7, 12, 17],
]
],
[
[
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
], 1, [2.2,3.3,4.4],
[
[1, 2, 3],
[4.2, 6.3, 8.4],
[3, 4, 5],
]
],
];
}

/**
* @test rowAddVector test row m exists
* @throws \Exception
*/
public function testRowAddVectorExceptionRowExists()
{
// Given
$A = MatrixFactory::createNumeric([
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
]);

$b = new Vector([1,2,3]);

// Then
$this->expectException(Exception\MatrixException::class);

// When
$A->rowAddVector($b, 4);
}

/**
* @test rowAddVector test vector->count() === matrix m
* @throws \Exception
*/
public function testRowAddVectorExceptionElementMismatch()
{
// Given
$A = MatrixFactory::createNumeric([
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
]);

$b = new Vector([1,2,3,4]);

// Then
$this->expectException(Exception\BadParameterException::class);

// When
$A->rowAddVector($b, 1);
}

/**
* @test rowSubtract
* @dataProvider dataProviderForRowSubtract
Expand Down

0 comments on commit c97386d

Please sign in to comment.