123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488 |
- <?php
- namespace MathPHP\Tests\LinearAlgebra\Matrix\Numeric;
- use MathPHP\LinearAlgebra\MatrixFactory;
- use MathPHP\LinearAlgebra\NumericMatrix;
- use MathPHP\LinearAlgebra\NumericSquareMatrix;
- use MathPHP\Exception;
- class MatrixOperationsTest extends \PHPUnit\Framework\TestCase
- {
- /**
- * @test trace
- * @dataProvider dataProviderForTrace
- */
- public function testTrace(array $A, $tr)
- {
- // Given
- $A = MatrixFactory::create($A);
- // When
- $trace = $A->trace();
- // Then
- $this->assertEquals($tr, $trace);
- }
- public function dataProviderForTrace(): array
- {
- return [
- [
- [[1]], 1
- ],
- [
- [
- [1, 2],
- [2, 3],
- ], 4
- ],
- [
- [
- [1, 2, 3],
- [4, 5, 6],
- [7, 8, 9],
- ], 15
- ],
- ];
- }
- /**
- * @test trace exception - not square
- */
- public function testTraceExceptionNotSquareMatrix()
- {
- // Given
- $A = MatrixFactory::create([
- [1, 2],
- [2, 3],
- [3, 4],
- ]);
- // Then
- $this->expectException(Exception\MatrixException::class);
- // When
- $A->trace();
- }
- /**
- * @test diagonal
- * @dataProvider dataProviderForDiagonal
- */
- public function testDiagonal(array $A, array $R)
- {
- // Given
- $A = MatrixFactory::create($A);
- $R = MatrixFactory::create($R);
- // When
- $diagonal = $A->diagonal();
- // Then
- $this->assertEquals($R, $diagonal);
- }
- public function dataProviderForDiagonal(): array
- {
- return [
- [
- [
- [1, 2, 3],
- [2, 3, 4],
- [3, 4, 5],
- ],
- [
- [1, 0, 0],
- [0, 3, 0],
- [0, 0, 5],
- ]
- ],
- [
- [
- [1, 2, 3],
- [2, 3, 4],
- [3, 4, 5],
- [4, 5, 6],
- ],
- [
- [1, 0, 0],
- [0, 3, 0],
- [0, 0, 5],
- [0, 0, 0],
- ]
- ],
- [
- [
- [1, 2, 3, 4],
- [2, 3, 4, 5],
- [3, 4, 5, 6],
- ],
- [
- [1, 0, 0, 0],
- [0, 3, 0, 0],
- [0, 0, 5, 0],
- ]
- ],
- ];
- }
- /**
- * @test inverse
- * @dataProvider dataProviderForInverse
- * @param array $A
- * @param array $A⁻¹
- * @throws \Exception
- */
- public function testInverse(array $A, array $A⁻¹)
- {
- // Given
- $A = MatrixFactory::create($A);
- $A⁻¹ = MatrixFactory::create($A⁻¹);
- // When
- $inverse = $A->inverse();
- $inverseAgain = $A->inverse();
- // Then
- $this->assertEqualsWithDelta($A⁻¹, $inverse, 0.001); // Test calculation
- $this->assertEqualsWithDelta($A⁻¹, $inverseAgain, 0.001); // Test class attribute
- }
- /**
- * @return array
- */
- public function dataProviderForInverse(): array
- {
- return [
- [
- [
- [1]
- ],
- [
- [1]
- ]
- ],
- [
- [
- [2]
- ],
- [
- [1 / 2]
- ]
- ],
- [
- [
- [10]
- ],
- [
- [1 / 10]
- ]
- ],
- [
- [
- [-3]
- ],
- [
- [-1 / 3]
- ]
- ],
- [
- [
- [4, 7],
- [2, 6],
- ],
- [
- [0.6, -0.7],
- [-0.2, 0.4],
- ],
- ],
- [
- [
- [4, 3],
- [3, 2],
- ],
- [
- [-2, 3],
- [3, -4],
- ],
- ],
- [
- [
- [1, 2],
- [3, 4],
- ],
- [
- [-2, 1],
- [3 / 2, -1 / 2],
- ],
- ],
- [
- [
- [3, 3.5],
- [3.2, 3.6],
- ],
- [
- [-9, 8.75],
- [8, -7.5],
- ],
- ],
- [
- [
- [1, 2, 3],
- [0, 4, 5],
- [1, 0, 6],
- ],
- [
- [12 / 11, -6 / 11, -1 / 11],
- [5 / 22, 3 / 22, -5 / 22],
- [-2 / 11, 1 / 11, 2 / 11],
- ],
- ],
- [
- [
- [7, 2, 1],
- [0, 3, -1],
- [-3, 4, -2],
- ],
- [
- [-2, 8, -5],
- [3, -11, 7],
- [9, -34, 21],
- ],
- ],
- [
- [
- [2, 0, 0],
- [0, 2, 0],
- [0, 0, 2],
- ],
- [
- [1/2, 0, 0],
- [0, 1/2, 0],
- [0, 0, 1/2],
- ],
- ],
- [
- [
- [3, 6, 6, 8],
- [4, 5, 3, 2],
- [2, 2, 2, 3],
- [6, 8, 4, 2],
- ],
- [
- [-0.333, 0.667, 0.667, -0.333],
- [0.167, -2.333, 0.167, 1.417],
- [0.167, 4.667, -1.833, -2.583],
- [0.000, -2.000, 1.000, 1.000],
- ],
- ],
- [
- [
- [2, 0, 0, 0],
- [0, 2, 0, 0],
- [0, 0, 2, 0],
- [0, 0, 0, 2],
- ],
- [
- [1/2, 0, 0, 0],
- [0, 1/2, 0, 0],
- [0, 0, 1/2, 0],
- [0, 0, 0, 1/2],
- ],
- ],
- [
- [
- [4, 23, 6, 4, 7],
- [3, 64, 23, 52, 2],
- [65, 45, 3, 23, 1],
- [2, 3, 4, 3, 9],
- [53, 99, 54, 32, 105],
- ],
- [
- [-0.142, 0.006, 0.003, -0.338, 0.038],
- [0.172, -0.012, 0.010, 0.275, -0.035],
- [-0.856, 0.082, -0.089, -2.344, 0.257],
- [0.164, -0.001, 0.026, 0.683, -0.070],
- [0.300, -0.033, 0.027, 0.909, -0.088],
- ],
- ],
- ];
- }
- /**
- * @test inverse exception - not square
- * @dataProvider dataProviderForInverseExceptionNotSquare
- */
- public function testInverseExceptionNotSquare(array $A)
- {
- // Given
- $A = MatrixFactory::create($A);
- // Then
- $this->expectException(Exception\MatrixException::class);
- // When
- $A->inverse();
- }
- public function dataProviderForInverseExceptionNotSquare(): array
- {
- return [
- [
- [
- [3, 4, 4],
- [6, 8, 5],
- ]
- ],
- ];
- }
- /**
- * @test inverse exception - det is zero
- * @dataProvider dataProviderForInverseExceptionDetIsZero
- */
- public function testInverseExceptionDetIsZero(array $A)
- {
- // Given
- $A = MatrixFactory::create($A);
- // Then
- $this->expectException(Exception\MatrixException::class);
- // When
- $A->inverse();
- }
- public function dataProviderForInverseExceptionDetIsZero(): array
- {
- return [
- [
- [
- [3, 4],
- [6, 8],
- ]
- ],
- ];
- }
- /**
- * @test cofactor
- * @dataProvider dataProviderForCofactor
- */
- public function testCofactor(array $A, int $mᵢ, int $nⱼ, $Cᵢⱼ)
- {
- // Given
- $A = MatrixFactory::create($A);
- // When
- $cofactor = $A->cofactor($mᵢ, $nⱼ);
- // Then
- $this->assertEquals($Cᵢⱼ, $cofactor);
- }
- public function dataProviderForCofactor(): array
- {
- return [
- [
- [
- [1, 4, 7],
- [3, 0, 5],
- [-1, 9, 11],
- ],
- 0, 0, -45
- ],
- [
- [
- [1, 4, 7],
- [3, 0, 5],
- [-1, 9, 11],
- ],
- 0, 1, -38
- ],
- [
- [
- [1, 4, 7],
- [3, 0, 5],
- [-1, 9, 11],
- ],
- 1, 2, -13
- ],
- [
- [
- [1, 2, 1],
- [6, -1, 0],
- [-1, -2, -1],
- ], 0, 0, 1
- ],
- [
- [
- [1, 2, 1],
- [6, -1, 0],
- [-1, -2, -1],
- ], 0, 1, 6
- ],
- [
- [
- [1, 2, 1],
- [6, -1, 0],
- [-1, -2, -1],
- ], 0, 2, -13
- ],
- [
- [
- [1, 2, 1],
- [6, -1, 0],
- [-1, -2, -1],
- ], 1, 0, 0
- ],
- [
- [
- [1, 2, 1],
- [6, -1, 0],
- [-1, -2, -1],
- ], 1, 1, 0
- ],
- [
- [
- [1, 2, 1],
- [6, -1, 0],
- [-1, -2, -1],
- ], 1, 2, 0
- ],
- [
- [
- [1, 2, 1],
- [6, -1, 0],
- [-1, -2, -1],
- ], 2, 0, 1
- ],
- [
- [
- [1, 2, 1],
- [6, -1, 0],
- [-1, -2, -1],
- ], 0, 0, 1
- ],
- [
- [
- [1, 2, 1],
- [6, -1, 0],
- [-1, -2, -1],
- ], 2, 2, -13
- ],
- ];
- }
- /**
- * @test cofactor exception - bad row
- */
- public function testCofactorExceptionBadRow()
- {
- // Given
- $A = MatrixFactory::create([
- [1, 2, 3],
- [2, 3, 4],
- [3, 4, 5],
- ]);
- // Then
- $this->expectException(Exception\MatrixException::class);
- // When
- $A->cofactor(4, 1);
- }
- /**
- * @test cofactor exception - bad column
- */
- public function testCofactorExceptionBadColumn()
- {
- $A = MatrixFactory::create([
- [1, 2, 3],
- [2, 3, 4],
- [3, 4, 5],
- ]);
- $this->expectException(Exception\MatrixException::class);
- $A->cofactor(1, 4);
- }
- /**
- * @test cofactor exception - not square
- */
- public function testCofactorExceptionNotSquare()
- {
- // Given
- $A = MatrixFactory::create([
- [1, 2, 3, 4],
- [2, 3, 4, 4],
- [3, 4, 5, 4],
- ]);
- // Then
- $this->expectException(Exception\MatrixException::class);
- // When
- $A->cofactor(1, 1);
- }
- /**
- * @test cofactorMatrix
- * @dataProvider dataProviderForCofactorMatrix
- */
- public function testCofactorMatrix(array $A, array $R)
- {
- // Given
- $A = MatrixFactory::create($A);
- $R = new NumericSquareMatrix($R);
- // When
- $cofactor = $A->cofactorMatrix();
- // Then
- $this->assertEqualsWithDelta($R, $cofactor, 0.00000001);
- }
- public function dataProviderForCofactorMatrix(): array
- {
- return [
- [
- [
- [6, 4],
- [3, 2],
- ],
- [
- [2, -3],
- [-4, 6],
- ],
- ],
- [
- [
- [1, 2, 3],
- [0, 4, 5],
- [1, 0, 6],
- ],
- [
- [24, 5, -4],
- [-12, 3, 2],
- [-2, -5, 4],
- ],
- ],
- [
- [
- [-1, 2, 3],
- [1, 5, 6],
- [0, 4, 3],
- ],
- [
- [-9, -3, 4],
- [6, -3, 4],
- [-3, 9, -7],
- ],
- ],
- [
- [
- [3, 65, 23],
- [98, 35, 86],
- [5, 2, 10],
- ],
- [
- [178, -550, 21],
- [-604, -85, 319],
- [4785, 1996, -6265],
- ],
- ],
- [
- [
- [2, -1, 4, 3, 2, 3, 3, 4, 4],
- [-1, 2, 3, 2, 1, 2, 2, 3, 3],
- [4, 3, 2, 1, 2, 3, 3, 4, 4],
- [2, 1, 2, 1, 2, 1, 1, 2, 2],
- [3, 2, 1, 2, 1, 2, 2, 3, 3],
- [3, 2, 3, 2, 1, 2, 2, 3, 3],
- [3, 2, 3, 2, 1, 2, 2, 1, 2],
- [4, 3, 4, 3, 2, 3, 1, 2, 2],
- [4, 3, 4, 3, 2, 3, 2, 2, 2],
- ],
- [
- [0, 128, 0, 0, 0, -128, 0, 0, 0,],
- [128, -80, 0, -32, -32, -16, 0, 32, -64,],
- [0, 0, 0, 256, 0, -256, 0, 0, 0,],
- [0, -32, 0, -64, -320, 352, 0, 64, -128,],
- [0, -32, 256, -320, -64, 96, 0, 64, -128,],
- [-128, -16, -256, 96, 352, 304, 0, -352, 192,],
- [0, 0, 0, 0, -0, 0, 0, 512, -512,],
- [-0, 32, 0, 64, 64, -352, 512, 192, -384,],
- [0, -64, 0, -128, -128, 192, -512, -384, 768,],
- ],
- ],
- [
- [
- [0, 1, 4, 3, 2, 3, 3, 4, 4],
- [1, 0, 3, 2, 1, 2, 2, 3, 3],
- [4, 3, 0, 1, 2, 3, 3, 4, 4],
- [3, 2, 1, 0, 1, 2, 2, 3, 3],
- [2, 1, 2, 1, 0, 1, 1, 2, 2],
- [3, 2, 3, 2, 1, 0, 2, 3, 3],
- [3, 2, 3, 2, 1, 2, 0, 1, 2],
- [4, 3, 4, 3, 2, 3, 1, 0, 2],
- [4, 3, 4, 3, 2, 3, 2, 2, 0],
- ],
- [
- [-640.0000, 736.0000, 96.0000, 0.0000, -224.0000, 96.0000, 0.0000, 64.0000, 64.0000],
- [ 736.0000, -1472.0000, 0.0000, 0.0000, 736.0000, 0.0000, 0.0000, 0.0000, 0.0000],
- [ 96.0000, 0.0000, -640.0000, 736.0000, -224.0000, 96.0000, 0.0000, 64.0000, 64.0000],
- [ -0.0000, 0.0000, 736.0000, -1472.0000, 736.0000, 0.0000, 0.0000, 0.0000, 0.0000],
- [-224.0000, 736.0000, -224.0000, 736.0000, -2544.0000, 512.0000, 736.0000, -272.0000, 96.0000],
- [ 96.0000, 0.0000, 96.0000, 0.0000, 512.0000, -640.0000, 0.0000, 64.0000, 64.0000],
- [ -0.0000, 0.0000, 0.0000, 0.0000, 736.0000, 0.0000, -1472.0000, 736.0000, 0.0000],
- [ 64.0000, 0.0000, 64.0000, 0.0000, -272.0000, 64.0000, 736.0000, -816.0000, 288.0000],
- [ 64.0000, 0.0000, 64.0000, 0.0000, 96.0000, 64.0000, 0.0000, 288.0000, -448.0000],
- ],
- ],
- [
- [
- [-1, 2, 3],
- [1, 5, 6],
- [0, 4, 3],
- ],
- [
- [-9, -3, 4],
- [6, -3, 4],
- [-3, 9, -7],
- ],
- ],
- [
- [
- [0, 1, 4],
- [1, 0, 3],
- [4, 3, 0],
- ],
- [
- [-9, 12, 3],
- [12, -16, 4],
- [3, 4, -1],
- ],
- ],
- ];
- }
- /**
- * @test cofactorMatrix exception - not square
- */
- public function testCofactorMatrixExceptionNotSquare()
- {
- // Given
- $A = MatrixFactory::create([
- [1, 2, 3, 4],
- [2, 3, 4, 4],
- [3, 4, 5, 4],
- ]);
- // Then
- $this->expectException(Exception\MatrixException::class);
- // When
- $A->cofactorMatrix();
- }
- /**
- * @test cofactorMatrix exception - too small
- */
- public function testCofactorMatrixExceptionTooSmall()
- {
- // Given
- $A = MatrixFactory::create([
- [1],
- ]);
- // Then
- $this->expectException(Exception\MatrixException::class);
- // When
- $A->cofactorMatrix();
- }
- /**
- * @test meanDeviation
- * @dataProvider dataProviderForMeanDeviation
- */
- public function testMeanDeviation(array $A, array $B)
- {
- // Given
- $A = MatrixFactory::create($A);
- $B = MatrixFactory::create($B);
- // When
- $meanDeviation = $A->meanDeviation();
- // Then
- $this->assertEquals($B, $meanDeviation);
- }
- public function dataProviderForMeanDeviation(): array
- {
- return [
- // Test data from: http://www.maths.manchester.ac.uk/~mkt/MT3732%20(MVA)/Intro.pdf
- [
- [
- [4, -1, 3],
- [1, 3, 5],
- ],
- [
- [2, -3, 1],
- [-2, 0, 2],
- ],
- ],
- // Test data from Linear Algebra and Its Applications (Lay)
- [
- [
- [1, 4, 7, 8],
- [2, 2, 8, 4],
- [1, 13, 1, 5],
- ],
- [
- [-4, -1, 2, 3],
- [-2, -2, 4, 0],
- [-4, 8, -4, 0],
- ],
- ],
- [
- [
- [19, 22, 6, 3, 2, 20],
- [12, 6, 9, 15, 13, 5],
- ],
- [
- [7, 10, -6, -9, -10, 8],
- [2, -4, -1, 5, 3, -5],
- ],
- ],
- ];
- }
- /**
- * @test meanDeviation column as variables
- * @dataProvider dataProviderForMeanDeviationColumnsAsVariables
- */
- public function testMeanDeviationColumnsAsVariables(array $A, array $B)
- {
- // Given
- $A = MatrixFactory::create($A);
- $B = MatrixFactory::create($B);
- // When
- $meanDeviation = $A->meanDeviation('columns');
- // Then
- $this->assertEqualsWithDelta($B, $meanDeviation, 0.00001);
- }
- public function dataProviderForMeanDeviationColumnsAsVariables(): array
- {
- return [
- [
- [
- [3, 5, 1],
- [9, 1, 4],
- ],
- [
- [-3, 2, -1.5],
- [3, -2, 1.5],
- ],
- ],
- [
- [
- [4, -1, 3],
- [1, 3, 5],
- ],
- [
- [1.5, -2, -1],
- [-1.5, 2, 1],
- ],
- ],
- [
- [
- [1, 4, 7, 8],
- [2, 2, 8, 4],
- [1, 13, 1, 5],
- ],
- [
- [-1 / 3, -7 / 3, 5 / 3, 7 / 3],
- [ 2 / 3, -13 / 3, 8 / 3, -5 / 3],
- [-1 / 3, 20 / 3, -13 / 3, -2 / 3],
- ],
- ],
- [
- [
- [90, 60, 90],
- [90, 90, 30],
- [60, 60, 60],
- [60, 60, 90],
- [30, 30, 30],
- ],
- [
- [24, 0, 30],
- [24, 30, -30],
- [-6, 0, 0],
- [-6, 0, 30],
- [-36, -30, -30],
- ],
- ],
- ];
- }
- /**
- * @test meanDeviation exception is direction is not rows or columns
- * @throws \Exception
- */
- public function testMeanDeviationDirectionException()
- {
- // Given
- $A = MatrixFactory::create([
- [1, 2, 3],
- [2, 3, 4],
- ]);
- // Then
- $this->expectException(Exception\BadParameterException::class);
- // When
- $A->meanDeviation('diagonal_direction');
- }
- /**
- * @test covarianceMatrix
- * @dataProvider dataProviderForCovarianceMatrix
- */
- public function testCovarianceMatrix(array $A, array $S)
- {
- // Given
- $A = MatrixFactory::create($A);
- // When
- $covarianceMatrix = $A->covarianceMatrix();
- // Then
- $this->assertEqualsWithDelta($S, $covarianceMatrix->getMatrix(), 0.0001);
- }
- public function dataProviderForCovarianceMatrix(): array
- {
- return [
- // Test data from Linear Algebra and Its Applications (Lay)
- [
- [
- [1, 4, 7, 8],
- [2, 2, 8, 4],
- [1, 13, 1, 5],
- ],
- [
- [10, 6, 0],
- [6, 8, -8],
- [0, -8, 32],
- ],
- ],
- [
- [
- [19, 22, 6, 3, 2, 20],
- [12, 6, 9, 15, 13, 5],
- ],
- [
- [86, -27],
- [-27, 16],
- ],
- ],
- // Test data from: http://www.itl.nist.gov/div898/handbook/pmc/section5/pmc541.htm
- [
- [
- [4, 4.2, 3.9, 4.3, 4.1],
- [2, 2.1, 2, 2.1, 2.2],
- [.6, .59, .58, .62, .63]
- ],
- [
- [0.025, 0.0075, 0.00175],
- [0.0075, 0.007, 0.00135],
- [0.00175, 0.00135, 0.00043],
- ],
- ],
- [
- [
- [2.5, 0.5, 2.2, 1.9, 3.1, 2.3, 2, 1, 1.5, 1.1],
- [2.4, 0.7, 2.9, 2.2, 3.0, 2.7, 1.6, 1.1, 1.6, 0.9],
- ],
- [
- [0.616555556, 0.615444444],
- [0.615444444, 0.716555556],
- ],
- ],
- // Test data from: https://www.mathworks.com/help/matlab/ref/cov.html
- [
- [
- [5, 1, 4],
- [0, -5, 9],
- [3, 7, 8],
- [7, 3, 10],
- ],
- [
- [4.3333, 8.8333, -3.0000, 5.6667],
- [8.8333, 50.3333, 6.5000, 24.1667],
- [-3.0000, 6.5000, 7.0000, 1.0000],
- [5.6667, 24.1667, 1.0000, 12.3333],
- ],
- ],
- // Test data from: http://stats.seandolinar.com/making-a-covariance-matrix-in-r/
- [
- [
- [1, 2, 3, 4, 5, 6],
- [2, 3, 5, 6, 1, 9],
- [3, 5, 5, 5, 10, 8],
- [10, 20, 30,40, 50, 55],
- [7, 8, 9, 4, 6, 10],
- ],
- [
- [ 3.5, 3.000000, 4.0, 32.500000, 0.400000],
- [ 3.0, 8.666667, 0.4, 25.333333, 2.466667],
- [ 4.0, 0.400000, 6.4, 38.000000, 0.400000],
- [32.5, 25.333333, 38.0, 304.166667, 1.333333],
- [ 0.4, 2.466667, 0.4, 1.333333, 4.666667],
- ],
- ],
- ];
- }
- /**
- * @test covarianceMatrix columns as variables
- * @dataProvider dataProviderForCovarianceMatrixColumnsAsVariables
- */
- public function testCovarianceMatrixColumnsAsVariables(array $A, array $S)
- {
- // Given
- $A = MatrixFactory::create($A);
- $direction = NumericMatrix::COLUMNS;
- // When
- $covarianceMatrix = $A->covarianceMatrix($direction);
- // Then
- $this->assertEqualsWithDelta($S, $covarianceMatrix->getMatrix(), 0.0001);
- }
- /**
- * Data generated with R cov(A)
- * @return array
- */
- public function dataProviderForCovarianceMatrixColumnsAsVariables(): array
- {
- return [
- [
- [
- [90, 60, 90],
- [90, 90, 30],
- [60, 60, 60],
- [60, 60, 90],
- [30, 30, 30],
- ],
- [
- [630, 450, 225],
- [450, 450, 0],
- [225, 0, 900],
- ],
- ],
- [
- [
- [2, -2],
- [8, -1],
- [6, 0],
- [4, 1],
- [10, 2],
- ],
- [
- [10, 3],
- [3, 2.5],
- ],
- ],
- [
- [
- [1, 4, 7, 8],
- [2, 2, 8, 4],
- [1, 13, 1, 5],
- ],
- [
- [0.3333333, -2.166667, 1.333333, -0.8333333],
- [-2.1666667, 34.333333, -22.166667, -1.3333333],
- [1.3333333, -22.166667, 14.333333, 1.1666667],
- [-0.8333333, -1.333333, 1.166667, 4.3333333],
- ],
- ],
- [
- [
- [19, 22, 6, 3, 2, 20],
- [12, 6, 9, 15, 13, 5],
- ],
- [
- [ 24.5, 56, -10.5, -42, -38.5, 52.5],
- [ 56.0, 128, -24.0, -96, -88.0, 120.0],
- [-10.5, -24, 4.5, 18, 16.5, -22.5],
- [-42.0, -96, 18.0, 72, 66.0, -90.0],
- [-38.5, -88, 16.5, 66, 60.5, -82.5],
- [ 52.5, 120, -22.5, -90, -82.5, 112.5],
- ],
- ],
- ];
- }
- /**
- * @test covarianceMatrix exception is direction is not rows or columns
- * @throws \Exception
- */
- public function testCovarianceMatrixDirectionException()
- {
- // Given
- $A = MatrixFactory::create([
- [1, 2, 3],
- [2, 3, 4],
- ]);
- // Then
- $this->expectException(Exception\BadParameterException::class);
- // When
- $covarianceMatrix = $A->covarianceMatrix('invalid_direction');
- }
- /**
- * @test adjugate returns the expected SquareMatrix
- * @dataProvider dataProviderForAdjugate
- * @param array $A
- * @param array $expected
- */
- public function testAdjugate(array $A, array $expected)
- {
- // Given
- $A = MatrixFactory::create($A);
- $expected = MatrixFactory::create($expected);
- // When
- $adj⟮A⟯ = $A->adjugate();
- // Then
- $this->assertEqualsWithDelta($expected, $adj⟮A⟯, 0.00001);
- $this->assertEqualsWithDelta($expected->getMatrix(), $adj⟮A⟯->getMatrix(), 0.00001);
- }
- public function dataProviderForAdjugate(): array
- {
- return [
- [
- [
- [0],
- ],
- [
- [1],
- ],
- ],
- [
- [
- [1],
- ],
- [
- [1],
- ],
- ],
- [
- [
- [5],
- ],
- [
- [1],
- ],
- ],
- // Data calculated using online calculator: http://www.dcode.fr/adjoint-matrix
- [
- [
- [1, 2],
- [3, 4],
- ],
- [
- [4, -2],
- [-3, 1],
- ],
- ],
- [
- [
- [4, -2],
- [-3, 1],
- ],
- [
- [1, 2],
- [3, 4],
- ],
- ],
- [
- [
- [1, 1, 1],
- [1, 1, 1],
- [1, 1, 1],
- ],
- [
- [0, 0, 0],
- [0, 0, 0],
- [0, 0, 0],
- ],
- ],
- [
- [
- [0, 0, 0],
- [0, 0, 0],
- [0, 0, 0],
- ],
- [
- [0, 0, 0],
- [0, 0, 0],
- [0, 0, 0],
- ],
- ],
- [
- [
- [1, 2, 3],
- [4, 5, 6],
- [7, 8, 9],
- ],
- [
- [-3, 6, -3],
- [6, -12, 6],
- [-3, 6, -3],
- ],
- ],
- [
- [
- [1, 2, 3],
- [4, 5, 6],
- [7, 8, 9],
- ],
- [
- [-3, 6, -3],
- [6, -12, 6],
- [-3, 6, -3],
- ],
- ],
- [
- [
- [1, 3, 4],
- [3, 4, 4],
- [4, 3, 2],
- ],
- [
- [-4, 6, -4],
- [10, -14, 8],
- [-7, 9, -5],
- ],
- ],
- [
- [
- [4, 8, 5, 4],
- [3, 5, 7, 9],
- [0, 8, 12, 5],
- [7, 9, 0, 3],
- ],
- [
- [-645, 39, 246, 333],
- [403, -17, -158, -223],
- [-392, 28, 136, 212],
- [296, -40, -100, -152],
- ],
- ],
- [
- [
- [2, -1, 4, 3, 2, 3, 3, 4, 4],
- [-1, 2, 3, 2, 1, 2, 2, 3, 3],
- [4, 3, 2, 1, 2, 3, 3, 4, 4],
- [2, 1, 2, 1, 2, 1, 1, 2, 2],
- [3, 2, 1, 2, 1, 2, 2, 3, 3],
- [3, 2, 3, 2, 1, 2, 2, 3, 3],
- [3, 2, 3, 2, 1, 2, 2, 1, 2],
- [4, 3, 4, 3, 2, 3, 1, 2, 2],
- [4, 3, 4, 3, 2, 3, 2, 2, 2],
- ],
- [
- [0, 128, 0, 0, 0, -128, 0, 0, -0],
- [128, -80, 0, -32, -32, -16, 0, 32, -64],
- [0, 0, 0, 0, 256, -256, 0, 0, -0],
- [0, -32, 256, -64, -320, 96, 0, 64, -128],
- [0, -32, 0, -320, -64, 352, 0, 64, -128],
- [-128, -16, -256, 352, 96, 304, -0, -352, 192],
- [-0, 0, -0, 2.8421709430404E-14, 0, -0, 0, 512, -512],
- [-0, 32, -0, 64, 64, -352, 512, 192, -384],
- [0, -64, 0, -128, -128, 192, -512, -384, 768],
- ]
- ],
- [
- [
- [0, 1, 4, 3, 2, 3, 3, 4, 4],
- [1, 0, 3, 2, 1, 2, 2, 3, 3],
- [4, 3, 0, 1, 2, 3, 3, 4, 4],
- [3, 2, 1, 0, 1, 2, 2, 3, 3],
- [2, 1, 2, 1, 0, 1, 1, 2, 2],
- [3, 2, 3, 2, 1, 0, 2, 3, 3],
- [3, 2, 3, 2, 1, 2, 0, 1, 2],
- [4, 3, 4, 3, 2, 3, 1, 0, 2],
- [4, 3, 4, 3, 2, 3, 2, 2, 0],
- ],
- [
- [-640, 736, 96, 0, -224, 96, 0, 64, 64],
- [736, -1472, 0, 0, 736, 0, 0, 0, 0],
- [96, 0, -640, 736, -224, 96, 0, 64, 64],
- [0, 0, 736, -1472, 736, 0, 0, 0, 0, ],
- [-224, 736, -224, 736, -2544, 512, 736, -272, 96],
- [96, 0, 96, 0, 512, -640, 0, 64, 64],
- [0, 0, 0, 0, 736, 0, -1472, 736, 0],
- [64, 0, 64, 0, -272, 64, 736, -816, 288],
- [64, 0, 64, 0, 96, 64, 0, 288, -448],
- ]
- ],
- ];
- }
- /**
- * @test adjugate throws an Exception\MatrixException if the matrix is not square
- */
- public function testAdjugateSquareMatrixException()
- {
- // Given
- $A = [
- [1, 2, 3],
- [2, 3, 4],
- ];
- $A = MatrixFactory::create($A);
- // Then
- $this->expectException(Exception\MatrixException::class);
- // When
- $adj⟮A⟯ = $A->adjugate();
- }
- /**
- * @test rank returns the expected value
- * @dataProvider dataProviderForRank
- */
- public function testRank(array $A, $expected)
- {
- // Given
- $A = MatrixFactory::create($A);
- // When
- $rank = $A->rank();
- $this->assertEquals($expected, $rank);
- }
- public function dataProviderForRank(): array
- {
- return [
- [
- [
- [0]
- ], 0
- ],
- [
- [
- [1]
- ], 1
- ],
- [
- [
- [2]
- ], 1
- ],
- [
- [
- [-2]
- ], 1
- ],
- [
- [
- [1, 2, 3],
- [2, 3, 4],
- [3, 4, 5],
- ], 2
- ],
- [
- [
- [1, 3, -1],
- [0, 1, 7],
- ], 2
- ],
- [
- [
- [1, 2, 1],
- [-2, -3, 1],
- [3, 5, 0],
- ], 2
- ],
- [
- [
- [0, 3, -6, 6, 4, -5],
- [3, -7, 8, -5, 8, 9],
- [3, -9, 12, -9, 6, 15],
- ], 3
- ],
- [
- [
- [0, 2, 8, -7],
- [2, -2, 4, 0],
- [-3, 4, -2, -5],
- ], 3
- ],
- [
- [
- [1, -2, 3, 9],
- [-1, 3, 0, -4],
- [2, -5, 5, 17],
- ], 3
- ],
- [
- [
- [1, 0, -2, 1, 0],
- [0, -1, -3, 1, 3],
- [-2, -1, 1, -1, 3],
- [0, 3, 9, 0, -12],
- ], 3
- ],
- [
- [
- [1, 1, 4, 1, 2],
- [0, 1, 2, 1, 1],
- [0, 0, 0, 1, 2],
- [1, -1, 0, 0, 2],
- [2, 1, 6, 0, 1],
- ], 3
- ],
- [
- [
- [1, 2, 0, -1, 1, -10],
- [1, 3, 1, 1, -1, -9],
- [2, 5, 1, 0, 0, -19],
- [3, 6, 0, 0, -6, -27],
- [1, 5, 3, 5, -5, -7],
- ], 3
- ],
- [
- [
- [-4, 3, 1, 5, -8],
- [6, 0, 9, 2, 6],
- [-1, 4, 4, 0, 2],
- [8, -1, 3, 4, 0],
- [5, 9, -7, -7, 1],
- ], 5
- ],
- [
- [
- [4, 7],
- [2, 6],
- ], 2
- ],
- [
- [
- [4, 3],
- [3, 2],
- ], 2
- ],
- [
- [
- [1, 2],
- [3, 4],
- ], 2
- ],
- [
- [
- [1, 2, 3],
- [0, 4, 5],
- [1, 0, 6],
- ], 3
- ],
- [
- [
- [7, 2, 1],
- [0, 3, -1],
- [-3, 4, -2],
- ], 3
- ],
- [
- [
- [3, 6, 6, 8],
- [4, 5, 3, 2],
- [2, 2, 2, 3],
- [6, 8, 4, 2],
- ], 4
- ],
- [
- [
- [0, 0],
- [0, 1],
- ], 1
- ],
- [
- [
- [1, 1, 1, 1, 1],
- [0, 1, 1, 1, 1],
- [0, 0, 0, 0, 1],
- ], 3
- ],
- [
- [
- [0, 0],
- [1, 1],
- [-1, 0],
- [0, -1],
- [0, 0],
- [0, 0],
- [0, 0],
- [0, 0],
- [1, 1],
- ], 2
- ],
- [
- [
- [1, 2, 3, 4, 3, 1],
- [2, 4, 6, 2, 6, 2],
- [3, 6, 18, 9, 9, -6],
- [4, 8, 12, 10, 12, 4],
- [5, 10, 24, 11, 15, -4],
- ], 3
- ],
- [
- [
- [1, 2, 3, 4, 3, 1],
- [2, 4, 6, 2, 6, 2],
- [3, 6, 18, 9, 9, -6],
- [4, 8, 12, 10, 12, 4],
- [5, 10, 24, 11, 15, -4]
- ], 3
- ],
- [
- [
- [0, 1],
- [1, 2],
- [0, 5],
- ], 2
- ],
- [
- [
- [1, 0, 1, 0, 1, 0],
- [1, 0, 1, 0, 0, 1],
- [1, 0, 0, 1, 1, 0],
- [1, 0, 0, 1, 0, 1],
- [0, 1, 0, 1, 1, 0],
- [0, 1, 0, 1, 0, 1],
- [0, 1, 1, 0, 1, 0],
- [0, 1, 1, 0, 0, 1],
- ], 4
- ],
- ];
- }
- }
|