PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.4.8
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.4.8
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 3.10.4 All 148 releases
visualizer / vendor / markbaker / matrix / classes / src / Functions.php

Functions.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.4.8, at vendor/markbaker/matrix/classes/src/Functions.php

338 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Matrix;
4
5 class Functions
6 {
7 /**
8 * Calculate the adjoint of the matrix
9 *
10 * @param Matrix $matrix The matrix whose adjoint we wish to calculate
11 * @return Matrix
12 *
13 * @throws Exception
14 */
15 private static function getAdjoint(Matrix $matrix)
16 {
17 return self::transpose(
18 self::getCofactors($matrix)
19 );
20 }
21
22 /**
23 * Return the adjoint of this matrix
24 * The adjugate, classical adjoint, or adjunct of a square matrix is the transpose of its cofactor matrix.
25 * The adjugate has sometimes been called the "adjoint", but today the "adjoint" of a matrix normally refers
26 * to its corresponding adjoint operator, which is its conjugate transpose.
27 *
28 * @param Matrix $matrix The matrix whose adjoint we wish to calculate
29 * @return Matrix
30 * @throws Exception
31 **/
32 public static function adjoint(Matrix $matrix)
33 {
34 if (!$matrix->isSquare()) {
35 throw new Exception('Adjoint can only be calculated for a square matrix');
36 }
37
38 return self::getAdjoint($matrix);
39 }
40
41 /**
42 * Calculate the cofactors of the matrix
43 *
44 * @param Matrix $matrix The matrix whose cofactors we wish to calculate
45 * @return Matrix
46 *
47 * @throws Exception
48 */
49 private static function getCofactors(Matrix $matrix)
50 {
51 $cofactors = self::getMinors($matrix);
52 $dimensions = $matrix->rows;
53
54 $cof = 1;
55 for ($i = 0; $i < $dimensions; ++$i) {
56 $cofs = $cof;
57 for ($j = 0; $j < $dimensions; ++$j) {
58 $cofactors[$i][$j] *= $cofs;
59 $cofs = -$cofs;
60 }
61 $cof = -$cof;
62 }
63
64 return new Matrix($cofactors);
65 }
66
67 /**
68 * Return the cofactors of this matrix
69 *
70 * @param Matrix $matrix The matrix whose cofactors we wish to calculate
71 * @return Matrix
72 *
73 * @throws Exception
74 */
75 public static function cofactors(Matrix $matrix)
76 {
77 if (!$matrix->isSquare()) {
78 throw new Exception('Cofactors can only be calculated for a square matrix');
79 }
80
81 return self::getCofactors($matrix);
82 }
83
84 /**
85 * @param Matrix $matrix
86 * @param int $row
87 * @param int $column
88 * @return float
89 * @throws Exception
90 */
91 private static function getDeterminantSegment(Matrix $matrix, $row, $column)
92 {
93 $tmpMatrix = $matrix->toArray();
94 unset($tmpMatrix[$row]);
95 array_walk(
96 $tmpMatrix,
97 function (&$row) use ($column) {
98 unset($row[$column]);
99 }
100 );
101
102 return self::getDeterminant(new Matrix($tmpMatrix));
103 }
104
105 /**
106 * Calculate the determinant of the matrix
107 *
108 * @param Matrix $matrix The matrix whose determinant we wish to calculate
109 * @return float
110 *
111 * @throws Exception
112 */
113 private static function getDeterminant(Matrix $matrix)
114 {
115 $dimensions = $matrix->rows;
116 $determinant = 0;
117
118 switch ($dimensions) {
119 case 1:
120 $determinant = $matrix->getValue(1, 1);
121 break;
122 case 2:
123 $determinant = $matrix->getValue(1, 1) * $matrix->getValue(2, 2) -
124 $matrix->getValue(1, 2) * $matrix->getValue(2, 1);
125 break;
126 default:
127 for ($i = 1; $i <= $dimensions; ++$i) {
128 $det = $matrix->getValue(1, $i) * self::getDeterminantSegment($matrix, 0, $i - 1);
129 if (($i % 2) == 0) {
130 $determinant -= $det;
131 } else {
132 $determinant += $det;
133 }
134 }
135 break;
136 }
137
138 return $determinant;
139 }
140
141 /**
142 * Return the determinant of this matrix
143 *
144 * @param Matrix $matrix The matrix whose determinant we wish to calculate
145 * @return float
146 * @throws Exception
147 **/
148 public static function determinant(Matrix $matrix)
149 {
150 if (!$matrix->isSquare()) {
151 throw new Exception('Determinant can only be calculated for a square matrix');
152 }
153
154 return self::getDeterminant($matrix);
155 }
156
157 /**
158 * Return the diagonal of this matrix
159 *
160 * @param Matrix $matrix The matrix whose diagonal we wish to calculate
161 * @return Matrix
162 * @throws Exception
163 **/
164 public static function diagonal(Matrix $matrix)
165 {
166 if (!$matrix->isSquare()) {
167 throw new Exception('Diagonal can only be extracted from a square matrix');
168 }
169
170 $dimensions = $matrix->rows;
171 $grid = Builder::createFilledMatrix(0, $dimensions, $dimensions)
172 ->toArray();
173
174 for ($i = 0; $i < $dimensions; ++$i) {
175 $grid[$i][$i] = $matrix->getValue($i + 1, $i + 1);
176 }
177
178 return new Matrix($grid);
179 }
180
181 /**
182 * Return the antidiagonal of this matrix
183 *
184 * @param Matrix $matrix The matrix whose antidiagonal we wish to calculate
185 * @return Matrix
186 * @throws Exception
187 **/
188 public static function antidiagonal(Matrix $matrix)
189 {
190 if (!$matrix->isSquare()) {
191 throw new Exception('Anti-Diagonal can only be extracted from a square matrix');
192 }
193
194 $dimensions = $matrix->rows;
195 $grid = Builder::createFilledMatrix(0, $dimensions, $dimensions)
196 ->toArray();
197
198 for ($i = 0; $i < $dimensions; ++$i) {
199 $grid[$i][$dimensions - $i - 1] = $matrix->getValue($i + 1, $dimensions - $i);
200 }
201
202 return new Matrix($grid);
203 }
204
205 /**
206 * Return the identity matrix
207 * The identity matrix, or sometimes ambiguously called a unit matrix, of size n is the n × n square matrix
208 * with ones on the main diagonal and zeros elsewhere
209 *
210 * @param Matrix $matrix The matrix whose identity we wish to calculate
211 * @return Matrix
212 * @throws Exception
213 **/
214 public static function identity(Matrix $matrix)
215 {
216 if (!$matrix->isSquare()) {
217 throw new Exception('Identity can only be created for a square matrix');
218 }
219
220 $dimensions = $matrix->rows;
221
222 return Builder::createIdentityMatrix($dimensions);
223 }
224
225 /**
226 * Return the inverse of this matrix
227 *
228 * @param Matrix $matrix The matrix whose inverse we wish to calculate
229 * @return Matrix
230 * @throws Exception
231 **/
232 public static function inverse(Matrix $matrix)
233 {
234 if (!$matrix->isSquare()) {
235 throw new Exception('Inverse can only be calculated for a square matrix');
236 }
237
238 $determinant = self::getDeterminant($matrix);
239 if ($determinant == 0.0) {
240 throw new Exception('Inverse can only be calculated for a matrix with a non-zero determinant');
241 }
242
243 if ($matrix->rows == 1) {
244 return new Matrix([[1 / $matrix->getValue(1, 1)]]);
245 }
246
247 return self::getAdjoint($matrix)
248 ->multiply(1 / $determinant);
249 }
250
251 /**
252 * Calculate the minors of the matrix
253 *
254 * @param Matrix $matrix The matrix whose minors we wish to calculate
255 * @return array[]
256 *
257 * @throws Exception
258 */
259 protected static function getMinors(Matrix $matrix)
260 {
261 $minors = $matrix->toArray();
262 $dimensions = $matrix->rows;
263 if ($dimensions == 1) {
264 return $minors;
265 }
266
267 for ($i = 0; $i < $dimensions; ++$i) {
268 for ($j = 0; $j < $dimensions; ++$j) {
269 $minors[$i][$j] = self::getDeterminantSegment($matrix, $i, $j);
270 }
271 }
272
273 return $minors;
274 }
275
276 /**
277 * Return the minors of the matrix
278 * The minor of a matrix A is the determinant of some smaller square matrix, cut down from A by removing one or
279 * more of its rows or columns.
280 * Minors obtained by removing just one row and one column from square matrices (first minors) are required for
281 * calculating matrix cofactors, which in turn are useful for computing both the determinant and inverse of
282 * square matrices.
283 *
284 * @param Matrix $matrix The matrix whose minors we wish to calculate
285 * @return Matrix
286 * @throws Exception
287 **/
288 public static function minors(Matrix $matrix)
289 {
290 if (!$matrix->isSquare()) {
291 throw new Exception('Minors can only be calculated for a square matrix');
292 }
293
294 return new Matrix(self::getMinors($matrix));
295 }
296
297 /**
298 * Return the trace of this matrix
299 * The trace is defined as the sum of the elements on the main diagonal (the diagonal from the upper left to the lower right)
300 * of the matrix
301 *
302 * @param Matrix $matrix The matrix whose trace we wish to calculate
303 * @return float
304 * @throws Exception
305 **/
306 public static function trace(Matrix $matrix)
307 {
308 if (!$matrix->isSquare()) {
309 throw new Exception('Trace can only be extracted from a square matrix');
310 }
311
312 $dimensions = $matrix->rows;
313 $result = 0;
314 for ($i = 1; $i <= $dimensions; ++$i) {
315 $result += $matrix->getValue($i, $i);
316 }
317
318 return $result;
319 }
320
321 /**
322 * Return the transpose of this matrix
323 *
324 * @param Matrix $matrix The matrix whose transpose we wish to calculate
325 * @return Matrix
326 **/
327 public static function transpose(Matrix $matrix)
328 {
329 $array = array_values(array_merge([null], $matrix->toArray()));
330 $grid = call_user_func_array(
331 'array_map',
332 $array
333 );
334
335 return new Matrix($grid);
336 }
337 }
338