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

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

Only Do What Only You Can Do

ハウスホルダー法

ハウスホルダー法を使って, 全ての固有値と, 対応する固有ベクトルを求める

対称行列 $ \boldsymbol{A} $ を, 以下のように分割して考える.

それに対応する, 以下のような対称行列 $ \boldsymbol{P} $ を考える.
$ \boldsymbol{A} $ に、 左右から行列 $ \boldsymbol{P} $ と 転置行列 $ \boldsymbol{P}^T $ をかける.
このとき
となるように $ \boldsymbol{P} $ を設定して 処理を反復すると, 三重対角行列が得られる.
得られた三重対角行列から, QR分解によって, 固有値・固有ベクトルを求める.

VBScript

Option Explicit

Private Const N  = 3

'ハウスホルダー変換とQR分解で固有値を求める
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 d: d = Array(0.0 ,0.0 ,0.0 ,0.0)
    Dim e: e = Array(0.0 ,0.0 ,0.0 ,0.0)

    'ハウスホルダー変換
    Call tridiagonalize(a, d, e)

    'QR分解
    Call decomp(a, d, e)

    WScript.StdOut.WriteLine
    WScript.StdOut.WriteLine "eigenvalue"
    Call disp_vector(d)

    WScript.StdOut.WriteLine
    WScript.StdOut.WriteLine "eigenvector"
    Call disp_matrix(a)
End Sub

'ハウスホルダー変換
Private Sub tridiagonalize(ByRef a, ByRef d, ByRef e)
    Dim v: v = Array(0.0 ,0.0 ,0.0 ,0.0)

    Dim i, j, k
    For k = 0 To N - 2
        d(k) = a(k)(k)

        Dim t: t = 0.0
        Dim w: w = Array(0.0, 0.0, 0.0, 0.0)
        For i = k + 1 To N
            w(i) = a(i)(k)
            t    = t + w(i) * w(i)
        Next

        Dim s: s = Sqr(t)
        If w(k + 1) < 0 Then
            s = -s
        End If

        If Abs(s) < 0.00000000001 Then
            e(k + 1) = 0.0
        Else
            e(k + 1) = -s
            w(k + 1) = w(k + 1) + s
            s = 1 / Sqr(w(k + 1) * s)
            For i = k + 1 To N
                w(i) = w(i) * s
            Next

            For i = k + 1 To N
                s = 0.0
                For j = k + 1 To N
                    If j <= i Then
                        s = s + a(i)(j) * w(j)
                    Else
                        s = s + a(j)(i) * w(j)
                    End If
                Next
                v(i) = s
            Next

            s = 0
            For i = k + 1 To N
                s = s + w(i) * v(i)
            Next
            s = s / 2
            For i = k + 1 To N
                v(i) = v(i) - s * w(i)
            Next
            For i = k + 1 To N
                For j = k + 1 To i
                    a(i)(j) = a(i)(j) - w(i) * v(j) - w(j) * v(i)
                Next
            Next
            '次の行は固有ベクトルを求めないなら不要
            For i = k + 1 To N
                a(i)(k) = w(i)
            Next
        End If
    Next

    d(N - 1) = a(N - 1)(N - 1)
    d(N)     = a(N)(N)

    e(0)     = 0.0
    e(N)     = a(N)(N - 1)

    '次の行は固有ベクトルを求めないなら不要
    For k = N To 0 Step -1
        If k < N - 1 Then
            For i = k + 1 To N
                w(i) = a(i)(k)
            Next
            For i = k + 1 To N
                s = 0.0
                For j = k + 1 To N
                    s = s + a(i)(j) * w(j)
                Next
                v(i) = s
            Next
            For i = k + 1 To N
                For j = k + 1 To N
                    a(i)(j) = a(i)(j) - v(i) * w(j)
                Next
            Next
        End If
        For i = 0 To N
            a(i)(k) = 0.0
        Next
        a(k)(k) = 1.0
    Next
End Sub

'QR分解
Private Sub decomp(ByRef a, ByRef d, ByRef e)
    Dim i, j, k

    e(0) = 1.0
    Dim h: h = N
    Do While (Abs(e(h)) < 0.00000000001)
        h = h - 1
    Loop

    Do While h > 0
        e(0) = 0.0
        Dim l: l = h - 1
        Do While (Abs(e(l)) >= 0.00000000001)
            l = l - 1
        Loop
        For j = 1 To 100
            Dim w: w = (d(h - 1) - d(h)) / 2.0
            Dim s: s = Sqr(w * w + e(h) * e(h))
            If w < 0.0 Then
                s = - s
            End If

            Dim x: x = d(l) - d(h) + e(h) * e(h) / (w + s)
            Dim y: y = e(l + 1)
            Dim z: z = 0.0
            Dim t, u
            For k = l To h - 1
                If Abs(x) >= Abs(y) Then
                    t = -y / x
                    u = 1 / Sqr(t * t + 1.0)
                    s = t * u
                Else
                    t = -x / y
                    s = 1 / Sqr(t * t + 1.0)
                    If t < 0 Then
                        s = -s
                    End If
                    u = t * s
                End If
                w = d(k) - d(k + 1)
                t = (w * s + 2 * u * e(k + 1)) * s
                d(k    ) = d(k    ) - t
                d(k + 1) = d(k + 1) + t
                e(k    ) = u * e(k) - s * z
                e(k + 1) = e(k + 1) * (u * u - s * s) + w * s * u

                '次の行は固有ベクトルを求めないなら不要
                For i = 0 To N
                    x = a(k    )(i)
                    y = a(k + 1)(i)
                    a(k    )(i) = u * x - s * y
                    a(k + 1)(i) = s * x + u * y
                Next

                If k < N - 1 Then
                    x = e(k + 1)
                    y = -s * e(k + 2)
                    z = y
                    e(k + 2) = u * e(k + 2)
                End If
            Next

            WScript.StdOut.Write Right(Space(3) & j, 3) & vbTab
            Call disp_vector(d)

            '収束判定
            If (Abs(e(h)) < 0.00000000001) Then Exit For
        Next

        e(0) = 1.0
        Do While (Abs(e(h)) < 0.00000000001)
            h = h - 1
        Loop
    Loop

    '次の行は固有ベクトルを求めないなら不要
    For k = 0 To N - 1
        l = k
        For i = k + 1 To N
            If d(i) > d(l) Then
                l = i
            End If
        Next

        t    = d(k)
        d(k) = d(l)
        d(l) = t

        For i = 0 To N
            t       = a(k)(i)
            a(k)(i) = a(l)(i)
            a(l)(i) = t
        Next
    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

'2次元配列を表示
Private Sub disp_matrix(ByVal matrix())
    Dim row, col
    For Each row In matrix
        For Each col In row
            WScript.StdOut.Write Right(Space(14) & FormatNumber(col, 10, -1, 0, 0), 14) & vbTab
        Next
        WScript.StdOut.WriteLine
    Next
End Sub
Z:\>cscript //nologo Z:\1106.vbs
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

JScript

var N = 4

// ハウスホルダー変換とQR分解で固有値を求める
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 d =  [1.0 ,0.0 ,0.0 ,0.0]
    var e =  [1.0 ,0.0 ,0.0 ,0.0]

    // ハウスホルダー変換
    tridiagonalize(a, d, e)

    // QR分解
    decomp(a, d, e)

    WScript.StdOut.WriteLine()
    WScript.StdOut.WriteLine("eigenvalue")
    disp_vector(d)

    WScript.StdOut.WriteLine()
    WScript.StdOut.WriteLine("eigenvector")
    disp_matrix(a)
}


// ハウスホルダー変換
function tridiagonalize(a, d, e)
{
    var v =  [0.0 ,0.0 ,0.0 ,0.0]

    for (var k = 0; k < N - 2; k++)
    {
        var w = [0.0 ,0.0 ,0.0 ,0.0]
        d[k] = a[k][k]

        var t = 0.0
        for (var i = k + 1; i < N; i++)
        {
            w[i] =  a[i][k]
            t    += w[i] * w[i]
        }
        var s = Math.sqrt(t)
        if (w[k + 1] < 0)
            s = -s

        if (Math.abs(s) < 0.00000000001)
            e[k + 1] = 0.0
        else
        {
            e[k + 1]  = -s
            w[k + 1] +=  s
            s = 1 / Math.sqrt(w[k + 1] * s)
            for (var i = k + 1; i < N; i++)
                w[i] *= s

            for (var i = k + 1; i < N; i++)
            {
                s = 0.0
                for (var j = k + 1; j < N; j++)
                {
                    if (j <= i)
                        s += a[i][j] * w[j]
                    else
                        s += a[j][i] * w[j]
                }
                v[i] = s
            }

            s = 0.0
            for (var i = k + 1; i < N; i++)
                s += w[i] * v[i]
            s /= 2.0
            for (var i = k + 1; i < N; i++)
                v[i] -= s * w[i]
            for (var i = k + 1; i < N; i++)
                for (var j = k + 1; j <= i; j++)
                    a[i][j] -= w[i] * v[j] + w[j] * v[i]
            // 次の行は固有ベクトルを求めないなら不要
            for (var i = k + 1; i < N; i++)
                a[i][k] = w[i]
        }
    }

    d[N - 2] = a[N - 2][N - 2]
    d[N - 1] = a[N - 1][N - 1]

    e[0]     = 0.0
    e[N - 1] = a[N - 1][N - 2]

    // 次の行は固有ベクトルを求めないなら不要
    for (var k = N - 1; k >= 0; k--)
    {
        var w = [0.0 ,0.0 ,0.0 ,0.0]
        if (k < N - 2)
        {
            for (var i = k + 1; i < N; i++)
                w[i] = a[i][k]
            for (var i = k + 1; i < N; i++)
            {
                var s = 0.0
                for (var j = k + 1; j < N; j++)
                    s += a[i][j] * w[j]
                v[i] = s
            }
            for (var i = k + 1; i < N; i++)
                for (var j = k + 1; j < N; j++)
                    a[i][j] -= v[i] * w[j]
        }
        for (var i = 0; i < N; i++)
            a[i][k] = 0.0
        a[k][k] = 1.0
    }
}

// QR分解
function decomp(a, d, e)
{
    e[0] = 1.0
    var h = N - 1
    while (Math.abs(e[h]) < 0.00000000001) h--

    while (h > 0)
    {
        e[0] = 0.0
        var l = h - 1
        while (Math.abs(e[l]) >= 0.00000000001) l--

        for (var j = 1; j <= 100; j++)
        {
            var w = (d[h - 1] - d[h]) / 2.0
            var s = Math.sqrt(w * w + e[h] * e[h])
            if (w < 0.0)
                s = -s

            var x = d[l] - d[h] + e[h] * e[h] / (w + s)
            var y = e[l + 1]
            var z = 0.0
            var t = 0.0
            var u = 0.0
            for (var k = l; k < h; k++)
            {
                if (Math.abs(x) >= Math.abs(y))
                {
                    t = -y / x
                    u = 1 / Math.sqrt(t * t + 1.0)
                    s = t * u
                }
                else
                {
                    t = -x / y
                    s = 1 / Math.sqrt(t * t + 1.0)
                    if (t < 0)
                        s = -s
                    u = t * s
                }
                w = d[k] - d[k + 1]
                t = (w * s + 2 * u * e[k + 1]) * s
                d[k    ] = d[k    ] - t
                d[k + 1] = d[k + 1] + t
                e[k    ] = u * e[k] - s * z
                e[k + 1] = e[k + 1] * (u * u - s * s) + w * s * u

                // 次の行は固有ベクトルを求めないなら不要
                for (var i = 0; i < N; i++)
                {
                    x = a[k    ][i]
                    y = a[k + 1][i]
                    a[k    ][i] = u * x - s * y
                    a[k + 1][i] = s * x + u * y
                }

                if (k < N - 2)
                {
                    x = e[k + 1]
                    y = -s * e[k + 2]
                    z = y
                    e[k + 2] = u * e[k + 2]
                }
            }

            WScript.StdOut.Write(("   "           + j).slice( -3) + "\t")
            disp_vector(d)

            // 収束判定
            if (Math.abs(e[h]) < 0.00000000001) break
        }

        e[0] = 1.0
        while (Math.abs(e[h]) < 0.00000000001) h--
    }

    // 次の行は固有ベクトルを求めないなら不要
    for (var k = 0; k < N - 1; k++)
    {
        var l = k
        for (var i = k + 1; i < N; i++)
            if (d[i] > d[l])
                l = i

        var t = d[k]
        d[k] = d[l]
        d[l] = t

        for (var i = 0; i < N; i++)
        {
            t       = a[k][i]
            a[k][i] = a[l][i]
            a[l][i] = t
        }
    }
}

// 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()
}
// 2次元配列を表示
function disp_matrix(matrix)
{
    for (var row = 0; row < N; row++)
    {
        for (var col = 0; col < N; col++)
            WScript.StdOut.Write(("              "    + matrix[row][col].toFixed(10)).slice(-14) + "\t")
        WScript.StdOut.WriteLine()
    }
}
Z:\>cscript //nologo Z:\1106.js
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

PowerShell

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

# 1次元配列を表示
function disp_vector($row)
{
    foreach ($col in $row)
    {
        Write-Host ([String]::Format("{0,14:F10}", $col)) -nonewline
    }
    Write-Host
}

# 2次元配列を表示
function disp_matrix($matrix)
{
    foreach ($row in $matrix)
    {
        foreach ($col in $row)
        {
            Write-Host ([String]::Format("{0,14:F10}", $col)) -nonewline
        }
        Write-Host
    }
}

# ハウスホルダー変換
function tridiagonalize($a, $d, $e)
{
    $v = (0.0 ,0.0 ,0.0 ,0.0)

    foreach ($k in 0..($N - 2))
    {
        $d[$k] = $a[$k][$k]
        $t     = 0.0
        $w     = (0.0, 0.0, 0.0, 0.0)
        foreach ($i in ($k + 1)..$N)
        {
            $w[$i] = $a[$i][$k]
            $t += ($w[$i] * $w[$i])
        }
        $s = [Math]::Sqrt($t)
        if ($w[$k + 1] -lt 0)
        {
            $s = -$s
        }

        if ([Math]::Abs($s) -lt 0.00000000001)
        {
            $e[$k + 1] = 0.0
        }
        else
        {
            $e[$k + 1] = -$s
            $w[$k + 1] += $s
            $s = 1 / [Math]::Sqrt($w[$k + 1] * $s)
            foreach ($i in ($k + 1)..$N)
            {
                $w[$i] *= $s
            }

            foreach ($i in ($k + 1)..$N)
            {
                $s = 0.0
                foreach ($j in ($k + 1)..$N)
                {
                    if ($j -le $i)
                    {
                        $s += $a[$i][$j] * $w[$j]
                    }
                    else
                    {
                        $s += $a[$j][$i] * $w[$j]
                    }
                }
                $v[$i] = $s
            }

            $s = 0
            foreach ($i in ($k + 1)..$N)
            {
                $s += $w[$i] * $v[$i]
            }

            $s /= 2
            foreach ($i in ($k + 1)..$N)
            {
                $v[$i] -= $s * $w[$i]
            }
            foreach ($i in ($k + 1)..$N)
            {
                foreach ($j in ($k + 1)..$i)
                {
                    $a[$i][$j] -= $w[$i] * $v[$j] + $w[$j] * $v[$i]
                }
            }
            # 次の行は固有ベクトルを求めないなら不要
            foreach ($i in ($k + 1)..$N)
            {
                $a[$i][$k] = $w[$i]
            }
        }
    }

    $d[$N - 1] = $a[$N - 1][$N - 1]
    $d[$N]     = $a[$N][$N]

    $e[0]      = 0.0
    $e[$N]     = $a[$N][$N - 1]

    # 次の行は固有ベクトルを求めないなら不要
    foreach ($k in ($N..0))
    {
        $w     = (0.0, 0.0, 0.0, 0.0)
        if ($k -lt ($N - 1))
        {
            foreach ($i in ($k + 1)..$N)
            {
                $w[$i] = $a[$i][$k]
            }
            foreach ($i in ($k + 1)..$N)
            {
                $s = 0.0
                foreach ($j in ($k + 1)..$N)
                {
                    $s += $a[$i][$j] * $w[$j]
                }
                $v[$i] = $s
            }
            foreach ($i in ($k + 1)..$N)
            {
                foreach ($j in ($k + 1)..$N)
                {
                    $a[$i][$j] -= $v[$i] * $w[$j]
                }
            }
        }
        foreach ($i in 0..$N)
        {
            $a[$i][$k] = 0.0
        }
        $a[$k][$k] = 1.0
    }
}

