source: sourcecode/application/libraries/PHPExcel/Shared/JAMA/Matrix.php @ 1

Last change on this file since 1 was 1, checked in by dungnv, 11 years ago
File size: 29.4 KB
Line 
1<?php
2/**
3 * @package JAMA
4 */
5
6/** PHPExcel root directory */
7if (!defined('PHPEXCEL_ROOT')) {
8        /**
9         * @ignore
10         */
11        define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../../');
12        require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
13}
14
15
16/*
17 *      Matrix class
18 *
19 *      @author Paul Meagher
20 *      @author Michael Bommarito
21 *      @author Lukasz Karapuda
22 *      @author Bartek Matosiuk
23 *      @version 1.8
24 *      @license PHP v3.0
25 *      @see http://math.nist.gov/javanumerics/jama/
26 */
27class PHPExcel_Shared_JAMA_Matrix {
28
29
30        const PolymorphicArgumentException      = "Invalid argument pattern for polymorphic function.";
31        const ArgumentTypeException                     = "Invalid argument type.";
32        const ArgumentBoundsException           = "Invalid argument range.";
33        const MatrixDimensionException          = "Matrix dimensions are not equal.";
34        const ArrayLengthException                      = "Array length must be a multiple of m.";
35
36        /**
37         *      Matrix storage
38         *
39         *      @var array
40         *      @access public
41         */
42        public $A = array();
43
44        /**
45         *      Matrix row dimension
46         *
47         *      @var int
48         *      @access private
49         */
50        private $m;
51
52        /**
53         *      Matrix column dimension
54         *
55         *      @var int
56         *      @access private
57         */
58        private $n;
59
60
61        /**
62         *      Polymorphic constructor
63         *
64         *      As PHP has no support for polymorphic constructors, we hack our own sort of polymorphism using func_num_args, func_get_arg, and gettype. In essence, we're just implementing a simple RTTI filter and calling the appropriate constructor.
65         */
66        public function __construct() {
67                if (func_num_args() > 0) {
68                        $args = func_get_args();
69                        $match = implode(",", array_map('gettype', $args));
70
71                        switch($match) {
72                                //Rectangular matrix - m x n initialized from 2D array
73                                case 'array':
74                                                $this->m = count($args[0]);
75                                                $this->n = count($args[0][0]);
76                                                $this->A = $args[0];
77                                                break;
78                                //Square matrix - n x n
79                                case 'integer':
80                                                $this->m = $args[0];
81                                                $this->n = $args[0];
82                                                $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0));
83                                                break;
84                                //Rectangular matrix - m x n
85                                case 'integer,integer':
86                                                $this->m = $args[0];
87                                                $this->n = $args[1];
88                                                $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0));
89                                                break;
90                                //Rectangular matrix - m x n initialized from packed array
91                                case 'array,integer':
92                                                $this->m = $args[1];
93                                                if ($this->m != 0) {
94                                                        $this->n = count($args[0]) / $this->m;
95                                                } else {
96                                                        $this->n = 0;
97                                                }
98                                                if (($this->m * $this->n) == count($args[0])) {
99                                                        for($i = 0; $i < $this->m; ++$i) {
100                                                                for($j = 0; $j < $this->n; ++$j) {
101                                                                        $this->A[$i][$j] = $args[0][$i + $j * $this->m];
102                                                                }
103                                                        }
104                                                } else {
105                                                        throw new PHPExcel_Calculation_Exception(self::ArrayLengthException);
106                                                }
107                                                break;
108                                default:
109                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
110                                                break;
111                        }
112                } else {
113                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
114                }
115        }       //      function __construct()
116
117
118        /**
119         *      getArray
120         *
121         *      @return array Matrix array
122         */
123        public function getArray() {
124                return $this->A;
125        }       //      function getArray()
126
127
128        /**
129         *      getRowDimension
130         *
131         *      @return int Row dimension
132         */
133        public function getRowDimension() {
134                return $this->m;
135        }       //      function getRowDimension()
136
137
138        /**
139         *      getColumnDimension
140         *
141         *      @return int Column dimension
142         */
143        public function getColumnDimension() {
144                return $this->n;
145        }       //      function getColumnDimension()
146
147
148        /**
149         *      get
150         *
151         *      Get the i,j-th element of the matrix.
152         *      @param int $i Row position
153         *      @param int $j Column position
154         *      @return mixed Element (int/float/double)
155         */
156        public function get($i = null, $j = null) {
157                return $this->A[$i][$j];
158        }       //      function get()
159
160
161        /**
162         *      getMatrix
163         *
164         *      Get a submatrix
165         *      @param int $i0 Initial row index
166         *      @param int $iF Final row index
167         *      @param int $j0 Initial column index
168         *      @param int $jF Final column index
169         *      @return Matrix Submatrix
170         */
171        public function getMatrix() {
172                if (func_num_args() > 0) {
173                        $args = func_get_args();
174                        $match = implode(",", array_map('gettype', $args));
175
176                        switch($match) {
177                                //A($i0...; $j0...)
178                                case 'integer,integer':
179                                                list($i0, $j0) = $args;
180                                                if ($i0 >= 0) { $m = $this->m - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }
181                                                if ($j0 >= 0) { $n = $this->n - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }
182                                                $R = new PHPExcel_Shared_JAMA_Matrix($m, $n);
183                                                for($i = $i0; $i < $this->m; ++$i) {
184                                                        for($j = $j0; $j < $this->n; ++$j) {
185                                                                $R->set($i, $j, $this->A[$i][$j]);
186                                                        }
187                                                }
188                                                return $R;
189                                                break;
190                                //A($i0...$iF; $j0...$jF)
191                                case 'integer,integer,integer,integer':
192                                                list($i0, $iF, $j0, $jF) = $args;
193                                                if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }
194                                                if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }
195                                                $R = new PHPExcel_Shared_JAMA_Matrix($m+1, $n+1);
196                                                for($i = $i0; $i <= $iF; ++$i) {
197                                                        for($j = $j0; $j <= $jF; ++$j) {
198                                                                $R->set($i - $i0, $j - $j0, $this->A[$i][$j]);
199                                                        }
200                                                }
201                                                return $R;
202                                                break;
203                                //$R = array of row indices; $C = array of column indices
204                                case 'array,array':
205                                                list($RL, $CL) = $args;
206                                                if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }
207                                                if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }
208                                                $R = new PHPExcel_Shared_JAMA_Matrix($m, $n);
209                                                for($i = 0; $i < $m; ++$i) {
210                                                        for($j = 0; $j < $n; ++$j) {
211                                                                $R->set($i - $i0, $j - $j0, $this->A[$RL[$i]][$CL[$j]]);
212                                                        }
213                                                }
214                                                return $R;
215                                                break;
216                                //$RL = array of row indices; $CL = array of column indices
217                                case 'array,array':
218                                                list($RL, $CL) = $args;
219                                                if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }
220                                                if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }
221                                                $R = new PHPExcel_Shared_JAMA_Matrix($m, $n);
222                                                for($i = 0; $i < $m; ++$i) {
223                                                        for($j = 0; $j < $n; ++$j) {
224                                                                $R->set($i, $j, $this->A[$RL[$i]][$CL[$j]]);
225                                                        }
226                                                }
227                                                return $R;
228                                                break;
229                                //A($i0...$iF); $CL = array of column indices
230                                case 'integer,integer,array':
231                                                list($i0, $iF, $CL) = $args;
232                                                if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }
233                                                if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }
234                                                $R = new PHPExcel_Shared_JAMA_Matrix($m, $n);
235                                                for($i = $i0; $i < $iF; ++$i) {
236                                                        for($j = 0; $j < $n; ++$j) {
237                                                                $R->set($i - $i0, $j, $this->A[$RL[$i]][$j]);
238                                                        }
239                                                }
240                                                return $R;
241                                                break;
242                                //$RL = array of row indices
243                                case 'array,integer,integer':
244                                                list($RL, $j0, $jF) = $args;
245                                                if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }
246                                                if (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }
247                                                $R = new PHPExcel_Shared_JAMA_Matrix($m, $n+1);
248                                                for($i = 0; $i < $m; ++$i) {
249                                                        for($j = $j0; $j <= $jF; ++$j) {
250                                                                $R->set($i, $j - $j0, $this->A[$RL[$i]][$j]);
251                                                        }
252                                                }
253                                                return $R;
254                                                break;
255                                default:
256                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
257                                                break;
258                        }
259                } else {
260                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
261                }
262        }       //      function getMatrix()
263
264
265        /**
266         *      checkMatrixDimensions
267         *
268         *      Is matrix B the same size?
269         *      @param Matrix $B Matrix B
270         *      @return boolean
271         */
272        public function checkMatrixDimensions($B = null) {
273                if ($B instanceof PHPExcel_Shared_JAMA_Matrix) {
274                        if (($this->m == $B->getRowDimension()) && ($this->n == $B->getColumnDimension())) {
275                                return true;
276                        } else {
277                                throw new PHPExcel_Calculation_Exception(self::MatrixDimensionException);
278                        }
279                } else {
280                        throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException);
281                }
282        }       //      function checkMatrixDimensions()
283
284
285
286        /**
287         *      set
288         *
289         *      Set the i,j-th element of the matrix.
290         *      @param int $i Row position
291         *      @param int $j Column position
292         *      @param mixed $c Int/float/double value
293         *      @return mixed Element (int/float/double)
294         */
295        public function set($i = null, $j = null, $c = null) {
296                // Optimized set version just has this
297                $this->A[$i][$j] = $c;
298        }       //      function set()
299
300
301        /**
302         *      identity
303         *
304         *      Generate an identity matrix.
305         *      @param int $m Row dimension
306         *      @param int $n Column dimension
307         *      @return Matrix Identity matrix
308         */
309        public function identity($m = null, $n = null) {
310                return $this->diagonal($m, $n, 1);
311        }       //      function identity()
312
313
314        /**
315         *      diagonal
316         *
317         *      Generate a diagonal matrix
318         *      @param int $m Row dimension
319         *      @param int $n Column dimension
320         *      @param mixed $c Diagonal value
321         *      @return Matrix Diagonal matrix
322         */
323        public function diagonal($m = null, $n = null, $c = 1) {
324                $R = new PHPExcel_Shared_JAMA_Matrix($m, $n);
325                for($i = 0; $i < $m; ++$i) {
326                        $R->set($i, $i, $c);
327                }
328                return $R;
329        }       //      function diagonal()
330
331
332        /**
333         *      getMatrixByRow
334         *
335         *      Get a submatrix by row index/range
336         *      @param int $i0 Initial row index
337         *      @param int $iF Final row index
338         *      @return Matrix Submatrix
339         */
340        public function getMatrixByRow($i0 = null, $iF = null) {
341                if (is_int($i0)) {
342                        if (is_int($iF)) {
343                                return $this->getMatrix($i0, 0, $iF + 1, $this->n);
344                        } else {
345                                return $this->getMatrix($i0, 0, $i0 + 1, $this->n);
346                        }
347                } else {
348                        throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException);
349                }
350        }       //      function getMatrixByRow()
351
352
353        /**
354         *      getMatrixByCol
355         *
356         *      Get a submatrix by column index/range
357         *      @param int $i0 Initial column index
358         *      @param int $iF Final column index
359         *      @return Matrix Submatrix
360         */
361        public function getMatrixByCol($j0 = null, $jF = null) {
362                if (is_int($j0)) {
363                        if (is_int($jF)) {
364                                return $this->getMatrix(0, $j0, $this->m, $jF + 1);
365                        } else {
366                                return $this->getMatrix(0, $j0, $this->m, $j0 + 1);
367                        }
368                } else {
369                        throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException);
370                }
371        }       //      function getMatrixByCol()
372
373
374        /**
375         *      transpose
376         *
377         *      Tranpose matrix
378         *      @return Matrix Transposed matrix
379         */
380        public function transpose() {
381                $R = new PHPExcel_Shared_JAMA_Matrix($this->n, $this->m);
382                for($i = 0; $i < $this->m; ++$i) {
383                        for($j = 0; $j < $this->n; ++$j) {
384                                $R->set($j, $i, $this->A[$i][$j]);
385                        }
386                }
387                return $R;
388        }       //      function transpose()
389
390
391        /**
392         *      trace
393         *
394         *      Sum of diagonal elements
395         *      @return float Sum of diagonal elements
396         */
397        public function trace() {
398                $s = 0;
399                $n = min($this->m, $this->n);
400                for($i = 0; $i < $n; ++$i) {
401                        $s += $this->A[$i][$i];
402                }
403                return $s;
404        }       //      function trace()
405
406
407        /**
408         *      uminus
409         *
410         *      Unary minus matrix -A
411         *      @return Matrix Unary minus matrix
412         */
413        public function uminus() {
414        }       //      function uminus()
415
416
417        /**
418         *      plus
419         *
420         *      A + B
421         *      @param mixed $B Matrix/Array
422         *      @return Matrix Sum
423         */
424        public function plus() {
425                if (func_num_args() > 0) {
426                        $args = func_get_args();
427                        $match = implode(",", array_map('gettype', $args));
428
429                        switch($match) {
430                                case 'object':
431                                                if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }
432                                                break;
433                                case 'array':
434                                                $M = new PHPExcel_Shared_JAMA_Matrix($args[0]);
435                                                break;
436                                default:
437                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
438                                                break;
439                        }
440                        $this->checkMatrixDimensions($M);
441                        for($i = 0; $i < $this->m; ++$i) {
442                                for($j = 0; $j < $this->n; ++$j) {
443                                        $M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]);
444                                }
445                        }
446                        return $M;
447                } else {
448                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
449                }
450        }       //      function plus()
451
452
453        /**
454         *      plusEquals
455         *
456         *      A = A + B
457         *      @param mixed $B Matrix/Array
458         *      @return Matrix Sum
459         */
460        public function plusEquals() {
461                if (func_num_args() > 0) {
462                        $args = func_get_args();
463                        $match = implode(",", array_map('gettype', $args));
464
465                        switch($match) {
466                                case 'object':
467                                                if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }
468                                                break;
469                                case 'array':
470                                                $M = new PHPExcel_Shared_JAMA_Matrix($args[0]);
471                                                break;
472                                default:
473                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
474                                                break;
475                        }
476                        $this->checkMatrixDimensions($M);
477                        for($i = 0; $i < $this->m; ++$i) {
478                                for($j = 0; $j < $this->n; ++$j) {
479                                        $validValues = True;
480                                        $value = $M->get($i, $j);
481                                        if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
482                                                $this->A[$i][$j] = trim($this->A[$i][$j],'"');
483                                                $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]);
484                                        }
485                                        if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
486                                                $value = trim($value,'"');
487                                                $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value);
488                                        }
489                                        if ($validValues) {
490                                                $this->A[$i][$j] += $value;
491                                        } else {
492                                                $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN();
493                                        }
494                                }
495                        }
496                        return $this;
497                } else {
498                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
499                }
500        }       //      function plusEquals()
501
502
503        /**
504         *      minus
505         *
506         *      A - B
507         *      @param mixed $B Matrix/Array
508         *      @return Matrix Sum
509         */
510        public function minus() {
511                if (func_num_args() > 0) {
512                        $args = func_get_args();
513                        $match = implode(",", array_map('gettype', $args));
514
515                        switch($match) {
516                                case 'object':
517                                                if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }
518                                                break;
519                                case 'array':
520                                                $M = new PHPExcel_Shared_JAMA_Matrix($args[0]);
521                                                break;
522                                default:
523                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
524                                                break;
525                        }
526                        $this->checkMatrixDimensions($M);
527                        for($i = 0; $i < $this->m; ++$i) {
528                                for($j = 0; $j < $this->n; ++$j) {
529                                        $M->set($i, $j, $M->get($i, $j) - $this->A[$i][$j]);
530                                }
531                        }
532                        return $M;
533                } else {
534                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
535                }
536        }       //      function minus()
537
538
539        /**
540         *      minusEquals
541         *
542         *      A = A - B
543         *      @param mixed $B Matrix/Array
544         *      @return Matrix Sum
545         */
546        public function minusEquals() {
547                if (func_num_args() > 0) {
548                        $args = func_get_args();
549                        $match = implode(",", array_map('gettype', $args));
550
551                        switch($match) {
552                                case 'object':
553                                                if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }
554                                                break;
555                                case 'array':
556                                                $M = new PHPExcel_Shared_JAMA_Matrix($args[0]);
557                                                break;
558                                default:
559                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
560                                                break;
561                        }
562                        $this->checkMatrixDimensions($M);
563                        for($i = 0; $i < $this->m; ++$i) {
564                                for($j = 0; $j < $this->n; ++$j) {
565                                        $validValues = True;
566                                        $value = $M->get($i, $j);
567                                        if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
568                                                $this->A[$i][$j] = trim($this->A[$i][$j],'"');
569                                                $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]);
570                                        }
571                                        if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
572                                                $value = trim($value,'"');
573                                                $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value);
574                                        }
575                                        if ($validValues) {
576                                                $this->A[$i][$j] -= $value;
577                                        } else {
578                                                $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN();
579                                        }
580                                }
581                        }
582                        return $this;
583                } else {
584                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
585                }
586        }       //      function minusEquals()
587
588
589        /**
590         *      arrayTimes
591         *
592         *      Element-by-element multiplication
593         *      Cij = Aij * Bij
594         *      @param mixed $B Matrix/Array
595         *      @return Matrix Matrix Cij
596         */
597        public function arrayTimes() {
598                if (func_num_args() > 0) {
599                        $args = func_get_args();
600                        $match = implode(",", array_map('gettype', $args));
601
602                        switch($match) {
603                                case 'object':
604                                                if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }
605                                                break;
606                                case 'array':
607                                                $M = new PHPExcel_Shared_JAMA_Matrix($args[0]);
608                                                break;
609                                default:
610                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
611                                                break;
612                        }
613                        $this->checkMatrixDimensions($M);
614                        for($i = 0; $i < $this->m; ++$i) {
615                                for($j = 0; $j < $this->n; ++$j) {
616                                        $M->set($i, $j, $M->get($i, $j) * $this->A[$i][$j]);
617                                }
618                        }
619                        return $M;
620                } else {
621                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
622                }
623        }       //      function arrayTimes()
624
625
626        /**
627         *      arrayTimesEquals
628         *
629         *      Element-by-element multiplication
630         *      Aij = Aij * Bij
631         *      @param mixed $B Matrix/Array
632         *      @return Matrix Matrix Aij
633         */
634        public function arrayTimesEquals() {
635                if (func_num_args() > 0) {
636                        $args = func_get_args();
637                        $match = implode(",", array_map('gettype', $args));
638
639                        switch($match) {
640                                case 'object':
641                                                if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }
642                                                break;
643                                case 'array':
644                                                $M = new PHPExcel_Shared_JAMA_Matrix($args[0]);
645                                                break;
646                                default:
647                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
648                                                break;
649                        }
650                        $this->checkMatrixDimensions($M);
651                        for($i = 0; $i < $this->m; ++$i) {
652                                for($j = 0; $j < $this->n; ++$j) {
653                                        $validValues = True;
654                                        $value = $M->get($i, $j);
655                                        if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
656                                                $this->A[$i][$j] = trim($this->A[$i][$j],'"');
657                                                $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]);
658                                        }
659                                        if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
660                                                $value = trim($value,'"');
661                                                $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value);
662                                        }
663                                        if ($validValues) {
664                                                $this->A[$i][$j] *= $value;
665                                        } else {
666                                                $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN();
667                                        }
668                                }
669                        }
670                        return $this;
671                } else {
672                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
673                }
674        }       //      function arrayTimesEquals()
675
676
677        /**
678         *      arrayRightDivide
679         *
680         *      Element-by-element right division
681         *      A / B
682         *      @param Matrix $B Matrix B
683         *      @return Matrix Division result
684         */
685        public function arrayRightDivide() {
686                if (func_num_args() > 0) {
687                        $args = func_get_args();
688                        $match = implode(",", array_map('gettype', $args));
689
690                        switch($match) {
691                                case 'object':
692                                                if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }
693                                                break;
694                                case 'array':
695                                                $M = new PHPExcel_Shared_JAMA_Matrix($args[0]);
696                                                break;
697                                default:
698                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
699                                                break;
700                        }
701                        $this->checkMatrixDimensions($M);
702                        for($i = 0; $i < $this->m; ++$i) {
703                                for($j = 0; $j < $this->n; ++$j) {
704                                        $validValues = True;
705                                        $value = $M->get($i, $j);
706                                        if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
707                                                $this->A[$i][$j] = trim($this->A[$i][$j],'"');
708                                                $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]);
709                                        }
710                                        if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
711                                                $value = trim($value,'"');
712                                                $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value);
713                                        }
714                                        if ($validValues) {
715                                                if ($value == 0) {
716                                                        //      Trap for Divide by Zero error
717                                                        $M->set($i, $j, '#DIV/0!');
718                                                } else {
719                                                        $M->set($i, $j, $this->A[$i][$j] / $value);
720                                                }
721                                        } else {
722                                                $M->set($i, $j, PHPExcel_Calculation_Functions::NaN());
723                                        }
724                                }
725                        }
726                        return $M;
727                } else {
728                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
729                }
730        }       //      function arrayRightDivide()
731
732
733        /**
734         *      arrayRightDivideEquals
735         *
736         *      Element-by-element right division
737         *      Aij = Aij / Bij
738         *      @param mixed $B Matrix/Array
739         *      @return Matrix Matrix Aij
740         */
741        public function arrayRightDivideEquals() {
742                if (func_num_args() > 0) {
743                        $args = func_get_args();
744                        $match = implode(",", array_map('gettype', $args));
745
746                        switch($match) {
747                                case 'object':
748                                                if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }
749                                                break;
750                                case 'array':
751                                                $M = new PHPExcel_Shared_JAMA_Matrix($args[0]);
752                                                break;
753                                default:
754                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
755                                                break;
756                        }
757                        $this->checkMatrixDimensions($M);
758                        for($i = 0; $i < $this->m; ++$i) {
759                                for($j = 0; $j < $this->n; ++$j) {
760                                        $this->A[$i][$j] = $this->A[$i][$j] / $M->get($i, $j);
761                                }
762                        }
763                        return $M;
764                } else {
765                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
766                }
767        }       //      function arrayRightDivideEquals()
768
769
770        /**
771         *      arrayLeftDivide
772         *
773         *      Element-by-element Left division
774         *      A / B
775         *      @param Matrix $B Matrix B
776         *      @return Matrix Division result
777         */
778        public function arrayLeftDivide() {
779                if (func_num_args() > 0) {
780                        $args = func_get_args();
781                        $match = implode(",", array_map('gettype', $args));
782
783                        switch($match) {
784                                case 'object':
785                                                if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }
786                                                break;
787                                case 'array':
788                                                $M = new PHPExcel_Shared_JAMA_Matrix($args[0]);
789                                                break;
790                                default:
791                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
792                                                break;
793                        }
794                        $this->checkMatrixDimensions($M);
795                        for($i = 0; $i < $this->m; ++$i) {
796                                for($j = 0; $j < $this->n; ++$j) {
797                                        $M->set($i, $j, $M->get($i, $j) / $this->A[$i][$j]);
798                                }
799                        }
800                        return $M;
801                } else {
802                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
803                }
804        }       //      function arrayLeftDivide()
805
806
807        /**
808         *      arrayLeftDivideEquals
809         *
810         *      Element-by-element Left division
811         *      Aij = Aij / Bij
812         *      @param mixed $B Matrix/Array
813         *      @return Matrix Matrix Aij
814         */
815        public function arrayLeftDivideEquals() {
816                if (func_num_args() > 0) {
817                        $args = func_get_args();
818                        $match = implode(",", array_map('gettype', $args));
819
820                        switch($match) {
821                                case 'object':
822                                                if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }
823                                                break;
824                                case 'array':
825                                                $M = new PHPExcel_Shared_JAMA_Matrix($args[0]);
826                                                break;
827                                default:
828                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
829                                                break;
830                        }
831                        $this->checkMatrixDimensions($M);
832                        for($i = 0; $i < $this->m; ++$i) {
833                                for($j = 0; $j < $this->n; ++$j) {
834                                        $this->A[$i][$j] = $M->get($i, $j) / $this->A[$i][$j];
835                                }
836                        }
837                        return $M;
838                } else {
839                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
840                }
841        }       //      function arrayLeftDivideEquals()
842
843
844        /**
845         *      times
846         *
847         *      Matrix multiplication
848         *      @param mixed $n Matrix/Array/Scalar
849         *      @return Matrix Product
850         */
851        public function times() {
852                if (func_num_args() > 0) {
853                        $args  = func_get_args();
854                        $match = implode(",", array_map('gettype', $args));
855
856                        switch($match) {
857                                case 'object':
858                                                if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $B = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }
859                                                if ($this->n == $B->m) {
860                                                        $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n);
861                                                        for($j = 0; $j < $B->n; ++$j) {
862                                                                for ($k = 0; $k < $this->n; ++$k) {
863                                                                        $Bcolj[$k] = $B->A[$k][$j];
864                                                                }
865                                                                for($i = 0; $i < $this->m; ++$i) {
866                                                                        $Arowi = $this->A[$i];
867                                                                        $s = 0;
868                                                                        for($k = 0; $k < $this->n; ++$k) {
869                                                                                $s += $Arowi[$k] * $Bcolj[$k];
870                                                                        }
871                                                                        $C->A[$i][$j] = $s;
872                                                                }
873                                                        }
874                                                        return $C;
875                                                } else {
876                                                        throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch));
877                                                }
878                                                break;
879                                case 'array':
880                                                $B = new PHPExcel_Shared_JAMA_Matrix($args[0]);
881                                                if ($this->n == $B->m) {
882                                                        $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n);
883                                                        for($i = 0; $i < $C->m; ++$i) {
884                                                                for($j = 0; $j < $C->n; ++$j) {
885                                                                        $s = "0";
886                                                                        for($k = 0; $k < $C->n; ++$k) {
887                                                                                $s += $this->A[$i][$k] * $B->A[$k][$j];
888                                                                        }
889                                                                        $C->A[$i][$j] = $s;
890                                                                }
891                                                        }
892                                                        return $C;
893                                                } else {
894                                                        throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch));
895                                                }
896                                                return $M;
897                                                break;
898                                case 'integer':
899                                                $C = new PHPExcel_Shared_JAMA_Matrix($this->A);
900                                                for($i = 0; $i < $C->m; ++$i) {
901                                                        for($j = 0; $j < $C->n; ++$j) {
902                                                                $C->A[$i][$j] *= $args[0];
903                                                        }
904                                                }
905                                                return $C;
906                                                break;
907                                case 'double':
908                                                $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $this->n);
909                                                for($i = 0; $i < $C->m; ++$i) {
910                                                        for($j = 0; $j < $C->n; ++$j) {
911                                                                $C->A[$i][$j] = $args[0] * $this->A[$i][$j];
912                                                        }
913                                                }
914                                                return $C;
915                                                break;
916                                case 'float':
917                                                $C = new PHPExcel_Shared_JAMA_Matrix($this->A);
918                                                for($i = 0; $i < $C->m; ++$i) {
919                                                        for($j = 0; $j < $C->n; ++$j) {
920                                                                $C->A[$i][$j] *= $args[0];
921                                                        }
922                                                }
923                                                return $C;
924                                                break;
925                                default:
926                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
927                                                break;
928                        }
929                } else {
930                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
931                }
932        }       //      function times()
933
934
935        /**
936         *      power
937         *
938         *      A = A ^ B
939         *      @param mixed $B Matrix/Array
940         *      @return Matrix Sum
941         */
942        public function power() {
943                if (func_num_args() > 0) {
944                        $args = func_get_args();
945                        $match = implode(",", array_map('gettype', $args));
946
947                        switch($match) {
948                                case 'object':
949                                                if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }
950                                                break;
951                                case 'array':
952                                                $M = new PHPExcel_Shared_JAMA_Matrix($args[0]);
953                                                break;
954                                default:
955                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
956                                                break;
957                        }
958                        $this->checkMatrixDimensions($M);
959                        for($i = 0; $i < $this->m; ++$i) {
960                                for($j = 0; $j < $this->n; ++$j) {
961                                        $validValues = True;
962                                        $value = $M->get($i, $j);
963                                        if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
964                                                $this->A[$i][$j] = trim($this->A[$i][$j],'"');
965                                                $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]);
966                                        }
967                                        if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
968                                                $value = trim($value,'"');
969                                                $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value);
970                                        }
971                                        if ($validValues) {
972                                                $this->A[$i][$j] = pow($this->A[$i][$j],$value);
973                                        } else {
974                                                $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN();
975                                        }
976                                }
977                        }
978                        return $this;
979                } else {
980                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
981                }
982        }       //      function power()
983
984
985        /**
986         *      concat
987         *
988         *      A = A & B
989         *      @param mixed $B Matrix/Array
990         *      @return Matrix Sum
991         */
992        public function concat() {
993                if (func_num_args() > 0) {
994                        $args = func_get_args();
995                        $match = implode(",", array_map('gettype', $args));
996
997                        switch($match) {
998                                case 'object':
999                                                if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }
1000                                case 'array':
1001                                                $M = new PHPExcel_Shared_JAMA_Matrix($args[0]);
1002                                                break;
1003                                default:
1004                                                throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
1005                                                break;
1006                        }
1007                        $this->checkMatrixDimensions($M);
1008                        for($i = 0; $i < $this->m; ++$i) {
1009                                for($j = 0; $j < $this->n; ++$j) {
1010                                        $this->A[$i][$j] = trim($this->A[$i][$j],'"').trim($M->get($i, $j),'"');
1011                                }
1012                        }
1013                        return $this;
1014                } else {
1015                        throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);
1016                }
1017        }       //      function concat()
1018
1019
1020        /**
1021         *      Solve A*X = B.
1022         *
1023         *      @param Matrix $B Right hand side
1024         *      @return Matrix ... Solution if A is square, least squares solution otherwise
1025         */
1026        public function solve($B) {
1027                if ($this->m == $this->n) {
1028                        $LU = new PHPExcel_Shared_JAMA_LUDecomposition($this);
1029                        return $LU->solve($B);
1030                } else {
1031                        $QR = new QRDecomposition($this);
1032                        return $QR->solve($B);
1033                }
1034        }       //      function solve()
1035
1036
1037        /**
1038         *      Matrix inverse or pseudoinverse.
1039         *
1040         *      @return Matrix ... Inverse(A) if A is square, pseudoinverse otherwise.
1041         */
1042        public function inverse() {
1043                return $this->solve($this->identity($this->m, $this->m));
1044        }       //      function inverse()
1045
1046
1047        /**
1048         *      det
1049         *
1050         *      Calculate determinant
1051         *      @return float Determinant
1052         */
1053        public function det() {
1054                $L = new PHPExcel_Shared_JAMA_LUDecomposition($this);
1055                return $L->det();
1056        }       //      function det()
1057
1058
1059}       //      class PHPExcel_Shared_JAMA_Matrix
Note: See TracBrowser for help on using the repository browser.