home > さまざまな言語で数値計算 > 固有値・固有ベクトル >

さまざまな言語で数値計算

Only Do What Only You Can Do

逆反復法

逆反復法を使って, 最小固有値と, 対応する固有ベクトルを求める

正方行列 $ \boldsymbol{A} $ の逆行列を求め

$ \boldsymbol{A}^{-1} \boldsymbol{x} = \displaystyle\frac{\boldsymbol{x}}{\lambda} $
として反復法で最大固有値を求めれば, その逆数が最小固有値になる.

逆行列を計算するより,

$ \boldsymbol{Ax}_k = \boldsymbol{LUx}_k = \boldsymbol{x}_{k-1} $
を解いた方が簡単.

逆べき乗法ともいう.

VBScript

Option Explicit

Private Const N = 3

'逆ベキ乗法で最小固有値を求める
Call Main

Private Sub Main()
    Dim a: a = Array(_
               Array(5.0, 4.0, 1.0, 1.0), _
               Array(4.0, 5.0, 1.0, 1.0), _
               Array(1.0, 1.0, 4.0, 2.0), _
               Array(1.0, 1.0, 2.0, 4.0))

    Dim x: x = Array(1.0 ,0.0 ,0.0 ,0.0)

    'LU分解
    Call forward_elimination(a)

    '逆ベキ乗法
    Dim lambda: lambda = inverse(a, x)

    WScript.StdOut.WriteLine
    WScript.StdOut.WriteLine "eigenvalue"
    WScript.StdOut.WriteLine Right(Space(14) & FormatNumber(lambda, 10, -1, 0, 0), 14)

    WScript.StdOut.WriteLine "eigenvector"
    Call disp_vector(x)
End Sub

'逆ベキ乗法
Private Function inverse(ByVal a, ByRef x0)
    Dim i, j, k

    Dim lambda: lambda = 0.0

    '正規化 (ベクトル x0 の長さを1にする)
    Call normarize(x0)
    Dim e0: e0 = 0.0
    For i = 0 To N
        e0 = e0 + x0(i)
    Next

    For k = 1 To 200
        '1次元配列を表示
        WScript.StdOut.Write Right(Space(3) & k, 3) & vbTab
        Call disp_vector(x0)

        'Ly = b から y を求める (前進代入)
        Dim y: y = Array(0.0, 0.0, 0.0, 0.0)
        Call forward_substitution(a,y,x0)

        'Ux = y から x を求める (後退代入)
        Dim x1: x1 = Array(0.0, 0.0, 0.0, 0.0)
        Call backward_substitution(a,x1,y)

        '内積
        Dim p0: p0 = 0.0
        Dim p1: p1 = 0.0
        For i = 0 To N
            p0 = p0 + x1(i) * x1(i)
            p1 = p1 + x1(i) * x0(i)
        Next
        '固有値
        lambda = p1 / p0

        '正規化 (ベクトル x1 の長さを1にする)
        Call normarize(x1)
        '収束判定
        Dim e1: e1 = 0.0
        For i = 0 To N
            e1 = e1 + x1(i)
        Next
        If Abs(e1 - e0) < 0.00000000001 Then Exit For

        x0 = x1
        e0 = e1
    Next

    inverse = lambda
End Function

'LU分解
Private Sub forward_elimination(ByRef a)
    Dim pivot, row, col
    For pivot = 0 To (N - 1)
        For row = (pivot + 1) To N
            Dim s: s = a(row)(pivot) / a(pivot)(pivot)
            For col = pivot To N
                a(row)(col) = a(row)(col) - a(pivot)(col) * s 'これが 上三角行列
            Next
            a(row)(pivot) = s                                 'これが 下三角行列
        Next
    Next
End Sub
'前進代入 (Ly = b から y を求める)
Private Sub forward_substitution(ByVal a, ByRef y, ByVal b)
    Dim row, col
    For row = 0 To N
        For col = 0 To row
            b(row) = b(row) - a(row)(col) * y(col)
        Next
        y(row) = b(row)
    Next
End Sub
'後退代入 (Ux = y から x を求める)
Private Sub backward_substitution(ByVal a, ByRef x, ByVal y)
    Dim row, col
    For row = N To 0 Step -1
        For col = N To (row + 1) Step - 1
            y(row) = y(row) - a(row)(col) * x(col)
        Next
        x(row) = y(row) / a(row)(row)
    Next
End Sub

'1次元配列を表示
Private Sub disp_vector(ByVal row)
    Dim col
    For Each col In row
        WScript.StdOut.Write Right(Space(14) & FormatNumber(col, 10, -1, 0, 0), 14) & vbTab
    Next
    WScript.StdOut.WriteLine
End Sub

'正規化 (ベクトルの長さを1にする)
Private Sub normarize(ByRef x())
    Dim s: s = 0.0

    Dim i
    For i = 0 To N
        s = s + x(i) * x(i)
    Next
    s = Sqr(s)

    For i = 0 To N
        x(i) = x(i) / s
    Next
End Sub
Z:\>cscript //nologo Z:\1102.vbs
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

JScript

var N = 4

// 逆ベキ乗法で最小固有値を求める
main()

function main()
{
    var a = [[5.0, 4.0, 1.0, 1.0],
             [4.0, 5.0, 1.0, 1.0],
             [1.0, 1.0, 4.0, 2.0],
             [1.0, 1.0, 2.0, 4.0]]
    var x =  [1.0 ,0.0 ,0.0 ,0.0]

    // LU分解
    forward_elimination(a)

    // 逆ベキ乗法
    var lambda = inverse(a, x)

    WScript.StdOut.WriteLine()
    WScript.StdOut.WriteLine("eigenvalue")
    WScript.StdOut.WriteLine(("              "    + lambda.toFixed(10)).slice(-14))

    WScript.StdOut.WriteLine("eigenvector")
    disp_vector(x)
}

// 逆ベキ乗法
function inverse(a, x0)
{
    var lambda = 0.0

    // 正規化 (ベクトル x0 の長さを1にする)
    normarize(x0)
    var e0 = 0.0
    for (var i = 0; i < N; i++)
        e0 += x0[i]

    for (var k = 1; k <= 200; k++)
    {
        // 1次元配列を表示
        WScript.StdOut.Write(("   "           + k).slice( -3) + "\t")
        disp_vector(x0)

        // Ly=b から y を求める (前進代入)
        var b = [0,0,0,0]
        var y = [0,0,0,0]
        for (var i = 0; i < N; i++)
            b[i] = x0[i]
        forward_substitution(a,y,b)

        // Ux=y から x を求める (後退代入)
        var x1 = [0,0,0,0]
        backward_substitution(a,x1,y)

        // 内積
        var p0 = 0.0
        var p1 = 0.0
        for (var i = 0; i < N; i++)
        {
            p0 += x1[i] * x1[i]
            p1 += x1[i] * x0[i]
        }
        // 固有値
        lambda = p1 / p0

        // 正規化 (ベクトル x1 の長さを1にする)
        normarize(x1)
        // 収束判定
        var e1 = 0.0
        for (var i = 0; i < N; i++)
            e1 += x1[i]
        if (Math.abs(e0 - e1) < 0.00000000001) break

        for (var i = 0; i < N; i++)
            x0[i] = x1[i]
        e0 = e1
    }
    return lambda
}

// 前進消去
function forward_elimination(a)
{
    for (var pivot = 0; pivot < N - 1; pivot++)
    {
        for (var row = pivot + 1; row < N; row++)
        {
            var s = a[row][pivot] / a[pivot][pivot]
            for (var col = pivot; col < N; col++)
                a[row][col] -= a[pivot][col] * s // これが 上三角行列
            a[row][pivot] = s                    // これが 下三角行列
        }
    }
}
// 前進代入
function forward_substitution(a, y, b)
{
    for (var row = 0; row < N; row++)
    {
        for (var col = 0; col < row; col++)
            b[row] -= a[row][col] * y[col]
        y[row] = b[row]
    }
}
// 後退代入
function backward_substitution(a, x, y)
{
    for (var row = N - 1; row >= 0; row--)
    {
        for (var col = N - 1; col > row; col--)
            y[row] -= a[row][col] * x[col]
        x[row] = y[row] / a[row][row]
    }
}
// 1次元配列を表示
function disp_vector(row)
{
    for (var i = 0; i < N; i++)
        WScript.StdOut.Write(("              "    + row[i].toFixed(10)).slice(-14) + "\t")
    WScript.StdOut.WriteLine()
}
// 正規化 (ベクトルの長さを1にする)
function normarize(x)
{
    var s = 0.0

    for (var i = 0; i < N; i++)
        s += x[i] * x[i]
    s = Math.sqrt(s)

    for (var i = 0; i < N; i++)
        x[i] /= s
}
Z:\>cscript //nologo Z:\1102.js
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

PowerShell

set-variable -name N -value 3 -option constant

# LU分解
function forward_elimination($a)
{
    foreach ($pivot in 0..($N - 1))
    {
        foreach ($row in ($pivot + 1)..$N)
        {
            $s = $a[$row][$pivot] / $a[$pivot][$pivot]
            foreach ($col in $pivot..$N)
            {
                $a[$row][$col] -= $a[$pivot][$col]    * $s # これが 上三角行列
            }
            $a[$row][$pivot]    = $s                       # これが 下三角行列
        }
    }
}
# 前進代入
function forward_substitution($a, $y, $b)
{
    foreach ($row in 0..$N)
    {
        foreach ($col in 0..$row)
        {
            $b[$row] -= $a[$row][$col] * $y[$col]
        }
        $y[$row] = $b[$row]
    }
}
# 後退代入
function backward_substitution($a, $x, $y)
{
    foreach ($row in $N..0)
    {
        if ($row -lt $N)
        {
            foreach ($col in $N..($row + 1))
            {
                $y[$row] -= $a[$row][$col] * $x[$col]
            }
        }
        $x[$row] = $y[$row] / $a[$row][$row]
    }
}
# 1次元配列を表示
function disp_vector($row)
{
    foreach ($col in $row)
    {
        Write-Host ([String]::Format("{0,14:F10}", $col)) -nonewline
    }
    Write-Host
}
# 正規化 (ベクトルの長さを1にする)
function normarize($x)
{
    $s = 0.0

    foreach ($i in 0..$N)
    {
        $s += $x[$i] * $x[$i]
    }
    $s = [Math]::Sqrt($s)

    foreach ($i in 0..$N)
    {
        $x[$i] /= $s
    }
}

