lapack-0.4: src/Numeric/LAPACK/Matrix/Inverse.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
module Numeric.LAPACK.Matrix.Inverse where
import qualified Numeric.LAPACK.Matrix.Type as Matrix
import qualified Numeric.LAPACK.Matrix.Layout.Private as Layout
import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape
import qualified Numeric.LAPACK.Matrix.Shape.Omni as Omni
import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent
import qualified Numeric.LAPACK.Matrix.Class as MatrixClass
import qualified Numeric.LAPACK.Matrix.Divide as Divide
import qualified Numeric.LAPACK.Matrix.Multiply as Multiply
import Numeric.LAPACK.Matrix.Divide ((#\|), (-/#))
import Numeric.LAPACK.Matrix.Type (Matrix)
import qualified Type.Data.Num.Unary as Unary
data Inverse typ
data instance
Matrix (Inverse typ)
extraLower extraUpper lowerf upperf meas vert horiz height width a
where
Inverse ::
(Omni.Strip lower, Fill lower ~ lowerf, Omni.PowerStrip lowerf,
Omni.Strip upper, Fill upper ~ upperf, Omni.PowerStrip upperf) =>
Matrix.QuadraticMeas typ xl xu upper lower meas width height a ->
Matrix.QuadraticMeas (Inverse typ) (xl,lower) (xu,upper)
lowerf upperf meas height width a
type family Fill offDiag
type instance Fill (Layout.Bands Unary.Zero) = Layout.Bands Unary.Zero
type instance Fill (Layout.Bands (Unary.Succ k)) = Layout.Filled
type instance Fill Layout.Filled = Layout.Filled
data PowerStripFact c = (Omni.PowerStrip c) => PowerStripFact
filledPowerStripFact ::
(Omni.Strip c) => Omni.StripSingleton c -> PowerStripFact (Fill c)
filledPowerStripFact w =
case w of
Omni.StripFilled -> PowerStripFact
Omni.StripBands Unary.Zero -> PowerStripFact
Omni.StripBands Unary.Succ -> PowerStripFact
instance (Matrix.Transpose typ) => Matrix.Transpose (Inverse typ) where
transpose (Inverse a) = Inverse $ Matrix.transpose a
instance
(Matrix.MultiplySame typ xl xu,
MatrixShape.PowerStrip lower, MatrixShape.PowerStrip upper) =>
Matrix.MultiplySame (Inverse typ) (xl,lower) (xu,upper) where
multiplySame (Inverse a) (Inverse b) = Inverse $ Matrix.multiplySame b a
instance (Matrix.Box typ) => Matrix.Box (Inverse typ) where
extent (Inverse m) = Extent.transpose $ Matrix.extent m
height (Inverse m) = Matrix.width m
width (Inverse m) = Matrix.height m
instance (Matrix.ToQuadratic typ) => Matrix.ToQuadratic (Inverse typ) where
heightToQuadratic (Inverse m) = Inverse $ Matrix.widthToQuadratic m
widthToQuadratic (Inverse m) = Inverse $ Matrix.heightToQuadratic m
instance (MatrixClass.Complex typ) => MatrixClass.Complex (Inverse typ) where
conjugate (Inverse m) = Inverse $ MatrixClass.conjugate m
fromReal (Inverse m) = Inverse $ MatrixClass.fromReal m
toComplex (Inverse m) = Inverse $ MatrixClass.toComplex m
instance
(Divide.Solve typ xl xu, Matrix.ToQuadratic typ,
Omni.Strip lower, Omni.Strip upper) =>
Multiply.MultiplyVector (Inverse typ) (xl,lower) (xu,upper) where
matrixVector (Inverse a) x = a#\|x
vectorMatrix x (Inverse a) = x-/#a
instance
(Divide.Solve typ xl xu, Matrix.ToQuadratic typ,
Omni.Strip lower, Omni.Strip upper) =>
Multiply.MultiplySquare (Inverse typ) (xl,lower) (xu,upper) where
transposableSquare trans (Inverse a) = Divide.solve trans a
squareFull (Inverse a) b = Divide.solveRight a b
fullSquare b (Inverse a) = Divide.solveLeft b a
instance
(Multiply.Power typ xl xu,
MatrixShape.PowerStrip lower, MatrixShape.PowerStrip upper) =>
Multiply.Power (Inverse typ) (xl,lower) (xu,upper) where
square (Inverse a) = Inverse $ Multiply.square a
power n (Inverse a) = Inverse $ Multiply.power n a
powers1 (Inverse a) = fmap Inverse $ Multiply.powers1 a
instance
(Divide.Determinant typ xl xu,
MatrixShape.PowerStrip lower, MatrixShape.PowerStrip upper) =>
Divide.Determinant (Inverse typ) (xl,lower) (xu,upper) where
determinant (Inverse a) = recip $ Divide.determinant a
instance
(Multiply.MultiplySquare typ xl xu, Matrix.ToQuadratic typ,
MatrixShape.PowerStrip lower, MatrixShape.PowerStrip upper) =>
Divide.Solve (Inverse typ) (xl,lower) (xu,upper) where
solve trans (Inverse a) = Multiply.transposableSquare trans a
solveRight (Inverse a) b = Multiply.squareFull a b
solveLeft b (Inverse a) = Multiply.fullSquare b a
instance
(Divide.Inverse typ xl xu, Multiply.MultiplySquare typ xl xu,
Matrix.ToQuadratic typ, MatrixShape.PowerStrip lower, MatrixShape.PowerStrip upper) =>
Divide.Inverse (Inverse typ) (xl,lower) (xu,upper) where
inverse (Inverse a) = Inverse $ Divide.inverse a