{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE EmptyDataDecls #-} {- | This module provides an infix operator and some data constructors that shall resemble mathematical notation. E.g. you can write @a#^T@ for @Matrix.transpose a@. It is clearly abuse of the type system because I suspect you will never write algorithms that are generic in the superscript type. -} module Numeric.LAPACK.Matrix.Superscript where import qualified Numeric.LAPACK.Singular as Singular import qualified Numeric.LAPACK.Matrix.Shape.Omni as Omni import qualified Numeric.LAPACK.Matrix.Layout as Layout import qualified Numeric.LAPACK.Matrix.Extent as Extent import qualified Numeric.LAPACK.Matrix.Array.Private as ArrMatrix import qualified Numeric.LAPACK.Matrix as Matrix import Numeric.LAPACK.Matrix.Layout.Private (Filled) import Numeric.LAPACK.Matrix.Extent (Shape, Small) import Numeric.LAPACK.Matrix (Matrix) import qualified Data.Array.Comfort.Shape as Shape import qualified Numeric.Netlib.Class as Class {- | left associative in contrast to ^, ^^ etc. because there is no law analogous to power law @(x^a)^b = x^(a*b)@. -} infixl 8 #^ class Superscript sup where data Exponent sup typA xlA xuA lowerA upperA measA vertA horizA heightA widthA typB xlB xuB lowerB upperB measB vertB horizB heightB widthB a (#^) :: (Extent.Measure measA, Extent.C vertA, Extent.C horizA) => (Shape.C widthA, Shape.C heightA) => (Extent.Measure measB, Extent.C vertB, Extent.C horizB) => (Shape.C widthB, Shape.C heightB) => (Class.Floating a) => Matrix typA xlA xuA lowerA upperA measA vertA horizA heightA widthA a -> Exponent sup typA xlA xuA lowerA upperA measA vertA horizA heightA widthA typB xlB xuB lowerB upperB measB vertB horizB heightB widthB a -> Matrix typB xlB xuB lowerB upperB measB vertB horizB heightB widthB a data None instance Superscript None where data Exponent None typA xlA xuA lowerA upperA measA vertA horizA heightA widthA typB xlB xuB lowerB upperB measB vertB horizB heightB widthB a where N :: Exponent None typ xl xu lower upper meas vert horiz height width typ xl xu lower upper meas vert horiz height width a a#^N = a data Transpose instance Superscript Transpose where data Exponent Transpose typA xlA xuA lowerA upperA measA vertA horizA heightA widthA typB xlB xuB lowerB upperB measB vertB horizB heightB widthB a where T :: (Matrix.Transpose typ) => Exponent Transpose typ xl xu lower upper meas vert horiz height width typ xu xl upper lower meas horiz vert width height a a#^T = Matrix.transpose a data Adjoint instance Superscript Adjoint where data Exponent Adjoint typA xlA xuA lowerA upperA measA vertA horizA heightA widthA typB xlB xuB lowerB upperB measB vertB horizB heightB widthB a where A :: (Matrix.Transpose typ, Matrix.Complex typ) => Exponent Adjoint typ xl xu lower upper meas vert horiz height width typ xu xl upper lower meas horiz vert width height a a#^A = Matrix.adjoint a data Conjugate instance Superscript Conjugate where data Exponent Conjugate typA xlA xuA lowerA upperA measA vertA horizA heightA widthA typB xlB xuB lowerB upperB measB vertB horizB heightB widthB a where C :: (Matrix.Complex typ) => Exponent Conjugate typ xl xu lower upper meas vert horiz height width typ xl xu lower upper meas vert horiz height width a a#^C = Matrix.conjugate a data Inverse instance Superscript Inverse where data Exponent Inverse typA xlA xuA lowerA upperA measA vertA horizA heightA widthA typB xlB xuB lowerB upperB measB vertB horizB heightB widthB a where -- We could relax lowerB and upperB using Filled type function Inv :: (Matrix.Inverse typ xl xu, Omni.PowerStrip lower, Omni.PowerStrip upper) => Exponent Inverse typ xl xu lower upper meas Small Small height width typ xl xu lower upper meas Small Small width height a a#^Inv = Matrix.inverse a data PseudoInverse instance Superscript PseudoInverse where data Exponent PseudoInverse typA xlA xuA lowerA upperA measA vertA horizA heightA widthA typB xlB xuB lowerB upperB measB vertB horizB heightB widthB a where Pseudo :: (typ ~ ArrMatrix.Array Layout.Unpacked Omni.Arbitrary) => Matrix.RealOf a -> Exponent PseudoInverse typ () () Filled Filled Shape Small Small sh sh typ () () Filled Filled Shape Small Small sh sh a a#^Pseudo rcond = snd $ Singular.pseudoInverseRCond rcond a data Power instance Superscript Power where data Exponent Power typA xlA xuA lowerA upperA measA vertA horizA heightA widthA typB xlB xuB lowerB upperB measB vertB horizB heightB widthB a where -- We could relax lowerB and upperB using Filled type function Exp :: (Matrix.Power typ xl xu, Omni.PowerStrip lower, Omni.PowerStrip upper) => Integer -> Exponent Power typ xl xu lower upper Shape Small Small sh sh typ xl xu lower upper Shape Small Small sh sh a a#^Exp n = Matrix.power n a