{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Numeric.LAPACK.Matrix.Hermitian (
   Hermitian,
   Transposition(..),

   size,
   fromList,
   autoFromList,
   identity,
   diagonal,
   takeDiagonal,
   forceOrder,

   stack, (*%%%#),
   split,
   takeTopLeft,
   takeTopRight,
   takeBottomRight,

   multiplyVector,
   square,
   multiplyFull,
   outer,
   sumRank1, sumRank1NonEmpty,
   sumRank2, sumRank2NonEmpty,

   toSquare, fromSymmetric,
   gramian,            gramianAdjoint,
   congruenceDiagonal, congruenceDiagonalAdjoint,
   congruence,         congruenceAdjoint,
   anticommutator,     anticommutatorAdjoint,
   addAdjoint,

   solve,
   inverse,
   determinant,

   eigenvalues,
   eigensystem,
   ) where

import qualified Numeric.LAPACK.Matrix.Hermitian.Eigen as Eigen
import qualified Numeric.LAPACK.Matrix.Hermitian.Linear as Linear
import qualified Numeric.LAPACK.Matrix.Hermitian.Basic as Basic
import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix
import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape
import qualified Numeric.LAPACK.Matrix.Extent as Extent
import Numeric.LAPACK.Matrix.Array.Triangular (Hermitian, Symmetric)
import Numeric.LAPACK.Matrix.Array (Full, General, Square)
import Numeric.LAPACK.Matrix.Shape.Private (Order)
import Numeric.LAPACK.Matrix.Modifier (Transposition(NonTransposed, Transposed))
import Numeric.LAPACK.Matrix.Private (ShapeInt)
import Numeric.LAPACK.Vector (Vector)
import Numeric.LAPACK.Scalar (RealOf, one)

import qualified Numeric.Netlib.Class as Class

import qualified Data.Array.Comfort.Storable.Unchecked as Array
import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Shape ((:+:))

import Foreign.Storable (Storable)

import qualified Data.NonEmpty as NonEmpty
import Data.Tuple.HT (mapFst)


size :: Hermitian sh a -> sh
size :: Hermitian sh a -> sh
size = Hermitian sh -> sh
forall size. Hermitian size -> size
MatrixShape.hermitianSize (Hermitian sh -> sh)
-> (Hermitian sh a -> Hermitian sh) -> Hermitian sh a -> sh
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hermitian sh a -> Hermitian sh
forall sh a. ArrayMatrix sh a -> sh
ArrMatrix.shape

fromList :: (Shape.C sh, Storable a) => Order -> sh -> [a] -> Hermitian sh a
fromList :: Order -> sh -> [a] -> Hermitian sh a
fromList Order
order sh
sh = Array (Hermitian sh) a -> Hermitian sh a
forall shA a. Array shA a -> ArrayMatrix shA a
ArrMatrix.lift0 (Array (Hermitian sh) a -> Hermitian sh a)
-> ([a] -> Array (Hermitian sh) a) -> [a] -> Hermitian sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Order -> sh -> [a] -> Array (Hermitian sh) a
forall sh a.
(C sh, Storable a) =>
Order -> sh -> [a] -> Hermitian sh a
Basic.fromList Order
order sh
sh

autoFromList :: (Storable a) => Order -> [a] -> Hermitian ShapeInt a
autoFromList :: Order -> [a] -> Hermitian ShapeInt a
autoFromList Order
order = Array (Hermitian ShapeInt) a -> Hermitian ShapeInt a
forall shA a. Array shA a -> ArrayMatrix shA a
ArrMatrix.lift0 (Array (Hermitian ShapeInt) a -> Hermitian ShapeInt a)
-> ([a] -> Array (Hermitian ShapeInt) a)
-> [a]
-> Hermitian ShapeInt a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Order -> [a] -> Array (Hermitian ShapeInt) a
forall a. Storable a => Order -> [a] -> Hermitian ShapeInt a
Basic.autoFromList Order
order

identity :: (Shape.C sh, Class.Floating a) => Order -> sh -> Hermitian sh a
identity :: Order -> sh -> Hermitian sh a
identity Order
order = Array (Hermitian sh) a -> Hermitian sh a
forall shA a. Array shA a -> ArrayMatrix shA a
ArrMatrix.lift0 (Array (Hermitian sh) a -> Hermitian sh a)
-> (sh -> Array (Hermitian sh) a) -> sh -> Hermitian sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Order -> sh -> Array (Hermitian sh) a
forall sh a. (C sh, Floating a) => Order -> sh -> Hermitian sh a
Basic.identity Order
order

diagonal ::
   (Shape.C sh, Class.Floating a) =>
   Order -> Vector sh (RealOf a) -> Hermitian sh a
diagonal :: Order -> Vector sh (RealOf a) -> Hermitian sh a
diagonal Order
order = Array (Hermitian sh) a -> Hermitian sh a
forall shA a. Array shA a -> ArrayMatrix shA a
ArrMatrix.lift0 (Array (Hermitian sh) a -> Hermitian sh a)
-> (Vector sh (RealOf a) -> Array (Hermitian sh) a)
-> Vector sh (RealOf a)
-> Hermitian sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Order -> Vector sh (RealOf a) -> Array (Hermitian sh) a
forall sh a.
(C sh, Floating a) =>
Order -> Vector sh (RealOf a) -> Hermitian sh a
Basic.diagonal Order
order

takeDiagonal ::
   (Shape.C sh, Class.Floating a) =>
   Hermitian sh a -> Vector sh (RealOf a)
takeDiagonal :: Hermitian sh a -> Vector sh (RealOf a)
takeDiagonal = Hermitian sh a -> Vector sh (RealOf a)
forall sh a.
(C sh, Floating a) =>
Hermitian sh a -> Vector sh (RealOf a)
Basic.takeDiagonal (Hermitian sh a -> Vector sh (RealOf a))
-> (Hermitian sh a -> Hermitian sh a)
-> Hermitian sh a
-> Vector sh (RealOf a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hermitian sh a -> Hermitian sh a
forall sh a. ArrayMatrix sh a -> Array sh a
ArrMatrix.toVector

forceOrder ::
   (Shape.C sh, Class.Floating a) =>
   Order -> Hermitian sh a -> Hermitian sh a
forceOrder :: Order -> Hermitian sh a -> Hermitian sh a
forceOrder = (Array (Hermitian sh) a -> Array (Hermitian sh) a)
-> Hermitian sh a -> Hermitian sh a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 ((Array (Hermitian sh) a -> Array (Hermitian sh) a)
 -> Hermitian sh a -> Hermitian sh a)
-> (Order -> Array (Hermitian sh) a -> Array (Hermitian sh) a)
-> Order
-> Hermitian sh a
-> Hermitian sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Order -> Array (Hermitian sh) a -> Array (Hermitian sh) a
forall sh a.
(C sh, Floating a) =>
Order -> Hermitian sh a -> Hermitian sh a
Basic.forceOrder

{- |
> toSquare (stack a b c)
>
> =
>
> toSquare a ||| b
> ===
> adjoint b ||| toSquare c

It holds @order (stack a b c) = order b@.
The function is most efficient when the order of all blocks match.
-}
stack ::
   (Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>
   Hermitian sh0 a -> General sh0 sh1 a -> Hermitian sh1 a ->
   Hermitian (sh0:+:sh1) a
stack :: Hermitian sh0 a
-> General sh0 sh1 a
-> Hermitian sh1 a
-> Hermitian (sh0 :+: sh1) a
stack = (Array (Hermitian sh0) a
 -> Array (General sh0 sh1) a
 -> Array (Hermitian sh1) a
 -> Array (Hermitian (sh0 :+: sh1)) a)
-> Hermitian sh0 a
-> General sh0 sh1 a
-> Hermitian sh1 a
-> Hermitian (sh0 :+: sh1) a
forall shA a shB b shC c shD d.
(Array shA a -> Array shB b -> Array shC c -> Array shD d)
-> ArrayMatrix shA a
-> ArrayMatrix shB b
-> ArrayMatrix shC c
-> ArrayMatrix shD d
ArrMatrix.lift3 Array (Hermitian sh0) a
-> Array (General sh0 sh1) a
-> Array (Hermitian sh1) a
-> Array (Hermitian (sh0 :+: sh1)) a
forall sh0 sh1 a.
(C sh0, Eq sh0, C sh1, Eq sh1, Floating a) =>
Hermitian sh0 a
-> General sh0 sh1 a
-> Hermitian sh1 a
-> Hermitian (sh0 :+: sh1) a
Basic.stack

infixr 2 *%%%#

(*%%%#) ::
   (Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>
   (Hermitian sh0 a, General sh0 sh1 a) -> Hermitian sh1 a ->
   Hermitian (sh0:+:sh1) a
*%%%# :: (Hermitian sh0 a, General sh0 sh1 a)
-> Hermitian sh1 a -> Hermitian (sh0 :+: sh1) a
(*%%%#) = (Hermitian sh0 a
 -> General sh0 sh1 a
 -> Hermitian sh1 a
 -> Hermitian (sh0 :+: sh1) a)
-> (Hermitian sh0 a, General sh0 sh1 a)
-> Hermitian sh1 a
-> Hermitian (sh0 :+: sh1) a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Hermitian sh0 a
-> General sh0 sh1 a
-> Hermitian sh1 a
-> Hermitian (sh0 :+: sh1) a
forall sh0 sh1 a.
(C sh0, Eq sh0, C sh1, Eq sh1, Floating a) =>
Hermitian sh0 a
-> General sh0 sh1 a
-> Hermitian sh1 a
-> Hermitian (sh0 :+: sh1) a
stack


split ::
   (Shape.C sh0, Shape.C sh1, Class.Floating a) =>
   Hermitian (sh0:+:sh1) a ->
   (Hermitian sh0 a, General sh0 sh1 a, Hermitian sh1 a)
split :: Hermitian (sh0 :+: sh1) a
-> (Hermitian sh0 a, General sh0 sh1 a, Hermitian sh1 a)
split Hermitian (sh0 :+: sh1) a
a = (Hermitian (sh0 :+: sh1) a -> Hermitian sh0 a
forall sh0 sh1 a.
(C sh0, C sh1, Floating a) =>
Hermitian (sh0 :+: sh1) a -> Hermitian sh0 a
takeTopLeft Hermitian (sh0 :+: sh1) a
a, Hermitian (sh0 :+: sh1) a -> General sh0 sh1 a
forall sh0 sh1 a.
(C sh0, C sh1, Floating a) =>
Hermitian (sh0 :+: sh1) a -> General sh0 sh1 a
takeTopRight Hermitian (sh0 :+: sh1) a
a, Hermitian (sh0 :+: sh1) a -> Hermitian sh1 a
forall sh0 sh1 a.
(C sh0, C sh1, Floating a) =>
Hermitian (sh0 :+: sh1) a -> Hermitian sh1 a
takeBottomRight Hermitian (sh0 :+: sh1) a
a)

takeTopLeft ::
   (Shape.C sh0, Shape.C sh1, Class.Floating a) =>
   Hermitian (sh0:+:sh1) a -> Hermitian sh0 a
takeTopLeft :: Hermitian (sh0 :+: sh1) a -> Hermitian sh0 a
takeTopLeft = (Array (Hermitian (sh0 :+: sh1)) a -> Array (Hermitian sh0) a)
-> Hermitian (sh0 :+: sh1) a -> Hermitian sh0 a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 Array (Hermitian (sh0 :+: sh1)) a -> Array (Hermitian sh0) a
forall sh0 sh1 a.
(C sh0, C sh1, Floating a) =>
Hermitian (sh0 :+: sh1) a -> Hermitian sh0 a
Basic.takeTopLeft

takeTopRight ::
   (Shape.C sh0, Shape.C sh1, Class.Floating a) =>
   Hermitian (sh0:+:sh1) a -> General sh0 sh1 a
takeTopRight :: Hermitian (sh0 :+: sh1) a -> General sh0 sh1 a
takeTopRight = (Array (Hermitian (sh0 :+: sh1)) a -> Array (General sh0 sh1) a)
-> Hermitian (sh0 :+: sh1) a -> General sh0 sh1 a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 Array (Hermitian (sh0 :+: sh1)) a -> Array (General sh0 sh1) a
forall sh0 sh1 a.
(C sh0, C sh1, Floating a) =>
Hermitian (sh0 :+: sh1) a -> General sh0 sh1 a
Basic.takeTopRight

takeBottomRight ::
   (Shape.C sh0, Shape.C sh1, Class.Floating a) =>
   Hermitian (sh0:+:sh1) a -> Hermitian sh1 a
takeBottomRight :: Hermitian (sh0 :+: sh1) a -> Hermitian sh1 a
takeBottomRight = (Array (Hermitian (sh0 :+: sh1)) a -> Array (Hermitian sh1) a)
-> Hermitian (sh0 :+: sh1) a -> Hermitian sh1 a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 Array (Hermitian (sh0 :+: sh1)) a -> Array (Hermitian sh1) a
forall sh0 sh1 a.
(C sh0, C sh1, Floating a) =>
Hermitian (sh0 :+: sh1) a -> Hermitian sh1 a
Basic.takeBottomRight


multiplyVector ::
   (Shape.C sh, Eq sh, Class.Floating a) =>
   Transposition -> Hermitian sh a -> Vector sh a -> Vector sh a
multiplyVector :: Transposition -> Hermitian sh a -> Vector sh a -> Vector sh a
multiplyVector Transposition
order = Transposition -> Hermitian sh a -> Vector sh a -> Vector sh a
forall sh a.
(C sh, Eq sh, Floating a) =>
Transposition -> Hermitian sh a -> Vector sh a -> Vector sh a
Basic.multiplyVector Transposition
order (Hermitian sh a -> Vector sh a -> Vector sh a)
-> (Hermitian sh a -> Hermitian sh a)
-> Hermitian sh a
-> Vector sh a
-> Vector sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hermitian sh a -> Hermitian sh a
forall sh a. ArrayMatrix sh a -> Array sh a
ArrMatrix.toVector

square ::
   (Shape.C sh, Eq sh, Class.Floating a) => Hermitian sh a -> Hermitian sh a
square :: Hermitian sh a -> Hermitian sh a
square = (Array (Hermitian sh) a -> Array (Hermitian sh) a)
-> Hermitian sh a -> Hermitian sh a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 Array (Hermitian sh) a -> Array (Hermitian sh) a
forall sh a. (C sh, Floating a) => Hermitian sh a -> Hermitian sh a
Basic.square

multiplyFull ::
   (Extent.C vert, Extent.C horiz,
    Shape.C height, Eq height, Shape.C width,
    Class.Floating a) =>
   Transposition -> Hermitian height a ->
   Full vert horiz height width a ->
   Full vert horiz height width a
multiplyFull :: Transposition
-> Hermitian height a
-> Full vert horiz height width a
-> Full vert horiz height width a
multiplyFull = (Array (Hermitian height) a
 -> Array (Full vert horiz height width) a
 -> Array (Full vert horiz height width) a)
-> Hermitian height a
-> Full vert horiz height width a
-> Full vert horiz height width a
forall shA a shB b shC c.
(Array shA a -> Array shB b -> Array shC c)
-> ArrayMatrix shA a -> ArrayMatrix shB b -> ArrayMatrix shC c
ArrMatrix.lift2 ((Array (Hermitian height) a
  -> Array (Full vert horiz height width) a
  -> Array (Full vert horiz height width) a)
 -> Hermitian height a
 -> Full vert horiz height width a
 -> Full vert horiz height width a)
-> (Transposition
    -> Array (Hermitian height) a
    -> Array (Full vert horiz height width) a
    -> Array (Full vert horiz height width) a)
-> Transposition
-> Hermitian height a
-> Full vert horiz height width a
-> Full vert horiz height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transposition
-> Array (Hermitian height) a
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
forall vert horiz height width a.
(C vert, C horiz, C height, Eq height, C width, Floating a) =>
Transposition
-> Hermitian height a
-> Full vert horiz height width a
-> Full vert horiz height width a
Basic.multiplyFull

outer ::
   (Shape.C sh, Class.Floating a) => Order -> Vector sh a -> Hermitian sh a
outer :: Order -> Vector sh a -> Hermitian sh a
outer Order
order = Array (Hermitian sh) a -> Hermitian sh a
forall shA a. Array shA a -> ArrayMatrix shA a
ArrMatrix.lift0 (Array (Hermitian sh) a -> Hermitian sh a)
-> (Vector sh a -> Array (Hermitian sh) a)
-> Vector sh a
-> Hermitian sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Order -> Vector sh a -> Array (Hermitian sh) a
forall sh a.
(C sh, Floating a) =>
Order -> Vector sh a -> Hermitian sh a
Basic.outer Order
order

sumRank1 ::
   (Shape.C sh, Eq sh, Class.Floating a) =>
   Order -> sh -> [(RealOf a, Vector sh a)] -> Hermitian sh a
sumRank1 :: Order -> sh -> [(RealOf a, Vector sh a)] -> Hermitian sh a
sumRank1 Order
order sh
sh = Array (Hermitian sh) a -> Hermitian sh a
forall shA a. Array shA a -> ArrayMatrix shA a
ArrMatrix.lift0 (Array (Hermitian sh) a -> Hermitian sh a)
-> ([(RealOf a, Vector sh a)] -> Array (Hermitian sh) a)
-> [(RealOf a, Vector sh a)]
-> Hermitian sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Order -> sh -> [(RealOf a, Vector sh a)] -> Array (Hermitian sh) a
forall sh a.
(C sh, Eq sh, Floating a) =>
Order -> sh -> [(RealOf a, Vector sh a)] -> Hermitian sh a
Basic.sumRank1 Order
order sh
sh

sumRank1NonEmpty ::
   (Shape.C sh, Eq sh, Class.Floating a) =>
   Order -> NonEmpty.T [] (RealOf a, Vector sh a) -> Hermitian sh a
sumRank1NonEmpty :: Order -> T [] (RealOf a, Vector sh a) -> Hermitian sh a
sumRank1NonEmpty Order
order (NonEmpty.Cons (RealOf a, Vector sh a)
x [(RealOf a, Vector sh a)]
xs) =
   Order -> sh -> [(RealOf a, Vector sh a)] -> Hermitian sh a
forall sh a.
(C sh, Eq sh, Floating a) =>
Order -> sh -> [(RealOf a, Vector sh a)] -> Hermitian sh a
sumRank1 Order
order (Vector sh a -> sh
forall sh a. Array sh a -> sh
Array.shape (Vector sh a -> sh) -> Vector sh a -> sh
forall a b. (a -> b) -> a -> b
$ (RealOf a, Vector sh a) -> Vector sh a
forall a b. (a, b) -> b
snd (RealOf a, Vector sh a)
x) ((RealOf a, Vector sh a)
x(RealOf a, Vector sh a)
-> [(RealOf a, Vector sh a)] -> [(RealOf a, Vector sh a)]
forall a. a -> [a] -> [a]
:[(RealOf a, Vector sh a)]
xs)

sumRank2 ::
   (Shape.C sh, Eq sh, Class.Floating a) =>
   Order -> sh -> [(a, (Vector sh a, Vector sh a))] -> Hermitian sh a
sumRank2 :: Order -> sh -> [(a, (Vector sh a, Vector sh a))] -> Hermitian sh a
sumRank2 Order
order sh
sh = Array (Hermitian sh) a -> Hermitian sh a
forall shA a. Array shA a -> ArrayMatrix shA a
ArrMatrix.lift0 (Array (Hermitian sh) a -> Hermitian sh a)
-> ([(a, (Vector sh a, Vector sh a))] -> Array (Hermitian sh) a)
-> [(a, (Vector sh a, Vector sh a))]
-> Hermitian sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Order
-> sh
-> [(a, (Vector sh a, Vector sh a))]
-> Array (Hermitian sh) a
forall sh a.
(C sh, Eq sh, Floating a) =>
Order -> sh -> [(a, (Vector sh a, Vector sh a))] -> Hermitian sh a
Basic.sumRank2 Order
order sh
sh

sumRank2NonEmpty ::
   (Shape.C sh, Eq sh, Class.Floating a) =>
   Order -> NonEmpty.T [] (a, (Vector sh a, Vector sh a)) -> Hermitian sh a
sumRank2NonEmpty :: Order -> T [] (a, (Vector sh a, Vector sh a)) -> Hermitian sh a
sumRank2NonEmpty Order
order (NonEmpty.Cons (a, (Vector sh a, Vector sh a))
xy [(a, (Vector sh a, Vector sh a))]
xys) =
   Order -> sh -> [(a, (Vector sh a, Vector sh a))] -> Hermitian sh a
forall sh a.
(C sh, Eq sh, Floating a) =>
Order -> sh -> [(a, (Vector sh a, Vector sh a))] -> Hermitian sh a
sumRank2 Order
order (Vector sh a -> sh
forall sh a. Array sh a -> sh
Array.shape (Vector sh a -> sh) -> Vector sh a -> sh
forall a b. (a -> b) -> a -> b
$ (Vector sh a, Vector sh a) -> Vector sh a
forall a b. (a, b) -> a
fst ((Vector sh a, Vector sh a) -> Vector sh a)
-> (Vector sh a, Vector sh a) -> Vector sh a
forall a b. (a -> b) -> a -> b
$ (a, (Vector sh a, Vector sh a)) -> (Vector sh a, Vector sh a)
forall a b. (a, b) -> b
snd (a, (Vector sh a, Vector sh a))
xy) ((a, (Vector sh a, Vector sh a))
xy(a, (Vector sh a, Vector sh a))
-> [(a, (Vector sh a, Vector sh a))]
-> [(a, (Vector sh a, Vector sh a))]
forall a. a -> [a] -> [a]
:[(a, (Vector sh a, Vector sh a))]
xys)


toSquare ::
   (Shape.C sh, Class.Floating a) => Hermitian sh a -> Square sh a
toSquare :: Hermitian sh a -> Square sh a
toSquare = (Array (Hermitian sh) a -> Array (Square sh) a)
-> Hermitian 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 (Hermitian sh) a -> Array (Square sh) a
forall sh a. (C sh, Floating a) => Hermitian sh a -> Square sh a
Basic.toSquare

fromSymmetric :: (Shape.C sh, Class.Real a) => Symmetric sh a -> Hermitian sh a
fromSymmetric :: Symmetric sh a -> Hermitian sh a
fromSymmetric =
   (Array (Symmetric sh) a -> Array (Hermitian sh) a)
-> Symmetric sh a -> Hermitian sh a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 ((Array (Symmetric sh) a -> Array (Hermitian sh) a)
 -> Symmetric sh a -> Hermitian sh a)
-> (Array (Symmetric sh) a -> Array (Hermitian sh) a)
-> Symmetric sh a
-> Hermitian sh a
forall a b. (a -> b) -> a -> b
$ (Symmetric sh -> Hermitian sh)
-> Array (Symmetric sh) a -> Array (Hermitian sh) a
forall sh0 sh1 a. (sh0 -> sh1) -> Array sh0 a -> Array sh1 a
Array.mapShape Symmetric sh -> Hermitian sh
forall size. Symmetric size -> Hermitian size
MatrixShape.hermitianFromSymmetric


{- |
gramian A = A^H * A
-}
gramian ::
   (Shape.C height, Shape.C width, Class.Floating a) =>
   General height width a -> Hermitian width a
gramian :: General height width a -> Hermitian width a
gramian = (Array (General height width) a -> Array (Hermitian width) a)
-> General height width a -> Hermitian width a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 Array (General height width) a -> Array (Hermitian width) a
forall height width a.
(C height, C width, Floating a) =>
General height width a -> Hermitian width a
Basic.gramian

{- |
gramianAdjoint A = A * A^H = gramian (A^H)
-}
gramianAdjoint ::
   (Shape.C height, Shape.C width, Class.Floating a) =>
   General height width a -> Hermitian height a
gramianAdjoint :: General height width a -> Hermitian height a
gramianAdjoint = (Array (General height width) a -> Array (Hermitian height) a)
-> General height width a -> Hermitian height a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 Array (General height width) a -> Array (Hermitian height) a
forall height width a.
(C height, C width, Floating a) =>
General height width a -> Hermitian height a
Basic.gramianAdjoint

{- |
congruenceDiagonal D A = A^H * D * A
-}
congruenceDiagonal ::
   (Shape.C height, Eq height, Shape.C width, Class.Floating a) =>
   Vector height (RealOf a) -> General height width a -> Hermitian width a
congruenceDiagonal :: Vector height (RealOf a)
-> General height width a -> Hermitian width a
congruenceDiagonal = (Array (General height width) a -> Array (Hermitian width) a)
-> General height width a -> Hermitian width a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 ((Array (General height width) a -> Array (Hermitian width) a)
 -> General height width a -> Hermitian width a)
-> (Vector height (RealOf a)
    -> Array (General height width) a -> Array (Hermitian width) a)
-> Vector height (RealOf a)
-> General height width a
-> Hermitian width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector height (RealOf a)
-> Array (General height width) a -> Array (Hermitian width) a
forall height width a.
(C height, Eq height, C width, Floating a) =>
Vector height (RealOf a)
-> General height width a -> Hermitian width a
Basic.congruenceDiagonal

{- |
congruenceDiagonalAdjoint A D = A * D * A^H
-}
congruenceDiagonalAdjoint ::
   (Shape.C height, Shape.C width, Eq width, Class.Floating a) =>
   General height width a -> Vector width (RealOf a) -> Hermitian height a
congruenceDiagonalAdjoint :: General height width a
-> Vector width (RealOf a) -> Hermitian height a
congruenceDiagonalAdjoint General height width a
a =
   Array (Hermitian height) a -> Hermitian height a
forall shA a. Array shA a -> ArrayMatrix shA a
ArrMatrix.lift0 (Array (Hermitian height) a -> Hermitian height a)
-> (Vector width (RealOf a) -> Array (Hermitian height) a)
-> Vector width (RealOf a)
-> Hermitian height a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. General height width a
-> Vector width (RealOf a) -> Array (Hermitian height) a
forall height width a.
(C height, C width, Eq width, Floating a) =>
General height width a
-> Vector width (RealOf a) -> Hermitian height a
Basic.congruenceDiagonalAdjoint (General height width a -> General height width a
forall sh a. ArrayMatrix sh a -> Array sh a
ArrMatrix.toVector General height width a
a)

{- |
congruence B A = A^H * B * A
-}
congruence ::
   (Shape.C height, Eq height, Shape.C width, Class.Floating a) =>
   Hermitian height a -> General height width a -> Hermitian width a
congruence :: Hermitian height a -> General height width a -> Hermitian width a
congruence = (Array (Hermitian height) a
 -> Array (General height width) a -> Array (Hermitian width) a)
-> Hermitian height a
-> General height width a
-> Hermitian width a
forall shA a shB b shC c.
(Array shA a -> Array shB b -> Array shC c)
-> ArrayMatrix shA a -> ArrayMatrix shB b -> ArrayMatrix shC c
ArrMatrix.lift2 Array (Hermitian height) a
-> Array (General height width) a -> Array (Hermitian width) a
forall height width a.
(C height, Eq height, C width, Floating a) =>
Hermitian height a -> General height width a -> Hermitian width a
Basic.congruence

{- |
congruenceAdjoint B A = A * B * A^H
-}
congruenceAdjoint ::
   (Shape.C height, Shape.C width, Eq width, Class.Floating a) =>
   General height width a -> Hermitian width a -> Hermitian height a
congruenceAdjoint :: General height width a -> Hermitian width a -> Hermitian height a
congruenceAdjoint = (Array (General height width) a
 -> Array (Hermitian width) a -> Array (Hermitian height) a)
-> General height width a
-> Hermitian width a
-> Hermitian height a
forall shA a shB b shC c.
(Array shA a -> Array shB b -> Array shC c)
-> ArrayMatrix shA a -> ArrayMatrix shB b -> ArrayMatrix shC c
ArrMatrix.lift2 Array (General height width) a
-> Array (Hermitian width) a -> Array (Hermitian height) a
forall height width a.
(C height, C width, Eq width, Floating a) =>
General height width a -> Hermitian width a -> Hermitian height a
Basic.congruenceAdjoint


{- |
anticommutator A B  =  A^H * B + B^H * A

Not exactly a matrix anticommutator,
thus I like to call it Hermitian anticommutator.
-}
anticommutator ::
   (Extent.C vert, Extent.C horiz,
    Shape.C height, Eq height, Shape.C width, Eq width,
    Class.Floating a) =>
   Full vert horiz height width a ->
   Full vert horiz height width a -> Hermitian width a
anticommutator :: Full vert horiz height width a
-> Full vert horiz height width a -> Hermitian width a
anticommutator = (Array (Full vert horiz height width) a
 -> Array (Full vert horiz height width) a
 -> Array (Hermitian width) a)
-> Full vert horiz height width a
-> Full vert horiz height width a
-> Hermitian width a
forall shA a shB b shC c.
(Array shA a -> Array shB b -> Array shC c)
-> ArrayMatrix shA a -> ArrayMatrix shB b -> ArrayMatrix shC c
ArrMatrix.lift2 ((Array (Full vert horiz height width) a
  -> Array (Full vert horiz height width) a
  -> Array (Hermitian width) a)
 -> Full vert horiz height width a
 -> Full vert horiz height width a
 -> Hermitian width a)
-> (Array (Full vert horiz height width) a
    -> Array (Full vert horiz height width) a
    -> Array (Hermitian width) a)
-> Full vert horiz height width a
-> Full vert horiz height width a
-> Hermitian width a
forall a b. (a -> b) -> a -> b
$ a
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
-> Array (Hermitian width) a
forall vert horiz height width a.
(C vert, C horiz, C height, Eq height, C width, Eq width,
 Floating a) =>
a
-> Full vert horiz height width a
-> Full vert horiz height width a
-> Hermitian width a
Basic.scaledAnticommutator a
forall a. Floating a => a
one

{- |
anticommutatorAdjoint A B
   = A * B^H + B * A^H
   = anticommutator (adjoint A) (adjoint B)
-}
anticommutatorAdjoint ::
   (Extent.C vert, Extent.C horiz,
    Shape.C height, Eq height, Shape.C width, Eq width,
    Class.Floating a) =>
   Full vert horiz height width a ->
   Full vert horiz height width a -> Hermitian height a
anticommutatorAdjoint :: Full vert horiz height width a
-> Full vert horiz height width a -> Hermitian height a
anticommutatorAdjoint = (Array (Full vert horiz height width) a
 -> Array (Full vert horiz height width) a
 -> Array (Hermitian height) a)
-> Full vert horiz height width a
-> Full vert horiz height width a
-> Hermitian height a
forall shA a shB b shC c.
(Array shA a -> Array shB b -> Array shC c)
-> ArrayMatrix shA a -> ArrayMatrix shB b -> ArrayMatrix shC c
ArrMatrix.lift2 ((Array (Full vert horiz height width) a
  -> Array (Full vert horiz height width) a
  -> Array (Hermitian height) a)
 -> Full vert horiz height width a
 -> Full vert horiz height width a
 -> Hermitian height a)
-> (Array (Full vert horiz height width) a
    -> Array (Full vert horiz height width) a
    -> Array (Hermitian height) a)
-> Full vert horiz height width a
-> Full vert horiz height width a
-> Hermitian height a
forall a b. (a -> b) -> a -> b
$ a
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
-> Array (Hermitian height) a
forall vert horiz height width a.
(C vert, C horiz, C height, Eq height, C width, Eq width,
 Floating a) =>
a
-> Full vert horiz height width a
-> Full vert horiz height width a
-> Hermitian height a
Basic.scaledAnticommutatorAdjoint a
forall a. Floating a => a
one

{- |
scaledAnticommutator alpha A B  =  alpha * A^H * B + conj alpha * B^H * A
-}
_scaledAnticommutator ::
   (Extent.C vert, Extent.C horiz,
    Shape.C height, Eq height, Shape.C width, Eq width,
    Class.Floating a) =>
   a ->
   Full vert horiz height width a ->
   Full vert horiz height width a -> Hermitian width a
_scaledAnticommutator :: a
-> Full vert horiz height width a
-> Full vert horiz height width a
-> Hermitian width a
_scaledAnticommutator = (Array (Full vert horiz height width) a
 -> Array (Full vert horiz height width) a
 -> Array (Hermitian width) a)
-> Full vert horiz height width a
-> Full vert horiz height width a
-> Hermitian width a
forall shA a shB b shC c.
(Array shA a -> Array shB b -> Array shC c)
-> ArrayMatrix shA a -> ArrayMatrix shB b -> ArrayMatrix shC c
ArrMatrix.lift2 ((Array (Full vert horiz height width) a
  -> Array (Full vert horiz height width) a
  -> Array (Hermitian width) a)
 -> Full vert horiz height width a
 -> Full vert horiz height width a
 -> Hermitian width a)
-> (a
    -> Array (Full vert horiz height width) a
    -> Array (Full vert horiz height width) a
    -> Array (Hermitian width) a)
-> a
-> Full vert horiz height width a
-> Full vert horiz height width a
-> Hermitian width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
-> Array (Hermitian width) a
forall vert horiz height width a.
(C vert, C horiz, C height, Eq height, C width, Eq width,
 Floating a) =>
a
-> Full vert horiz height width a
-> Full vert horiz height width a
-> Hermitian width a
Basic.scaledAnticommutator

{- |
addAdjoint A = A^H + A
-}
addAdjoint :: (Shape.C sh, Class.Floating a) => Square sh a -> Hermitian sh a
addAdjoint :: Square sh a -> Hermitian sh a
addAdjoint = (Array (Square sh) a -> Array (Hermitian sh) a)
-> Square sh a -> Hermitian sh a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 Array (Square sh) a -> Array (Hermitian sh) a
forall sh a. (C sh, Floating a) => Square sh a -> Hermitian sh a
Basic.addAdjoint



solve ::
   (Extent.C vert, Extent.C horiz,
    Shape.C sh, Eq sh, Shape.C nrhs, Class.Floating a) =>
   Hermitian sh a -> Full vert horiz sh nrhs a -> Full vert horiz sh nrhs a
solve :: Hermitian sh a
-> Full vert horiz sh nrhs a -> Full vert horiz sh nrhs a
solve = (Array (Hermitian sh) a
 -> Array (Full vert horiz sh nrhs) a
 -> Array (Full vert horiz sh nrhs) a)
-> Hermitian sh a
-> Full vert horiz sh nrhs a
-> Full vert horiz sh nrhs a
forall shA a shB b shC c.
(Array shA a -> Array shB b -> Array shC c)
-> ArrayMatrix shA a -> ArrayMatrix shB b -> ArrayMatrix shC c
ArrMatrix.lift2 Array (Hermitian sh) a
-> Array (Full vert horiz sh nrhs) a
-> Array (Full vert horiz sh nrhs) a
forall vert horiz sh nrhs a.
(C vert, C horiz, C sh, Eq sh, C nrhs, Floating a) =>
Hermitian sh a
-> Full vert horiz sh nrhs a -> Full vert horiz sh nrhs a
Linear.solve

inverse :: (Shape.C sh, Class.Floating a) => Hermitian sh a -> Hermitian sh a
inverse :: Hermitian sh a -> Hermitian sh a
inverse = (Array (Hermitian sh) a -> Array (Hermitian sh) a)
-> Hermitian sh a -> Hermitian sh a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 Array (Hermitian sh) a -> Array (Hermitian sh) a
forall sh a. (C sh, Floating a) => Hermitian sh a -> Hermitian sh a
Linear.inverse

determinant :: (Shape.C sh, Class.Floating a) => Hermitian sh a -> RealOf a
determinant :: Hermitian sh a -> RealOf a
determinant = Hermitian sh a -> RealOf a
forall sh a. (C sh, Floating a) => Hermitian sh a -> RealOf a
Linear.determinant (Hermitian sh a -> RealOf a)
-> (Hermitian sh a -> Hermitian sh a) -> Hermitian sh a -> RealOf a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hermitian sh a -> Hermitian sh a
forall sh a. ArrayMatrix sh a -> Array sh a
ArrMatrix.toVector



eigenvalues ::
   (Shape.C sh, Class.Floating a) =>
   Hermitian sh a -> Vector sh (RealOf a)
eigenvalues :: Hermitian sh a -> Vector sh (RealOf a)
eigenvalues = Hermitian sh a -> Vector sh (RealOf a)
forall sh a.
(C sh, Floating a) =>
Hermitian sh a -> Vector sh (RealOf a)
Eigen.values (Hermitian sh a -> Vector sh (RealOf a))
-> (Hermitian sh a -> Hermitian sh a)
-> Hermitian sh a
-> Vector sh (RealOf a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hermitian sh a -> Hermitian sh a
forall sh a. ArrayMatrix sh a -> Array sh a
ArrMatrix.toVector

{- |
For symmetric eigenvalue problems, @eigensystem@ and @schur@ coincide.
-}
eigensystem ::
   (Shape.C sh, Class.Floating a) =>
   Hermitian sh a -> (Square sh a, Vector sh (RealOf a))
eigensystem :: Hermitian sh a -> (Square sh a, Vector sh (RealOf a))
eigensystem = (Array (Square sh) a -> Square sh a)
-> (Array (Square sh) a, Vector sh (RealOf a))
-> (Square sh a, Vector sh (RealOf a))
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst Array (Square sh) a -> Square sh a
forall shA a. Array shA a -> ArrayMatrix shA a
ArrMatrix.lift0 ((Array (Square sh) a, Vector sh (RealOf a))
 -> (Square sh a, Vector sh (RealOf a)))
-> (Hermitian sh a -> (Array (Square sh) a, Vector sh (RealOf a)))
-> Hermitian sh a
-> (Square sh a, Vector sh (RealOf a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hermitian sh a -> (Array (Square sh) a, Vector sh (RealOf a))
forall sh a.
(C sh, Floating a) =>
Hermitian sh a -> (Square sh a, Vector sh (RealOf a))
Eigen.decompose (Hermitian sh a -> (Array (Square sh) a, Vector sh (RealOf a)))
-> (Hermitian sh a -> Hermitian sh a)
-> Hermitian sh a
-> (Array (Square sh) a, Vector sh (RealOf a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hermitian sh a -> Hermitian sh a
forall sh a. ArrayMatrix sh a -> Array sh a
ArrMatrix.toVector