Passed
Push — main ( b63ebb...d6f51d )
by Shubham
02:04
created

lu   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 87
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 34
dl 0
loc 87
rs 10
c 0
b 0
f 0
wmc 16

5 Methods

Rating   Name   Duplication   Size   Complexity  
A l() 0 2 1
A p() 0 2 1
C factory() 0 42 12
A __construct() 0 1 1
A u() 0 2 1
1
<?php
2
3
declare (strict_types=1);
4
5
namespace Np\linAlgb\decompositions;
6
7
use Np\matrix;
8
use Np\vector;
9
use Np\core\lapack;
10
use Np\exceptions\invalidArgumentException;
11
12
/**
13
 * LU
14
 *
15
 * The LU decomposition is a factorization of a Matrix as the product of a
16
 * lower and upper triangular matrix as well as a permutation matrix.
17
 *
18
 * @package Np
19
 * @category Scientific Library
20
 * @author ghost (Shubham Chaudhary)
21
 * @email [email protected]
22
 * @copyright (c) 2020-2021, Shubham Chaudhary
23
 */
24
class lu {
25
26
    /**
27
     * 
28
     * @param matrix $m
29
     * @return self
30
     * @throws InvalidArgumentException
31
     */
32
    public static function factory(matrix $m): self {
33
        if (!$m->isSquare()) {
34
            throw new invalidArgumentException('Matrix must be given.');
35
        }
36
        $ipiv = vector::factory($m->col, vector::INT);
37
        $ar = $m->copy();
38
        $lp = lapack::getrf($ar, $ipiv);
39
        if ($lp != 0) {
40
            return null;
41
        }
42
        $l = matrix::factory($m->col, $m->col);
43
        $u = matrix::factory($m->col, $m->col);
44
        $p = matrix::factory($m->col, $m->col);
45
        for ($i = 0; $i < $m->col; ++$i) {
46
            for ($j = 0; $j < $i; ++$j) {
47
                $l->data[$i * $m->col + $j] = $ar->data[$i * $m->col + $j];
48
            }
49
            $l->data[$i * $m->col + $i] = 1.0;
50
            for ($j = $i + 1; $j < $m->col; ++$j) {
51
                $l->data[$i * $m->col + $j] = 0.0;
52
            }
53
        }
54
        for ($i = 0; $i < $m->col; ++$i) {
55
            for ($j = 0; $j < $i; ++$j) {
56
                $u->data[$i * $m->col + $j] = 0.0;
57
            }
58
            for ($j = $i; $j < $m->col; ++$j) {
59
                $u->data[$i * $m->col + $j] = $ar->data[$i * $m->col + $j];
60
            }
61
        }
62
        for ($i = 0; $i < $m->col; ++$i) {
63
            for ($j = 0; $j < $m->col; ++$j) {
64
                if ($j == $ipiv->data[$i] - 1) {
65
                    $p->data[$i * $m->col + $j] = 1;
66
                } else {
67
                    $p->data[$i * $m->col + $j] = 0;
68
                }
69
            }
70
        }
71
        unset($ar);
72
        unset($ipiv);
73
        return new self($l, $u, $p);
74
    }
75
76
    /**
77
     * 
78
     * @param matrix $l
79
     * @param matrix $u
80
     * @param matrix $p
81
     */
82
    protected function __construct(protected matrix $l, protected matrix $u, protected matrix $p) {
83
        
84
    }
85
86
    /**
87
     * Return the lower triangular matrix.
88
     *
89
     * @return matrix
90
     */
91
    public function l(): matrix {
92
        return $this->l;
93
    }
94
95
    /**
96
     * Return the upper triangular matrix.
97
     *
98
     * @return matrix
99
     */
100
    public function u(): matrix {
101
        return $this->u;
102
    }
103
104
    /**
105
     * Return the permutation matrix.
106
     * 
107
     * @return matrix
108
     */
109
    public function p(): matrix {
110
        return $this->p;
111
    }
112
113
}
114