# QR分解
function decomp($a, $d, $e)
{
    $e[0] = 1.0
    $h = $N
    while ([Math]::Abs($e[$h]) -lt 0.00000000001)
    {
        $h--
    }

    while ($h -gt 0)
    {
        $e[0] = 0.0
        $l = $h - 1
        while ([Math]::Abs($e[$l]) -ge 0.00000000001)
        {
            $l--
        }
        foreach ($j in 1..100)
        {
            $w = ($d[$h - 1] - $d[$h]) / 2.0
            $s = [Math]::Sqrt($w * $w + $e[$h] * $e[$h])
            if ($w -lt 0.0)
            {
                $s = - $s
            }

            $x = $d[$l] - $d[$h] + $e[$h] * $e[$h] / ($w + $s)
            $y = $e[$l + 1]
            $z = 0.0
            foreach ($k in $l..($h - 1))
            {
                if ([Math]::Abs($x) -ge [Math]::Abs($y))
                {
                    $t = -$y / $x
                    $u = 1 / [Math]::Sqrt($t * $t + 1.0)
                    $s = $t * $u
                }
                else
                {
                    $t = -$x / $y
                    $s = 1 / [Math]::Sqrt($t * $t + 1.0)
                    if ($t -lt 0)
                    {
                        $s = -$s
                    }
                    $u = $t * $s
                }
                $w = $d[$k] - $d[$k + 1]
                $t = ($w * $s + 2 * $u * $e[$k + 1]) * $s
                $d[$k    ] = $d[$k    ] - $t
                $d[$k + 1] = $d[$k + 1] + $t
                $e[$k    ] = $u * $e[$k] - $s * $z
                $e[$k + 1] = $e[$k + 1] * ($u * $u - $s * $s) + $w * $s * $u

                # 次の行は固有ベクトルを求めないなら不要
                foreach ($i in 0..$N)
                {
                    $x = $a[$k    ][$i]
                    $y = $a[$k + 1][$i]
                    $a[$k    ][$i] = $u * $x - $s * $y
                    $a[$k + 1][$i] = $s * $x + $u * $y
                }

                if ($k -lt $N - 1)
                {
                    $x = $e[$k + 1]
                    $y = -$s * $e[$k + 2]
                    $z = $y
                    $e[$k + 2] = $u * $e[$k + 2]
                }
            }

            Write-Host ([String]::Format("{0,3:D}`t", $j)) -nonewline
            disp_vector $d

            # 収束判定
            if ([Math]::Abs($e[$h]) -lt 0.00000000001)
            {
                break
            }
        }

        $e[0] = 1.0
        while ([Math]::Abs($e[$h]) -lt 0.00000000001)
        {
            $h--
        }
    }

    # 次の行は固有ベクトルを求めないなら不要
    foreach ($k in 0..($N - 1))
    {
        $l = $k
        foreach ($i in ($k + 1)..$N)
        {
            if ($d[$i] -gt $d[$l])
            {
                $l = $i
            }
        }

        $t    = $d[$k]
        $d[$k] = $d[$l]
        $d[$l] = $t

        foreach ($i in 0..$N)
        {
            $t       = $a[$k][$i]
            $a[$k][$i] = $a[$l][$i]
            $a[$l][$i] = $t
        }
    }
}

# ハウスホルダー変換とQR分解で固有値を求める
$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)
$d = (0.0 ,0.0 ,0.0 ,0.0)
$e = (0.0 ,0.0 ,0.0 ,0.0)

# ハウスホルダー変換
tridiagonalize $a $d $e

# QR分解
decomp $a $d $e

Write-Host
Write-Host "固有値"
disp_vector $d

Write-Host
Write-Host "固有ベクトル"
disp_matrix $a
Z:\>powershell -file Z:\1106.ps1
  1   7.8421052632  3.1783029001  4.9795918367  2.0000000000
  2   8.4366343427  2.5633699270  4.9999957303  2.0000000000
  3   8.9326997461  2.0673002539  5.0000000000  2.0000000000
  4   9.2864656206  1.7135343794  5.0000000000  2.0000000000
  1  10.0000000000  1.0000000000  5.0000000000  2.0000000000

固有値
 10.0000000000  5.0000000000  2.0000000000  1.0000000000

固有ベクトル
  0.6324555320  0.6324555320  0.3162277660  0.3162277660
  0.3162277660  0.3162277660 -0.6324555320 -0.6324555320
  0.0000000000  0.0000000000 -0.7071067812  0.7071067812
  0.7071067812 -0.7071067812  0.0000000000  0.0000000000

Perl

use constant N => 3;

# ハウスホルダー変換とQR分解で固有値を求める
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 @d =  (0.0, 0.0, 0.0, 0.0);
    my @e =  (0.0, 0.0, 0.0, 0.0);

    # ハウスホルダー変換
    tridiagonalize(\@a, \@d, \@e);

    # QR分解
    decomp(\@a, \@d, \@e);

    print "\neigenvalue\n";
    disp_vector(\@d);

    print "\neigenvector\n";
    disp_matrix(\@a);
}

# ハウスホルダー変換
sub tridiagonalize
{
    my ($a, $d, $e) = @_;
    my @v = (0.0, 0.0, 0.0, 0.0);

    for $k (0..(N - 2))
    {
        my @w   = (0.0, 0.0, 0.0, 0.0);
        $$d[$k] = $$a[$k][$k];

        my $t = 0.0;
        for $i (($k + 1)..N)
        {
            $w[$i]  = $$a[$i][$k];
            $t     += ($w[$i] * $w[$i]);
        }
        my $s = sqrt($t);
        $s = -$s if ($w[$k + 1] < 0);

        if (abs($s) < 0.00000000001)
        {
            $$e[$k + 1] = 0.0;
        }
        else
        {
            $$e[$k + 1] = -$s;
            $w[$k + 1] +=  $s;
            $s = 1 / sqrt($w[$k + 1] * $s);
            for $i (($k + 1)..N)
            {
                $w[$i] *= $s;
            }

            for $i (($k + 1)..N)
            {
                $s = 0.0;
                for $j (($k + 1)..N)
                {
                    if ($j <= $i)
                    {
                        $s += $$a[$i][$j] * $w[$j];
                    }
                    else
                    {
                        $s += $$a[$j][$i] * $w[$j];
                    }
                }
                $v[$i] = $s;
            }

            $s = 0;
            for $i (($k + 1)..N)
            {
                $s += $w[$i] * $v[$i];
            }
            $s /= 2;
            for $i (($k + 1)..N)
            {
                $v[$i] -= $s * $w[$i];
            }
            for $i (($k + 1)..N)
            {
                for $j (($k + 1)..$i)
                {
                    $$a[$i][$j] -= $w[$i] * $v[$j] + $w[$j] * $v[$i];
                }
            }
            # 次の行は固有ベクトルを求めないなら不要
            for $i (($k + 1)..N)
            {
                $$a[$i][$k] = $w[$i];
            }
        }
    }

    $$d[N - 1] = $$a[N - 1][N - 1];
    $$d[N]     = $$a[N][N];

    $$e[0]     = 0.0;
    $$e[N]     = $$a[N][N - 1];

    # 次の行は固有ベクトルを求めないなら不要
    for $k (reverse(0..N))
    {
        $w     = (0.0, 0.0, 0.0, 0.0);
        if ($k < (N - 1))
        {
            for $i (($k + 1)..N)
            {
                $w[$i] = $$a[$i][$k];
            }
            for $i (($k + 1)..N)
            {
                $s = 0.0;
                for $j (($k + 1)..N)
                {
                    $s += $$a[$i][$j] * $w[$j];
                }
                $v[$i] = $s;
            }
            for $i (($k + 1)..N)
            {
                for $j (($k + 1)..N)
                {
                    $$a[$i][$j] -= $v[$i] * $w[$j];
                }
            }
        }
        for $i (0..N)
        {
            $$a[$i][$k] = 0.0;
        }
        $$a[$k][$k] = 1.0;
    }
}

# QR分解
sub decomp
{
    my ($a, $d, $e) = @_;

    $$e[0] = 1.0;
    my $h  = N;
    $h-- while (abs($$e[$h]) < 0.00000000001);

    while ($h > 0)
    {
        $$e[0] = 0.0;
        my $l = $h - 1;
        $l-- while (abs($$e[$l]) >= 0.00000000001);

        for $j (1..100)
        {
            my $w = ($$d[$h - 1] - $$d[$h]) / 2.0;
            my $s = sqrt($w * $w + $$e[$h] * $$e[$h]);
            $s = - $s if ($w < 0.0);

            my $x = $$d[$l] - $$d[$h] + $$e[$h] * $$e[$h] / ($w + $s);
            my $y = $$e[$l + 1];
            my $z = 0.0;
            my $t = 0.0;
            my $u = 0.0;
            for $k ($l..($h - 1))
            {
                if (abs($x) >= abs($y))
                {
                    $t = -$y / $x;
                    $u = 1 / sqrt($t * $t + 1.0);
                    $s = $t * $u;
                }
                else
                {
                    $t = -$x / $y;
                    $s = 1 / sqrt($t * $t + 1.0);
                    $s = -$s if ($t < 0.0);
                    $u = $t * $s;
                }
                $w = $$d[$k] - $$d[$k + 1];
                $t = ($w * $s + 2 * $u * $$e[$k + 1]) * $s;
                $$d[$k    ] = $$d[$k    ] - $t;
                $$d[$k + 1] = $$d[$k + 1] + $t;
                $$e[$k    ] = $u * $$e[$k] - $s * $z;
                $$e[$k + 1] = $$e[$k + 1] * ($u * $u - $s * $s) + $w * $s * $u;

                # 次の行は固有ベクトルを求めないなら不要
                for $i (0..N)
                {
                    $x = $$a[$k    ][$i];
                    $y = $$a[$k + 1][$i];
                    $$a[$k    ][$i] = $u * $x - $s * $y;
                    $$a[$k + 1][$i] = $s * $x + $u * $y;
                }

                if ($k < N - 1)
                {
                    $x = $$e[$k + 1];
                    $y = -$s * $$e[$k + 2];
                    $z = $y;
                    $$e[$k + 2] = $u * $$e[$k + 2];
                }
            }

            printf("%3d\t", $j);
            disp_vector(\@$d);

            # 収束判定
            last if (abs($$e[$h]) < 0.00000000001);
        }

        $$e[0] = 1.0;
        $h-- while (abs($$e[$h]) < 0.00000000001);
    }

    # 次の行は固有ベクトルを求めないなら不要
    for $k (0..(N - 1))
    {
        $l = $k;
        for $i (($k + 1)..N)
        {
            $l = $i if ($$d[$i] > $$d[$l]);
        }

        $t      = $$d[$k];
        $$d[$k] = $$d[$l];
        $$d[$l] = $t;

        for $i (0..N)
        {
            $t          = $$a[$k][$i];
            $$a[$k][$i] = $$a[$l][$i];
            $$a[$l][$i] = $t;
        }
    }
}

# 1次元配列を表示
sub disp_vector
{
    my ($x) = @_;
    for $i (0..N)
    {
        printf("%14.10f\t", $$x[$i]);
    }
    print "\n";
}
# 2次元配列を表示
sub disp_matrix
{
    my ($matrix) = @_;
    foreach $row (@$matrix)
    {
        foreach $col (@$row)
        {
            printf("%14.10f\t", $col);
        }
        print "\n";
    }
}

Z:\>perl Z:\1106.pl
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

PHP

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

# ハウスホルダー変換とQR分解で固有値を求める
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]];
    $d =  [0.0, 0.0, 0.0, 0.0];
    $e =  [0.0, 0.0, 0.0, 0.0];

    # ハウスホルダー変換
    tridiagonalize($a, $d, $e);

    # QR分解
    decomp($a, $d, $e);

    print "\neigenvalue\n";
    disp_vector($d);

    print "\neigenvector\n";
    disp_matrix($a);
}

# ハウスホルダー変換
function tridiagonalize(&$a, &$d, &$e)
{
    $v =  [0.0, 0.0, 0.0, 0.0];

    foreach (range(0, (N - 2)) as $k)
    {
        $w   = [0.0, 0.0, 0.0, 0.0];
        $d[$k] = $a[$k][$k];

        $t = 0.0;
        foreach (range(($k + 1), N) as $i)
        {
            $w[$i]  = $a[$i][$k];
            $t     += ($w[$i] * $w[$i]);
        }
        $s = sqrt($t);
        if ($w[$k + 1] < 0)
            $s = -$s;

        if (abs($s) < 0.00000000001)
        {
            $e[$k + 1] = 0.0;
        }
        else
        {
            $e[$k + 1] = -$s;
            $w[$k + 1] +=  $s;
            $s = 1 / sqrt($w[$k + 1] * $s);
            foreach (range(($k + 1), N) as $i)
            {
                $w[$i] *= $s;
            }

            foreach (range(($k + 1), N) as $i)
            {
                $s = 0.0;
                foreach (range(($k + 1), N) as $j)
                {
                    if ($j <= $i)
                    {
                        $s += $a[$i][$j] * $w[$j];
                    }
                    else
                    {
                        $s += $a[$j][$i] * $w[$j];
                    }
                }
                $v[$i] = $s;
            }

            $s = 0;
            foreach (range(($k + 1), N) as $i)
            {
                $s += $w[$i] * $v[$i];
            }
            $s /= 2;
            foreach (range(($k + 1), N) as $i)
            {
                $v[$i] -= $s * $w[$i];
            }
            foreach (range(($k + 1), N) as $i)
            {
                foreach (range(($k + 1), $i) as $j)
                {
                    $a[$i][$j] -= $w[$i] * $v[$j] + $w[$j] * $v[$i];
                }
            }
            # 次の行は固有ベクトルを求めないなら不要
            foreach (range(($k + 1), N) as $i)
            {
                $a[$i][$k] = $w[$i];
            }
        }
    }

    $d[N - 1] = $a[N - 1][N - 1];
    $d[N]     = $a[N][N];

    $e[0]     = 0.0;
    $e[N]     = $a[N][N - 1];

    # 次の行は固有ベクトルを求めないなら不要
    foreach (range(N, 0) as $k)
    {
        $w = [0.0, 0.0, 0.0, 0.0];
        if ($k < (N - 1))
        {
            foreach (range(($k + 1), N) as $i)
            {
                $w[$i] = $a[$i][$k];
            }
            foreach (range(($k + 1), N) as $i)
            {
                $s = 0.0;
                foreach (range(($k + 1), N) as $j)
                {
                    $s += $a[$i][$j] * $w[$j];
                }
                $v[$i] = $s;
            }
            foreach (range(($k + 1), N) as $i)
            {
                foreach (range(($k + 1), N) as $j)
                {
                    $a[$i][$j] -= $v[$i] * $w[$j];
                }
            }
        }
        foreach (range(0, N) as $i)
        {
            $a[$i][$k] = 0.0;
        }
        $a[$k][$k] = 1.0;
    }
}

