ILIAS  Release_4_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
Matrix.php
Go to the documentation of this file.
1 <?php
6 define('RAND_MAX', mt_getrandmax());
7 define('RAND_MIN', 0);
8 
10 if (!defined('PHPEXCEL_ROOT')) {
14  define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../../');
15 }
16 
17 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/utils/Error.php';
18 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/utils/Maths.php';
19 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/CholeskyDecomposition.php';
20 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/LUDecomposition.php';
21 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/QRDecomposition.php';
22 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/EigenvalueDecomposition.php';
23 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/SingularValueDecomposition.php';
24 
25 /*
26  * Matrix class
27  *
28  * @author Paul Meagher
29  * @author Michael Bommarito
30  * @author Lukasz Karapuda
31  * @author Bartek Matosiuk
32  * @version 1.8
33  * @license PHP v3.0
34  * @see http://math.nist.gov/javanumerics/jama/
35  */
36 class Matrix {
37 
44  public $A = array();
45 
52  private $m;
53 
60  private $n;
61 
62 
68  public function __construct() {
69  if (func_num_args() > 0) {
70  $args = func_get_args();
71  $match = implode(",", array_map('gettype', $args));
72 
73  switch($match) {
74  //Square matrix - n x n
75  case 'integer':
76  $this->m = $args[0];
77  $this->n = $args[0];
78  $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0));
79  break;
80  //Rectangular matrix - m x n
81  case 'integer,integer':
82  $this->m = $args[0];
83  $this->n = $args[1];
84  $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0));
85  break;
86  //Rectangular matrix constant-filled - m x n filled with c
87  case 'integer,integer,integer':
88  $this->m = $args[0];
89  $this->n = $args[1];
90  $this->A = array_fill(0, $this->m, array_fill(0, $this->n, $args[2]));
91  break;
92  //Rectangular matrix constant-filled - m x n filled with c
93  case 'integer,integer,double':
94  $this->m = $args[0];
95  $this->n = $args[1];
96  $this->A = array_fill(0, $this->m, array_fill(0, $this->n, $args[2]));
97  break;
98  //Rectangular matrix - m x n initialized from 2D array
99  case 'array':
100  $this->m = count($args[0]);
101  $this->n = count($args[0][0]);
102  $this->A = $args[0];
103  break;
104  //Rectangular matrix - m x n initialized from 2D array
105  case 'array,integer,integer':
106  $this->m = $args[1];
107  $this->n = $args[2];
108  $this->A = $args[0];
109  break;
110  //Rectangular matrix - m x n initialized from packed array
111  case 'array,integer':
112  $this->m = $args[1];
113  if ($this->m != 0) {
114  $this->n = count($args[0]) / $this->m;
115  } else {
116  $this->n = 0;
117  }
118  if (($this->m * $this->n) == count($args[0])) {
119  for($i = 0; $i < $this->m; ++$i) {
120  for($j = 0; $j < $this->n; ++$j) {
121  $this->A[$i][$j] = $args[0][$i + $j * $this->m];
122  }
123  }
124  } else {
126  }
127  break;
128  default:
130  break;
131  }
132  } else {
134  }
135  } // function __construct()
136 
137 
143  public function getArray() {
144  return $this->A;
145  } // function getArray()
146 
147 
153  public function getArrayCopy() {
154  return $this->A;
155  } // function getArrayCopy()
156 
157 
165  public function constructWithCopy($A) {
166  $this->m = count($A);
167  $this->n = count($A[0]);
168  $newCopyMatrix = new Matrix($this->m, $this->n);
169  for ($i = 0; $i < $this->m; ++$i) {
170  if (count($A[$i]) != $this->n) {
172  }
173  for ($j = 0; $j < $this->n; ++$j) {
174  $newCopyMatrix->A[$i][$j] = $A[$i][$j];
175  }
176  }
177  return $newCopyMatrix;
178  } // function constructWithCopy()
179 
180 
187  public function getColumnPackedCopy() {
188  $P = array();
189  for($i = 0; $i < $this->m; ++$i) {
190  for($j = 0; $j < $this->n; ++$j) {
191  array_push($P, $this->A[$j][$i]);
192  }
193  }
194  return $P;
195  } // function getColumnPackedCopy()
196 
197 
204  public function getRowPackedCopy() {
205  $P = array();
206  for($i = 0; $i < $this->m; ++$i) {
207  for($j = 0; $j < $this->n; ++$j) {
208  array_push($P, $this->A[$i][$j]);
209  }
210  }
211  return $P;
212  } // function getRowPackedCopy()
213 
214 
220  public function getRowDimension() {
221  return $this->m;
222  } // function getRowDimension()
223 
224 
230  public function getColumnDimension() {
231  return $this->n;
232  } // function getColumnDimension()
233 
234 
243  public function get($i = null, $j = null) {
244  return $this->A[$i][$j];
245  } // function get()
246 
247 
258  public function getMatrix() {
259  if (func_num_args() > 0) {
260  $args = func_get_args();
261  $match = implode(",", array_map('gettype', $args));
262 
263  switch($match) {
264  //A($i0...; $j0...)
265  case 'integer,integer':
266  list($i0, $j0) = $args;
267  if ($i0 >= 0) { $m = $this->m - $i0; } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
268  if ($j0 >= 0) { $n = $this->n - $j0; } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
269  $R = new Matrix($m, $n);
270  for($i = $i0; $i < $this->m; ++$i) {
271  for($j = $j0; $j < $this->n; ++$j) {
272  $R->set($i, $j, $this->A[$i][$j]);
273  }
274  }
275  return $R;
276  break;
277  //A($i0...$iF; $j0...$jF)
278  case 'integer,integer,integer,integer':
279  list($i0, $iF, $j0, $jF) = $args;
280  if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
281  if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
282  $R = new Matrix($m+1, $n+1);
283  for($i = $i0; $i <= $iF; ++$i) {
284  for($j = $j0; $j <= $jF; ++$j) {
285  $R->set($i - $i0, $j - $j0, $this->A[$i][$j]);
286  }
287  }
288  return $R;
289  break;
290  //$R = array of row indices; $C = array of column indices
291  case 'array,array':
292  list($RL, $CL) = $args;
293  if (count($RL) > 0) { $m = count($RL); } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
294  if (count($CL) > 0) { $n = count($CL); } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
295  $R = new Matrix($m, $n);
296  for($i = 0; $i < $m; ++$i) {
297  for($j = 0; $j < $n; ++$j) {
298  $R->set($i - $i0, $j - $j0, $this->A[$RL[$i]][$CL[$j]]);
299  }
300  }
301  return $R;
302  break;
303  //$RL = array of row indices; $CL = array of column indices
304  case 'array,array':
305  list($RL, $CL) = $args;
306  if (count($RL) > 0) { $m = count($RL); } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
307  if (count($CL) > 0) { $n = count($CL); } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
308  $R = new Matrix($m, $n);
309  for($i = 0; $i < $m; ++$i) {
310  for($j = 0; $j < $n; ++$j) {
311  $R->set($i, $j, $this->A[$RL[$i]][$CL[$j]]);
312  }
313  }
314  return $R;
315  break;
316  //A($i0...$iF); $CL = array of column indices
317  case 'integer,integer,array':
318  list($i0, $iF, $CL) = $args;
319  if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
320  if (count($CL) > 0) { $n = count($CL); } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
321  $R = new Matrix($m, $n);
322  for($i = $i0; $i < $iF; ++$i) {
323  for($j = 0; $j < $n; ++$j) {
324  $R->set($i - $i0, $j, $this->A[$RL[$i]][$j]);
325  }
326  }
327  return $R;
328  break;
329  //$RL = array of row indices
330  case 'array,integer,integer':
331  list($RL, $j0, $jF) = $args;
332  if (count($RL) > 0) { $m = count($RL); } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
333  if (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
334  $R = new Matrix($m, $n+1);
335  for($i = 0; $i < $m; ++$i) {
336  for($j = $j0; $j <= $jF; ++$j) {
337  $R->set($i, $j - $j0, $this->A[$RL[$i]][$j]);
338  }
339  }
340  return $R;
341  break;
342  default:
344  break;
345  }
346  } else {
348  }
349  } // function getMatrix()
350 
351 
362  public function setMatrix() {
363  if (func_num_args() > 0) {
364  $args = func_get_args();
365  $match = implode(",", array_map('gettype', $args));
366 
367  switch($match) {
368  case 'integer,integer,object':
369  if ($args[2] instanceof Matrix) { $M = $args[2]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
370  if (($args[0] + $M->m) <= $this->m) { $i0 = $args[0]; } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
371  if (($args[1] + $M->n) <= $this->n) { $j0 = $args[1]; } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
372  for($i = $i0; $i < $i0 + $M->m; ++$i) {
373  for($j = $j0; $j < $j0 + $M->n; ++$j) {
374  $this->A[$i][$j] = $M->get($i - $i0, $j - $j0);
375  }
376  }
377  break;
378  case 'integer,integer,array':
379  $M = new Matrix($args[2]);
380  if (($args[0] + $M->m) <= $this->m) { $i0 = $args[0]; } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
381  if (($args[1] + $M->n) <= $this->n) { $j0 = $args[1]; } else { throw new Exception(JAMAError(ArgumentBoundsException)); }
382  for($i = $i0; $i < $i0 + $M->m; ++$i) {
383  for($j = $j0; $j < $j0 + $M->n; ++$j) {
384  $this->A[$i][$j] = $M->get($i - $i0, $j - $j0);
385  }
386  }
387  break;
388  default:
390  break;
391  }
392  } else {
394  }
395  } // function setMatrix()
396 
397 
405  public function checkMatrixDimensions($B = null) {
406  if ($B instanceof Matrix) {
407  if (($this->m == $B->getRowDimension()) && ($this->n == $B->getColumnDimension())) {
408  return true;
409  } else {
411  }
412  } else {
414  }
415  } // function checkMatrixDimensions()
416 
417 
418 
428  public function set($i = null, $j = null, $c = null) {
429  // Optimized set version just has this
430  $this->A[$i][$j] = $c;
431  /*
432  if (is_int($i) && is_int($j) && is_numeric($c)) {
433  if (($i < $this->m) && ($j < $this->n)) {
434  $this->A[$i][$j] = $c;
435  } else {
436  echo "A[$i][$j] = $c<br />";
437  throw new Exception(JAMAError(ArgumentBoundsException));
438  }
439  } else {
440  throw new Exception(JAMAError(ArgumentTypeException));
441  }
442  */
443  } // function set()
444 
445 
454  public function identity($m = null, $n = null) {
455  return $this->diagonal($m, $n, 1);
456  } // function identity()
457 
458 
468  public function diagonal($m = null, $n = null, $c = 1) {
469  $R = new Matrix($m, $n);
470  for($i = 0; $i < $m; ++$i) {
471  $R->set($i, $i, $c);
472  }
473  return $R;
474  } // function diagonal()
475 
476 
486  public function filled($m = null, $n = null, $c = 0) {
487  if (is_int($m) && is_int($n) && is_numeric($c)) {
488  $R = new Matrix($m, $n, $c);
489  return $R;
490  } else {
492  }
493  } // function filled()
494 
503  public function random($m = null, $n = null, $a = RAND_MIN, $b = RAND_MAX) {
504  if (is_int($m) && is_int($n) && is_numeric($a) && is_numeric($b)) {
505  $R = new Matrix($m, $n);
506  for($i = 0; $i < $m; ++$i) {
507  for($j = 0; $j < $n; ++$j) {
508  $R->set($i, $j, mt_rand($a, $b));
509  }
510  }
511  return $R;
512  } else {
514  }
515  } // function random()
516 
517 
524  public function packed() {
525  return $this->getRowPacked();
526  } // function packed()
527 
528 
537  public function getMatrixByRow($i0 = null, $iF = null) {
538  if (is_int($i0)) {
539  if (is_int($iF)) {
540  return $this->getMatrix($i0, 0, $iF + 1, $this->n);
541  } else {
542  return $this->getMatrix($i0, 0, $i0 + 1, $this->n);
543  }
544  } else {
546  }
547  } // function getMatrixByRow()
548 
549 
558  public function getMatrixByCol($j0 = null, $jF = null) {
559  if (is_int($j0)) {
560  if (is_int($jF)) {
561  return $this->getMatrix(0, $j0, $this->m, $jF + 1);
562  } else {
563  return $this->getMatrix(0, $j0, $this->m, $j0 + 1);
564  }
565  } else {
567  }
568  } // function getMatrixByCol()
569 
570 
577  public function transpose() {
578  $R = new Matrix($this->n, $this->m);
579  for($i = 0; $i < $this->m; ++$i) {
580  for($j = 0; $j < $this->n; ++$j) {
581  $R->set($j, $i, $this->A[$i][$j]);
582  }
583  }
584  return $R;
585  } // function transpose()
586 
587 
594  public function norm1() {
595  $r = 0;
596  for($j = 0; $j < $this->n; ++$j) {
597  $s = 0;
598  for($i = 0; $i < $this->m; ++$i) {
599  $s += abs($this->A[$i][$j]);
600  }
601  $r = ($r > $s) ? $r : $s;
602  }
603  return $r;
604  } // function norm1()
605 
606 
613  public function norm2() {
614  } // function norm2()
615 
616 
623  public function normInf() {
624  $r = 0;
625  for($i = 0; $i < $this->m; ++$i) {
626  $s = 0;
627  for($j = 0; $j < $this->n; ++$j) {
628  $s += abs($this->A[$i][$j]);
629  }
630  $r = ($r > $s) ? $r : $s;
631  }
632  return $r;
633  } // function normInf()
634 
635 
642  public function normF() {
643  $f = 0;
644  for ($i = 0; $i < $this->m; ++$i) {
645  for ($j = 0; $j < $this->n; ++$j) {
646  $f = hypo($f,$this->A[$i][$j]);
647  }
648  }
649  return $f;
650  } // function normF()
651 
652 
658  public function rank () {
659  $svd = new SingularValueDecomposition($this);
660  return $svd->rank();
661  } // function rank ()
662 
663 
669  public function cond () {
670  $svd = new SingularValueDecomposition($this);
671  return $svd->cond();
672  } // function cond ()
673 
674 
681  public function trace() {
682  $s = 0;
683  $n = min($this->m, $this->n);
684  for($i = 0; $i < $n; ++$i) {
685  $s += $this->A[$i][$i];
686  }
687  return $s;
688  } // function trace()
689 
690 
697  public function uminus() {
698  } // function uminus()
699 
700 
708  public function plus() {
709  if (func_num_args() > 0) {
710  $args = func_get_args();
711  $match = implode(",", array_map('gettype', $args));
712 
713  switch($match) {
714  case 'object':
715  if ($args[0] instanceof Matrix) { $M = $args[0]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
716  break;
717  case 'array':
718  $M = new Matrix($args[0]);
719  break;
720  default:
722  break;
723  }
724  $this->checkMatrixDimensions($M);
725  for($i = 0; $i < $this->m; ++$i) {
726  for($j = 0; $j < $this->n; ++$j) {
727  $M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]);
728  }
729  }
730  return $M;
731  } else {
733  }
734  } // function plus()
735 
736 
744  public function plusEquals() {
745  if (func_num_args() > 0) {
746  $args = func_get_args();
747  $match = implode(",", array_map('gettype', $args));
748 
749  switch($match) {
750  case 'object':
751  if ($args[0] instanceof Matrix) { $M = $args[0]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
752  break;
753  case 'array':
754  $M = new Matrix($args[0]);
755  break;
756  default:
758  break;
759  }
760  $this->checkMatrixDimensions($M);
761  for($i = 0; $i < $this->m; ++$i) {
762  for($j = 0; $j < $this->n; ++$j) {
763  $this->A[$i][$j] += $M->get($i, $j);
764  }
765  }
766  return $this;
767  } else {
769  }
770  } // function plusEquals()
771 
772 
780  public function minus() {
781  if (func_num_args() > 0) {
782  $args = func_get_args();
783  $match = implode(",", array_map('gettype', $args));
784 
785  switch($match) {
786  case 'object':
787  if ($args[0] instanceof Matrix) { $M = $args[0]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
788  break;
789  case 'array':
790  $M = new Matrix($args[0]);
791  break;
792  default:
794  break;
795  }
796  $this->checkMatrixDimensions($M);
797  for($i = 0; $i < $this->m; ++$i) {
798  for($j = 0; $j < $this->n; ++$j) {
799  $M->set($i, $j, $M->get($i, $j) - $this->A[$i][$j]);
800  }
801  }
802  return $M;
803  } else {
805  }
806  } // function minus()
807 
808 
816  public function minusEquals() {
817  if (func_num_args() > 0) {
818  $args = func_get_args();
819  $match = implode(",", array_map('gettype', $args));
820 
821  switch($match) {
822  case 'object':
823  if ($args[0] instanceof Matrix) { $M = $args[0]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
824  break;
825  case 'array':
826  $M = new Matrix($args[0]);
827  break;
828  default:
830  break;
831  }
832  $this->checkMatrixDimensions($M);
833  for($i = 0; $i < $this->m; ++$i) {
834  for($j = 0; $j < $this->n; ++$j) {
835  $this->A[$i][$j] -= $M->get($i, $j);
836  }
837  }
838  return $this;
839  } else {
841  }
842  } // function minusEquals()
843 
844 
853  public function arrayTimes() {
854  if (func_num_args() > 0) {
855  $args = func_get_args();
856  $match = implode(",", array_map('gettype', $args));
857 
858  switch($match) {
859  case 'object':
860  if ($args[0] instanceof Matrix) { $M = $args[0]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
861  break;
862  case 'array':
863  $M = new Matrix($args[0]);
864  break;
865  default:
867  break;
868  }
869  $this->checkMatrixDimensions($M);
870  for($i = 0; $i < $this->m; ++$i) {
871  for($j = 0; $j < $this->n; ++$j) {
872  $M->set($i, $j, $M->get($i, $j) * $this->A[$i][$j]);
873  }
874  }
875  return $M;
876  } else {
878  }
879  } // function arrayTimes()
880 
881 
890  public function arrayTimesEquals() {
891  if (func_num_args() > 0) {
892  $args = func_get_args();
893  $match = implode(",", array_map('gettype', $args));
894 
895  switch($match) {
896  case 'object':
897  if ($args[0] instanceof Matrix) { $M = $args[0]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
898  break;
899  case 'array':
900  $M = new Matrix($args[0]);
901  break;
902  default:
904  break;
905  }
906  $this->checkMatrixDimensions($M);
907  for($i = 0; $i < $this->m; ++$i) {
908  for($j = 0; $j < $this->n; ++$j) {
909  $this->A[$i][$j] *= $M->get($i, $j);
910  }
911  }
912  return $this;
913  } else {
915  }
916  } // function arrayTimesEquals()
917 
918 
927  public function arrayRightDivide() {
928  if (func_num_args() > 0) {
929  $args = func_get_args();
930  $match = implode(",", array_map('gettype', $args));
931 
932  switch($match) {
933  case 'object':
934  if ($args[0] instanceof Matrix) { $M = $args[0]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
935  break;
936  case 'array':
937  $M = new Matrix($args[0]);
938  break;
939  default:
941  break;
942  }
943  $this->checkMatrixDimensions($M);
944  for($i = 0; $i < $this->m; ++$i) {
945  for($j = 0; $j < $this->n; ++$j) {
946  $M->set($i, $j, $this->A[$i][$j] / $M->get($i, $j));
947  }
948  }
949  return $M;
950  } else {
952  }
953  } // function arrayRightDivide()
954 
955 
964  public function arrayRightDivideEquals() {
965  if (func_num_args() > 0) {
966  $args = func_get_args();
967  $match = implode(",", array_map('gettype', $args));
968 
969  switch($match) {
970  case 'object':
971  if ($args[0] instanceof Matrix) { $M = $args[0]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
972  break;
973  case 'array':
974  $M = new Matrix($args[0]);
975  break;
976  default:
978  break;
979  }
980  $this->checkMatrixDimensions($M);
981  for($i = 0; $i < $this->m; ++$i) {
982  for($j = 0; $j < $this->n; ++$j) {
983  $this->A[$i][$j] = $this->A[$i][$j] / $M->get($i, $j);
984  }
985  }
986  return $M;
987  } else {
989  }
990  } // function arrayRightDivideEquals()
991 
992 
1001  public function arrayLeftDivide() {
1002  if (func_num_args() > 0) {
1003  $args = func_get_args();
1004  $match = implode(",", array_map('gettype', $args));
1005 
1006  switch($match) {
1007  case 'object':
1008  if ($args[0] instanceof Matrix) { $M = $args[0]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
1009  break;
1010  case 'array':
1011  $M = new Matrix($args[0]);
1012  break;
1013  default:
1015  break;
1016  }
1017  $this->checkMatrixDimensions($M);
1018  for($i = 0; $i < $this->m; ++$i) {
1019  for($j = 0; $j < $this->n; ++$j) {
1020  $M->set($i, $j, $M->get($i, $j) / $this->A[$i][$j]);
1021  }
1022  }
1023  return $M;
1024  } else {
1026  }
1027  } // function arrayLeftDivide()
1028 
1029 
1038  public function arrayLeftDivideEquals() {
1039  if (func_num_args() > 0) {
1040  $args = func_get_args();
1041  $match = implode(",", array_map('gettype', $args));
1042 
1043  switch($match) {
1044  case 'object':
1045  if ($args[0] instanceof Matrix) { $M = $args[0]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
1046  break;
1047  case 'array':
1048  $M = new Matrix($args[0]);
1049  break;
1050  default:
1052  break;
1053  }
1054  $this->checkMatrixDimensions($M);
1055  for($i = 0; $i < $this->m; ++$i) {
1056  for($j = 0; $j < $this->n; ++$j) {
1057  $this->A[$i][$j] = $M->get($i, $j) / $this->A[$i][$j];
1058  }
1059  }
1060  return $M;
1061  } else {
1063  }
1064  } // function arrayLeftDivideEquals()
1065 
1066 
1074  public function times() {
1075  if (func_num_args() > 0) {
1076  $args = func_get_args();
1077  $match = implode(",", array_map('gettype', $args));
1078 
1079  switch($match) {
1080  case 'object':
1081  if ($args[0] instanceof Matrix) { $B = $args[0]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
1082  if ($this->n == $B->m) {
1083  $C = new Matrix($this->m, $B->n);
1084  for($j = 0; $j < $B->n; ++$j) {
1085  for ($k = 0; $k < $this->n; ++$k) {
1086  $Bcolj[$k] = $B->A[$k][$j];
1087  }
1088  for($i = 0; $i < $this->m; ++$i) {
1089  $Arowi = $this->A[$i];
1090  $s = 0;
1091  for($k = 0; $k < $this->n; ++$k) {
1092  $s += $Arowi[$k] * $Bcolj[$k];
1093  }
1094  $C->A[$i][$j] = $s;
1095  }
1096  }
1097  return $C;
1098  } else {
1099  throw new Exception(JAMAError(MatrixDimensionMismatch));
1100  }
1101  break;
1102  case 'array':
1103  $B = new Matrix($args[0]);
1104  if ($this->n == $B->m) {
1105  $C = new Matrix($this->m, $B->n);
1106  for($i = 0; $i < $C->m; ++$i) {
1107  for($j = 0; $j < $C->n; ++$j) {
1108  $s = "0";
1109  for($k = 0; $k < $C->n; ++$k) {
1110  $s += $this->A[$i][$k] * $B->A[$k][$j];
1111  }
1112  $C->A[$i][$j] = $s;
1113  }
1114  }
1115  return $C;
1116  } else {
1117  throw new Exception(JAMAError(MatrixDimensionMismatch));
1118  }
1119  return $M;
1120  break;
1121  case 'integer':
1122  $C = new Matrix($this->A);
1123  for($i = 0; $i < $C->m; ++$i) {
1124  for($j = 0; $j < $C->n; ++$j) {
1125  $C->A[$i][$j] *= $args[0];
1126  }
1127  }
1128  return $C;
1129  break;
1130  case 'double':
1131  $C = new Matrix($this->m, $this->n);
1132  for($i = 0; $i < $C->m; ++$i) {
1133  for($j = 0; $j < $C->n; ++$j) {
1134  $C->A[$i][$j] = $args[0] * $this->A[$i][$j];
1135  }
1136  }
1137  return $C;
1138  break;
1139  case 'float':
1140  $C = new Matrix($this->A);
1141  for($i = 0; $i < $C->m; ++$i) {
1142  for($j = 0; $j < $C->n; ++$j) {
1143  $C->A[$i][$j] *= $args[0];
1144  }
1145  }
1146  return $C;
1147  break;
1148  default:
1150  break;
1151  }
1152  } else {
1154  }
1155  } // function times()
1156 
1157 
1165  public function power() {
1166  if (func_num_args() > 0) {
1167  $args = func_get_args();
1168  $match = implode(",", array_map('gettype', $args));
1169 
1170  switch($match) {
1171  case 'object':
1172  if ($args[0] instanceof Matrix) { $M = $args[0]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
1173  break;
1174  case 'array':
1175  $M = new Matrix($args[0]);
1176  break;
1177  default:
1179  break;
1180  }
1181  $this->checkMatrixDimensions($M);
1182  for($i = 0; $i < $this->m; ++$i) {
1183  for($j = 0; $j < $this->n; ++$j) {
1184  $this->A[$i][$j] = pow($this->A[$i][$j],$M->get($i, $j));
1185  }
1186  }
1187  return $this;
1188  } else {
1190  }
1191  } // function power()
1192 
1193 
1201  public function concat() {
1202  if (func_num_args() > 0) {
1203  $args = func_get_args();
1204  $match = implode(",", array_map('gettype', $args));
1205 
1206  switch($match) {
1207  case 'object':
1208  if ($args[0] instanceof Matrix) { $M = $args[0]; } else { throw new Exception(JAMAError(ArgumentTypeException)); }
1209  case 'array':
1210  $M = new Matrix($args[0]);
1211  break;
1212  default:
1214  break;
1215  }
1216  $this->checkMatrixDimensions($M);
1217  for($i = 0; $i < $this->m; ++$i) {
1218  for($j = 0; $j < $this->n; ++$j) {
1219 // $this->A[$i][$j] = '"'.trim($this->A[$i][$j],'"').trim($M->get($i, $j),'"').'"';
1220  $this->A[$i][$j] = trim($this->A[$i][$j],'"').trim($M->get($i, $j),'"');
1221  }
1222  }
1223  return $this;
1224  } else {
1226  }
1227  } // function concat()
1228 
1229 
1236  public function chol() {
1237  return new CholeskyDecomposition($this);
1238  } // function chol()
1239 
1240 
1247  public function lu() {
1248  return new LUDecomposition($this);
1249  } // function lu()
1250 
1251 
1258  public function qr() {
1259  return new QRDecomposition($this);
1260  } // function qr()
1261 
1262 
1269  public function eig() {
1270  return new EigenvalueDecomposition($this);
1271  } // function eig()
1272 
1273 
1280  public function svd() {
1281  return new SingularValueDecomposition($this);
1282  } // function svd()
1283 
1284 
1291  public function solve($B) {
1292  if ($this->m == $this->n) {
1293  $LU = new LUDecomposition($this);
1294  return $LU->solve($B);
1295  } else {
1296  $QR = new QRDecomposition($this);
1297  return $QR->solve($B);
1298  }
1299  } // function solve()
1300 
1301 
1307  public function inverse() {
1308  return $this->solve($this->identity($this->m, $this->m));
1309  } // function inverse()
1310 
1311 
1318  public function det() {
1319  $L = new LUDecomposition($this);
1320  return $L->det();
1321  } // function det()
1322 
1323 
1329  public function mprint($A, $format="%01.2f", $width=2) {
1330  $m = count($A);
1331  $n = count($A[0]);
1332  $spacing = str_repeat('&nbsp;',$width);
1333 
1334  for ($i = 0; $i < $m; ++$i) {
1335  for ($j = 0; $j < $n; ++$j) {
1336  $formatted = sprintf($format, $A[$i][$j]);
1337  echo $formatted.$spacing;
1338  }
1339  echo "<br />";
1340  }
1341  } // function mprint()
1342 
1343 
1349  public function toHTML($width=2) {
1350  print('<table style="background-color:#eee;">');
1351  for($i = 0; $i < $this->m; ++$i) {
1352  print('<tr>');
1353  for($j = 0; $j < $this->n; ++$j) {
1354  print('<td style="background-color:#fff;border:1px solid #000;padding:2px;text-align:center;vertical-align:middle;">' . $this->A[$i][$j] . '</td>');
1355  }
1356  print('</tr>');
1357  }
1358  print('</table>');
1359  } // function toHTML()
1360 
1361 } // class Matrix