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 = ArrMatrix.lift2 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 = ArrMatrix.lift2 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 = ArrMatrix.lift1 Linear.decompose

determinant ::
   (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>
   Banded.HermitianPosDef offDiag size a -> RealOf a
determinant = Linear.determinant . ArrMatrix.toVector