{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Numeric.LAPACK.Matrix.Square (
Square,
size,
mapSize,
toFull,
toGeneral,
fromFull,
liberalFromFull,
fromScalar,
toScalar,
fromList,
autoFromList,
transpose,
adjoint,
identity,
identityFrom,
identityFromWidth,
identityFromHeight,
diagonal,
takeDiagonal,
trace,
stack, (|=|),
split, takeTopLeft, takeBottomRight,
multiply,
square,
power,
congruence,
congruenceAdjoint,
solve,
inverse,
determinant,
eigenvalues,
schur,
schurComplex,
eigensystem,
ComplexOf,
) where
import qualified Numeric.LAPACK.Matrix.Triangular as Triangular
import qualified Numeric.LAPACK.Matrix.Square.Eigen as Eigen
import qualified Numeric.LAPACK.Matrix.Square.Linear as Linear
import qualified Numeric.LAPACK.Matrix.Square.Basic as Basic
import qualified Numeric.LAPACK.Matrix.Basic as FullBasic
import qualified Numeric.LAPACK.Matrix.Array.Private as ArrMatrix
import qualified Numeric.LAPACK.Matrix.Shape.Omni as Omni
import qualified Numeric.LAPACK.Matrix.Extent as Extent
import qualified Numeric.LAPACK.Shape as ExtShape
import Numeric.LAPACK.Matrix.Array.Private
(Full, General, Square, SquareMeas, LiberalSquare)
import Numeric.LAPACK.Matrix.Private (ShapeInt)
import Numeric.LAPACK.Vector (Vector)
import Numeric.LAPACK.Scalar (ComplexOf)
import qualified Numeric.Netlib.Class as Class
import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Shape ((::+))
import Foreign.Storable (Storable)
import Data.Tuple.HT (mapPair, mapSnd, mapTriple)
import Data.Complex (Complex)
size :: Square sh a -> sh
size = Omni.squareSize . ArrMatrix.shape
mapSize :: (sh0 -> sh1) -> Square sh0 a -> Square sh1 a
mapSize = ArrMatrix.lift1 . Basic.mapSize
toGeneral :: Square sh a -> General sh sh a
toGeneral = toFull
toFull ::
(Extent.Measured meas vert, Extent.Measured meas horiz) =>
Square sh a -> Full meas vert horiz sh sh a
toFull = ArrMatrix.lift1 Basic.toFull
fromFull ::
(Extent.Measure meas, Extent.C vert, Extent.C horiz, Eq sh) =>
Full meas vert horiz sh sh a -> Square sh a
fromFull = ArrMatrix.lift1 Basic.fromFull
liberalFromFull ::
(Extent.Measure meas, Extent.C vert, Extent.C horiz,
Shape.C height, Shape.C width) =>
Full meas vert horiz height width a -> LiberalSquare height width a
liberalFromFull = ArrMatrix.lift1 Basic.liberalFromFull
fromScalar :: (Storable a) => a -> Square () a
fromScalar = ArrMatrix.lift0 . Basic.fromScalar
toScalar :: (Storable a) => Square () a -> a
toScalar = Basic.toScalar . ArrMatrix.toVector
fromList :: (Shape.C sh, Storable a) => sh -> [a] -> Square sh a
fromList sh = ArrMatrix.lift0 . Basic.fromList sh
autoFromList :: (Storable a) => [a] -> Square ShapeInt a
autoFromList = ArrMatrix.lift0 . Basic.autoFromList
transpose :: Square sh a -> Square sh a
transpose = ArrMatrix.lift1 Basic.transpose
adjoint :: (Shape.C sh, Class.Floating a) => Square sh a -> Square sh a
adjoint = ArrMatrix.lift1 Basic.adjoint
identity :: (Shape.C sh, Class.Floating a) => sh -> Square sh a
identity = ArrMatrix.lift0 . Basic.identity
identityFrom :: (Shape.C sh, Class.Floating a) => Square sh a -> Square sh a
identityFrom = ArrMatrix.lift1 Basic.identityFrom
identityFromWidth ::
(Shape.C height, Shape.C width, Class.Floating a) =>
General height width a -> Square width a
identityFromWidth = ArrMatrix.lift1 Basic.identityFromWidth
identityFromHeight ::
(Shape.C height, Shape.C width, Class.Floating a) =>
General height width a -> Square height a
identityFromHeight = ArrMatrix.lift1 Basic.identityFromHeight
diagonal :: (Shape.C sh, Class.Floating a) => Vector sh a -> Square sh a
diagonal = ArrMatrix.lift0 . Basic.diagonal
takeDiagonal :: (Shape.C sh, Class.Floating a) => Square sh a -> Vector sh a
takeDiagonal = Basic.takeDiagonal . ArrMatrix.toVector
trace :: (Shape.C sh, Class.Floating a) => Square sh a -> a
trace = Basic.trace . ArrMatrix.toVector
infix 3 |=|
(|=|) ::
(Extent.Measure meas, Extent.C vert, Extent.C horiz,
Shape.C sizeA, Eq sizeA, Shape.C sizeB, Eq sizeB, Class.Floating a) =>
(Square sizeA a, Full meas vert horiz sizeA sizeB a) ->
(Full meas horiz vert sizeB sizeA a, Square sizeB a) ->
Square (sizeA::+sizeB) a
(a,b) |=| (c,d) = stack a b c d
stack ::
(Extent.Measure meas, Extent.C vert, Extent.C horiz,
Shape.C sizeA, Eq sizeA, Shape.C sizeB, Eq sizeB, Class.Floating a) =>
Square sizeA a -> Full meas vert horiz sizeA sizeB a ->
Full meas horiz vert sizeB sizeA a -> Square sizeB a ->
Square (sizeA::+sizeB) a
stack = ArrMatrix.lift4 Basic.stack
split ::
(Shape.C sizeA, Shape.C sizeB, Class.Floating a) =>
Square (sizeA::+sizeB) a ->
(Square sizeA a, General sizeA sizeB a,
General sizeB sizeA a, Square sizeB a)
split a =
let af = Basic.toFull $ ArrMatrix.toVector a
top = FullBasic.takeTop af
bottom = FullBasic.takeBottom af
in (ArrMatrix.lift0 $ Basic.fromFullUnchecked $ FullBasic.takeLeft top,
ArrMatrix.lift0 $ FullBasic.takeRight top,
ArrMatrix.lift0 $ FullBasic.takeLeft bottom,
ArrMatrix.lift0 $ Basic.fromFullUnchecked $ FullBasic.takeRight bottom)
takeTopLeft ::
(Shape.C sizeA, Shape.C sizeB, Class.Floating a) =>
Square (sizeA::+sizeB) a -> Square sizeA a
takeTopLeft =
ArrMatrix.lift1
(Basic.fromFullUnchecked .
FullBasic.takeLeft . FullBasic.takeTop . Basic.toFull)
takeBottomRight ::
(Shape.C sizeA, Shape.C sizeB, Class.Floating a) =>
Square (sizeA::+sizeB) a -> Square sizeB a
takeBottomRight =
ArrMatrix.lift1
(Basic.fromFullUnchecked .
FullBasic.takeRight . FullBasic.takeBottom . Basic.toFull)
multiply ::
(Shape.C sh, Eq sh, Class.Floating a) =>
Square sh a -> Square sh a -> Square sh a
multiply = ArrMatrix.lift2 FullBasic.multiply
square :: (Shape.C sh, Class.Floating a) => Square sh a -> Square sh a
square = ArrMatrix.lift1 Basic.square
power ::
(Shape.C sh, Class.Floating a) =>
Integer -> Square sh a -> Square sh a
power = ArrMatrix.lift1 . Basic.power
congruence ::
(Shape.C height, Eq height, Shape.C width, Class.Floating a) =>
Square height a -> General height width a -> Square width a
congruence = ArrMatrix.lift2 Basic.congruence
congruenceAdjoint ::
(Shape.C height, Shape.C width, Eq width, Class.Floating a) =>
General height width a -> Square width a -> Square height a
congruenceAdjoint = ArrMatrix.lift2 Basic.congruenceAdjoint
solve ::
(Extent.Measure meas, Extent.C vert, Extent.C horiz,
Shape.C sh, Eq sh, Shape.C nrhs, Class.Floating a) =>
Square sh a ->
Full meas vert horiz sh nrhs a -> Full meas vert horiz sh nrhs a
solve = ArrMatrix.lift2 Linear.solve
inverse ::
(Extent.Measure meas, Shape.C height, Shape.C width, Class.Floating a) =>
SquareMeas meas height width a -> SquareMeas meas width height a
inverse = ArrMatrix.lift1 Linear.inverse
determinant :: (Shape.C sh, Class.Floating a) => Square sh a -> a
determinant = Linear.determinant . ArrMatrix.toVector
eigenvalues ::
(ExtShape.Permutable sh, Class.Floating a) =>
Square sh a -> Vector sh (ComplexOf a)
eigenvalues = Eigen.values . ArrMatrix.toVector
schur ::
(ExtShape.Permutable sh, Class.Floating a) =>
Square sh a -> (Square sh a, Triangular.QuasiUpper sh a)
schur =
mapPair (ArrMatrix.lift0, ArrMatrix.liftUnpacked0) .
Eigen.schur . ArrMatrix.toVector
schurComplex ::
(ExtShape.Permutable sh, Class.Real a, Complex a ~ ac) =>
Square sh ac -> (Square sh ac, Triangular.Upper sh ac)
schurComplex = mapSnd Triangular.takeUpper . schur
eigensystem ::
(ExtShape.Permutable sh, Class.Floating a, ComplexOf a ~ ac) =>
Square sh a -> (Square sh ac, Vector sh ac, Square sh ac)
eigensystem =
mapTriple (ArrMatrix.lift0, id, ArrMatrix.lift0) .
Eigen.decompose . ArrMatrix.toVector