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