{-# LANGUAGE GADTs #-}
module Numeric.LAPACK.Matrix.Array.Basic where
import qualified Numeric.LAPACK.Matrix.BandedHermitian.Basic as BandedHermitian
import qualified Numeric.LAPACK.Matrix.Banded.Basic as Banded
import qualified Numeric.LAPACK.Matrix.Triangular.Basic as Triangular
import qualified Numeric.LAPACK.Matrix.Mosaic.Packed as Packed
import qualified Numeric.LAPACK.Matrix.Mosaic.Basic as Mosaic
import qualified Numeric.LAPACK.Matrix.Symmetric.Unified as Symmetric
import qualified Numeric.LAPACK.Matrix.Square.Basic as Square
import qualified Numeric.LAPACK.Matrix.Array.Private as ArrMatrix
import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape
import qualified Numeric.LAPACK.Matrix.Shape.Omni as Omni
import qualified Numeric.LAPACK.Matrix.Layout.Private as Layout
import qualified Numeric.LAPACK.Matrix.Extent as Extent
import qualified Numeric.LAPACK.Vector as Vector
import qualified Numeric.LAPACK.Scalar as Scalar
import Numeric.LAPACK.Matrix.Array.Private (ArrayMatrix, Quadratic)
import Numeric.LAPACK.Vector (Vector)
import qualified Numeric.Netlib.Class as Class
import qualified Data.Array.Comfort.Storable.Unchecked as Array
import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Storable (Array)
mapHeight ::
(ArrayMatrix pack property lower upper Extent.Size vert horiz ~ matrix,
Extent.C vert, Extent.C horiz,
Shape.C heightA, Shape.C heightB, Shape.C width) =>
(heightA -> heightB) ->
matrix heightA width a -> matrix heightB width a
mapHeight f =
ArrMatrix.Array . Array.mapShape (Omni.mapHeight f) . ArrMatrix.unwrap
mapWidth ::
(ArrayMatrix pack property lower upper Extent.Size vert horiz ~ matrix,
Extent.C vert, Extent.C horiz,
Shape.C widthA, Shape.C widthB, Shape.C height) =>
(widthA -> widthB) ->
matrix height widthA a -> matrix height widthB a
mapWidth f =
ArrMatrix.Array . Array.mapShape (Omni.mapWidth f) . ArrMatrix.unwrap
mapSquareSize ::
(Shape.C shA, Shape.C shB) =>
(shA -> shB) ->
Quadratic pack property lower upper shA a ->
Quadratic pack property lower upper shB a
mapSquareSize f =
ArrMatrix.Array . Array.mapShape (Omni.mapSquareSize f) . ArrMatrix.unwrap
toFull ::
(Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
(Shape.C height, Shape.C width, Class.Floating a) =>
ArrayMatrix pack property lower upper meas vert horiz height width a ->
ArrMatrix.Full meas vert horiz height width a
toFull a =
case ArrMatrix.shape a of
Omni.Full _ -> ArrMatrix.liftUnpacked1 id a
Omni.UpperTriangular _ -> ArrMatrix.lift1 Triangular.toSquare a
Omni.LowerTriangular _ -> ArrMatrix.lift1 Triangular.toSquare a
Omni.Symmetric _ -> ArrMatrix.lift1 Symmetric.toSquare a
Omni.Hermitian _ -> ArrMatrix.lift1 Symmetric.toSquare a
Omni.Banded _ -> ArrMatrix.lift1 Banded.toFull a
Omni.UnitBandedTriangular _ -> ArrMatrix.lift1 Banded.toFull a
Omni.BandedHermitian _ ->
ArrMatrix.lift1 (Banded.toFull . BandedHermitian.toBanded) a
unpack ::
(Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
(Shape.C height, Shape.C width, Class.Floating a) =>
ArrayMatrix pack property lower upper meas vert horiz height width a ->
ArrayMatrix Layout.Unpacked
property lower upper meas vert horiz height width a
unpack a =
case ArrMatrix.shape a of
Omni.Full _ -> ArrMatrix.liftUnpacked1 id a
Omni.UpperTriangular _ -> ArrMatrix.lift1 Mosaic.unpack a
Omni.LowerTriangular _ -> ArrMatrix.lift1 Mosaic.unpack a
Omni.Symmetric _ -> ArrMatrix.lift1 Mosaic.unpack a
Omni.Hermitian _ -> ArrMatrix.lift1 Mosaic.unpack a
Omni.Banded _ ->
ArrMatrix.liftUnpacked0 $ Banded.toFull $ ArrMatrix.toVector a
Omni.UnitBandedTriangular _ ->
ArrMatrix.liftUnpacked0 $ Banded.toFull $ ArrMatrix.toVector a
Omni.BandedHermitian _ ->
ArrMatrix.liftUnpacked0 $ Banded.toFull $
BandedHermitian.toBanded $ ArrMatrix.toVector a
takeDiagonal ::
(Shape.C sh, Class.Floating a) =>
Quadratic pack property lower upper sh a -> Vector sh a
takeDiagonal a =
case ArrMatrix.shape a of
Omni.Full fullShape ->
Square.takeDiagonal $ Array.reshape fullShape $ ArrMatrix.unwrap a
Omni.UpperTriangular _ -> Mosaic.takeDiagonal $ ArrMatrix.toVector a
Omni.LowerTriangular _ -> Mosaic.takeDiagonal $ ArrMatrix.toVector a
Omni.Symmetric _ -> Mosaic.takeDiagonal $ ArrMatrix.toVector a
Omni.Hermitian _ -> Mosaic.takeDiagonal $ ArrMatrix.toVector a
Omni.Banded _ -> Banded.takeDiagonal $ ArrMatrix.toVector a
Omni.UnitBandedTriangular _ -> Banded.takeDiagonal $ ArrMatrix.toVector a
Omni.BandedHermitian _ ->
Vector.fromReal $ BandedHermitian.takeDiagonal $ ArrMatrix.toVector a
identityFromShape ::
(Shape.C sh, Class.Floating a) =>
MatrixShape.Quadratic pack property lower upper sh ->
Quadratic pack property lower upper sh a
identityFromShape omni =
ArrMatrix.Array $
case omni of
Omni.Full _ ->
identityOmni Omni.Full Square.identityOrder omni
Omni.UpperTriangular _ ->
identityOmni Omni.UpperTriangular Packed.identity omni
Omni.LowerTriangular _ ->
identityOmni Omni.LowerTriangular Packed.identity omni
Omni.Symmetric _ ->
identityOmni Omni.Symmetric Packed.identity omni
Omni.Hermitian _ ->
identityOmni Omni.Hermitian Packed.identity omni
Omni.Banded _ ->
identityOmni Omni.Banded Banded.identityFatOrder omni
Omni.UnitBandedTriangular _ ->
identityOmni Omni.UnitBandedTriangular Banded.identityFatOrder omni
Omni.BandedHermitian _ ->
identityOmni Omni.BandedHermitian
BandedHermitian.identityFatOrder omni
identityOmni ::
(shape -> omni) ->
(Layout.Order -> sh -> Array shape a) ->
MatrixShape.Quadratic pack property lower upper sh -> Array omni a
identityOmni consOmni eye omni =
Array.mapShape consOmni $ eye (Omni.order omni) (Omni.squareSize omni)
identityFrom ::
(Shape.C sh, Class.Floating a) =>
Quadratic pack property lower upper sh a ->
Quadratic pack property lower upper sh a
identityFrom = identityFromShape . ArrMatrix.shape
identityOrder ::
(Omni.Quadratic pack property lower upper, Shape.C sh, Class.Floating a) =>
Layout.Order -> sh -> Quadratic pack property lower upper sh a
identityOrder order sh = identityFromShape $ Omni.quadratic order sh
signNegativeDeterminant ::
(Shape.C sh, Class.Floating a) =>
MatrixShape.Quadratic pack property lower upper sh -> a
signNegativeDeterminant shape =
Scalar.minusOne ^ mod (Shape.size (Omni.squareSize shape)) 2