# QR分解
function decomp(&$a, &$d, &$e)
{
    $e[0] = 1.0;
    $h  = N;
    while (abs($e[$h]) < 0.00000000001) $h--;

    while ($h > 0)
    {
        $e[0] = 0.0;
        $l = $h - 1;
        while (abs($e[$l]) >= 0.00000000001) $l--;

        foreach (range(1, 100) as $j)
        {
            $w = ($d[$h - 1] - $d[$h]) / 2.0;
            $s = sqrt($w * $w + $e[$h] * $e[$h]);
            if ($w < 0.0)
                $s = - $s;

            $x = $d[$l] - $d[$h] + $e[$h] * $e[$h] / ($w + $s);
            $y = $e[$l + 1];
            $z = 0.0;
            $t = 0.0;
            $u = 0.0;
            foreach (range(l, ($h - 1)) as $k)
            {
                if (abs($x) >= abs($y))
                {
                    $t = -$y / $x;
                    $u = 1 / sqrt($t * $t + 1.0);
                    $s = $t * $u;
                }
                else
                {
                    $t = -$x / $y;
                    $s = 1 / sqrt($t * $t + 1.0);
                    if ($t < 0.0)
                        $s = -$s;
                    $u = $t * $s;
                }
                $w = $d[$k] - $d[$k + 1];
                $t = ($w * $s + 2 * $u * $e[$k + 1]) * $s;
                $d[$k    ] = $d[$k    ] - $t;
                $d[$k + 1] = $d[$k + 1] + $t;
                $e[$k    ] = $u * $e[$k] - $s * $z;
                $e[$k + 1] = $e[$k + 1] * ($u * $u - $s * $s) + $w * $s * $u;

                # 次の行は固有ベクトルを求めないなら不要
                foreach (range(0, N) as $i)
                {
                    $x = $a[$k    ][$i];
                    $y = $a[$k + 1][$i];
                    $a[$k    ][$i] = $u * $x - $s * $y;
                    $a[$k + 1][$i] = $s * $x + $u * $y;
                }

                if ($k < N - 1)
                {
                    $x = $e[$k + 1];
                    $y = -$s * $e[$k + 2];
                    $z = $y;
                    $e[$k + 2] = $u * $e[$k + 2];
                }
            }

            printf("%3d\t", $j);
            disp_vector($d);

            # 収束判定
            if (abs($e[$h]) < 0.00000000001) break;
        }

        $e[0] = 1.0;
        while (abs($e[$h]) < 0.00000000001) $h--;
    }

    # 次の行は固有ベクトルを求めないなら不要
    foreach (range(0, (N - 1)) as $k)
    {
        $l = $k;
        foreach (range(($k + 1), N) as $i)
        {
            if ($d[$i] > $d[$l])
                $l = $i;
        }

        $t      = $d[$k];
        $d[$k] = $d[$l];
        $d[$l] = $t;

        foreach (range(0, N) as $i)
        {
            $t          = $a[$k][$i];
            $a[$k][$i] = $a[$l][$i];
            $a[$l][$i] = $t;
        }
    }
}

# 1次元配列を表示
function disp_vector($row)
{
    foreach ($row as $col)
    {
        printf("%14.10f\t", $col);
    }
    print "\n";
}
# 2次元配列を表示
function disp_matrix($matrix)
{
    foreach ($matrix as $row)
    {
        foreach ($row as $col)
        {
            printf("%14.10f\t", $col);
        }
        print "\n";
    }
}
?>
Z:\>php Z:\1106.php
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

Python

# coding: Shift_JIS
import math

N = 4

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

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

# ハウスホルダー変換
def tridiagonalize(a, d, e):
    v =  [0.0 ,0.0 ,0.0 ,0.0]

    for k in range(0, N - 2, 1):
        w = [0.0 ,0.0 ,0.0 ,0.0]
        d[k] = a[k][k]

        t = 0.0
        for i in range(k + 1, N, 1):
            w[i] =  a[i][k]
            t    += w[i] * w[i]
        s = math.sqrt(t)
        if (w[k + 1] < 0):
            s = -s

        if (abs(s) < 0.00000000001):
            e[k + 1] = 0.0
        else:
            e[k + 1]  = -s
            w[k + 1] +=  s
            s = 1 / math.sqrt(w[k + 1] * s)
            for i in range(k + 1, N, 1):
                w[i] *= s

            for i in range(k + 1, N, 1):
                s = 0.0
                for j in range(k + 1, N, 1):
                    if (j <= i):
                        s += a[i][j] * w[j]
                    else:
                        s += a[j][i] * w[j]
                v[i] = s

            s = 0.0
            for i in range(k + 1, N, 1):
                s += w[i] * v[i]
            s /= 2.0
            for i in range(k + 1, N, 1):
                v[i] -= s * w[i]
            for i in range(k + 1, N, 1):
                for j in range(k + 1, i + 1, 1):
                    a[i][j] -= w[i] * v[j] + w[j] * v[i]
            # 次の行は固有ベクトルを求めないなら不要
            for i in range(k + 1, N, 1):
                a[i][k] = w[i]

    d[N - 2] = a[N - 2][N - 2]
    d[N - 1] = a[N - 1][N - 1]

    e[0]     = 0.0
    e[N - 1] = a[N - 1][N - 2]

    # 次の行は固有ベクトルを求めないなら不要
    for k in range(N - 1, -1, -1):
        w = [0.0 ,0.0 ,0.0 ,0.0]
        if (k < N - 2):
            for i in range(k + 1, N, 1):
                w[i] = a[i][k]
            for i in range(k + 1, N, 1):
                s = 0.0
                for j in range(k + 1, N, 1):
                    s += a[i][j] * w[j]
                v[i] = s
            for i in range(k + 1, N, 1):
                for j in range(k + 1, N, 1):
                    a[i][j] -= v[i] * w[j]

        for i in range(0, N, 1):
            a[i][k] = 0.0
        a[k][k] = 1.0

# QR分解
def decomp(a, d, e):
    e[0] = 1.0
    h = N - 1
    while (abs(e[h]) < 0.00000000001):
        h -= 1

    while (h > 0):
        e[0] = 0.0
        l = h - 1
        while (abs(e[l]) >= 0.00000000001):
            l -= 1

        for j in range(1, 100, 1):
            w = (d[h - 1] - d[h]) / 2.0
            s = math.sqrt(w * w + e[h] * e[h])
            if (w < 0.0):
                s = -s

            x = d[l] - d[h] + e[h] * e[h] / (w + s)
            y = e[l + 1]
            z = 0.0
            t = 0.0
            u = 0.0
            for k in range(l, h, 1):
                if (abs(x) >= abs(y)):
                    t = -y / x
                    u = 1 / math.sqrt(t * t + 1.0)
                    s = t * u
                else:
                    t = -x / y
                    s = 1 / math.sqrt(t * t + 1.0)
                    if (t < 0):
                        s = -s
                    u = t * s

                w = d[k] - d[k + 1]
                t = (w * s + 2 * u * e[k + 1]) * s
                d[k    ] = d[k    ] - t
                d[k + 1] = d[k + 1] + t
                e[k    ] = u * e[k] - s * z
                e[k + 1] = e[k + 1] * (u * u - s * s) + w * s * u

                # 次の行は固有ベクトルを求めないなら不要
                for i in range(0, N, 1):
                    x = a[k    ][i]
                    y = a[k + 1][i]
                    a[k    ][i] = u * x - s * y
                    a[k + 1][i] = s * x + u * y

                if (k < N - 2):
                    x = e[k + 1]
                    y = -s * e[k + 2]
                    z = y
                    e[k + 2] = u * e[k + 2]

            print "%3d\t" % j,
            disp_vector(d)

            # 収束判定
            if (abs(e[h]) < 0.00000000001):
                break

        e[0] = 1.0
        while (abs(e[h]) < 0.00000000001):
            h -= 1

    # 次の行は固有ベクトルを求めないなら不要
    for k in range(0, N - 1, 1):
        l = k
        for i in range(k + 1, N, 1):
            if (d[i] > d[l]):
                l = i

        t = d[k]
        d[k] = d[l]
        d[l] = t

        for i in range(0, N, 1):
            t       = a[k][i]
            a[k][i] = a[l][i]
            a[l][i] = t

# ハウスホルダー変換とQR分解で固有値を求める
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]]
d =  [1.0 ,0.0 ,0.0 ,0.0]
e =  [1.0 ,0.0 ,0.0 ,0.0]

# ハウスホルダー変換
tridiagonalize(a, d, e)

# QR分解
decomp(a, d, e)

print ""
print "eigenvalue"
disp_vector(d)

print ""
print "eigenvector"
disp_matrix(a)
Z:\>python Z:\1106.py
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

Ruby

# coding: Shift_JIS

N = 3

# 1次元配列を表示
def disp_vector(row)
    row.each do |col|
        printf("%14.10f\t", col)
    end
    puts ""
end

# 2次元配列を表示
def disp_matrix(matrix)
    matrix.each do |row|
        row.each do |col|
            printf("%14.10f\t", col)
        end
        puts ""
    end
end

# ハウスホルダー変換
def tridiagonalize(a, d, e)
    v =  [0.0 ,0.0 ,0.0 ,0.0]

    (0..(N - 2)).each do |k|
        w = [0.0 ,0.0 ,0.0 ,0.0]
        d[k] = a[k][k]

        t = 0.0
        ((k + 1)..N).each do |i|
            w[i] =  a[i][k]
            t    += w[i] * w[i]
        end
        s = Math.sqrt(t)
        s = -s if (w[k + 1] < 0)

        if (s.abs < 0.00000000001)
            e[k + 1] = 0.0
        else
            e[k + 1]  = -s
            w[k + 1] +=  s
            s = 1 / Math.sqrt(w[k + 1] * s)
            ((k + 1)..N).each do |i|
                w[i] *= s
            end

            ((k + 1)..N).each do |i|
                s = 0.0
                ((k + 1)..N).each do |j|
                    if (j <= i)
                        s += a[i][j] * w[j]
                    else
                        s += a[j][i] * w[j]
                    end
                end
                v[i] = s
            end

            s = 0.0
            ((k + 1)..N).each do |i|
                s += w[i] * v[i]
            end
            s /= 2.0
            ((k + 1)..N).each do |i|
                v[i] -= s * w[i]
            end
            ((k + 1)..N).each do |i|
                ((k + 1)..i).each do |j|
                    a[i][j] -= w[i] * v[j] + w[j] * v[i]
                end
            end
            # 次の行は固有ベクトルを求めないなら不要
            ((k + 1)..N).each do |i|
                a[i][k] = w[i]
            end
        end
    end

    d[N - 1] = a[N - 1][N - 1]
    d[N]     = a[N][N]

    e[0]     = 0.0
    e[N]     = a[N][N - 1]

    # 次の行は固有ベクトルを求めないなら不要
    (0..N).reverse_each do |k|
        w = [0.0 ,0.0 ,0.0 ,0.0]
        if (k < N - 1)
            ((k + 1)..N).each do |i|
                w[i] = a[i][k]
            end
            ((k + 1)..N).each do |i|
                s = 0.0
                ((k + 1)..N).each do |j|
                    s += a[i][j] * w[j]
                end
                v[i] = s
            end
            ((k + 1)..N).each do |i|
                ((k + 1)..N).each do |j|
                    a[i][j] -= v[i] * w[j]
                end
            end
        end

        (0..N).each do |i|
            a[i][k] = 0.0
        end
        a[k][k] = 1.0
    end
end

# QR分解
def decomp(a, d, e)
    e[0] = 1.0
    h = N - 1
    h -= 1 while ((e[h]).abs < 0.00000000001)

    while (h > 0)
        e[0] = 0.0
        l = h - 1
        l -= 1 while ((e[l]).abs >= 0.00000000001)

        (1..100).each do |j|
            w = (d[h - 1] - d[h]) / 2.0
            s = Math.sqrt(w * w + e[h] * e[h])
            s = -s if (w < 0.0)

            x = d[l] - d[h] + e[h] * e[h] / (w + s)
            y = e[l + 1]
            z = 0.0
            t = 0.0
            u = 0.0
            (l..(h - 1)).each do |k|
                if (x.abs >= y.abs)
                    t = -y / x
                    u = 1 / Math.sqrt(t * t + 1.0)
                    s = t * u
                else
                    t = -x / y
                    s = 1 / Math.sqrt(t * t + 1.0)
                    s = -s if (t < 0)
                    u = t * s
                end

                w = d[k] - d[k + 1]
                t = (w * s + 2 * u * e[k + 1]) * s
                d[k    ] = d[k    ] - t
                d[k + 1] = d[k + 1] + t
                e[k    ] = u * e[k] - s * z
                e[k + 1] = e[k + 1] * (u * u - s * s) + w * s * u

                # 次の行は固有ベクトルを求めないなら不要
                (0..N).each do |i|
                    x = a[k    ][i]
                    y = a[k + 1][i]
                    a[k    ][i] = u * x - s * y
                    a[k + 1][i] = s * x + u * y
                end

                if (k < N - 1)
                    x = e[k + 1]
                    y = -s * e[k + 2]
                    z = y
                    e[k + 2] = u * e[k + 2]
                end
            end
            printf("%3d\t", j)
            disp_vector(d)

            # 収束判定
            break if ((e[h]).abs < 0.00000000001)
        end

        e[0] = 1.0
        h -= 1 while ((e[h]).abs < 0.00000000001)
    end

    # 次の行は固有ベクトルを求めないなら不要
    (0..(N - 1)).each do |k|
        l = k
        ((k + 1)..N).each do |i|
            l = i if (d[i] > d[l])
        end

        t = d[k]
        d[k] = d[l]
        d[l] = t

        (0..N).each do |i|
            t       = a[k][i]
            a[k][i] = a[l][i]
            a[l][i] = t
        end
    end
end

# ハウスホルダー変換とQR分解で固有値を求める
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]]
d =  [1.0 ,0.0 ,0.0 ,0.0]
e =  [1.0 ,0.0 ,0.0 ,0.0]

# ハウスホルダー変換
tridiagonalize(a, d, e)

# QR分解
decomp(a, d, e)

puts ""
puts "eigenvalue"
disp_vector(d)

puts ""
puts "eigenvector"
disp_matrix(a)
Z:\>ruby Z:\1106.rb
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

Groovy

N = 3

