{-# LANGUAGE GADTs #-}
module Numeric.LAPACK.Matrix.HermitianPositiveDefinite (
   Hermitian.Semidefinite,
   Hermitian.assureFullRank,
   Hermitian.assureAnyRank,
   Hermitian.relaxSemidefinite,
   Hermitian.relaxIndefinite,
   Hermitian.assurePositiveDefiniteness,
   Hermitian.relaxDefiniteness,

   solve,
   solveDecomposed,
   inverse,
   decompose,
   determinant,
   ) where

import qualified Numeric.LAPACK.Matrix.HermitianPositiveDefinite.Linear
                                                                  as Linear
import qualified Numeric.LAPACK.Matrix.Array.Hermitian as Hermitian
import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix
import qualified Numeric.LAPACK.Matrix.Layout.Private as Layout
import qualified Numeric.LAPACK.Matrix.Extent as Extent
import Numeric.LAPACK.Matrix.Array.Mosaic (HermitianPosDefP, UpperP)
import Numeric.LAPACK.Matrix.Array (Full)
import Numeric.LAPACK.Scalar (RealOf)

import qualified Numeric.Netlib.Class as Class

import qualified Data.Array.Comfort.Shape as Shape



solve ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Layout.Packing pack, Shape.C sh, Eq sh, Shape.C nrhs, Class.Floating a) =>
   HermitianPosDefP pack sh a ->
   Full meas vert horiz sh nrhs a -> Full meas vert horiz sh nrhs a
solve :: HermitianPosDefP pack sh a
-> Full meas vert horiz sh nrhs a -> Full meas vert horiz sh nrhs a
solve = (PlainArray
   pack
   HermitianPositiveDefinite
   Filled
   Filled
   Shape
   Small
   Small
   sh
   sh
   a
 -> PlainArray
      Unpacked Arbitrary Filled Filled meas vert horiz sh nrhs a
 -> PlainArray
      Unpacked Arbitrary Filled Filled meas vert horiz sh nrhs a)
-> HermitianPosDefP pack sh a
-> Full meas vert horiz sh nrhs a
-> Full meas vert horiz sh nrhs a
forall packA propA lowerA upperA measA vertA horizA heightA widthA
       packB propB lowerB upperB measB vertB horizB heightB widthB packC
       propC lowerC upperC measC vertC horizC heightC widthC a b c.
(ToPlain
   packA propA lowerA upperA measA vertA horizA heightA widthA,
 ToPlain
   packB propB lowerB upperB measB vertB horizB heightB widthB,
 FromPlain
   packC propC lowerC upperC measC vertC horizC heightC widthC) =>
(PlainArray
   packA propA lowerA upperA measA vertA horizA heightA widthA a
 -> PlainArray
      packB propB lowerB upperB measB vertB horizB heightB widthB b
 -> PlainArray
      packC propC lowerC upperC measC vertC horizC heightC widthC c)
-> ArrayMatrix
     packA propA lowerA upperA measA vertA horizA heightA widthA a
-> ArrayMatrix
     packB propB lowerB upperB measB vertB horizB heightB widthB b
-> ArrayMatrix
     packC propC lowerC upperC measC vertC horizC heightC widthC c
ArrMatrix.lift2 PlainArray
  pack
  HermitianPositiveDefinite
  Filled
  Filled
  Shape
  Small
  Small
  sh
  sh
  a
-> PlainArray
     Unpacked Arbitrary Filled Filled meas vert horiz sh nrhs a
-> PlainArray
     Unpacked Arbitrary Filled Filled meas vert horiz sh nrhs a
forall meas vert horiz sh nrhs a pack.
(Measure meas, C vert, C horiz, C sh, Eq sh, C nrhs, Floating a) =>
Hermitian pack sh a
-> Full meas vert horiz sh nrhs a -> Full meas vert horiz sh nrhs a
Linear.solve

{- |
> solve a b == solveDecomposed (decompose a) b
> solve (gramian u) b == solveDecomposed u b
-}
solveDecomposed ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Layout.Packing pack, Shape.C sh, Eq sh, Shape.C nrhs, Class.Floating a) =>
   UpperP pack sh a ->
   Full meas vert horiz sh nrhs a -> Full meas vert horiz sh nrhs a
solveDecomposed :: UpperP pack sh a
-> Full meas vert horiz sh nrhs a -> Full meas vert horiz sh nrhs a
solveDecomposed = (PlainArray pack Arbitrary Empty Filled Shape Small Small sh sh a
 -> PlainArray
      Unpacked Arbitrary Filled Filled meas vert horiz sh nrhs a
 -> PlainArray
      Unpacked Arbitrary Filled Filled meas vert horiz sh nrhs a)
-> UpperP pack sh a
-> Full meas vert horiz sh nrhs a
-> Full meas vert horiz sh nrhs a
forall packA propA lowerA upperA measA vertA horizA heightA widthA
       packB propB lowerB upperB measB vertB horizB heightB widthB packC
       propC lowerC upperC measC vertC horizC heightC widthC a b c.
(ToPlain
   packA propA lowerA upperA measA vertA horizA heightA widthA,
 ToPlain
   packB propB lowerB upperB measB vertB horizB heightB widthB,
 FromPlain
   packC propC lowerC upperC measC vertC horizC heightC widthC) =>
(PlainArray
   packA propA lowerA upperA measA vertA horizA heightA widthA a
 -> PlainArray
      packB propB lowerB upperB measB vertB horizB heightB widthB b
 -> PlainArray
      packC propC lowerC upperC measC vertC horizC heightC widthC c)
