Skip to content

Instantly share code, notes, and snippets.

@ebresafegaga
Created November 11, 2020 20:10
Show Gist options
  • Save ebresafegaga/a8c4aeacc0f93c9853c8792f457f5056 to your computer and use it in GitHub Desktop.
Save ebresafegaga/a8c4aeacc0f93c9853c8792f457f5056 to your computer and use it in GitHub Desktop.
Determinant of a matrix by pivotal condensation in F#
let rc l =
List.length l, List.length << List.head $ l
let ij i j l =
let cols, rows = rc l
if i >= rows || j >= cols then failwith "Out of bounds error"
else List.nth (List.nth l i) j
let mapRow i f l =
let m = List.nth l i
let newRow = m |> List.map f
l |> List.mapi (fun a x -> if a = i then newRow else x)
let mapAll f l = l |> List.map (List.map f)
let mapAlli f l =
l |> List.mapi (fun i x -> x |> List.mapi (fun j x -> f x (i, j)))
let rec foldi f init l =
let rec go acc ll count =
match ll with
| [] -> acc
| x :: xs -> go (f count acc x) xs $ add1 count
go init l 0
let remr i l =
l
|> foldi (fun index s x -> if index = i then s else s @ [x]) []
let remc i l =
// Add check for i against l
let rem ii ll =
let rec go acc c ml =
match ml with
| [] -> acc
| x :: xs ->
if ii = c then go acc (add1 c) xs
else go (acc @ [x]) (add1 c) xs
go [] 0 ll
l |> List.map (rem i)
let remij i j l = remc j << remr i $ l
let printM l =
l |> List.iter (fun x -> printf "["
x |> List.iter (fun x -> printf "%3f, " x)
printf "]\n")
// Pivotal Condensation
// Elements of ML programming Ex 5.2.4
let rec det matrix =
if rc matrix = (1, 1) then ij 0 0 matrix
else
let a = matrix |> ij 0 0
(* Insert check to make sure a is not zero here *)
let m = matrix |> mapRow 0 (fun x -> x / a)
let m' = m |> remij 0 0
// Note that we're adding one because each cell in the new matrix
// have shifted left and up.
a * det (m' |> mapAlli (fun x (i, j) -> x - (ij 0 (add1 j) m * ij (add1 i) 0 m)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment