FC2ブログ
QLOOK ANALYTICS

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

ガウスの消去法(Gaussian Elimination)

連立方程式の解を求めるガウスの消去法です。



5x1+2x2+0x3=9
1x1+4x2+2x3=15
6x1+1x2+4x3=20


例えばこんな連立方程式を解きたければ
それぞれの方程式の係数を(定数項も)配列にします。



r1 = [5,2,0,9]
r2 = [1,4,2,15]
r3 = [6,1,4,20]

んでもってあとはそれらを引数にくれてやれば解の配列をはき出します。
ただし、解なしの場合や不定解の場合はエラーをはくだけです。
他はなんもしません。


ge = GaussianElimination.new
p ge.solve(r1,r2,r3) #=>[1.0, 2.0, 3.0]


上の例だと
x1=1、x2=2、x3=3
が解みたいですね。


ソースコードの構造は至って簡単です。
前進消去、後退代入、ピボット選択それぞれメソッドがありますので、
それをうまいこと実行してやるだけです。



ソースファイル gaussian_elimination.zip



class GaussianElimination
def initialize
@mat = nil
@dimension = 0
@solve = nil
end

def solve(*arrays)
@mat = arrays
@dimension = @mat.size
return "Dimension Error" if @dimension != @mat[0].size - 1
@solve = Array.new(@dimension)
return "Solve Error" unless forward_elimination
backward_substitution
return @solve
end

def forward_elimination
0.upto(@dimension-1) do |i|
nextto = true
@mat[i+1..-1].each{|line| if line[i] != 0 then nextto = false; break end}
if nextto
return false if @mat[i][i] == 0.0
next
end
select_pivot(i)
a = @mat[i][i]
@mat[i+1..-1].each do |line|
s = line[i] / a.to_f
line[i] = 0.0
(i+1).upto(@dimension) do |j|
line[j] -= s * @mat[i][j]
end
end
end
return true
end

def backward_substitution
(@dimension - 1).downto(0) do |i|
@solve[i] = @mat[i][-1]
(@dimension - 1).downto(i+1) do |j|
@solve[i] -= @mat[i][j] * @solve[j]
end
@solve[i] /= @mat[i][i].to_f
end
end

def select_pivot(i)
index = @mat.index(@mat[i..-1].max{|line1, line2| line1[i] <=> line2[i]})
return if i == index
@mat[i],@mat[index] = @mat[index],@mat[i]
end
end

ge = GaussianElimination.new
r1 = [5,2,0,9]
r2 = [1,4,2,15]
r3 = [6,1,4,20]
p ge.solve(r1,r2,r3)

関連記事

tag : Ruby ガウスの消去法

コメントの投稿

非公開コメント

プロフィール

gentlawk

Author:gentlawk
「BlueRedZone」を運営
Rubyが大好き
主にゲームプログラミングに取り組む
拍手がつくと地味に喜ぶ

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
Twitter
QRコード
QR
ブロとも申請フォーム

この人とブロともになる

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。