Task: Gaussian elimination






PHP: function swap_rows(&$a, &$b, $r1, $r2)
{
    if ($r1 == $r2) return;

    $tmp = $a[$r1];
    $a[$r1] = $a[$r2];
    $a[$r2] = $tmp;

    $tmp = $b[$r1];
    $b[$r1] = $b[$r2];
    $b[$r2] = $tmp;
}

function gauss_eliminate($A, $b, $N)
{
    for ($col = 0; $col < $N; $col++)
    {
        $j = $col;
        $max = $A[$j][$j];

        for ($i = $col + 1; $i < $N; $i++)
        {
            $tmp = abs($A[$i][$col]);
            if ($tmp > $max)
            {
                $j = $i;
                $max = $tmp;
            }
        }

        swap_rows($A, $b, $col, $j);

        for ($i = $col + 1; $i < $N; $i++)
        {
            $tmp = $A[$i][$col] / $A[$col][$col];
            for ($j = $col + 1; $j < $N; $j++)
            {
                $A[$i][$j] -= $tmp * $A[$col][$j];
            }
            $A[$i][$col] = 0;
            $b[$i] -= $tmp * $b[$col];
        }
    }
    $x = array();
    for ($col = $N - 1; $col >= 0; $col--)
    {
        $tmp = $b[$col];
        for ($j = $N - 1; $j > $col; $j--)
        {
            $tmp -= $x[$j] * $A[$col][$j];
        }
        $x[$col] = $tmp / $A[$col][$col];
    }
    return $x;
}

function test_gauss()
{
    $a = array(
        array(1.00, 0.00, 0.00,  0.00,  0.00, 0.00),
        array(1.00, 0.63, 0.39,  0.25,  0.16, 0.10),
        array(1.00, 1.26, 1.58,  1.98,  2.49, 3.13),
        array(1.00, 1.88, 3.55,  6.70, 12.62, 23.80),
        array(1.00, 2.51, 6.32, 15.88, 39.90, 100.28),
        array(1.00, 3.14, 9.87, 31.01, 97.41, 306.02)
    );
    $b = array( -0.01, 0.61, 0.91, 0.99, 0.60, 0.02 );

    $x = gauss_eliminate($a, $b, 6);

    ksort($x);
    print_r($x);
}

test_gauss();





Fortran:         program ge

          real, allocatable :: a(:,:),b(:)
          a = reshape(                             &
          [1.0, 1.00, 1.00,  1.00,   1.00,   1.00, &
           0.0, 0.63, 1.26,  1.88,   2.51,   3.14, &
           0.0, 0.39, 1.58,  3.55,   6.32,   9.87, &
           0.0, 0.25, 1.98,  6.70,  15.88,  31.01, &
           0.0, 0.16, 2.49, 12.62,  39.90,  97.41, &
           0.0, 0.10, 3.13, 23.80, 100.28, 306.02], [6,6] )
          b = [-0.01, 0.61, 0.91, 0.99, 0.60, 0.02]
          print'(f15.7)',solve_wbs(ge_wpp(a,b))

        contains
  
          function solve_wbs(u) result(x) 
            real                 :: u(:,:)
            integer              :: i,n
            real   , allocatable :: x(:)
            n = size(u,1)
            allocate(x(n))
            forall (i=n:1:-1) x(i) = ( u(i,n+1) - sum(u(i,i+1:n)*x(i+1:n)) ) / u(i,i)
          end function

          function  ge_wpp(a,b) result(u) 
            real                 :: a(:,:),b(:),upi
            integer              :: i,j,n,p
            real   , allocatable :: u(:,:)
            n = size(a,1)
            u = reshape( [a,b], [n,n+1] )
            do j=1,n
              p = maxloc(abs(u(j:n,j)),1) + j-1 
              if (p /= j) u([p,j],j) = u([j,p],j)
              u(j+1:,j) = u(j+1:,j)/u(j,j)
              do i=j+1,n+1
                upi = u(p,i)
                if (p /= j) u([p,j],i) = u([j,p],i)
                u(j+1:n,i) = u(j+1:n,i) - upi*u(j+1:n,j)
              end do
            end do
          end function

        end program