Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Gaussian Elimination in Haskell #193

Merged
merged 35 commits into from
Jul 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
db5f246
Added Huffman with Haskell
jiegillet Apr 17, 2018
7933406
Changed Nil to Maybe (Tree a)
jiegillet Apr 17, 2018
eb3c7b4
Small typo in Huffman.md
jiegillet Apr 17, 2018
388799c
Merge remote-tracking branch 'upstream/master'
jiegillet Apr 19, 2018
2fc1d8f
Jarvis March in Haskell
jiegillet Apr 19, 2018
d980303
Merge remote-tracking branch 'upstream/master'
jiegillet Apr 20, 2018
a9466b6
fixed merge conflict
jiegillet May 14, 2018
7227bd0
added a file to allow merge
jiegillet Jun 3, 2018
a3d9fad
Updated remote to algorithm-archivists and synced
jiegillet Jun 3, 2018
608c54d
Merge remote-tracking branch 'upstream/master'
jiegillet Jun 29, 2018
93e6702
Merge remote-tracking branch 'upstream/master'
jiegillet Jun 29, 2018
989d8cd
Merge remote-tracking branch 'upstream/master'
jiegillet Jul 1, 2018
f957b3c
Added Gaussian Elimination in Haskell
jiegillet Jul 1, 2018
0d922cb
fixed a file for merging
jiegillet Jul 2, 2018
42ab99e
Merge branch 'master' of github.com:jiegillet/algorithm-archive
jiegillet Jul 2, 2018
de67eb9
Added Gaussian Elimination in Haskell
jiegillet Jul 1, 2018
57b8e7a
Changed pseudocode to code
jiegillet Jul 2, 2018
16ca5bf
fixing a blunder
jiegillet Jul 2, 2018
5e34439
Indented code with hindent
jiegillet Jul 3, 2018
f7a5306
Modified chapter to include singular systems
jiegillet Jul 3, 2018
5cba46c
Merging from origin, again
jiegillet Jul 3, 2018
d1ea0a7
fixing some of my typos.
leios Jul 4, 2018
b2d25b9
Merge pull request #1 from leios/gaussianElimination_updates
jiegillet Jul 4, 2018
7ceb7bd
Text edits, less frenchy more mathy
jiegillet Jul 4, 2018
b0e677e
Merge branch 'master' of https://github.com/algorithm-archivists/algo…
jiegillet Jul 17, 2018
d531fde
Merge branch 'master' of github.com:jiegillet/algorithm-archive
jiegillet Jul 17, 2018
fd3eeef
huffman encoding version was broken
jiegillet Jul 17, 2018
ee565eb
fixing huffman.md
jiegillet Jul 17, 2018
33a715e
removing stuff for conflict
jiegillet Jul 17, 2018
86e5d3b
Updated algorithms and added back substitution
jiegillet Jul 20, 2018
285c92f
merged with upstream
jiegillet Jul 20, 2018
05639f3
Added code in chapter
jiegillet Jul 20, 2018
b205393
removed code at wrong path
jiegillet Jul 20, 2018
3557019
Merge branch 'gaussianElimination' of github.com:jiegillet/algorithm-…
jiegillet Jul 26, 2018
2208ea3
Passed the code through hindent and added some comments
jiegillet Jul 26, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions contents/gaussian_elimination/code/haskell/gaussianElimination.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import Data.Array
import Data.Function (on)
import Data.List (intercalate, maximumBy)
import Data.Ratio

type Matrix a = Array (Int, Int) a

type Vector a = Array Int a

swapRows :: Int -> Int -> Matrix a -> Matrix a
swapRows r1 r2 m
| r1 == r2 = m
| otherwise =
m //
concat [[((r2, c), m ! (r1, c)), ((r1, c), m ! (r2, c))] | c <- [c1 .. cn]]
where
((_, c1), (_, cn)) = bounds m

subRows ::
Fractional a
=> (Int, Int) -- pivot location
-> (Int, Int) -- rows to cover
-> (Int, Int) -- columns to cover
-> Matrix a
-> Matrix a
subRows (r, c) (r1, rn) (c1, cn) m =
accum
(-)
m
[ ((i, j), m ! (i, c) * m ! (r, j) / m ! (r, c))
| i <- [r1 .. rn]
, j <- [c1 .. cn]
]

gaussianElimination :: (Fractional a, Ord a) => Matrix a -> Matrix a
gaussianElimination mat = go (r1, c1) mat
where
((r1, c1), (rn, cn)) = bounds mat
go (r, c) m
| c == cn = m
| pivot == 0 = go (r, c + 1) m
| otherwise = go (r + 1, c + 1) $ subRows (r, c) (r + 1, rn) (c, cn) m'
where
(target, pivot) =
maximumBy (compare `on` abs . snd) [(k, m ! (k, c)) | k <- [r .. rn]]
m' = swapRows r target m

