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

linAlg::dotVector()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
namespace Np\linAlgb;
4
5
use Np\core\{blas,lapack};
6
use Np\matrix, Np\vector;
7
/**
8
 * Linear Algebra
9
 * 
10
 * 
11
 * 
12
 * @package   Np
13
 * @category  Scientific Computing
14
 * @author    ghost (Shubham Chaudhary)
15
 * @email     [email protected]
16
 * @copyright (c) 2020-2021, Shubham Chaudhary
17
 */
18
trait linAlg {
19
    
20
    /**
21
     *  
22
     * get dot product of m.m | m.v | v.v
23
     * 
24
     * @param \Np\matrix|\Np\vector $d
25
     * @return matrix|vector
26
     */
27
    public function dot(matrix|vector $d): matrix|vector {
28
        if ($this instanceof matrix) {
29
            if ($d instanceof matrix) {
30
                return $this->dotMatrix($d);
31
            }
32
            return $this->dotVector($d);
33
        }
34
        return blas::dot($this, $d);
35
    }
36
37
    /**
38
     * get matrix & matrix dot product
39
     * @param \Np\matrix $matrix
40
     * @return \Np\matrix
41
     */
42
    protected function dotMatrix(matrix $matrix): matrix {
43
        if ($this->checkDimensions($this,$matrix)) {
44
            $ar = self::factory($this->row, $matrix->col);
45
            blas::gemm($this, $matrix, $ar);
46
            return $ar;
47
        }
48
    }
49
50
    /**
51
     * get dot product of matrix & a vector
52
     * @param \Np\vector $vector
53
     * @return \Np\vector
54
     */
55
    protected function dotVector(vector $vector): vector {
56
        if ($this->checkDimensions($vector, $this)) {
57
            $mvr = vector::factory($this->col);
58
            blas::gemv($this, $vector, $mvr);
59
            return $mvr;
60
        }
61
    }
62
    
63
    /**
64
     * 
65
     * Compute the multiplicative inverse of the matrix.
66
     * @return matrix|null
67
     */
68
    public function inverse(): matrix|null {
69
        if ($this->isSquare()) {
70
            $imat = $this->copy();
71
            $ipiv = vector::factory($this->row, vector::INT);
72
            $lp = lapack::getrf($imat, $ipiv);
73
            if ($lp != 0) {
74
                return null;
75
            }
76
            $lp = lapack::getri($imat, $ipiv);
77
            if ($lp != 0) {
78
                return null;
79
            }
80
            unset($ipiv);
81
            unset($lp);
82
            return $imat;
83
        }
84
        self::_err('Error::invalid Size of matrix!');
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return Np\linAlgb\null|Np\matrix. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
85
    }
86
87
    /**
88
     * FIXEME:-Bug noticed on 10/06/21
89
     * Compute the (Moore-Penrose) pseudo inverse of the general matrix.
90
     * @return matrix|null
91
     */
92
    public function pseudoInverse(): matrix|null {
93
        $k = min($this->row, $this->col);
94
        $s = vector::factory($k);
95
        $u = self::factory($this->row, $this->row);
96
        $vt = self::factory($this->col, $this->col);
97
        $imat = $this->copy();
98
        $lp = lapack::gesdd($imat, $s, $u, $vt);
99
        if ($lp != 0) {
100
            return null;
101
        }
102
        for ($i = 0; $i < $k; ++$i) {
103
            blas::scale(1.0 / $s->data[$i], $vt->rowAsVector($i));
104
        }
105
        unset($imat);
106
        unset($k);
107
        unset($lp);
108
        unset($s);
109
        $mr = self::factory($this->col, $this->row, $this->dtype);
110
        blas::gemm($vt, $u, $mr);
111
        unset($u);
112
        unset($vt);
113
        return $mr;
114
    }
115
    
116
}
117