Gauss-Seidel

อ่านก่อน

Gauss-Seidel เป็นวิธีที่ปรับปรุงจาก Jacobi วิธีนี้พยายามเร่งให้ลู่หาคำตอบเร็วขึ้นโดยนำค่า x1 ที่คำนวณแล้วไปใช้ทันทีในรอบนั้น (ถ้าเป็น Jacobi จะคำนวณหา x1_i โดยใช้ x0 ล้วนๆ แต่ถ้าเป็นวิธีนี้จะเป็น x0 กับ x1) จุดที่แตกต่างคือจุดที่ผมเขียนคอมเมนท์ว่า change ก็ sugoi ดี แก้เล็กน้อยแต่ได้วิธีที่ลู่เร็วขึ้น (แต่บางทีก็ลู่ออกในขณะที่ Jacobi ลู่เข้า)

อินพุท เหมือนกับ Jacobi

  • m : Matrix1 ที่มีสัมประสิทธิ์ของตัวแปรแต่ละตัว และตัวเลขที่อยู่ฝั่งขวาของเครื่องหมายเท่ากับ
  • x0 : base-1 อาร์เรย์ที่เป็นการเดาเริ่มต้น
  • e : ค่าความผิดพลาดที่ยอมรับได้
  • round : จำนวนรอบสูงสุด
def gauss_seidel(m, x0 = nil, e = 0.00001, round = 1000)

เอาท์พุท

  • อาร์เรย์ของคำตอบ base-1

โค้ดทั้งหมด

require_relative 'base1'

def gauss_seidel(m, x0 = nil, e = 0.00001, round = 1000)
  n  = m.row_count
  b  = m.column(n+1)
  x0 = Array1.new(n, 0.0) if x0 == nil 
  x1 = x0.clone                           # change

  for r in 1..round
    for i in 1..n
      sum = 0.0
      for j in 1..n
        sum -= m[i,j] * x1[j] if i != j   # change
      end
      x1[i] = (sum + b[i]) / m[i,i]     
    end
    return x1 if terminate(x1, x0, e)
    x0.fill { |i| x1[i] }                 # change
  end
  
  raise "Solution does not converge"
end

def terminate(x1, x0, e)
  x1.each_index { |i| return false if ((x1[i] - x0[i]) / x1[i]) >= e }
  return true
end

การใช้งาน


ผลการรัน

หากจะนำโค้ดหรือข้อความไปใช้ ต้องแสดงที่มา และห้ามใช้ในเชิงพาณิชย์

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s