# 逆ベキ乗法
function inverse($a, $x0)
{
    $lambda = 0.0

    # 正規化 (ベクトル x0 の長さを1にする)
    normarize $x0
    $e0 = 0.0
    foreach ($i in 0..$N)
    {
        $e0 += $x0[$i]
    }

    foreach ($k in 1..200)
    {
        # 1次元配列を表示
        Write-Host ([String]::Format("{0,3:D}`t", $k)) -nonewline
        disp_vector $x0

        # Ly = b から y を求める (前進代入)
        $y = (0.0, 0.0, 0.0, 0.0)
        $b = (0.0, 0.0, 0.0, 0.0)
        foreach ($i in 0..$N)
        {
            $b[$i] = $x0[$i]
        }
        forward_substitution $a $y $b

        # Ux = y から x を求める (後退代入)
        $x1 = (0.0, 0.0, 0.0, 0.0)
        backward_substitution $a $x1 $y

        # 内積
        $p0 = 0.0
        $p1 = 0.0
        foreach ($i in 0..$N)
        {
            $p0 += $x1[$i] * $x1[$i]
            $p1 += $x1[$i] * $x0[$i]
        }
        # 固有値
        $lambda = $p1 / $p0

        # 正規化 (ベクトル x1 の長さを1にする)
        normarize $x1
        # 収束判定
        $e1 = 0.0
        foreach ($i in 0..$N)
        {
            $e1 += $x1[$i]
        }
        if ([Math]::Abs($e0 - $e1) -lt 0.00000000001)
        {
            break
        }
        $lambda0 = $lambda1
        foreach ($i in 0..$N)
        {
            $x0[$i] = $x1[$i]
        }
        $e0 = $e1
    }

    $lambda
}

# 逆ベキ乗法で最小固有値を求める

$a = (5.0, 4.0, 1.0, 1.0),
     (4.0, 5.0, 1.0, 1.0),
     (1.0, 1.0, 4.0, 2.0),
     (1.0, 1.0, 2.0, 4.0)
$x = (1.0 ,0.0 ,0.0 ,0.0)

# LU分解
forward_elimination $a

# 逆ベキ乗法
$lambda = (inverse $a $x)

Write-Host
Write-Host "eigenvalue"
Write-Host ([String]::Format("{0,14:F10}", $lambda))

Write-Host "eigenvector"
disp_vector $x
Z:\>powershell -file Z:\1102.ps1
  1   1.0000000000  0.0000000000  0.0000000000  0.0000000000
  2   0.7856989466 -0.6173348866 -0.0280606767 -0.0280606767
  3   0.7182768487 -0.6956539558 -0.0084835848 -0.0084835848
  4   0.7087990176 -0.7054049282 -0.0019798855 -0.0019798855
  5   0.7073894400 -0.7068237547 -0.0004242640 -0.0004242640
  6   0.7071576856 -0.7070558622 -0.0000876812 -0.0000876812
  7   0.7071163975 -0.7070971642 -0.0000178191 -0.0000178191
  8   0.7071086479 -0.7071049144 -0.0000035921 -0.0000035921
  9   0.7071071489 -0.7071064135 -0.0000007212 -0.0000007212
 10   0.7071068542 -0.7071067082 -0.0000001445 -0.0000001445
 11   0.7071067957 -0.7071067666 -0.0000000289 -0.0000000289
 12   0.7071067841 -0.7071067783 -0.0000000058 -0.0000000058
 13   0.7071067818 -0.7071067806 -0.0000000012 -0.0000000012
 14   0.7071067813 -0.7071067811 -0.0000000002 -0.0000000002
 15   0.7071067812 -0.7071067812  0.0000000000  0.0000000000
 16   0.7071067812 -0.7071067812  0.0000000000  0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812 -0.7071067812  0.0000000000  0.0000000000

Perl

use constant N => 3;

# 逆ベキ乗法で最小固有値を求める
main();

sub main
{
    my @a = ([5.0, 4.0, 1.0, 1.0],
             [4.0, 5.0, 1.0, 1.0],
             [1.0, 1.0, 4.0, 2.0],
             [1.0, 1.0, 2.0, 4.0]);
    my @x =  (1.0, 0.0, 0.0, 0.0);

    # LU分解
    forward_elimination(\@a);

    # 逆ベキ乗法 Inverse iteration
    $lambda = inverse(\@a, \@x);

    print "\neigenvalue\n";
    printf("%14.10f", $lambda);

    print "\neigenvector\n";
    disp_vector(\@x);
}

# 逆ベキ乗法 Inverse iteration
sub inverse
{
    my ($a, $x0) = @_;
    my $lambda   = 0.0;

    # 正規化 (ベクトル x0 の長さを1にする)
    normarize(\@$x0);
    my $e0 = 0.0;
    for $i (0..N)
    {
        $e0 += $$x0[$i];
    }

    for $k (1..200)
    {
        # 1次元配列を表示
        printf("%3d\t", $k);
        disp_vector(\@$x0);

        # Ly = b から y を求める (前進代入)
        my @b = (0.0, 0.0, 0.0, 0.0);
        my @y;
        for $i (0..N)
        {
            $b[$i] = $$x0[$i];
        }
        forward_substitution(\@$a, \@y, \@b);

        # Ux = y から x を求める (後退代入)
        my @x1;
        backward_substitution(\@$a, \@x1, \@y);

        # 内積 inner product
        my $p0 = 0.0;
        my $p1 = 0.0;
        for $i (0..N)
        {
            $p0 += $x1[$i] *  $x1[$i];
            $p1 += $x1[$i] * $$x0[$i];
        }
        # 固有値 eigenvalue
        $lambda = $p1 / $p0;

        # 正規化 (ベクトル x1 の長さを1にする)
        normarize(\@x1);
        # 収束判定
        my $e1 = 0.0;
        for $i (0..N)
        {
            $e1 += $x1[$i];
        }
        last if (abs($e0 - $e1) < 0.00000000001);

        for $i (0..N)
        {
            $$x0[$i] = $x1[$i];
        }
        $e0 = $e1;
    }

    $lambda;
}

# LU分解
sub forward_elimination
{
    my ($a) = @_;

    for $pivot (0..(N - 1))
    {
        for $row (($pivot + 1)..N)
        {
            my $s = $$a[$row][$pivot] / $$a[$pivot][$pivot];
            for $col ($pivot..N)
            {
                $$a[$row][$col] -= $$a[$pivot][$col] * $s; # これが 上三角行列
            }
            $$a[$row][$pivot]  = $s;                       # これが 下三角行列
        }
    }
}
# 前進代入
sub forward_substitution
{
    my ($a, $y, $b) = @_;

    for $row (0..N)
    {
        for $col (0..$row)
        {
            $$b[$row] -= $$a[$row][$col] * $$y[$col];
        }
        $$y[$row] = $$b[$row];
    }
}
# 後退代入
sub backward_substitution
{
    my ($a, $x, $y) = @_;

    for $row (reverse(0..N))
    {
        for $col (reverse(($row + 1)..N))
        {
            $$y[$row] -= $$a[$row][$col] * $$x[$col];
        }
        $$x[$row] = $$y[$row] / $$a[$row][$row];
    }
}

# 1次元配列を表示
sub disp_vector
{
    my ($x) = @_;
    for $i (0..N)
    {
        printf("%14.10f\t", $$x[$i]);
    }
    print "\n";
}
# 正規化 (ベクトルの長さを1にする)
sub normarize
{
    my ($x) = @_;
    my  $s  = 0.0;
    for $i (0..N)
    {
        $s += $$x[$i] * $$x[$i];
    }
    $s = sqrt($s);

    for $i (0..N)
    {
        $$x[$i] /= $s;
    }
}
Z:\>perl Z:\1102.pl
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

PHP

<?php
define("N", 3);

# 逆ベキ乗法で最小固有値を求める
main();

function main()
{
    $a = [[5.0, 4.0, 1.0, 1.0],
          [4.0, 5.0, 1.0, 1.0],
          [1.0, 1.0, 4.0, 2.0],
          [1.0, 1.0, 2.0, 4.0]];
    $x =  [1.0, 0.0, 0.0, 0.0];

    # LU分解
    forward_elimination($a);

    # 逆ベキ乗法
    $lambda = inverse($a, $x);

    print "\neigenvalue\n";
    printf("%14.10f", $lambda);

    print "\neigenvector\n";
    disp_vector($x);
}

# 逆ベキ乗法
function inverse(&$a, &$x0)
{
    $lambda   = 0.0;

    # 正規化 (ベクトル x0 の長さを1にする)
    normarize($x0);
    $e0 = 0.0;
    foreach (range(0, N) as $i)
    {
        $e0 += $x0[$i];
    }

    foreach (range(1, 200) as $k)
    {
        # 1次元配列を表示
        printf("%3d\t", $k);
        disp_vector($x0);

        # Ly=b から y を求める (前進代入)
        $y = [0.0, 0.0, 0.0, 0.0];
        forward_substitution($a, $y, $x0);

        # Ux=y から x を求める (後退代入)
        $x1 = [0.0, 0.0, 0.0, 0.0];
        backward_substitution($a, $x1, $y);

        # 内積
        $p0 = 0.0;
        $p1 = 0.0;
        foreach (range(0, N) as $i)
        {
            $p0 += $x1[$i] * $x1[$i];
            $p1 += $x1[$i] * $x0[$i];
        }
        # 固有値
        $lambda = $p1 / $p0;

        # 正規化 (ベクトル x1 の長さを1にする)
        normarize($x1);
        # 収束判定
        $e1 = 0.0;
        foreach (range(0, N) as $i)
        {
            $e1 += $x1[$i];
        }
        if (abs($e0 - $e1) < 0.00000000001) break;

        foreach (range(0, N) as $i)
        {
            $x0[$i] = $x1[$i];
        }
        $e0 = $e1;
    }

    return $lambda;
}

