예제 #1
0
 public function testMatrixGetReturnsCorrectValue()
 {
     $testArray = array(array(1, 2, 3), array(0, 2, 1), array(2.5, 1, 3));
     $this->object = new RationalMatrix($testArray);
     for ($r = 1; $r < 4; $r++) {
         for ($c = 1; $c < 4; $c++) {
             $this->assertEquals(RationalTypeFactory::create($testArray[$r - 1][$c - 1]), $this->object->get($r, $c));
         }
     }
 }
예제 #2
0
파일: Matrix.php 프로젝트: hoenirvili/cn
 /**
  * Multiply the given matrices.
  *
  * @param matrix  left matrix
  * @param matrix  right matrix
  * @return  matrix product matrix $a*$b
  */
 public static function multiply($a, $b)
 {
     // First check dimensions.
     new Assertion($a instanceof Matrix, 'Given first matrix not of class Matrix.');
     new Assertion($b instanceof Matrix, 'Given second matrix not of class Matrix.');
     new Assertion($a->columns() == $b->rows(), 'Given dimensions are not compatible.');
     $c = new Matrix($a->rows(), $b->columns());
     $c->setAll(0.0);
     for ($i = 0; $i < $a->rows(); $i++) {
         for ($j = 0; $j < $b->columns(); $j++) {
             for ($k = 0; $k < $a->columns(); $k++) {
                 $c->set($i, $j, $c->get($i, $j) + $a->get($i, $k) * $b->get($k, $j));
             }
         }
     }
     return $c;
 }
예제 #3
0
파일: Matrix.php 프로젝트: Gyebro/rajzteszt
 /**
  * plus
  * A + B
  * @param mixed $B Matrix/Array 
  * @return Matrix Sum
  */
 function plus()
 {
     if (func_num_args() > 0) {
         $args = func_get_args();
         $match = implode(",", array_map('gettype', $args));
         switch ($match) {
             case 'object':
                 $M = is_a($args[0], 'Matrix') ? $args[0] : trigger_error(ArgumentTypeException, ERROR);
                 //$this->checkMatrixDimensions($M);
                 for ($i = 0; $i < $this->m; $i++) {
                     for ($j = 0; $j < $this->n; $j++) {
                         $M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]);
                     }
                 }
                 return $M;
                 break;
             case 'array':
                 $M = new Matrix($args[0]);
                 //$this->checkMatrixDimensions($M);
                 for ($i = 0; $i < $this->m; $i++) {
                     for ($j = 0; $j < $this->n; $j++) {
                         $M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]);
                     }
                 }
                 return $M;
                 break;
             default:
                 trigger_error(PolymorphicArgumentException, ERROR);
                 break;
         }
     } else {
         trigger_error(PolymorphicArgumentException, ERROR);
     }
 }
예제 #4
0
 /**
  *	setMatrix
  *
  *	Set a submatrix
  *	@param int $i0 Initial row index
  *	@param int $j0 Initial column index
  *	@param mixed $S Matrix/Array submatrix
  *	($i0, $j0, $S) $S = Matrix
  *	($i0, $j0, $S) $S = Array
  */
 public function setMatrix()
 {
     if (func_num_args() > 0) {
         $args = func_get_args();
         $match = implode(",", array_map('gettype', $args));
         switch ($match) {
             case 'integer,integer,object':
                 if ($args[2] instanceof Matrix) {
                     $M = $args[2];
                 } else {
                     throw new Exception(JAMAError(ArgumentTypeException));
                 }
                 if ($args[0] + $M->m <= $this->m) {
                     $i0 = $args[0];
                 } else {
                     throw new Exception(JAMAError(ArgumentBoundsException));
                 }
                 if ($args[1] + $M->n <= $this->n) {
                     $j0 = $args[1];
                 } else {
                     throw new Exception(JAMAError(ArgumentBoundsException));
                 }
                 for ($i = $i0; $i < $i0 + $M->m; ++$i) {
                     for ($j = $j0; $j < $j0 + $M->n; ++$j) {
                         $this->A[$i][$j] = $M->get($i - $i0, $j - $j0);
                     }
                 }
                 break;
             case 'integer,integer,array':
                 $M = new Matrix($args[2]);
                 if ($args[0] + $M->m <= $this->m) {
                     $i0 = $args[0];
                 } else {
                     throw new Exception(JAMAError(ArgumentBoundsException));
                 }
                 if ($args[1] + $M->n <= $this->n) {
                     $j0 = $args[1];
                 } else {
                     throw new Exception(JAMAError(ArgumentBoundsException));
                 }
                 for ($i = $i0; $i < $i0 + $M->m; ++$i) {
                     for ($j = $j0; $j < $j0 + $M->n; ++$j) {
                         $this->A[$i][$j] = $M->get($i - $i0, $j - $j0);
                     }
                 }
                 break;
             default:
                 throw new Exception(JAMAError(PolymorphicArgumentException));
                 break;
         }
     } else {
         throw new Exception(JAMAError(PolymorphicArgumentException));
     }
 }