gaussJordan :: (Fractional a, Eq a) => Matrix a -> Matrix a
gaussJordan mat = go (r1, c1) mat
where
((r1, c1), (rn, cn)) = bounds mat
go (r, c) m
| c == cn = m
| m ! (r, c) == 0 = go (r, c + 1) m
| otherwise = go (r + 1, c + 1) $ subRows (r, c) (r1, r - 1) (c, cn) m'
where
m' = accum (/) m [((r, j), m ! (r, c)) | j <- [c .. cn]]

backSubstitution :: (Fractional a) => Matrix a -> Vector a
backSubstitution m = sol
where
((r1, _), (rn, cn)) = bounds m
sol =
listArray (r1, rn) [(m ! (r, cn) - sum' r) / m ! (r, r) | r <- [r1 .. rn]]
sum' r = sum [m ! (r, k) * sol ! k | k <- [r + 1 .. rn]]

printM :: (Show a) => Matrix a -> String
printM m =
let ((r1, c1), (rn, cn)) = bounds m
in unlines
[ intercalate "\t" [show $ m ! (r, c) | c <- [c1 .. cn]]
| r <- [r1 .. rn]
]

printV :: (Show a) => Vector a -> String
printV = unlines . map show . elems

main :: IO ()
main = do
let mat = [2, 3, 4, 6, 1, 2, 3, 4, 3, -4, 0, 10] :: [Ratio Int]
m = listArray ((1, 1), (3, 4)) mat
putStrLn "Original Matrix:"
putStrLn $ printM m
putStrLn "Echelon form"
putStrLn $ printM $ gaussianElimination m
putStrLn "Reduced echelon form"
putStrLn $ printM $ gaussJordan $ gaussianElimination m
putStrLn "Solution from back substitution"
putStrLn $ printV $ backSubstitution $ gaussianElimination m
11 changes: 9 additions & 2 deletions contents/gaussian_elimination/gaussian_elimination.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ $$
\begin{array}{ccc|c}
1 & 0 & 0 & \frac{18}{11} \\
0 & 1 & 0 & \frac{-14}{11} \\
0 & 0 & 1 & \frac{18}{11}
0 & 0 & 1 & \frac{18}{11}
\end{array}
\right]
$$
Expand Down Expand Up @@ -358,6 +358,8 @@ In code, this looks like:
[import:13-44, lang:"c_cpp"](code/c/gaussian_elimination.c)
{% sample lang="rs" %}
[import:41-78, lang:"rust"](code/rust/gaussian_elimination.rs)
{% sample lang="hs" %}
[import:10-36, lang:"haskell"](code/haskell/gaussianElimination.hs)
{% endmethod %}

Now, to be clear: this algorithm creates an upper-triangular matrix.
Expand Down Expand Up @@ -390,6 +392,8 @@ This code does not exist yet in C, so here's Julia code (sorry for the inconveni
{% sample lang="rs" %}
This code does not exist yet in rust, so here's Julia code (sorry for the inconvenience)
[import:70-96, lang:"julia"](code/julia/gaussian_elimination.jl)
{% sample lang="hs" %}
[import:38-46, lang:"haskell"](code/haskell/gaussianElimination.hs)
{% endmethod %}

## Back-substitution
Expand Down Expand Up @@ -418,6 +422,8 @@ In code, this involves keeping a rolling sum of all the values we substitute in
[import:46-58, lang:"c_cpp"](code/c/gaussian_elimination.c)
{% sample lang="rs" %}
[import:79-94, lang:"rust"](code/rust/gaussian_elimination.rs)
{% sample lang="hs" %}
[import:48-53, lang:"haskell"](code/haskell/gaussianElimination.hs)
{% endmethod %}

## Conclusions
Expand All @@ -438,6 +444,8 @@ As for what's next... Well, we are in for a treat! The above algorithm clearly h
[import, lang:"c_cpp"](code/c/gaussian_elimination.c)
{% sample lang="rs" %}
[import, lang:"rust"](code/rust/gaussian_elimination.rs)
{% sample lang="hs" %}
[import, lang:"haskell"](code/haskell/gaussianElimination.hs)
{% endmethod %}


Expand All @@ -463,4 +471,3 @@ $$
\newcommand{\bfomega}{\boldsymbol{\omega}}
\newcommand{\bftau}{\boldsymbol{\tau}}
$$