[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/phpexcel/PHPExcel/Shared/JAMA/ -> Matrix.php (source)

   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  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1