Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add row/columnAddVector to NumericMatrix #462

Merged
merged 11 commits into from
Dec 31, 2022
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) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: This should actually be n and not m. I've fixed this and added some unit tests around it.

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