public function testMultiply() { $identity = $this->getIdentityMatrix($this->size); $array = array(); for ($i = 0; $i < $this->size; $i++) { for ($j = 0; $j < $this->size; $j++) { $array[$i][$j] = rand(); } } $matrix = new LL_Matrix($array); if ($this->strassen) { $result = $matrix->strassenMultiply($identity); } else { $result = $matrix->naiveMultiply($identity); } }
public function strassenMultiply(LL_Matrix $matrix) { if ($this->columns() != $matrix->rows()) { // impossible operation. return false; } if ($this->columns() < 32) { return $this->naiveMultiply($matrix); } // get these from $this. $subdivisions = $this->subdivide($this, 2, 2); if ($subdivisions === false) { return $this->naiveMultiply($matrix); } $a11 = new LL_Matrix($subdivisions[0][0]); $a12 = new LL_Matrix($subdivisions[0][1]); $a21 = new LL_Matrix($subdivisions[1][0]); $a22 = new LL_Matrix($subdivisions[1][1]); // get these from $matrix $subdivisions = $this->subdivide($matrix, 2, 2); if ($subdivisions === false) { // fall back on naïve if even subdivide isn't possible. return $this->naiveMultiply($matrix); } $b11 = new LL_Matrix($subdivisions[0][0]); $b12 = new LL_Matrix($subdivisions[0][1]); $b21 = new LL_Matrix($subdivisions[1][0]); $b22 = new LL_Matrix($subdivisions[1][1]); // intermediaries /* M1 = (A11 + A22) (B11 + B22) M2 = (A21 + A22) B11 M3 = A11 (B12 – B22) M4 = A22 (B21 – B11) M5 = (A11 + A12) B22 M6 = (A21 – A11) (B11 + B12) M7 = (A12 – A22) (B21 + B22) */ $m1_1 = $a11->add($a22); $m1_2 = $b11->add($b22); $m1 = $m1_1->strassenMultiply($m1_2); unset($m1_1); unset($m1_2); $m2_1 = $a21->add($a22); $m2 = $m2_1->strassenMultiply($b11); unset($m2_1); $m3_1 = $b12->subtract($b22); $m3 = $a11->strassenMultiply($m3_1); unset($m3_1); $m4_1 = $b21->subtract($b11); $m4 = $a22->strassenMultiply($m4_1); $m5_1 = $a11->add($a12); $m5 = $m5_1->strassenMultiply($b22); $m6_1 = $a21->subtract($a11); $m6_2 = $b11->add($b12); $m6 = $m6_1->strassenMultiply($m6_2); $m7_1 = $a12->add($a22); $m7_2 = $b21->add($b22); $m7 = $m7_1->strassenMultiply($m7_2); // result $c11 = $m1->add($m1); $c11 = $c11->add($m4); $c11 = $c11->subtract($m5); $c11 = $c11->add($m7); $c12 = $m3->add($m5); $c21 = $m2->add($m4); $c22 = $m1->subtract($m2); $c22 = $c22->add($m3); $c22 = $c22->add($m6); $result = array(array($c11, $c12), array($c21, $c22)); return $this->rebuild($result); }