Ejemplo n.º 1
0
 /** 
  * 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>";
 }
Ejemplo n.º 2
0
 /**
  * det
  * Calculate determinant
  * @return float Determinant
  */
 function det()
 {
     $L = new LUDecomposition($this);
     return $L->det();
 }
Ejemplo n.º 3
0
function fitcircle($X, $Y)
{
    $points = sizeof($X);
    if ($points < 3) {
        return array("cx" => 0, "cy" => 0, "r" => 0, "err" => 100);
    }
    // Mean of points
    $meanX = 0;
    $meanY = 0;
    for ($i = 0; $i < sizeof($X); $i++) {
        $meanX += $X[$i];
        $meanY += $Y[$i];
    }
    $meanX /= $points;
    $meanY /= $points;
    // Auxiliary means
    $mXx = 0;
    $mXy = 0;
    $mYy = 0;
    $mRx = 0;
    $mRy = 0;
    for ($i = 0; $i < sizeof($X); $i++) {
        $x = $X[$i];
        $y = $Y[$i];
        $r = $x * $x + $y * $y;
        $mXx += $x * ($x - $meanX);
        $mXy += $x * ($y - $meanY);
        $mYy += $y * ($y - $meanY);
        $mRx += $r * ($x - $meanX);
        $mRy += $r * ($y - $meanY);
    }
    $mXx /= $points;
    $mXy /= $points;
    $mYy /= $points;
    $mRx /= $points;
    $mRy /= $points;
    // Assemble matrix
    $A[0][0] = $mXx;
    $A[0][1] = 2.0 * $mXy;
    $A[1][0] = 0.0;
    $A[1][1] = $mYy;
    $matrixA = new Matrix($A);
    // A=A+transpose(A)
    $matrixA = $matrixA->plus($matrixA->transpose());
    // Assemble B vector
    $b[0][0] = $mRx;
    $b[1][0] = $mRy;
    $matrixB = new Matrix($b);
    // Calculate center Solve A*x=b for x,then center=x
    $LU = new LUDecomposition($matrixA);
    if ($LU->isNonsingular()) {
        $C = $matrixA->solve($matrixB);
        $cx = $C->get(0, 0);
        $cy = $C->get(1, 0);
        // Calculate radius
        $meanR2 = 0;
        $maxR2 = 0;
        $minR2 = 10000;
        for ($i = 0; $i < sizeof($X); $i++) {
            $x = $X[$i];
            $y = $Y[$i];
            $r2 = ($x - $cx) * ($x - $cx) + ($y - $cy) * ($y - $cy);
            if ($r2 > $maxR2) {
                $maxR2 = $r2;
            }
            if ($r2 < $minR2) {
                $minR2 = $r2;
            }
            $meanR2 += $r2;
        }
        $meanR2 /= $points;
        $radius = sqrt($meanR2);
        // Calculate error
        $err = sqrt($maxR2) / sqrt($minR2);
        // Return
        return array("cx" => $cx, "cy" => $cy, "r" => $radius, "err" => $err);
    } else {
        return array("cx" => 0, "cy" => 0, "r" => 0, "err" => 100);
    }
}