// ハウスホルダー変換とQR分解で固有値を求める
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 d =  [1.0 ,0.0 ,0.0 ,0.0]  as double[]
    def e =  [1.0 ,0.0 ,0.0 ,0.0]  as double[]

    // ハウスホルダー変換
    tridiagonalize(a, d, e)

    // QR分解
    decomp(a, d, e)

    println()
    println("eigenvalue")
    disp_vector(d)

    println()
    println("eigenvector")
    disp_matrix(a)
}

// ハウスホルダー変換
def tridiagonalize(a, d, e) {
    def v =  [0.0 ,0.0 ,0.0 ,0.0] as double[]

    for (k in 0..(N - 2)) {
        def w = [0.0 ,0.0 ,0.0 ,0.0] as double[]
        d[k] = a[k][k]

        t = 0.0
        for (i in (k + 1)..N) {
            w[i] =  a[i][k]
            t    += w[i] * w[i]
        }
        s = Math.sqrt(t)
        if (w[k + 1] < 0) s = -s

        if (Math.abs(s) < 0.00000000001)
            e[k + 1] = 0.0
        else {
            e[k + 1]  = -s
            w[k + 1] +=  s
            s = 1 / Math.sqrt(w[k + 1] * s)
            for (i in (k + 1)..N)
                w[i] *= s

            for (i in (k + 1)..N) {
                s = 0.0
                for (j in (k + 1)..N) {
                    if (j <= i)
                        s += a[i][j] * w[j]
                    else
                        s += a[j][i] * w[j]
                }
                v[i] = s
            }

            s = 0.0
            for (i in (k + 1)..N)
                s += w[i] * v[i]
            s /= 2.0
            for (i in (k + 1)..N)
                v[i] -= s * w[i]
            for (i in (k + 1)..N)
                for (j in (k + 1)..i)
                    a[i][j] -= w[i] * v[j] + w[j] * v[i]
            // 次の行は固有ベクトルを求めないなら不要
            for (i in (k + 1)..N)
                a[i][k] = w[i]
        }
    }

    d[N - 1] = a[N - 1][N - 1]
    d[N]     = a[N][N]

    e[0]     = 0.0
    e[N]     = a[N][N - 1]

    // 次の行は固有ベクトルを求めないなら不要
    for (k in N..0) {
        w = [0.0 ,0.0 ,0.0 ,0.0]
        if (k < N - 1) {
            for (i in (k + 1)..N)
                w[i] = a[i][k]
            for (i in (k + 1)..N) {
                s = 0.0
                for (j in (k + 1)..N)
                    s += a[i][j] * w[j]
                v[i] = s
            }
            for (i in (k + 1)..N)
                for (j in (k + 1)..N)
                    a[i][j] -= v[i] * w[j]
        }
        for (i in 0..N)
            a[i][k] = 0.0
        a[k][k] = 1.0
    }
}

// QR分解
def decomp(a, d, e) {
    e[0] = 1.0
    h = N - 1
    while (Math.abs(e[h]) < 0.00000000001) h--

    while (h > 0) {
        e[0] = 0.0
        l = h - 1
        while (Math.abs(e[l]) >= 0.00000000001) l--

        for (j in 1..100) {
            w = (d[h - 1] - d[h]) / 2.0
            s = Math.sqrt(w * w + e[h] * e[h])
            if (w < 0.0) s = -s

            x = d[l] - d[h] + e[h] * e[h] / (w + s)
            y = e[l + 1]
            z = 0.0
            t = 0.0
            u = 0.0
            for (k in l..(h - 1)) {
                if (Math.abs(x) >= Math.abs(y)) {
                    t = -y / x
                    u = 1 / Math.sqrt(t * t + 1.0)
                    s = t * u
                }
                else {
                    t = -x / y
                    s = 1 / Math.sqrt(t * t + 1.0)
                    if (t < 0)
                        s = -s
                    u = t * s
                }

                w = d[k] - d[k + 1]
                t = (w * s + 2 * u * e[k + 1]) * s
                d[k    ] = d[k    ] - t
                d[k + 1] = d[k + 1] + t
                e[k    ] = u * e[k] - s * z
                e[k + 1] = e[k + 1] * (u * u - s * s) + w * s * u

                // 次の行は固有ベクトルを求めないなら不要
                for (i in 0..N) {
                    x = a[k    ][i]
                    y = a[k + 1][i]
                    a[k    ][i] = u * x - s * y
                    a[k + 1][i] = s * x + u * y
                }

                if (k < N - 1) {
                    x = e[k + 1]
                    y = -s * e[k + 2]
                    z = y
                    e[k + 2] = u * e[k + 2]
                }
            }

            printf("%3d\t" , j)
            disp_vector(d)

            // 収束判定
            if (Math.abs(e[h]) < 0.00000000001) break
        }

        e[0] = 1.0
        while (Math.abs(e[h]) < 0.00000000001) h--
    }

    // 次の行は固有ベクトルを求めないなら不要
    for (k in 0..(N - 1)) {
        l = k
        for (i in (k + 1)..N)
            if (d[i] > d[l])
                l = i

        t    = d[k]
        d[k] = d[l]
        d[l] = t

        for (i in 0..N) {
            t       = a[k][i]
            a[k][i] = a[l][i]
            a[l][i] = t
        }
    }
}

// 1次元配列を表示
def disp_vector(row) {
    for (col in row) {
        printf("%14.10f\t" , col)
    }
    println()
}
// 2次元配列を表示
def disp_matrix(matrix) {
    for (row in matrix) {
        for (col in row) {
            printf("%14.10f\t" , col)
        }
        println()
    }
}
Z:\>gvy Gvy1106.gvy
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

Pascal

