PHPExcel

# Source for file TestMatrix.php

Documentation is available at TestMatrix.php

1. <?php
3. require_once "../Matrix.php";
5. class TestMatrix {
7. function TestMatrix () {
9. // define test variables
11. $errorCount = 0;
12. $warningCount = 0;
13. $columnwise = array(1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.);
14. $rowwise = array(1.,4.,7.,10.,2.,5.,8.,11.,3.,6.,9.,12.);
15. $avals = array(array(1.,4.,7.,10.),array(2.,5.,8.,11.),array(3.,6.,9.,12.));
16. $rankdef = $avals;
17. $tvals = array(array(1.,2.,3.),array(4.,5.,6.),array(7.,8.,9.),array(10.,11.,12.));
18. $subavals = array(array(5.,8.,11.),array(6.,9.,12.));
19. $rvals = array(array(1.,4.,7.),array(2.,5.,8.,11.),array(3.,6.,9.,12.));
20. $pvals = array(array(1.,1.,1.),array(1.,2.,3.),array(1.,3.,6.));
21. $ivals = array(array(1.,0.,0.,0.),array(0.,1.,0.,0.),array(0.,0.,1.,0.));
22. $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.));
23. $square = array(array(166.,188.,210.),array(188.,214.,240.),array(210.,240.,270.));
24. $sqSolution = array(array(13.),array(15.));
25. $condmat = array(array(1.,3.),array(7.,9.));
26. $rows = 3;
27. $cols = 4;
28. $invalidID = 5; /* should trigger bad shape for construction with val */
29. $raggedr = 0; /* (raggedr,raggedc) should be out of bounds in ragged array */
30. $raggedc = 4;
31. $validID = 3; /* leading dimension of intended test Matrices */
32. $nonconformld = 4; /* leading dimension which is valid, but nonconforming */
33. $ib = 1; /* index ranges for sub Matrix */
34. $ie = 2;
35. $jb = 1;
36. $je = 3;
37. $rowindexset = array(1,2);
38. $badrowindexset = array(1,3);
39. $columnindexset = array(1,2,3);
40. $badcolumnindexset = array(1,2,4);
41. $columnsummax = 33.;
42. $rowsummax = 30.;
43. $sumofdiagonals = 15;
44. $sumofsquares = 650;
46. /**
47. * Test matrix methods
48. */
50. /**
51. * Constructors and constructor-like methods:
52. *
53. * Matrix(double[], int)
54. * Matrix(double[][])
55. * Matrix(int, int)
56. * Matrix(int, int, double)
57. * Matrix(int, int, double[][])
58. * constructWithCopy(double[][])
59. * random(int,int)
60. * identity(int)
61. */
62. echo "<p>Testing constructors and constructor-like methods...</p>";
64. $A = new Matrix($columnwise, 3);
65. if($A instanceof Matrix) {
66. $this-> try_success ("Column-packed constructor...");
67. } else
68. $errorCount = $this-> try_failure ($errorCount, "Column-packed constructor...", "Unable to construct Matrix");
70. $T = new Matrix($tvals);
71. if($T instanceof Matrix)
72. $this-> try_success ("2D array constructor...");
73. else
74. $errorCount = $this-> try_failure ($errorCount, "2D array constructor...", "Unable to construct Matrix");
76. $A = new Matrix($columnwise, $validID);
77. $B = new Matrix($avals);
78. $tmp = $B->get(0,0);
79. $avals[0][0] = 0.0;
80. $C = $B->minus($A);
81. $avals[0][0] = $tmp;
82. $B = Matrix::constructWithCopy($avals);
83. $tmp = $B->get(0,0);
84. $avals[0][0] = 0.0;
85. /** check that constructWithCopy behaves properly **/
86. if ( ( $tmp - $B->get(0,0) ) != 0.0 )
87. $errorCount = $this-> try_failure ($errorCount,"constructWithCopy... ","copy not effected... data visible outside");
88. else
89. $this-> try_success ("constructWithCopy... ","");
91. $I = new Matrix($ivals);
92. if ( $this-> checkMatrices ($I,Matrix::identity(3,4)) )
93. $this-> try_success ("identity... ","");
94. else
95. $errorCount = $this-> try_failure ($errorCount,"identity... ","identity Matrix not successfully created");
97. /**
98. * Access Methods:
99. *
100. * getColumnDimension()
101. * getRowDimension()
102. * getArray()
103. * getArrayCopy()
104. * getColumnPackedCopy()
105. * getRowPackedCopy()
106. * get(int,int)
107. * getMatrix(int,int,int,int)
108. * getMatrix(int,int,int[])
109. * getMatrix(int[],int,int)
110. * getMatrix(int[],int[])
111. * set(int,int,double)
112. * setMatrix(int,int,int,int,Matrix)
113. * setMatrix(int,int,int[],Matrix)
114. * setMatrix(int[],int,int,Matrix)
115. * setMatrix(int[],int[],Matrix)
116. */
117. print "<p>Testing access methods...</p>";
119. $B = new Matrix($avals);
120. if($B->getRowDimension() == $rows)
121. $this-> try_success ("getRowDimension...");
122. else
123. $errorCount = $this-> try_failure ($errorCount, "getRowDimension...");
125. if($B->getColumnDimension() == $cols)
126. $this-> try_success ("getColumnDimension...");
127. else
128. $errorCount = $this-> try_failure ($errorCount, "getColumnDimension...");
130. $barray = $B->getArray();
131. if($this-> checkArrays ($barray, $avals))
132. $this-> try_success ("getArray...");
133. else
134. $errorCount = $this-> try_failure ($errorCount, "getArray...");
136. $bpacked = $B->getColumnPackedCopy();
137. if($this-> checkArrays ($bpacked, $columnwise))
138. $this-> try_success ("getColumnPackedCopy...");
139. else
140. $errorCount = $this-> try_failure ($errorCount, "getColumnPackedCopy...");
142. $bpacked = $B->getRowPackedCopy();
143. if($this-> checkArrays ($bpacked, $rowwise))
144. $this-> try_success ("getRowPackedCopy...");
145. else
146. $errorCount = $this-> try_failure ($errorCount, "getRowPackedCopy...");
148. /**
149. * Array-like methods:
150. * minus
151. * minusEquals
152. * plus
153. * plusEquals
154. * arrayLeftDivide
155. * arrayLeftDivideEquals
156. * arrayRightDivide
157. * arrayRightDivideEquals
158. * arrayTimes
159. * arrayTimesEquals
160. * uminus
161. */
162. print "<p>Testing array-like methods...</p>";
164. /**
165. * I/O methods:
166. * read
167. * print
168. * serializable:
169. * writeObject
170. * readObject
171. */
172. print "<p>Testing I/O methods...</p>";
174. /**
175. * Test linear algebra methods
176. */
177. echo "<p>Testing linear algebra methods...<p>";
179. $A = new Matrix($columnwise, 3);
180. if( $this-> checkMatrices ($A->transpose(), $T) )
181. $this-> try_success ("Transpose check...");
182. else
183. $errorCount = $this-> try_failure ($errorCount, "Transpose check...", "Matrices are not equal");
185. if($this-> checkScalars ($A->norm1(), $columnsummax))
186. $this-> try_success ("Maximum column sum...");
187. else
188. $errorCount = $this-> try_failure ($errorCount, "Maximum column sum...", "Incorrect: " . $A->norm1() . " != " . $columnsummax);
190. if($this-> checkScalars ($A->normInf(), $rowsummax))
191. $this-> try_success ("Maximum row sum...");
192. else
193. $errorCount = $this-> try_failure ($errorCount, "Maximum row sum...", "Incorrect: " . $A->normInf() . " != " . $rowsummax );
195. if($this-> checkScalars ($A->normF(), sqrt ($sumofsquares)))
196. $this-> try_success ("Frobenius norm...");
197. else
198. $errorCount = $this-> try_failure ($errorCount, "Frobenius norm...", "Incorrect:" . $A->normF() . " != " . sqrt ($sumofsquares));
200. if($this-> checkScalars ($A->trace(), $sumofdiagonals))
201. $this-> try_success ("Matrix trace...");
202. else
203. $errorCount = $this-> try_failure ($errorCount, "Matrix trace...", "Incorrect: " . $A->trace() . " != " . $sumofdiagonals);
205. $B = $A->getMatrix(0, $A->getRowDimension(), 0, $A->getRowDimension());
206. if( $B->det() == 0 )
207. $this-> try_success ("Matrix determinant...");
208. else
209. $errorCount = $this-> try_failure ($errorCount, "Matrix determinant...", "Incorrect: " . $B->det() . " != " . 0);
211. $A = new Matrix($columnwise,3);
212. $SQ = new Matrix($square);
213. if ($this-> checkMatrices ($SQ, $A->times($A->transpose())))
214. $this-> try_success ("times(Matrix)...");
215. else {
216. $errorCount = $this-> try_failure ($errorCount, "times(Matrix)...", "Unable to multiply matrices");
217. $SQ->toHTML();
218. $AT->toHTML();
219. }
221. $A = new Matrix($columnwise, 4);
223. $QR = $A->qr();
224. $R = $QR->getR();
225. $Q = $QR->getQ();
226. if($this-> checkMatrices ($A, $Q->times($R)))
227. $this-> try_success ("QRDecomposition...","");
228. else
229. $errorCount = $this-> try_failure ($errorCount,"QRDecomposition...","incorrect qr decomposition calculation");
231. $A = new Matrix($columnwise, 4);
232. $SVD = $A->svd();
233. $U = $SVD->getU();
234. $S = $SVD->getS();
235. $V = $SVD->getV();
236. if ($this-> checkMatrices ($A, $U->times($S->times($V->transpose()))))
237. $this-> try_success ("SingularValueDecomposition...","");
238. else
239. $errorCount = $this-> try_failure ($errorCount,"SingularValueDecomposition...","incorrect singular value decomposition calculation");
241. $n = $A->getColumnDimension();
242. $A = $A->getMatrix(0,$n-1,0,$n-1);
243. $A->set(0,0,0.);
245. $LU = $A->lu();
246. $L = $LU->getL();
247. if ( $this-> checkMatrices ($A->getMatrix($LU->getPivot(),0,$n-1), $L->times($LU->getU())) )
248. $this-> try_success ("LUDecomposition...","");
249. else
250. $errorCount = $this-> try_failure ($errorCount,"LUDecomposition...","incorrect LU decomposition calculation");
252. $X = $A->inverse();
253. if ( $this-> checkMatrices ($A->times($X),Matrix::identity(3,3)) )
254. $this-> try_success ("inverse()...","");
255. else
256. $errorCount = $this-> try_failure ($errorCount, "inverse()...","incorrect inverse calculation");
258. $DEF = new Matrix($rankdef);
259. if($this-> checkScalars ($DEF->rank(), min ($DEF->getRowDimension(), $DEF->getColumnDimension())-1))
260. $this-> try_success ("Rank...");
261. else
262. $this-> try_failure ("Rank...", "incorrect rank calculation");
264. $B = new Matrix($condmat);
265. $SVD = $B->svd();
266. $singularvalues = $SVD->getSingularValues();
267. if($this-> checkScalars ($B->cond(), $singularvalues[0]/$singularvalues[ min ($B->getRowDimension(), $B->getColumnDimension())-1]))
268. $this-> try_success ("Condition number...");
269. else
270. $this-> try_failure ("Condition number...", "incorrect condition number calculation");
272. $SUB = new Matrix($subavals);
273. $O = new Matrix($SUB->getRowDimension(),1,1.0);
274. $SOL = new Matrix($sqSolution);
275. $SQ = $SUB->getMatrix(0,$SUB->getRowDimension()-1,0,$SUB->getRowDimension()-1);
276. if ( $this-> checkMatrices ($SQ->solve($SOL),$O) )
277. $this-> try_success ("solve()...","");
278. else
279. $errorCount = $this-> try_failure ($errorCount,"solve()...","incorrect lu solve calculation");
281. $A = new Matrix($pvals);
282. $Chol = $A->chol();
283. $L = $Chol->getL();
284. if ( $this-> checkMatrices ($A, $L->times($L->transpose())) )
285. $this-> try_success ("CholeskyDecomposition...","");
286. else
287. $errorCount = $this-> try_failure ($errorCount,"CholeskyDecomposition...","incorrect Cholesky decomposition calculation");
289. $X = $Chol->solve(Matrix::identity(3,3));
290. if ( $this-> checkMatrices ($A->times($X), Matrix::identity(3,3)) )
291. $this-> try_success ("CholeskyDecomposition solve()...","");
292. else
293. $errorCount = $this-> try_failure ($errorCount,"CholeskyDecomposition solve()...","incorrect Choleskydecomposition solve calculation");
295. $Eig = $A->eig();
296. $D = $Eig->getD();
297. $V = $Eig->getV();
298. if( $this-> checkMatrices ($A->times($V),$V->times($D)) )
299. $this-> try_success ("EigenvalueDecomposition (symmetric)...","");
300. else
301. $errorCount = $this-> try_failure ($errorCount,"EigenvalueDecomposition (symmetric)...","incorrect symmetric Eigenvalue decomposition calculation");
303. $A = new Matrix($evals);
304. $Eig = $A->eig();
305. $D = $Eig->getD();
306. $V = $Eig->getV();
307. if ( $this-> checkMatrices ($A->times($V),$V->times($D)) )
308. $this-> try_success ("EigenvalueDecomposition (nonsymmetric)...","");
309. else
310. $errorCount = $this-> try_failure ($errorCount,"EigenvalueDecomposition (nonsymmetric)...","incorrect nonsymmetric Eigenvalue decomposition calculation");
312. print("<b>{$errorCount} total errors</b>.");
313. }
315. /**
316. * Print appropriate messages for successful outcome try
317. * @param string $s
318. * @param string $e
319. */
320. function try_success ($s, $e = "") {
321. print "> ". $s ."success<br />";
322. if ($e != "")
323. print "> Message: ". $e ."<br />";
324. }
326. /**
327. * Print appropriate messages for unsuccessful outcome try
328. * @param int $count
329. * @param string $s
330. * @param string $e
331. * @return int incremented counter
332. */
333. function try_failure ($count, $s, $e="") {
334. print "> ". $s ."*** failure ***<br />> Message: ". $e ."<br />";
335. return ++$count;
336. }
338. /**
339. * Print appropriate messages for unsuccessful outcome try
340. * @param int $count
341. * @param string $s
342. * @param string $e
343. * @return int incremented counter
344. */
345. function try_warning ($count, $s, $e="") {
346. print "> ". $s ."*** warning ***<br />> Message: ". $e ."<br />";
347. return ++$count;
348. }
350. /**
351. * Check magnitude of difference of "scalars".
352. * @param float $x
353. * @param float $y
354. */
355. function checkScalars ($x, $y) {
356. $eps = pow (2.0,-52.0);
357. if ($x == 0 & abs ($y) < 10*$eps) return;
358. if ($y == 0 & abs ($x) < 10*$eps) return;
359. if ( abs ($x-$y) > 10 * $eps * max ( abs ($x), abs ($y)))
360. return false;
361. else
362. return true;
363. }
365. /**
366. * Check norm of difference of "vectors".
367. * @param float $x[]
368. * @param float $y[]
369. */
370. function checkVectors ($x, $y) {
371. $nx = count ($x);
372. $ny = count ($y);
373. if ($nx == $ny)
374. for($i=0; $i < $nx; ++$i)
375. $this-> checkScalars ($x[$i],$y[$i]);
376. else
377. die("Attempt to compare vectors of different lengths");
378. }
380. /**
381. * Check norm of difference of "arrays".
382. * @param float $x[][]
383. * @param float $y[][]
384. */
385. function checkArrays ($x, $y) {
386. $A = new Matrix($x);
387. $B = new Matrix($y);
388. return $this-> checkMatrices ($A,$B);
389. }
391. /**
392. * Check norm of difference of "matrices".
393. * @param matrix $X
394. * @param matrix $Y
395. */
396. function checkMatrices ($X = null, $Y = null) {
397. if( $X == null || $Y == null )
398. return false;
400. $eps = pow (2.0,-52.0);
401. if ($X->norm1() == 0. & $Y->norm1() < 10*$eps) return true;
402. if ($Y->norm1() == 0. & $X->norm1() < 10*$eps) return true;
404. $A = $X->minus($Y);
406. if ($A->norm1() > 1000 * $eps * max ($X->norm1(),$Y->norm1()))
407. die("The norm of (X-Y) is too large: ".$A->norm1());
408. else
409. return true;
410. }
412. }
414. $test = new TestMatrix ;
415. ?>

Documentation generated on Fri, 12 Oct 2012 00:18:10 +0200 by phpDocumentor 1.4.4