{-# LANGUAGE TypeFamilies #-}
module Numeric.LAPACK.Matrix.Symmetric.Linear (
   determinant,
   ) where

import qualified Numeric.LAPACK.Matrix.Symmetric.Unified as Symmetric
import qualified Numeric.LAPACK.Matrix.Layout.Private as Layout
import Numeric.LAPACK.Matrix.Symmetric.Basic (SymmetricP)

import qualified Numeric.Netlib.Class as Class

import qualified Data.Array.Comfort.Shape as Shape

import Foreign.Ptr (Ptr)
import Foreign.Storable (peek)


determinant ::
   (Layout.Packing pack, Shape.C sh, Class.Floating a) =>
   SymmetricP pack sh a -> a
determinant = Symmetric.determinant peekBlockDeterminant

peekBlockDeterminant ::
   (Class.Floating a) => (Ptr a, Maybe (Ptr a, Ptr a)) -> IO a
peekBlockDeterminant (a0Ptr,ext) = do
   a0 <- peek a0Ptr
   case ext of
      Nothing -> return a0
      Just (a1Ptr,bPtr) -> do
         a1 <- peek a1Ptr
         b <- peek bPtr
         return (a0*a1 - b*b)