PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.5.1
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.5.1
4.0.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 All 149 releases
← All changes | vendor/markbaker/matrix/classes/src/Matrix.php +62 -42 3.1.33.5.1 View file →
@@ -6,10 +6,15 @@
6 6 *
7 7 * @copyright Copyright (c) 2018 Mark Baker (https://github.com/MarkBaker/PHPMatrix)
8 8 * @license https://opensource.org/licenses/MIT MIT
9 9 */
10 +
10 11 namespace Matrix;
11 12
13 +use Generator;
14 +use Matrix\Decomposition\LU;
15 +use Matrix\Decomposition\QR;
16 +
12 17 /**
13 18 * Matrix object.
14 19 *
15 20 * @package Matrix
@@ -31,8 +36,9 @@
31 36 * @method Matrix subtract(...$matrices)
32 37 * @method Matrix multiply(...$matrices)
33 38 * @method Matrix divideby(...$matrices)
34 39 * @method Matrix divideinto(...$matrices)
40 + * @method Matrix directsum(...$matrices)
35 41 */
36 42 class Matrix
37 43 {
38 44 protected $rows;
@@ -43,9 +49,9 @@
43 49 * Create a new Matrix object from an array of values
44 50 *
45 51 * @param array $grid
46 52 */
47 - public function __construct(array $grid)
53 + final public function __construct(array $grid)
48 54 {
49 55 $this->buildFromArray(array_values($grid));
50 56 }
51 57
@@ -60,10 +66,9 @@
60 66 $columns = array_reduce(
61 67 $grid,
62 68 function ($carry, $value) {
63 69 return max($carry, is_array($value) ? count($value) : 1);
64 - },
65 - 0
70 + }
66 71 );
67 72 $this->columns = $columns;
68 73
69 74 array_walk(
@@ -81,9 +86,9 @@
81 86
82 87 /**
83 88 * Validate that a row number is a positive integer
84 89 *
85 - * @param $row
90 + * @param int $row
86 91 * @return int
87 92 * @throws Exception
88 93 */
89 94 public static function validateRow($row)
@@ -91,15 +96,15 @@
91 96 if ((!is_numeric($row)) || (intval($row) < 1)) {
92 97 throw new Exception('Invalid Row');
93 98 }
94 99
95 - return (int) $row;
100 + return (int)$row;
96 101 }
97 102
98 103 /**
99 104 * Validate that a column number is a positive integer
100 105 *
101 - * @param $column
106 + * @param int $column
102 107 * @return int
103 108 * @throws Exception
104 109 */
105 110 public static function validateColumn($column)
@@ -107,15 +112,15 @@
107 112 if ((!is_numeric($column)) || (intval($column) < 1)) {
108 113 throw new Exception('Invalid Column');
109 114 }
110 115
111 - return (int) $column;
116 + return (int)$column;
112 117 }
113 118
114 119 /**
115 120 * Validate that a row number falls within the set of rows for this matrix
116 121 *
117 - * @param $row
122 + * @param int $row
118 123 * @return int
119 124 * @throws Exception
120 125 */
121 126 protected function validateRowInRange($row)
@@ -130,9 +135,9 @@
130 135
131 136 /**
132 137 * Validate that a column number falls within the set of columns for this matrix
133 138 *
134 - * @param $column
139 + * @param int $column
135 140 * @return int
136 141 * @throws Exception
137 142 */
138 143 protected function validateColumnInRange($column)
@@ -151,9 +156,9 @@
151 156 * A negative $rowCount value will return rows until that many rows from the end of the matrix
152 157 *
153 158 * Note that row numbers start from 1, not from 0
154 159 *
155 - * @param $row
160 + * @param int $row
156 161 * @param int $rowCount
157 162 * @return static
158 163 * @throws Exception
159 164 */
@@ -159,13 +164,13 @@
159 164 */
160 165 public function getRows($row, $rowCount = 1)
161 166 {
162 167 $row = $this->validateRowInRange($row);
163 - if ($rowCount == 0) {
168 + if ($rowCount === 0) {
164 169 $rowCount = $this->rows - $row + 1;
165 170 }
166 171
167 - return new static(array_slice($this->grid, $row - 1, $rowCount));
172 + return new static(array_slice($this->grid, $row - 1, (int)$rowCount));
168 173 }
169 174
170 175 /**
171 176 * Return a new matrix as a subset of columns from this matrix, starting at column number $column, and $columnCount columns
@@ -173,11 +178,11 @@
173 178 * A negative $columnCount value will return columns until that many columns from the end of the matrix
174 179 *
175 180 * Note that column numbers start from 1, not from 0
176 181 *
177 - * @param $column
182 + * @param int $column
178 183 * @param int $columnCount
179 - * @return static
184 + * @return Matrix
180 185 * @throws Exception
181 186 */
182 187 public function getColumns($column, $columnCount = 1)
183 188 {
@@ -201,9 +206,9 @@
201 206 * A $rowCount value of 0 will remove all rows of the matrix from $row
202 207 *
203 208 * Note that row numbers start from 1, not from 0
204 209 *
205 - * @param $row
210 + * @param int $row
206 211 * @param int $rowCount
207 212 * @return static
208 213 * @throws Exception
209 214 */
@@ -209,14 +214,14 @@
209 214 */
210 215 public function dropRows($row, $rowCount = 1)
211 216 {
212 217 $this->validateRowInRange($row);
213 - if ($rowCount == 0) {
218 + if ($rowCount === 0) {
214 219 $rowCount = $this->rows - $row + 1;
215 220 }
216 221
217 222 $grid = $this->grid;
218 - array_splice($grid, $row - 1, $rowCount);
223 + array_splice($grid, $row - 1, (int)$rowCount);
219 224
220 225 return new static($grid);
221 226 }
222 227
@@ -227,9 +232,9 @@
227 232 * A $columnCount value of 0 will remove all columns of the matrix from $column
228 233 *
229 234 * Note that column numbers start from 1, not from 0
230 235 *
231 - * @param $column
236 + * @param int $column
232 237 * @param int $columnCount
233 238 * @return static
234 239 * @throws Exception
235 240 */
@@ -238,14 +243,14 @@
238 243 $this->validateColumnInRange($column);
239 244 if ($columnCount < 1) {
240 245 $columnCount = $this->columns + $columnCount - $column + 1;
241 246 }
242 -
247 +
243 248 $grid = $this->grid;
244 249 array_walk(
245 250 $grid,
246 251 function (&$row) use ($column, $columnCount) {
247 - array_splice($row, $column - 1, $columnCount);
252 + array_splice($row, $column - 1, (int)$columnCount);
248 253 }
249 254 );
250 255
251 256 return new static($grid);
@@ -254,11 +259,11 @@
254 259 /**
255 260 * Return a value from this matrix, from the "cell" identified by the row and column numbers
256 261 * Note that row and column numbers start from 1, not from 0
257 262 *
258 - * @param $row
259 - * @param $column
260 - * @return static
263 + * @param int $row
264 + * @param int $column
265 + * @return mixed
261 266 * @throws Exception
262 267 */
263 268 public function getValue($row, $column)
264 269 {
@@ -269,11 +274,11 @@
269 274 }
270 275
271 276 /**
272 277 * Returns a Generator that will yield each row of the matrix in turn as a vector matrix
273 - * or the value of each cell if the matrix is a vector
278 + * or the value of each cell if the matrix is a column vector
274 279 *
275 - * @return \Generator|Matrix[]|mixed[]
280 + * @return Generator|Matrix[]|mixed[]
276 281 */
277 282 public function rows()
278 283 {
279 284 foreach ($this->grid as $i => $row) {
@@ -284,11 +289,11 @@
284 289 }
285 290
286 291 /**
287 292 * Returns a Generator that will yield each column of the matrix in turn as a vector matrix
288 - * or the value of each cell if the matrix is a vector
293 + * or the value of each cell if the matrix is a row vector
289 294 *
290 - * @return \Generator|Matrix[]|mixed[]
295 + * @return Generator|Matrix[]|mixed[]
291 296 */
292 297 public function columns()
293 298 {
294 299 for ($i = 0; $i < $this->columns; ++$i) {
@@ -329,8 +334,26 @@
329 334 {
330 335 return $this->grid;
331 336 }
332 337
338 + /**
339 + * Solve A*X = B.
340 + *
341 + * @param Matrix $B Right hand side
342 + *
343 + * @throws Exception
344 + *
345 + * @return Matrix ... Solution if A is square, least squares solution otherwise
346 + */
347 + public function solve(Matrix $B)
348 + {
349 + if ($this->columns === $this->rows) {
350 + return (new LU($this))->solve($B);
351 + }
352 +
353 + return (new QR($this))->solve($B);
354 + }
355 +
333 356 protected static $getters = [
334 357 'rows',
335 358 'columns',
336 359 ];
@@ -337,11 +360,11 @@
337 360
338 361 /**
339 362 * Access specific properties as read-only (no setters)
340 363 *
341 - * @param $propertyName
342 - * @return mixed
343 - * @throws Exception
364 + * @param string $propertyName
365 + * @return mixed
366 + * @throws Exception
344 367 */
345 368 public function __get($propertyName)
346 369 {
347 370 $propertyName = strtolower($propertyName);
@@ -378,26 +401,23 @@
378 401
379 402 /**
380 403 * Returns the result of the function call or operation
381 404 *
382 - * @param string $functionName
383 - * @param mixed[] $arguments
384 - * @return Matrix|float
385 - * @throws Exception|\InvalidArgumentException
405 + * @param string $functionName
406 + * @param mixed[] $arguments
407 + * @return Matrix|float
408 + * @throws Exception
386 409 */
387 410 public function __call($functionName, $arguments)
388 411 {
389 412 $functionName = strtolower(str_replace('_', '', $functionName));
390 413
391 - // Test for function calls
392 - if (in_array($functionName, self::$functions)) {
414 + if (in_array($functionName, self::$functions, true) || in_array($functionName, self::$operations, true)) {
393 415 $functionName = "\\" . __NAMESPACE__ . "\\{$functionName}";
394 - return $functionName($this, ...$arguments);
395 - }
396 - // Test for operation calls
397 - if (in_array($functionName, self::$operations)) {
398 - $functionName = "\\" . __NAMESPACE__ . "\\{$functionName}";
399 - return $functionName($this, ...$arguments);
416 + if (is_callable($functionName)) {
417 + $arguments = array_values(array_merge([$this], $arguments));
418 + return call_user_func_array($functionName, $arguments);
419 + }
400 420 }
401 421 throw new Exception('Function or Operation does not exist');
402 422 }
403 423 }