예제 #5
0
 function TestMatrix()
 {
     // define test variables
     $errorCount = 0;
     $warningCount = 0;
     $columnwise = array(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);
     $rowwise = array(1.0, 4.0, 7.0, 10.0, 2.0, 5.0, 8.0, 11.0, 3.0, 6.0, 9.0, 12.0);
     $avals = array(array(1.0, 4.0, 7.0, 10.0), array(2.0, 5.0, 8.0, 11.0), array(3.0, 6.0, 9.0, 12.0));
     $rankdef = $avals;
     $tvals = array(array(1.0, 2.0, 3.0), array(4.0, 5.0, 6.0), array(7.0, 8.0, 9.0), array(10.0, 11.0, 12.0));
     $subavals = array(array(5.0, 8.0, 11.0), array(6.0, 9.0, 12.0));
     $rvals = array(array(1.0, 4.0, 7.0), array(2.0, 5.0, 8.0, 11.0), array(3.0, 6.0, 9.0, 12.0));
     $pvals = array(array(1.0, 1.0, 1.0), array(1.0, 2.0, 3.0), array(1.0, 3.0, 6.0));
     $ivals = array(array(1.0, 0.0, 0.0, 0.0), array(0.0, 1.0, 0.0, 0.0), array(0.0, 0.0, 1.0, 0.0));
     $evals = array(array(0.0, 1.0, 0.0, 0.0), array(1.0, 0.0, 2.0E-7, 0.0), array(0.0, -2.0E-7, 0.0, 1.0), array(0.0, 0.0, 1.0, 0.0));
     $square = array(array(166.0, 188.0, 210.0), array(188.0, 214.0, 240.0), array(210.0, 240.0, 270.0));
     $sqSolution = array(array(13.0), array(15.0));
     $condmat = array(array(1.0, 3.0), array(7.0, 9.0));
     $rows = 3;
     $cols = 4;
     $invalidID = 5;
     /* should trigger bad shape for construction with val        */
     $raggedr = 0;
     /* (raggedr,raggedc) should be out of bounds in ragged array */
     $raggedc = 4;
     $validID = 3;
     /* leading dimension of intended test Matrices               */
     $nonconformld = 4;
     /* leading dimension which is valid, but nonconforming       */
     $ib = 1;
     /* index ranges for sub Matrix                               */
     $ie = 2;
     $jb = 1;
     $je = 3;
     $rowindexset = array(1, 2);
     $badrowindexset = array(1, 3);
     $columnindexset = array(1, 2, 3);
     $badcolumnindexset = array(1, 2, 4);
     $columnsummax = 33.0;
     $rowsummax = 30.0;
     $sumofdiagonals = 15;
     $sumofsquares = 650;
     /**
      * Test matrix methods
      */
     /**
      * Constructors and constructor-like methods:
      *
      *   Matrix(double[], int)
      *   Matrix(double[][])
      *   Matrix(int, int)
      *   Matrix(int, int, double)
      *   Matrix(int, int, double[][])
      *   constructWithCopy(double[][])
      *   random(int,int)
      *   identity(int)
      */
     echo "<p>Testing constructors and constructor-like methods...</p>";
     $A = new Matrix($columnwise, 3);
     if ($A instanceof Matrix) {
         $this->try_success("Column-packed constructor...");
     } else {
         $errorCount = $this->try_failure($errorCount, "Column-packed constructor...", "Unable to construct Matrix");
     }
     $T = new Matrix($tvals);
     if ($T instanceof Matrix) {
         $this->try_success("2D array constructor...");
     } else {
         $errorCount = $this->try_failure($errorCount, "2D array constructor...", "Unable to construct Matrix");
     }
     $A = new Matrix($columnwise, $validID);
     $B = new Matrix($avals);
     $tmp = $B->get(0, 0);
     $avals[0][0] = 0.0;
     $C = $B->minus($A);
     $avals[0][0] = $tmp;
     $B = Matrix::constructWithCopy($avals);
     $tmp = $B->get(0, 0);
     $avals[0][0] = 0.0;
     /** check that constructWithCopy behaves properly **/
     if ($tmp - $B->get(0, 0) != 0.0) {
         $errorCount = $this->try_failure($errorCount, "constructWithCopy... ", "copy not effected... data visible outside");
     } else {
         $this->try_success("constructWithCopy... ", "");
     }
     $I = new Matrix($ivals);
     if ($this->checkMatrices($I, Matrix::identity(3, 4))) {
         $this->try_success("identity... ", "");
     } else {
         $errorCount = $this->try_failure($errorCount, "identity... ", "identity Matrix not successfully created");
     }
     /**
      * Access Methods:
      *
      *   getColumnDimension()
      *   getRowDimension()
      *   getArray()
      *   getArrayCopy()
      *   getColumnPackedCopy()
      *   getRowPackedCopy()
      *   get(int,int)
      *   getMatrix(int,int,int,int)
      *   getMatrix(int,int,int[])
      *   getMatrix(int[],int,int)
      *   getMatrix(int[],int[])
      *   set(int,int,double)
      *   setMatrix(int,int,int,int,Matrix)
      *   setMatrix(int,int,int[],Matrix)
      *   setMatrix(int[],int,int,Matrix)
      *   setMatrix(int[],int[],Matrix)
      */
     print "<p>Testing access methods...</p>";
     $B = new Matrix($avals);
     if ($B->getRowDimension() == $rows) {
         $this->try_success("getRowDimension...");
     } else {
         $errorCount = $this->try_failure($errorCount, "getRowDimension...");
     }
     if ($B->getColumnDimension() == $cols) {
         $this->try_success("getColumnDimension...");
     } else {
         $errorCount = $this->try_failure($errorCount, "getColumnDimension...");
     }
     $barray = $B->getArray();
     if ($this->checkArrays($barray, $avals)) {
         $this->try_success("getArray...");
     } else {
         $errorCount = $this->try_failure($errorCount, "getArray...");
     }
     $bpacked = $B->getColumnPackedCopy();
     if ($this->checkArrays($bpacked, $columnwise)) {
         $this->try_success("getColumnPackedCopy...");
     } else {
         $errorCount = $this->try_failure($errorCount, "getColumnPackedCopy...");
     }
     $bpacked = $B->getRowPackedCopy();
     if ($this->checkArrays($bpacked, $rowwise)) {
         $this->try_success("getRowPackedCopy...");
     } else {
         $errorCount = $this->try_failure($errorCount, "getRowPackedCopy...");
     }
     /**
      * Array-like methods:
      *   minus
      *   minusEquals
      *   plus
      *   plusEquals
      *   arrayLeftDivide
      *   arrayLeftDivideEquals
      *   arrayRightDivide
      *   arrayRightDivideEquals
      *   arrayTimes
      *   arrayTimesEquals
      *   uminus
      */
     print "<p>Testing array-like methods...</p>";
     /**
      * I/O methods:
      *   read
      *   print
      *   serializable:
      *   writeObject
      *   readObject
      */
     print "<p>Testing I/O methods...</p>";
     /**
      * Test linear algebra methods
      */
     echo "<p>Testing linear algebra methods...<p>";
     $A = new Matrix($columnwise, 3);
     if ($this->checkMatrices($A->transpose(), $T)) {
         $this->try_success("Transpose check...");
     } else {
         $errorCount = $this->try_failure($errorCount, "Transpose check...", "Matrices are not equal");
     }
     if ($this->checkScalars($A->norm1(), $columnsummax)) {
         $this->try_success("Maximum column sum...");
     } else {
         $errorCount = $this->try_failure($errorCount, "Maximum column sum...", "Incorrect: " . $A->norm1() . " != " . $columnsummax);
     }
     if ($this->checkScalars($A->normInf(), $rowsummax)) {
         $this->try_success("Maximum row sum...");
     } else {
         $errorCount = $this->try_failure($errorCount, "Maximum row sum...", "Incorrect: " . $A->normInf() . " != " . $rowsummax);
     }
     if ($this->checkScalars($A->normF(), sqrt($sumofsquares))) {
         $this->try_success("Frobenius norm...");
     } else {
         $errorCount = $this->try_failure($errorCount, "Frobenius norm...", "Incorrect:" . $A->normF() . " != " . sqrt($sumofsquares));
     }
     if ($this->checkScalars($A->trace(), $sumofdiagonals)) {
         $this->try_success("Matrix trace...");
     } else {
         $errorCount = $this->try_failure($errorCount, "Matrix trace...", "Incorrect: " . $A->trace() . " != " . $sumofdiagonals);
     }
     $B = $A->getMatrix(0, $A->getRowDimension(), 0, $A->getRowDimension());
     if ($B->det() == 0) {
         $this->try_success("Matrix determinant...");
     } else {
         $errorCount = $this->try_failure($errorCount, "Matrix determinant...", "Incorrect: " . $B->det() . " != " . 0);
     }
     $A = new Matrix($columnwise, 3);
     $SQ = new Matrix($square);
     if ($this->checkMatrices($SQ, $A->times($A->transpose()))) {
         $this->try_success("times(Matrix)...");
     } else {
         $errorCount = $this->try_failure($errorCount, "times(Matrix)...", "Unable to multiply matrices");
         $SQ->toHTML();
         $AT->toHTML();
     }
     $A = new Matrix($columnwise, 4);
     $QR = $A->qr();
     $R = $QR->getR();
     $Q = $QR->getQ();
     if ($this->checkMatrices($A, $Q->times($R))) {
         $this->try_success("QRDecomposition...", "");
     } else {
         $errorCount = $this->try_failure($errorCount, "QRDecomposition...", "incorrect qr decomposition calculation");
     }
     $A = new Matrix($columnwise, 4);
     $SVD = $A->svd();
     $U = $SVD->getU();
     $S = $SVD->getS();
     $V = $SVD->getV();
     if ($this->checkMatrices($A, $U->times($S->times($V->transpose())))) {
         $this->try_success("SingularValueDecomposition...", "");
     } else {
         $errorCount = $this->try_failure($errorCount, "SingularValueDecomposition...", "incorrect singular value decomposition calculation");
     }
     $n = $A->getColumnDimension();
     $A = $A->getMatrix(0, $n - 1, 0, $n - 1);
     $A->set(0, 0, 0.0);
     $LU = $A->lu();
     $L = $LU->getL();
     if ($this->checkMatrices($A->getMatrix($LU->getPivot(), 0, $n - 1), $L->times($LU->getU()))) {
         $this->try_success("LUDecomposition...", "");
     } else {
         $errorCount = $this->try_failure($errorCount, "LUDecomposition...", "incorrect LU decomposition calculation");
     }
     $X = $A->inverse();
     if ($this->checkMatrices($A->times($X), Matrix::identity(3, 3))) {
         $this->try_success("inverse()...", "");
     } else {
         $errorCount = $this->try_failure($errorCount, "inverse()...", "incorrect inverse calculation");
     }
     $DEF = new Matrix($rankdef);
     if ($this->checkScalars($DEF->rank(), min($DEF->getRowDimension(), $DEF->getColumnDimension()) - 1)) {
         $this->try_success("Rank...");
     } else {
         $this->try_failure("Rank...", "incorrect rank calculation");
     }
     $B = new Matrix($condmat);
     $SVD = $B->svd();
     $singularvalues = $SVD->getSingularValues();
     if ($this->checkScalars($B->cond(), $singularvalues[0] / $singularvalues[min($B->getRowDimension(), $B->getColumnDimension()) - 1])) {
         $this->try_success("Condition number...");
     } else {
         $this->try_failure("Condition number...", "incorrect condition number calculation");
     }
     $SUB = new Matrix($subavals);
     $O = new Matrix($SUB->getRowDimension(), 1, 1.0);
     $SOL = new Matrix($sqSolution);
     $SQ = $SUB->getMatrix(0, $SUB->getRowDimension() - 1, 0, $SUB->getRowDimension() - 1);
     if ($this->checkMatrices($SQ->solve($SOL), $O)) {
         $this->try_success("solve()...", "");
     } else {
         $errorCount = $this->try_failure($errorCount, "solve()...", "incorrect lu solve calculation");
     }
     $A = new Matrix($pvals);
     $Chol = $A->chol();
     $L = $Chol->getL();
     if ($this->checkMatrices($A, $L->times($L->transpose()))) {
         $this->try_success("CholeskyDecomposition...", "");
     } else {
         $errorCount = $this->try_failure($errorCount, "CholeskyDecomposition...", "incorrect Cholesky decomposition calculation");
     }
     $X = $Chol->solve(Matrix::identity(3, 3));
     if ($this->checkMatrices($A->times($X), Matrix::identity(3, 3))) {
         $this->try_success("CholeskyDecomposition solve()...", "");
     } else {
         $errorCount = $this->try_failure($errorCount, "CholeskyDecomposition solve()...", "incorrect Choleskydecomposition solve calculation");
     }
     $Eig = $A->eig();
     $D = $Eig->getD();
     $V = $Eig->getV();
     if ($this->checkMatrices($A->times($V), $V->times($D))) {
         $this->try_success("EigenvalueDecomposition (symmetric)...", "");
     } else {
         $errorCount = $this->try_failure($errorCount, "EigenvalueDecomposition (symmetric)...", "incorrect symmetric Eigenvalue decomposition calculation");
     }
     $A = new Matrix($evals);
     $Eig = $A->eig();
     $D = $Eig->getD();
     $V = $Eig->getV();
     if ($this->checkMatrices($A->times($V), $V->times($D))) {
         $this->try_success("EigenvalueDecomposition (nonsymmetric)...", "");
     } else {
         $errorCount = $this->try_failure($errorCount, "EigenvalueDecomposition (nonsymmetric)...", "incorrect nonsymmetric Eigenvalue decomposition calculation");
     }
     print "<b>{$errorCount} total errors</b>.";
 }
