416 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
		
		
			
		
	
	
			416 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| 
								 | 
							
								<?php
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								require_once "../Matrix.php";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class TestMatrix {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function TestMatrix() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // define test variables
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    $errorCount   = 0;
							 | 
						||
| 
								 | 
							
								    $warningCount = 0;
							 | 
						||
| 
								 | 
							
								    $columnwise   = array(1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.);
							 | 
						||
| 
								 | 
							
								    $rowwise      = array(1.,4.,7.,10.,2.,5.,8.,11.,3.,6.,9.,12.);
							 | 
						||
| 
								 | 
							
								    $avals        = array(array(1.,4.,7.,10.),array(2.,5.,8.,11.),array(3.,6.,9.,12.));
							 | 
						||
| 
								 | 
							
								    $rankdef      = $avals;
							 | 
						||
| 
								 | 
							
								    $tvals        = array(array(1.,2.,3.),array(4.,5.,6.),array(7.,8.,9.),array(10.,11.,12.));
							 | 
						||
| 
								 | 
							
								    $subavals     = array(array(5.,8.,11.),array(6.,9.,12.));
							 | 
						||
| 
								 | 
							
								    $rvals        = array(array(1.,4.,7.),array(2.,5.,8.,11.),array(3.,6.,9.,12.));
							 | 
						||
| 
								 | 
							
								    $pvals        = array(array(1.,1.,1.),array(1.,2.,3.),array(1.,3.,6.));
							 | 
						||
| 
								 | 
							
								    $ivals        = array(array(1.,0.,0.,0.),array(0.,1.,0.,0.),array(0.,0.,1.,0.));
							 | 
						||
| 
								 | 
							
								    $evals        = array(array(0.,1.,0.,0.),array(1.,0.,2.e-7,0.),array(0.,-2.e-7,0.,1.),array(0.,0.,1.,0.));
							 | 
						||
| 
								 | 
							
								    $square       = array(array(166.,188.,210.),array(188.,214.,240.),array(210.,240.,270.));
							 | 
						||
| 
								 | 
							
								    $sqSolution   = array(array(13.),array(15.));
							 | 
						||
| 
								 | 
							
								    $condmat      = array(array(1.,3.),array(7.,9.));
							 | 
						||
| 
								 | 
							
								    $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.;
							 | 
						||
| 
								 | 
							
								    $rowsummax         = 30.;
							 | 
						||
| 
								 | 
							
								    $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.);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    $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>.");
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								  * Print appropriate messages for successful outcome try
							 | 
						||
| 
								 | 
							
								  * @param string $s
							 | 
						||
| 
								 | 
							
								  * @param string $e
							 | 
						||
| 
								 | 
							
								  */
							 | 
						||
