module Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite (
   Hermitian.Semidefinite,
   Hermitian.assureFullRank,
   Hermitian.assureAnyRank,
   Hermitian.relaxSemidefinite,
   Hermitian.relaxIndefinite,
   Hermitian.assurePositiveDefiniteness,
   Hermitian.relaxDefiniteness,
   solve,
   solveDecomposed,
   decompose,
   determinant,
   ) where

import qualified Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite.Linear
                                                                  as Linear
import qualified Numeric.LAPACK.Matrix.Array.Hermitian as Hermitian
import qualified Numeric.LAPACK.Matrix.Array.Banded as Banded
import qualified Numeric.LAPACK.Matrix.Array.Private as ArrMatrix
import qualified Numeric.LAPACK.Matrix.Extent as Extent
import Numeric.LAPACK.Matrix.Array.Private (Full)
import Numeric.LAPACK.Scalar (RealOf)

import qualified Numeric.Netlib.Class as Class

import qualified Type.Data.Num.Unary as Unary

import qualified Data.Array.Comfort.Shape as Shape


solve ::
   (Unary.Natural offDiag, Shape.C size, Eq size,
    Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.C nrhs, Class.Floating a) =>
   Banded.HermitianPosDef offDiag size a ->
   Full meas vert horiz size nrhs a -> Full meas vert horiz size nrhs a
solve :: HermitianPosDef offDiag size a
-> Full meas vert horiz size nrhs a
-> Full meas vert horiz size nrhs a
solve = (PlainArray
   Packed
   HermitianPositiveDefinite
   (Bands offDiag)
   (Bands offDiag)
   Shape
   Small
   Small
   size
   size
   a
 -> PlainArray
      Unpacked Arbitrary Filled Filled meas vert horiz size nrhs a
 -> PlainArray
      Unpacked Arbitrary Filled Filled meas vert horiz size nrhs a)
-> HermitianPosDef offDiag size a
-> Full meas vert horiz size nrhs a
-> Full meas vert horiz size 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
  Packed
  HermitianPositiveDefinite
  (Bands offDiag)
  (Bands offDiag)
  Shape
  Small
  Small
  size
  size
  a
-> PlainArray
     Unpacked Arbitrary Filled Filled meas vert horiz size nrhs a
-> PlainArray
     Unpacked Arbitrary Filled Filled meas vert horiz size nrhs a
forall offDiag size meas vert horiz nrhs a.
(Natural offDiag, C size, Eq size, Measure meas, C vert, C horiz,
 C nrhs, Floating a) =>
BandedHermitian offDiag size a
-> Full meas vert horiz size nrhs a
-> Full meas vert horiz size nrhs a
Linear.solve

{- |
> solve a b == solveDecomposed (decompose a) b
> solve (gramian u) b == solveDecomposed u b
-}
solveDecomposed ::
   (Unary.Natural offDiag, Shape.C size, Eq size,
    Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.C nrhs, Class.Floating a) =>
   Banded.Upper offDiag size a ->
   Full meas vert horiz size nrhs a -> Full meas vert horiz size nrhs a
solveDecomposed :: Upper offDiag size a
-> Full meas vert horiz size nrhs a
-> Full meas vert horiz size nrhs a
solveDecomposed = (PlainArray
   Packed
   Arbitrary
   (Bands U0)
   (Bands offDiag)
   Shape
   Small
   Small
   size
   size
   a
 -> PlainArray
      Unpacked Arbitrary Filled Filled meas vert horiz size nrhs a
 -> PlainArray
      Unpacked Arbitrary Filled Filled meas vert horiz size nrhs a)
-> Upper offDiag size a
-> Full meas vert horiz size nrhs a
-> Full meas vert horiz size 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
  Packed
  Arbitrary
  (Bands U0)
  (Bands offDiag)
  Shape
  Small
  Small
  size
  size
  a
-> PlainArray
     Unpacked Arbitrary Filled Filled meas vert horiz size nrhs a
-> PlainArray
     Unpacked Arbitrary Filled Filled meas vert horiz size nrhs a
forall offDiag size meas vert horiz nrhs a.
(Natural offDiag, C size, Eq size, Measure meas, C vert, C horiz,
 C nrhs, Floating a) =>
Upper offDiag size a
-> Full meas vert horiz size nrhs a
-> Full meas vert horiz size nrhs a
Linear.solveDecomposed

{- |
Cholesky decomposition
-}
decompose ::
   (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>
   Banded.HermitianPosDef offDiag size a -> Banded.Upper offDiag size a
decompose :: HermitianPosDef offDiag size a -> Upper offDiag size a
decompose = (PlainArray
   Packed
   HermitianPositiveDefinite
   (Bands offDiag)
   (Bands offDiag)
   Shape
   Small
   Small
   size
   size
   a
 -> PlainArray
      Packed
      Arbitrary
      (Bands U0)
      (Bands offDiag)
      Shape
      Small
      Small
      size
      size
      a)
-> HermitianPosDef offDiag size a -> Upper offDiag size 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
  Packed
  HermitianPositiveDefinite
  (Bands offDiag)
  (Bands offDiag)
  Shape
  Small
  Small
  size
  size
  a
-> PlainArray
     Packed
     Arbitrary
     (Bands U0)
     (Bands offDiag)
     Shape
     Small
     Small
     size
     size
     a
forall offDiag size a.
(Natural offDiag, C size, Floating a) =>
BandedHermitian offDiag size a -> Upper offDiag size a
Linear.decompose

determinant ::
   (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>
   Banded.HermitianPosDef offDiag size a -> RealOf a
determinant :: HermitianPosDef offDiag size a -> RealOf a
determinant = BandedHermitian offDiag size a -> RealOf a
forall offDiag size a.
(Natural offDiag, C size, Floating a) =>
BandedHermitian offDiag size a -> RealOf a
Linear.determinant (BandedHermitian offDiag size a -> RealOf a)
-> (HermitianPosDef offDiag size a
    -> BandedHermitian offDiag size a)
-> HermitianPosDef offDiag size a
-> RealOf a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HermitianPosDef offDiag size a -> BandedHermitian offDiag size 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