-> ArrayMatrix
     packA propA lowerA upperA measA vertA horizA heightA widthA a
-> ArrayMatrix
     packB propB lowerB upperB measB vertB horizB heightB widthB b
-> ArrayMatrix
     packC propC lowerC upperC measC vertC horizC heightC widthC c
ArrMatrix.lift2 PlainArray pack Arbitrary Empty Filled Shape Small Small sh sh a
-> PlainArray
     Unpacked Arbitrary Filled Filled meas vert horiz sh nrhs a
-> PlainArray
     Unpacked Arbitrary Filled Filled meas vert horiz sh nrhs a
forall meas vert horiz sh nrhs a pack.
(Measure meas, C vert, C horiz, C sh, Eq sh, C nrhs, Floating a) =>
Upper pack sh a
-> Full meas vert horiz sh nrhs a -> Full meas vert horiz sh nrhs a
Linear.solveDecomposed

inverse ::
   (Layout.Packing pack, Shape.C sh, Class.Floating a) =>
   HermitianPosDefP pack sh a -> HermitianPosDefP pack sh a
inverse :: HermitianPosDefP pack sh a -> HermitianPosDefP pack sh a
inverse = (PlainArray
   pack
   HermitianPositiveDefinite
   Filled
   Filled
   Shape
   Small
   Small
   sh
   sh
   a
 -> PlainArray
      pack
      HermitianPositiveDefinite
      Filled
      Filled
      Shape
      Small
      Small
      sh
      sh
      a)
-> HermitianPosDefP pack sh a -> HermitianPosDefP pack sh a
forall packA propA lowerA upperA measA vertA horizA heightA widthA
       packB propB lowerB upperB measB vertB horizB heightB widthB a b.
(ToPlain
   packA propA lowerA upperA measA vertA horizA heightA widthA,
 FromPlain
   packB propB lowerB upperB measB vertB horizB heightB widthB) =>
(PlainArray
   packA propA lowerA upperA measA vertA horizA heightA widthA a
 -> PlainArray
      packB propB lowerB upperB measB vertB horizB heightB widthB b)
-> ArrayMatrix
     packA propA lowerA upperA measA vertA horizA heightA widthA a
-> ArrayMatrix
     packB propB lowerB upperB measB vertB horizB heightB widthB b
ArrMatrix.lift1 PlainArray
  pack
  HermitianPositiveDefinite
  Filled
  Filled
  Shape
  Small
  Small
  sh
  sh
  a
-> PlainArray
     pack
     HermitianPositiveDefinite
     Filled
     Filled
     Shape
     Small
     Small
     sh
     sh
     a
forall sh a pack.
(C sh, Floating a) =>
Hermitian pack sh a -> Hermitian pack sh a
Linear.inverse

{- |
Cholesky decomposition
-}
decompose ::
   (Layout.Packing pack, Shape.C sh, Class.Floating a) =>
   HermitianPosDefP pack sh a -> UpperP pack sh a
decompose :: HermitianPosDefP pack sh a -> UpperP pack sh a
decompose = (PlainArray
   pack
   HermitianPositiveDefinite
   Filled
   Filled
   Shape
   Small
   Small
   sh
   sh
   a
 -> PlainArray
      pack Arbitrary Empty Filled Shape Small Small sh sh a)
-> HermitianPosDefP pack sh a -> UpperP pack sh a
forall packA propA lowerA upperA measA vertA horizA heightA widthA
       packB propB lowerB upperB measB vertB horizB heightB widthB a b.
(ToPlain
   packA propA lowerA upperA measA vertA horizA heightA widthA,
 FromPlain
   packB propB lowerB upperB measB vertB horizB heightB widthB) =>
(PlainArray
   packA propA lowerA upperA measA vertA horizA heightA widthA a
 -> PlainArray
      packB propB lowerB upperB measB vertB horizB heightB widthB b)
-> ArrayMatrix
     packA propA lowerA upperA measA vertA horizA heightA widthA a
-> ArrayMatrix
     packB propB lowerB upperB measB vertB horizB heightB widthB b
ArrMatrix.lift1 PlainArray
  pack
  HermitianPositiveDefinite
  Filled
  Filled
  Shape
  Small
  Small
  sh
  sh
  a
-> PlainArray pack Arbitrary Empty Filled Shape Small Small sh sh a
forall sh a pack.
(C sh, Floating a) =>
Hermitian pack sh a -> Upper pack sh a
Linear.decompose

determinant ::
   (Layout.Packing pack, Shape.C sh, Class.Floating a) =>
   HermitianPosDefP pack sh a -> RealOf a
determinant :: HermitianPosDefP pack sh a -> RealOf a
determinant = Hermitian pack sh a -> RealOf a
forall sh a pack.
(C sh, Floating a) =>
Hermitian pack sh a -> RealOf a
Linear.determinant (Hermitian pack sh a -> RealOf a)
-> (HermitianPosDefP pack sh a -> Hermitian pack sh a)
-> HermitianPosDefP pack sh a
-> RealOf a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HermitianPosDefP pack sh a -> Hermitian pack sh a
forall pack property lower upper meas vert horiz height width a.
ToPlain pack property lower upper meas vert horiz height width =>
ArrayMatrix
  pack property lower upper meas vert horiz height width a
-> PlainArray
     pack property lower upper meas vert horiz height width a
ArrMatrix.toVector