{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE UndecidableInstances #-}
module Numeric.LAPACK.Matrix.Inverse where
import qualified Numeric.LAPACK.Matrix.Type.Private 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.Private (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 ::
Matrix.QuadraticMeas typ xl xu upper lower meas width height a ->
Matrix.QuadraticMeas (Inverse typ) (xl,lower) (xu,upper)
lower upper 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
type family InverseExtra xl
type instance InverseExtra (xl,lower) = xl
type family InverseStrip xl
type instance InverseStrip (xl,lower) = lower
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
type TransposeExtra (Inverse typ) extra =
Matrix.TransposeExtra typ (InverseExtra extra)
transpose (Inverse a) = Inverse $ Matrix.transpose a
instance (Matrix.MultiplySame typ) => Matrix.MultiplySame (Inverse typ) where
type MultiplySameExtra (Inverse typ) extra =
(Matrix.MultiplySameExtra typ (InverseExtra extra),
MatrixShape.PowerStrip (InverseStrip extra))
multiplySame (Inverse a) (Inverse b) = Inverse $ Matrix.multiplySame b a
instance (Matrix.Box typ) => Matrix.Box (Inverse typ) where
type BoxExtra (Inverse typ) extra = Matrix.BoxExtra typ (InverseExtra extra)
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, Matrix.ToQuadratic typ) =>
Multiply.MultiplyVector (Inverse typ) where
type MultiplyVectorExtra (Inverse typ) extra =
(Multiply.MultiplyVectorExtra typ (InverseExtra extra),
Divide.SolveExtra typ (InverseExtra extra),
Matrix.BoxExtra typ (InverseExtra extra),
Omni.Strip (InverseStrip extra))
matrixVector (Inverse a) x = a#\|x
vectorMatrix x (Inverse a) = x-/#a
instance
(Divide.Solve typ, Matrix.ToQuadratic typ) =>
Multiply.MultiplySquare (Inverse typ) where
type MultiplySquareExtra (Inverse typ) extra =
(Multiply.MultiplySquareExtra typ (InverseExtra extra),
Divide.SolveExtra typ (InverseExtra extra),
Matrix.BoxExtra typ (InverseExtra extra),
Omni.Strip (InverseStrip extra))
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) => Multiply.Power (Inverse typ) where
type PowerExtra (Inverse typ) extra =
(Multiply.PowerExtra typ (InverseExtra extra),
MatrixShape.PowerStrip (InverseStrip extra))
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) => Divide.Determinant (Inverse typ) where
type DeterminantExtra (Inverse typ) extra =
(Divide.DeterminantExtra typ (InverseExtra extra),
MatrixShape.PowerStrip (InverseStrip extra))
determinant (Inverse a) = recip $ Divide.determinant a
instance
(Multiply.MultiplySquare typ, Matrix.ToQuadratic typ) =>
Divide.Solve (Inverse typ) where
type SolveExtra (Inverse typ) extra =
(Divide.SolveExtra typ (InverseExtra extra),
Multiply.MultiplySquareExtra typ (InverseExtra extra),
MatrixShape.PowerStrip (InverseStrip extra))
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, Multiply.MultiplySquare typ, Matrix.ToQuadratic typ) =>
Divide.Inverse (Inverse typ) where
type InverseExtra (Inverse typ) extra =
(Divide.InverseExtra typ (InverseExtra extra),
Multiply.MultiplySquareExtra typ (InverseExtra extra),
MatrixShape.PowerStrip (InverseStrip extra))
inverse (Inverse a) = Inverse $ Divide.inverse a