さまざまな言語で数値計算
Only Do What Only You Can Do
ガウス・ザイデル法
ガウス・ザイデル法を使って, 連立一次方程式の解を求める .
考え方はヤコビ法とほぼ同じ.
例として, 連立一次方程式
を考える.
ヤコビ法の場合, 漸化式で書くと
だったが, 2番目以降の式の $x_n$ の代わりに, 1番目の式で計算して得られた $x_{n+1}$ を使う.
同様に, 3番目以降の式の $y_n$ の代わりに, 2番目の式で計算して得られた $y_{n+1}$ を使う.
まとめると,
VBScript
Option Explicit Private Const N = 4 Private a: a = Array(Array(9,2,1,1),Array(2,8,-2,1),Array(-1,-2,7,-2),Array(1,-1,-2,6)) Private b: b = Array(20,16,8,17) Private c: c = Array(0,0,0,0) 'ガウス・ザイデル法 gauss a,b,c WScript.StdOut.WriteLine "X" disp_vector c 'ガウス・ザイデル法 Private Sub gauss(ByVal a, ByVal b, ByRef x0) Do While(True) Dim finish: finish = True Dim i, j For i = 0 To (N - 1) Dim x1: x1 = 0 For j = 0 To (N - 1) If i <> j Then x1 = x1 + a(i)(j) * x0(j) End If Next x1 = (b(i) - x1) / a(i)(i) If (Abs(x1 - x0(i)) > 0.0000000001) Then finish = False End If x0(i) = x1 Next If (finish) Then Exit Sub End If disp_vector x0 Loop 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
Z:\>cscript //nologo Z:\1002.vbs 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
JScript
var N = 4 var a = [[9,2,1,1],[2,8,-2,1],[-1,-2,7,-2],[1,-1,-2,6]] var b = [20,16,8,17] var c = [0,0,0,0] // ガウス・ザイデル法 gauss(a,b,c) WScript.StdOut.WriteLine("X") disp_vector(c) // ガウス・ザイデル法 function gauss(a, b, x0) { while (true) { var finish = true for (i = 0; i < N; i++) { var x1 = 0 for (j = 0; j < N; j++) if (j != i) x1 += a[i][j] * x0[j] x1 = (b[i] - x1) / a[i][i] if (Math.abs(x1 - x0[i]) > 0.0000000001) finish = false x0[i] = x1 } if (finish) return disp_vector(x0) } } // 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() }
Z:\>cscript //nologo Z:\1002.js 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.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 } # ガウス・ザイデル法 function gauss($a, $b, $x0) { while ($true) { $finish = $true foreach ($i in 0..$N) { $x1 = 0 foreach ($j in 0..$N) { if ($j -ne $i) { $x1 += $a[$i][$j] * $x0[$j] } } $x1 = ($b[$i] - $x1) / $a[$i][$i] if ([Math]::Abs($x1 - $x0[$i]) -gt 0.0000000001) { $finish = $false } $x0[$i] = $x1 } if ($finish) { return } disp_vector $x0 } } $a = (9.0,2.0,1.0,1.0), (2.0,8.0,-2.0,1.0), (-1.0,-2.0,7.0,-2.0), (1.0,-1.0,-2.0,6.0) $b = 20.0, 16.0, 8.0, 17.0 $c = 0.0, 0.0, 0.0, 0.0 # ガウス・ザイデル法 gauss $a $b $c Write-Host "X" disp_vector $c
Z:\>powershell -file Z:\1002.ps1 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
Perl
use constant N => 3; my @a = ([9,2,1,1],[2,8,-2,1],[-1,-2,7,-2],[1,-1,-2,6]); my @b = (20,16,8,17); my @c = (0,0,0,0); # ガウス・ザイデル法 gauss(\@a, \@b, \@c); print "X\n"; disp_vector(\@c); # ガウス・ザイデル法 sub gauss { my ($a, $b, $x0) = @_; while (1) { my $finish = 1; for $i (0..N) { my $x1 = 0; for $j (0..N) { if ($j != $i) { $x1 += $$a[$i][$j] * $$x0[$j]; } } $x1 = ($$b[$i] - $x1) / $$a[$i][$i]; $finish = 0 if (abs($x1 - $$x0[$i]) > 0.0000000001); $$x0[$i] = $x1; } return if ($finish); disp_vector($x0); } } # 1次元配列を表示 sub disp_vector { my ($row) = @_; foreach $col (@$row) { printf("%14.10f\t", $col); } print "\n"; }
Z:\>perl Z:\1002.pl 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
PHP
<?php define("N", 3); $a = [[9,2,1,1],[2,8,-2,1],[-1,-2,7,-2],[1,-1,-2,6]]; $b = [20,16,8,17]; $c = [0,0,0,0]; # ガウス・ザイデル法 gauss($a, $b, $c); print "X\n"; disp_vector($c); # ガウス・ザイデル法 function gauss($a, $b, &$x0) { while (true) { $finish = true; foreach (range(0, N) as $i) { $x1 = 0; foreach (range(0, N) as $j) { if ($j != $i) $x1 += $a[$i][$j] * $x0[$j]; } $x1 = ($b[$i] - $x1) / $a[$i][$i]; if (abs($x1 - $x0[$i]) > 0.0000000001) $finish = false; $x0[$i] = $x1; } if ($finish) return; disp_vector($x0); } } # 1次元配列を表示 function disp_vector($row) { foreach ($row as $col) printf("%14.10f\t", $col); print "\n"; } ?>
Z:\>php Z:\1002.php 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
Python
# coding: Shift_JIS N = 4 # 1次元配列を表示 def disp_vector(row): for col in row: print "%14.10f\t" % col, print "" # ガウス・ザイデル法 def gauss(a, b, x0): while True: x1 = 0.0 finish = True for i in range(0, N, 1): x1 = 0 for j in range(0, N, 1): if (j != i): x1 += a[i][j] * x0[j] x1 = (b[i] - x1) / a[i][i] if (abs(x1 - x0[i]) > 0.0000000001): finish = False x0[i] = x1 if (finish): return disp_vector(x0) a = [[ 9.0, 2.0, 1.0, 1.0], [2.0, 8.0, -2.0, 1.0], [-1.0, -2.0, 7.0, -2.0], [1.0, -1.0, -2.0, 6.0]] b = [20.0, 16.0, 8.0, 17.0] c = [ 0.0, 0.0, 0.0, 0.0] # ガウス・ザイデル法 gauss(a,b,c) print "X" disp_vector(c)
Z:\>python Z:\1002.py 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
Ruby
# coding: Shift_JIS N = 3 # 1次元配列を表示 def disp_vector(row) row.each do |col| printf("%14.10f\t", col) end puts "" end # ガウス・ザイデル法 def gauss(a, b, x0) while true finish = true (0..N).each do |i| x1 = 0 (0..N).each do |j| if (j != i) x1 += a[i][j] * x0[j] end end x1 = (b[i] - x1) / a[i][i] if ((x1 - x0[i]).abs > 0.0000000001) finish = false end x0[i] = x1 end return if (finish) disp_vector(x0) end end a = [[ 9.0, 2.0, 1.0, 1.0], [2.0, 8.0, -2.0, 1.0], [-1.0, -2.0, 7.0, -2.0], [1.0, -1.0, -2.0, 6.0]] b = [20.0, 16.0, 8.0, 17.0] c = [ 0.0, 0.0, 0.0, 0.0] # ガウス・ザイデル法 gauss(a,b,c) puts "X" disp_vector(c)
Z:\>ruby Z:\1002.rb 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
Groovy
N = 3 def a = [[ 9.0, 2.0, 1.0, 1.0], [2.0, 8.0, -2.0, 1.0], [-1.0, -2.0, 7.0, -2.0], [1.0, -1.0, -2.0, 6.0]] as double[][] def b = [20.0, 16.0, 8.0, 17.0] as double[] def c = [ 0.0, 0.0, 0.0, 0.0] as double[] // ガウス・ザイデル法 gauss(a,b,c) println("X") disp_vector(c) // ガウス・ザイデル法 def gauss(a, b, x0) { def x1 = [ 0.0, 0.0, 0.0, 0.0] as double[] while (true) { def finish = true for (i in 0..N ) { x1[i] = 0 for (j in 0..N ) { if (j != i) x1[i] += a[i][j] * x0[j] } x1[i] = (b[i] - x1[i]) / a[i][i] if (Math.abs(x1[i] - x0[i]) > 0.0000000001) finish = false x0[i] = x1[i] } if (finish) return disp_vector(x0) } } // 1次元配列を表示 def disp_vector(row) { for (col in row) { printf ("%14.10f\t" , col) } println() }
Z:\>groovy Groovy1002.groovy 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
Pascal
program Pas1002(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; // ガウス・ザイデル法 procedure gauss(a:TwoDimArray; b:array of Double; var x0:array of Double); var x1 :Double; finish:Boolean; i, j:Integer; begin while (true) do begin finish := true; for i := Low(x0) to High(x0) do begin x1 := 0.0; for j := Low(x0) to High(x0) do if j <> i then x1 := x1 + a[i,j] * x0[j]; x1 := (b[i] - x1) / a[i,i]; if (Abs(x1 - x0[i]) > 0.0000000001) then finish := false; x0[i] := x1; end; if finish then exit; disp_vector(x0); end; end; var a :TwoDimArray = (( 9.0, 2.0, 1.0, 1.0), (2.0, 8.0, -2.0, 1.0), (-1.0, -2.0, 7.0, -2.0), (1.0, -1.0, -2.0, 6.0)); b :array [0..N] of Double = (20.0, 16.0, 8.0, 17.0); c :array [0..N] of Double = ( 0.0, 0.0, 0.0, 0.0); begin // ガウス・ザイデル法 gauss(a,b,c); writeln('X'); disp_vector(c); end.
Z:\>fpc -v0 -l- Pas1002.pp Z:\>Pas1002 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
Ada
with TEXT_IO, Ada.Long_Float_Text_IO, Ada.Numerics.Long_Elementary_Functions; use TEXT_IO, Ada.Long_Float_Text_IO, Ada.Numerics.Long_Elementary_Functions; procedure Ada1002 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 := (( 9.0, 2.0, 1.0, 1.0), (2.0, 8.0, -2.0, 1.0), (-1.0, -2.0, 7.0, -2.0), (1.0, -1.0, -2.0, 6.0)); b:Long_Float_Array := (20.0, 16.0, 8.0, 17.0); c:Long_Float_Array := ( 0.0, 0.0, 0.0, 0.0); -- 1次元配列を表示 procedure disp_vector(row:Long_Float_Array) is begin for i in row'Range loop Put(row(i), Fore=>3, Aft=>10, Exp=>0); Put(Ascii.HT); end loop; New_Line; end disp_vector; -- ガウス・ザイデル法 procedure gauss(a:Long_Float_TwoDimArray; b:Long_Float_Array; x0:in out Long_Float_Array) is x1:Long_Float; finish:Boolean; begin while true loop finish := true; for i in x0'Range loop x1 := 0.0; for j in x0'Range loop if j /= i then x1 := x1 + a(i,j) * x0(j); end if; end loop; x1 := (b(i) - x1) / a(i,i); if (Abs(x1 - x0(i)) > 0.0000000001) then finish := false; end if; x0(i) := x1; end loop; if finish then exit; end if; disp_vector(x0); end loop; end gauss; begin -- ガウス・ザイデル法 gauss(a,b,c); Put_Line("X"); disp_vector(c); end Ada1002;
xxxxxx@yyyyyy /Z $ gnatmake Ada1002.adb xxxxxx@yyyyyy /Z $ Ada1002 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
VB.NET
Option Explicit Module VB1002 Private Const N As Integer = 3 Public Sub Main() Dim a(,) As Double = {{9,2,1,1},{2,8,-2,1},{-1,-2,7,-2},{1,-1,-2,6}} Dim b() As Double = {20,16,8,17} Dim c() As Double = {0,0,0,0} 'ガウス・ザイデル法 gauss(a,b,c) Console.WriteLine("X") disp_vector(c) 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 'ガウス・ザイデル法 Private Sub gauss(ByVal a(,) As Double, ByVal b() As Double, ByVal x0() As Double) Do While(True) Dim finish As Boolean = True For i As Integer = 0 To N Dim x1 As Double = 0 For j As Integer = 0 To N If j <> i Then x1 += a(i,j) * x0(j) End If Next x1 = (b(i) - x1) / a(i,i) If (Math.Abs(x1 - x0(i)) > 0.0000000001) Then finish = False x0(i) = x1 Next If finish Then Return disp_vector(x0) Loop End Sub End Module
Z:\>vbc -nologo VB1002.vb Z:\>VB1002 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
C#
using System; public class CS1002 { private const int N = 4; public static void Main() { double[,] a = {{9,2,1,1},{2,8,-2,1},{-1,-2,7,-2},{1,-1,-2,6}}; double[] b = {20,16,8,17}; double[] c = {0,0,0,0}; // ガウス・ザイデル法 gauss(a,b,c); Console.WriteLine("X"); disp_vector(c); } // ガウス・ザイデル法 private static void gauss(double[,] a, double[] b, double[] x0) { while (true) { bool finish = true; for (int i = 0; i < N; i++) { double x1 = 0; for (int j = 0; j < N; j++) if (j != i) x1 += a[i,j] * x0[j]; x1 = (b[i] - x1) / a[i,i]; if (Math.Abs(x1 - x0[i]) > 0.0000000001) finish = false; x0[i] = x1; } if (finish) return; disp_vector(x0); } } // 1次元配列を表示 private static void disp_vector(double[] row) { foreach (double col in row) Console.Write(string.Format("{0,14:F10}\t", col)); Console.WriteLine(); } }
Z:\>csc -nologo CS1002.cs Z:\>CS1002 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
Java
import java.lang.*; public class Java1002 { private static final int N = 4; public static void main(String []args) { double[][] a = {{9,2,1,1},{2,8,-2,1},{-1,-2,7,-2},{1,-1,-2,6}}; double[] b = {20,16,8,17}; double[] c = {0,0,0,0}; // ガウス・ザイデル法 gauss(a,b,c); System.out.println("X"); disp_vector(c); } // ガウス・ザイデル法 private static void gauss(double[][] a, double[] b, double[] x0) { while (true) { boolean finish = true; for (int i = 0; i < N; i++) { double x1 = 0; for (int j = 0; j < N; j++) if (j != i) x1 += a[i][j] * x0[j]; x1 = (b[i] - x1) / a[i][i]; if (Math.abs(x1 - x0[i]) > 0.0000000001) finish = false; x0[i] = x1; } if (finish) return; disp_vector(x0); } } // 1次元配列を表示 private static void disp_vector(double[] row) { for (double col: row) System.out.print(String.format("%14.10f\t", col)); System.out.println(); } }
Z:\>javac Java1002.java Z:\>java Java1002 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
C++
#include <iostream> #include <iomanip> #include <math.h> using namespace std; const int N = 4; // ガウス・ザイデル法 void gauss(double a[N][N], double b[N], double c[N]); // 1次元配列を表示 void disp_vector(double row[N]); int main() { double a[N][N] = {{9,2,1,1},{2,8,-2,1},{-1,-2,7,-2},{1,-1,-2,6}}; double b[N] = {20,16,8,17}; double c[N] = {0,0,0,0}; // ガウス・ザイデル法 gauss(a,b,c); cout << "X" << endl; disp_vector(c); return 0; } // ガウス・ザイデル法 void gauss(double a[N][N], double b[N], double x0[N]) { while (true) { bool finish = true; for (int i = 0; i < N; i++) { double x1 = 0; for (int j = 0; j < N; j++) if (j != i) x1 += a[i][j] * x0[j]; x1 = (b[i] - x1) / a[i][i]; if (fabs(x1 - x0[i]) > 0.0000000001) finish = false; x0[i] = x1; } if (finish) return; disp_vector(x0); } } // 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; }
Z:\>bcc32 -q CP1002.cpp cp1002.cpp: Z:\>CP1002 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
Objective-C
#import <Foundation/Foundation.h> #import <math.h> const int N = 4; // ガウス・ザイデル法 void gauss(double a[N][N], double b[N], double c[N]); // 1次元配列を表示 void disp_vector(double row[N]); int main() { double a[4][4] = {{9,2,1,1},{2,8,-2,1},{-1,-2,7,-2},{1,-1,-2,6}}; double b[4] = {20,16,8,17}; double c[4] = {0,0,0,0}; // ガウス・ザイデル法 gauss(a,b,c); printf("X\n"); disp_vector(c); return 0; } // ガウス・ザイデル法 void gauss(double a[N][N], double b[N], double x0[N]) { while (YES) { BOOL finish = YES; int i, j; for (i = 0; i < N; i++) { double x1 = 0; for (j = 0; j < N; j++) if (j != i) x1 += a[i][j] * x0[j]; x1 = (b[i] - x1) / a[i][i]; if (fabs(x1 - x0[i]) > 0.0000000001) finish = NO; x0[i] = x1; } if (finish) return; disp_vector(x0); } } // 1次元配列を表示 void disp_vector(double row[N]) { int i; for (i = 0; i < N; i++) { printf("%14.10f\t", row[i]); } printf("\n"); }
xxxxxx@yyyyyy /Z $ gcc -o OC1002 OC1002.m -lobjc -lgnustep-base -I $INCLUDE -L $LIB $CFLAGS xxxxxx@yyyyyy /Z $ OC1002 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
D
import std.stdio; import std.math; const int N = 4; void main(string[] args) { double[N][N] a = [[9,2,1,1],[2,8,-2,1],[-1,-2,7,-2],[1,-1,-2,6]]; double[N] b = [20,16,8,17]; double[N] c = [0,0,0,0]; // ガウス・ザイデル法 gauss(a,b,c); writefln("X"); disp_vector(c); } // ガウス・ザイデル法 void gauss(double[N][N] a, double[N] b, ref double[N] x0) { while (true) { bool finish = true; foreach(i; 0..N) { double x1 = 0; foreach(j; 0..N) if (j != i) x1 += a[i][j] * x0[j]; x1 = (b[i] - x1) / a[i][i]; if (fabs(x1 - x0[i]) > 0.0000000001) finish = false; x0[i] = x1; } if (finish) return; disp_vector(x0); } } // 1次元配列を表示 void disp_vector(double[] row) { foreach(col; row) writef("%14.10f\t", col); writefln(""); }
Z:\>dmd D1002.d Z:\>D1002 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
Go
package main import "fmt" import "math" const N = 4 func main() { var a [N][N]float64 = [N][N]float64{{9,2,1,1},{2,8,-2,1},{-1,-2,7,-2},{1,-1,-2,6}} var b = []float64{20,16,8,17} var c = []float64{0,0,0,0} // ガウス・ザイデル法 gauss(a,b,c) fmt.Println("X") disp_vector(c) } // ガウス・ザイデル法 func gauss(a[N][N]float64, b[]float64, x0[]float64) { for { var finish = true for i := 0; i < N; i++ { var x1 float64 = b[i] for j := 0; j < N; j++ { if (j != i) { x1 -= a[i][j] * x0[j] } } x1 /= a[i][i] if (math.Fabs(x1 - x0[i]) > 0.0000000001) { finish = false } x0[i] = x1 } if (finish) { return } disp_vector(x0) } } // 1次元配列を表示 func disp_vector(row[]float64) { for _, col := range row { fmt.Printf("%14.10f\t", col) } fmt.Println("") }
Z:\>8g GO1002.go Z:\>8l -o GO1002.exe GO1002.8 Z:\>GO1002 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
Scala
object Scala1002 { val N = 3 def main(args: Array[String]) { var a:Array[Array[Double]] = Array(Array(9,2,1,1),Array(2,8,-2,1),Array(-1,-2,7,-2),Array(1,-1,-2,6)) var b:Array[Double] = Array(20,16,8,17) var c:Array[Double] = Array(0,0,0,0) // ガウス・ザイデル法 gauss(a,b,c) println("X") disp_vector(c) } // ガウス・ザイデル法 def gauss(a:Array[Array[Double]], b:Array[Double], x0:Array[Double]) = { var finish:Boolean = false while (!finish) { finish = true for (i <- 0 to N) { var x1:Double = 0 for (j <- 0 to N) if (j != i) x1 += a(i)(j) * x0(j) x1 = (b(i) - x1) / a(i)(i) if (Math.abs(x1 - x0(i)) > 0.0000000001) finish = false x0(i) = x1 } if (!finish) disp_vector(x0) } } // 1次元配列を表示 def disp_vector(row:Array[Double]) = { row.foreach { col => print("%14.10f\t".format(col)) } println() } }
Z:\>scala Scala1002.scala 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
F#
module Fs1002 open System let N = 3 // 1次元配列を表示 let disp_vector (row:float[]) = row |> Array.iter (fun x -> printf "%14.10f" x) printfn "" // ガウス・ザイデル法 let gauss (a:float[][]) (b:float[]) (x0:float[]) = let mutable finish:bool = false while not finish do finish <- true for i in [0..N] do let mutable x1:float = 0.0 for j in [0..N] do if j <> i then x1 <- x1 + a.[i].[j] * x0.[j] x1 <- (b.[i] - x1) / a.[i].[i] if Math.Abs(x1 - x0.[i]) > 0.0000000001 then finish <- false x0.[i] <- x1 if not finish then disp_vector x0 let a:float[][] = [| [| 9.0;2.0;1.0;1.0 |]; [|2.0;8.0;-2.0;1.0 |]; [|-1.0;-2.0;7.0;-2.0 |]; [|1.0;-1.0;-2.0;6.0 |] |] let b:float[] = [| 20.0;16.0;8.0;17.0 |] let c:float[] = [| 0.0;0.0;0.0;0.0 |] // ガウス・ザイデル法 gauss a b c printfn "X" disp_vector c exit 0
Z:\>fsi --nologo --quiet Fs1002.fs 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
Clojure
(def N 4) (def a [[9.0 2.0 1.0 1.0] [2.0 8.0 -2.0 1.0] [-1.0 -2.0 7.0 -2.0] [1.0 -1.0 -2.0 6.0]]) (def b [20.0 16.0 8.0 17.0]) (def x0 [0.0 0.0 0.0 0.0]) ;1次元配列を表示 (defn disp_vector [row] (doseq [col row] (print (format "%14.10f\t" col))) (println)) ;2次元配列を表示 (defn disp_matrix [matrix] (doseq [row matrix] (doseq [col row] (print (format "%14.10f\t" col))) (println))) ;ガウス・ザイデル法 (defn row_loop [row a b x0 x1] (def a1 (map (fn [a b] [a b]) (nth a row) x0)) (def a2 (concat (take row a1) (drop (+ row 1) a1))) (def a3 (map (fn [x] (* (first x) (second x))) a2)) (def s (apply + a3)) (def x (/ (- (nth b row) s) (nth (nth a row) row))) (def xs (cons x x1)) (def x2 (concat (take (inc row) (reverse xs)) (drop (inc row) x0))) (if (>= row (- N 1)) (reverse xs) (row_loop (inc row) a b x2 xs))) (defn gauss [a b x0 xs] (def x1 (row_loop 0 a b x0 [])) (def cnt (count (filter (fn [x] (>= x 0.0000000001)) (map (fn [x] (. Math abs (- (first x) (second x)))) (map (fn [a b] [a b]) x0 x1))))) (if (< cnt 1) (vector (reverse xs) x1) (gauss a b x1 (cons x1 xs)))) ;ガウス・ザイデル法 (def xs (gauss a b x0 [])) (disp_matrix (first xs)) (println "X") (disp_vector (second xs))
Z:\>java -cp C:\ProgramFiles\clojure-1.5.1\clojure-1.5.1.jar clojure.main Clj1002.clj 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000
Haskell
import Text.Printf import Control.Monad n = 4::Int -- 2次元配列を表示 disp_matrix::[[Double]]->IO() disp_matrix matrix = do forM_ matrix $ \row -> do forM_ row $ \elem -> do printf "%14.10f\t" elem putStrLn "" -- 1次元配列を表示 disp_vector::[Double]->IO() disp_vector vector = do forM_ vector $ \elem -> do printf "%14.10f\t" elem putStrLn "" -- ガウス・ザイデル法 row_loop::Int->[[Double]]->[Double]->[Double]->[Double]->[Double] row_loop row a b x0 x1 = let a1 = zip (a!!row) x0 a2 = take row a1 ++ drop (row + 1) a1 a3 = map (\(x, y) -> x * y) $ a2 s = sum a3 x = ((b!!row) - s) / a!!row!!row xs = x:x1 x2 = (take (row+1) (reverse xs)) ++ (drop (row+1) x0) in if row >= (n - 1) then reverse xs else (row_loop (row+1) a b x2 xs) gauss::[[Double]]->[Double]->[Double]->[[Double]]->([[Double]],[Double]) gauss a b x0 xs = let x1 = (row_loop 0 a b x0 []) cnt = length $ filter (>= 0.0000000001) $ map (\(x,y) -> abs(x - y)) $ zip x0 x1 in if cnt < 1 then (reverse xs, x1) else (gauss a b x1 (x1:xs)) main = do let a = [[9,2,1,1],[2,8,-2,1],[-1,-2,7,-2],[1,-1,-2,6::Double]] let b = [20,16,8,17::Double] let x0 = [0,0,0,0::Double] -- ガウス・ザイデル法 let (xs, x1) = gauss a b x0 [] disp_matrix xs putStrLn "X" disp_vector x1
Z:\>runghc Hs1002.hs 2.2222222222 1.4444444444 1.8730158730 3.3280423280 1.3233392122 1.7214138742 2.7746073738 3.8245482349 1.1064462937 1.9389717407 2.9476408921 3.9546345385 1.0244201209 1.9864758755 2.9866629927 3.9892302900 1.0056838851 1.9965909906 2.9967609209 3.9974048246 1.0014058081 1.9991631751 2.9992202582 3.9993663139 1.0003430086 1.9997985232 2.9998103832 3.9998460468 1.0000829471 1.9999511032 2.9999538924 3.9999626568 1.0000201383 1.9999881064 2.9999888093 3.9999909311 1.0000048941 1.9999971124 2.9999972830 3.9999977974 1.0000011883 1.9999992990 2.9999993402 3.9999994652 1.0000002885 1.9999998298 2.9999998398 3.9999998701 1.0000000701 1.9999999587 2.9999999611 3.9999999685 1.0000000170 1.9999999900 2.9999999906 3.9999999923 1.0000000041 1.9999999976 2.9999999977 3.9999999981 1.0000000010 1.9999999994 2.9999999994 3.9999999995 1.0000000002 1.9999999999 2.9999999999 3.9999999999 1.0000000001 2.0000000000 3.0000000000 4.0000000000 X 1.0000000000 2.0000000000 3.0000000000 4.0000000000