{-# LANGUAGE TypeSynonymInstances, FlexibleInstances#-} module Geometry.Matrix ( -- * Functions getIndependent ) where import Numeric.LinearAlgebra.HMatrix import qualified Data.Matrix as M import Data.Function -- instance Element Rational -- getIndependent :: [[Rational]] -> [[Rational]] -> Int -> Int -> M.Matrix Rational-> [[Rational]] -- getIndependent initial accum currRank maxRank slackMat -- | currRank == maxRank = accum -- | accum == [] = getIndependent (tail initial) (return $ head initial) 1 maxRank slackMat -- | otherwise = if newRank > currRank -- then getIndependent (tail initial) (candidate:accum) (currRank+1) maxRank slackMat -- else getIndependent (tail initial) accum currRank maxRank slackMat -- where -- slack = map (map fromRational) $ M.toLists slackMat -- candidate = head initial -- setVectors = map (1:) $ candidate:accum -- matrix = fromLists $ zipRev ((map (map fromRational)) setVectors :: [[Double]]) (slack) -- newRank = rank matrix -- | Get independet rows/columns of a non square matrix getIndependent :: [[Rational]] -> [[Rational]] -> Int -> Int -> M.Matrix Rational-> [[Rational]] getIndependent initial accum currRank maxRank slackMat | currRank == maxRank = accum | accum == [] = getIndependent (tail initial) (return $ head initial) 1 maxRank slackMat | otherwise = if newRank > currRank then getIndependent (tail initial) (candidate:accum) (currRank+1) maxRank slackMat else getIndependent (tail initial ++ [candidate]) accum currRank maxRank slackMat where slack = map (map fromRational) $ M.toLists slackMat candidate = head initial setVectors = map (1:) $ candidate:accum matrix = fromLists $ zipRev ((map (map fromRational)) setVectors :: [[Double]]) (slack) newRank = rank matrix zipRev :: [[Double]] -> [[Double]] -> [[Double]] zipRev a = (reverse . ((zipWith (++)) `on` reverse) a)