program Pas1106(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;

// 2次元配列を表示
procedure disp_matrix(matrix:TwoDimArray);
var
    row, col:Integer;
begin
    for row := 0 to N do
    begin
        for col := 0 to N do
            write(format('%14.10f'#9, [matrix[row][col]]));
        writeln();
    end;
end;


// ハウスホルダー変換
procedure tridiagonalize(var a:TwoDimArray; var d:array of Double; var e:array of Double);
var
    w:array [0..N] of Double;
    v:array [0..N] of Double;
    i, j, k:Integer;
    s, t:Double;
begin
    for k := 0 to N do
        v[k] := 0.0;

    for k := 0 to (N - 2) do
    begin
        for i := 0 to N do
            w[i] := 0.0;
        d[k] := a[k][k];

        t :=  0.0;
        for i := (k + 1) to N do
        begin
            w[i] := a[i][k];
            t    := t + w[i] * w[i];
        end;
        s := Sqrt(t);
        if w[k + 1] < 0 then
            s := -s;

        if Abs(s) < 0.00000000001 then
        begin
            e[k + 1] := 0.0;
        end
        else
        begin
            e[k + 1]  := -s;
            w[k + 1]  := w[k + 1] + s;
            s         := 1.0 / Sqrt(w[k + 1] * s);
            for i := (k + 1) to N do
                w[i] := w[i] * s;

            for i := (k + 1) to N do
            begin
                s := 0.0;
                for j := (k + 1) to N do
                    if j <= i then
                        s := s + a[i][j] * w[j]
                    else
                        s := s + a[j][i] * w[j];
                v[i] := s;
            end;

            s := 0.0;
            for i := (k + 1) to N do
                s := s + w[i] * v[i];
            s := s / 2.0;
            for i := (k + 1) to N do
                v[i] := v[i] - s * w[i];
            for i := (k + 1) to N do
                for j := (k + 1) to i do
                    a[i][j] := a[i][j] - (w[i] * v[j] + w[j] * v[i]);
            // 次の行は固有ベクトルを求めないなら不要
            for i := (k + 1) to N do
                a[i][k] := w[i];
        end;
    end;

    d[N - 1] := a[N - 1][N - 1];
    d[N]     := a[N][N];

    e[0]     := 0.0;
    e[N]     := a[N][N - 1];

    // 次の行は固有ベクトルを求めないなら不要
    for k := N downto 0 do
    begin
        for i := 0 to N do
            w[i] := 0.0;

        if k < N - 1 then
        begin
            for i := (k + 1) to N do
                w[i] := a[i][k];
            for i := (k + 1) to N do
            begin
                s := 0.0;
                for j := (k + 1) to N do
                    s := s + a[i][j] * w[j];
                v[i] := s;
            end;
            for i := (k + 1) to N do
                for j := (k + 1) to N do
                    a[i][j] := a[i][j] - v[i] * w[j];
        end;
        for i := 0 to N do
            a[i][k] := 0.0;
        a[k][k] := 1.0;
    end;
end;

// QR分解
procedure decomp(var a:TwoDimArray; var d:array of Double; var e:array of Double);
var
    h, l:Integer;
    i, j, k:Integer;
    w, s :Double;
    x, y, z :Double;
    t, u :Double;
begin
    e[0] := 1.0;
    h    := N;
    while (Abs(e[h]) < 0.00000000001) do
        dec(h);

    while (h > 0) do
    begin
        e[0] := 0.0;
        l := h - 1;
        while (Abs(e[l]) >= 0.00000000001) do
            dec(l);

        for j := 1 to 100 do
        begin
            w := (d[h - 1] - d[h]) / 2.0;
            s := Sqrt(w * w + e[h] * e[h]);
            if w < 0.0 then
                s := -s;

            x := d[l] - d[h] + e[h] * e[h] / (w + s);
            y := e[l + 1];
            z := 0.0;
            t := 0.0;
            u := 0.0;
            for k := l to (h - 1) do
            begin
                if Abs(x) >= Abs(y) then
                begin
                    t := -y / x;
                    u := 1.0 / Sqrt(t * t + 1.0);
                    s := t * u;
                end
                else
                begin
                    t := -x / y;
                    s := 1.0 / Sqrt(t * t + 1.0);
                    if t < 0 then
                        s := -s;
                    u := t * s;
                end;
                w := d[k] - d[k + 1];
                t := (w * s + 2.0 * u * e[k + 1]) * s;
                d[k    ] := d[k    ] - t;
                d[k + 1] := d[k + 1] + t;
                e[k    ] := u * e[k] - s * z;
                e[k + 1] := e[k + 1] * (u * u - s * s) + w * s * u;

                // 次の行は固有ベクトルを求めないなら不要
                for i := 0 to N do
                begin
                    x := a[k    , i];
                    y := a[k + 1, i];
                    a[k    , i] := u * x - s * y;
                    a[k + 1, i] := s * x + u * y;
                end;

                if k < N - 1 then
                begin
                    x        :=      e[k + 1];
                    y        := -s * e[k + 2];
                    z        := y;
                    e[k + 2] := u * e[k + 2];
                end;
            end;

            write(format('%3d'#9, [j]));
            disp_vector(d);

            // 収束判定
            if (Abs(e[h]) < 0.00000000001) then break;
        end;

        e[0] := 1.0;
        while (Abs(e[h]) < 0.00000000001) do
            dec(h);
    end;

    // 次の行は固有ベクトルを求めないなら不要
    for k := 0 to (N - 1) do
    begin
        l := k;
        for i := (k + 1) to N  do
            if d[i] > d[l] then
                l := i;

        t    := d[k];
        d[k] := d[l];
        d[l] := t;

        for i := 0 to N do
        begin
            t       := a[k][i];
            a[k][i] := a[l][i];
            a[l][i] := t;
        end;
    end;
end;

// ハウスホルダー変換とQR分解で固有値を求める
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));

    d:array [0..N] of Double;
    e:array [0..N] of Double;
begin
    // ハウスホルダー変換
    tridiagonalize(a, d, e);

    // QR分解
    decomp(a, d, e);

    writeln();
    writeln('eigenvalue');
    disp_vector(d);

    writeln();
    writeln('eigenvector');
    disp_matrix(a);
end.
Z:\>fpc -v0 -l- Pas1106.pp

Z:\>Pas1106
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000    0.0000000000   -0.7071067812    0.7071067812
  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 Ada1106 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));

    d, e:Long_Float_Array;

    -- 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;

    -- 2次元配列を表示
    procedure disp_matrix(matrix:Long_Float_TwoDimArray) is
    begin
        for row in 0..N loop
            for col in 0..N loop
                Put(matrix(row, col), Fore=>3, Aft=>10, Exp=>0);
                Put(Ascii.HT);
            end loop;
            New_Line;
        end loop;
    end disp_matrix;

    -- ハウスホルダー変換
    procedure tridiagonalize(a:in out Long_Float_TwoDimArray; d:in out Long_Float_Array; e:in out Long_Float_Array) is
        w, v:Long_Float_Array;
        t, s:Long_Float;
    begin
        for k in 0..N loop
            v(k) := 0.0;
        end loop;
        for k in 0..(N - 2) loop
            for i in 0..N loop
                w(i) := 0.0;
            end loop;
            d(k) := a(k, k);

            t := 0.0;
            for i in (k + 1)..N loop
                w(i) := a(i, k);
                t    := t + w(i) * w(i);
            end loop;
            s := Sqrt(t);
            if w(k + 1) < 0.0 then
                s := -s;
            end if;

            if Abs(s) < 0.00000000001 then
                e(k + 1) := 0.0;
            else
                e(k + 1) := -s;
                w(k + 1) := w(k + 1) + s;
                s := 1.0 / Sqrt(w(k + 1) * s);
                for i in (k + 1)..N loop
                    w(i) := w(i) * s;
                end loop;

                for i in (k + 1)..N loop
                    s := 0.0;
                    for j in (k + 1)..N loop
                        if j <= i then
                            s := s + a(i, j) * w(j);
                        else
                            s := s + a(j, i) * w(j);
                        end if;
                    end loop;
                    v(i) := s;
                end loop;

                s := 0.0;
                for i in (k + 1)..N loop
                    s := s + w(i) * v(i);
                end loop;
                s := s / 2.0;
                for i in (k + 1)..N loop
                    v(i) := v(i) - s * w(i);
                end loop;
                for i in (k + 1)..N loop
                    for j in (k + 1)..i loop
                        a(i, j) := a(i, j) - (w(i) * v(j) + w(j) * v(i));
                    end loop;
                end loop;

                -- 次の行は固有ベクトルを求めないなら不要
                for i in (k + 1)..N loop
                    a(i, k) := w(i);
                end loop;
            end if;
        end loop;

        d(N - 1) := a(N - 1, N - 1);
        d(N)     := a(N, N);

        e(0)     := 0.0;
        e(N)     := a(N, N - 1);

        -- 次の行は固有ベクトルを求めないなら不要
        for k in reverse 0..N loop
            for i in 0..N loop
                w(i) := 0.0;
            end loop;
            if k < N - 1 then
                for i in (k + 1)..N loop
                    w(i) := a(i, k);
                end loop;
                for i in (k + 1)..N loop
                    s := 0.0;
                    for j in (k + 1)..N loop
                        s := s + a(i, j) * w(j);
                    end loop;
                    v(i) := s;
                end loop;
                for i in (k + 1)..N loop
                    for j in (k + 1)..N loop
                        a(i, j) := a(i, j) - v(i) * w(j);
                    end loop;
                end loop;
            end if;
            for i in 0..N loop
                a(i, k) := 0.0;
            end loop;
            a(k, k) := 1.0;
        end loop;
    end tridiagonalize;

    -- QR分解
    procedure decomp(a:in out Long_Float_TwoDimArray; d:in out Long_Float_Array; e:in out Long_Float_Array) is
        h, l:Integer;
        s, t, u, w, x, y, z:Long_Float;
    begin
        e(0) := 1.0;
        h := N;
        while (Abs(e(h)) < 0.00000000001) loop
            h := h -1;
        end loop;

        while (h > 0) loop
            e(0) := 0.0;
            l := h - 1;
            while (Abs(e(l)) >= 0.00000000001) loop
                l := l - 1;
            end loop;
            for j in 1..100 loop
                w := (d(h - 1) - d(h)) / 2.0;
                s := Sqrt(w * w + e(h) * e(h));
                if w < 0.0 then
                    s := -s;
                end if;

                x := d(l) - d(h) + e(h) * e(h) / (w + s);
                y := e(l + 1);
                z := 0.0;
                t := 0.0;
                u := 0.0;
                for k in l..(h - 1) loop
                    if Abs(x) >= Abs(y) then
                        t := -y / x;
                        u := 1.0 / Sqrt(t * t + 1.0);
                        s := t * u;
                    else
                        t := -x / y;
                        s := 1.0 / Sqrt(t * t + 1.0);
                        if t < 0.0 then
                            s := -s;
                        end if;
                        u := t * s;
                    end if;
                    w := d(k) - d(k + 1);
                    t := (w * s + 2.0 * u * e(k + 1)) * s;
                    d(k    ) := d(k    ) - t;
                    d(k + 1) := d(k + 1) + t;
                    e(k    ) := u * e(k) - s * z;
                    e(k + 1) := e(k + 1) * (u * u - s * s) + w * s * u;

                    -- 次の行は固有ベクトルを求めないなら不要
                    for i in 0..N loop
                        x := a(k    , i);
                        y := a(k + 1, i);
                        a(k    , i) := u * x - s * y;
                        a(k + 1, i) := s * x + u * y;
                    end loop;

                    if k < N - 1 then
                        x := e(k + 1);
                        y := -s * e(k + 2);
                        z := y;
                        e(k + 2) := u * e(k + 2);
                    end if;
                end loop;

                Put(j, Width=> 3);
                Put(Ascii.HT);
                disp_vector(d);

                -- 収束判定
                if (Abs(e(h)) < 0.00000000001) then
                    exit;
                end if;
            end loop;

            e(0) := 1.0;
            while (Abs(e(h)) < 0.00000000001) loop
                h := h - 1;
            end loop;
        end loop;

        -- 次の行は固有ベクトルを求めないなら不要
        for k in 0..(N - 1) loop
            l := k;
            for i in (k + 1)..N loop
                if d(i) > d(l) then
                    l := i;
                end if;
            end loop;

            t    := d(k);
            d(k) := d(l);
            d(l) := t;

            for i in 0..N loop
                t       := a(k, i);
                a(k, i) := a(l, i);
                a(l, i) := t;
            end loop;
        end loop;
    end decomp;

-- ハウスホルダー変換とQR分解で固有値を求める
begin
    -- ハウスホルダー変換;
    tridiagonalize(a, d, e);

    -- QR分解
    decomp(a, d, e);
    New_Line;

    Put_Line("eigenvalue");
    disp_vector(d);
    New_Line;

    Put_Line("eigenvector");
    disp_matrix(a);
end Ada1106;
xxxxxx@yyyyyy /Z
$ gnatmake Ada1106.adb

xxxxxx@yyyyyy /Z
$ Ada1106
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000   -0.0000000000

VB.NET

Option Explicit

Module VB1106
    Private Const N As Integer = 3

    'ハウスホルダー変換とQR分解で固有値を求める
    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 d()  As Double = New Double(N){}
        Dim e()  As Double = New Double(N){}

        'ハウスホルダー変換
        tridiagonalize(a, d, e)

        'QR分解
        decomp(a, d, e)

        Console.WriteLine()
        Console.WriteLine("eigenvalue")
        disp_vector(d)

        Console.WriteLine()
        Console.WriteLine("eigenvector")
        disp_matrix(a)
    End Sub

    'ハウスホルダー変換
    Private Sub tridiagonalize(ByRef a(,) As Double, ByRef d() As Double, ByRef e() As Double)
        Dim w() As Double = New Double(N){}
        Dim v() As Double = New Double(N){}

        For k As Integer = 0 To N - 2
            d(k) = a(k, k)

            Dim t As Double =  0.0
            For i As Integer = k + 1 To N
                w(i) =  a(i, k)
                t    += w(i) * w(i)
            Next
            Dim s As Double = Math.Sqrt(t)
            If w(k + 1) < 0 Then
                s = -s
            End If

            If Math.Abs(s) < 0.00000000001 Then
                e(k + 1) = 0.0
            Else
                e(k + 1)  = -s
                w(k + 1) +=  s
                s = 1 / Math.Sqrt(w(k + 1) * s)
                For i As Integer = k + 1 To N
                    w(i) *= s
                Next

                For i As Integer = k + 1 To N
                    s = 0.0
                    For j As Integer = k + 1 To N
                        If j <= i Then
                            s += a(i, j) * w(j)
                        Else
                            s += a(j, i) * w(j)
                        End If
                    Next
                    v(i) = s
                Next

                s = 0.0
                For i As Integer = k + 1 To N
                    s += w(i) * v(i)
                Next
                s /= 2.0
                For i As Integer = k + 1 To N
                    v(i) -= s * w(i)
                Next
                For i As Integer = k + 1 To N
                    For j As Integer = k + 1 To i
                        a(i, j) -= w(i) * v(j) + w(j) * v(i)
                    Next
                Next
                '次の行は固有ベクトルを求めないなら不要
                For i As Integer = k + 1 To N
                    a(i, k) = w(i)
                Next
            End If
        Next

        d(N - 1) = a(N - 1, N - 1)
        d(N)     = a(N, N)

        e(0)     = 0.0
        e(N)     = a(N, N - 1)

        '次の行は固有ベクトルを求めないなら不要
        For k As Integer = N To 0 Step -1
            w = {0.0 ,0.0 ,0.0 ,0.0}
            If k < N - 1 Then
                For i As Integer = k + 1 To N
                    w(i) = a(i, k)
                Next
                For i As Integer = k + 1 To N
                    Dim s As Double  = 0.0
                    For j As Integer = k + 1 To N
                        s += a(i, j) * w(j)
                    Next
                    v(i) = s
                Next
                For i As Integer = k + 1 To N
                    For j As Integer = k + 1 To N
                        a(i, j) -= v(i) * w(j)
                    Next
                Next
            End If
            For i As Integer = 0 To N
                a(i, k) = 0.0
            Next
            a(k, k) = 1.0
        Next
    End Sub

    'QR分解
    Private Sub decomp(ByRef a(,) As Double, ByRef d() As Double, ByRef e() As Double)
        e(0) = 1.0
        Dim h As Integer = N
        Do While (Math.Abs(e(h)) < 0.00000000001)
            h -= 1
        Loop

        Do While h > 0
            e(0) = 0.0
            Dim l As Integer = h - 1
            Do While (Math.Abs(e(l)) >= 0.00000000001)
                l -= 1
            Loop
            For j As Integer = 1 To 100
                Dim w As Double = (d(h - 1) - d(h)) / 2.0
                Dim s As Double = Math.Sqrt(w * w + e(h) * e(h))
                If w < 0.0 Then
                    s = -s
                End If

                Dim x As Double = d(l) - d(h) + e(h) * e(h) / (w + s)
                Dim y As Double = e(l + 1)
                Dim z As Double = 0.0
                Dim t As Double = 0.0
                Dim u As Double = 0.0
                For k As Integer = l To h - 1
                    If Math.Abs(x) >= Math.Abs(y) Then
                        t = -y / x
                        u = 1 / Math.Sqrt(t * t + 1.0)
                        s = t * u
                    Else
                        t = -x / y
                        s = 1 / Math.Sqrt(t * t + 1.0)
                        If t < 0 Then
                            s = -s
                        End If
                        u = t * s
                    End If
                    w = d(k) - d(k + 1)
                    t = (w * s + 2 * u * e(k + 1)) * s
                    d(k    ) = d(k    ) - t
                    d(k + 1) = d(k + 1) + t
                    e(k    ) = u * e(k) - s * z
                    e(k + 1) = e(k + 1) * (u * u - s * s) + w * s * u

                    '次の行は固有ベクトルを求めないなら不要
                    For i As Integer = 0 To N
                        x = a(k    , i)
                        y = a(k + 1, i)
                        a(k    , i) = u * x - s * y
                        a(k + 1, i) = s * x + u * y
                    Next

                    If k < N - 1 Then
                        x = e(k + 1)
                        y = -s * e(k + 2)
                        z = y
                        e(k + 2) = u * e(k + 2)
                    End If
                Next

                Console.Write(String.Format("{0,3:D}{1}", j, vbTab))
                Call disp_vector(d)

                '収束判定
                If (Math.Abs(e(h)) < 0.00000000001) Then Exit For
            Next

            e(0) = 1.0
            Do While (Math.Abs(e(h)) < 0.00000000001)
                h -= 1
            Loop
        Loop

        '次の行は固有ベクトルを求めないなら不要
        For k As Integer = 0 To N - 1
            Dim l As Integer = k
            For i As Integer = k + 1 To N
                If d(i) > d(l) Then
                    l = i
                End If
            Next

            Dim t As Double = d(k)
            d(k) = d(l)
            d(l) = t

            For i As Integer = 0 To N
                t       = a(k, i)
                a(k, i) = a(l, i)
                a(l, i) = t
            Next
        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

    '2次元配列を表示
    Private Sub disp_matrix(ByVal matrix(,) As Double)
        For row As Integer = 0 To N
            For col As Integer = 0 To N
                Console.Write(String.Format("{0,14:F10}{1}", matrix(row, col), vbTab))
            Next
            Console.WriteLine()
        Next
    End Sub
End Module
Z:\>vbc -nologo VB1106.vb

Z:\>VB1106
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000    0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

C#

using System;

public class CS1106
{
    private const int N = 4;

    // ハウスホルダー変換とQR分解で固有値を求める
    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[] d = new double[N];
        double[] e = new double[N];

        // ハウスホルダー変換
        tridiagonalize(a, d, e);

        // QR分解
        decomp(a, d, e);

        Console.WriteLine();
        Console.WriteLine("eigenvalue");
        disp_vector(d);

        Console.WriteLine();
        Console.WriteLine("eigenvector");
        disp_matrix(a);
    }

    // ハウスホルダー変換
    private static void tridiagonalize(double[,] a, double[] d, double[] e)
    {
        double[] w = new double[N];
        double[] v = new double[N];

        for (int k = 0; k < N - 2; k++)
        {
            d[k] = a[k, k];

            double t = 0.0;
            for (int i = k + 1; i < N; i++)
            {
                w[i] =  a[i, k];
                t    += w[i] * w[i];
            }
            double s = Math.Sqrt(t);
            if (w[k + 1] < 0)
                s = -s;

            if (Math.Abs(s) < 0.00000000001)
                e[k + 1] = 0.0;
            else
            {
                e[k + 1]  = -s;
                w[k + 1] +=  s;
                s = 1 / Math.Sqrt(w[k + 1] * s);
                for (int i = k + 1; i < N; i++)
                    w[i] *= s;

                for (int i = k + 1; i < N; i++)
                {
                    s = 0.0;
                    for (int j = k + 1; j < N; j++)
                    {
                        if (j <= i)
                            s += a[i, j] * w[j];
                        else
                            s += a[j, i] * w[j];
                    }
                    v[i] = s;
                }

                s = 0.0;
                for (int i = k + 1; i < N; i++)
                    s += w[i] * v[i];
                s /= 2.0;
                for (int i = k + 1; i < N; i++)
                    v[i] -= s * w[i];
                for (int i = k + 1; i < N; i++)
                    for (int j = k + 1; j <= i; j++)
                        a[i, j] -= w[i] * v[j] + w[j] * v[i];
                // 次の行は固有ベクトルを求めないなら不要
                for (int i = k + 1; i < N; i++)
                    a[i, k] = w[i];
            }
        }

        d[N - 2] = a[N - 2, N - 2];
        d[N - 1] = a[N - 1, N - 1];

        e[0]     = 0.0;
        e[N - 1] = a[N - 1, N - 2];

        // 次の行は固有ベクトルを求めないなら不要
        for (int k = N - 1; k >= 0; k--)
        {
            w = new double[] {0.0 ,0.0 ,0.0 ,0.0};
            if (k < N - 2)
            {
                for (int i = k + 1; i < N; i++)
                    w[i] = a[i, k];
                for (int i = k + 1; i < N; i++)
                {
                    double s = 0.0;
                    for (int j = k + 1; j < N; j++)
                        s += a[i, j] * w[j];
                    v[i] = s;
                }
                for (int i = k + 1; i < N; i++)
                    for (int j = k + 1; j < N; j++)
                        a[i, j] -= v[i] * w[j];
            }
            for (int i = 0; i < N; i++)
                a[i, k] = 0.0;
            a[k, k] = 1.0;
        }
    }

    // QR分解
    private static void decomp(double[,] a, double[] d, double[] e)
    {
        e[0] = 1.0;
        int h = N - 1;
        while (Math.Abs(e[h]) < 0.00000000001) h--;

        while (h > 0)
        {
            e[0] = 0.0;
            int l = h - 1;
            while (Math.Abs(e[l]) >= 0.00000000001) l--;

            for (int j = 1; j <= 100; j++)
            {
                double w = (d[h - 1] - d[h]) / 2.0;
                double s = Math.Sqrt(w * w + e[h] * e[h]);
                if (w < 0.0)
                    s = -s;

                double x = d[l] - d[h] + e[h] * e[h] / (w + s);
                double y = e[l + 1];
                double z = 0.0;
                double t = 0.0;
                double u = 0.0;
                for (int k = l; k < h; k++)
                {
                    if (Math.Abs(x) >= Math.Abs(y))
                    {
                        t = -y / x;
                        u = 1 / Math.Sqrt(t * t + 1.0);
                        s = t * u;
                    }
                    else
                    {
                        t = -x / y;
                        s = 1 / Math.Sqrt(t * t + 1.0);
                        if (t < 0)
                            s = -s;
                        u = t * s;
                    }
                    w = d[k] - d[k + 1];
                    t = (w * s + 2 * u * e[k + 1]) * s;
                    d[k    ] = d[k    ] - t;
                    d[k + 1] = d[k + 1] + t;
                    e[k    ] = u * e[k] - s * z;
                    e[k + 1] = e[k + 1] * (u * u - s * s) + w * s * u;

                    // 次の行は固有ベクトルを求めないなら不要
                    for (int i = 0; i < N; i++)
                    {
                        x = a[k    , i];
                        y = a[k + 1, i];
                        a[k    , i] = u * x - s * y;
                        a[k + 1, i] = s * x + u * y;
                    }

                    if (k < N - 2)
                    {
                        x = e[k + 1];
                        y = -s * e[k + 2];
                        z = y;
                        e[k + 2] = u * e[k + 2];
                    }
                }

                Console.Write(string.Format("{0,3:D}\t", j));
                disp_vector(d);

                // 収束判定
                if (Math.Abs(e[h]) < 0.00000000001) break;
            }

            e[0] = 1.0;
            while (Math.Abs(e[h]) < 0.00000000001) h--;
        }

        // 次の行は固有ベクトルを求めないなら不要
        for (int k = 0; k < N - 1; k++)
        {
            int l = k;
            for (int i = k + 1; i < N; i++)
                if (d[i] > d[l])
                    l = i;

            double t = d[k];
            d[k] = d[l];
            d[l] = t;

            for (int i = 0; i < N; i++)
            {
                t       = a[k, i];
                a[k, i] = a[l, i];
                a[l, i] = t;
            }
        }
    }

    // 1次元配列を表示
    private static void disp_vector(double[] row)
    {
        foreach (double col in row)
            Console.Write(string.Format("{0,14:F10}\t", col));
        Console.WriteLine();
    }
    // 2次元配列を表示
    private static void disp_matrix(double[,] matrix)
    {
        for (int row = 0; row < N; row++)
        {
            for (int col = 0; col < N; col++)
                Console.Write(string.Format("{0,14:F10}\t", matrix[row,col]));
            Console.WriteLine();
        }
    }
}
Z:\>csc -nologo CS1106.cs

Z:\>CS1106
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000    0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

Java

import java.lang.*;

public class Java1106 {

    private static final int N = 4;

    // ハウスホルダー変換とQR分解で固有値を求める
    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[] d = new double[N];
        double[] e = new double[N];

        // ハウスホルダー変換
        tridiagonalize(a, d, e);

        // QR分解
        decomp(a, d, e);

        System.out.println();
        System.out.println("eigenvalue");
        disp_vector(d);

        System.out.println();
        System.out.println("eigenvector");
        disp_matrix(a);
    }

    // ハウスホルダー変換
    private static void tridiagonalize(double[][] a, double[] d, double[] e) {
        double[] w = new double[N];
        double[] v = new double[N];

        for (int k = 0; k < N - 2; k++) {
            d[k] = a[k][k];

            double t = 0.0;
            for (int i = k + 1; i < N; i++) {
                w[i] =  a[i][k];
                t    += w[i] * w[i];
            }
            double s = Math.sqrt(t);
            if (w[k + 1] < 0)
                s = -s;

            if (Math.abs(s) < 0.00000000001)
                e[k + 1] = 0.0;
            else {
                e[k + 1]  = -s;
                w[k + 1] +=  s;
                s = 1 / Math.sqrt(w[k + 1] * s);
                for (int i = k + 1; i < N; i++)
                    w[i] *= s;

                for (int i = k + 1; i < N; i++) {
                    s = 0.0;
                    for (int j = k + 1; j < N; j++) {
                        if (j <= i)
                            s += a[i][j] * w[j];
                        else
                            s += a[j][i] * w[j];
                    }
                    v[i] = s;
                }

                s = 0.0;
                for (int i = k + 1; i < N; i++)
                    s += w[i] * v[i];
                s /= 2.0;
                for (int i = k + 1; i < N; i++)
                    v[i] -= s * w[i];
                for (int i = k + 1; i < N; i++)
                    for (int j = k + 1; j <= i; j++)
                        a[i][j] -= w[i] * v[j] + w[j] * v[i];
                // 次の行は固有ベクトルを求めないなら不要
                for (int i = k + 1; i < N; i++)
                    a[i][k] = w[i];
            }
        }

        d[N - 2] = a[N - 2][N - 2];
        d[N - 1] = a[N - 1][N - 1];

        e[0]     = 0.0;
        e[N - 1] = a[N - 1][N - 2];

        // 次の行は固有ベクトルを求めないなら不要
        for (int k = N - 1; k >= 0; k--) {
            w = new double[] {0.0 ,0.0 ,0.0 ,0.0};
            if (k < N - 2) {
                for (int i = k + 1; i < N; i++)
                    w[i] = a[i][k];
                for (int i = k + 1; i < N; i++) {
                    double s = 0.0;
                    for (int j = k + 1; j < N; j++)
                        s += a[i][j] * w[j];
                    v[i] = s;
                }
                for (int i = k + 1; i < N; i++)
                    for (int j = k + 1; j < N; j++)
                        a[i][j] -= v[i] * w[j];
            }
            for (int i = 0; i < N; i++)
                a[i][k] = 0.0;
            a[k][k] = 1.0;
        }
    }

    // QR分解
    private static void decomp(double[][] a, double[] d, double[] e) {
        e[0] = 1.0;
        int h = N - 1;
        while (Math.abs(e[h]) < 0.00000000001) h--;

        while (h > 0) {
            e[0] = 0.0;
            int l = h - 1;
            while (Math.abs(e[l]) >= 0.00000000001) l--;

            for (int j = 1; j <= 100; j++) {
                double w = (d[h - 1] - d[h]) / 2.0;
                double s = Math.sqrt(w * w + e[h] * e[h]);
                if (w < 0.0)
                    s = -s;

                double x = d[l] - d[h] + e[h] * e[h] / (w + s);
                double y = e[l + 1];
                double z = 0.0;
                double t = 0.0;
                double u = 0.0;
                for (int k = l; k < h; k++) {
                    if (Math.abs(x) >= Math.abs(y)) {
                        t = -y / x;
                        u = 1 / Math.sqrt(t * t + 1.0);
                        s = t * u;
                    } else {
                        t = -x / y;
                        s = 1 / Math.sqrt(t * t + 1.0);
                        if (t < 0)
                            s = -s;
                        u = t * s;
                    }
                    w = d[k] - d[k + 1];
                    t = (w * s + 2 * u * e[k + 1]) * s;
                    d[k    ] = d[k    ] - t;
                    d[k + 1] = d[k + 1] + t;
                    e[k    ] = u * e[k] - s * z;
                    e[k + 1] = e[k + 1] * (u * u - s * s) + w * s * u;

                    // 次の行は固有ベクトルを求めないなら不要
                    for (int i = 0; i < N; i++) {
                        x = a[k    ][i];
                        y = a[k + 1][i];
                        a[k    ][i] = u * x - s * y;
                        a[k + 1][i] = s * x + u * y;
                    }

                    if (k < N - 2) {
                        x = e[k + 1];
                        y = -s * e[k + 2];
                        z = y;
                        e[k + 2] = u * e[k + 2];
                    }
                }

                System.out.print(String.format("%3d\t", j));
                disp_vector(d);

                // 収束判定
                if (Math.abs(e[h]) < 0.00000000001) break;
            }

            e[0] = 1.0;
            while (Math.abs(e[h]) < 0.00000000001) h--;
        }

        // 次の行は固有ベクトルを求めないなら不要
        for (int k = 0; k < N - 1; k++) {
            int l = k;
            for (int i = k + 1; i < N; i++)
                if (d[i] > d[l])
                    l = i;

            double t = d[k];
            d[k] = d[l];
            d[l] = t;

            for (int i = 0; i < N; i++) {
                t       = a[k][i];
                a[k][i] = a[l][i];
                a[l][i] = t;
            }
        }
    }

    // 1次元配列を表示
    private static void disp_vector(double[] row) {
        for (double col: row)
            System.out.print(String.format("%14.10f\t", col));
        System.out.println();
    }
    // 2次元配列を表示
    private static void disp_matrix(double[][] matrix) {
        for (int row = 0; row < N; row++) {
            for (int col = 0; col < N; col++)
                System.out.print(String.format("%14.10f\t", matrix[row][col]));
            System.out.println();
        }
    }
}
Z:\>javac Java1106.java

Z:\>java Java1106
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

C++

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

const int N = 4;

// ハウスホルダー変換
void tridiagonalize(double a[N][N], double d[N], double e[N]);
// QR分解
void decomp(double a[N][N], double d[N], double e[N]);
// 1次元配列を表示
void disp_vector(double row[N]);
// 2次元配列を表示
void disp_matrix(double matrix[N][N]);

// ハウスホルダー変換とQR分解で固有値を求める
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 d[N];
    double e[N];

    // ハウスホルダー変換
    tridiagonalize(a, d, e);

    // QR分解
    decomp(a, d, e);

    cout << endl << "eigenvalue" << endl;
    disp_vector(d);

    cout << endl << "eigenvector" << endl;
    disp_matrix(a);

    return 0;
}

// ハウスホルダー変換
void tridiagonalize(double a[N][N], double d[N], double e[N])
{
    double v[N];

    for (int k = 0; k < N - 2; k++)
    {
        double w[N] = {0.0 ,0.0 ,0.0 ,0.0};
        d[k] = a[k][k];

        double t = 0.0;
        for (int i = k + 1; i < N; i++)
        {
            w[i] =  a[i][k];
            t += w[i] * w[i];
        }
        double s = sqrt(t);
        if (w[k + 1] < 0)
            s = -s;

        if (fabs(s) < 0.00000000001)
            e[k + 1] = 0.0;
        else
        {
            e[k + 1]  = -s;
            w[k + 1] +=  s;
            s = 1 / sqrt(w[k + 1] * s);
            for (int i = k + 1; i < N; i++)
                w[i] *= s;

            for (int i = k + 1; i < N; i++)
            {
                s = 0.0;
                for (int j = k + 1; j < N; j++)
                {
                    if (j <= i)
                        s += a[i][j] * w[j];
                    else
                        s += a[j][i] * w[j];
                }
                v[i] = s;
            }

            s = 0.0;
            for (int i = k + 1; i < N; i++)
                s += w[i] * v[i];
            s /= 2.0;
            for (int i = k + 1; i < N; i++)
                v[i] -= s * w[i];
            for (int i = k + 1; i < N; i++)
                for (int j = k + 1; j <= i; j++)
                    a[i][j] -= w[i] * v[j] + w[j] * v[i];
            // 次の行は固有ベクトルを求めないなら不要
            for (int i = k + 1; i < N; i++)
                a[i][k] = w[i];
        }
    }

    d[N - 2] = a[N - 2][N - 2];
    d[N - 1] = a[N - 1][N - 1];

    e[0]     = 0.0;
    e[N - 1] = a[N - 1][N - 2];

    // 次の行は固有ベクトルを求めないなら不要
    for (int k = N - 1; k >= 0; k--)
    {
        double w[N] = {0.0 ,0.0 ,0.0 ,0.0};
        if (k < N - 2)
        {
            for (int i = k + 1; i < N; i++)
                w[i] = a[i][k];
            for (int i = k + 1; i < N; i++)
            {
                double s = 0.0;
                for (int j = k + 1; j < N; j++)
                    s += a[i][j] * w[j];
                v[i] = s;
            }
            for (int i = k + 1; i < N; i++)
                for (int j = k + 1; j < N; j++)
                    a[i][j] -= v[i] * w[j];
        }
        for (int i = 0; i < N; i++)
            a[i][k] = 0.0;
        a[k][k] = 1.0;
    }
}

// QR分解
void decomp(double a[N][N], double d[N], double e[N])
{
    e[0] = 1.0;
    int h = N - 1;
    while (fabs(e[h]) < 0.00000000001) h--;

    while (h > 0)
    {
        e[0] = 0.0;
        int l = h - 1;
        while (fabs(e[l]) >= 0.00000000001) l--;

        for (int j = 1; j <= 100; j++)
        {
            double w = (d[h - 1] - d[h]) / 2.0;
            double s = sqrt(w * w + e[h] * e[h]);
            if (w < 0.0)
                s = -s;

            double x = d[l] - d[h] + e[h] * e[h] / (w + s);
            double y = e[l + 1];
            double z = 0.0;
            double t;
            double u;
            for (int k = l; k < h; k++)
            {
                if (fabs(x) >= fabs(y))
                {
                    t = -y / x;
                    u = 1 / sqrt(t * t + 1.0);
                    s = t * u;
                }
                else
                {
                    t = -x / y;
                    s = 1 / sqrt(t * t + 1.0);
                    if (t < 0)
                        s = -s;
                    u = t * s;
                }
                w = d[k] - d[k + 1];
                t = (w * s + 2 * u * e[k + 1]) * s;
                d[k    ] = d[k    ] - t;
                d[k + 1] = d[k + 1] + t;
                e[k    ] = u * e[k] - s * z;
                e[k + 1] = e[k + 1] * (u * u - s * s) + w * s * u;

                // 次の行は固有ベクトルを求めないなら不要
                for (int i = 0; i < N; i++)
                {
                    x = a[k    ][i];
                    y = a[k + 1][i];
                    a[k    ][i] = u * x - s * y;
                    a[k + 1][i] = s * x + u * y;
                }

                if (k < N - 2)
                {
                    x = e[k + 1];
                    y = -s * e[k + 2];
                    z = y;
                    e[k + 2] = u * e[k + 2];
                }
            }

            cout << setw(3) << j << "\t";
            disp_vector(d);

            // 収束判定
            if (fabs(e[h]) < 0.00000000001) break;
        }

        e[0] = 1.0;
        while (fabs(e[h]) < 0.00000000001) h--;
    }

    // 次の行は固有ベクトルを求めないなら不要
    for (int k = 0; k < N - 1; k++)
    {
        int l = k;
        for (int i = k + 1; i < N; i++)
            if (d[i] > d[l])
                l = i;

        double t = d[k];
        d[k] = d[l];
        d[l] = t;

        for (int i = 0; i < N; i++)
        {
            t       = a[k][i];
            a[k][i] = a[l][i];
            a[l][i] = t;
        }
    }
}

// 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;
}
// 2次元配列を表示
void disp_matrix(double matrix[N][N])
{
    for (int row = 0; row < N; row++)
    {
        for (int col = 0; col < N; col++)
            cout << setw(14) << fixed << setprecision(10) << matrix[row][col] << "\t";
        cout << endl;
    }
}
Z:\>bcc32 -q CP1106.cpp
cp1106.cpp:

Z:\>CP1106
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000   -0.0000000000

Objective-C

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

#define N 4

// ハウスホルダー変換
void tridiagonalize(double a[N][N], double d[N], double e[N]);
// QR分解
void decomp(double a[N][N], double d[N], double e[N]);
// 1次元配列を表示
void disp_vector(double row[N]);
// 2次元配列を表示
void disp_matrix(double matrix[N][N]);

// ハウスホルダー変換とQR分解で固有値を求める
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 d[N];
    double e[N];

    // ハウスホルダー変換
    tridiagonalize(a, d, e);

    // QR分解
    printf("\nQR分解\n");
    decomp(a, d, e);

    printf("\neigenvalue\n");
    disp_vector(d);

    printf("\neigenvector\n");
    disp_matrix(a);

    return 0;
}

