/** * @inheritDoc */ public function derive(NumericMatrix $mA, $extra = null) { if ($mA->is('empty')) { return TypeFactory::createInt(0); } if ($mA->is('singleitem')) { return $mA->get(1, 1); } $calc = new Calculator(); return array_reduce($mA->toArray(), function ($c1, $row) use($calc) { return array_reduce($row, function ($carry, $item) use($calc) { return $calc->add($item, $carry); }, $c1); }, TypeFactory::createInt(0)); }
/** * Find tr(M) * * @param NumericMatrix $mA * @param mixed $extra * @return numeric * * @throws Chippyash/Math/Matrix/Exceptions/UndefinedComputationException */ public function derive(NumericMatrix $mA, $extra = null) { if ($mA->is('singleitem')) { return $mA->get(1, 1); } $this->assertMatrixIsNotEmpty($mA, 'No trace for empty matrix')->assertMatrixIsSquare($mA, 'No trace for non-square matrix'); $tr = new FloatType(0); $size = $mA->rows(); $data = $mA->toArray(); $calc = new Calculator(); for ($x = 0; $x < $size; $x++) { $tr = $calc->add($tr, $data[$x][$x]); } return $tr; }
/** * Add single scalar value to each member of the matrix and return result * * @param NumericMatrix $mA First matrix to act on - required * @param scalar $extra value to add * * @return NumericMatrix|RationalMatrix|ComplexMatrix * * @throws Chippyash/Matrix/Exceptions/ComputationException */ public function compute(NumericMatrix $mA, $extra = null) { if ($mA->is('empty')) { return $this->createCorrectMatrixType($mA); } $scalar = $this->createCorrectScalarType($mA, $extra); $data = $mA->toArray(); $m = $mA->rows(); $n = $mA->columns(); $calc = new Calculator(); for ($row = 0; $row < $m; $row++) { for ($col = 0; $col < $n; $col++) { $data[$row][$col] = $calc->add($data[$row][$col], $scalar); } } return $this->createCorrectMatrixType($mA, $data); }
/** * Carry out the actual multiplication using standard matrix multiplication * method. * * @param \Chippyash\Math\Matrix\NumericMatrix $mA * @param \Chippyash\Math\Matrix\NumericMatrix $mB * @return array * @throws ComputationException */ protected function doComputation(NumericMatrix $mA, NumericMatrix $mB) { $size = max([$mA->columns(), $mA->rows(), $mB->columns(), $mB->rows()]); $product = (new ZMatrix())->create([$size, $size])->toArray(); $dA = $mA->toArray(); $dB = $mB->toArray(); $zero = $this->createCorrectScalarType($mA, 0); $calc = new Calculator(); for ($i = 0; $i < $size; $i++) { for ($k = 0; $k < $size; $k++) { for ($j = 0; $j < $size; $j++) { $a = isset($dA[$i][$k]) ? $dA[$i][$k] : $zero; $b = isset($dB[$k][$j]) ? $dB[$k][$j] : $zero; $product[$i][$j] = $calc->add($product[$i][$j], $calc->mul($a, $b)); } } } return $product; }
/** * Inter row multiplication * * @param array $a * @param NumericTypeInterface $multiple * @param int $rowToMultiplyWith * @param int $rowToAddTo * @param \Chippyash\Math\Type\Calculator $calc */ protected function addMultipleOfOtherRowToRow(array &$a, $multiple, $rowToMultiplyWith, $rowToAddTo, Calculator $calc) { $numberOfColumns = count($a[0]); for ($l = 0; $l < $numberOfColumns; $l++) { $a[$rowToAddTo][$l] = $calc->add($a[$rowToAddTo][$l], $calc->mul($a[$rowToMultiplyWith][$l], $multiple)); } }
/** * @inheritDoc */ protected function doCompute(NumericTypeInterface $a, NumericTypeInterface $b, Calculator $calc) { return $calc->add($a, $b); }
/** * LU Decomposition constructor. * * @param \Chippyash\Math\Matrix\NumericMatrix $mA */ protected function LUDecomposition(NumericMatrix $mA) { // Use a "left-looking", dot-product, Crout/Doolittle algorithm. $LU = $mA->toArray(); $m = $this->rows = $mA->rows(); $n = $this->cols = $mA->columns(); for ($i = 0; $i < $m; $i++) { $this->piv[$i] = $i; } $this->pivsign = 1; $LUrowi = []; $LUcolj = []; $calc = new Calculator(); $comp = new Comparator(); $zeroInt = $this->createCorrectScalarType($mA, 0); // Outer loop. for ($j = 0; $j < $n; $j++) { // Make a copy of the j-th column to localize references. for ($i = 0; $i < $m; $i++) { $LUcolj[$i] =& $LU[$i][$j]; } // Apply previous transformations. for ($i = 0; $i < $m; $i++) { $LUrowi = $LU[$i]; // Most of the time is spent in the following dot product. $kmax = min($i, $j); $s = clone $zeroInt; for ($k = 0; $k < $kmax; $k++) { $s = $calc->add($s, $calc->mul($LUrowi[$k], $LUcolj[$k])); } $LUcolj[$i] = $calc->sub($LUcolj[$i], $s); $LUrowi[$j] = $LUcolj[$i]; } // Find pivot and exchange if necessary. $p = $j; for ($i = $j + 1; $i < $m; $i++) { if ($comp->gt($LUcolj[$i]->abs(), $LUcolj[$p]->abs())) { $p = $i; } } if ($p != $j) { for ($k = 0; $k < $n; $k++) { //swap $t = $LU[$p][$k]; $LU[$p][$k] = $LU[$j][$k]; $LU[$j][$k] = $t; } $k = $this->piv[$p]; $this->piv[$p] = $this->piv[$j]; $this->piv[$j] = $k; $this->pivsign = $this->pivsign * -1; } // Compute multipliers. if ($j < $m && $comp->neq($LU[$j][$j], $zeroInt)) { for ($i = $j + 1; $i < $m; $i++) { $LU[$i][$j] = $calc->div($LU[$i][$j], $LU[$j][$j]); } } } $this->set('LU', $this->createCorrectMatrixType($mA, $LU)); }