module Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite (
   solve,
   solveDecomposed,
   decompose,
   determinant,
   ) where

import qualified Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite.Linear
                                                                  as Linear
import qualified Numeric.LAPACK.Matrix.Array.Banded as Banded
import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix
import qualified Numeric.LAPACK.Matrix.Extent as Extent
import Numeric.LAPACK.Matrix.Array (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.C vert, Extent.C horiz, Shape.C nrhs, Class.Floating a) =>
   Banded.Hermitian offDiag size a ->
   Full vert horiz size nrhs a -> Full 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.C vert, Extent.C horiz, Shape.C nrhs, Class.Floating a) =>
   Banded.Upper offDiag size a ->
   Full vert horiz size nrhs a -> Full vert horiz size nrhs a
solveDecomposed = ArrMatrix.lift2 Linear.solveDecomposed

{- |
Cholesky decomposition
-}
decompose ::
   (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>
   Banded.Hermitian offDiag size a -> Banded.Upper offDiag size a
decompose = ArrMatrix.lift1 Linear.decompose

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