Skip to content

Instantly share code, notes, and snippets.

@siliconbrain
Last active August 29, 2015 13:56
Show Gist options
  • Save siliconbrain/8986507 to your computer and use it in GitHub Desktop.
Save siliconbrain/8986507 to your computer and use it in GitHub Desktop.
Fourier–Motzkin elimination algorithm in different languages
;; Fourier-Motzkin eliminator
(defn fme [rows]
(letfn [(shorten [[x & xs]]
(let [lambda (if (== 0.0 x) 1.0 (-> x double Math/abs))]
(map #(/ %1 lambda) xs)))
(classify-rows [rows]
(group-by (fn [row] (-> row first double Math/signum {-1.0 :lts, 0.0 :eqs, 1.0 :gts}))
rows))]
(-> rows
classify-rows
(fn [m] (into {} (for [[k v] m] [k (shorten v)])))
(fn [{:keys [lts eqs gts]]
(into eqs (for [lt-row lts, gt-row gts]
(map + lt-row gt-row)))))))
-- Fourier-Motzkin eliminator
fme rows = case map3 (scale'n'drop, (drop 1), scale'n'drop) (groupRows rows) of
(is, ns, js) -> ns ++ [vecAdd i j | i <- is, j <- js]
where
map3 (f1, f2, f3) (l1, l2, l3) = (map f1 l1, map f2 l2, map f3 l3)
scale'n'drop (x:xs) = map (/ (abs x)) xs
groupRows = foldr route ([], [], [])
where route row acc@(lt, eq, gt) =
case row of
[] -> acc
x:_ -> if x < 0 then (row:lt, eq, gt)
else if x > 0 then ( lt, eq, row:gt)
else ( lt, row:eq, gt)
vecAdd = zipWith (+)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment