Clean
This commit is contained in:
		| @ -1,116 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * quadratic (p-o)'S'S(p-o) | ||||
|  * solve for o, S | ||||
|  * S is a single scale factor | ||||
|  */ | ||||
| class LMQuadTest { | ||||
|  | ||||
| 	/** | ||||
| 	 * @param array[] $x | ||||
| 	 * @param array[] $a | ||||
| 	 */ | ||||
| 	function val($x, $a) { | ||||
| 		if (count($a) != 3) die ("Wrong number of elements in array a"); | ||||
| 		if (count($x) != 2) die ("Wrong number of elements in array x"); | ||||
|  | ||||
| 		$ox = $a[0]; | ||||
| 		$oy = $a[1]; | ||||
| 		$s  = $a[2]; | ||||
|  | ||||
| 		$sdx = $s * ($x[0] - $ox); | ||||
| 		$sdy = $s * ($x[1] - $oy); | ||||
|  | ||||
| 		return ($sdx * $sdx) + ($sdy * $sdy); | ||||
|    }	//	function val() | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * z = (p-o)'S'S(p-o) | ||||
| 	 * dz/dp = 2S'S(p-o) | ||||
| 	 * | ||||
| 	 * z = (s*(px-ox))^2 + (s*(py-oy))^2 | ||||
| 	 * dz/dox = -2(s*(px-ox))*s | ||||
| 	 * dz/ds = 2*s*[(px-ox)^2 + (py-oy)^2] | ||||
| 	 * | ||||
| 	 * z = (s*dx)^2 + (s*dy)^2 | ||||
| 	 * dz/ds = 2(s*dx)*dx + 2(s*dy)*dy | ||||
| 	 * | ||||
| 	 * @param array[] $x | ||||
| 	 * @param array[] $a | ||||
| 	 * @param int $a_k | ||||
| 	 * @param array[] $a | ||||
| 	 */ | ||||
| 	function grad($x, $a, $a_k) { | ||||
| 		if (count($a) != 3) die ("Wrong number of elements in array a"); | ||||
| 		if (count($x) != 2) die ("Wrong number of elements in array x"); | ||||
| 		if ($a_k < 3) die ("a_k=".$a_k); | ||||
|  | ||||
| 		$ox = $a[0]; | ||||
| 		$oy = $a[1]; | ||||
| 		$s  = $a[2]; | ||||
|  | ||||
| 		$dx = ($x[0] - $ox); | ||||
| 		$dy = ($x[1] - $oy); | ||||
|  | ||||
| 		if ($a_k == 0) | ||||
| 			return -2.*$s*$s*$dx; | ||||
| 		elseif ($a_k == 1) | ||||
| 			return -2.*$s*$s*$dy; | ||||
| 		else | ||||
| 			return 2.*$s*($dx*$dx + $dy*$dy); | ||||
| 	}	//	function grad() | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * @return array[] $a | ||||
| 	 */ | ||||
| 	function initial() { | ||||
| 		$a[0] = 0.05; | ||||
| 		$a[1] = 0.1; | ||||
| 		$a[2] = 1.0; | ||||
|  | ||||
| 		return $a; | ||||
| 	}	//	function initial() | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * @return Object[] $a | ||||
| 	 */ | ||||
| 	function testdata() { | ||||
| 		$npts = 25; | ||||
|  | ||||
| 		$a[0] = 0.; | ||||
| 		$a[1] = 0.; | ||||
| 		$a[2] = 0.9; | ||||
|  | ||||
| 		$i = 0; | ||||
|  | ||||
| 		for ($r = -2; $r <= 2; ++$r) { | ||||
| 			for ($c = -2; $c <= 2; ++$c) { | ||||
| 				$x[$i][0] = $c; | ||||
| 				$x[$i][1] = $r; | ||||
| 				$y[$i] = $this->val($x[$i], $a); | ||||
| 				print("Quad ".$c.",".$r." -> ".$y[$i]."<br />"); | ||||
| 				$s[$i] = 1.; | ||||
| 				++$i; | ||||
| 			} | ||||
| 		} | ||||
| 		print("quad x= "); | ||||
|  | ||||
| 		$qx = new Matrix($x); | ||||
| 		$qx->print(10, 2); | ||||
|  | ||||
| 		print("quad y= "); | ||||
| 		$qy = new Matrix($y, $npts); | ||||
| 		$qy->print(10, 2); | ||||
|  | ||||
| 		$o[0] = $x; | ||||
| 		$o[1] = $a; | ||||
| 		$o[2] = $y; | ||||
| 		$o[3] = $s; | ||||
|  | ||||
| 		return $o; | ||||
| 	}	//	function testdata() | ||||
|  | ||||
| }	//	class LMQuadTest | ||||
| @ -1,59 +0,0 @@ | ||||
| <?php | ||||
|  | ||||
| require_once "../Matrix.php"; | ||||
|  | ||||
| /** | ||||
|  * Given n points (x0,y0)...(xn-1,yn-1), the following methid computes | ||||
|  * the polynomial factors of the n-1't degree polynomial passing through | ||||
|  * the n points. | ||||
|  * | ||||
|  * Example: Passing in three points (2,3) (1,4) and (3,7) will produce | ||||
|  * the results [2.5, -8.5, 10] which means that the points are on the | ||||
|  * curve y = 2.5x² - 8.5x + 10. | ||||
|  * | ||||
|  * @see http://geosoft.no/software/lagrange/LagrangeInterpolation.java.html | ||||
|  * @author Jacob Dreyer | ||||
|  * @author Paul Meagher (port to PHP and minor changes) | ||||
|  * | ||||
|  * @param x[] float | ||||
|  * @param y[] float | ||||
|  */ | ||||
| class LagrangeInterpolation { | ||||
|  | ||||
| 	public function findPolynomialFactors($x, $y) { | ||||
| 		$n = count($x); | ||||
|  | ||||
| 		$data = array();  // double[n][n]; | ||||
| 		$rhs  = array();  // double[n]; | ||||
|  | ||||
| 		for ($i = 0; $i < $n; ++$i) { | ||||
| 			$v = 1; | ||||
| 			for ($j = 0; $j < $n; ++$j) { | ||||
| 				$data[$i][$n-$j-1] = $v; | ||||
| 				$v *= $x[$i]; | ||||
| 			} | ||||
| 			$rhs[$i] = $y[$i]; | ||||
| 		} | ||||
|  | ||||
| 		// Solve m * s = b | ||||
| 		$m = new Matrix($data); | ||||
| 		$b = new Matrix($rhs, $n); | ||||
|  | ||||
| 		$s = $m->solve($b); | ||||
|  | ||||
| 		return $s->getRowPackedCopy(); | ||||
| 	}	//	function findPolynomialFactors() | ||||
|  | ||||
| }	//	class LagrangeInterpolation | ||||
|  | ||||
|  | ||||
| $x = array(2.0, 1.0, 3.0); | ||||
| $y = array(3.0, 4.0, 7.0); | ||||
|  | ||||
| $li = new LagrangeInterpolation; | ||||
| $f = $li->findPolynomialFactors($x, $y); | ||||
|  | ||||
|  | ||||
| for ($i = 0; $i < 3; ++$i) { | ||||
| 	echo $f[$i]."<br />"; | ||||
| } | ||||
| @ -1,59 +0,0 @@ | ||||
| <?php | ||||
|  | ||||
| require_once "../Matrix.php"; | ||||
|  | ||||
| /** | ||||
|  * Given n points (x0,y0)...(xn-1,yn-1), the following method computes | ||||
|  * the polynomial factors of the n-1't degree polynomial passing through | ||||
|  * the n points. | ||||
|  * | ||||
|  * Example: Passing in three points (2,3) (1,4) and (3,7) will produce | ||||
|  * the results [2.5, -8.5, 10] which means that the points are on the | ||||
|  * curve y = 2.5x² - 8.5x + 10. | ||||
|  * | ||||
|  * @see http://geosoft.no/software/lagrange/LagrangeInterpolation.java.html | ||||
|  * @see http://source.freehep.org/jcvsweb/ilc/LCSIM/wdview/lcsim/src/org/lcsim/fit/polynomial/PolynomialFitter.java | ||||
|  * @author Jacob Dreyer | ||||
|  * @author Paul Meagher (port to PHP and minor changes) | ||||
|  * | ||||
|  * @param x[] float | ||||
|  * @param y[] float | ||||
|  */ | ||||
| class LagrangeInterpolation { | ||||
|  | ||||
| 	public function findPolynomialFactors($x, $y) { | ||||
| 		$n = count($x); | ||||
|  | ||||
| 		$data = array();  // double[n][n]; | ||||
| 		$rhs  = array();  // double[n]; | ||||
|  | ||||
| 		for ($i = 0; $i < $n; ++$i) { | ||||
| 			$v = 1; | ||||
| 			for ($j = 0; $j < $n; ++$j) { | ||||
| 				$data[$i][$n-$j-1] = $v; | ||||
| 				$v *= $x[$i]; | ||||
| 			} | ||||
| 			$rhs[$i] = $y[$i]; | ||||
| 		} | ||||
|  | ||||
| 		// Solve m * s = b | ||||
| 		$m = new Matrix($data); | ||||
| 		$b = new Matrix($rhs, $n); | ||||
|  | ||||
| 		$s = $m->solve($b); | ||||
|  | ||||
| 		return $s->getRowPackedCopy(); | ||||
| 	}	//	function findPolynomialFactors() | ||||
|  | ||||
| }	//	class LagrangeInterpolation | ||||
|  | ||||
|  | ||||
| $x = array(2.0, 1.0, 3.0); | ||||
| $y = array(3.0, 4.0, 7.0); | ||||
|  | ||||
| $li = new LagrangeInterpolation; | ||||
| $f = $li->findPolynomialFactors($x, $y); | ||||
|  | ||||
| for ($i = 0; $i < 3; ++$i) { | ||||
| 	echo $f[$i]."<br />"; | ||||
| } | ||||
| @ -1,185 +0,0 @@ | ||||
| <?php | ||||
|  | ||||
| // Levenberg-Marquardt in PHP | ||||
|  | ||||
| // http://www.idiom.com/~zilla/Computer/Javanumeric/LM.java | ||||
|  | ||||
| class LevenbergMarquardt { | ||||
|  | ||||
| 	/** | ||||
| 	 * Calculate the current sum-squared-error | ||||
| 	 * | ||||
| 	 * Chi-squared is the distribution of squared Gaussian errors, | ||||
| 	 * thus the name. | ||||
| 	 * | ||||
| 	 * @param double[][] $x | ||||
| 	 * @param double[] $a | ||||
| 	 * @param double[] $y, | ||||
| 	 * @param double[] $s, | ||||
| 	 * @param object $f | ||||
| 	 */ | ||||
| 	function chiSquared($x, $a, $y, $s, $f) { | ||||
| 		$npts = count($y); | ||||
| 		$sum = 0.0; | ||||
|  | ||||
| 		for ($i = 0; $i < $npts; ++$i) { | ||||
| 			$d = $y[$i] - $f->val($x[$i], $a); | ||||
| 			$d = $d / $s[$i]; | ||||
| 			$sum = $sum + ($d*$d); | ||||
| 		} | ||||
|  | ||||
| 		return $sum; | ||||
| 	}	//	function chiSquared() | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * Minimize E = sum {(y[k] - f(x[k],a)) / s[k]}^2 | ||||
| 	 * The individual errors are optionally scaled by s[k]. | ||||
| 	 * Note that LMfunc implements the value and gradient of f(x,a), | ||||
| 	 * NOT the value and gradient of E with respect to a! | ||||
| 	 * | ||||
| 	 * @param x array of domain points, each may be multidimensional | ||||
| 	 * @param y corresponding array of values | ||||
| 	 * @param a the parameters/state of the model | ||||
| 	 * @param vary false to indicate the corresponding a[k] is to be held fixed | ||||
| 	 * @param s2 sigma^2 for point i | ||||
| 	 * @param lambda blend between steepest descent (lambda high) and | ||||
| 	 *	jump to bottom of quadratic (lambda zero). | ||||
| 	 * 	Start with 0.001. | ||||
| 	 * @param termepsilon termination accuracy (0.01) | ||||
| 	 * @param maxiter	stop and return after this many iterations if not done | ||||
| 	 * @param verbose	set to zero (no prints), 1, 2 | ||||
| 	 * | ||||
| 	 * @return the new lambda for future iterations. | ||||
| 	 *  Can use this and maxiter to interleave the LM descent with some other | ||||
| 	 *  task, setting maxiter to something small. | ||||
| 	 */ | ||||
| 	function solve($x, $a, $y, $s, $vary, $f, $lambda, $termepsilon, $maxiter, $verbose) { | ||||
| 		$npts = count($y); | ||||
| 		$nparm = count($a); | ||||
|  | ||||
| 		if ($verbose > 0) { | ||||
| 			print("solve x[".count($x)."][".count($x[0])."]"); | ||||
| 			print(" a[".count($a)."]"); | ||||
| 			println(" y[".count(length)."]"); | ||||
| 		} | ||||
|  | ||||
| 		$e0 = $this->chiSquared($x, $a, $y, $s, $f); | ||||
|  | ||||
| 		//double lambda = 0.001; | ||||
| 		$done = false; | ||||
|  | ||||
| 		// g = gradient, H = hessian, d = step to minimum | ||||
| 		// H d = -g, solve for d | ||||
| 		$H = array(); | ||||
| 		$g = array(); | ||||
|  | ||||
| 		//double[] d = new double[nparm]; | ||||
|  | ||||
| 		$oos2 = array(); | ||||
|  | ||||
| 		for($i = 0; $i < $npts; ++$i) { | ||||
| 			$oos2[$i] = 1./($s[$i]*$s[$i]); | ||||
| 		} | ||||
| 		$iter = 0; | ||||
| 		$term = 0;	// termination count test | ||||
|  | ||||
| 		do { | ||||
| 			++$iter; | ||||
|  | ||||
| 			// hessian approximation | ||||
| 			for( $r = 0; $r < $nparm; ++$r) { | ||||
| 				for( $c = 0; $c < $nparm; ++$c) { | ||||
| 					for( $i = 0; $i < $npts; ++$i) { | ||||
| 						if ($i == 0) $H[$r][$c] = 0.; | ||||
| 						$xi = $x[$i]; | ||||
| 						$H[$r][$c] += ($oos2[$i] * $f->grad($xi, $a, $r) * $f->grad($xi, $a, $c)); | ||||
| 					}  //npts | ||||
| 				} //c | ||||
| 			} //r | ||||
|  | ||||
| 			// boost diagonal towards gradient descent | ||||
| 			for( $r = 0; $r < $nparm; ++$r) | ||||
| 				$H[$r][$r] *= (1. + $lambda); | ||||
|  | ||||
| 			// gradient | ||||
| 			for( $r = 0; $r < $nparm; ++$r) { | ||||
| 				for( $i = 0; $i < $npts; ++$i) { | ||||
| 					if ($i == 0) $g[$r] = 0.; | ||||
| 					$xi = $x[$i]; | ||||
| 					$g[$r] += ($oos2[$i] * ($y[$i]-$f->val($xi,$a)) * $f->grad($xi, $a, $r)); | ||||
| 				} | ||||
| 			} //npts | ||||
|  | ||||
| 			// scale (for consistency with NR, not necessary) | ||||
| 			if ($false) { | ||||
| 				for( $r = 0; $r < $nparm; ++$r) { | ||||
| 					$g[$r] = -0.5 * $g[$r]; | ||||
| 					for( $c = 0; $c < $nparm; ++$c) { | ||||
| 						$H[$r][$c] *= 0.5; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			// solve H d = -g, evaluate error at new location | ||||
| 			//double[] d = DoubleMatrix.solve(H, g); | ||||
| //			double[] d = (new Matrix(H)).lu().solve(new Matrix(g, nparm)).getRowPackedCopy(); | ||||
| 			//double[] na = DoubleVector.add(a, d); | ||||
| //			double[] na = (new Matrix(a, nparm)).plus(new Matrix(d, nparm)).getRowPackedCopy(); | ||||
| //			double e1 = chiSquared(x, na, y, s, f); | ||||
|  | ||||
| //			if (verbose > 0) { | ||||
| //				System.out.println("\n\niteration "+iter+" lambda = "+lambda); | ||||
| //				System.out.print("a = "); | ||||
| //				(new Matrix(a, nparm)).print(10, 2); | ||||
| //				if (verbose > 1) { | ||||
| //					System.out.print("H = "); | ||||
| //					(new Matrix(H)).print(10, 2); | ||||
| //					System.out.print("g = "); | ||||
| //					(new Matrix(g, nparm)).print(10, 2); | ||||
| //					System.out.print("d = "); | ||||
| //					(new Matrix(d, nparm)).print(10, 2); | ||||
| //				} | ||||
| //				System.out.print("e0 = " + e0 + ": "); | ||||
| //				System.out.print("moved from "); | ||||
| //				(new Matrix(a, nparm)).print(10, 2); | ||||
| //				System.out.print("e1 = " + e1 + ": "); | ||||
| //				if (e1 < e0) { | ||||
| //					System.out.print("to "); | ||||
| //					(new Matrix(na, nparm)).print(10, 2); | ||||
| //				} else { | ||||
| //					System.out.println("move rejected"); | ||||
| //				} | ||||
| //			} | ||||
|  | ||||
| 			// termination test (slightly different than NR) | ||||
| //			if (Math.abs(e1-e0) > termepsilon) { | ||||
| //				term = 0; | ||||
| //			} else { | ||||
| //				term++; | ||||
| //				if (term == 4) { | ||||
| //					System.out.println("terminating after " + iter + " iterations"); | ||||
| //					done = true; | ||||
| //				} | ||||
| //			} | ||||
| //			if (iter >= maxiter) done = true; | ||||
|  | ||||
| 			// in the C++ version, found that changing this to e1 >= e0 | ||||
| 			// was not a good idea.  See comment there. | ||||
| 			// | ||||
| //			if (e1 > e0 || Double.isNaN(e1)) { // new location worse than before | ||||
| //				lambda *= 10.; | ||||
| //			} else {		// new location better, accept new parameters | ||||
| //				lambda *= 0.1; | ||||
| //				e0 = e1; | ||||
| //				// simply assigning a = na will not get results copied back to caller | ||||
| //				for( int i = 0; i < nparm; i++ ) { | ||||
| //					if (vary[i]) a[i] = na[i]; | ||||
| //				} | ||||
| //			} | ||||
| 		} while(!$done); | ||||
|  | ||||
| 		return $lambda; | ||||
| 	}	//	function solve() | ||||
|  | ||||
| }	//	class LevenbergMarquardt | ||||
| @ -1,182 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
| * @package JAMA | ||||
| */ | ||||
|  | ||||
| require_once "../Matrix.php"; | ||||
|  | ||||
| /** | ||||
| * Example of use of Matrix Class, featuring magic squares. | ||||
| */ | ||||
| class MagicSquareExample { | ||||
|  | ||||
|   /** | ||||
|   * Generate magic square test matrix. | ||||
|   * @param int n dimension of matrix | ||||
|   */ | ||||
|   function magic($n) { | ||||
|  | ||||
|     // Odd order | ||||
|  | ||||
|     if (($n % 2) == 1) { | ||||
|       $a = ($n+1)/2; | ||||
|       $b = ($n+1); | ||||
|       for ($j = 0; $j < $n; ++$j) | ||||
|         for ($i = 0; $i < $n; ++$i) | ||||
|           $M[$i][$j] = $n*(($i+$j+$a) % $n) + (($i+2*$j+$b) % $n) + 1; | ||||
|  | ||||
|     // Doubly Even Order | ||||
|  | ||||
|     } else if (($n % 4) == 0) { | ||||
|       for ($j = 0; $j < $n; ++$j) { | ||||
|         for ($i = 0; $i < $n; ++$i) { | ||||
|           if ((($i+1)/2)%2 == (($j+1)/2)%2) | ||||
|             $M[$i][$j] = $n*$n-$n*$i-$j; | ||||
|           else | ||||
|             $M[$i][$j] = $n*$i+$j+1; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|     // Singly Even Order | ||||
|  | ||||
|     } else { | ||||
|  | ||||
|       $p = $n/2; | ||||
|       $k = ($n-2)/4; | ||||
|       $A = $this->magic($p); | ||||
|       $M = array(); | ||||
|       for ($j = 0; $j < $p; ++$j) { | ||||
|         for ($i = 0; $i < $p; ++$i) { | ||||
|           $aij = $A->get($i,$j); | ||||
|           $M[$i][$j]       = $aij; | ||||
|           $M[$i][$j+$p]    = $aij + 2*$p*$p; | ||||
|           $M[$i+$p][$j]    = $aij + 3*$p*$p; | ||||
|           $M[$i+$p][$j+$p] = $aij + $p*$p; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       for ($i = 0; $i < $p; ++$i) { | ||||
|         for ($j = 0; $j < $k; ++$j) { | ||||
|           $t = $M[$i][$j]; | ||||
|           $M[$i][$j] = $M[$i+$p][$j]; | ||||
|           $M[$i+$p][$j] = $t; | ||||
|         } | ||||
|         for ($j = $n-$k+1; $j < $n; ++$j) { | ||||
|           $t = $M[$i][$j]; | ||||
|           $M[$i][$j] = $M[$i+$p][$j]; | ||||
|           $M[$i+$p][$j] = $t; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       $t = $M[$k][0];  $M[$k][0]  = $M[$k+$p][0];  $M[$k+$p][0]  = $t; | ||||
|       $t = $M[$k][$k]; $M[$k][$k] = $M[$k+$p][$k]; $M[$k+$p][$k] = $t; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     return new Matrix($M); | ||||
|  | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|   * Simple function to replicate PHP 5 behaviour | ||||
|   */ | ||||
|   function microtime_float() { | ||||
|     list($usec, $sec) = explode(" ", microtime()); | ||||
|     return ((float)$usec + (float)$sec); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|   * Tests LU, QR, SVD and symmetric Eig decompositions. | ||||
|   * | ||||
|   *   n       = order of magic square. | ||||
|   *   trace   = diagonal sum, should be the magic sum, (n^3 + n)/2. | ||||
|   *   max_eig = maximum eigenvalue of (A + A')/2, should equal trace. | ||||
|   *   rank    = linear algebraic rank, should equal n if n is odd, | ||||
|   *             be less than n if n is even. | ||||
|   *   cond    = L_2 condition number, ratio of singular values. | ||||
|   *   lu_res  = test of LU factorization, norm1(L*U-A(p,:))/(n*eps). | ||||
|   *   qr_res  = test of QR factorization, norm1(Q*R-A)/(n*eps). | ||||
|   */ | ||||
|   function main() { | ||||
|     ?> | ||||
|     <p>Test of Matrix Class, using magic squares.</p> | ||||
|     <p>See MagicSquareExample.main() for an explanation.</p> | ||||
|     <table border='1' cellspacing='0' cellpadding='4'> | ||||
|       <tr> | ||||
|         <th>n</th> | ||||
|         <th>trace</th> | ||||
|         <th>max_eig</th> | ||||
|         <th>rank</th> | ||||
|         <th>cond</th> | ||||
|         <th>lu_res</th> | ||||
|         <th>qr_res</th> | ||||
|       </tr> | ||||
|       <?php | ||||
|       $start_time = $this->microtime_float(); | ||||
|       $eps = pow(2.0,-52.0); | ||||
|       for ($n = 3; $n <= 6; ++$n) { | ||||
|         echo "<tr>"; | ||||
|  | ||||
|         echo "<td align='right'>$n</td>"; | ||||
|  | ||||
|         $M = $this->magic($n); | ||||
|         $t = (int) $M->trace(); | ||||
|  | ||||
|         echo "<td align='right'>$t</td>"; | ||||
|  | ||||
|         $O = $M->plus($M->transpose()); | ||||
|         $E = new EigenvalueDecomposition($O->times(0.5)); | ||||
|         $d = $E->getRealEigenvalues(); | ||||
|  | ||||
|         echo "<td align='right'>".$d[$n-1]."</td>"; | ||||
|  | ||||
|         $r = $M->rank(); | ||||
|  | ||||
|         echo "<td align='right'>".$r."</td>"; | ||||
|  | ||||
|         $c = $M->cond(); | ||||
|  | ||||
|         if ($c < 1/$eps) | ||||
|           echo "<td align='right'>".sprintf("%.3f",$c)."</td>"; | ||||
|         else | ||||
|           echo "<td align='right'>Inf</td>"; | ||||
|  | ||||
|         $LU = new LUDecomposition($M); | ||||
|         $L = $LU->getL(); | ||||
|         $U = $LU->getU(); | ||||
|         $p = $LU->getPivot(); | ||||
|         // Java version: R = L.times(U).minus(M.getMatrix(p,0,n-1)); | ||||
|         $S = $L->times($U); | ||||
|         $R = $S->minus($M->getMatrix($p,0,$n-1)); | ||||
|         $res = $R->norm1()/($n*$eps); | ||||
|  | ||||
|         echo "<td align='right'>".sprintf("%.3f",$res)."</td>"; | ||||
|  | ||||
|         $QR = new QRDecomposition($M); | ||||
|         $Q = $QR->getQ(); | ||||
|         $R = $QR->getR(); | ||||
|         $S = $Q->times($R); | ||||
|         $R = $S->minus($M); | ||||
|         $res = $R->norm1()/($n*$eps); | ||||
|  | ||||
|         echo "<td align='right'>".sprintf("%.3f",$res)."</td>"; | ||||
|  | ||||
|         echo "</tr>"; | ||||
|  | ||||
|      } | ||||
|      echo "<table>"; | ||||
|      echo "<br />"; | ||||
|  | ||||
|      $stop_time = $this->microtime_float(); | ||||
|      $etime = $stop_time - $start_time; | ||||
|  | ||||
|      echo "<p>Elapsed time is ". sprintf("%.4f",$etime) ." seconds.</p>"; | ||||
|  | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
| $magic = new MagicSquareExample(); | ||||
| $magic->main(); | ||||
|  | ||||
| ?> | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,263 +0,0 @@ | ||||
| <?php | ||||
|  | ||||
| error_reporting(E_ALL); | ||||
|  | ||||
| /** | ||||
|  * @package JAMA | ||||
|  */ | ||||
|  | ||||
| require_once '../Matrix.php'; | ||||
| require_once 'Stats.php'; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Example of use of Matrix Class, featuring magic squares. | ||||
|  */ | ||||
| class Benchmark { | ||||
| 	public $stat; | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * Simple function to replicate PHP 5 behaviour | ||||
| 	 */ | ||||
| 	function microtime_float() { | ||||
| 		list($usec, $sec) = explode(" ", microtime()); | ||||
|  | ||||
| 		return ((float)$usec + (float)$sec); | ||||
| 	}	//	function microtime_float() | ||||
|  | ||||
|  | ||||
| 	function displayStats($times = null) { | ||||
| 		$this->stat->setData($times); | ||||
| 		$stats = $this->stat->calcFull(); | ||||
|  | ||||
| 		echo '<table style="margin-left:32px;">'; | ||||
| 		echo '<tr><td style="text-align:right;"><b>n:</b><td style="text-align:right;">' . $stats['count'] . ' </td></tr>'; | ||||
| 		echo '<tr><td style="text-align:right;"><b>Mean:</b><td style="text-align:right;">' . $stats['mean'] . ' </td></tr>'; | ||||
| 		echo '<tr><td style="text-align:right;"><b>Min.:</b><td style="text-align:right;">' . $stats['min'] . ' </td></tr>'; | ||||
| 		echo '<tr><td style="text-align:right;"><b>Max.:</b><td style="text-align:right;">' . $stats['max'] . ' </td></tr>'; | ||||
| 		echo '<tr><td style="text-align:right;"><b>σ:</b><td style="text-align:right;">' . $stats['stdev'] . ' </td></tr>'; | ||||
| 		echo '<tr><td style="text-align:right;"><b>Variance:</b><td style="text-align:right;">' . $stats['variance'] . ' </td></tr>'; | ||||
| 		echo '<tr><td style="text-align:right;"><b>Range:</b><td style="text-align:right;">' . $stats['range'] . ' </td></tr>'; | ||||
| 		echo '</table>'; | ||||
|  | ||||
| 		return $stats; | ||||
| 	}	//	function displayStats() | ||||
|  | ||||
|  | ||||
| 	function runEig($n = 4, $t = 100) { | ||||
| 		$times = array(); | ||||
|  | ||||
| 		for ($i = 0; $i < $t; ++$i) { | ||||
| 			$M = Matrix::random($n, $n); | ||||
| 			$start_time = $this->microtime_float(); | ||||
| 			$E = new EigenvalueDecomposition($M); | ||||
| 			$stop_time = $this->microtime_float(); | ||||
| 			$times[] = $stop_time - $start_time; | ||||
| 		} | ||||
|  | ||||
| 		return $times; | ||||
| 	}	//	function runEig() | ||||
|  | ||||
|  | ||||
| 	function runLU($n = 4, $t = 100) { | ||||
| 		$times = array(); | ||||
|  | ||||
| 		for ($i = 0; $i < $t; ++$i) { | ||||
| 			$M = Matrix::random($n, $n); | ||||
| 			$start_time = $this->microtime_float(); | ||||
| 			$E = new LUDecomposition($M); | ||||
| 			$stop_time = $this->microtime_float(); | ||||
| 			$times[] = $stop_time - $start_time; | ||||
| 		} | ||||
|  | ||||
| 		return $times; | ||||
| 	}	//	function runLU() | ||||
|  | ||||
|  | ||||
| 	function runQR($n = 4, $t = 100) { | ||||
| 		$times = array(); | ||||
|  | ||||
| 		for ($i = 0; $i < $t; ++$i) { | ||||
| 			$M = Matrix::random($n, $n); | ||||
| 			$start_time = $this->microtime_float(); | ||||
| 			$E = new QRDecomposition($M); | ||||
| 			$stop_time = $this->microtime_float(); | ||||
| 			$times[] = $stop_time - $start_time; | ||||
| 		} | ||||
|  | ||||
| 		return $times; | ||||
| 	}	//	function runQR() | ||||
|  | ||||
|  | ||||
| 	function runCholesky($n = 4, $t = 100) { | ||||
| 		$times = array(); | ||||
|  | ||||
| 		for ($i = 0; $i < $t; ++$i) { | ||||
| 			$M = Matrix::random($n, $n); | ||||
| 			$start_time = $this->microtime_float(); | ||||
| 			$E = new CholeskyDecomposition($M); | ||||
| 			$stop_time = $this->microtime_float(); | ||||
| 			$times[] = $stop_time - $start_time; | ||||
| 		} | ||||
|  | ||||
| 		return $times; | ||||
| 	}	//	function runCholesky() | ||||
|  | ||||
|  | ||||
| 	function runSVD($n = 4, $t = 100) { | ||||
| 		$times = array(); | ||||
|  | ||||
| 		for ($i = 0; $i < $t; ++$i) { | ||||
| 			$M = Matrix::random($n, $n); | ||||
| 			$start_time = $this->microtime_float(); | ||||
| 			$E = new SingularValueDecomposition($M); | ||||
| 			$stop_time = $this->microtime_float(); | ||||
| 			$times[] = $stop_time - $start_time; | ||||
| 		} | ||||
|  | ||||
| 		return $times; | ||||
| 	}	//	function runSVD() | ||||
|  | ||||
|  | ||||
| 	function run() { | ||||
| 		$n = 8; | ||||
| 		$t = 16; | ||||
| 		$sum = 0; | ||||
| 		echo "<b>Cholesky decomposition: $t random {$n}x{$n} matrices</b><br />"; | ||||
| 		$r = $this->displayStats($this->runCholesky($n, $t)); | ||||
| 		$sum += $r['mean'] * $n; | ||||
|  | ||||
| 		echo '<hr />'; | ||||
|  | ||||
| 		echo "<b>Eigenvalue decomposition: $t random {$n}x{$n} matrices</b><br />"; | ||||
| 		$r = $this->displayStats($this->runEig($n, $t)); | ||||
| 		$sum += $r['mean'] * $n; | ||||
|  | ||||
| 		echo '<hr />'; | ||||
|  | ||||
| 		echo "<b>LU decomposition: $t random {$n}x{$n} matrices</b><br />"; | ||||
| 		$r = $this->displayStats($this->runLU($n, $t)); | ||||
| 		$sum += $r['mean'] * $n; | ||||
|  | ||||
| 		echo '<hr />'; | ||||
|  | ||||
| 		echo "<b>QR decomposition: $t random {$n}x{$n} matrices</b><br />"; | ||||
| 		$r = $this->displayStats($this->runQR($n, $t)); | ||||
| 		$sum += $r['mean'] * $n; | ||||
|  | ||||
| 		echo '<hr />'; | ||||
|  | ||||
| 		echo "<b>Singular Value decomposition: $t random {$n}x{$n} matrices</b><br />"; | ||||
| 		$r = $this->displayStats($this->runSVD($n, $t)); | ||||
| 		$sum += $r['mean'] * $n; | ||||
|  | ||||
| 		return $sum; | ||||
| 	}	//	function run() | ||||
|  | ||||
|  | ||||
| 	public function __construct() { | ||||
| 		$this->stat = new Base(); | ||||
| 	}	//	function Benchmark() | ||||
|  | ||||
| }  // class Benchmark		(end MagicSquareExample) | ||||
|  | ||||
|  | ||||
| $benchmark = new Benchmark(); | ||||
|  | ||||
| switch($_REQUEST['decomposition']) { | ||||
| 	case 'cholesky': | ||||
| 		$m = array(); | ||||
| 		for ($i = 2; $i <= 8; $i *= 2) { | ||||
| 			$t = 32 / $i; | ||||
| 			echo "<b>Cholesky decomposition: $t random {$i}x{$i} matrices</b><br />"; | ||||
| 			$s = $benchmark->displayStats($benchmark->runCholesky($i, $t)); | ||||
| 			$m[$i] = $s['mean']; | ||||
| 			echo "<br />"; | ||||
| 		} | ||||
| 		echo '<pre>'; | ||||
| 		foreach($m as $x => $y) { | ||||
| 			echo "$x\t" . 1000*$y . "\n"; | ||||
| 		} | ||||
| 		echo '</pre>'; | ||||
| 		break; | ||||
| 	case 'eigenvalue': | ||||
| 		$m = array(); | ||||
| 		for ($i = 2; $i <= 8; $i *= 2) { | ||||
| 			$t = 32 / $i; | ||||
| 			echo "<b>Eigenvalue decomposition: $t random {$i}x{$i} matrices</b><br />"; | ||||
| 			$s = $benchmark->displayStats($benchmark->runEig($i, $t)); | ||||
| 			$m[$i] = $s['mean']; | ||||
| 			echo "<br />"; | ||||
| 		} | ||||
| 		echo '<pre>'; | ||||
| 		foreach($m as $x => $y) { | ||||
| 			echo "$x\t" . 1000*$y . "\n"; | ||||
| 		} | ||||
| 		echo '</pre>'; | ||||
| 		break; | ||||
| 	case 'lu': | ||||
| 		$m = array(); | ||||
| 		for ($i = 2; $i <= 8; $i *= 2) { | ||||
| 			$t = 32 / $i; | ||||
| 			echo "<b>LU decomposition: $t random {$i}x{$i} matrices</b><br />"; | ||||
| 			$s = $benchmark->displayStats($benchmark->runLU($i, $t)); | ||||
| 			$m[$i] = $s['mean']; | ||||
| 			echo "<br />"; | ||||
| 		} | ||||
| 		echo '<pre>'; | ||||
| 		foreach($m as $x => $y) { | ||||
| 			echo "$x\t" . 1000*$y . "\n"; | ||||
| 		} | ||||
| 		echo '</pre>'; | ||||
| 		break; | ||||
| 	case 'qr': | ||||
| 		$m = array(); | ||||
| 		for ($i = 2; $i <= 8; $i *= 2) { | ||||
| 			$t = 32 / $i; | ||||
| 			echo "<b>QR decomposition: $t random {$i}x{$i} matrices</b><br />"; | ||||
| 			$s = $benchmark->displayStats($benchmark->runQR($i, $t)); | ||||
| 			$m[$i] = $s['mean']; | ||||
| 			echo "<br />"; | ||||
| 		} | ||||
| 		echo '<pre>'; | ||||
| 		foreach($m as $x => $y) { | ||||
| 			echo "$x\t" . 1000*$y . "\n"; | ||||
| 		} | ||||
| 		echo '</pre>'; | ||||
| 		break; | ||||
| 	case 'svd': | ||||
| 		$m = array(); | ||||
| 		for($i = 2; $i <= 8; $i *= 2) { | ||||
| 			$t = 32 / $i; | ||||
| 			echo "<b>Singular value decomposition: $t random {$i}x{$i} matrices</b><br />"; | ||||
| 			$s = $benchmark->displayStats($benchmark->runSVD($i, $t)); | ||||
| 			$m[$i] = $s['mean']; | ||||
| 			echo "<br />"; | ||||
| 		} | ||||
| 		echo '<pre>'; | ||||
| 		foreach($m as $x => $y) { | ||||
| 			echo "$x\t" . 1000*$y . "\n"; | ||||
| 		} | ||||
| 		echo '</pre>'; | ||||
| 		break; | ||||
| 	case 'all': | ||||
| 		$s = $benchmark->run(); | ||||
| 		print("<br /><b>Total<b>: {$s}s<br />"); | ||||
| 		break; | ||||
| 	default: | ||||
| 		?> | ||||
| 		<ul> | ||||
| 			<li><a href="benchmark.php?decomposition=all">Complete Benchmark</a> | ||||
| 				<ul> | ||||
| 					<li><a href="benchmark.php?decomposition=cholesky">Cholesky</a></li> | ||||
| 					<li><a href="benchmark.php?decomposition=eigenvalue">Eigenvalue</a></li> | ||||
| 					<li><a href="benchmark.php?decomposition=lu">LU</a></li> | ||||
| 					<li><a href="benchmark.php?decomposition=qr">QR</a></li> | ||||
| 					<li><a href="benchmark.php?decomposition=svd">Singular Value</a></li> | ||||
| 				</ul> | ||||
| 			</li> | ||||
| 		</ul> | ||||
| 		<?php | ||||
| 		break; | ||||
| } | ||||
| @ -1,73 +0,0 @@ | ||||
| <?php | ||||
| require_once "../Matrix.php"; | ||||
| /* | ||||
| * @package JAMA | ||||
| * @author Michael Bommarito | ||||
| * @author Paul Meagher | ||||
| * @version 0.1 | ||||
| * | ||||
| * Function to fit an order n polynomial function through | ||||
| * a series of x-y data points using least squares. | ||||
| * | ||||
| * @param $X array x values | ||||
| * @param $Y array y values | ||||
| * @param $n int order of polynomial to be used for fitting | ||||
| * @returns array $coeffs of polynomial coefficients | ||||
| * Pre-Conditions: the system is not underdetermined: sizeof($X) > $n+1 | ||||
| */ | ||||
| function polyfit($X, $Y, $n) { | ||||
| 	for ($i = 0; $i < sizeof($X); ++$i) | ||||
| 		for ($j = 0; $j <= $n; ++$j) | ||||
| 			$A[$i][$j] = pow($X[$i], $j); | ||||
| 	for ($i=0; $i < sizeof($Y); ++$i) | ||||
| 		$B[$i] = array($Y[$i]); | ||||
| 	$matrixA = new Matrix($A); | ||||
| 	$matrixB = new Matrix($B); | ||||
| 	$C = $matrixA->solve($matrixB); | ||||
| 	return $C->getMatrix(0, $n, 0, 1); | ||||
| } | ||||
|  | ||||
| function printpoly( $C = null ) { | ||||
| 	for($i = $C->m - 1; $i >= 0; --$i) { | ||||
| 		$r = $C->get($i, 0); | ||||
| 		if ( abs($r) <= pow(10, -9) ) | ||||
| 			$r = 0; | ||||
| 		if ($i == $C->m - 1) | ||||
| 			echo $r . "x<sup>$i</sup>"; | ||||
| 		else if ($i < $C->m - 1) | ||||
| 			echo " + " . $r . "x<sup>$i</sup>"; | ||||
| 		else if ($i == 0) | ||||
| 			echo " + " . $r; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| $X = array(0,1,2,3,4,5); | ||||
| $Y = array(4,3,12,67,228, 579); | ||||
| $points = new Matrix(array($X, $Y)); | ||||
| $points->toHTML(); | ||||
| printpoly(polyfit($X, $Y, 4)); | ||||
|  | ||||
| echo '<hr />'; | ||||
|  | ||||
| $X = array(0,1,2,3,4,5); | ||||
| $Y = array(1,2,5,10,17, 26); | ||||
| $points = new Matrix(array($X, $Y)); | ||||
| $points->toHTML(); | ||||
| printpoly(polyfit($X, $Y, 2)); | ||||
|  | ||||
| echo '<hr />'; | ||||
|  | ||||
| $X = array(0,1,2,3,4,5,6); | ||||
| $Y = array(-90,-104,-178,-252,-26, 1160, 4446); | ||||
| $points = new Matrix(array($X, $Y)); | ||||
| $points->toHTML(); | ||||
| printpoly(polyfit($X, $Y, 5)); | ||||
|  | ||||
| echo '<hr />'; | ||||
|  | ||||
| $X = array(0,1,2,3,4); | ||||
| $Y = array(mt_rand(0, 10), mt_rand(40, 80), mt_rand(240, 400), mt_rand(1800, 2215), mt_rand(8000, 9000)); | ||||
| $points = new Matrix(array($X, $Y)); | ||||
| $points->toHTML(); | ||||
| printpoly(polyfit($X, $Y, 3)); | ||||
| ?> | ||||
| @ -1,78 +0,0 @@ | ||||
| <?php | ||||
|  | ||||
| include "../Matrix.php"; | ||||
|  | ||||
| /** | ||||
| * Tiling of matrix X in [rowWise by colWise] dimension. Tiling | ||||
| * creates a larger matrix than the original data X. Example, if | ||||
| * X is to be tiled in a [3 x 4] manner, then: | ||||
| * | ||||
| *     /            \ | ||||
| *     | X  X  X  X | | ||||
| * C = | X  X  X  X | | ||||
| *     | X  X  X  X | | ||||
| *     \           / | ||||
| * | ||||
| * @param X Matrix | ||||
| * @param rowWise int | ||||
| * @param colWise int | ||||
| * @return Matrix | ||||
| */ | ||||
|  | ||||
| function tile(&$X, $rowWise, $colWise){ | ||||
|  | ||||
|   $xArray = $X->getArray(); | ||||
|   print_r($xArray); | ||||
|  | ||||
|   $countRow    = 0; | ||||
|   $countColumn = 0; | ||||
|  | ||||
|   $m = $X->getRowDimension(); | ||||
|   $n = $X->getColumnDimension(); | ||||
|  | ||||
|   if( $rowWise<1 || $colWise<1 ){ | ||||
|     die("tile : Array index is out-of-bound."); | ||||
|   } | ||||
|  | ||||
|   $newRowDim = $m*$rowWise; | ||||
|   $newColDim = $n*$colWise; | ||||
|  | ||||
|   $result = array(); | ||||
|  | ||||
|   for($i=0 ; $i<$newRowDim; ++$i) { | ||||
|  | ||||
|     $holder = array(); | ||||
|  | ||||
|     for($j=0 ; $j<$newColDim ; ++$j) { | ||||
|  | ||||
|       $holder[$j] = $xArray[$countRow][$countColumn++]; | ||||
|  | ||||
|       // reset the column-index to zero to avoid reference to out-of-bound index in xArray[][] | ||||
|  | ||||
|       if($countColumn == $n) { $countColumn = 0; } | ||||
|  | ||||
|     } // end for | ||||
|  | ||||
|     ++$countRow; | ||||
|  | ||||
|     // reset the row-index to zero to avoid reference to out-of-bound index in xArray[][] | ||||
|  | ||||
|     if($countRow == $m) { $countRow = 0; } | ||||
|  | ||||
|     $result[$i] = $holder; | ||||
|  | ||||
|   } // end for | ||||
|  | ||||
|   return new Matrix($result); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| $X =array(1,2,3,4,5,6,7,8,9); | ||||
| $nRow = 3; | ||||
| $nCol = 3; | ||||
| $tiled_matrix = tile(new Matrix($X), $nRow, $nCol); | ||||
| echo "<pre>"; | ||||
| print_r($tiled_matrix); | ||||
| echo "</pre>"; | ||||
| ?> | ||||
		Reference in New Issue
	
	Block a user