JAMA
[ class tree: JAMA ] [ index: JAMA ] [ all elements ]

Source for file MagicSquareExample.php

Documentation is available at MagicSquareExample.php

  1. <?php
  2. /**
  3. * @package JAMA
  4. */
  5.  
  6. require_once "../Matrix.php";
  7.  
  8. /**
  9. * Example of use of Matrix Class, featuring magic squares.
  10. */
  11.  
  12.   /**
  13.   * Generate magic square test matrix.
  14.   * @param int n dimension of matrix
  15.   */
  16.   function magic($n) {
  17.  
  18.     // Odd order
  19.  
  20.     if (($n % 2) == 1) {
  21.       $a = ($n+1)/2;
  22.       $b = ($n+1);
  23.       for ($j = 0; $j < $n; ++$j)
  24.         for ($i = 0; $i < $n; ++$i)
  25.           $M[$i][$j] = $n*(($i+$j+$a) % $n) + (($i+2*$j+$b) % $n) + 1;
  26.  
  27.     // Doubly Even Order
  28.  
  29.     } else if (($n % 4) == 0) {
  30.       for ($j = 0; $j < $n; ++$j) {
  31.         for ($i = 0; $i < $n; ++$i) {
  32.           if ((($i+1)/2)%2 == (($j+1)/2)%2)
  33.             $M[$i][$j] = $n*$n-$n*$i-$j;
  34.           else
  35.             $M[$i][$j] = $n*$i+$j+1;
  36.         }
  37.       }
  38.  
  39.     // Singly Even Order
  40.  
  41.     } else {
  42.  
  43.       $p = $n/2;
  44.       $k = ($n-2)/4;
  45.       $A = $this->magic($p);
  46.       $M = array();
  47.       for ($j = 0; $j < $p; ++$j) {
  48.         for ($i = 0; $i < $p; ++$i) {
  49.           $aij = $A->get($i,$j);
  50.           $M[$i][$j]       = $aij;
  51.           $M[$i][$j+$p]    = $aij + 2*$p*$p;
  52.           $M[$i+$p][$j]    = $aij + 3*$p*$p;
  53.           $M[$i+$p][$j+$p] = $aij + $p*$p;
  54.         }
  55.       }
  56.  
  57.       for ($i = 0; $i < $p; ++$i) {
  58.         for ($j = 0; $j < $k; ++$j) {
  59.           $t = $M[$i][$j];
  60.           $M[$i][$j] = $M[$i+$p][$j];
  61.           $M[$i+$p][$j] = $t;
  62.         }
  63.         for ($j = $n-$k+1; $j < $n; ++$j) {
  64.           $t = $M[$i][$j];
  65.           $M[$i][$j] = $M[$i+$p][$j];
  66.           $M[$i+$p][$j] = $t;
  67.         }
  68.       }
  69.  
  70.       $t = $M[$k][0];  $M[$k][0]  = $M[$k+$p][0];  $M[$k+$p][0]  = $t;
  71.       $t = $M[$k][$k]; $M[$k][$k] = $M[$k+$p][$k]; $M[$k+$p][$k] = $t;
  72.  
  73.     }
  74.  
  75.     return new Matrix($M);
  76.  
  77.   }
  78.  
  79.   /**
  80.   * Simple function to replicate PHP 5 behaviour
  81.   */
  82.   function microtime_float() {
  83.     list($usec, $sec) = explode(" ", microtime());
  84.     return ((float)$usec + (float)$sec);
  85.   }
  86.  
  87.   /**
  88.   * Tests LU, QR, SVD and symmetric Eig decompositions.
  89.   *
  90.   *   n       = order of magic square.
  91.   *   trace   = diagonal sum, should be the magic sum, (n^3 + n)/2.
  92.   *   max_eig = maximum eigenvalue of (A + A')/2, should equal trace.
  93.   *   rank    = linear algebraic rank, should equal n if n is odd,
  94.   *             be less than n if n is even.
  95.   *   cond    = L_2 condition number, ratio of singular values.
  96.   *   lu_res  = test of LU factorization, norm1(L*U-A(p,:))/(n*eps).
  97.   *   qr_res  = test of QR factorization, norm1(Q*R-A)/(n*eps).
  98.   */
  99.   function main() {
  100.     ?>
  101.     <p>Test of Matrix Class, using magic squares.</p>
  102.     <p>See MagicSquareExample.main() for an explanation.</p>
  103.     <table border='1' cellspacing='0' cellpadding='4'>
  104.       <tr>
  105.         <th>n</th>
  106.         <th>trace</th>
  107.         <th>max_eig</th>
  108.         <th>rank</th>
  109.         <th>cond</th>
  110.         <th>lu_res</th>
  111.         <th>qr_res</th>
  112.       </tr>
  113.       <?php
  114.       $start_time = $this->microtime_float();
  115.       $eps = pow(2.0,-52.0);
  116.       for ($n = 3; $n <= 6; ++$n) {
  117.         echo "<tr>";
  118.  
  119.         echo "<td align='right'>$n</td>";
  120.  
  121.         $M = $this->magic($n);
  122.         $t = (int) $M->trace();
  123.  
  124.         echo "<td align='right'>$t</td>";
  125.  
  126.         $O = $M->plus($M->transpose());
  127.         $E = new EigenvalueDecomposition($O->times(0.5));
  128.         $d = $E->getRealEigenvalues();
  129.  
  130.         echo "<td align='right'>".$d[$n-1]."</td>";
  131.  
  132.         $r = $M->rank();
  133.  
  134.         echo "<td align='right'>".$r."</td>";
  135.  
  136.         $c = $M->cond();
  137.  
  138.         if ($c < 1/$eps)
  139.           echo "<td align='right'>".sprintf("%.3f",$c)."</td>";
  140.         else
  141.           echo "<td align='right'>Inf</td>";
  142.  
  143.         $LU = new LUDecomposition($M);
  144.         $L = $LU->getL();
  145.         $U = $LU->getU();
  146.         $p = $LU->getPivot();
  147.         // Java version: R = L.times(U).minus(M.getMatrix(p,0,n-1));
  148.         $S = $L->times($U);
  149.         $R = $S->minus($M->getMatrix($p,0,$n-1));
  150.         $res = $R->norm1()/($n*$eps);
  151.  
  152.         echo "<td align='right'>".sprintf("%.3f",$res)."</td>";
  153.  
  154.         $QR = new QRDecomposition($M);
  155.         $Q = $QR->getQ();
  156.         $R = $QR->getR();
  157.         $S = $Q->times($R);
  158.         $R = $S->minus($M);
  159.         $res = $R->norm1()/($n*$eps);
  160.  
  161.         echo "<td align='right'>".sprintf("%.3f",$res)."</td>";
  162.  
  163.         echo "</tr>";
  164.  
  165.      }
  166.      echo "<table>";
  167.      echo "<br />";
  168.  
  169.      $stop_time = $this->microtime_float();
  170.      $etime = $stop_time - $start_time;
  171.  
  172.      echo "<p>Elapsed time is ". sprintf("%.4f",$etime) ." seconds.</p>";
  173.  
  174.   }
  175.  
  176. }
  177.  
  178. $magic = new MagicSquareExample();
  179. $magic->main();
  180.  
  181. ?>

Documentation generated on Sun, 27 Feb 2011 16:32:34 -0800 by phpDocumentor 1.4.3