mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-11 17:58:41 +00:00
Further matrix implementation
This commit is contained in:
parent
b27154dc19
commit
9f5f45fa7c
34
Math/Matrix/InverseType.php
Normal file
34
Math/Matrix/InverseType.php
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/**
|
||||
* Orange Management
|
||||
*
|
||||
* PHP Version 7.0
|
||||
*
|
||||
* @category TBD
|
||||
* @package TBD
|
||||
* @author OMS Development Team <dev@oms.com>
|
||||
* @author Dennis Eichhorn <d.eichhorn@oms.com>
|
||||
* @copyright 2013 Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link http://orange-management.com
|
||||
*/
|
||||
namespace phpOMS\Math\Matrix;
|
||||
|
||||
use phpOMS\Datatypes\Enum;
|
||||
|
||||
/**
|
||||
* Account type enum.
|
||||
*
|
||||
* @category Framework
|
||||
* @package phpOMS\DataStorage\Database
|
||||
* @author OMS Development Team <dev@oms.com>
|
||||
* @author Dennis Eichhorn <d.eichhorn@oms.com>
|
||||
* @license OMS License 1.0
|
||||
* @link http://orange-management.com
|
||||
* @since 1.0.0
|
||||
*/
|
||||
abstract class InverseType extends Enum
|
||||
{
|
||||
const GAUSS_JORDAN = 0;
|
||||
}
|
||||
|
|
@ -160,4 +160,178 @@ class Matrix implements ArrayAccess, Iterator
|
|||
|
||||
return $newMatrix;
|
||||
}
|
||||
|
||||
public function upperTriangular() : Matrix
|
||||
{
|
||||
$matrix = new Matrix($this->n, $this->n);
|
||||
|
||||
$matrixArr = $this->matrix;
|
||||
$matrix->setMatrix($this->upperTrianglize($matrixArr));
|
||||
|
||||
return $matrix;
|
||||
}
|
||||
|
||||
public function lowerTriangular() : Matrix
|
||||
{
|
||||
// todo: implement
|
||||
return new Matrix($this->m, $this->n);
|
||||
}
|
||||
|
||||
public function diag() : Matrix
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function inverse(int $algorithm = InversionType::GAUSS_JORDAN) : Matrix
|
||||
{
|
||||
if($this->n !== $this->m) {
|
||||
throw new \Exception('Dimension');
|
||||
}
|
||||
|
||||
switch($algorithm) {
|
||||
case InversionType::GAUSS_JORDAN:
|
||||
return $this->inverseGaussJordan();
|
||||
default:
|
||||
throw new \Exception('');
|
||||
}
|
||||
}
|
||||
|
||||
private function inverseGaussJordan() : Matrix
|
||||
{
|
||||
$newMatrixArr = $this->matrix;
|
||||
|
||||
// extending matrix by identity matrix
|
||||
for($i = 0; $i < $this->n; $i++) {
|
||||
for($j = $this->n; $j < $this->n * 2; $j++) {
|
||||
|
||||
if($j === ($i + $this->n)) {
|
||||
$newMatrixArr[$i][$j] = 1;
|
||||
} else {
|
||||
$newMatrixArr[$i][$j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo: maybe replace by triangulize/vice versa????!!!?!?!
|
||||
// pivoting
|
||||
for($i = $this->n - 1; $i > 0; $i--) {
|
||||
if ($newMatrixArr[$i - 1][0] < $newMatrixArr[$i][0]) {
|
||||
for($j = 0; $j < $this->n * 2; $j++) {
|
||||
$temp = $newMatrixArr[$i][$j];
|
||||
$newMatrixArr[$i][$j] = $newMatrixArr[$i-1][$j];
|
||||
$newMatrixArr[$i-1][$j] = $temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* create diagonal matrix */
|
||||
for($i = 0; $i < $this->n; $i++) {
|
||||
for($j = 0; $j < $this->n; $j++) {
|
||||
if ($j !== $i) {
|
||||
$temp = $newMatrixArr[$j][$i] / $newMatrixArr[$i][$i];
|
||||
|
||||
for($c = 0; $c < $this->n * 2; $c++) {
|
||||
$newMatrixArr[$j][$c] -= $newMatrixArr[$i][$c] * $temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* create unit matrix */
|
||||
for($i = 0; $i < $this->n; $i++) {
|
||||
$temp = $newMatrixArr[$i][$i];
|
||||
|
||||
for($j = 0; $j < $this->n * 2; $j++) {
|
||||
$newMatrixArr[$i][$j] = $newMatrixArr[$i][$j] / $temp;
|
||||
}
|
||||
}
|
||||
|
||||
/* removing identity matrix */
|
||||
for($i = 0; $i < $this->n; $i++) {
|
||||
$newMatrixArr[$i] = array_slice($newMatrixArr[$i], $this->n);
|
||||
}
|
||||
|
||||
$newMatrix = new Matrix($this->n, $this->n);
|
||||
$newMatrix->setMatrix($newMatrixArr);
|
||||
|
||||
return $newMatrix;
|
||||
}
|
||||
|
||||
private function decompositionCholesky() : Matrix
|
||||
{
|
||||
$newMatrix = new Matrix($this->n, $this->n);
|
||||
$newMatrixArr = $newMatrix->getMatrix();
|
||||
|
||||
for ($i = 0; $i < $this->n; $i++) {
|
||||
for ($j = 0; $j < $i+1; $j++) {
|
||||
$temp = 0;
|
||||
|
||||
for ($c = 0; $c < $j; $c++) {
|
||||
$temp += $newMatrixArr[$i][$c] * $newMatrixArr[$j][$c];
|
||||
}
|
||||
|
||||
$newMatrixArr[$i][$j] = ($i == $j) ? sqrt($this->matrix[$i][$i] - $temp) : (1 / $newMatrixArr[$j][$j] * ($this->matrix[$i][$j] - $temp));
|
||||
}
|
||||
}
|
||||
|
||||
$newMatrix->setMatrix($newMatrixArr);
|
||||
|
||||
return $newMatrix;
|
||||
}
|
||||
|
||||
private function upperTrianglize(array &$arr) : int
|
||||
{
|
||||
$n = count($arr);
|
||||
$sign = 1;
|
||||
|
||||
for ($i = 0; $i < $n; $i++) {
|
||||
$max = 0;
|
||||
|
||||
for ($j = $i; $j < $n; $j++) {
|
||||
if (abs($arr[$j][$i]) > abs($arr[$max][$i])) {
|
||||
$max = $j;
|
||||
}
|
||||
}
|
||||
|
||||
if ($max) {
|
||||
$sign = -$sign;
|
||||
$temp = $arr[$i];
|
||||
$arr[$i] = $arr[$max], $arr[$max] = $temp;
|
||||
}
|
||||
|
||||
if (!$arr[$i][$i]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for ($j = $i + 1; $j < $n; $j++) {
|
||||
$r = $arr[$j][$i] / $arr[$i][$i];
|
||||
|
||||
if (!$r) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for ($c = $i; $c < $n; $c ++) {
|
||||
$arr[$j][$c] -= $arr[$i][$c] * $r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sign;
|
||||
}
|
||||
|
||||
public function det()
|
||||
{
|
||||
if($this->n === 1) {
|
||||
return $this->matrix[0][0];
|
||||
}
|
||||
|
||||
$trianglize = $this->matrix;
|
||||
$prod = $this->(upperTrianglize($trianglize));
|
||||
|
||||
for($i = 0; $i < $this->n; $i++) {
|
||||
$prod *= $trianglize[$i][$i];
|
||||
}
|
||||
|
||||
return $prod;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user