module Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite.Linear (
solve,
solveDecomposed,
decompose,
determinant,
) where
import qualified Numeric.LAPACK.Matrix.Banded.Basic as Banded
import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape
import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent
import Numeric.LAPACK.Linear.Private (solver)
import Numeric.LAPACK.Matrix.BandedHermitian.Basic (BandedHermitian)
import Numeric.LAPACK.Matrix.Hermitian.Private (Determinant(..))
import Numeric.LAPACK.Matrix.Triangular.Private (copyTriangleToTemp)
import Numeric.LAPACK.Matrix.Shape.Private (uploFromOrder)
import Numeric.LAPACK.Matrix.Private (Full, Conjugation(Conjugated))
import Numeric.LAPACK.Scalar (RealOf, realPart)
import Numeric.LAPACK.Private (copyBlock, withInfo, rankMsg, definiteMsg)
import qualified Numeric.LAPACK.FFI.Generic as LapackGen
import qualified Numeric.Netlib.Utility as Call
import qualified Numeric.Netlib.Class as Class
import qualified Type.Data.Num.Unary as Unary
import Type.Data.Num (integralFromProxy)
import Type.Base.Proxy (Proxy(Proxy))
import qualified Data.Array.Comfort.Storable.Unchecked as Array
import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Storable.Unchecked (Array(Array))
import Foreign.ForeignPtr (withForeignPtr)
import Control.Monad.Trans.Cont (ContT(ContT), evalContT)
import Control.Monad.IO.Class (liftIO)
solve ::
(Unary.Natural offDiag, Shape.C size, Eq size,
Extent.C vert, Extent.C horiz, Shape.C nrhs, Class.Floating a) =>
BandedHermitian offDiag size a ->
Full vert horiz size nrhs a -> Full vert horiz size nrhs a
solve (Array (MatrixShape.BandedHermitian numOff orderA shA) a) =
solver "BandedHermitian.solve" shA $ \n nPtr nrhsPtr xPtr ldxPtr -> do
uploPtr <- Call.char $ uploFromOrder orderA
let k = integralFromProxy numOff
let lda = k+1
kPtr <- Call.cint k
aPtr <- copyTriangleToTemp Conjugated orderA (n*lda) a
ldaPtr <- Call.leadingDim lda
liftIO $
withInfo definiteMsg "pbsv" $
LapackGen.pbsv uploPtr nPtr kPtr nrhsPtr aPtr ldaPtr xPtr ldxPtr
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 (Array (MatrixShape.Banded (_zero,numOff) orderA shA) a) =
solver "BandedHermitian.solveDecomposed" (Extent.squareSize shA) $
\n nPtr nrhsPtr xPtr ldxPtr -> do
uploPtr <- Call.char $ uploFromOrder orderA
let k = integralFromProxy numOff
let lda = k+1
kPtr <- Call.cint k
aPtr <- copyTriangleToTemp Conjugated orderA (n*lda) a
ldaPtr <- Call.leadingDim lda
liftIO $
withInfo rankMsg "pbtrs" $
LapackGen.pbtrs uploPtr nPtr kPtr nrhsPtr aPtr ldaPtr xPtr ldxPtr
decompose ::
(Unary.Natural offDiag, Shape.C size, Class.Floating a) =>
BandedHermitian offDiag size a -> Banded.Upper offDiag size a
decompose (Array (MatrixShape.BandedHermitian numOff order sh) a) =
Array.unsafeCreateWithSize
(MatrixShape.bandedSquare (Proxy,numOff) order sh) $ \bSize bPtr -> do
evalContT $ do
let k = integralFromProxy numOff
uploPtr <- Call.char $ uploFromOrder order
nPtr <- Call.cint $ Shape.size sh
kPtr <- Call.cint k
aPtr <- ContT $ withForeignPtr a
ldbPtr <- Call.leadingDim $ k+1
liftIO $ do
copyBlock bSize aPtr bPtr
withInfo definiteMsg "pbtrf" $
LapackGen.pbtrf uploPtr nPtr kPtr bPtr ldbPtr
determinant ::
(Unary.Natural offDiag, Shape.C size, Class.Floating a) =>
BandedHermitian offDiag size a -> RealOf a
determinant =
getDeterminant $
Class.switchFloating
(Determinant determinantAux) (Determinant determinantAux)
(Determinant determinantAux) (Determinant determinantAux)
determinantAux ::
(Unary.Natural offDiag, Shape.C size,
Class.Floating a, RealOf a ~ ar, Class.Real ar) =>
BandedHermitian offDiag size a -> ar
determinantAux =
(^(2::Int)) . product . map realPart . Array.toList .
Banded.takeDiagonal . decompose