{-# LANGUAGE ConstraintKinds, FlexibleContexts, FlexibleInstances, GADTs   #-}
{-# LANGUAGE KindSignatures, MultiParamTypeClasses                         #-}
{-# LANGUAGE NoMonomorphismRestriction, TypeFamilies, TypeSynonymInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Algebra.Matrix (Matrix(..), delta, companion,
                       gaussReduction, maxNorm, rankWith, det,
                       inverse, inverseWith) where
import           Algebra.Internal
import qualified Algebra.LinkedMatrix as LM
import           Algebra.Prelude.Core hiding (maxNorm, zero)

import           Control.Lens                (both, view, (%~), (&), _3)
import           Control.Monad               (when)
import qualified Data.Matrix                 as DM
import qualified Data.Vector                 as V
import           GHC.Exts                    (Constraint)
import           Numeric.Algebra             (Additive, DecidableZero)
import           Numeric.Algebra             (Monoidal, Multiplicative)
import           Numeric.Algebra             (Unital)
import qualified Numeric.Algebra             as NA
import qualified Numeric.Decidable.Zero      as NA
import qualified Numeric.LinearAlgebra       as LA
import qualified Numeric.LinearAlgebra.Devel as LA
import qualified Prelude                     as P

{-# ANN module "HLint: ignore Redundant bang pattern" #-}

class Matrix mat where
  type Elem mat a :: Constraint
  cmap  :: (Elem mat a, Elem mat b) => (a -> b) -> mat a -> mat b
  empty :: Elem mat b => mat b
  fromLists :: Elem mat a => [[a]] -> mat a
  fromCols  :: Elem mat a => [V.Vector a] -> mat a
  fromCols [] = Int -> Int -> mat a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
Int -> Int -> mat a
zero Int
0 Int
0
  fromCols [Vector a]
xs = (mat a -> mat a -> mat a) -> [mat a] -> mat a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 mat a -> mat a -> mat a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
mat a -> mat a -> mat a
(<||>) ([mat a] -> mat a) -> [mat a] -> mat a
forall a b. (a -> b) -> a -> b
$ (Vector a -> mat a) -> [Vector a] -> [mat a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map Vector a -> mat a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
Vector a -> mat a
colVector [Vector a]
xs
  fromRows :: Elem mat a => [V.Vector a] -> mat a
  fromRows [] = Int -> Int -> mat a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
Int -> Int -> mat a
zero Int
0 Int
0
  fromRows [Vector a]
xs = (mat a -> mat a -> mat a) -> [mat a] -> mat a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 mat a -> mat a -> mat a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
mat a -> mat a -> mat a
(<-->) ([mat a] -> mat a) -> [mat a] -> mat a
forall a b. (a -> b) -> a -> b
$ (Vector a -> mat a) -> [Vector a] -> [mat a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map Vector a -> mat a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
Vector a -> mat a
rowVector [Vector a]
xs
  toCols :: Elem mat a => mat a -> [V.Vector a]
  toCols mat a
m = (Int -> Vector a) -> [Int] -> [Vector a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (Int -> mat a -> Vector a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
Int -> mat a -> Vector a
`getCol` mat a
m) [Int
1..mat a -> Int
forall (mat :: * -> *) a. Matrix mat => mat a -> Int
ncols mat a
m]
  toRows :: Elem mat a => mat a -> [V.Vector a]
  toRows mat a
m = (Int -> Vector a) -> [Int] -> [Vector a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (Int -> mat a -> Vector a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
Int -> mat a -> Vector a
`getRow` mat a
m) [Int
1..mat a -> Int
forall (mat :: * -> *) a. Matrix mat => mat a -> Int
nrows mat a
m]
  ncols :: mat a -> Int
  nrows :: mat a -> Int
  identity :: Elem mat a => Int -> mat a
  diag     :: Elem mat a => V.Vector a -> mat a
  getDiag :: Elem mat a => mat a -> V.Vector a
  trace :: Elem mat a => mat a -> a
  diagProd :: Elem mat a => mat a -> a
  zero :: Elem mat a => Int -> Int -> mat a
  colVector :: Elem mat a => V.Vector a -> mat a
  rowVector :: Elem mat a => V.Vector a -> mat a
  getCol :: Elem mat a => Int -> mat a -> V.Vector a
  getRow :: Elem mat a => Int -> mat a -> V.Vector a
  switchRows :: Elem mat a => Int -> Int -> mat a -> mat a
  scaleRow :: Elem mat a => a -> Int -> mat a -> mat a
  combineRows :: Elem mat a => Int -> a -> Int -> mat a -> mat a
  trans :: Elem mat a => mat a -> mat a
  buildMatrix :: Elem mat a => Int -> Int -> ((Int, Int) -> a) -> mat a
  index :: Elem mat a => Int -> Int -> mat a -> Maybe a
  index Int
i Int
j mat a
m = if Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
i Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= mat a -> Int
forall (mat :: * -> *) a. Matrix mat => mat a -> Int
nrows mat a
m Bool -> Bool -> Bool
&& Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
j Bool -> Bool -> Bool
&& Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= mat a -> Int
forall (mat :: * -> *) a. Matrix mat => mat a -> Int
ncols mat a
m
                then a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> a -> Maybe a
forall a b. (a -> b) -> a -> b
$ mat a
m mat a -> (Int, Int) -> a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
mat a -> (Int, Int) -> a
! (Int
i, Int
j)
                else Maybe a
forall a. Maybe a
Nothing
  (!) :: Elem mat a => mat a -> (Int, Int) -> a
  (<||>) :: Elem mat a => mat a -> mat a -> mat a
  (<-->) :: Elem mat a => mat a -> mat a -> mat a
  nonZeroRows :: (DecidableZero a, Elem mat a) => mat a -> [Int]
  nonZeroRows = ((Int, Vector a) -> Int) -> [(Int, Vector a)] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (Int, Vector a) -> Int
forall a b. (a, b) -> a
fst ([(Int, Vector a)] -> [Int])
-> (mat a -> [(Int, Vector a)]) -> mat a -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Vector a) -> Bool) -> [(Int, Vector a)] -> [(Int, Vector a)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((a -> Bool) -> Vector a -> Bool
forall a. (a -> Bool) -> Vector a -> Bool
V.any (Bool -> Bool
not (Bool -> Bool) -> (a -> Bool) -> a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bool
forall r. DecidableZero r => r -> Bool
NA.isZero) (Vector a -> Bool)
-> ((Int, Vector a) -> Vector a) -> (Int, Vector a) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Vector a) -> Vector a
forall a b. (a, b) -> b
snd) ([(Int, Vector a)] -> [(Int, Vector a)])
-> (mat a -> [(Int, Vector a)]) -> mat a -> [(Int, Vector a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> [Vector a] -> [(Int, Vector a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
1..] ([Vector a] -> [(Int, Vector a)])
-> (mat a -> [Vector a]) -> mat a -> [(Int, Vector a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. mat a -> [Vector a]
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
mat a -> [Vector a]
toRows
  nonZeroCols :: (DecidableZero a, Elem mat a) => mat a -> [Int]
  nonZeroCols = ((Int, Vector a) -> Int) -> [(Int, Vector a)] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (Int, Vector a) -> Int
forall a b. (a, b) -> a
fst ([(Int, Vector a)] -> [Int])
-> (mat a -> [(Int, Vector a)]) -> mat a -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Vector a) -> Bool) -> [(Int, Vector a)] -> [(Int, Vector a)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((a -> Bool) -> Vector a -> Bool
forall a. (a -> Bool) -> Vector a -> Bool
V.any (Bool -> Bool
not (Bool -> Bool) -> (a -> Bool) -> a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bool
forall r. DecidableZero r => r -> Bool
NA.isZero) (Vector a -> Bool)
-> ((Int, Vector a) -> Vector a) -> (Int, Vector a) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Vector a) -> Vector a
forall a b. (a, b) -> b
snd) ([(Int, Vector a)] -> [(Int, Vector a)])
-> (mat a -> [(Int, Vector a)]) -> mat a -> [(Int, Vector a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> [Vector a] -> [(Int, Vector a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
1..] ([Vector a] -> [(Int, Vector a)])
-> (mat a -> [Vector a]) -> mat a -> [(Int, Vector a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. mat a -> [Vector a]
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
mat a -> [Vector a]
toCols

instance Matrix DM.Matrix where
  type Elem DM.Matrix a = P.Num a
  empty :: Matrix b
empty = Int -> Int -> Matrix b
forall a. Num a => Int -> Int -> Matrix a
DM.zero Int
0 Int
0
  cmap :: (a -> b) -> Matrix a -> Matrix b
cmap  = (a -> b) -> Matrix a -> Matrix b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
  fromLists :: [[a]] -> Matrix a
fromLists = [[a]] -> Matrix a
forall a. [[a]] -> Matrix a
DM.fromLists
  ncols :: Matrix a -> Int
ncols = Matrix a -> Int
forall a. Matrix a -> Int
DM.ncols
  nrows :: Matrix a -> Int
nrows = Matrix a -> Int
forall a. Matrix a -> Int
DM.nrows
  trans :: Matrix a -> Matrix a
trans = Matrix a -> Matrix a
forall a. Matrix a -> Matrix a
DM.transpose
  identity :: Int -> Matrix a
identity = Int -> Matrix a
forall a. Num a => Int -> Matrix a
DM.identity
  diag :: Vector a -> Matrix a
diag Vector a
v = Int -> Int -> ((Int, Int) -> a) -> Matrix a
forall a. Int -> Int -> ((Int, Int) -> a) -> Matrix a
DM.matrix (Vector a -> Int
forall a. Vector a -> Int
V.length Vector a
v) (Vector a -> Int
forall a. Vector a -> Int
V.length Vector a
v) (((Int, Int) -> a) -> Matrix a) -> ((Int, Int) -> a) -> Matrix a
forall a b. (a -> b) -> a -> b
$ \(Int
i, Int
j) ->
    if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
j then Vector a
v Vector a -> Int -> a
forall a. Vector a -> Int -> a
V.! (Int
iInt -> Int -> Int
forall r. Group r => r -> r -> r
-Int
1) else a
0
  getDiag :: Matrix a -> Vector a
getDiag = Matrix a -> Vector a
forall a. Matrix a -> Vector a
DM.getDiag
  trace :: Matrix a -> a
trace = Matrix a -> a
forall a. Num a => Matrix a -> a
DM.trace
  diagProd :: Matrix a -> a
diagProd = Matrix a -> a
forall a. Num a => Matrix a -> a
DM.diagProd
  zero :: Int -> Int -> Matrix a
zero = Int -> Int -> Matrix a
forall a. Num a => Int -> Int -> Matrix a
DM.zero
  colVector :: Vector a -> Matrix a
colVector = Vector a -> Matrix a
forall a. Vector a -> Matrix a
DM.colVector
  rowVector :: Vector a -> Matrix a
rowVector = Vector a -> Matrix a
forall a. Vector a -> Matrix a
DM.rowVector
  getCol :: Int -> Matrix a -> Vector a
getCol = Int -> Matrix a -> Vector a
forall a. Int -> Matrix a -> Vector a
DM.getCol
  getRow :: Int -> Matrix a -> Vector a
getRow = Int -> Matrix a -> Vector a
forall a. Int -> Matrix a -> Vector a
DM.getRow
  switchRows :: Int -> Int -> Matrix a -> Matrix a
switchRows = Int -> Int -> Matrix a -> Matrix a
forall a. Int -> Int -> Matrix a -> Matrix a
DM.switchRows
  combineRows :: Int -> a -> Int -> Matrix a -> Matrix a
combineRows = Int -> a -> Int -> Matrix a -> Matrix a
forall a. Num a => Int -> a -> Int -> Matrix a -> Matrix a
DM.combineRows
  scaleRow :: a -> Int -> Matrix a -> Matrix a
scaleRow = a -> Int -> Matrix a -> Matrix a
forall a. Num a => a -> Int -> Matrix a -> Matrix a
DM.scaleRow
  buildMatrix :: Int -> Int -> ((Int, Int) -> a) -> Matrix a
buildMatrix = Int -> Int -> ((Int, Int) -> a) -> Matrix a
forall a. Int -> Int -> ((Int, Int) -> a) -> Matrix a
DM.matrix
  (!) = Matrix a -> (Int, Int) -> a
forall a. Matrix a -> (Int, Int) -> a
(DM.!)
  <||> :: Matrix a -> Matrix a -> Matrix a
(<||>) = Matrix a -> Matrix a -> Matrix a
forall a. Matrix a -> Matrix a -> Matrix a
(DM.<|>)
  <--> :: Matrix a -> Matrix a -> Matrix a
(<-->) = Matrix a -> Matrix a -> Matrix a
forall a. Matrix a -> Matrix a -> Matrix a
(DM.<->)

swapIJ :: Eq a => a -> a -> a -> a
swapIJ :: a -> a -> a -> a
swapIJ a
i a
j a
k
  | a
k a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
i = a
j
  | a
k a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
j = a
i
  | Bool
otherwise = a
k

instance Matrix LA.Matrix where
  type Elem LA.Matrix a = (P.Num a, LA.Numeric  a, LA.Element a, LA.Container LA.Vector a)
  empty :: Matrix b
empty = [[b]] -> Matrix b
forall t. Element t => [[t]] -> Matrix t
LA.fromLists [[]]
  fromLists :: [[a]] -> Matrix a
fromLists = [[a]] -> Matrix a
forall t. Element t => [[t]] -> Matrix t
LA.fromLists
  cmap :: (a -> b) -> Matrix a -> Matrix b
cmap = (a -> b) -> Matrix a -> Matrix b
forall b (c :: * -> *) e.
(Element b, Container c e) =>
(e -> b) -> c e -> c b
LA.cmap
  ncols :: Matrix a -> Int
ncols = Matrix a -> Int
forall a. Matrix a -> Int
LA.cols
  nrows :: Matrix a -> Int
nrows = Matrix a -> Int
forall a. Matrix a -> Int
LA.rows
  trans :: Matrix a -> Matrix a
trans = Matrix a -> Matrix a
forall m mt. Transposable m mt => m -> mt
LA.tr
  identity :: Int -> Matrix a
identity = Int -> Matrix a
forall a. (Num a, Element a) => Int -> Matrix a
LA.ident
  fromCols :: [Vector a] -> Matrix a
fromCols = [Vector a] -> Matrix a
forall t. Element t => [Vector t] -> Matrix t
LA.fromColumns ([Vector a] -> Matrix a)
-> ([Vector a] -> [Vector a]) -> [Vector a] -> Matrix a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Vector a -> Vector a) -> [Vector a] -> [Vector a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ([a] -> Vector a
forall a. Storable a => [a] -> Vector a
LA.fromList ([a] -> Vector a) -> (Vector a -> [a]) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> [a]
forall a. Vector a -> [a]
V.toList)
  diag :: Vector a -> Matrix a
diag = Vector a -> Matrix a
forall a. (Num a, Element a) => Vector a -> Matrix a
LA.diag (Vector a -> Matrix a)
-> (Vector a -> Vector a) -> Vector a -> Matrix a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Vector a
forall a. Storable a => [a] -> Vector a
LA.fromList ([a] -> Vector a) -> (Vector a -> [a]) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> [a]
forall a. Vector a -> [a]
V.toList
  getDiag :: Matrix a -> Vector a
getDiag = [a] -> Vector a
forall a. [a] -> Vector a
V.fromList ([a] -> Vector a) -> (Matrix a -> [a]) -> Matrix a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> [a]
forall a. Storable a => Vector a -> [a]
LA.toList (Vector a -> [a]) -> (Matrix a -> Vector a) -> Matrix a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix a -> Vector a
forall t. Element t => Matrix t -> Vector t
LA.takeDiag
  trace :: Matrix a -> a
trace = Vector a -> a
forall (c :: * -> *) e. Container c e => c e -> e
LA.sumElements (Vector a -> a) -> (Matrix a -> Vector a) -> Matrix a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix a -> Vector a
forall t. Element t => Matrix t -> Vector t
LA.takeDiag
  diagProd :: Matrix a -> a
diagProd = Vector a -> a
forall (c :: * -> *) e. Container c e => c e -> e
LA.prodElements (Vector a -> a) -> (Matrix a -> Vector a) -> Matrix a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix a -> Vector a
forall t. Element t => Matrix t -> Vector t
LA.takeDiag
  zero :: Int -> Int -> Matrix a
zero Int
i Int
j = a -> (Int, Int) -> Matrix a
forall e d (c :: * -> *). Konst e d c => e -> d -> c e
LA.konst a
0 (Int
i, Int
j)
  colVector :: Vector a -> Matrix a
colVector = Vector a -> Matrix a
forall a. Storable a => Vector a -> Matrix a
LA.asColumn (Vector a -> Matrix a)
-> (Vector a -> Vector a) -> Vector a -> Matrix a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Vector a
forall a. Storable a => [a] -> Vector a
LA.fromList ([a] -> Vector a) -> (Vector a -> [a]) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> [a]
forall a. Vector a -> [a]
V.toList
  rowVector :: Vector a -> Matrix a
rowVector = Vector a -> Matrix a
forall a. Storable a => Vector a -> Matrix a
LA.asRow (Vector a -> Matrix a)
-> (Vector a -> Vector a) -> Vector a -> Matrix a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Vector a
forall a. Storable a => [a] -> Vector a
LA.fromList ([a] -> Vector a) -> (Vector a -> [a]) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> [a]
forall a. Vector a -> [a]
V.toList
  toCols :: Matrix a -> [Vector a]
toCols = (Vector a -> Vector a) -> [Vector a] -> [Vector a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ([a] -> Vector a
forall a. [a] -> Vector a
V.fromList ([a] -> Vector a) -> (Vector a -> [a]) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> [a]
forall a. Storable a => Vector a -> [a]
LA.toList) ([Vector a] -> [Vector a])
-> (Matrix a -> [Vector a]) -> Matrix a -> [Vector a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix a -> [Vector a]
forall t. Element t => Matrix t -> [Vector t]
LA.toColumns
  toRows :: Matrix a -> [Vector a]
toRows = (Vector a -> Vector a) -> [Vector a] -> [Vector a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ([a] -> Vector a
forall a. [a] -> Vector a
V.fromList ([a] -> Vector a) -> (Vector a -> [a]) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> [a]
forall a. Storable a => Vector a -> [a]
LA.toList) ([Vector a] -> [Vector a])
-> (Matrix a -> [Vector a]) -> Matrix a -> [Vector a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix a -> [Vector a]
forall t. Element t => Matrix t -> [Vector t]
LA.toRows
  getCol :: Int -> Matrix a -> Vector a
getCol Int
i = [a] -> Vector a
forall a. [a] -> Vector a
V.fromList ([a] -> Vector a) -> (Matrix a -> [a]) -> Matrix a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> [a]
forall a. Storable a => Vector a -> [a]
LA.toList (Vector a -> [a]) -> (Matrix a -> Vector a) -> Matrix a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Vector a] -> Int -> Vector a
forall a. [a] -> Int -> a
!! (Int
i Int -> Int -> Int
forall r. Group r => r -> r -> r
- Int
1)) ([Vector a] -> Vector a)
-> (Matrix a -> [Vector a]) -> Matrix a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix a -> [Vector a]
forall t. Element t => Matrix t -> [Vector t]
LA.toColumns
  getRow :: Int -> Matrix a -> Vector a
getRow Int
i = [a] -> Vector a
forall a. [a] -> Vector a
V.fromList ([a] -> Vector a) -> (Matrix a -> [a]) -> Matrix a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> [a]
forall a. Storable a => Vector a -> [a]
LA.toList (Vector a -> [a]) -> (Matrix a -> Vector a) -> Matrix a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Vector a] -> Int -> Vector a
forall a. [a] -> Int -> a
!! (Int
i Int -> Int -> Int
forall r. Group r => r -> r -> r
- Int
1)) ([Vector a] -> Vector a)
-> (Matrix a -> [Vector a]) -> Matrix a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix a -> [Vector a]
forall t. Element t => Matrix t -> [Vector t]
LA.toRows
  switchRows :: Int -> Int -> Matrix a -> Matrix a
switchRows Int
i Int
j Matrix a
m = Matrix a
m Matrix a -> [Int] -> Matrix a
forall t. Element t => Matrix t -> [Int] -> Matrix t
LA.? (Int -> Int) -> [Int] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (Int -> Int -> Int -> Int
forall a. Eq a => a -> a -> a -> a
swapIJ (Int
iInt -> Int -> Int
forall r. Group r => r -> r -> r
-Int
1) (Int
jInt -> Int -> Int
forall r. Group r => r -> r -> r
-Int
1)) [Int
0.. Matrix a -> Int
forall (mat :: * -> *) a. Matrix mat => mat a -> Int
nrows Matrix a
m Int -> Int -> Int
forall r. Group r => r -> r -> r
- Int
1]
  combineRows :: Int -> a -> Int -> Matrix a -> Matrix a
combineRows Int
j a
s Int
i Matrix a
m = ((Int, Int) -> a -> a) -> Matrix a -> Matrix a
forall a b.
(Element a, Storable b) =>
((Int, Int) -> a -> b) -> Matrix a -> Matrix b
LA.mapMatrixWithIndex (\(Int
k,Int
l) a
v -> if Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
j Int -> Int -> Int
forall r. Group r => r -> r -> r
- Int
1 then a
s a -> a -> a
forall a. Num a => a -> a -> a
P.* (Matrix a
m Matrix a -> (Int, Int) -> a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
mat a -> (Int, Int) -> a
! (Int
i,Int
lInt -> Int -> Int
forall r. Additive r => r -> r -> r
+Int
1)) a -> a -> a
forall a. Num a => a -> a -> a
P.+ a
v else a
v) Matrix a
m
  buildMatrix :: Int -> Int -> ((Int, Int) -> a) -> Matrix a
buildMatrix Int
w Int
h (Int, Int) -> a
f = (Int, Int) -> (a -> a -> a) -> Matrix a
forall d f (c :: * -> *) e. Build d f c e => d -> f -> c e
LA.build (Int
w, Int
h) (\a
i a
j -> (Int, Int) -> a
f (a -> Int
forall e. Container Matrix e => e -> Int
toIntLA a
iInt -> Int -> Int
forall r. Additive r => r -> r -> r
+Int
1, a -> Int
forall e. Container Matrix e => e -> Int
toIntLA a
jInt -> Int -> Int
forall r. Additive r => r -> r -> r
+Int
1))
  scaleRow :: a -> Int -> Matrix a -> Matrix a
scaleRow a
a Int
i = ((Matrix a, ()) -> Matrix a
forall a b. (a, b) -> a
fst ((Matrix a, ()) -> Matrix a)
-> (Matrix a -> (Matrix a, ())) -> Matrix a -> Matrix a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Matrix a -> (Matrix a, ())) -> Matrix a -> Matrix a)
-> (Matrix a -> (Matrix a, ())) -> Matrix a -> Matrix a
forall a b. (a -> b) -> a -> b
$ (forall s. (Int, Int) -> STMatrix s a -> ST s ())
-> Matrix a -> (Matrix a, ())
forall t u.
Element t =>
(forall s. (Int, Int) -> STMatrix s t -> ST s u)
-> Matrix t -> (Matrix t, u)
LA.mutable ((forall s. (Int, Int) -> STMatrix s a -> ST s ())
 -> Matrix a -> (Matrix a, ()))
-> (forall s. (Int, Int) -> STMatrix s a -> ST s ())
-> Matrix a
-> (Matrix a, ())
forall a b. (a -> b) -> a -> b
$ \(Int
k, Int
l) STMatrix s a
m -> do
    a
v <- STMatrix s a -> Int -> Int -> ST s a
forall t s. Storable t => STMatrix s t -> Int -> Int -> ST s t
LA.readMatrix STMatrix s a
m Int
k Int
l
    Bool -> ST s () -> ST s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
i Int -> Int -> Int
forall r. Group r => r -> r -> r
- Int
1) (ST s () -> ST s ()) -> ST s () -> ST s ()
forall a b. (a -> b) -> a -> b
$
      STMatrix s a -> Int -> Int -> a -> ST s ()
forall t s.
Storable t =>
STMatrix s t -> Int -> Int -> t -> ST s ()
LA.writeMatrix STMatrix s a
m Int
k Int
l (a
a a -> a -> a
forall a. Num a => a -> a -> a
P.* a
v)
  Matrix a
m ! :: Matrix a -> (Int, Int) -> a
! (Int
i, Int
j) = Matrix a
m Matrix a -> IndexOf Matrix -> a
forall (c :: * -> *) e. Container c e => c e -> IndexOf c -> e
`LA.atIndex` (Int
i Int -> Int -> Int
forall r. Group r => r -> r -> r
- Int
1, Int
j Int -> Int -> Int
forall r. Group r => r -> r -> r
- Int
1)
  Matrix a
m <||> :: Matrix a -> Matrix a -> Matrix a
<||> Matrix a
n = [Vector a] -> Matrix a
forall t. Element t => [Vector t] -> Matrix t
LA.fromColumns ([Vector a] -> Matrix a) -> [Vector a] -> Matrix a
forall a b. (a -> b) -> a -> b
$ Matrix a -> [Vector a]
forall t. Element t => Matrix t -> [Vector t]
LA.toColumns Matrix a
m [Vector a] -> [Vector a] -> [Vector a]
forall w. Monoid w => w -> w -> w
++ Matrix a -> [Vector a]
forall t. Element t => Matrix t -> [Vector t]
LA.toColumns Matrix a
n
  Matrix a
m <--> :: Matrix a -> Matrix a -> Matrix a
<--> Matrix a
n = [Vector a] -> Matrix a
forall t. Element t => [Vector t] -> Matrix t
LA.fromRows ([Vector a] -> Matrix a) -> [Vector a] -> Matrix a
forall a b. (a -> b) -> a -> b
$ Matrix a -> [Vector a]
forall t. Element t => Matrix t -> [Vector t]
LA.toRows Matrix a
m [Vector a] -> [Vector a] -> [Vector a]
forall w. Monoid w => w -> w -> w
++ Matrix a -> [Vector a]
forall t. Element t => Matrix t -> [Vector t]
LA.toRows Matrix a
n

toIntLA :: LA.Container LA.Matrix e => e -> Int
toIntLA :: e -> Int
toIntLA e
e = Z -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Z -> Int) -> Z -> Int
forall a b. (a -> b) -> a -> b
$ Matrix e -> Matrix Z
forall (c :: * -> *) e. Container c e => c e -> c Z
LA.toZ ((Int
1 Int -> Int -> [e] -> Matrix e
forall a. Storable a => Int -> Int -> [a] -> Matrix a
LA.>< Int
1) [e
e]) Matrix Z -> IndexOf Matrix -> Z
forall (c :: * -> *) e. Container c e => c e -> IndexOf c -> e
`LA.atIndex` (Int
0, Int
0)

instance Matrix LM.Matrix where
  type Elem LM.Matrix a = (CoeffRing a, Unital a, Monoidal a, Multiplicative a, Additive a)
  cmap :: (a -> b) -> Matrix a -> Matrix b
cmap = (a -> b) -> Matrix a -> Matrix b
forall a a1. DecidableZero a => (a1 -> a) -> Matrix a1 -> Matrix a
LM.cmap
  (!) Matrix a
m (Int, Int)
pos = Matrix a
m Matrix a -> (Int, Int) -> a
forall a. Monoidal a => Matrix a -> (Int, Int) -> a
LM.! ((Int, Int)
pos (Int, Int) -> ((Int, Int) -> (Int, Int)) -> (Int, Int)
forall a b. a -> (a -> b) -> b
& (Int -> Identity Int) -> (Int, Int) -> Identity (Int, Int)
forall (r :: * -> * -> *) a b.
Bitraversable r =>
Traversal (r a a) (r b b) a b
both ((Int -> Identity Int) -> (Int, Int) -> Identity (Int, Int))
-> (Int -> Int) -> (Int, Int) -> (Int, Int)
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Int -> Int
forall a. Enum a => a -> a
pred)
  index :: Int -> Int -> Matrix a -> Maybe a
index Int
i Int
j = Int -> Int -> Matrix a -> Maybe a
forall a. Monoidal a => Int -> Int -> Matrix a -> Maybe a
LM.index (Int
iInt -> Int -> Int
forall r. Group r => r -> r -> r
-Int
1) (Int
jInt -> Int -> Int
forall r. Group r => r -> r -> r
-Int
1)
  empty :: Matrix b
empty = Matrix b
forall a. Matrix a
LM.empty
  buildMatrix :: Int -> Int -> ((Int, Int) -> a) -> Matrix a
buildMatrix Int
h Int
w (Int, Int) -> a
f = [((Int, Int), a)] -> Matrix a
forall a. DecidableZero a => [((Int, Int), a)] -> Matrix a
LM.fromList [((Int
i, Int
j), (Int, Int) -> a
f (Int
i,Int
j)) | Int
j <- [Int
1..Int
w], Int
i <- [Int
1..Int
h]]
  trans :: Matrix a -> Matrix a
trans = Matrix a -> Matrix a
forall a. Matrix a -> Matrix a
LM.transpose
  combineRows :: Int -> a -> Int -> Matrix a -> Matrix a
combineRows Int
j a
s Int
i = a -> Int -> Int -> Matrix a -> Matrix a
forall a.
(DecidableZero a, Multiplicative a) =>
a -> Int -> Int -> Matrix a -> Matrix a
LM.combineRows a
s (Int
iInt -> Int -> Int
forall r. Group r => r -> r -> r
-Int
1) (Int
jInt -> Int -> Int
forall r. Group r => r -> r -> r
-Int
1)
  switchRows :: Int -> Int -> Matrix a -> Matrix a
switchRows Int
i Int
j = Int -> Int -> Matrix a -> Matrix a
forall a. Int -> Int -> Matrix a -> Matrix a
LM.switchRows (Int
iInt -> Int -> Int
forall r. Group r => r -> r -> r
-Int
1) (Int
jInt -> Int -> Int
forall r. Group r => r -> r -> r
-Int
1)
  scaleRow :: a -> Int -> Matrix a -> Matrix a
scaleRow a
a Int
i = a -> Int -> Matrix a -> Matrix a
forall a.
(DecidableZero a, Multiplicative a) =>
a -> Int -> Matrix a -> Matrix a
LM.scaleRow a
a (Int -> Int
forall a. Enum a => a -> a
pred Int
i)
  zero :: Int -> Int -> Matrix a
zero = Int -> Int -> Matrix a
forall a. Int -> Int -> Matrix a
LM.zeroMat
  identity :: Int -> Matrix a
identity = Int -> Matrix a
forall a. Unital a => Int -> Matrix a
LM.identity
  diag :: Vector a -> Matrix a
diag = Vector a -> Matrix a
forall a. DecidableZero a => Vector a -> Matrix a
LM.diag
  getDiag :: Matrix a -> Vector a
getDiag = Matrix a -> Vector a
forall a. Monoidal a => Matrix a -> Vector a
LM.getDiag
  diagProd :: Matrix a -> a
diagProd = Matrix a -> a
forall c. (Unital c, Monoidal c) => Matrix c -> c
LM.diagProd
  trace :: Matrix a -> a
trace = Matrix a -> a
forall c. Monoidal c => Matrix c -> c
LM.trace
  getRow :: Int -> Matrix a -> Vector a
getRow = Int -> Matrix a -> Vector a
forall a. Monoidal a => Int -> Matrix a -> Vector a
LM.getRow (Int -> Matrix a -> Vector a)
-> (Int -> Int) -> Int -> Matrix a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int
forall a. Enum a => a -> a
pred
  getCol :: Int -> Matrix a -> Vector a
getCol = Int -> Matrix a -> Vector a
forall a. Monoidal a => Int -> Matrix a -> Vector a
LM.getCol (Int -> Matrix a -> Vector a)
-> (Int -> Int) -> Int -> Matrix a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int
forall a. Enum a => a -> a
pred
  nrows :: Matrix a -> Int
nrows = Matrix a -> Int
forall a. Matrix a -> Int
LM.nrows
  ncols :: Matrix a -> Int
ncols = Matrix a -> Int
forall a. Matrix a -> Int
LM.ncols
  fromLists :: [[a]] -> Matrix a
fromLists = [[a]] -> Matrix a
forall a. DecidableZero a => [[a]] -> Matrix a
LM.fromLists
  <||> :: Matrix a -> Matrix a -> Matrix a
(<||>) = Matrix a -> Matrix a -> Matrix a
forall b. DecidableZero b => Matrix b -> Matrix b -> Matrix b
(LM.<||>)
  <--> :: Matrix a -> Matrix a -> Matrix a
(<-->) = Matrix a -> Matrix a -> Matrix a
forall b. DecidableZero b => Matrix b -> Matrix b -> Matrix b
(LM.<-->)
  rowVector :: Vector a -> Matrix a
rowVector = Vector a -> Matrix a
forall a. DecidableZero a => Vector a -> Matrix a
LM.rowVector
  colVector :: Vector a -> Matrix a
colVector = Vector a -> Matrix a
forall a. DecidableZero a => Vector a -> Matrix a
LM.colVector
  nonZeroRows :: Matrix a -> [Int]
nonZeroRows = Matrix a -> [Int]
forall r. Matrix r -> [Int]
LM.nonZeroRows
  nonZeroCols :: Matrix a -> [Int]
nonZeroCols = Matrix a -> [Int]
forall r. Matrix r -> [Int]
LM.nonZeroCols

delta :: (NA.Monoidal r, NA.Unital r) => Int -> Int -> r
delta :: Int -> Int -> r
delta Int
i Int
j | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
j = r
forall r. Unital r => r
NA.one
          | Bool
otherwise = r
forall m. Monoidal m => m
NA.zero

companion :: (KnownNat n, CoeffRing r, Matrix mat,
              Elem mat r, IsMonomialOrder n ord)
          => Ordinal n -> OrderedPolynomial r ord n -> mat r
companion :: Ordinal n -> OrderedPolynomial r ord n -> mat r
companion Ordinal n
odn OrderedPolynomial r ord n
poly =
  let deg :: Int
deg = OrderedPolynomial r ord n -> Int
forall poly. IsPolynomial poly => poly -> Int
totalDegree' OrderedPolynomial r ord n
poly
      vx :: OrderedMonomial
  (MOrder (OrderedPolynomial r ord n))
  (Arity (OrderedPolynomial r ord n))
vx  = OrderedPolynomial r ord n
-> OrderedMonomial
     (MOrder (OrderedPolynomial r ord n))
     (Arity (OrderedPolynomial r ord n))
forall poly.
IsOrderedPolynomial poly =>
poly -> OrderedMonomial (MOrder poly) (Arity poly)
leadingMonomial (Ordinal (Arity (OrderedPolynomial r ord n))
-> OrderedPolynomial r ord n
forall poly. IsPolynomial poly => Ordinal (Arity poly) -> poly
var Ordinal n
Ordinal (Arity (OrderedPolynomial r ord n))
odn OrderedPolynomial r ord n
-> OrderedPolynomial r ord n -> OrderedPolynomial r ord n
forall a. a -> a -> a
`asTypeOf` OrderedPolynomial r ord n
poly)
  in Int -> Int -> ((Int, Int) -> r) -> mat r
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
Int -> Int -> ((Int, Int) -> a) -> mat a
buildMatrix Int
deg Int
deg (((Int, Int) -> r) -> mat r) -> ((Int, Int) -> r) -> mat r
forall a b. (a -> b) -> a -> b
$ \(Int
j, Int
k) ->
  if Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
k Bool -> Bool -> Bool
&& Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
deg Int -> Int -> Int
forall r. Group r => r -> r -> r
- Int
1
  then Int -> Int -> r
forall r. (Monoidal r, Unital r) => Int -> Int -> r
delta Int
j (Int
kInt -> Int -> Int
forall r. Additive r => r -> r -> r
+Int
1)
  else r -> r
forall r. Group r => r -> r
NA.negate (r -> r) -> r -> r
forall a b. (a -> b) -> a -> b
$ OrderedMonomial
  (MOrder (OrderedPolynomial r ord n))
  (Arity (OrderedPolynomial r ord n))
-> OrderedPolynomial r ord n
-> Coefficient (OrderedPolynomial r ord n)
forall poly.
IsOrderedPolynomial poly =>
OrderedMonomial (MOrder poly) (Arity poly)
-> poly -> Coefficient poly
coeff (OrderedMonomial ord n -> Natural -> OrderedMonomial ord n
forall r. Unital r => r -> Natural -> r
NA.pow OrderedMonomial ord n
OrderedMonomial
  (MOrder (OrderedPolynomial r ord n))
  (Arity (OrderedPolynomial r ord n))
vx (Int -> Natural
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Natural) -> Int -> Natural
forall a b. (a -> b) -> a -> b
$ Int
jInt -> Int -> Int
forall r. Group r => r -> r -> r
-Int
1 :: NA.Natural)) OrderedPolynomial r ord n
poly

-- | @gaussReduction a = (a', p)@ where @a'@ is row echelon form and @p@ is pivoting matrix.
gaussReduction :: (Matrix mat, Elem mat a, Normed a, Eq a, NA.Field a)
               => mat a -> (mat a, mat a)
gaussReduction :: mat a -> (mat a, mat a)
gaussReduction mat a
mat =
  let (mat a
a, mat a
b, a
_) = mat a -> (mat a, mat a, a)
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a, Normed a, Eq a, Field a) =>
mat a -> (mat a, mat a, a)
gaussReduction' mat a
mat in (mat a
a, mat a
b)

-- | @gaussReduction a = (a', p)@ where @a'@ is row echelon form and @p@ is pivoting matrix.
gaussReduction' :: (Matrix mat, Elem mat a, Normed a, Eq a, NA.Field a)
               => mat a -> (mat a, mat a, a)
gaussReduction' :: mat a -> (mat a, mat a, a)
gaussReduction' mat a
mat = {-# SCC "gaussRed" #-} Int -> Int -> mat a -> mat a -> a -> (mat a, mat a, a)
go Int
1 Int
1 mat a
mat (Int -> mat a
forall (mat :: * -> *) a. (Matrix mat, Elem mat a) => Int -> mat a
identity (Int -> mat a) -> Int -> mat a
forall a b. (a -> b) -> a -> b
$ mat a -> Int
forall (mat :: * -> *) a. Matrix mat => mat a -> Int
nrows mat a
mat) a
forall r. Unital r => r
NA.one
  where
    go :: Int -> Int -> mat a -> mat a -> a -> (mat a, mat a, a)
go Int
i Int
j mat a
a mat a
p a
acc
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> mat a -> Int
forall (mat :: * -> *) a. Matrix mat => mat a -> Int
nrows mat a
mat Bool -> Bool -> Bool
|| Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> mat a -> Int
forall (mat :: * -> *) a. Matrix mat => mat a -> Int
ncols mat a
mat = (mat a
a, mat a
p, a
acc)
      | Bool
otherwise =
        let (Int
k, a
new) = ((Int, a) -> (Int, a) -> Ordering) -> [(Int, a)] -> (Int, a)
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
maximumBy (((Int, a) -> Norm a) -> (Int, a) -> (Int, a) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (((Int, a) -> Norm a) -> (Int, a) -> (Int, a) -> Ordering)
-> ((Int, a) -> Norm a) -> (Int, a) -> (Int, a) -> Ordering
forall a b. (a -> b) -> a -> b
$ a -> Norm a
forall a. Normed a => a -> Norm a
norm (a -> Norm a) -> ((Int, a) -> a) -> (Int, a) -> Norm a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, a) -> a
forall a b. (a, b) -> b
snd) [(Int
l, mat a
a mat a -> (Int, Int) -> a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
mat a -> (Int, Int) -> a
! (Int
l, Int
j)) | Int
l <- [Int
i..mat a -> Int
forall (mat :: * -> *) a. Matrix mat => mat a -> Int
nrows mat a
mat]]
        in if a
new a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall m. Monoidal m => m
NA.zero
           then Int -> Int -> mat a -> mat a -> a -> (mat a, mat a, a)
go Int
i (Int
j Int -> Int -> Int
forall r. Additive r => r -> r -> r
+ Int
1) mat a
a mat a
p a
forall m. Monoidal m => m
NA.zero
           else let prc :: Int -> mat a -> mat a -> (mat a, mat a)
prc Int
l mat a
a0 mat a
p0
                      | Int
l Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
i = Int -> mat a -> mat a -> (mat a, mat a)
prc (Int
lInt -> Int -> Int
forall r. Additive r => r -> r -> r
+Int
1) mat a
a0 mat a
p0
                      | Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> mat a -> Int
forall (mat :: * -> *) a. Matrix mat => mat a -> Int
nrows mat a
mat = (mat a
a0, mat a
p0)
                      | Bool
otherwise     =
                        let coe :: a
coe = a -> a
forall r. Group r => r -> r
NA.negate (mat a
a0 mat a -> (Int, Int) -> a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
mat a -> (Int, Int) -> a
! (Int
l, Int
j))
                            a'' :: mat a
a'' = Int -> a -> Int -> mat a -> mat a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
Int -> a -> Int -> mat a -> mat a
combineRows Int
l a
coe Int
i mat a
a0
                            p'' :: mat a
p'' = Int -> a -> Int -> mat a -> mat a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
Int -> a -> Int -> mat a -> mat a
combineRows Int
l a
coe Int
i mat a
p0
                        in Int -> mat a -> mat a -> (mat a, mat a)
prc (Int
lInt -> Int -> Int
forall r. Additive r => r -> r -> r
+Int
1) mat a
a'' mat a
p''
                    (mat a
a', mat a
p') = Int -> mat a -> mat a -> (mat a, mat a)
prc Int
1 (a -> Int -> mat a -> mat a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
a -> Int -> mat a -> mat a
scaleRow (a -> a
forall r. Division r => r -> r
NA.recip a
new) Int
i (mat a -> mat a) -> mat a -> mat a
forall a b. (a -> b) -> a -> b
$ Int -> Int -> mat a -> mat a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
Int -> Int -> mat a -> mat a
switchRows Int
i Int
k mat a
a)
                                     (a -> Int -> mat a -> mat a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
a -> Int -> mat a -> mat a
scaleRow (a -> a
forall r. Division r => r -> r
NA.recip a
new) Int
i (mat a -> mat a) -> mat a -> mat a
forall a b. (a -> b) -> a -> b
$ Int -> Int -> mat a -> mat a
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
Int -> Int -> mat a -> mat a
switchRows Int
i Int
k mat a
p)
                    offset :: a -> a
offset = if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
k then a -> a
forall a. a -> a
id else a -> a
forall r. Group r => r -> r
NA.negate
                in Int -> Int -> mat a -> mat a -> a -> (mat a, mat a, a)
go (Int
iInt -> Int -> Int
forall r. Additive r => r -> r -> r
+Int
1) (Int
jInt -> Int -> Int
forall r. Additive r => r -> r -> r
+Int
1) mat a
a' mat a
p' (a -> a
offset (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ a
acc a -> a -> a
forall r. Multiplicative r => r -> r -> r
NA.* a
new)

det :: (Elem mat a, Eq a, NA.Field a, Normed a, Matrix mat)
    => mat a -> a
det :: mat a -> a
det = Getting a (mat a, mat a, a) a -> (mat a, mat a, a) -> a
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting a (mat a, mat a, a) a
forall s t a b. Field3 s t a b => Lens s t a b
_3 ((mat a, mat a, a) -> a)
-> (mat a -> (mat a, mat a, a)) -> mat a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. mat a -> (mat a, mat a, a)
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a, Normed a, Eq a, Field a) =>
mat a -> (mat a, mat a, a)
gaussReduction'

maxNorm :: (Elem mat a, Normed a, Matrix mat) => mat a -> Norm a
maxNorm :: mat a -> Norm a
maxNorm = [Norm a] -> Norm a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Norm a] -> Norm a) -> (mat a -> [Norm a]) -> mat a -> Norm a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Norm a]] -> [Norm a]
forall w. Monoid w => [w] -> w
concat ([[Norm a]] -> [Norm a])
-> (mat a -> [[Norm a]]) -> mat a -> [Norm a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Vector a -> [Norm a]) -> [Vector a] -> [[Norm a]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ((a -> Norm a) -> [a] -> [Norm a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map a -> Norm a
forall a. Normed a => a -> Norm a
norm ([a] -> [Norm a]) -> (Vector a -> [a]) -> Vector a -> [Norm a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> [a]
forall a. Vector a -> [a]
V.toList) ([Vector a] -> [[Norm a]])
-> (mat a -> [Vector a]) -> mat a -> [[Norm a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. mat a -> [Vector a]
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a) =>
mat a -> [Vector a]
toRows

rankWith :: (Elem mat r, CoeffRing r, Matrix mat)
         => (mat r -> mat r) -> mat r -> Int
rankWith :: (mat r -> mat r) -> mat r -> Int
rankWith mat r -> mat r
gauss = [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Int] -> Int) -> (mat r -> [Int]) -> mat r -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. mat r -> [Int]
forall (mat :: * -> *) a.
(Matrix mat, DecidableZero a, Elem mat a) =>
mat a -> [Int]
nonZeroRows (mat r -> [Int]) -> (mat r -> mat r) -> mat r -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. mat r -> mat r
gauss

inverse :: (Elem mat a, Eq a, NA.Field a, Normed a, Matrix mat)
        => mat a -> mat a
inverse :: mat a -> mat a
inverse = (mat a, mat a) -> mat a
forall a b. (a, b) -> b
snd ((mat a, mat a) -> mat a)
-> (mat a -> (mat a, mat a)) -> mat a -> mat a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. mat a -> (mat a, mat a)
forall (mat :: * -> *) a.
(Matrix mat, Elem mat a, Normed a, Eq a, Field a) =>
mat a -> (mat a, mat a)
gaussReduction

inverseWith :: (mat a -> (mat a, mat a)) -> mat a -> mat a
inverseWith :: (mat a -> (mat a, mat a)) -> mat a -> mat a
inverseWith = ((mat a, mat a) -> mat a
forall a b. (a, b) -> b
snd ((mat a, mat a) -> mat a)
-> (mat a -> (mat a, mat a)) -> mat a -> mat a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.)