# LU分解
function forward_elimination(&$a)
{
    foreach (range(0, N - 1) as $pivot)
    {
        foreach (range($pivot + 1, N) as $row)
        {
            $s = $a[$row][$pivot] / $a[$pivot][$pivot];
            foreach (range($pivot, N) as $col)
                $a[$row][$col] -= $a[$pivot][$col]    * $s; # これが 上三角行列
            $a[$row][$pivot]    = $s;                       # これが 下三角行列
        }
    }
}
# 前進代入
function forward_substitution($a, &$y, $b)
{
    foreach (range(0, N) as $row)
    {
        foreach (range(0, $row) as $col)
            $b[$row] -= $a[$row][$col] * $y[$col];
        $y[$row] = $b[$row];
    }
}
# 後退代入
function backward_substitution($a, &$x, $y)
{
    foreach (range(N, 0) as $row)
    {
        if (($row + 1) <= N)
            foreach (range(N, $row + 1) as $col)
                $y[$row] -= $a[$row][$col] * $x[$col];
        $x[$row] = $y[$row] / $a[$row][$row];
    }
}
# 1次元配列を表示
function disp_vector($row)
{
    foreach ($row as $col)
        printf("%14.10f\t", $col);
    print "\n";
}
# 正規化 (ベクトルの長さを1にする)
function normarize(&$x)
{
    $s = 0.0;
    foreach (range(0, N) as $i)
    {
        $s += $x[$i] * $x[$i];
    }
    $s = sqrt($s);

    foreach (range(0, N) as $i)
    {
        $x[$i] /= $s;
    }
}
?>
Z:\>php Z:\1102.php
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

Python

# coding: Shift_JIS
import math

N = 4

# 前進消去
def forward_elimination(a):
    for pivot in range(0, N - 1, 1):
        for row in range(pivot + 1, N, 1):
            s = a[row][pivot] / a[pivot][pivot]
            for col in range(pivot, N, 1):
                a[row][col] -= a[pivot][col]    * s # これが 上三角行列
            a[row][pivot]    = s                    # これが 下三角行列

# 前進代入
def forward_substitution(a, y, b):
    for row in range(0, N, 1):
        for col in range(0, row, 1):
            b[row] -= a[row][col] * y[col]

        y[row] = b[row]

# 後退代入
def backward_substitution(a, x, y):
    for row in range(N - 1, -1, -1):
        for col in range(N - 1, row, -1):
            y[row] -= a[row][col] * x[col]
        x[row] = y[row] / a[row][row]


# 1次元配列を表示
def disp_vector(row):
    for col in row:
        print "%14.10f\t" % col,
    print ""

# 正規化 (ベクトルの長さを1にする)
def normarize(x):
    s = 0.0

    for i in range(0, N, 1):
        s += x[i] * x[i]
    s = math.sqrt(s)

    for i in range(0, N, 1):
        x[i] /= s

# 逆ベキ乗法
def inverse(a, x0):
    lambda0 = 0.0

    # 正規化 (ベクトル x0 の長さを1にする)
    normarize(x0)
    e0 = 0.0
    for i in range(0, N, 1):
        e0 += x0[i]

    for k in range(1, 200, 1):
        # 1次元配列を表示
        print "%3d\t" % k,
        disp_vector(x0)

        # Ly=b から y を求める (前進代入)
        y = [0.0, 0.0, 0.0, 0.0]
        b = [0.0, 0.0, 0.0, 0.0]
        for i in range(0, N, 1):
            b[i] = x0[i]
        forward_substitution(a, y, b)

        # Ux=y から x を求める (後退代入)
        x1 =  [ 0.0,  0.0,  0.0,  0.0]
        backward_substitution(a, x1, y)

        # 内積
        p0 = 0.0
        p1 = 0.0
        for i in range(0, N, 1):
            p0 += x1[i] * x1[i]
            p1 += x1[i] * x0[i]

        # 固有値
        lambda0 = p1 / p0

        # 正規化 (ベクトル x1 の長さを1にする)
        normarize(x1)
        # 収束判定
        e1 = 0.0
        for i in range(0, N, 1):
            e1 += x1[i]
        if (abs(e0 - e1) < 0.00000000001):
            break

        for i in range(0, N, 1):
            x0[i] = x1[i]
        e0 = e1

    return lambda0

# 逆ベキ乗法で最小固有値を求める

a = [[5.0, 4.0, 1.0, 1.0],
     [4.0, 5.0, 1.0, 1.0],
     [1.0, 1.0, 4.0, 2.0],
     [1.0, 1.0, 2.0, 4.0]]
x =  [1.0 ,0.0 ,0.0 ,0.0]

# LU分解
forward_elimination(a)

# 逆ベキ乗法
lambda0 = inverse(a, x)

print ""
print "eigenvalue"
print "%14.10f" % lambda0

print "eigenvector"
disp_vector(x)
Z:\>python Z:\1102.py
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

Ruby

# coding: Shift_JIS

N = 3

# 前進消去
def forward_elimination(a)
    0.upto(N - 1) do |pivot|
        (pivot + 1).upto(N) do |row|
            s = a[row][pivot] / a[pivot][pivot]
            pivot.upto(N) do |col|
                a[row][col] -= a[pivot][col] * s # これが 上三角行列
            end
            a[row][pivot]    = s                 # これが 下三角行列
        end
    end
end
# 前進代入
def forward_substitution(a, y, b)
    (0..N).each do |row|
        (0..row).each do |col|
            b[row] -= a[row][col] * y[col]
        end
        y[row] = b[row]
    end
end
# 後退代入
def backward_substitution(a, x, y)
    (0..N).reverse_each do |row|
        ((row + 1)..N).reverse_each do |col|
            y[row] -= a[row][col] * x[col]
        end
        x[row] = y[row] / a[row][row]
    end
end

# 1次元配列を表示
def disp_vector(row)
    row.each do |col|
        printf("%14.10f\t", col)
    end
    puts ""
end
# 正規化 (ベクトルの長さを1にする)
def normarize(x)
    s = 0.0

    (0..N).each do |i|
        s += x[i] * x[i]
    end
    s = Math.sqrt(s)

    (0..N).each do |i|
        x[i] /= s
    end
end

# 逆ベキ乗法
def inverse(a, x0)
    lambda = 0.0

    # 正規化 (ベクトル x0 の長さを1にする)
    normarize(x0)
    e0 = 0.0
    (0..N).each do |i|
        e0 += x0[i]
    end

    (1..200).each do |k|
        # 1次元配列を表示
        printf("%3d\t", k)
        disp_vector(x0)

        # Ly=b から y を求める (前進代入)
        y = [0.0, 0.0, 0.0, 0.0]
        b = [0.0, 0.0, 0.0, 0.0]
        (0..N).each do |i|
            b[i] = x0[i]
        end
        forward_substitution(a, y, b)

        # Ux=y から x を求める (後退代入)
        x1 =  [ 0.0,  0.0,  0.0,  0.0]
        backward_substitution(a, x1, y)

        # 内積
        p0 = 0.0
        p1 = 0.0
        (0..N).each do |i|
            p0 += x1[i] * x1[i]
            p1 += x1[i] * x0[i]
        end
        # 固有値
        lambda = p1 / p0

        # 正規化 (ベクトル x1 の長さを1にする)
        normarize(x1)
        # 収束判定
        e1 = 0.0
        (0..N).each do |i|
            e1 += x1[i]
        end
        break if ((e0 - e1).abs < 0.00000000001)

        (0..N).each do |i|
            x0[i] = x1[i]
        end
        e0 = e1
    end

    lambda
end

# 逆ベキ乗法で最小固有値を求める

a = [[5.0, 4.0, 1.0, 1.0],
     [4.0, 5.0, 1.0, 1.0],
     [1.0, 1.0, 4.0, 2.0],
     [1.0, 1.0, 2.0, 4.0]]
x =  [1.0 ,0.0 ,0.0 ,0.0]

# LU分解
forward_elimination(a)

# 逆ベキ乗法
lambda0 = inverse(a, x)

puts ""
puts "eigenvalue"
printf("%14.10f\n", lambda0)

puts "eigenvector"
disp_vector(x)
Z:\>ruby Z:\1102.rb
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

Groovy

N = 3

// 逆ベキ乗法で最小固有値を求める
main()

def main() {
    def a = [[5.0, 4.0, 1.0, 1.0],
             [4.0, 5.0, 1.0, 1.0],
             [1.0, 1.0, 4.0, 2.0],
             [1.0, 1.0, 2.0, 4.0]] as double[][]
    def x =  [1.0 ,0.0 ,0.0 ,0.0]  as double[]

    // LU分解
    forward_elimination(a)

    // 逆ベキ乗法
    lambda = inverse(a, x)

    println()
    println("eigenvalue")
    printf("%14.10f\n" , lambda)

    println("eigenvector")
    disp_vector(x)
}

// 逆ベキ乗法
def inverse(a, x0) {
    lambda = 0.0

    // 正規化 (ベクトル x0 の長さを1にする)
    normarize(x0)
    e0 = 0.0
    for (i in 0..N)
        e0 += x0[i]

    for (k in 1..200) {
        // 1次元配列を表示
        printf("%3d\t" , k)
        disp_vector(x0)

        // Ly=b から y を求める (前進代入)
        b = [0.0,0.0,0.0,0.0]
        y = [0.0,0.0,0.0,0.0]
        for (i in 0..N)
            b[i] = x0[i]
        forward_substitution(a,y,b)

        // Ux=y から x を求める (後退代入)
        x1 = [0.0,0.0,0.0,0.0]
        backward_substitution(a,x1,y)

        // 内積
        p0 = 0.0
        p1 = 0.0
        for (i in 0..N) {
            p0 += x1[i] * x1[i]
            p1 += x1[i] * x0[i]
        }
        // 固有値
        lambda = p1 / p0

        // 正規化 (ベクトル x1 の長さを1にする)
        normarize(x1)
        // 収束判定
        e1 = 0.0
        for (i in 0..N)
            e1 += x1[i]
        if (Math.abs(e0 - e1) < 0.00000000001) break

        for (i in 0..N)
            x0[i] = x1[i]
        e0 = e1
    }
    lambda
}

