module Numeric.LAPACK.Matrix.Divide where
import qualified Numeric.LAPACK.Matrix.Plain.Divide as ArrDivide
import qualified Numeric.LAPACK.Matrix.Array.Basic as Basic
import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix
import qualified Numeric.LAPACK.Matrix.Permutation as PermMatrix
import qualified Numeric.LAPACK.Matrix.Multiply as Multiply
import qualified Numeric.LAPACK.Matrix.Type as Type
import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape
import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent
import qualified Numeric.LAPACK.Vector as Vector
import Numeric.LAPACK.Matrix.Array (Full)
import Numeric.LAPACK.Matrix.Type (Matrix, scaleWithCheck)
import Numeric.LAPACK.Matrix.Modifier
(Transposition(NonTransposed,Transposed),
Inversion(Inverted))
import Numeric.LAPACK.Vector (Vector)
import qualified Numeric.Netlib.Class as Class
import qualified Data.Array.Comfort.Shape as Shape
import Data.Semigroup ((<>))
class
(Type.Box typ, Type.HeightOf typ ~ Type.WidthOf typ) =>
Determinant typ where
determinant :: (Class.Floating a) => Matrix typ a -> a
class (Type.Box typ, Type.HeightOf typ ~ Type.WidthOf typ) => Solve typ where
solve ::
(Type.HeightOf typ ~ height, Eq height, Shape.C width,
Extent.C horiz, Extent.C vert, Class.Floating a) =>
Transposition -> Matrix typ a ->
Full vert horiz height width a -> Full vert horiz height width a
solve NonTransposed a b = solveRight a b
solve Transposed a b = Basic.transpose $ solveLeft (Basic.transpose b) a
solveRight ::
(Type.HeightOf typ ~ height, Eq height, Shape.C width,
Extent.C horiz, Extent.C vert, Class.Floating a) =>
Matrix typ a ->
Full vert horiz height width a -> Full vert horiz height width a
solveRight = solve NonTransposed
solveLeft ::
(Type.WidthOf typ ~ width, Eq width, Shape.C height,
Extent.C horiz, Extent.C vert, Class.Floating a) =>
Full vert horiz height width a ->
Matrix typ a -> Full vert horiz height width a
solveLeft = Basic.swapMultiply $ solve Transposed
class (Solve typ, Multiply.Power typ) => Inverse typ where
inverse :: (Class.Floating a) => Matrix typ a -> Matrix typ a
infixl 7 ##/#
infixr 7 #\##
(#\##) ::
(Solve typ, Type.HeightOf typ ~ height, Eq height, Shape.C width,
Extent.C horiz, Extent.C vert, Class.Floating a) =>
Matrix typ a ->
Full vert horiz height width a -> Full vert horiz height width a
(#\##) = solveRight
(##/#) ::
(Solve typ, Type.WidthOf typ ~ width, Eq width, Shape.C height,
Extent.C horiz, Extent.C vert, Class.Floating a) =>
Full vert horiz height width a ->
Matrix typ a -> Full vert horiz height width a
(##/#) = solveLeft
solveVector ::
(Solve typ, Type.HeightOf typ ~ height, Eq height, Class.Floating a) =>
Transposition -> Matrix typ a -> Vector height a -> Vector height a
solveVector trans =
ArrMatrix.unliftColumn MatrixShape.ColumnMajor . solve trans
infixl 7 -/#
infixr 7 #\|
(#\|) ::
(Solve typ, Type.HeightOf typ ~ height, Eq height, Class.Floating a) =>
Matrix typ a -> Vector height a -> Vector height a
(#\|) = solveVector NonTransposed
(-/#) ::
(Solve typ, Type.HeightOf typ ~ height, Eq height, Class.Floating a) =>
Vector height a -> Matrix typ a -> Vector height a
(-/#) = flip $ solveVector Transposed
instance (Shape.C shape, Eq shape) => Determinant (Type.Scale shape) where
determinant (Type.Scale sh a) = a ^ Shape.size sh
instance (Shape.C shape, Eq shape) => Solve (Type.Scale shape) where
solve _trans =
scaleWithCheck "Matrix.Scale.solve" Type.height $
ArrMatrix.lift1 . Vector.scale . recip
instance (Shape.C shape, Eq shape) => Inverse (Type.Scale shape) where
inverse (Type.Scale shape a) = Type.Scale shape $ recip a
instance (Shape.C shape) => Determinant (PermMatrix.Permutation shape) where
determinant = PermMatrix.determinant
instance (Shape.C shape) => Solve (PermMatrix.Permutation shape) where
solve trans =
PermMatrix.multiplyFull
(Inverted <> PermMatrix.inversionFromTransposition trans)
instance (Shape.C shape) => Inverse (PermMatrix.Permutation shape) where
inverse = PermMatrix.transpose
instance
(ArrDivide.Determinant shape) => Determinant (ArrMatrix.Array shape) where
determinant = ArrDivide.determinant . ArrMatrix.toVector
instance (ArrDivide.Solve shape) => Solve (ArrMatrix.Array shape) where
solve = ArrMatrix.lift2 . ArrDivide.solve
solveLeft = ArrMatrix.lift2 ArrDivide.solveLeft
solveRight = ArrMatrix.lift2 ArrDivide.solveRight
instance (ArrDivide.Inverse shape) => Inverse (ArrMatrix.Array shape) where
inverse = ArrMatrix.lift1 ArrDivide.inverse