{-# LANGUAGE TypeFamilies #-}
module Numeric.LAPACK.Matrix.Plain.Class (
   Admissible(check),
   Homogeneous(zero, negate, scaleReal),
   ShapeOrder(forceOrder, shapeOrder), adaptOrder,
   Additive(add, sub),
   Complex(conjugate, fromReal, toComplex),
   SquareShape(toSquare, identityOrder, takeDiagonal),
   ) where

import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape
import qualified Numeric.LAPACK.Matrix.Shape.Box as Box
import qualified Numeric.LAPACK.Matrix.Extent as Extent
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.Hermitian.Basic as Hermitian
import qualified Numeric.LAPACK.Matrix.Square.Basic as Square
import qualified Numeric.LAPACK.Matrix.Basic as Basic
import qualified Numeric.LAPACK.Vector as Vector
import qualified Numeric.LAPACK.Scalar as Scalar
import Numeric.LAPACK.Matrix.Private (Square)
import Numeric.LAPACK.Vector (Vector)
import Numeric.LAPACK.Scalar (RealOf, ComplexOf)
import Numeric.LAPACK.Wrapper (Flip(Flip, getFlip))

import qualified Numeric.Netlib.Class as Class

import qualified Type.Data.Num.Unary as Unary

import Control.Applicative ((<|>))

import qualified Data.Array.Comfort.Storable.Unchecked as Array
import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Storable.Unchecked (Array, (!))

import qualified Data.Complex as Complex
import Data.Functor.Compose (Compose(Compose, getCompose))
import Data.Maybe.HT (toMaybe)

import Prelude hiding (negate)



class (Shape.C shape) => Admissible shape where
   check :: (Class.Floating a) => Array shape a -> Maybe String

assert :: msg -> Bool -> Maybe msg
assert :: msg -> Bool -> Maybe msg
assert msg
msg = (Bool -> msg -> Maybe msg) -> msg -> Bool -> Maybe msg
forall a b c. (a -> b -> c) -> b -> a -> c
flip Bool -> msg -> Maybe msg
forall a. Bool -> a -> Maybe a
toMaybe msg
msg (Bool -> Maybe msg) -> (Bool -> Bool) -> Bool -> Maybe msg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not

instance
   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>
      Admissible (MatrixShape.Full vert horiz height width) where
   check :: Array (Full vert horiz height width) a -> Maybe String
check Array (Full vert horiz height width) a
_ = Maybe String
forall a. Maybe a
Nothing

instance (Shape.C size) => Admissible (MatrixShape.Hermitian size) where
   check :: Array (Hermitian size) a -> Maybe String
check =
      String -> Bool -> Maybe String
forall msg. msg -> Bool -> Maybe msg
assert String
"Hermitian with non-real diagonal" (Bool -> Maybe String)
-> (Array (Hermitian size) a -> Bool)
-> Array (Hermitian size) a
-> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      Vector size a -> Bool
forall sh a. (C sh, Floating a) => Vector sh a -> Bool
isReal (Vector size a -> Bool)
-> (Array (Hermitian size) a -> Vector size a)
-> Array (Hermitian size) a
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Triangular Empty NonUnit Filled size a -> Vector size a
forall lo up sh a diag.
(Content lo, Content up, C sh, Floating a) =>
Triangular lo diag up sh a -> Vector sh a
Triangular.takeDiagonal (Triangular Empty NonUnit Filled size a -> Vector size a)
-> (Array (Hermitian size) a
    -> Triangular Empty NonUnit Filled size a)
-> Array (Hermitian size) a
-> Vector size a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array (Hermitian size) a -> Triangular Empty NonUnit Filled size a
forall sh a.
(C sh, Floating a) =>
Hermitian sh a -> Array (UpperTriangular NonUnit sh) a
Hermitian.takeUpper

instance
   (MatrixShape.Content lo, MatrixShape.TriDiag diag, MatrixShape.Content up,
    Shape.C size) =>
      Admissible (MatrixShape.Triangular lo diag up size) where
   check :: Array (Triangular lo diag up size) a -> Maybe String
check =
      CheckDiag lo up size a (Maybe String) diag
-> Array (Triangular lo diag up size) a -> Maybe String
forall lo up sh a b diag.
CheckDiag lo up sh a b diag -> Triangular lo diag up sh a -> b
getCheckDiag (CheckDiag lo up size a (Maybe String) diag
 -> Array (Triangular lo diag up size) a -> Maybe String)
-> CheckDiag lo up size a (Maybe String) diag
-> Array (Triangular lo diag up size) a
-> Maybe String
forall a b. (a -> b) -> a -> b
$
      CheckDiag lo up size a (Maybe String) Unit
-> CheckDiag lo up size a (Maybe String) NonUnit
-> CheckDiag lo up size a (Maybe String) diag
forall diag (f :: * -> *).
TriDiag diag =>
f Unit -> f NonUnit -> f diag
MatrixShape.switchTriDiag
         ((Triangular lo Unit up size a -> Maybe String)
-> CheckDiag lo up size a (Maybe String) Unit
forall lo up sh a b diag.
(Triangular lo diag up sh a -> b) -> CheckDiag lo up sh a b diag
CheckDiag ((Triangular lo Unit up size a -> Maybe String)
 -> CheckDiag lo up size a (Maybe String) Unit)
-> (Triangular lo Unit up size a -> Maybe String)
-> CheckDiag lo up size a (Maybe String) Unit
forall a b. (a -> b) -> a -> b
$ Maybe String -> Triangular lo Unit up size a -> Maybe String
forall a b. a -> b -> a
const Maybe String
forall a. Maybe a
Nothing)
         ((Triangular lo NonUnit up size a -> Maybe String)
-> CheckDiag lo up size a (Maybe String) NonUnit
forall lo up sh a b diag.
(Triangular lo diag up sh a -> b) -> CheckDiag lo up sh a b diag
CheckDiag Triangular lo NonUnit up size a -> Maybe String
forall size a lo diag up.
(C size, Floating a, Content lo, TriDiag diag, Content up) =>
Triangular lo diag up size a -> Maybe String
checkUnitDiagonal)

newtype CheckDiag lo up sh a b diag =
   CheckDiag {CheckDiag lo up sh a b diag -> Triangular lo diag up sh a -> b
getCheckDiag :: Triangular.Triangular lo diag up sh a -> b}

checkUnitDiagonal ::
   (Shape.C size, Class.Floating a,
   MatrixShape.Content lo, MatrixShape.TriDiag diag, MatrixShape.Content up) =>
   Triangular.Triangular lo diag up size a -> Maybe String
checkUnitDiagonal :: Triangular lo diag up size a -> Maybe String
checkUnitDiagonal =
   String -> Bool -> Maybe String
forall msg. msg -> Bool -> Maybe msg
assert String
"Triangular.Unit with non-unit diagonal elements" (Bool -> Maybe String)
-> (Triangular lo diag up size a -> Bool)
-> Triangular lo diag up size a
-> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   (a -> Bool) -> [a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (a -> a -> Bool
forall a. Floating a => a -> a -> Bool
Scalar.equal a
forall a. Floating a => a
Scalar.one) ([a] -> Bool)
-> (Triangular lo diag up size a -> [a])
-> Triangular lo diag up size a
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector size a -> [a]
forall sh a. (C sh, Storable a) => Vector sh a -> [a]
Vector.toList (Vector size a -> [a])
-> (Triangular lo diag up size a -> Vector size a)
-> Triangular lo diag up size a
-> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Triangular lo diag up size a -> Vector size a
forall lo up sh a diag.
(Content lo, Content up, C sh, Floating a) =>
Triangular lo diag up sh a -> Vector sh a
Triangular.takeDiagonal

instance
   (Unary.Natural sub, Unary.Natural super, Extent.C vert, Extent.C horiz,
    Shape.C height, Shape.C width) =>
      Admissible (MatrixShape.Banded sub super vert horiz height width) where
   check :: Array (Banded sub super vert horiz height width) a -> Maybe String
check Array (Banded sub super vert horiz height width) a
arr0 =
      let arr :: Banded sub super Big Big (Deferred height) (Deferred width) a
arr =
            (height -> Deferred height)
-> Banded sub super Big Big height (Deferred width) a
-> Banded sub super Big Big (Deferred height) (Deferred width) a
forall vert horiz heightA heightB super sub width a.
(GeneralTallWide vert horiz, GeneralTallWide horiz vert) =>
(heightA -> heightB)
-> Banded super sub vert horiz heightA width a
-> Banded super sub vert horiz heightB width a
Banded.mapHeight height -> Deferred height
forall sh. sh -> Deferred sh
Shape.Deferred (Banded sub super Big Big height (Deferred width) a
 -> Banded sub super Big Big (Deferred height) (Deferred width) a)
-> Banded sub super Big Big height (Deferred width) a
-> Banded sub super Big Big (Deferred height) (Deferred width) a
forall a b. (a -> b) -> a -> b
$
            (width -> Deferred width)
-> Banded sub super Big Big height width a
-> Banded sub super Big Big height (Deferred width) a
forall vert horiz widthA widthB super sub height a.
(GeneralTallWide vert horiz, GeneralTallWide horiz vert) =>
(widthA -> widthB)
-> Banded super sub vert horiz height widthA a
-> Banded super sub vert horiz height widthB a
Banded.mapWidth width -> Deferred width
forall sh. sh -> Deferred sh
Shape.Deferred (Banded sub super Big Big height width a
 -> Banded sub super Big Big height (Deferred width) a)
-> Banded sub super Big Big height width a
-> Banded sub super Big Big height (Deferred width) a
forall a b. (a -> b) -> a -> b
$
            Map vert horiz Big Big height width
-> Array (Banded sub super vert horiz height width) a
-> Banded sub super Big Big height width a
forall vertA horizA vertB horizB height width super sub a.
(C vertA, C horizA, C vertB, C horizB) =>
Map vertA horizA vertB horizB height width
-> Banded super sub vertA horizA height width a
-> Banded super sub vertB horizB height width a
Banded.mapExtent Map vert horiz Big Big height width
forall vert horiz height width.
(C vert, C horiz) =>
Map vert horiz Big Big height width
Extent.toGeneral Array (Banded sub super vert horiz height width) a
arr0
      in String -> Bool -> Maybe String
forall msg. msg -> Bool -> Maybe msg
assert String
"Banded with non-zero unused elements" (Bool -> Maybe String) -> Bool -> Maybe String
forall a b. (a -> b) -> a -> b
$
         (BandedIndex (DeferredIndex height) (DeferredIndex width) -> Bool)
-> [BandedIndex (DeferredIndex height) (DeferredIndex width)]
-> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (a -> Bool
forall a. Floating a => a -> Bool
Scalar.isZero (a -> Bool)
-> (BandedIndex (DeferredIndex height) (DeferredIndex width) -> a)
-> BandedIndex (DeferredIndex height) (DeferredIndex width)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Banded sub super Big Big (Deferred height) (Deferred width) a
arrBanded sub super Big Big (Deferred height) (Deferred width) a
-> Index
     (Banded sub super Big Big (Deferred height) (Deferred width))
-> a
forall sh a.
(Indexed sh, Storable a) =>
Array sh a -> Index sh -> a
!)) ([BandedIndex (DeferredIndex height) (DeferredIndex width)]
 -> Bool)
-> [BandedIndex (DeferredIndex height) (DeferredIndex width)]
-> Bool
forall a b. (a -> b) -> a -> b
$
         (BandedIndex (DeferredIndex height) (DeferredIndex width) -> Bool)
-> [BandedIndex (DeferredIndex height) (DeferredIndex width)]
-> [BandedIndex (DeferredIndex height) (DeferredIndex width)]
forall a. (a -> Bool) -> [a] -> [a]
filter
            (\BandedIndex (DeferredIndex height) (DeferredIndex width)
ix -> case BandedIndex (DeferredIndex height) (DeferredIndex width)
ix of MatrixShape.InsideBox DeferredIndex height
_ DeferredIndex width
_ -> Bool
False; BandedIndex (DeferredIndex height) (DeferredIndex width)
_ -> Bool
True) ([BandedIndex (DeferredIndex height) (DeferredIndex width)]
 -> [BandedIndex (DeferredIndex height) (DeferredIndex width)])
-> [BandedIndex (DeferredIndex height) (DeferredIndex width)]
-> [BandedIndex (DeferredIndex height) (DeferredIndex width)]
forall a b. (a -> b) -> a -> b
$
         Banded sub super Big Big (Deferred height) (Deferred width)
-> [Index
      (Banded sub super Big Big (Deferred height) (Deferred width))]
forall sh. Indexed sh => sh -> [Index sh]
Shape.indices (Banded sub super Big Big (Deferred height) (Deferred width)
 -> [Index
       (Banded sub super Big Big (Deferred height) (Deferred width))])
-> Banded sub super Big Big (Deferred height) (Deferred width)
-> [Index
      (Banded sub super Big Big (Deferred height) (Deferred width))]
forall a b. (a -> b) -> a -> b
$ Banded sub super Big Big (Deferred height) (Deferred width) a
-> Banded sub super Big Big (Deferred height) (Deferred width)
forall sh a. Array sh a -> sh
Array.shape Banded sub super Big Big (Deferred height) (Deferred width) a
arr

instance
   (Unary.Natural off, Shape.C size) =>
      Admissible (MatrixShape.BandedHermitian off size) where
   check :: Array (BandedHermitian off size) a -> Maybe String
check Array (BandedHermitian off size) a
arr =
      let u :: Square U0 off size a
u = Array (BandedHermitian off size) a -> Square U0 off size a
forall offDiag size a.
(Natural offDiag, C size, Floating a) =>
BandedHermitian offDiag size a -> Square U0 offDiag size a
BandedHermitian.takeUpper Array (BandedHermitian off size) a
arr
      in Square U0 off size a -> Maybe String
forall shape a.
(Admissible shape, Floating a) =>
Array shape a -> Maybe String
check Square U0 off size a
u Maybe String -> Maybe String -> Maybe String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
         (String -> Bool -> Maybe String
forall msg. msg -> Bool -> Maybe msg
assert String
"BandedHermitian with non-real diagonal" (Bool -> Maybe String)
-> (Square U0 off size a -> Bool)
-> Square U0 off size a
-> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
          Vector size a -> Bool
forall sh a. (C sh, Floating a) => Vector sh a -> Bool
isReal (Vector size a -> Bool)
-> (Square U0 off size a -> Vector size a)
-> Square U0 off size a
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Square U0 off size a -> Vector size a
forall sub super sh a.
(Natural sub, Natural super, C sh, Floating a) =>
Square sub super sh a -> Vector sh a
Banded.takeDiagonal (Square U0 off size a -> Maybe String)
-> Square U0 off size a -> Maybe String
forall a b. (a -> b) -> a -> b
$ Square U0 off size a
u)

isReal :: (Shape.C sh, Class.Floating a) => Vector sh a -> Bool
isReal :: Vector sh a -> Bool
isReal =
   Flip (->) Bool (Vector sh a) -> Vector sh a -> Bool
forall (f :: * -> * -> *) b a. Flip f b a -> f a b
getFlip (Flip (->) Bool (Vector sh a) -> Vector sh a -> Bool)
-> Flip (->) Bool (Vector sh a) -> Vector sh a -> Bool
forall a b. (a -> b) -> a -> b
$ Compose (Flip (->) Bool) (Array sh) a
-> Flip (->) Bool (Vector sh a)
forall k1 (f :: k1 -> *) k2 (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose (Compose (Flip (->) Bool) (Array sh) a
 -> Flip (->) Bool (Vector sh a))
-> Compose (Flip (->) Bool) (Array sh) a
-> Flip (->) Bool (Vector sh a)
forall a b. (a -> b) -> a -> b
$
   Compose (Flip (->) Bool) (Array sh) Float
-> Compose (Flip (->) Bool) (Array sh) Double
-> Compose (Flip (->) Bool) (Array sh) (Complex Float)
-> Compose (Flip (->) Bool) (Array sh) (Complex Double)
-> Compose (Flip (->) Bool) (Array sh) a
forall a (f :: * -> *).
Floating a =>
f Float
-> f Double -> f (Complex Float) -> f (Complex Double) -> f a
Class.switchFloating
      (Flip (->) Bool (Array sh Float)
-> Compose (Flip (->) Bool) (Array sh) Float
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (Flip (->) Bool (Array sh Float)
 -> Compose (Flip (->) Bool) (Array sh) Float)
-> Flip (->) Bool (Array sh Float)
-> Compose (Flip (->) Bool) (Array sh) Float
forall a b. (a -> b) -> a -> b
$ (Array sh Float -> Bool) -> Flip (->) Bool (Array sh Float)
forall (f :: * -> * -> *) b a. f a b -> Flip f b a
Flip ((Array sh Float -> Bool) -> Flip (->) Bool (Array sh Float))
-> (Array sh Float -> Bool) -> Flip (->) Bool (Array sh Float)
forall a b. (a -> b) -> a -> b
$ Bool -> Array sh Float -> Bool
forall a b. a -> b -> a
const Bool
True)
      (Flip (->) Bool (Array sh Double)
-> Compose (Flip (->) Bool) (Array sh) Double
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (Flip (->) Bool (Array sh Double)
 -> Compose (Flip (->) Bool) (Array sh) Double)
-> Flip (->) Bool (Array sh Double)
-> Compose (Flip (->) Bool) (Array sh) Double
forall a b. (a -> b) -> a -> b
$ (Array sh Double -> Bool) -> Flip (->) Bool (Array sh Double)
forall (f :: * -> * -> *) b a. f a b -> Flip f b a
Flip ((Array sh Double -> Bool) -> Flip (->) Bool (Array sh Double))
-> (Array sh Double -> Bool) -> Flip (->) Bool (Array sh Double)
forall a b. (a -> b) -> a -> b
$ Bool -> Array sh Double -> Bool
forall a b. a -> b -> a
const Bool
True)
      (Flip (->) Bool (Array sh (Complex Float))
-> Compose (Flip (->) Bool) (Array sh) (Complex Float)
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (Flip (->) Bool (Array sh (Complex Float))
 -> Compose (Flip (->) Bool) (Array sh) (Complex Float))
-> Flip (->) Bool (Array sh (Complex Float))
-> Compose (Flip (->) Bool) (Array sh) (Complex Float)
forall a b. (a -> b) -> a -> b
$ (Array sh (Complex Float) -> Bool)
-> Flip (->) Bool (Array sh (Complex Float))
forall (f :: * -> * -> *) b a. f a b -> Flip f b a
Flip Array sh (Complex Float) -> Bool
forall sh a. (C sh, Real a) => Vector sh (Complex a) -> Bool
isComplexReal)
      (Flip (->) Bool (Array sh (Complex Double))
-> Compose (Flip (->) Bool) (Array sh) (Complex Double)
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (Flip (->) Bool (Array sh (Complex Double))
 -> Compose (Flip (->) Bool) (Array sh) (Complex Double))
-> Flip (->) Bool (Array sh (Complex Double))
-> Compose (Flip (->) Bool) (Array sh) (Complex Double)
forall a b. (a -> b) -> a -> b
$ (Array sh (Complex Double) -> Bool)
-> Flip (->) Bool (Array sh (Complex Double))
forall (f :: * -> * -> *) b a. f a b -> Flip f b a
Flip Array sh (Complex Double) -> Bool
forall sh a. (C sh, Real a) => Vector sh (Complex a) -> Bool
isComplexReal)

isComplexReal ::
   (Shape.C sh, Class.Real a) => Vector sh (Complex.Complex a) -> Bool
isComplexReal :: Vector sh (Complex a) -> Bool
isComplexReal = (a -> Bool) -> [a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all a -> Bool
forall a. Floating a => a -> Bool
Scalar.isZero ([a] -> Bool)
-> (Vector sh (Complex a) -> [a]) -> Vector sh (Complex a) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector sh a -> [a]
forall sh a. (C sh, Storable a) => Vector sh a -> [a]
Vector.toList (Vector sh a -> [a])
-> (Vector sh (Complex a) -> Vector sh a)
-> Vector sh (Complex a)
-> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector sh (Complex a) -> Vector sh a
forall sh a. (C sh, Real a) => Vector sh (Complex a) -> Vector sh a
Vector.imaginaryPart


class (Shape.C shape) => Complex shape where
   conjugate ::
      (Class.Floating a) => Array shape a -> Array shape a
   conjugate = Array shape a -> Array shape a
forall sh a. (C sh, Floating a) => Vector sh a -> Vector sh a
Vector.conjugate
   fromReal ::
      (Class.Floating a) =>
      Array shape (RealOf a) -> Array shape a
   fromReal = Array shape (RealOf a) -> Array shape a
forall sh a.
(C sh, Floating a) =>
Vector sh (RealOf a) -> Vector sh a
Vector.fromReal
   toComplex ::
      (Class.Floating a) =>
      Array shape a -> Array shape (ComplexOf a)
   toComplex = Array shape a -> Array shape (ComplexOf a)
forall sh a.
(C sh, Floating a) =>
Vector sh a -> Vector sh (ComplexOf a)
Vector.toComplex

instance
   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>
      Complex (MatrixShape.Full vert horiz height width) where

instance (Shape.C size) => Complex (MatrixShape.Hermitian size) where

instance
   (MatrixShape.Content lo, MatrixShape.TriDiag diag, MatrixShape.Content up,
    Shape.C size) =>
      Complex (MatrixShape.Triangular lo diag up size) where

instance
   (Unary.Natural sub, Unary.Natural super, Extent.C vert, Extent.C horiz,
    Shape.C height, Shape.C width) =>
      Complex (MatrixShape.Banded sub super vert horiz height width) where

instance
   (Unary.Natural off, Shape.C size) =>
      Complex (MatrixShape.BandedHermitian off size) where


class (Shape.C shape) => Homogeneous shape where
   zero :: (Class.Floating a) => shape -> Array shape a
   zero = shape -> Array shape a
forall sh a. (C sh, Floating a) => sh -> Vector sh a
Vector.zero
   negate :: (Class.Floating a) => Array shape a -> Array shape a
   negate = Array shape a -> Array shape a
forall sh a. (C sh, Floating a) => Vector sh a -> Vector sh a
Vector.negate
   scaleReal :: (Class.Floating a) =>
      RealOf a -> Array shape a -> Array shape a
   scaleReal = RealOf a -> Array shape a -> Array shape a
forall sh a.
(C sh, Floating a) =>
RealOf a -> Vector sh a -> Vector sh a
Vector.scaleReal


instance
   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>
      Homogeneous (MatrixShape.Full vert horiz height width) where

instance (Shape.C size) => Homogeneous (MatrixShape.Hermitian size) where

instance
   (MatrixShape.Content lo, MatrixShape.NonUnit ~ diag, MatrixShape.Content up,
    Shape.C size) =>
      Homogeneous (MatrixShape.Triangular lo diag up size) where

instance
   (Unary.Natural sub, Unary.Natural super, Extent.C vert, Extent.C horiz,
    Shape.C height, Shape.C width) =>
      Homogeneous (MatrixShape.Banded sub super vert horiz height width) where

instance
   (Unary.Natural off, Shape.C size) =>
      Homogeneous (MatrixShape.BandedHermitian off size) where


class (Shape.C shape) => ShapeOrder shape where
   forceOrder ::
      (Class.Floating a) =>
      MatrixShape.Order -> Array shape a -> Array shape a
   shapeOrder :: shape -> MatrixShape.Order

{- |
@adaptOrder x y@ contains the data of @y@ with the layout of @x@.
-}
adaptOrder ::
   (ShapeOrder shape, Class.Floating a) =>
   Array shape a -> Array shape a -> Array shape a
adaptOrder :: Array shape a -> Array shape a -> Array shape a
adaptOrder = Order -> Array shape a -> Array shape a
forall shape a.
(ShapeOrder shape, Floating a) =>
Order -> Array shape a -> Array shape a
forceOrder (Order -> Array shape a -> Array shape a)
-> (Array shape a -> Order)
-> Array shape a
-> Array shape a
-> Array shape a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. shape -> Order
forall shape. ShapeOrder shape => shape -> Order
shapeOrder (shape -> Order)
-> (Array shape a -> shape) -> Array shape a -> Order
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array shape a -> shape
forall sh a. Array sh a -> sh
Array.shape

instance
   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>
      ShapeOrder (MatrixShape.Full vert horiz height width) where
   forceOrder :: Order
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
forceOrder = Order
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
forall vert horiz height width a.
(C vert, C horiz, C height, C width, Floating a) =>
Order
-> Full vert horiz height width a -> Full vert horiz height width a
Basic.forceOrder
   shapeOrder :: Full vert horiz height width -> Order
shapeOrder = Full vert horiz height width -> Order
forall vert horiz height width.
Full vert horiz height width -> Order
MatrixShape.fullOrder

instance (Shape.C size) => ShapeOrder (MatrixShape.Hermitian size) where
   forceOrder :: Order -> Array (Hermitian size) a -> Array (Hermitian size) a
forceOrder = Order -> Array (Hermitian size) a -> Array (Hermitian size) a
forall sh a.
(C sh, Floating a) =>
Order -> Hermitian sh a -> Hermitian sh a
Hermitian.forceOrder
   shapeOrder :: Hermitian size -> Order
shapeOrder = Hermitian size -> Order
forall size. Hermitian size -> Order
MatrixShape.hermitianOrder

instance
   (MatrixShape.Content lo,
    MatrixShape.TriDiag diag,
    MatrixShape.Content up, Shape.C size) =>
      ShapeOrder (MatrixShape.Triangular lo diag up size) where
   forceOrder :: Order
-> Array (Triangular lo diag up size) a
-> Array (Triangular lo diag up size) a
forceOrder = Order
-> Array (Triangular lo diag up size) a
-> Array (Triangular lo diag up size) a
forall lo up diag sh a.
(Content lo, Content up, TriDiag diag, C sh, Floating a) =>
Order -> Triangular lo diag up sh a -> Triangular lo diag up sh a
Triangular.forceOrder
   shapeOrder :: Triangular lo diag up size -> Order
shapeOrder = Triangular lo diag up size -> Order
forall lo diag up size. Triangular lo diag up size -> Order
MatrixShape.triangularOrder


class (Homogeneous shape, Eq shape) => Additive shape where
   add, sub ::
      (Class.Floating a) =>
      Array shape a -> Array shape a -> Array shape a
   sub Array shape a
a = Array shape a -> Array shape a -> Array shape a
forall shape a.
(Additive shape, Floating a) =>
Array shape a -> Array shape a -> Array shape a
add Array shape a
a (Array shape a -> Array shape a)
-> (Array shape a -> Array shape a)
-> Array shape a
-> Array shape a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array shape a -> Array shape a
forall shape a.
(Homogeneous shape, Floating a) =>
Array shape a -> Array shape a
negate

instance
   (Extent.C vert, Extent.C horiz,
    Shape.C height, Eq height, Shape.C width, Eq width) =>
      Additive (MatrixShape.Full vert horiz height width) where
   add :: Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
add = Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
forall shape a.
(ShapeOrder shape, Eq shape, Floating a) =>
Array shape a -> Array shape a -> Array shape a
addGen
   sub :: Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
sub = Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
forall shape a.
(ShapeOrder shape, Eq shape, Floating a) =>
Array shape a -> Array shape a -> Array shape a
subGen

instance (Shape.C size, Eq size) => Additive (MatrixShape.Hermitian size) where
   add :: Array (Hermitian size) a
-> Array (Hermitian size) a -> Array (Hermitian size) a
add = Array (Hermitian size) a
-> Array (Hermitian size) a -> Array (Hermitian size) a
forall shape a.
(ShapeOrder shape, Eq shape, Floating a) =>
Array shape a -> Array shape a -> Array shape a
addGen
   sub :: Array (Hermitian size) a
-> Array (Hermitian size) a -> Array (Hermitian size) a
sub = Array (Hermitian size) a
-> Array (Hermitian size) a -> Array (Hermitian size) a
forall shape a.
(ShapeOrder shape, Eq shape, Floating a) =>
Array shape a -> Array shape a -> Array shape a
subGen

instance
   (MatrixShape.Content lo, Eq lo,
    MatrixShape.NonUnit ~ diag,
    MatrixShape.Content up, Eq up,
    Shape.C size, Eq size) =>
      Additive (MatrixShape.Triangular lo diag up size) where
   add :: Array (Triangular lo diag up size) a
-> Array (Triangular lo diag up size) a
-> Array (Triangular lo diag up size) a
add = Array (Triangular lo diag up size) a
-> Array (Triangular lo diag up size) a
-> Array (Triangular lo diag up size) a
forall shape a.
(ShapeOrder shape, Eq shape, Floating a) =>
Array shape a -> Array shape a -> Array shape a
addGen
   sub :: Array (Triangular lo diag up size) a
-> Array (Triangular lo diag up size) a
-> Array (Triangular lo diag up size) a
sub = Array (Triangular lo diag up size) a
-> Array (Triangular lo diag up size) a
-> Array (Triangular lo diag up size) a
forall shape a.
(ShapeOrder shape, Eq shape, Floating a) =>
Array shape a -> Array shape a -> Array shape a
subGen

addGen, subGen ::
   (ShapeOrder shape, Eq shape, Class.Floating a) =>
   Array shape a -> Array shape a -> Array shape a
addGen :: Array shape a -> Array shape a -> Array shape a
addGen Array shape a
a Array shape a
b = Array shape a -> Array shape a -> Array shape a
forall sh a.
(C sh, Eq sh, Floating a) =>
Vector sh a -> Vector sh a -> Vector sh a
Vector.add (Array shape a -> Array shape a -> Array shape a
forall shape a.
(ShapeOrder shape, Floating a) =>
Array shape a -> Array shape a -> Array shape a
adaptOrder Array shape a
b Array shape a
a) Array shape a
b
subGen :: Array shape a -> Array shape a -> Array shape a
subGen Array shape a
a Array shape a
b = Array shape a -> Array shape a -> Array shape a
forall sh a.
(C sh, Eq sh, Floating a) =>
Vector sh a -> Vector sh a -> Vector sh a
Vector.sub (Array shape a -> Array shape a -> Array shape a
forall shape a.
(ShapeOrder shape, Floating a) =>
Array shape a -> Array shape a -> Array shape a
adaptOrder Array shape a
b Array shape a
a) Array shape a
b


class
   (Box.Box shape, Box.HeightOf shape ~ Box.WidthOf shape) =>
      SquareShape shape where
   toSquare ::
      (Box.HeightOf shape ~ sh, Class.Floating a) =>
      Array shape a -> Square sh a
   identityOrder ::
      (Box.HeightOf shape ~ sh, Class.Floating a) =>
      MatrixShape.Order -> sh -> Array shape a
   takeDiagonal ::
      (Box.HeightOf shape ~ sh, Class.Floating a) =>
      Array shape a -> Vector sh a

instance
   (Extent.Small ~ vert, Extent.Small ~ horiz,
    Shape.C height, height ~ width) =>
      SquareShape (MatrixShape.Full vert horiz height width) where
   toSquare :: Array (Full vert horiz height width) a -> Square sh a
toSquare = Array (Full vert horiz height width) a -> Square sh a
forall a. a -> a
id
   identityOrder :: Order -> sh -> Array (Full vert horiz height width) a
identityOrder = Order -> sh -> Array (Full vert horiz height width) a
forall sh a. (C sh, Floating a) => Order -> sh -> Square sh a
Square.identityOrder
   takeDiagonal :: Array (Full vert horiz height width) a -> Vector sh a
takeDiagonal = Array (Full vert horiz height width) a -> Vector sh a
forall sh a. (C sh, Floating a) => Square sh a -> Vector sh a
Square.takeDiagonal

instance (Shape.C size) => SquareShape (MatrixShape.Hermitian size) where
   toSquare :: Array (Hermitian size) a -> Square sh a
toSquare = Array (Hermitian size) a -> Square sh a
forall sh a. (C sh, Floating a) => Hermitian sh a -> Square sh a
Hermitian.toSquare
   identityOrder :: Order -> sh -> Array (Hermitian size) a
identityOrder = Order -> sh -> Array (Hermitian size) a
forall sh a. (C sh, Floating a) => Order -> sh -> Hermitian sh a
Hermitian.identity
   takeDiagonal :: Array (Hermitian size) a -> Vector sh a
takeDiagonal = Array size (RealOf a) -> Vector sh a
forall sh a.
(C sh, Floating a) =>
Vector sh (RealOf a) -> Vector sh a
Vector.fromReal (Array size (RealOf a) -> Vector sh a)
-> (Array (Hermitian size) a -> Array size (RealOf a))
-> Array (Hermitian size) a
-> Vector sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array (Hermitian size) a -> Array size (RealOf a)
forall sh a.
(C sh, Floating a) =>
Hermitian sh a -> Vector sh (RealOf a)
Hermitian.takeDiagonal

instance
   (MatrixShape.Content lo, MatrixShape.TriDiag diag, MatrixShape.Content up,
    Shape.C size) =>
      SquareShape (MatrixShape.Triangular lo diag up size) where
   toSquare :: Array (Triangular lo diag up size) a -> Square sh a
toSquare = Array (Triangular lo diag up size) a -> Square sh a
forall lo up sh a diag.
(Content lo, Content up, C sh, Floating a) =>
Triangular lo diag up sh a -> Square sh a
Triangular.toSquare
   identityOrder :: Order -> sh -> Array (Triangular lo diag up size) a
identityOrder Order
order =
      Triangular lo Unit up size a
-> Array (Triangular lo diag up size) a
forall diag lo up sh a.
TriDiag diag =>
Triangular lo Unit up sh a -> Triangular lo diag up sh a
Triangular.relaxUnitDiagonal (Triangular lo Unit up size a
 -> Array (Triangular lo diag up size) a)
-> (size -> Triangular lo Unit up size a)
-> size
-> Array (Triangular lo diag up size) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Order -> size -> Triangular lo Unit up size a
forall lo up sh a.
(Content lo, Content up, C sh, Floating a) =>
Order -> sh -> Triangular lo Unit up sh a
Triangular.identity Order
order
   takeDiagonal :: Array (Triangular lo diag up size) a -> Vector sh a
takeDiagonal = Array (Triangular lo diag up size) a -> Vector sh a
forall lo up sh a diag.
(Content lo, Content up, C sh, Floating a) =>
Triangular lo diag up sh a -> Vector sh a
Triangular.takeDiagonal

instance
   (Unary.Natural sub, Unary.Natural super,
    Extent.Small ~ vert, Extent.Small ~ horiz,
    Shape.C height, height ~ width) =>
      SquareShape
         (MatrixShape.Banded sub super vert horiz height width) where
   toSquare :: Array (Banded sub super vert horiz height width) a -> Square sh a
toSquare = Array (Banded sub super vert horiz height width) a -> Square sh a
forall sub super vert horiz height width a.
(Natural sub, Natural super, C vert, C horiz, C height, C width,
 Floating a) =>
Banded sub super vert horiz height width a
-> Full vert horiz height width a
Banded.toFull
   identityOrder :: Order -> sh -> Array (Banded sub super vert horiz height width) a
identityOrder = Order -> sh -> Array (Banded sub super vert horiz height width) a
forall sub super size a.
(Natural sub, Natural super, C size, Floating a) =>
Order -> size -> Square sub super size a
Banded.identityFatOrder
   takeDiagonal :: Array (Banded sub super vert horiz height width) a -> Vector sh a
takeDiagonal = Array (Banded sub super vert horiz height width) a -> Vector sh a
forall sub super sh a.
(Natural sub, Natural super, C sh, Floating a) =>
Square sub super sh a -> Vector sh a
Banded.takeDiagonal

instance
   (Unary.Natural offDiag, Shape.C size) =>
      SquareShape (MatrixShape.BandedHermitian offDiag size) where
   toSquare :: Array (BandedHermitian offDiag size) a -> Square sh a
toSquare = Banded offDiag offDiag Small Small sh sh a -> Square sh a
forall sub super vert horiz height width a.
(Natural sub, Natural super, C vert, C horiz, C height, C width,
 Floating a) =>
Banded sub super vert horiz height width a
-> Full vert horiz height width a
Banded.toFull (Banded offDiag offDiag Small Small sh sh a -> Square sh a)
-> (BandedHermitian offDiag sh a
    -> Banded offDiag offDiag Small Small sh sh a)
-> BandedHermitian offDiag sh a
-> Square sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BandedHermitian offDiag sh a
-> Banded offDiag offDiag Small Small sh sh a
forall offDiag size a.
(Natural offDiag, C size, Floating a) =>
BandedHermitian offDiag size a -> Square offDiag offDiag size a
BandedHermitian.toBanded
   identityOrder :: Order -> sh -> Array (BandedHermitian offDiag size) a
identityOrder = Order -> sh -> Array (BandedHermitian offDiag size) a
forall offDiag sh a.
(Natural offDiag, C sh, Floating a) =>
Order -> sh -> BandedHermitian offDiag sh a
BandedHermitian.identityFatOrder
   takeDiagonal :: Array (BandedHermitian offDiag size) a -> Vector sh a
takeDiagonal = Array size (RealOf a) -> Vector sh a
forall sh a.
(C sh, Floating a) =>
Vector sh (RealOf a) -> Vector sh a
Vector.fromReal (Array size (RealOf a) -> Vector sh a)
-> (Array (BandedHermitian offDiag size) a
    -> Array size (RealOf a))
-> Array (BandedHermitian offDiag size) a
-> Vector sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array (BandedHermitian offDiag size) a -> Array size (RealOf a)
forall offDiag size a.
(Natural offDiag, C size, Floating a) =>
BandedHermitian offDiag size a -> Vector size (RealOf a)
BandedHermitian.takeDiagonal