// 前進消去
def forward_elimination(a) {
    for (pivot in 0..(N - 1)) {
        for (row in (pivot + 1)..N) {
            s = a[row][pivot] / a[pivot][pivot]
            for (col in pivot..N)
                a[row][col] -= a[pivot][col] * s // これが 上三角行列
            a[row][pivot]    = s                 // これが 下三角行列
        }
    }
}
// Ly=b から y を求める (前進代入)
def forward_substitution(a, y, b) {
    for (row in 0..N) {
        for (col in 0..row)
            b[row] -= a[row][col] * y[col]
        y[row] = b[row]
    }
}
// Ux=y から x を求める (後退代入)
def backward_substitution(a, x, y) {
    for (row = N; row >= 0; row--) {
        for (col = N; col > row; col--)
            y[row] -= a[row][col] * x[col]
        x[row] = y[row] / a[row][row]
    }
}
// 1次元配列を表示
def disp_vector(row) {
    for (col in row) {
        printf("%14.10f\t" , col)
    }
    println()
}
// 正規化 (ベクトルの長さを1にする)
def normarize(x) {
    s = 0.0

    for (i in 0..N)
        s += x[i] * x[i]
    s = Math.sqrt(s)

    for (i in 0..N)
        x[i] /= s
}
Z:\>gvy Gvy1102.gvy
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

Pascal

program Pas1102(arg);
{$MODE delphi}

uses
    SysUtils, Math;

const
    N = 3;

type
    TwoDimArray = array [0..N,0..N] of Double;

// 1次元配列を表示
procedure disp_vector(row:array of Double);
var
    i:Integer;