예제 #6
0
파일: QRGivens.php 프로젝트: hoenirvili/cn
 /**
  * Assembles Q using the single givens rotations.
  * 
  * @return  matrix  Q
  */
 public function getQ()
 {
     // Q is an mxm matrix if m is the maximum of the number of rows and thenumber of columns.
     $m = max($this->_matrix->columns(), $this->_matrix->rows());
     $Q = new Matrix($m, $m);
     $Q->setAll(0.0);
     // Begin with the identity matrix.
     for ($i = 0; $i < $Q->rows(); $i++) {
         $Q->set($i, $i, 1.0);
     }
     for ($j = $this->_matrix->columns() - 1; $j >= 0; $j--) {
         for ($i = $this->_matrix->rows() - 1; $i > $j; $i--) {
             // Get c and s which are stored in the i-th row, j-th column.
             $aij = $this->_matrix->get($i, $j);
             $c = 0;
             $s = 0;
             if ($aij == 0) {
                 $c = 0.0;
                 $s = 1.0;
             } else {
                 if (abs($aij) < 1) {
                     $s = 2.0 * abs($aij);
                     $c = sqrt(1 - pow($s, 2));
                     if ($aij < 0) {
                         $c = -$c;
                     }
                 } else {
                     $c = 2.0 / $aij;
                     $s = sqrt(1 - pow($c, 2));
                 }
             }
             for ($k = 0; $k < $this->_matrix->columns(); $k++) {
                 $jk = $Q->get($j, $k);
                 $ik = $Q->get($i, $k);
                 $Q->set($j, $k, $c * $jk - $s * $ik);
                 $Q->set($i, $k, $s * $jk + $c * $ik);
             }
         }
     }
     return $Q;
 }