// ハウスホルダー変換
void tridiagonalize(double a[N][N], double d[N], double e[N])
{
    int i, j, k;
    double v[N];

    for (k = 0; k < N - 2; k++)
    {
        double w[N] = {0.0 ,0.0 ,0.0 ,0.0};
        d[k] = a[k][k];

        double t = 0.0;
        for (i = k + 1; i < N; i++)
        {
            w[i] =  a[i][k];
            t    += w[i] * w[i];
        }
        double s = sqrt(t);
        if (w[k + 1] < 0)
            s = -s;

        if (fabs(s) < 0.00000000001)
            e[k + 1] = 0.0;
        else
        {
            e[k + 1]  = -s;
            w[k + 1] +=  s;
            s = 1 / sqrt(w[k + 1] * s);
            for (i = k + 1; i < N; i++)
                w[i] *= s;

            for (i = k + 1; i < N; i++)
            {
                s = 0.0;
                for (j = k + 1; j < N; j++)
                {
                    if (j <= i)
                        s += a[i][j] * w[j];
                    else
                        s += a[j][i] * w[j];
                }
                v[i] = s;
            }

            s = 0.0;
            for (i = k + 1; i < N; i++)
                s += w[i] * v[i];
            s /= 2.0;
            for (i = k + 1; i < N; i++)
                v[i] -= s * w[i];
            for (i = k + 1; i < N; i++)
                for (j = k + 1; j <= i; j++)
                    a[i][j] -= w[i] * v[j] + w[j] * v[i];
            // 次の行は固有ベクトルを求めないなら不要
            for (i = k + 1; i < N; i++)
                a[i][k] = w[i];
        }
    }

    d[N - 2] = a[N - 2][N - 2];
    d[N - 1] = a[N - 1][N - 1];

    e[0]     = 0.0;
    e[N - 1] = a[N - 1][N - 2];

    // 次の行は固有ベクトルを求めないなら不要
    for (k = N - 1; k >= 0; k--)
    {
        double w[N] = {0.0 ,0.0 ,0.0 ,0.0};
        if (k < N - 2)
        {
            for (i = k + 1; i < N; i++)
                w[i] = a[i][k];
            for (i = k + 1; i < N; i++)
            {
                double s = 0.0;
                for (j = k + 1; j < N; j++)
                    s += a[i][j] * w[j];
                v[i] = s;
            }
            for (i = k + 1; i < N; i++)
                for (j = k + 1; j < N; j++)
                    a[i][j] -= v[i] * w[j];
        }
        for (i = 0; i < N; i++)
            a[i][k] = 0.0;
        a[k][k] = 1.0;
    }
}

// QR分解
void decomp(double a[N][N], double d[N], double e[N])
{
    int i, j, k;

    e[0] = 1.0;
    int h = N - 1;
    while (fabs(e[h]) < 0.00000000001) h--;

    while (h > 0)
    {
        e[0] = 0.0;
        int l = h - 1;
        while (fabs(e[l]) >= 0.00000000001) l--;

        for (j = 1; j <= 100; j++)
        {
            double w = (d[h - 1] - d[h]) / 2.0;
            double s = sqrt(w * w + e[h] * e[h]);
            if (w < 0.0)
                s = -s;

            double x = d[l] - d[h] + e[h] * e[h] / (w + s);
            double y = e[l + 1];
            double z = 0.0;
            double t = 0.0;
            double u = 0.0;
            for (k = l; k < h; k++)
            {
                if (fabs(x) >= fabs(y))
                {
                    t = -y / x;
                    u = 1 / sqrt(t * t + 1.0);
                    s = t * u;
                }
                else
                {
                    t = -x / y;
                    s = 1 / sqrt(t * t + 1.0);
                    if (t < 0)
                        s = -s;
                    u = t * s;
                }
                w = d[k] - d[k + 1];
                t = (w * s + 2 * u * e[k + 1]) * s;
                d[k    ] = d[k    ] - t;
                d[k + 1] = d[k + 1] + t;
                e[k    ] = u * e[k] - s * z;
                e[k + 1] = e[k + 1] * (u * u - s * s) + w * s * u;

                // 次の行は固有ベクトルを求めないなら不要
                for (i = 0; i < N; i++)
                {
                    x = a[k    ][i];
                    y = a[k + 1][i];
                    a[k    ][i] = u * x - s * y;
                    a[k + 1][i] = s * x + u * y;
                }

                if (k < N - 2)
                {
                    x = e[k + 1];
                    y = -s * e[k + 2];
                    z = y;
                    e[k + 2] = u * e[k + 2];
                }
            }

            printf("%3d\t", j);
            disp_vector(d);

            // 収束判定
            if (fabs(e[h]) < 0.00000000001) break;
        }

        e[0] = 1.0;
        while (fabs(e[h]) < 0.00000000001) h--;
    }

    // 次の行は固有ベクトルを求めないなら不要
    for (k = 0; k < N - 1; k++)
    {
        int l = k;
        for (i = k + 1; i < N; i++)
            if (d[i] > d[l])
                l = i;

        double t = d[k];
        d[k] = d[l];
        d[l] = t;

        for (i = 0; i < N; i++)
        {
            t       = a[k][i];
            a[k][i] = a[l][i];
            a[l][i] = t;
        }
    }
}

// 1次元配列を表示
void disp_vector(double row[N])
{
    int i;
    for (i = 0; i < N; i++)
        printf("%14.10f\t", row[i]);
    printf("\n");
}
// 2次元配列を表示
void disp_matrix(double matrix[N][N])
{
    int col, row;
    for (row = 0; row < N; row++)
    {
        for (col = 0; col < N; col++)
            printf("%14.10f\t", matrix[row][col]);
        printf("\n");
    }
}
xxxxxx@yyyyyy /Z
$ gcc -o OC1106 OC1106.m -lobjc -lgnustep-base -I $INCLUDE -L $LIB $CFLAGS

xxxxxx@yyyyyy /Z
$ OC1106

QR分解
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000   -0.0000000000

D

import std.stdio;
import std.math;

const int N = 4;

// ハウスホルダー変換とQR分解で固有値を求める
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 d[N];
    double e[N];

    // ハウスホルダー変換
    tridiagonalize(a, d, e);

    // QR分解
    decomp(a, d, e);

    writefln("\neigenvalue");
    disp_vector(d);

    writefln("\neigenvector");
    disp_matrix(a);
}

// ハウスホルダー変換
void tridiagonalize(ref double[N][N] a, ref double[N] d, ref double[N] e)
{
    double v[N];

    foreach (k; 0..N - 2)
    {
        double w[N] = [0.0 ,0.0 ,0.0 ,0.0];
        d[k] = a[k][k];

        double t = 0.0;
        foreach (i; k + 1..N)
        {
            w[i] =  a[i][k];
            t    += w[i] * w[i];
        }
        double s = sqrt(t);
        if (w[k + 1] < 0)
            s = -s;

        if (fabs(s) < 0.00000000001)
            e[k + 1] = 0.0;
        else
        {
            e[k + 1]  = -s;
            w[k + 1] +=  s;
            s = 1 / sqrt(w[k + 1] * s);
            foreach (i; k + 1..N)
                w[i] *= s;

            foreach (i; k + 1..N)
            {
                s = 0.0;
                foreach (j; k + 1..N)
                {
                    if (j <= i)
                        s += a[i][j] * w[j];
                    else
                        s += a[j][i] * w[j];
                }
                v[i] = s;
            }

            s = 0.0;
            foreach (i; k + 1..N)
                s += w[i] * v[i];
            s /= 2.0;
            foreach (i; k + 1..N)
                v[i] -= s * w[i];
            foreach (i; k + 1..N)
                foreach (j; k + 1..i + 1)
                    a[i][j] -= w[i] * v[j] + w[j] * v[i];
            // 次の行は固有ベクトルを求めないなら不要
            foreach (i; k + 1..N)
                a[i][k] = w[i];
        }
    }

    d[N - 2] = a[N - 2][N - 2];
    d[N - 1] = a[N - 1][N - 1];

    e[0]     = 0.0;
    e[N - 1] = a[N - 1][N - 2];

    // 次の行は固有ベクトルを求めないなら不要
    foreach_reverse (k; 0..N)
    {
        double w[N] = [0.0 ,0.0 ,0.0 ,0.0];
        if (k < N - 2)
        {
            foreach (i; k + 1..N)
                w[i] = a[i][k];
            foreach (i; k + 1..N)
            {
                double s = 0.0;
                foreach (j; k + 1..N)
                    s += a[i][j] * w[j];
                v[i] = s;
            }
            foreach (i; k + 1..N)
                foreach (j; k + 1..N)
                    a[i][j] -= v[i] * w[j];
        }
        foreach (i; 0..N)
            a[i][k] = 0.0;
        a[k][k] = 1.0;
    }
}

// QR分解
void decomp(ref double[N][N] a, ref double[N] d, ref double[N] e)
{
    e[0] = 1.0;
    int h = N - 1;
    while (fabs(e[h]) < 0.00000000001) h--;

    while (h > 0)
    {
        e[0] = 0.0;
        int l = h - 1;
        while (fabs(e[l]) >= 0.00000000001) l--;

        foreach (j; 1..100)
        {
            double w = (d[h - 1] - d[h]) / 2.0;
            double s = sqrt(w * w + e[h] * e[h]);
            if (w < 0.0)
                s = -s;

            double x = d[l] - d[h] + e[h] * e[h] / (w + s);
            double y = e[l + 1];
            double z = 0.0;
            double t = 0.0;
            double u = 0.0;
            foreach (k; l..h)
            {
                if (fabs(x) >= fabs(y))
                {
                    t = -y / x;
                    u = 1 / sqrt(t * t + 1.0);
                    s = t * u;
                }
                else
                {
                    t = -x / y;
                    s = 1 / sqrt(t * t + 1.0);
                    if (t < 0)
                        s = -s;
                    u = t * s;
                }
                w = d[k] - d[k + 1];
                t = (w * s + 2 * u * e[k + 1]) * s;
                d[k    ] = d[k    ] - t;
                d[k + 1] = d[k + 1] + t;
                e[k    ] = u * e[k] - s * z;
                e[k + 1] = e[k + 1] * (u * u - s * s) + w * s * u;

                // 次の行は固有ベクトルを求めないなら不要
                foreach (i; 0..N)
                {
                    x = a[k    ][i];
                    y = a[k + 1][i];
                    a[k    ][i] = u * x - s * y;
                    a[k + 1][i] = s * x + u * y;
                }

                if (k < N - 2)
                {
                    x = e[k + 1];
                    y = -s * e[k + 2];
                    z = y;
                    e[k + 2] = u * e[k + 2];
                }
            }

            writef("%3d\t", j);
            disp_vector(d);

            // 収束判定
            if (fabs(e[h]) < 0.00000000001) break;
        }

        e[0] = 1.0;
        while (fabs(e[h]) < 0.00000000001) h--;
    }

    // 次の行は固有ベクトルを求めないなら不要
    foreach (k; 0..N - 1)
    {
        int l = k;
        foreach (i; k + 1..N)
            if (d[i] > d[l])
                l = i;

        double t = d[k];
        d[k] = d[l];
        d[l] = t;

        foreach (i; 0..N)
        {
            t       = a[k][i];
            a[k][i] = a[l][i];
            a[l][i] = t;
        }
    }
}

// 1次元配列を表示
void disp_vector(double[N] row)
{
    foreach (i; 0..N)
        writef("%14.10f\t", row[i]);
    writefln("");
}
// 2次元配列を表示
void disp_matrix(double[N][N] matrix)
{
    foreach (row; 0..N)
    {
        foreach (col; 0..N)
            writef("%14.10f\t", matrix[row][col]);
        writefln("");
    }
}
Z:\>dmd D1106.d

Z:\>D1106
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812   -0.0000000000   -0.0000000000

Go

package main

import "fmt"
import "math"

const N = 4

// ハウスホルダー変換とQR分解で固有値を求める
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 d               = []float64     {0.0 ,0.0 ,0.0 ,0.0}
    var e               = []float64     {0.0 ,0.0 ,0.0 ,0.0}

    // ハウスホルダー変換
    tridiagonalize(&a, d, e)

    // QR分解
    decomp(&a, d, e)

    fmt.Println("\neigenvalue")
    disp_vector(d)

    fmt.Println("\neigenvector")
    disp_matrix(a)
}

// ハウスホルダー変換
func tridiagonalize(a *[N][N]float64, d []float64, e []float64) {
    var v = []float64 {0.0 ,0.0 ,0.0 ,0.0}

    for k := 0; k < N - 2; k++ {
        var w = []float64 {0.0 ,0.0 ,0.0 ,0.0}
        d[k] = a[k][k]

        var t float64 = 0.0
        for i := k + 1; i < N; i++ {
            w[i] =  a[i][k]
            t    += w[i] * w[i]
        }
        var s float64 = math.Sqrt(t)
        if (w[k + 1] < 0) {
            s = -s
        }

        if (math.Abs(s) < 0.00000000001) {
            e[k + 1] = 0.0
        } else {
            e[k + 1]  = -s
            w[k + 1] +=  s
            s = 1 / math.Sqrt(w[k + 1] * s)
            for i := k + 1; i < N; i++ {
                w[i] *= s
            }

            for i := k + 1; i < N; i++ {
                s = 0.0
                for j := k + 1; j < N; j++ {
                    if (j <= i) {
                        s += a[i][j] * w[j]
                    } else {
                        s += a[j][i] * w[j]
                    }
                }
                v[i] = s
            }

            s = 0.0
            for i := k + 1; i < N; i++ {
                s += w[i] * v[i]
            }
            s /= 2.0
            for i := k + 1; i < N; i++ {
                v[i] -= s * w[i]
            }
            for i := k + 1; i < N; i++ {
                for j := k + 1; j < i + 1; j++ {
                    a[i][j] -= w[i] * v[j] + w[j] * v[i]
                }
            }
            // 次の行は固有ベクトルを求めないなら不要
            for i := k + 1; i < N; i++ {
                a[i][k] = w[i]
            }
        }
    }

    d[N - 2] = a[N - 2][N - 2]
    d[N - 1] = a[N - 1][N - 1]

    e[0]     = 0.0
    e[N - 1] = a[N - 1][N - 2]

    // 次の行は固有ベクトルを求めないなら不要
    for k := N - 1; k >= 0; k-- {
        var w = []float64 {0.0 ,0.0 ,0.0 ,0.0}
        if (k < N - 2) {
            for i := k + 1; i < N; i++ {
                w[i] = a[i][k]
            }
            for i := k + 1; i < N; i++ {
                var s float64 = 0.0
                for j := k + 1; j < N; j++ {
                    s += a[i][j] * w[j]
                }
                v[i] = s
            }
            for i := k + 1; i < N; i++ {
                for j := k + 1; j < N; j++ {
                    a[i][j] -= v[i] * w[j]
                }
            }
        }
        for i := 0; i < N; i++ {
            a[i][k] = 0.0
        }
        a[k][k] = 1.0
    }

}

// QR分解
func decomp(a *[N][N]float64, d []float64, e []float64) {
    e[0] = 1.0
    var h int = N - 1
    for (math.Abs(e[h]) < 0.00000000001) {
        h--
    }
    for (h > 0) {
        e[0] = 0.0
        var l int = h - 1
        for (math.Abs(e[l]) >= 0.00000000001) {
            l--
        }

        for j := 1; j < 100; j++ {
            var w float64 = (d[h - 1] - d[h]) / 2.0
            var s float64 = math.Sqrt(w * w + e[h] * e[h])
            if (w < 0.0) {
                s = -s
            }

            var x float64 = d[l] - d[h] + e[h] * e[h] / (w + s)
            var y float64 = e[l + 1]
            var z float64 = 0.0
            var t float64 = 0.0
            var u float64 = 0.0
            for k := l; k < h; k++ {
                if (math.Abs(x) >= math.Abs(y)) {
                    t = -y / x
                    u = 1 / math.Sqrt(t * t + 1.0)
                    s = t * u
                } else {
                    t = -x / y
                    s = 1 / math.Sqrt(t * t + 1.0)
                    if (t < 0) {
                        s = -s
                    }
                    u = t * s
                }
                w = d[k] - d[k + 1]
                t = (w * s + 2 * u * e[k + 1]) * s
                d[k    ] = d[k    ] - t
                d[k + 1] = d[k + 1] + t
                e[k    ] = u * e[k] - s * z
                e[k + 1] = e[k + 1] * (u * u - s * s) + w * s * u

                // 次の行は固有ベクトルを求めないなら不要
                for i := 0; i < N; i++ {
                    x = a[k    ][i]
                    y = a[k + 1][i]
                    a[k    ][i] = u * x - s * y
                    a[k + 1][i] = s * x + u * y
                }

                if (k < N - 2) {
                    x = e[k + 1]
                    y = -s * e[k + 2]
                    z = y
                    e[k + 2] = u * e[k + 2]
                }
            }

            fmt.Printf("%3d\t", j)
            disp_vector(d)

            // 収束判定
            if (math.Abs(e[h]) < 0.00000000001) {
                break
            }
        }

        e[0] = 1.0
        for (math.Abs(e[h]) < 0.00000000001) {
            h--
        }
    }

    // 次の行は固有ベクトルを求めないなら不要
    for k := 0; k < N - 1; k++ {
        var l int = k
        for i := k + 1; i < N; i++ {
            if (d[i] > d[l]) {
                l = i
            }
        }

        var t float64 = d[k]
        d[k] = d[l]
        d[l] = t

        for i := 0; i < N; i++ {
            t       = a[k][i]
            a[k][i] = a[l][i]
            a[l][i] = t
        }
    }
}