| 
								 | 
							
								  function try_success($s, $e = "") {
							 | 
						||
| 
								 | 
							
								    print "> ". $s ."success<br />";
							 | 
						||
| 
								 | 
							
								    if ($e != "")
							 | 
						||
| 
								 | 
							
								      print "> Message: ". $e ."<br />";
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								  * Print appropriate messages for unsuccessful outcome try
							 | 
						||
| 
								 | 
							
								  * @param int $count
							 | 
						||
| 
								 | 
							
								  * @param string $s
							 | 
						||
| 
								 | 
							
								  * @param string $e
							 | 
						||
| 
								 | 
							
								  * @return int incremented counter
							 | 
						||
| 
								 | 
							
								  */
							 | 
						||
| 
								 | 
							
								  function try_failure($count, $s, $e="") {
							 | 
						||
| 
								 | 
							
								    print "> ". $s ."*** failure ***<br />> Message: ". $e ."<br />";
							 | 
						||
| 
								 | 
							
								    return ++$count;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								  * Print appropriate messages for unsuccessful outcome try
							 | 
						||
| 
								 | 
							
								  * @param int $count
							 | 
						||
| 
								 | 
							
								  * @param string $s
							 | 
						||
| 
								 | 
							
								  * @param string $e
							 | 
						||
| 
								 | 
							
								  * @return int incremented counter
							 | 
						||
| 
								 | 
							
								  */
							 | 
						||
| 
								 | 
							
								  function try_warning($count, $s, $e="") {
							 | 
						||
| 
								 | 
							
								    print "> ". $s ."*** warning ***<br />> Message: ". $e ."<br />";
							 | 
						||
| 
								 | 
							
								    return ++$count;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								  * Check magnitude of difference of "scalars".
							 | 
						||
| 
								 | 
							
								  * @param float $x
							 | 
						||
| 
								 | 
							
								  * @param float $y
							 | 
						||
| 
								 | 
							
								  */
							 | 
						||
| 
								 | 
							
								  function checkScalars($x, $y) {
							 | 
						||
| 
								 | 
							
								    $eps = pow(2.0,-52.0);
							 | 
						||
| 
								 | 
							
								    if ($x == 0 & abs($y) < 10*$eps) return;
							 | 
						||
| 
								 | 
							
								    if ($y == 0 & abs($x) < 10*$eps) return;
							 | 
						||
| 
								 | 
							
								    if (abs($x-$y) > 10 * $eps * max(abs($x),abs($y)))
							 | 
						||
| 
								 | 
							
								      return false;
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								      return true;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								  * Check norm of difference of "vectors".
							 | 
						||
| 
								 | 
							
								  * @param float $x[]
							 | 
						||
| 
								 | 
							
								  * @param float $y[]
							 | 
						||
| 
								 | 
							
								  */
							 | 
						||
| 
								 | 
							
								  function checkVectors($x, $y) {
							 | 
						||
| 
								 | 
							
								    $nx = count($x);
							 | 
						||
| 
								 | 
							
								    $ny = count($y);
							 | 
						||
| 
								 | 
							
								    if ($nx == $ny)
							 | 
						||
| 
								 | 
							
								      for($i=0; $i < $nx; ++$i)
							 | 
						||
| 
								 | 
							
								        $this->checkScalars($x[$i],$y[$i]);
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								      die("Attempt to compare vectors of different lengths");
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								  * Check norm of difference of "arrays".
							 | 
						||
| 
								 | 
							
								  * @param float $x[][]
							 | 
						||
| 
								 | 
							
								  * @param float $y[][]
							 | 
						||
| 
								 | 
							
								  */
							 | 
						||
| 
								 | 
							
								  function checkArrays($x, $y) {
							 | 
						||
| 
								 | 
							
								    $A = new Matrix($x);
							 | 
						||
| 
								 | 
							
								    $B = new Matrix($y);
							 | 
						||
| 
								 | 
							
								    return $this->checkMatrices($A,$B);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								  * Check norm of difference of "matrices".
							 | 
						||
| 
								 | 
							
								  * @param matrix $X
							 | 
						||
| 
								 | 
							
								  * @param matrix $Y
							 | 
						||
| 
								 | 
							
								  */
							 | 
						||
| 
								 | 
							
								  function checkMatrices($X = null, $Y = null) {
							 | 
						||
| 
								 | 
							
								    if( $X == null || $Y == null )
							 | 
						||
| 
								 | 
							
								      return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    $eps = pow(2.0,-52.0);
							 | 
						||
| 
								 | 
							
								    if ($X->norm1() == 0. & $Y->norm1() < 10*$eps) return true;
							 | 
						||
| 
								 | 
							
								    if ($Y->norm1() == 0. & $X->norm1() < 10*$eps) return true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    $A = $X->minus($Y);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if ($A->norm1() > 1000 * $eps * max($X->norm1(),$Y->norm1()))
							 | 
						||
| 
								 | 
							
								      die("The norm of (X-Y) is too large: ".$A->norm1());
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								      return true;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								$test = new TestMatrix;
							 | 
						||
| 
								 | 
							
								?>
							 |