begin
    for i := Low(row) to High(row) do
        write(format('%14.10f'#9, [row[i]]));
    writeln();
end;
// 正規化 (ベクトルの長さを1にする)
procedure normarize(var x:array of Double);
var
    s:Double = 0.0;
    i:Integer;
begin
    for i := Low(x) to High(x) do
        s := s + x[i] * x[i];
    s := Sqrt(s);

    for i := Low(x) to High(x) do
        x[i] := x[i] / s;
end;
// LU分解
procedure forward_elimination(var a:TwoDimArray);
var
    s:Double;
    pivot, row, col:Integer;
begin
    for pivot := Low(a) to High(a) - 1 do
    begin
        for row := (pivot + 1) to High(a) do
        begin
            s := a[row,pivot] / a[pivot,pivot];
            for col := pivot to High(a) do
                a[row,col] := a[row,col] - a[pivot,col] * s; // これが 上三角行列
            a[row,pivot]   := s;                             // これが 下三角行列
        end;
    end;
end;
// 前進代入 (Ly = b から y を求める)
procedure forward_substitution(a:TwoDimArray; var y:array of Double; b:array of Double);
var
    row, col:Integer;
begin
    for row := Low(a) to High(a) do
    begin
        for col := Low(a) to row do
            b[row] := b[row] - a[row,col] * y[col];
        y[row] := b[row];
    end;
end;
// 後退代入 (Ux = y から x を求める)
procedure backward_substitution(a:TwoDimArray; var x:array of Double; var y:array of Double);
var
    row, col:Integer;
begin
    for row := High(a) downto Low(a) do
    begin
        for col := High(a) downto row + 1 do
            y[row] := y[row] - a[row,col] * x[col];
        x[row] := y[row] / a[row,row];
    end;
end;

// 逆ベキ乗法
function inverse(a:TwoDimArray; var x0:array of Double):Double;
var
    lambda:Double = 0.0;
    p0, p1, e0, e1:Double;
    i, k:Integer;
    b:array [0..N] of Double = (0.0, 0.0, 0.0, 0.0);
    y:array [0..N] of Double = (0.0, 0.0, 0.0, 0.0);
    x1:array [0..N] of Double = (0.0, 0.0, 0.0, 0.0);
 begin
    // 正規化 (ベクトル x0 の長さを1にする)
    normarize(x0);
    e0 := 0.0;
    for i := Low(x0) to High(x0) do
        e0 := e0 + x0[i];

    for k := 1 to 100 do
    begin
        // 1次元配列を表示
        write(format('%3d'#9, [k]));
        disp_vector(x0);

        // Ly = b から y を求める (前進代入)
        for i := Low(x0) to High(x0) do
        begin
            b[i] := x0[i];
            y[i] := 0;
        end;
        forward_substitution(a,y,b);

        // Ux = y から x を求める (後退代入)
        for i := Low(x1) to High(x1) do
            x1[i] := 0;
        backward_substitution(a,x1,y);

        // 内積
        p0 := 0.0;
        p1 := 0.0;
        for i := Low(x0) to High(x0) do
        begin
            p0 := p0 + x1[i] * x1[i];
            p1 := p1 + x1[i] * x0[i];
        end;
        // 固有値
        lambda := p1 / p0;

        // 正規化 (ベクトル x1 の長さを1にする)
        normarize(x1);
        // 収束判定
        e1 := 0.0;
        for i := Low(x0) to High(x0) do
            e1 := e1 + x1[i];
        if Abs(e1 - e0) < 0.00000000001 then
            break;

        for i := Low(x0) to High(x0) do
            x0[i] := x1[i];
        e0 := e1;
    end;

    inverse := lambda;
end;

// 逆ベキ乗法で最小固有値を求める
var
    a :TwoDimArray = ((5.0, 4.0, 1.0, 1.0)
                     ,(4.0, 5.0, 1.0, 1.0)
                     ,(1.0, 1.0, 4.0, 2.0)
                     ,(1.0, 1.0, 2.0, 4.0));
    x :array [0..N] of Double = (1.0, 0.0, 0.0, 0.0);
    lambda:Double;
begin
    // LU分解
    forward_elimination(a);

    // 逆ベキ乗法
    lambda := inverse(a, x);

    writeln();
    writeln('eigenvalue');
    writeln(format('%14.10f', [lambda]));

    writeln('eigenvector');
    disp_vector(x);
end.
Z:\>fpc -v0 -l- Pas1102.pp

Z:\>Pas1102
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812    0.0000000000    0.0000000000
 16   0.7071067812   -0.7071067812    0.0000000000    0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

Ada

with TEXT_IO, Ada.Integer_Text_IO, Ada.Long_Float_Text_IO, Ada.Numerics.Long_Elementary_Functions;
use  TEXT_IO, Ada.Integer_Text_IO, Ada.Long_Float_Text_IO, Ada.Numerics.Long_Elementary_Functions;

procedure Ada1102 is

    N : Constant Integer := 3;

    type Long_Float_Array       is array (0..N)       of Long_Float;
    type Long_Float_TwoDimArray is array (0..N, 0..N) of Long_Float;

    a:Long_Float_TwoDimArray := ((5.0, 4.0, 1.0, 1.0)
                                ,(4.0, 5.0, 1.0, 1.0)
                                ,(1.0, 1.0, 4.0, 2.0)
                                ,(1.0, 1.0, 2.0, 4.0));

    x:Long_Float_Array := (1.0, 0.0, 0.0, 0.0);

    -- 1次元配列を表示
    procedure disp_vector(row:Long_Float_Array) is
    begin
        for i in row'Range loop
            Put(row(i), Fore=>3, Aft=>10, Exp=>0);
            Put(Ascii.HT);
        end loop;
        New_Line;
    end disp_vector;

    -- 正規化 (ベクトルの長さを1にする)
    procedure normarize(x:in out Long_Float_Array) is
        s:Long_Float;
    begin
        s := 0.0;
        for i in x'Range loop
            s := s + x(i) * x(i);
        end loop;
        s := Sqrt(s);

        for i in x'Range loop
            x(i) := x(i) / s;
        end loop;
    end normarize;

    -- LU分解
    procedure forward_elimination(a:in out Long_Float_TwoDimArray) is
        s:Long_Float;
    begin
        for pivot in a'First..(a'Last - 1) loop
            for row in (pivot + 1)..a'Last loop
                s := a(row,pivot) / a(pivot,pivot);
                for col in pivot..a'Last loop
                    a(row,col) := a(row,col) - a(pivot,col) * s; -- これが 上三角行列
                end loop;
                a(row,pivot)   := s;                             -- これが 下三角行列
            end loop;
        end loop;
    end forward_elimination;

    -- 前進代入 (Ly = b から y を求める)
    procedure forward_substitution(a:Long_Float_TwoDimArray; y:in out Long_Float_Array; b:in out Long_Float_Array) is
    begin
        for row in a'Range loop
            for col in a'First..row loop
                b(row) := b(row) - a(row,col) * y(col);
            end loop;
            y(row) := b(row);
        end loop;
    end forward_substitution;

    -- 後退代入 (Ux = y から x を求める)
    procedure backward_substitution(a:Long_Float_TwoDimArray; x:in out Long_Float_Array; y:in out Long_Float_Array) is
    begin
        for row in reverse a'Range loop
            for col in reverse (row + 1)..a'Last loop
                y(row) := y(row) - a(row,col) * x(col);
            end loop;
            x(row) := y(row) / a(row,row);
        end loop;
    end backward_substitution;

    -- 逆ベキ乗法
    procedure inverse(a:Long_Float_TwoDimArray; x0:in out Long_Float_Array; lambda:out Long_Float) is
        p0, p1, e0, e1:Long_Float;
        b:Long_Float_Array  := (0.0, 0.0, 0.0, 0.0);
        y:Long_Float_Array  := (0.0, 0.0, 0.0, 0.0);
        x1:Long_Float_Array := (0.0, 0.0, 0.0, 0.0);
    begin
        -- 正規化 (ベクトル x0 の長さを1にする)
        normarize(x0);
        e0 := 0.0;
        for i in x0'Range loop
            e0 := e0 + x0(i);
        end loop;

        for k in 1..100 loop
            -- 1次元配列を表示
            Put(k, Width=> 3);
            Put(Ascii.HT);
            disp_vector(x0);

            -- Ly = b から y を求める (前進代入)
            for i in x0'Range loop
                b(i) := x0(i);
                y(i) := 0.0;
            end loop;
            forward_substitution(a,y,b);

            -- Ux = y から x を求める (後退代入)
            for i in x1'Range loop
                x1(i) := 0.0;
            end loop;
            backward_substitution(a,x1,y);

            -- 内積
            p0 := 0.0;
            p1 := 0.0;
            for i in x0'Range loop
                p0 := p0 + x1(i) * x1(i);
                p1 := p1 + x1(i) * x0(i);
            end loop;
            -- 固有値
            lambda := p1 / p0;

            -- 正規化 (ベクトル x1 の長さを1にする)
            normarize(x1);
            -- 収束判定
            e1 := 0.0;
            for i in x0'Range loop
                e1 := e1 + x1(i);
            end loop;
            if Abs(e1 - e0) < 0.00000000001 then
                exit;
            end if;

            for i in x0'Range loop
                x0(i) := x1(i);
            end loop;
            e0 := e1;
        end loop;
    end inverse;

-- 逆ベキ乗法で最小固有値を求める
    lambda:Long_Float := 0.0;
begin
    -- LU分解
    forward_elimination(a);

    -- 逆ベキ乗法
    inverse(a, x, lambda);

    Put_Line("");
    Put_Line("eigenvalue");
    Put(lambda, Fore=>3, Aft=>10, Exp=>0);
    New_Line;

    Put_Line("eigenvector");
    disp_vector(x);
end Ada1102;
xxxxxx@yyyyyy /Z
$ gnatmake Ada1102.adb

xxxxxx@yyyyyy /Z
$ Ada1102
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

VB.NET

Option Explicit

Module VB1102
    Private Const N As Integer = 3

    '逆ベキ乗法で最小固有値を求める
    Public Sub Main()
        Dim a(,) As Double = {{5.0, 4.0, 1.0, 1.0},
                              {4.0, 5.0, 1.0, 1.0},
                              {1.0, 1.0, 4.0, 2.0},
                              {1.0, 1.0, 2.0, 4.0}}
        Dim x()  As Double =  {1.0 ,0.0 ,0.0 ,0.0}

        'LU分解
        forward_elimination(a)

        '逆ベキ乗法
        Dim lambda As Double = inverse(a, x)

        Console.WriteLine()
        Console.WriteLine("eigenvalue")
        Console.WriteLine(String.Format("{0,14:F10}", lambda))

        Console.WriteLine("eigenvector")
        disp_vector(x)
    End Sub

    '逆ベキ乗法
    Private Function inverse(ByVal a(,) As Double, ByRef x0() As Double) As Double
        Dim lambda As Double = 0.0

        '正規化 (ベクトル x0 の長さを1にする)
        normarize(x0)
        Dim e0 As Double = 0.0
        For i As Integer = 0 To N
            e0 += x0(i)
        Next

        For k As Integer = 1 To 100
            '1次元配列を表示
            Console.Write(String.Format("{0,3:D}{1}", k, vbTab))
            disp_vector(x0)

            'Ly = b から y を求める (前進代入)
            Dim b() As Double = New Double(N){}
            Dim y() As Double = New Double(N){}
            For i As Integer = 0 To N
                b(i) = x0(i)
            Next
            forward_substitution(a,y,b)
            'Ux = y から x を求める (後退代入)
            Dim x1() As Double = New Double(N){}
            backward_substitution(a,x1,y)

            '内積
            Dim p0 As Double = 0.0
            Dim p1 As Double = 0.0
            For i As Integer = 0 To N
                p0 += x1(i) * x1(i)
                p1 += x1(i) * x0(i)
            Next
            '固有値
            lambda = p1 / p0

            '正規化 (ベクトル x1 の長さを1にする)
            normarize(x1)
            '収束判定
            Dim e1 As Double = 0.0
            For i As Integer = 0 To N
                e1 += x1(i)
            Next
            If Math.Abs(e1 - e0) < 0.00000000001 Then Exit For

            For i As Integer = 0 To N
                x0(i) = x1(i)
            Next
            e0 = e1
        Next

        Return lambda
    End Function

    'LU分解
    Private Sub forward_elimination(ByRef a(,) As Double)
        For pivot As Integer = 0 To (N - 1)
            For row As Integer = (pivot + 1) To N
                Dim s As Double = a(row, pivot) / a(pivot, pivot)
                For col As Integer = pivot To N
                    a(row, col) -= a(pivot, col) * s 'これが 上三角行列
                Next
                a(row, pivot) = s                    'これが 下三角行列
            Next
        Next
    End Sub
    '前進代入 (Ly = b から y を求める)
    Private Sub forward_substitution(ByVal a(,) As Double, ByRef y() As Double, ByVal b() As Double)
        For row As Integer = 0 To N
            For col As Integer = 0 To row
                b(row) -= a(row, col) * y(col)
            Next
            y(row) = b(row)
        Next
    End Sub
    '後退代入 (Ux = y から x を求める)
    Private Sub backward_substitution(ByVal a(,) As Double, ByRef x() As Double, ByVal y() As Double)
        For row As Integer = N To 0 Step -1
            For col As Integer = N To (row + 1) Step - 1
                y(row) -= a(row, col) * x(col)
            Next
            x(row) = y(row) / a(row, row)
        Next
    End Sub

    '1次元配列を表示
    Private Sub disp_vector(ByVal row() As Double)
        For Each col As Double In row
            Console.Write(String.Format("{0,14:F10}{1}", col, vbTab))
        Next
        Console.WriteLine()
    End Sub

    '正規化 (ベクトルの長さを1にする)
    Private Sub normarize(ByRef x() As Double)
        Dim s As Double = 0.0

        For i As Integer = 0 To N
            s += x(i) * x(i)
        Next
        s = Math.Sqrt(s)

        For i As Integer = 0 To N
            x(i) /= s
        Next
    End Sub

End Module
Z:\>vbc -nologo VB1102.vb

Z:\>VB1102
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812    0.0000000000    0.0000000000
 16   0.7071067812   -0.7071067812    0.0000000000    0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

C#

using System;

public class CS1102
{
    private const int N = 4;

    // 逆ベキ乗法で最小固有値を求める
    public static void Main()
    {
        double[,] a = {{5.0, 4.0, 1.0, 1.0},
                       {4.0, 5.0, 1.0, 1.0},
                       {1.0, 1.0, 4.0, 2.0},
                       {1.0, 1.0, 2.0, 4.0}};
        double[]  x  = {1.0 ,0.0 ,0.0 ,0.0};

        // LU分解
        forward_elimination(a);

        // 逆ベキ乗法
        double lambda = inverse(a, x);

        Console.WriteLine();
        Console.WriteLine("eigenvalue");
        Console.WriteLine(string.Format("{0,14:F10}", lambda));

        Console.WriteLine("eigenvector");
        disp_vector(x);
    }

    // 逆ベキ乗法
    private static double inverse(double[,] a, double[] x0)
    {
        double lambda = 0.0;

        // 正規化 (ベクトル x0 の長さを1にする)
        normarize(x0);
        double e0 = 0.0;
        for (int i = 0; i < N; i++)
            e0 += x0[i];

        for (int k = 1; k <= 200; k++)
        {
            // 1次元配列を表示
            Console.Write(string.Format("{0,3:D}\t", k));
            disp_vector(x0);

            // Ly = b から y を求める (前進代入)
            double[] b = new double[N];
            double[] y = new double[N];
            for (int i = 0; i < N; i++)
                b[i] = x0[i];
            forward_substitution(a,y,b);
            // Ux = y から x を求める (後退代入)
            double[] x1 = new double[N];
            backward_substitution(a,x1,y);

            // 内積
            double p0 = 0.0;
            double p1 = 0.0;
            for (int i = 0; i < N; i++)
            {
                p0 += x1[i] * x1[i];
                p1 += x1[i] * x0[i];
            }
            // 固有値
            lambda = p1 / p0;

            // 正規化 (ベクトル x1 の長さを1にする)
            normarize(x1);
            // 収束判定
            double e1 = 0.0;
            for (int i = 0; i < N; i++)
                e1 += x1[i];
            if (Math.Abs(e0 - e1) < 0.00000000001) break;

            for (int i = 0; i < N; i++)
                x0[i] = x1[i];
            e0 = e1;
        }
        return lambda;
    }

    // LU分解
    private static void forward_elimination(double[,] a)
    {
        for (int pivot = 0; pivot < N - 1; pivot++)
        {
            for (int row = pivot + 1; row < N; row++)
            {
                double s = a[row,pivot] / a[pivot,pivot];
                for (int col = pivot; col < N; col++)
                    a[row,col] -= a[pivot,col] * s; // これが 上三角行列
                a[row,pivot] = s;                   // これが 下三角行列
            }
        }
    }
    // 前進代入
    private static void forward_substitution(double[,] a, double[] y, double[] b)
    {
        for (int row = 0; row < N; row++)
        {
            for (int col = 0; col < row; col++)
                b[row] -= a[row,col] * y[col];
            y[row] = b[row];
        }
    }
    // 後退代入
    private static void backward_substitution(double[,] a, double[] x, double[] y)
    {
        for (int row = N - 1; row >= 0; row--)
        {
            for (int col = N - 1; col > row; col--)
                y[row] -= a[row,col] * x[col];
            x[row] = y[row] / a[row,row];
        }
    }

    // 1次元配列を表示
    private static void disp_vector(double[] row)
    {
        foreach (double col in row)
            Console.Write(string.Format("{0,14:F10}\t", col));
        Console.WriteLine();
    }
    // 正規化 (ベクトルの長さを1にする)
    private static void normarize(double[] x)
    {
        double s = 0.0;

        for (int i = 0; i < N; i++)
            s += x[i] * x[i];
        s = Math.Sqrt(s);

        for (int i = 0; i < N; i++)
            x[i] /= s;
    }
}
Z:\>csc -nologo CS1102.cs

Z:\>CS1102
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812    0.0000000000    0.0000000000
 16   0.7071067812   -0.7071067812    0.0000000000    0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

Java

import java.lang.*;

public class Java1102 {

    private static final int N = 4;

    // 逆ベキ乗法で最小固有値を求める
    public static void main(String []args) {
        double[][] a = {{5.0, 4.0, 1.0, 1.0},
                        {4.0, 5.0, 1.0, 1.0},
                        {1.0, 1.0, 4.0, 2.0},
                        {1.0, 1.0, 2.0, 4.0}};
        double[]   x  = {1.0 ,0.0 ,0.0 ,0.0};

        // LU分解
        forward_elimination(a);

        // 逆ベキ乗法
        double lambda = inverse(a, x);

        System.out.println();
        System.out.println("eigenvalue");
        System.out.println(String.format("%14.10f", lambda));

        System.out.println("eigenvector");
        disp_vector(x);
    }

    // 逆ベキ乗法
    private static double inverse(double[][] a, double[] x0) {
        double lambda = 0.0;

        // 正規化 (ベクトル x0 の長さを1にする)
        normarize(x0);
        double e0 = 0.0;
        for (int i = 0; i < N; i++)
            e0 += x0[i];

        for (int k = 1; k <= 100; k++) {
            // 正規化 (ベクトル x0 の長さを1にする)
            normarize(x0);
            // 1次元配列を表示
            System.out.print(String.format("%3d\t", k));
            disp_vector(x0);

            // Ly = b から y を求める (前進代入)
            double[] b = new double[N];
            double[] y = new double[N];
            for (int i = 0; i < N; i++)
                b[i] = x0[i];
            forward_substitution(a,y,b);
            // Ux = y から x を求める (後退代入)
            double[] x1 = new double[N];
            backward_substitution(a,x1,y);

            // 内積
            double p0 = 0.0;
            double p1 = 0.0;
            for (int i = 0; i < N; i++) {
                p0 += x1[i] * x1[i];
                p1 += x1[i] * x0[i];
            }
            // 固有値
            lambda = p1 / p0;

            // 正規化 (ベクトル x1 の長さを1にする)
            normarize(x1);
            // 収束判定
            double e1 = 0.0;
            for (int i = 0; i < N; i++)
                e1 += x1[i];
            if (Math.abs(e0 - e1) < 0.00000000001) break;

            for (int i = 0; i < N; i++)
                x0[i] = x1[i];
            e0 = e1;
        }
        return lambda;
    }

    // LU分解
    private static void forward_elimination(double[][] a) {
        for (int pivot = 0; pivot < N - 1; pivot++) {
            for (int row = pivot + 1; row < N; row++) {
                double s = a[row][pivot] / a[pivot][pivot];
                for (int col = pivot; col < N; col++)
                    a[row][col] -= a[pivot][col] * s; // これが 上三角行列
                a[row][pivot] = s;                    // これが 下三角行列
            }
        }
    }
    // 前進代入
    private static void forward_substitution(double[][] a, double[] y, double[] b) {
        for (int row = 0; row < N; row++) {
            for (int col = 0; col < row; col++)
                b[row] -= a[row][col] * y[col];
            y[row] = b[row];
        }
    }
    // 後退代入
    private static void backward_substitution(double[][] a, double[] x, double[] y) {
        for (int row = N - 1; row >= 0; row--) {
            for (int col = N - 1; col > row; col--)
                y[row] -= a[row][col] * x[col];
            x[row] = y[row] / a[row][row];
        }
    }

    // 1次元配列を表示
    private static void disp_vector(double[] row) {
        for (double col: row)
            System.out.print(String.format("%14.10f\t", col));
        System.out.println();
    }
    // 正規化 (ベクトルの長さを1にする)
    private static void normarize(double[] x) {
        double s = 0.0;

        for (int i = 0; i < N; i++)
            s += x[i] * x[i];
        s = Math.sqrt(s);

        for (int i = 0; i < N; i++)
            x[i] /= s;
    }
}
Z:\>javac Java1102.java

Z:\>java Java1102
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

C++

#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;

const int N = 4;

// 逆ベキ乗法
double inverse(double a[N][N], double x0[N]);
// LU分解
void forward_elimination(double a[N][N]);
// 前進代入
void forward_substitution(double a[N][N], double y[N], double b[N]);
// 後退代入
void backward_substitution(double a[N][N], double x[N], double y[N]);
// 1次元配列を表示
void disp_vector(double row[N]);
// 正規化 (ベクトルの長さを1にする)
void normarize(double x[N]);

// 逆ベキ乗法で最小固有値を求める
int main()
{
    double a[N][N] = {{5.0, 4.0, 1.0, 1.0},
                      {4.0, 5.0, 1.0, 1.0},
                      {1.0, 1.0, 4.0, 2.0},
                      {1.0, 1.0, 2.0, 4.0}};
    double x[N]    =  {1.0 ,0.0 ,0.0 ,0.0};

    // LU分解
    forward_elimination(a);

    // 逆ベキ乗法
    double lambda = inverse(a, x);

    cout << endl << "eigenvalue" << endl;
    cout << setw(14) << fixed << setprecision(10) << lambda;

    cout << endl << "eigenvector" << endl;
    disp_vector(x);

    return 0;
}

// 逆ベキ乗法
double inverse(double a[N][N], double x0[N])
{
    double lambda = 0.0;

    // 正規化 (ベクトル x0 の長さを1にする)
    normarize(x0);
    double e0 = 0.0;
    for (int i = 0; i < N; i++)
        e0 += x0[i];

    for (int k = 1; k <= 100; k++)
    {
        // 1次元配列を表示
        cout << setw(3) << k << "\t";
        disp_vector(x0);

        // Ly = b から y を求める (前進代入)
        double b[N] = {0.0 ,0.0 ,0.0 ,0.0};
        double y[N] = {0.0 ,0.0 ,0.0 ,0.0};
        for (int i = 0; i < N; i++)
            b[i] = x0[i];
        forward_substitution(a,y,b);
        // Ux = y から x を求める (後退代入)
        double x1[N] = {0.0 ,0.0 ,0.0 ,0.0};
        backward_substitution(a,x1,y);

        // 内積
        double p0 = 0.0;
        double p1 = 0.0;
        for (int i = 0; i < N; i++)
        {
            p0 += x1[i] * x1[i];
            p1 += x1[i] * x0[i];
        }
        // 固有値
        lambda = p1 / p0;

        // 正規化 (ベクトル x1 の長さを1にする)
        normarize(x1);
        // 収束判定
        double e1 = 0.0;
        for (int i = 0; i < N; i++)
            e1 += x1[i];
        if (fabs(e0 - e1) < 0.00000000001) break;

        for (int i = 0; i < N; i++)
            x0[i] = x1[i];
        e0 = e1;
    }
    return lambda;
}
// LU分解
void forward_elimination(double a[N][N])
{
    for (int pivot = 0; pivot < N - 1; pivot++)
    {
        for (int row = pivot + 1; row < N; row++)
        {
            double s = a[row][pivot] / a[pivot][pivot];
            for (int col = pivot; col < N; col++)
                a[row][col] -= a[pivot][col] * s; // これが 上三角行列
            a[row][pivot] = s;                    // これが 下三角行列
        }
    }
}
// 前進代入
void forward_substitution(double a[N][N], double y[N], double b[N])
{
    for (int row = 0; row < N; row++)
    {
        for (int col = 0; col < row; col++)
            b[row] -= a[row][col] * y[col];
        y[row] = b[row];
    }
}
// 後退代入
void backward_substitution(double a[N][N], double x[N], double y[N])
{
    for (int row = N - 1; row >= 0; row--)
    {
        for (int col = N - 1; col > row; col--)
            y[row] -= a[row][col] * x[col];
        x[row] = y[row] / a[row][row];
    }
}
// 1次元配列を表示
void disp_vector(double row[N])
{
    for (int i = 0; i < N; i++)
        cout << setw(14) << fixed << setprecision(10) << row[i] << "\t";
    cout << endl;
}
// 正規化 (ベクトルの長さを1にする)
void normarize(double x[N])
{
    double s = 0.0;

    for (int i = 0; i < N; i++)
        s += x[i] * x[i];
    s = sqrt(s);

    for (int i = 0; i < N; i++)
        x[i] /= s;
}
Z:\>bcc32 -q CP1102.cpp
cp1102.cpp:

Z:\>CP1102
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

Objective-C

#import <Foundation/Foundation.h>
#import <math.h>

#define N 4

// 逆ベキ乗法
double inverse(double a[N][N], double x0[N]);
// LU分解
void forward_elimination(double a[N][N]);
// 前進代入
void forward_substitution(double a[N][N], double y[N], double b[N]);
// 後退代入
void backward_substitution(double a[N][N], double x[N], double y[N]);
// 1次元配列を表示
void disp_vector(double row[N]);
// 正規化 (ベクトルの長さを1にする)
void normarize(double x[N]);

// 逆ベキ乗法で最小固有値を求める
int main()
{
    double a[N][N] = {{5.0, 4.0, 1.0, 1.0},
                      {4.0, 5.0, 1.0, 1.0},
                      {1.0, 1.0, 4.0, 2.0},
                      {1.0, 1.0, 2.0, 4.0}};
    double x[N]    =  {1.0 ,0.0 ,0.0 ,0.0};

    // LU分解
    forward_elimination(a);

    // 逆ベキ乗法 Inverse iteration
    double lambda = inverse(a, x);

    printf("\neigenvalue\n");
    printf("%14.10f\n", lambda);

    printf("eigenvector\n");
    disp_vector(x);

    return 0;
}

// 逆ベキ乗法
double inverse(double a[N][N], double x0[N])
{
    int i, j, k;
    double lambda = 0.0;

    // 正規化 (ベクトル x0 の長さを1にする)
    normarize(x0);
    double e0 = 0.0;
    for (i = 0; i < N; i++)
        e0 += x0[i];

    for (k = 1; k <= 200; k++)
    {
        // 1次元配列を表示
        printf("%3d\t", k);
        disp_vector(x0);

        // Ly = b から y を求める (前進代入)
        double b[N] = {0.0 ,0.0 ,0.0 ,0.0};
        double y[N] = {0.0 ,0.0 ,0.0 ,0.0};
        for (i = 0; i < N; i++)
            b[i] = x0[i];
        forward_substitution(a,y,b);
        // Ux = y から x を求める (後退代入)
        double x1[N] = {0.0 ,0.0 ,0.0 ,0.0};
        backward_substitution(a,x1,y);

        // 内積
        double p0 = 0.0;
        double p1 = 0.0;
        for (i = 0; i < N; i++)
        {
            p0 += x1[i] * x1[i];
            p1 += x1[i] * x0[i];
        }
        // 固有値
        lambda = p1 / p0;

        // 正規化 (ベクトル x1 の長さを1にする)
        normarize(x1);
        double e1 = 0.0;
        // 収束判定
        for (i = 0; i < N; i++)
            e1 += x1[i];
        if (fabs(e0 - e1) < 0.00000000001) break;

        for (i = 0; i < N; i++)
            x0[i] = x1[i];
        e0 = e1;
    }
    return lambda;
}
// LU分解
void forward_elimination(double a[N][N])
{
    int pivot, row, col;
    for (pivot = 0; pivot < N - 1; pivot++)
    {
        for (row = pivot + 1; row < N; row++)
        {
            double s = a[row][pivot] / a[pivot][pivot];
            for (col = pivot; col < N; col++)
                a[row][col] -= a[pivot][col] * s; // これが 上三角行列
            a[row][pivot] = s;                    // これが 下三角行列
        }
    }
}
// 前進代入
void forward_substitution(double a[N][N], double y[N], double b[N])
{
    int row, col;
    for (row = 0; row < N; row++)
    {
        for (col = 0; col < row; col++)
            b[row] -= a[row][col] * y[col];
        y[row] = b[row];
    }
}
// 後退代入
void backward_substitution(double a[N][N], double x[N], double y[N])
{
    int row, col;
    for (row = N - 1; row >= 0; row--)
    {
        for (col = N - 1; col > row; col--)
            y[row] -= a[row][col] * x[col];
        x[row] = y[row] / a[row][row];
    }
}
// 1次元配列を表示
void disp_vector(double row[N])
{
    int i;
    for (i = 0; i < N; i++)
        printf("%14.10f\t", row[i]);
    printf("\n");
}
// 正規化 (ベクトルの長さを1にする)
void normarize(double x[N])
{
    int i;
    double s = 0.0;

    for (i = 0; i < N; i++)
        s += x[i] * x[i];
    s = sqrt(s);

    for (i = 0; i < N; i++)
        x[i] /= s;
}
xxxxxx@yyyyyy /Z
$ gcc -o OC1102 OC1102.m -lobjc -lgnustep-base -I $INCLUDE -L $LIB $CFLAGS

xxxxxx@yyyyyy /Z
$ OC1102
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

D

import std.stdio;
import std.math;

const int N = 4;

// 逆ベキ乗法で最小固有値を求める
void main(string[] args)
{
    double a[N][N] = [[5.0, 4.0, 1.0, 1.0],
                      [4.0, 5.0, 1.0, 1.0],
                      [1.0, 1.0, 4.0, 2.0],
                      [1.0, 1.0, 2.0, 4.0]];
    double x[N]    =  [1.0 ,0.0 ,0.0 ,0.0];

    // LU分解
    forward_elimination(a);

    // 逆ベキ乗法
    double lambda = inverse(a, x);

    writefln("\neigenvalue");
    writefln("%14.10f", lambda);

    writefln("eigenvector");
    disp_vector(x);
}

// 逆ベキ乗法
double inverse(double[N][N] a, ref double[N] x0)
{
    double lambda = 0.0;

    // 正規化 (ベクトル x0 の長さを1にする)
    normarize(x0);
    double e0 = 0.0;
    foreach (i; 0..N)
        e0 += x0[i];

    foreach (k; 1..200)
    {
        // 1次元配列を表示
        writef("%3d\t", k);
        disp_vector(x0);

        // Ly = b から y を求める (前進代入)
        double[N] b = [0.0 ,0.0 ,0.0 ,0.0];
        double[N] y = [0.0 ,0.0 ,0.0 ,0.0];
        foreach (i; 0..N)
            b[i] = x0[i];
        forward_substitution(a,y,b);
        // Ux = y から x を求める (後退代入)
        double[N] x1 = [0.0 ,0.0 ,0.0 ,0.0];
        backward_substitution(a,x1,y);

        // 内積
        double p0 = 0.0;
        double p1 = 0.0;
        foreach (i; 0..N)
        {
            p0 += x1[i] * x1[i];
            p1 += x1[i] * x0[i];
        }
        // 固有値
        lambda = p1 / p0;

        // 正規化 (ベクトル x1 の長さを1にする)
        normarize(x1);
        // 収束判定
        double e1 = 0.0;
        foreach (i; 0..N)
            e1 += x1[i];
        if (fabs(e0 - e1) < 0.00000000001) break;

        foreach (i; 0..N)
            x0[i] = x1[i];
        e0 = e1;
    }
    return lambda;
}
// LU分解
void forward_elimination(ref double[N][N] a)
{
    foreach (pivot; 0..N)
    {
        foreach (row; (pivot + 1)..N)
        {
            double s = a[row][pivot] / a[pivot][pivot];
            foreach (col; pivot..N)
                a[row][col] -= a[pivot][col] * s; // これが 上三角行列
            a[row][pivot] = s;                    // これが 下三角行列
        }
    }
}
// 前進代入
void forward_substitution(double[N][N] a, ref double[N] y, ref double[N] b)
{
    foreach (row; 0..N)
    {
        foreach (col; 0..row)
            b[row] -= a[row][col] * y[col];
        y[row] = b[row];
    }
}
// 後退代入
void backward_substitution(double[N][N] a, ref double[N] x, ref double[N] y)
{
    foreach_reverse (row; 0..N)
    {
        foreach_reverse (col; (row+1)..N)
            y[row] -= a[row][col] * x[col];
        x[row] = y[row] / a[row][row];
    }
}
// 1次元配列を表示
void disp_vector(double[N] row)
{
    foreach(col; row)
        writef("%14.10f\t", col);
    writefln("");
}
// 正規化 (ベクトルの長さを1にする)
void normarize(ref double[N] x)
{
    double s = 0.0;

    foreach (i; 0..N)
        s += x[i] * x[i];
    s = sqrt(s);

    foreach (i; 0..N)
        x[i] /= s;
}
Z:\>dmd D1102.d

Z:\>D1102
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606766   -0.0280606766
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242639   -0.0004242639
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178190   -0.0000178190
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000057   -0.0000000057
 13   0.7071067818   -0.7071067806   -0.0000000011   -0.0000000011
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

Go

package main

import "fmt"
import "math"

const N = 4

func main() {
    var a [N][N]float64 = [N][N]float64{{5.0, 4.0, 1.0, 1.0},
                                        {4.0, 5.0, 1.0, 1.0},
                                        {1.0, 1.0, 4.0, 2.0},
                                        {1.0, 1.0, 2.0, 4.0}}
    var x               = []float64     {1.0 ,0.0 ,0.0 ,0.0}

    // LU分解
    forward_elimination(&a)

    // 逆ベキ乗法
    var lambda float64 = inverse(a, x)

    fmt.Println("\neigenvalue")
    fmt.Printf("%14.10f\n", lambda)

    fmt.Println("eigenvector")
    disp_vector(x)
}

// 逆ベキ乗法
func inverse(a[N][N]float64, x0[]float64) float64 {
    var lambda float64 = 0.0

    // 正規化 (ベクトル x0 の長さを1にする)
    normarize(x0)
    var e0 float64 = 0.0
    for i := 0; i < N; i++ {
        e0 += x0[i]
    }

    for k := 1; k < 200; k++ {
        // 1次元配列を表示
        fmt.Printf("%3d\t", k)
        disp_vector(x0)

        // Ly = b から y を求める (前進代入)
        var b = []float64 {0.0 ,0.0 ,0.0 ,0.0}
        var y = []float64 {0.0 ,0.0 ,0.0 ,0.0}
        for i := 0; i < N; i++ {
            b[i] = x0[i]
        }
        forward_substitution(a,y,b)
        // Ux = y から x を求める (後退代入)
        var x1 = []float64 {0.0 ,0.0 ,0.0 ,0.0}
        backward_substitution(a,x1,y)

        // 内積
        var p0 float64 = 0.0
        var p1 float64 = 0.0
        for i := 0; i < N; i++ {
            p0 += x1[i] * x1[i]
            p1 += x1[i] * x0[i]
        }
        // 固有値
        lambda = p1 / p0

        // 正規化 (ベクトル x1 の長さを1にする)
        normarize(x1)
        // 収束判定
        var e1 float64 = 0.0
        for i := 0; i < N; i++ {
            e1 += x1[i]
        }
        if (math.Abs(e0 - e1) < 0.00000000001) {
            break
        }

        for i := 0; i < N; i++ {
            x0[i] = x1[i]
        }
        e0 = e1
    }
    return lambda
}
// LU分解
func forward_elimination(a *[N][N]float64) {
    for pivot := 0; pivot < N - 1; pivot++ {
        for row := pivot + 1; row < N; row++ {
            var s = a[row][pivot] / a[pivot][pivot]
            for col := pivot; col < N; col++ {
                a[row][col] -= a[pivot][col] * s  // これが 上三角行列
            }
            a[row][pivot] = s                     // これが 下三角行列
        }
    }
}
// 前進代入
func forward_substitution(a [N][N]float64, y []float64, b []float64) {
    for row := 0; row < N; row++ {
        for col := 0; col < row; col++ {
            b[row] -= a[row][col] * y[col]
        }
        y[row] = b[row]
    }
}
// 後退代入
func backward_substitution(a [N][N]float64, x []float64, y []float64) {
    for row := N - 1; row >= 0; row-- {
        for col := N - 1; col > row; col-- {
            y[row] -= a[row][col] * x[col]
        }
        x[row] = y[row] / a[row][row]
    }
}
// 1次元配列を表示
func disp_vector(row[]float64) {
    for _, col := range row {
        fmt.Printf("%14.10f\t", col)
    }
    fmt.Println("")
}
// 正規化 (ベクトルの長さを1にする)
func normarize(x[]float64) {
    var s float64 = 0.0

    for i := 0; i < N; i++ {
        s += x[i] * x[i]
    }
    s = math.Sqrt(s)

    for i := 0; i < N; i++ {
        x[i] /= s
    }
}
Z:\>go run GO1102.go
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

Scala

object Scala1102 {
    val N = 3

    // 逆ベキ乗法で最小固有値を求める
    def main(args: Array[String]) {
        var a:Array[Array[Double]] = Array(Array(5.0, 4.0, 1.0, 1.0)
                                          ,Array(4.0, 5.0, 1.0, 1.0)
                                          ,Array(1.0, 1.0, 4.0, 2.0)
                                          ,Array(1.0, 1.0, 2.0, 4.0))

        var x:Array[Double] =              Array(1.0 ,0.0 ,0.0 ,0.0)

        // LU分解
        forward_elimination(a)

        // 逆ベキ乗法
        val (lambda, x1) = inverse(a, x)

        println()
        println("eigenvalue")
        println("%14.10f".format(lambda))

        println("eigenvector")
        disp_vector(x1)
    }

    // 逆ベキ乗法
    def inverse(a:Array[Array[Double]], x:Array[Double]): (Double, Array[Double]) = {
        var x0:Array[Double] = normarize(x)
        var x1:Array[Double] = Array(0.0 ,0.0 ,0.0 ,0.0)
        var lambda:Double    = 0.0
        var e:Double         = 0.0
        var k = 1
        do {
            e  = x0.sum
            // 1次元配列を表示
            print("%3d\t".format(k))
            disp_vector(x0)
            k += 1

            // Ly = b から y を求める (前進代入)
            var b = x0.clone
            var y:Array[Double] = Array(0.0 ,0.0 ,0.0 ,0.0)
            forward_substitution(a,y,b)

            // Ux = y から x を求める (後退代入)
            x1 = Array(0.0 ,0.0 ,0.0 ,0.0)
            backward_substitution(a,x1,y)

            // 内積
            var (t1, t2) = (x0 zip x1).map(t => t match {case (f, s) => (s * s, s * f)}).unzip
            // 固有値
            lambda = t2.sum / t1.sum

            // 正規化 (ベクトル x1 の長さを1にする)
            x1 = normarize(x1)
            x0 = x1.clone
        } while (k <= 100 && Math.abs(e - x1.sum) >= 0.00000000001)

        return (lambda, x0)
    }

    // LU分解
    def forward_elimination(a:Array[Array[Double]]) {
        for (pivot <- 0 to N - 1) {
            for (row <- pivot + 1 to N) {
                var s:Double = a(row)(pivot) / a(pivot)(pivot)
                for (col <- pivot to N)
                    a(row)(col) -= a(pivot)(col)    * s // これが 上三角行列
                a(row)(pivot) = s                       // これが 下三角行列
            }
        }
    }
    // 前進代入
    def forward_substitution(a:Array[Array[Double]], y:Array[Double], b:Array[Double]) {
        for (row <- 0 to N) {
            for (col <- 0 to row - 1)
                b(row) -= a(row)(col) * y(col)
            y(row) = b(row)
        }
    }
    // 後退代入
    def backward_substitution(a:Array[Array[Double]], x:Array[Double], y:Array[Double]) {
        for (row <- (0 to N).reverse) {
            for (col <- (row + 1 to N).reverse)
                y(row) -= a(row)(col) * x(col)
            x(row) = y(row) / a(row)(row)
        }
    }

    // 1次元配列を表示
    def disp_vector(row:Array[Double]) = {
        row.foreach { col =>
            print("%14.10f\t".format(col))
        }
        println()
    }
    // 正規化 (ベクトルの長さを1にする)
    def normarize(x:Array[Double]):Array[Double] = {
        var s:Double = x.map(n => n * n).sum
        s = Math.sqrt(s)
        x.map(n => n / s)
    }
}
Z:\>scala Scala1102.scala
  1   1.0000000000    0.0000000000    0.0000000000    0.0000000000
  2   0.7856989466   -0.6173348866   -0.0280606767   -0.0280606767
  3   0.7182768487   -0.6956539558   -0.0084835848   -0.0084835848
  4   0.7087990176   -0.7054049282   -0.0019798855   -0.0019798855
  5   0.7073894400   -0.7068237547   -0.0004242640   -0.0004242640
  6   0.7071576856   -0.7070558622   -0.0000876812   -0.0000876812
  7   0.7071163975   -0.7070971642   -0.0000178191   -0.0000178191
  8   0.7071086479   -0.7071049144   -0.0000035921   -0.0000035921
  9   0.7071071489   -0.7071064135   -0.0000007212   -0.0000007212
 10   0.7071068542   -0.7071067082   -0.0000001445   -0.0000001445
 11   0.7071067957   -0.7071067666   -0.0000000289   -0.0000000289
 12   0.7071067841   -0.7071067783   -0.0000000058   -0.0000000058
 13   0.7071067818   -0.7071067806   -0.0000000012   -0.0000000012
 14   0.7071067813   -0.7071067811   -0.0000000002   -0.0000000002
 15   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000
 16   0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

F#

module Fs1102

open System

let N = 3

// LU分解
let forward_elimination (a:float[][]) =
    for pivot in [0..N - 1] do
        for row in [pivot + 1 .. N] do
            let s:float = a.[row].[pivot] / a.[pivot].[pivot]
            for col in [pivot..N] do
                a.[row].[col] <- a.[row].[col] - a.[pivot].[col]    * s // これが 上三角行列
            a.[row].[pivot]   <- s                                      // これが 下三角行列

// 前進代入
let forward_substitution (a:float[][]) (y:float[]) (b:float[]) =
    for row in [0..N] do
        for col in 0..(row - 1) do
            b.[row] <- b.[row] - a.[row].[col] * y.[col]
        y.[row] <- b.[row]

// 後退代入
let backward_substitution (a:float[][]) (x:float[]) (y:float[]) =
    for row in (List.rev [0..N]) do
        for col in (List.rev [row + 1 .. N]) do
            y.[row] <- y.[row] - a.[row].[col] * x.[col]
        x.[row] <- y.[row] / a.[row].[row]

// 1次元配列を表示
let disp_vector (row:float[]) =
    row |> Array.iter (fun x -> printf "%14.10f" x)
    printfn ""

// 正規化 (ベクトルの長さを1にする)
let normarize(x:float[]):float[] =
    let s = x |> Array.map (fun n -> n * n) |> Array.sum

    x |> Array.map(fun n -> n / Math.Sqrt(s))

// 逆ベキ乗法
let inverse (a:float[][]) (x:float[]) : float * float[] =
    let mutable x0:float[] = normarize x
    let mutable x1:float[] = [|0.0 ;0.0 ;0.0 ;0.0|]

    let mutable lambda = 0.0
    let mutable e      = 0.0
    let mutable k      = 1
    let mutable sw     = true
    while sw || (k <= 100 && Math.Abs(e - (x1 |> Array.sum)) >= 0.00000000001) do
        if sw then sw <- false

        e <- x0 |> Array.sum
        // 1次元配列を表示
        printf "%3d\t" k
        disp_vector x0
        k <- k + 1

        // Ly = b から y を求める (前進代入)
        let mutable b         = Array.copy x0
        let mutable y:float[] = [|0.0 ;0.0 ;0.0 ;0.0|]
        forward_substitution a y b

        // Ux = y から x を求める (後退代入)
        let mutable x1 = [|0.0 ;0.0 ;0.0 ;0.0|]
        backward_substitution a x1 y

        // 内積
        let t1, t2 = Array.zip x0 x1
                     |> Array.map(fun t -> match t with | (f, s) -> (s * s, s * f))
                     |> Array.unzip

        // 固有値
        lambda <- (t2 |> Array.sum) / (t1 |> Array.sum)

        // 正規化 (ベクトル x1 の長さを1にする)
        x1 <- normarize x1
        x0 <- Array.copy x1

    (lambda, x0)

// 逆ベキ乗法で最小固有値を求める

let mutable a:float[][] = [| [|5.0; 4.0; 1.0; 1.0|];
                             [|4.0; 5.0; 1.0; 1.0|];
                             [|1.0; 1.0; 4.0; 2.0|];
                             [|1.0; 1.0; 2.0; 4.0|] |]
let mutable x:float[]   =    [|1.0 ;0.0 ;0.0 ;0.0|]

// LU分解
forward_elimination a

// 逆ベキ乗法
let (lambda, x1) = inverse a x

printfn ""
printfn "eigenvalue"
printfn "%14.10f" lambda

printfn "eigenvector"
disp_vector x1

exit 0
Z:\>fsi  --nologo --quiet Fs1102.fs
  1   1.0000000000  0.0000000000  0.0000000000  0.0000000000
  2   0.7856989466 -0.6173348866 -0.0280606767 -0.0280606767
  3   0.7182768487 -0.6956539558 -0.0084835848 -0.0084835848
  4   0.7087990176 -0.7054049282 -0.0019798855 -0.0019798855
  5   0.7073894400 -0.7068237547 -0.0004242640 -0.0004242640
  6   0.7071576856 -0.7070558622 -0.0000876812 -0.0000876812
  7   0.7071163975 -0.7070971642 -0.0000178191 -0.0000178191
  8   0.7071086479 -0.7071049144 -0.0000035921 -0.0000035921
  9   0.7071071489 -0.7071064135 -0.0000007212 -0.0000007212
 10   0.7071068542 -0.7071067082 -0.0000001445 -0.0000001445
 11   0.7071067957 -0.7071067666 -0.0000000289 -0.0000000289
 12   0.7071067841 -0.7071067783 -0.0000000058 -0.0000000058
 13   0.7071067818 -0.7071067806 -0.0000000012 -0.0000000012
 14   0.7071067813 -0.7071067811 -0.0000000002 -0.0000000002
 15   0.7071067812 -0.7071067812  0.0000000000  0.0000000000
 16   0.7071067812 -0.7071067812  0.0000000000  0.0000000000

eigenvalue
  1.0000000000
eigenvector
  0.7071067812 -0.7071067812  0.0000000000  0.0000000000

Clojure

Haskell

inserted by FC2 system