// 1次元配列を表示
func disp_vector(row[]float64) {
    for _, col := range row {
        fmt.Printf("%14.10f\t", col)
    }
    fmt.Println("")
}
// 2次元配列を表示
func disp_matrix(matrix[N][N]float64) {
    for row := 0; row < N; row++ {
        for col := 0; col < N; col++ {
            fmt.Printf("%14.10f\t", matrix[row][col])
        }
        fmt.Println()
    }
}
Z:\>go run GO1106.go
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

Scala

object Scala1106 {
    val N = 3

    // ハウスホルダー変換とQR分解で固有値を求める
    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 (d, e) = tridiagonalize(a)

        // QR分解
        decomp(a, d, e)

        println()
        println("eigenvalue")
        disp_vector(d)

        println()
        println("eigenvector")
        disp_matrix(a)
    }

    // ハウスホルダー変換
    def tridiagonalize(a: => Array[Array[Double]]): (Array[Double], Array[Double]) = {
        var v = new Array[Double](N + 1)
        var d = new Array[Double](N + 1)
        var e = new Array[Double](N + 1)

        for (k <- 0 to N - 2) {
            d(k) = a(k)(k)

            var w = (for (i <- 0 to N) yield
                        (if (i < k + 1) 0.0
                         else           a(i)(k))
                    ).toArray
            var s = Math.sqrt(w.map(n => n * n).sum)
            if (w(k + 1) < 0)
                s = -s

            if (Math.abs(s) < 0.00000000001)
                e(k + 1) = 0.0
            else {
                e(k + 1)  = -s
                w(k + 1) +=  s
                s = 1 / Math.sqrt(w(k + 1) * s)

                for (i <- k + 1 to N)
                    w(i) *= s

                for (i <- k + 1 to N) {
                    v(i) = (for (j <- k + 1 to N) yield
                               (if (j <= i) a(i)(j) * w(j)
                                else        a(j)(i) * w(j))
                           ).sum
                }

                s = (for (i <- k + 1 to N) yield
                        (w(i) * v(i))
                    ).sum / 2.0

                for (i <- k + 1 to N)
                    v(i) -= s * w(i)

                for (i <- k + 1 to N)
                    for (j <- k + 1 to i)
                        a(i)(j) -= w(i) * v(j) + w(j) * v(i)

                // 次の行は固有ベクトルを求めないなら不要
                for (i <- k + 1 to N)
                    a(i)(k) = w(i)
            }
        }

        d(N - 1) = a(N - 1)(N - 1)
        d(N    ) = a(N    )(N    )

        e(0)     = 0.0
        e(N    ) = a(N    )(N - 1)

        // 次の行は固有ベクトルを求めないなら不要
        for (k <- (N to 0 by -1)) {
            var w = (for (i <- 0 to N) yield
                        (if (i < k + 1) 0.0
                         else           a(i)(k))
                    ).toArray

                for (i <- k + 1 to N) {
                    v(i) = (for (j <- k + 1 to N) yield
                               (a(i)(j) * w(j))
                           ).sum
                }

                for (i <- k + 1 to N)
                    for (j <- k + 1 to N)
                        a(i)(j) -= v(i) * w(j)

            for (i <- 0 to N)
                a(i)(k) = 0.0
            a(k)(k) = 1.0
        }

        return (d, e)
    }

    // QR分解
    def decomp(a: => Array[Array[Double]], d: => Array[Double], e: => Array[Double]) {
        e(0) = 1.0
        var h = N
        while (Math.abs(e(h)) < 0.00000000001) h -= 1

        while (h > 0) {
            e(0) = 0.0
            var l = h - 1
            while (Math.abs(e(l)) >= 0.00000000001) l -= 1

            var j = 1
            do {
                var w = (d(h - 1) - d(h)) / 2.0
                var s = Math.sqrt(w * w + e(h) * e(h))
                if (w < 0.0)
                    s = -s

                var x = d(l) - d(h) + e(h) * e(h) / (w + s)
                var y = e(l + 1)
                var z = 0.0
                var t = 0.0
                var u = 0.0
                for (k <- l to h - 1) {
                    if (Math.abs(x) >= Math.abs(y)) {
                        t = -y / x
                        u = 1 / Math.sqrt(t * t + 1.0)
                        s = t * u
                    } else {
                        t = -x / y
                        s = 1 / Math.sqrt(t * t + 1.0) * (if (t < 0) -1.0 else 1.0)
                        u = t * s
                    }
                    w = d(k) - d(k + 1)
                    t = (w * s + 2 * u * e(k + 1)) * s
                    d(k    ) = d(k    ) - t
                    d(k + 1) = d(k + 1) + t
                    e(k    ) = u * e(k) - s * z
                    e(k + 1) = e(k + 1) * (u * u - s * s) + w * s * u

                    // 次の行は固有ベクトルを求めないなら不要
                    for (i <- 0 to N) {
                        x = a(k    )(i)
                        y = a(k + 1)(i)
                        a(k    )(i) = u * x - s * y
                        a(k + 1)(i) = s * x + u * y
                    }

                    if (k < N - 2) {
                        x = e(k + 1)
                        y = -s * e(k + 2)
                        z = y
                        e(k + 2) = u * e(k + 2)
                    }
                }

                print("%3d\t".format(j))
                j += 1
                disp_vector(d)

            } while (j <= 100 && Math.abs(e(h)) >= 0.00000000001)

            e(0) = 1.0
            while (Math.abs(e(h)) < 0.00000000001) h -= 1
        }

        // 次の行は固有ベクトルを求めないなら不要
        for (k <- 0 to N - 1) {
            var l = k
            for (i <- k + 1 to N)
                if (d(i) > d(l))
                    l = i

            var t = d(k)
            d(k) = d(l)
            d(l) = t

            for (i <- 0 to N) {
                t       = a(k)(i)
                a(k)(i) = a(l)(i)
                a(l)(i) = t
            }
        }
    }

    // 1次元配列を表示
    def disp_vector(row:Array[Double]) = {
        row.map( col => print("%14.10f\t".format(col)))
        println()
    }
    // 2次元配列を表示
    def disp_matrix(matrix:Array[Array[Double]]) {
        for (row <- 0 to N) {
            for (col <- 0 to N)
                print("%14.10f\t".format(matrix(row)(col)))
            println()
        }
    }
}
Z:\>scala Scala1106.scala
  1   7.8421052632    3.1783029001    4.9795918367    2.0000000000
  2   8.4366343427    2.5633699270    4.9999957303    2.0000000000
  3   8.9326997461    2.0673002539    5.0000000000    2.0000000000
  4   9.2864656206    1.7135343794    5.0000000000    2.0000000000
  1  10.0000000000    1.0000000000    5.0000000000    2.0000000000

eigenvalue
 10.0000000000    5.0000000000    2.0000000000    1.0000000000

eigenvector
  0.6324555320    0.6324555320    0.3162277660    0.3162277660
  0.3162277660    0.3162277660   -0.6324555320   -0.6324555320
  0.0000000000   -0.0000000000   -0.7071067812    0.7071067812
  0.7071067812   -0.7071067812    0.0000000000    0.0000000000

F#

module Fs1106

open System

let N = 3

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

// 2次元配列を表示
let disp_matrix (matrix:float[][]) =
    for row in [0..N] do
        for col in [0..N] do
            printf "%14.10f" matrix.[row].[col]
        printfn ""

// ハウスホルダー変換
let tridiagonalize (a:float[][]) : float[] * float[] =
    let v:float[] = [| for i in 0..N -> 0.0 |]
    let d:float[] = [| for i in 0..N -> 0.0 |]
    let e:float[] = [| for i in 0..N -> 0.0 |]

    for k in [0..(N - 2)] do
        d.[k] <- a.[k].[k]

        let w = [| for i in [0..N] ->
                       if (i < k + 1) then 0.0
                                      else a.[i].[k]
                |]
        let mutable s = Math.Sqrt(w |> Array.map (fun n -> n * n)
                                    |> Array.sum)
        if (w.[k + 1] < 0.0) then
            s <- -s

        if (Math.Abs(s) < 0.00000000001) then
            e.[k + 1] <- 0.0
        else
            e.[k + 1] <- -s
            w.[k + 1] <- w.[k + 1] + s
            s <- (1.0 / Math.Sqrt(w.[k + 1] * s))

            for i in [(k + 1)..N] do
                w.[i] <- w.[i] * s

            for i in [(k + 1)..N] do
                v.[i] <- [| for j in [(k + 1)..N] ->
                                if (j <= i) then a.[i].[j] * w.[j]
                                            else a.[j].[i] * w.[j]
                         |] |> Array.sum

            s <- (   [| for i in[(k + 1)..N] ->
                            w.[i] * v.[i]
                     |] |> Array.sum
                 ) / 2.0

            for i in [(k + 1)..N] do
                v.[i] <- v.[i] - s * w.[i]

            for i in [(k + 1)..N] do
                for j in [(k + 1)..i] do
                    a.[i].[j] <- a.[i].[j] - (w.[i] * v.[j] + w.[j] * v.[i])

            // 次の行は固有ベクトルを求めないなら不要
            for i in [(k + 1)..N] do
                a.[i].[k] <- w.[i]

    d.[N - 1] <- a.[N - 1].[N - 1]
    d.[N    ] <- a.[N    ].[N    ]

    e.[0]     <- 0.0
    e.[N    ] <- a.[N    ].[N - 1]

    // 次の行は固有ベクトルを求めないなら不要
    for k = N downto 0 do
        if k < N - 1 then
            let w = [| for i in [0..N] ->
                           if (i < k + 1) then 0.0
                                          else a.[i].[k]
                    |]

            for i in [(k + 1)..N] do
                v.[i] <- [| for j in [(k + 1)..N] ->
                                a.[i].[j] * w.[j]
                         |] |> Array.sum

            for i in [(k + 1)..N] do
                for j in [(k + 1)..N] do
                    a.[i].[j] <- a.[i].[j] - v.[i] * w.[j]

        for i in [0..N] do
            a.[i].[k] <- 0.0
        a.[k].[k] <- 1.0

    (d, e)


// QR分解
let decomp (a:float[][]) (d:float[]) (e:float[]) =
    e.[0] <- 1.0
    let mutable h = N
    while (Math.Abs(e.[h]) < 0.00000000001) do h <- h - 1

    while (h > 0) do
        e.[0] <- 0.0
        let mutable l = h - 1
        while (Math.Abs(e.[l]) >= 0.00000000001) do l <- l - 1

        let mutable j  = 1
        let mutable sw = true
        while sw || (j <= 100 && Math.Abs(e.[h]) >= 0.00000000001) do
            if sw then sw <- false

            let mutable w = (d.[h - 1] - d.[h]) / 2.0
            let mutable s = Math.Sqrt(w * w + e.[h] * e.[h])
            if (w < 0.0) then
                s <- -s

            let mutable x = d.[l] - d.[h] + e.[h] * e.[h] / (w + s)
            let mutable y = e.[l + 1]
            let mutable z = 0.0
            let mutable t = 0.0
            let mutable u = 0.0
            for k in [l..(h - 1)] do
                if (Math.Abs(x) >= Math.Abs(y)) then
                    t <- -y / x
                    u <- 1.0 / Math.Sqrt(t * t + 1.0)
                    s <- t * u
                else
                    t <- -x / y
                    s <- 1.0 / Math.Sqrt(t * t + 1.0) * if (t < 0.0) then -1.0 else 1.0
                    u <- t * s

                w <- d.[k] - d.[k + 1]
                t <- (w * s + 2.0 * u * e.[k + 1]) * s
                d.[k    ] <- d.[k    ] - t
                d.[k + 1] <- d.[k + 1] + t
                e.[k    ] <- u * e.[k] - s * z
                e.[k + 1] <- e.[k + 1] * (u * u - s * s) + w * s * u

                // 次の行は固有ベクトルを求めないなら不要
                for i in [0..N] do
                    x <- a.[k    ].[i]
                    y <- a.[k + 1].[i]
                    a.[k    ].[i] <- u * x - s * y
                    a.[k + 1].[i] <- s * x + u * y

                if k < N - 2 then
                    x <- e.[k + 1]
                    y <- -s * e.[k + 2]
                    z <- y
                    e.[k + 2] <- u * e.[k + 2]

            printf "%3d\t" j
            j <- j + 1
            disp_vector d

        e.[0] <- 1.0
        while (Math.Abs(e.[h]) < 0.00000000001) do h <- h - 1

    // 次の行は固有ベクトルを求めないなら不要
    for k in [0..(N - 1)] do
        let mutable l = k
        for i in [(k + 1)..N] do
            if d.[i] > d.[l] then
                l <- i

        let t =  d.[k]
        d.[k] <- d.[l]
        d.[l] <- t

        for i in [0..N] do
            let t     =  a.[k].[i]
            a.[k].[i] <- a.[l].[i]
            a.[l].[i] <- t

// ハウスホルダー変換とQR分解で固有値を求める
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 (d, e) = tridiagonalize a

// QR分解
decomp a d e

printfn ""
printfn "eigenvalue"
disp_vector d

printfn ""
printfn "eigenvector"
disp_matrix a

exit 0
Z:\>fsi  --nologo --quiet Fs1106.fs
  1   7.8421052632  3.1783029001  4.9795918367  2.0000000000
  2   8.4366343427  2.5633699270  4.9999957303  2.0000000000
  3   8.9326997461  2.0673002539  5.0000000000  2.0000000000
  4   9.2864656206  1.7135343794  5.0000000000  2.0000000000
  1  10.0000000000  1.0000000000  5.0000000000  2.0000000000

eigenvalue
 10.0000000000  5.0000000000  2.0000000000  1.0000000000

eigenvector
  0.6324555320  0.6324555320  0.3162277660  0.3162277660
  0.3162277660  0.3162277660 -0.6324555320 -0.6324555320
  0.0000000000  0.0000000000 -0.7071067812  0.7071067812
  0.7071067812 -0.7071067812  0.0000000000  0.0000000000

Clojure

Haskell

inserted by FC2 system