lapack-0.5.2: src/Numeric/LAPACK/Matrix/Triangular/Eigen.hs
{-# LANGUAGE GADTs #-}
module Numeric.LAPACK.Matrix.Triangular.Eigen (
values,
decompose,
) where
import qualified Numeric.LAPACK.Matrix.Mosaic.Basic as Mosaic
import qualified Numeric.LAPACK.Matrix.Layout.Private as Layout
import qualified Numeric.LAPACK.Vector as Vector
import Numeric.LAPACK.Matrix.Mosaic.Private
(unpackZero, unpackToTemp, fillTriangle,
forPointers, rowMajorPointers)
import Numeric.LAPACK.Matrix.Triangular.Basic (TriangularP)
import Numeric.LAPACK.Matrix.Layout.Private
(Order(ColumnMajor,RowMajor), uploOrder)
import Numeric.LAPACK.Vector (Vector)
import Numeric.LAPACK.Scalar (zero)
import Numeric.LAPACK.Private (copyToColumnMajorTemp, withInfo, errorCodeMsg)
import qualified Numeric.LAPACK.FFI.Complex as LapackComplex
import qualified Numeric.LAPACK.FFI.Real as LapackReal
import qualified Numeric.BLAS.FFI.Generic as BlasGen
import qualified Numeric.Netlib.Utility as Call
import qualified Numeric.Netlib.Class as Class
import qualified Data.Array.Comfort.Storable.Unchecked.Monadic as ArrayIO
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.C.Types (CInt, CChar)
import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)
import Foreign.Ptr (Ptr, nullPtr)
import Control.Monad.Trans.Cont (ContT(ContT), evalContT)
import Control.Monad.IO.Class (liftIO)
import Data.Complex (Complex)
import Data.Tuple.HT (swap, mapPair)
values ::
(Layout.UpLo uplo, Shape.C sh, Class.Floating a) =>
TriangularP pack uplo sh a -> Vector sh a
values = Mosaic.takeDiagonal
decompose ::
(Layout.UpLo uplo, Layout.Packing vpack,
Shape.C sh, Class.Floating a) =>
TriangularP pack uplo sh a ->
(TriangularP vpack uplo sh a, TriangularP vpack uplo sh a)
decompose (Array (Layout.Mosaic packing mirror uplo order sh) a) =
let triShape ord =
Layout.Mosaic
Layout.Unpacked mirror uplo (uploOrder uplo ord) sh
n = Shape.size sh
in swapUpper uplo $
mapPair (Vector.conjugate . Mosaic.repack, Mosaic.repack) $
Array.unsafeCreateWithSizeAndResult (triShape RowMajor) $ \_ vlPtr ->
ArrayIO.unsafeCreate (triShape ColumnMajor) $ \vrPtr ->
evalContT $ do
sidePtr <- Call.char 'B'
howManyPtr <- Call.char 'A'
let selectPtr = nullPtr
aPtr <- toColumnMajorTemp packing (uploOrder uplo order) n a
ldaPtr <- Call.leadingDim n
mmPtr <- Call.cint n
mPtr <- Call.alloca
liftIO $ withInfo errorCodeMsg "trevc" $
trevc sidePtr howManyPtr selectPtr n
aPtr ldaPtr vlPtr ldaPtr vrPtr ldaPtr mmPtr mPtr
swapUpper :: Layout.UpLoSingleton uplo -> (a,a) -> (a,a)
swapUpper uplo =
case uplo of
Layout.Lower -> id
Layout.Upper -> swap
toColumnMajorTemp ::
(Class.Floating a) =>
Layout.PackingSingleton pack -> Order ->
Int -> ForeignPtr a -> ContT () IO (Ptr a)
toColumnMajorTemp packing order n a =
case packing of
Layout.Packed ->
let unpk =
case order of
ColumnMajor -> unpackZero ColumnMajor
RowMajor -> unpackZeroRowMajor
in unpackToTemp unpk n a
Layout.Unpacked ->
case order of
ColumnMajor -> ContT $ withForeignPtr a
RowMajor -> copyToColumnMajorTemp order n n a
unpackZeroRowMajor :: Class.Floating a => Int -> Ptr a -> Ptr a -> IO ()
unpackZeroRowMajor n packedPtr fullPtr = do
fillTriangle zero RowMajor n fullPtr
unpackRowMajor n packedPtr fullPtr
unpackRowMajor :: Class.Floating a => Int -> Ptr a -> Ptr a -> IO ()
unpackRowMajor n packedPtr fullPtr = evalContT $ do
incxPtr <- Call.cint 1
incyPtr <- Call.cint n
liftIO $
forPointers (rowMajorPointers n fullPtr packedPtr) $
\nPtr (dstPtr,srcPtr) ->
BlasGen.copy nPtr srcPtr incxPtr dstPtr incyPtr
type TREVC_ a =
Ptr CChar -> Ptr CChar -> Ptr Bool ->
Int -> Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt ->
Ptr CInt -> Ptr CInt -> Ptr CInt -> IO ()
newtype TREVC a = TREVC {getTREVC :: TREVC_ a}
trevc :: Class.Floating a => TREVC_ a
trevc =
getTREVC $
Class.switchFloating
(TREVC trevcReal) (TREVC trevcReal)
(TREVC trevcComplex) (TREVC trevcComplex)
trevcReal :: Class.Real a => TREVC_ a
trevcReal sidePtr howmnyPtr selectPtr n
tPtr ldtPtr vlPtr ldvlPtr vrPtr ldvrPtr mmPtr mPtr infoPtr =
evalContT $ do
nPtr <- Call.cint n
workPtr <- Call.allocaArray (3*n)
liftIO $
LapackReal.trevc sidePtr howmnyPtr selectPtr nPtr
tPtr ldtPtr vlPtr ldvlPtr vrPtr ldvrPtr mmPtr mPtr workPtr infoPtr
trevcComplex :: Class.Real a => TREVC_ (Complex a)
trevcComplex sidePtr howmnyPtr selectPtr n
tPtr ldtPtr vlPtr ldvlPtr vrPtr ldvrPtr mmPtr mPtr infoPtr =
evalContT $ do
nPtr <- Call.cint n
workPtr <- Call.allocaArray (2*n)
rworkPtr <- Call.allocaArray n
liftIO $
LapackComplex.trevc sidePtr howmnyPtr selectPtr nPtr
tPtr ldtPtr vlPtr ldvlPtr vrPtr ldvrPtr mmPtr mPtr
workPtr rworkPtr infoPtr