Guassian Elimination

  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.
  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.

อันนี้เป็นโจทย์ที่ได้ตอนผมนั่งทำการบ้านวิชา Numerical Analysis ครับ

เราสามารถเขียนโปรแกรมภาษาต่างๆเพื่อทำ Guassian Elimination ได้ยังไงเหรอครับ

Guassian Elimination คือการแปลง matrix ของระบบสมการเชิงเส้นโดยจะได้ผลลัพธ์เป็นระบบสมการที่มีสัมประสิทธิ์เป็น matrix สามเหลี่ยมบน

เช่น

a b c|x0 = y0
d e f|x1 = y1
g h i|x2 = y2 

เมื่อทำ guassian elimination แล้วจะได้เป็น

a b c|x0 = y0
0 E F|x1 = Y1
0 0 I|x2 = Y2 

(สังเกตตัวเล็กตัวใหญ่)

โดยที่ E = e - b*d/a, F = f - c*d/a, Y1 = y1 - y0*d/a
และ I = ( i - c*g/a ) - F*E/h, Y2 = (y2 - y0*g/a) - Y1*E/h

โดยเมื่อแทนย้อนกลับแล้วจะได้ระบบสมการที่เป็นจริง

สำหรับ Pseudocode ของ Gaussian_elimination สามารถดูได้ที่นี่ http://en.wikipedia.org/wiki/Gaussian_elimination

จะยากไปไหมน้อ

Ruby Version ครับ
http://www.codenone.com/node/76

pittaya's picture

ใช้ NumPy ดีไหมหนอ :P

sugree's picture

Python แบบยาว

http://www.codenone.com/node/79

พยายามเขียนด้วย haskell แล้ว แต่ไม่สำเร็จ
สุดท้ายก็ใช้วิชาลอก
ไปเจอคุณ Joy Goodman แกเขียนอธิบายอย่างละเอียดเขียว
อ่านได้ที่
PhD Thesis: Incremental Program Transformation Using Abstract Parallel Machines
วิธี implement แบบง่ายสุด อยู่ในหัวข้อ non-monadic stage.

สำหรับคนที่ยังไม่สนใจ ลองดูรูปร่างของ code ก่อนแล้วกัน

type Vector a = [a]
type Matrix a = [[a]]
 
gauss :: Fractional a => Matrix a -> Vector a -> Vector a
gauss a b =
    let m = zipWith join a b
          where join xs y = xs ++ [y]
        n = length b
        m2 = foldl deal_with_jth_row m [1..n-1]
        x = accum_scanr1 solve_ith_eqn m2
    in 
        x
 
deal_with_jth_row :: Fractional a => Matrix a -> Int -> Matrix a
deal_with_jth_row m j = first_j_rows ++ (map put_0_in_jth_pos other_rows)
         where
           first_j_rows = take j m
           other_rows   = drop j m
           put_0_in_jth_pos row =  zipWith join row (m !! (j-1))
               where
                 join x y = mult * y + x
                 mult = -(row !! (j-1) / m !! (j-1) !! (j-1))
 
 
solve_ith_eqn :: Fractional a => Vector a -> Vector a -> a
solve_ith_eqn row zs = 
    (foldl (+) (row!!n) (zipWith f (drop i row) zs)) / (row!!(i-1))
   where n = (length row) - 1
         i = n - length zs
         f x y = -(x * y)
 
 
accum_scanr1 :: (a -> [b] -> b) -> [a] -> [b]
accum_scanr1 f zs = map head (scanr' g [] zs)
   where 
        g x ys = (f x ys):ys
        scanr' f a xs = init(scanr f a xs)
sugree's picture

นี่มันเหมือนกับ parallel gaussian elimination เลย โอ้ว functional มันดีอย่างนี้นี่เอง แปลว่าคนที่อยากเรียนเรื่อง parallel algorithm ควรถูกส่งไปเรียน functional programming ก่อน (รึเปล่า?)

ย้าย Codenone

ประกาศย้าย Codenone ไปใช้ Forum ของ Blognone แทนครับ ตามไปตั้งกระทู้ต่อได้ที่ Codenone Forum (รายละเอียดอ่านจากกระทู้ ย้าย Codenone ไปรวมกับ Blognone)

กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น