อันนี้เป็นโจทย์ที่ได้ตอนผมนั่งทำการบ้านวิชา 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
ใช้ NumPy ดีไหมหนอ :P
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)นี่มันเหมือนกับ parallel gaussian elimination เลย โอ้ว functional มันดีอย่างนี้นี่เอง แปลว่าคนที่อยากเรียนเรื่อง parallel algorithm ควรถูกส่งไปเรียน functional programming ก่อน (รึเปล่า?)