diff --git a/4dev/tests/Convert/CoreLibsConvertMathTest.php b/4dev/tests/Convert/CoreLibsConvertMathTest.php index 95002850..6441ca79 100644 --- a/4dev/tests/Convert/CoreLibsConvertMathTest.php +++ b/4dev/tests/Convert/CoreLibsConvertMathTest.php @@ -156,12 +156,32 @@ final class CoreLibsConvertMathTest extends TestCase public function providerMultiplyMatrices(): array { return [ - 'single' => [ + '[3] x [3] => [3x1]' => [ [1, 2, 3], [1, 2, 3], [14] ], - 'double first' => [ + '[3] x [3x1]' => [ + [1, 2, 3], + [[1], [2], [3]], + [14] + ], + '[3] x [3x1]' => [ + [1, 2, 3], + [[1], [2], [3]], + [14] + ], + '[1x3L] x [3x1]' => [ + [[1, 2, 3]], + [[1], [2], [3]], + [14] + ], + '[1x3] x [3x1]' => [ + [[1], [2], [3]], + [[1], [2], [3]], + [1, 2, 3] + ], + '[2x3] x [3] => [3x1]' => [ [ [1, 2, 3], [1, 2, 3] @@ -172,7 +192,18 @@ final class CoreLibsConvertMathTest extends TestCase 14 ] ], - 'double both' => [ + '[2x3] x [3x1]' => [ + [ + [1, 2, 3], + [1, 2, 3] + ], + [[1], [2], [3]], + [ + 14, + 14 + ] + ], + '[2x3] x [2x3] => [3x3]' => [ [ [1, 2, 3], [1, 2, 3], @@ -186,7 +217,37 @@ final class CoreLibsConvertMathTest extends TestCase [3, 6, 9] ] ], - 'tripple first, single second' => [ + '[2x3] x [3x3]' => [ + [ + [1, 2, 3], + [1, 2, 3], + ], + [ + [1, 2, 3], + [1, 2, 3], + [0, 0, 0], + ], + [ + [3, 6, 9], + [3, 6, 9] + ] + ], + '[2x3] x [3x2]' => [ + 'a' => [ + [1, 2, 3], + [1, 2, 3], + ], + 'b' => [ + [1, 1], + [2, 2], + [3, 3], + ], + 'prod' => [ + [14, 14], + [14, 14], + ] + ], + '[3x3] x [3] => [1x3]' => [ [ [1, 2, 3], [1, 2, 3], @@ -199,7 +260,7 @@ final class CoreLibsConvertMathTest extends TestCase 14 ] ], - 'tripple first, double second' => [ + '[3x3] x [2x3] => [3x3]' => [ [ [1, 2, 3], [1, 2, 3], @@ -215,7 +276,24 @@ final class CoreLibsConvertMathTest extends TestCase [3, 6, 9], ] ], - 'single first, tripple second' => [ + '[3x3] x [3x3]' => [ + [ + [1, 2, 3], + [1, 2, 3], + [1, 2, 3], + ], + [ + [1, 2, 3], + [1, 2, 3], + // [0, 0, 0], + ], + [ + [3, 6, 9], + [3, 6, 9], + [3, 6, 9], + ] + ], + '[3] x [3x3]' => [ [1, 2, 3], [ [1, 2, 3], @@ -226,7 +304,7 @@ final class CoreLibsConvertMathTest extends TestCase [6, 12, 18], ] ], - 'double first, tripple second' => [ + '[2x3] x [3x3]' => [ [ [1, 2, 3], [1, 2, 3], diff --git a/www/lib/CoreLibs/Convert/Math.php b/www/lib/CoreLibs/Convert/Math.php index a20085f7..41eb7463 100644 --- a/www/lib/CoreLibs/Convert/Math.php +++ b/www/lib/CoreLibs/Convert/Math.php @@ -136,6 +136,28 @@ class Math * * It returns an array which is the product of the two number matrices passed as parameters. * + * NOTE: + * if the right side (B matrix) has a missing row, this row will be fillwed with 0 instead of + * throwing an error: + * A: + * [ + * [1, 2, 3], + * [4, 5, 6], + * ] + * B: + * [ + * [7, 8, 9], + * [10, 11, 12], + * ] + * The B will get a third row with [0, 0, 0] added to make the multiplication work as it will be + * rewritten as + * B-rewrite: + * [ + * [7, 10, 0], + * [8, 11, 12], + * [0, 0, 0] <- automatically added + * ] + * * @param array> $a m x n matrice * @param array> $b n x p matrice * @@ -161,8 +183,9 @@ class Math $p = count($b[0]); // transpose $b: + // so that we can multiply row by row $bCols = array_map( - callback: fn ($k) => \array_map( + callback: fn ($k) => array_map( (fn ($i) => is_array($i) ? $i[$k] : 0), $b, ), @@ -175,7 +198,8 @@ class Math array_reduce( array: $row, callback: fn ($a, $v, $i = null) => $a + $v * ( - $col[$i ?? array_search($v, $row) ?: 0] + // if last entry missing for full copy add a 0 to it + $col[$i ?? array_search($v, $row, true)] ?? 0 /** @phpstan-ignore-line */ ), initial: 0, ) : @@ -191,7 +215,7 @@ class Math if ($m === 1) { // Avoid [[a, b, c, ...]]: - $product = $product[0]; + return $product[0]; } if ($p === 1) {