{-# LANGUAGE TypeFamilies #-}
module Numeric.LAPACK.Matrix.Class (
   SquareShape(toSquare, identityOrder, takeDiagonal),
   identityFrom,
   identityFromHeight,
   identityFromWidth,
   trace,
   Complex(conjugate, fromReal, toComplex),
   ) where

import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix
import qualified Numeric.LAPACK.Matrix.Type as Type
import qualified Numeric.LAPACK.Matrix.Plain.Class as Plain
import qualified Numeric.LAPACK.Matrix.Triangular as Triangular
import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape
import qualified Numeric.LAPACK.Matrix.Permutation as Permutation
import qualified Numeric.LAPACK.Permutation.Private as Perm
import qualified Numeric.LAPACK.Vector as Vector
import qualified Numeric.LAPACK.Scalar as Scalar
import Numeric.LAPACK.Matrix.Array (ArrayMatrix)
import Numeric.LAPACK.Vector (Vector)
import Numeric.LAPACK.Scalar (RealOf, ComplexOf)

import qualified Numeric.Netlib.Class as Class

import qualified Data.Array.Comfort.Shape as Shape


class Complex typ where
   conjugate ::
      (Class.Floating a) => Type.Matrix typ a -> Type.Matrix typ a
   fromReal ::
      (Class.Floating a) => Type.Matrix typ (RealOf a) -> Type.Matrix typ a
   toComplex ::
      (Class.Floating a) => Type.Matrix typ a -> Type.Matrix typ (ComplexOf a)

instance (Plain.Complex sh) => Complex (ArrMatrix.Array sh) where
   conjugate :: Matrix (Array sh) a -> Matrix (Array sh) a
conjugate = (Array sh a -> Array sh a)
-> Matrix (Array sh) a -> Matrix (Array sh) a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 Array sh a -> Array sh a
forall shape a.
(Complex shape, Floating a) =>
Array shape a -> Array shape a
Plain.conjugate
   fromReal :: Matrix (Array sh) (RealOf a) -> Matrix (Array sh) a
fromReal  = (Array sh (RealOf a) -> Array sh a)
-> Matrix (Array sh) (RealOf a) -> Matrix (Array sh) a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 Array sh (RealOf a) -> Array sh a
forall shape a.
(Complex shape, Floating a) =>
Array shape (RealOf a) -> Array shape a
Plain.fromReal
   toComplex :: Matrix (Array sh) a -> Matrix (Array sh) (ComplexOf a)
toComplex = (Array sh a -> Array sh (ComplexOf a))
-> Matrix (Array sh) a -> Matrix (Array sh) (ComplexOf a)
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 Array sh a -> Array sh (ComplexOf a)
forall shape a.
(Complex shape, Floating a) =>
Array shape a -> Array shape (ComplexOf a)
Plain.toComplex

instance (Shape.C shape) => Complex (Type.Scale shape) where
   conjugate :: Matrix (Scale shape) a -> Matrix (Scale shape) a
conjugate (Type.Scale sh m) = shape -> a -> Matrix (Scale shape) a
forall shape a. shape -> a -> Matrix (Scale shape) a
Type.Scale shape
sh (a -> Matrix (Scale shape) a) -> a -> Matrix (Scale shape) a
forall a b. (a -> b) -> a -> b
$ a -> a
forall a. Floating a => a -> a
Scalar.conjugate a
m
   fromReal :: Matrix (Scale shape) (RealOf a) -> Matrix (Scale shape) a
fromReal (Type.Scale sh m) = shape -> a -> Matrix (Scale shape) a
forall shape a. shape -> a -> Matrix (Scale shape) a
Type.Scale shape
sh (a -> Matrix (Scale shape) a) -> a -> Matrix (Scale shape) a
forall a b. (a -> b) -> a -> b
$ RealOf a -> a
forall a. Floating a => RealOf a -> a
Scalar.fromReal RealOf a
m
   toComplex :: Matrix (Scale shape) a -> Matrix (Scale shape) (ComplexOf a)
toComplex (Type.Scale sh m) = shape -> ComplexOf a -> Matrix (Scale shape) (ComplexOf a)
forall shape a. shape -> a -> Matrix (Scale shape) a
Type.Scale shape
sh (ComplexOf a -> Matrix (Scale shape) (ComplexOf a))
-> ComplexOf a -> Matrix (Scale shape) (ComplexOf a)
forall a b. (a -> b) -> a -> b
$ a -> ComplexOf a
forall a. Floating a => a -> ComplexOf a
Scalar.toComplex a
m

instance (Shape.C shape) => Complex (Perm.Permutation shape) where
   conjugate :: Matrix (Permutation shape) a -> Matrix (Permutation shape) a
conjugate = Matrix (Permutation shape) a -> Matrix (Permutation shape) a
forall a. a -> a
id
   fromReal :: Matrix (Permutation shape) (RealOf a)
-> Matrix (Permutation shape) a
fromReal (Type.Permutation p) = Permutation shape -> Matrix (Permutation shape) a
forall sh a. Permutation sh -> Matrix (Permutation sh) a
Type.Permutation Permutation shape
p
   toComplex :: Matrix (Permutation shape) a
-> Matrix (Permutation shape) (ComplexOf a)
toComplex (Type.Permutation p) = Permutation shape -> Matrix (Permutation shape) (ComplexOf a)
forall sh a. Permutation sh -> Matrix (Permutation sh) a
Type.Permutation Permutation shape
p


class SquareShape typ where
   toSquare ::
      (Type.HeightOf typ ~ sh, Class.Floating a) =>
      Type.Matrix typ a -> ArrMatrix.Square sh a
   identityOrder ::
      (Type.HeightOf typ ~ sh, Class.Floating a) =>
      MatrixShape.Order -> sh -> Type.Matrix typ a
   takeDiagonal ::
      (Type.HeightOf typ ~ sh, Class.Floating a) =>
      Type.Matrix typ a -> Vector sh a

instance (ArrMatrix.SquareShape sh) => SquareShape (ArrMatrix.Array sh) where
   toSquare :: Matrix (Array sh) a -> Square sh a
toSquare = (Array sh a -> Array (Square sh) a)
-> Matrix (Array sh) a -> Square sh a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 Array sh a -> Array (Square sh) a
forall shape sh a.
(SquareShape shape, HeightOf shape ~ sh, Floating a) =>
Array shape a -> Square sh a
Plain.toSquare
   identityOrder :: Order -> sh -> Matrix (Array sh) a
identityOrder Order
order = Array sh a -> Matrix (Array sh) a
forall shA a. Array shA a -> ArrayMatrix shA a
ArrMatrix.lift0 (Array sh a -> Matrix (Array sh) a)
-> (sh -> Array sh a) -> sh -> Matrix (Array sh) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Order -> sh -> Array sh a
forall shape sh a.
(SquareShape shape, HeightOf shape ~ sh, Floating a) =>
Order -> sh -> Array shape a
Plain.identityOrder Order
order
   takeDiagonal :: Matrix (Array sh) a -> Vector sh a
takeDiagonal = Array sh a -> Vector sh a
forall shape sh a.
(SquareShape shape, HeightOf shape ~ sh, Floating a) =>
Array shape a -> Vector sh a
Plain.takeDiagonal (Array sh a -> Vector sh a)
-> (Matrix (Array sh) a -> Array sh a)
-> Matrix (Array sh) a
-> Vector sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix (Array sh) a -> Array sh a
forall sh a. ArrayMatrix sh a -> Array sh a
ArrMatrix.toVector

instance (Shape.C sh) => SquareShape (Type.Scale sh) where
   toSquare :: Matrix (Scale sh) a -> Square sh a
toSquare (Type.Scale sh a) =
      Triangular Empty NonUnit Empty sh a -> Square sh a
forall lo up sh a diag.
(Content lo, Content up, C sh, Floating a) =>
Triangular lo diag up sh a -> Square sh a
Triangular.toSquare (Triangular Empty NonUnit Empty sh a -> Square sh a)
-> Triangular Empty NonUnit Empty sh a -> Square sh a
forall a b. (a -> b) -> a -> b
$ Triangular Empty NonUnit Empty sh a
-> Triangular Empty NonUnit Empty sh a
forall diag sh a. FlexDiagonal diag sh a -> FlexDiagonal diag sh a
Triangular.asDiagonal (Triangular Empty NonUnit Empty sh a
 -> Triangular Empty NonUnit Empty sh a)
-> Triangular Empty NonUnit Empty sh a
-> Triangular Empty NonUnit Empty sh a
forall a b. (a -> b) -> a -> b
$
      Order -> Vector sh a -> Triangular Empty NonUnit Empty sh a
forall lo up sh a.
(Content lo, Content up, C sh, Floating a) =>
Order -> Vector sh a -> Triangular lo NonUnit up sh a
Triangular.diagonal Order
MatrixShape.RowMajor (Vector sh a -> Triangular Empty NonUnit Empty sh a)
-> Vector sh a -> Triangular Empty NonUnit Empty sh a
forall a b. (a -> b) -> a -> b
$ sh -> a -> Vector sh a
forall sh a. (C sh, Floating a) => sh -> a -> Vector sh a
Vector.constant sh
sh a
a
   identityOrder :: Order -> sh -> Matrix (Scale sh) a
identityOrder Order
_ sh
sh = sh -> a -> Matrix (Scale sh) a
forall shape a. shape -> a -> Matrix (Scale shape) a
Type.Scale sh
sh a
forall a. Floating a => a
Scalar.one
   takeDiagonal :: Matrix (Scale sh) a -> Vector sh a
takeDiagonal (Type.Scale sh a) = sh -> a -> Vector sh a
forall sh a. (C sh, Floating a) => sh -> a -> Vector sh a
Vector.constant sh
sh a
a

instance (Shape.C sh) => SquareShape (Perm.Permutation sh) where
   toSquare :: Matrix (Permutation sh) a -> Square sh a
toSquare = Matrix (Permutation sh) a -> Square sh a
forall sh a.
(C sh, Floating a) =>
Matrix (Permutation sh) a -> Square sh a
Permutation.toMatrix
   identityOrder :: Order -> sh -> Matrix (Permutation sh) a
identityOrder Order
_ = sh -> Matrix (Permutation sh) a
forall sh a. C sh => sh -> Matrix (Permutation sh) a
Permutation.identity
   takeDiagonal :: Matrix (Permutation sh) a -> Vector sh a
takeDiagonal = Permutation sh -> Vector sh a
forall sh a. (C sh, Floating a) => Permutation sh -> Vector sh a
Perm.takeDiagonal (Permutation sh -> Vector sh a)
-> (Matrix (Permutation sh) a -> Permutation sh)
-> Matrix (Permutation sh) a
-> Vector sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix (Permutation sh) a -> Permutation sh
forall sh a. C sh => Matrix (Permutation sh) a -> Permutation sh
Permutation.toPermutation


identityFrom ::
   (Plain.SquareShape shape, ArrMatrix.ShapeOrder shape, Class.Floating a) =>
   ArrayMatrix shape a -> ArrayMatrix shape a
identityFrom :: ArrayMatrix shape a -> ArrayMatrix shape a
identityFrom ArrayMatrix shape a
m =
   Order -> WidthOf shape -> ArrayMatrix shape a
forall typ sh a.
(SquareShape typ, HeightOf typ ~ sh, Floating a) =>
Order -> sh -> Matrix typ a
identityOrder (shape -> Order
forall shape. ShapeOrder shape => shape -> Order
ArrMatrix.shapeOrder (shape -> Order) -> shape -> Order
forall a b. (a -> b) -> a -> b
$ ArrayMatrix shape a -> shape
forall sh a. ArrayMatrix sh a -> sh
ArrMatrix.shape ArrayMatrix shape a
m) (ArrayMatrix shape a -> HeightOf (Array shape)
forall typ a. Box typ => Matrix typ a -> HeightOf typ
Type.height ArrayMatrix shape a
m)

identityFromHeight ::
   (ArrMatrix.ShapeOrder shape, MatrixShape.Box shape,
    MatrixShape.HeightOf shape ~ Type.HeightOf typ, SquareShape typ,
    Class.Floating a) =>
   ArrayMatrix shape a -> Type.Matrix typ a
identityFromHeight :: ArrayMatrix shape a -> Matrix typ a
identityFromHeight ArrayMatrix shape a
m =
   Order -> HeightOf typ -> Matrix typ a
forall typ sh a.
(SquareShape typ, HeightOf typ ~ sh, Floating a) =>
Order -> sh -> Matrix typ a
identityOrder (shape -> Order
forall shape. ShapeOrder shape => shape -> Order
ArrMatrix.shapeOrder (shape -> Order) -> shape -> Order
forall a b. (a -> b) -> a -> b
$ ArrayMatrix shape a -> shape
forall sh a. ArrayMatrix sh a -> sh
ArrMatrix.shape ArrayMatrix shape a
m) (ArrayMatrix shape a -> HeightOf (Array shape)
forall typ a. Box typ => Matrix typ a -> HeightOf typ
Type.height ArrayMatrix shape a
m)

identityFromWidth ::
   (ArrMatrix.ShapeOrder shape, MatrixShape.Box shape,
    MatrixShape.WidthOf shape ~ Type.HeightOf typ, SquareShape typ,
    Class.Floating a) =>
   ArrayMatrix shape a -> Type.Matrix typ a
identityFromWidth :: ArrayMatrix shape a -> Matrix typ a
identityFromWidth ArrayMatrix shape a
m =
   Order -> HeightOf typ -> Matrix typ a
forall typ sh a.
(SquareShape typ, HeightOf typ ~ sh, Floating a) =>
Order -> sh -> Matrix typ a
identityOrder (shape -> Order
forall shape. ShapeOrder shape => shape -> Order
ArrMatrix.shapeOrder (shape -> Order) -> shape -> Order
forall a b. (a -> b) -> a -> b
$ ArrayMatrix shape a -> shape
forall sh a. ArrayMatrix sh a -> sh
ArrMatrix.shape ArrayMatrix shape a
m) (ArrayMatrix shape a -> WidthOf (Array shape)
forall typ a. Box typ => Matrix typ a -> WidthOf typ
Type.width ArrayMatrix shape a
m)

trace ::
   (SquareShape typ, Type.HeightOf typ ~ sh, Shape.C sh, Class.Floating a) =>
   Type.Matrix typ a -> a
trace :: Matrix typ a -> a
trace = Vector sh a -> a
forall sh a. (C sh, Floating a) => Vector sh a -> a
Vector.sum (Vector sh a -> a)
-> (Matrix typ a -> Vector sh a) -> Matrix typ a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix typ a -> Vector sh a
forall typ sh a.
(SquareShape typ, HeightOf typ ~ sh, Floating a) =>
Matrix typ a -> Vector sh a
takeDiagonal