예제 #7
0
 /**
  * Assembles Q using the single givens rotations.
  * 
  * @return  matrix  Q
  */
 public function getQ()
 {
     // Q is an m x m matrix if m is the maximum of the number of rows and thenumber of columns.
     $m = max($this->_matrix->columns(), $this->_matrix->rows());
     $Q = new Matrix($m, $m);
     $Q->setAll(0.0);
     // Begin with the identity matrix.
     for ($i = 0; $i < min($Q->rows(), $Q->columns()); $i++) {
         $Q->set($i, $i, 1.0);
     }
     // Got backwards through all householder transformations and apply them on
     for ($k = $this->_matrix->columns() - 1; $k >= 0; $k--) {
         for ($j = $k; $j < $Q->columns(); $j++) {
             // First compute w^T(j) = v^T * Q(j) where Q(j) is the j-th column of Q.
             $w = $Q->get($k, $j) * 1.0;
             for ($i = $k + 1; $i < $Q->rows(); $i++) {
                 $w += $this->_matrix->get($i, $k) * $Q->get($i, $j);
             }
             // Now : Q(i,j) = Q(i,j) - tau(k)*v(i)*w(j).
             $Q->set($k, $j, $Q->get($k, $j) - $this->_tau->get($k) * 1.0 * $w);
             for ($i = $k + 1; $i < $Q->rows(); $i++) {
                 $Q->set($i, $j, $Q->get($i, $j) - $this->_tau->get($k) * $this->_matrix->get($i, $k) * $w);
             }
         }
     }
     return $Q;
 }