packages feed

lapack 0.2.4 → 0.3

raw patch · 100 files changed

+12191/−5311 lines, 100 filesdep +blaze-htmldep +hyperdep +textdep ~basedep ~comfort-arraydep ~monoid-transformerPVP ok

version bump matches the API change (PVP)

Dependencies added: blaze-html, hyper, text

Dependency ranges changed: base, comfort-array, monoid-transformer, semigroups, transformers, utility-ht

API changes (from Hackage documentation)

- Numeric.LAPACK.Format: instance (C vert, C horiz, C height, C width) => FormatArray (Full vert horiz height width)
- Numeric.LAPACK.Format: instance (Content lo, Content up, TriDiag diag, C size) => FormatArray (Triangular lo diag up size)
- Numeric.LAPACK.Format: instance (Eq lower, C vert, C horiz, C height, C width) => FormatArray (Split lower vert horiz height width)
- Numeric.LAPACK.Format: instance (Natural offDiag, C size) => FormatArray (BandedHermitian offDiag size)
- Numeric.LAPACK.Format: instance (Natural sub, Natural super, C vert, C horiz, C height, C width) => FormatArray (Banded sub super vert horiz height width)
- Numeric.LAPACK.Format: instance C size => FormatArray (Hermitian size)
- Numeric.LAPACK.Format: instance Eq Separator
- Numeric.LAPACK.Format: instance Integral i => FormatArray (OneBased i)
- Numeric.LAPACK.Format: instance Integral i => FormatArray (ZeroBased i)
- Numeric.LAPACK.Format: instance Ord Separator
- Numeric.LAPACK.Format: instance Show Separator
- Numeric.LAPACK.Linear.LowerUpper: data LowerUpper vert horiz height width a
- Numeric.LAPACK.Linear.LowerUpper: instance (C vert, C horiz, C height, C width, Floating a) => Format (LowerUpper vert horiz height width a)
- Numeric.LAPACK.Linear.LowerUpper: instance (Show height, Show width, Show a, Storable a, C height, C width, C vert, C horiz) => Show (LowerUpper vert horiz height width a)
- Numeric.LAPACK.Linear.LowerUpper: multiplyFullRight :: (C vert, C horiz, C height, Eq height, C width, C fuse, Eq fuse, Floating a) => LowerUpper vert horiz height fuse a -> Full vert horiz fuse width a -> Full vert horiz height width a
- Numeric.LAPACK.Matrix: (#>) :: (MultiplyRight shape, Floating a) => Array shape a -> Vector (WidthOf shape) a -> Vector (HeightOf shape) a
- Numeric.LAPACK.Matrix: (<#) :: (MultiplyLeft shape, Floating a) => Vector (HeightOf shape) a -> Array shape a -> Vector (WidthOf shape) a
- Numeric.LAPACK.Matrix: (<#>) :: (Multiply shapeA shapeB, Floating a) => Array shapeA a -> Array shapeB a -> Array (Multiplied shapeA shapeB) a
- Numeric.LAPACK.Matrix: class C shape => MultiplyLeft shape
- Numeric.LAPACK.Matrix: class C shape => MultiplyRight shape
- Numeric.LAPACK.Matrix: flatten :: (C vert, C horiz, C height, C width, Floating a) => Full vert horiz height width a -> Vector ZeroInt a
- Numeric.LAPACK.Matrix: scaleColumnsComplex :: (C vert, C horiz, C height, C width, Eq width, Real a) => Vector width a -> Full vert horiz height width (Complex a) -> Full vert horiz height width (Complex a)
- Numeric.LAPACK.Matrix: scaleRowsComplex :: (C vert, C horiz, C height, Eq height, C width, Real a) => Vector height a -> Full vert horiz height width (Complex a) -> Full vert horiz height width (Complex a)
- Numeric.LAPACK.Matrix: takeBottomRows :: (C vert, C height0, C height1, C width, Floating a) => Full vert Big (height0 :+: height1) width a -> Full vert Big height1 width a
- Numeric.LAPACK.Matrix: takeLeftColumns :: (C vert, C height, C width0, C width1, Floating a) => Full Big vert height (width0 :+: width1) a -> Full Big vert height width0 a
- Numeric.LAPACK.Matrix: takeRightColumns :: (C vert, C height, C width0, C width1, Floating a) => Full Big vert height (width0 :+: width1) a -> Full Big vert height width1 a
- Numeric.LAPACK.Matrix: takeTopRows :: (C vert, C height0, C height1, C width, Floating a) => Full vert Big (height0 :+: height1) width a -> Full vert Big height0 width a
- Numeric.LAPACK.Matrix: type ZeroInt = ZeroBased Int
- Numeric.LAPACK.Matrix: zeroInt :: Int -> ZeroInt
- Numeric.LAPACK.Matrix.BandedHermitian: covariance :: (C size, Eq size, Floating a, Natural sub, Natural super) => Square sub super size a -> BandedHermitian (sub :+: super) size a
- Numeric.LAPACK.Matrix.Hermitian: covariance :: (C height, C width, Eq width, Floating a) => General height width a -> Hermitian width a
- Numeric.LAPACK.Matrix.Triangular: forceNonUnitDiagonal :: Triangular lo NonUnit up sh a -> Triangular lo NonUnit up sh a
- Numeric.LAPACK.Matrix.Triangular: forceUnitDiagonal :: Triangular lo Unit up sh a -> Triangular lo Unit up sh a
- Numeric.LAPACK.Matrix.Triangular: inverseGeneric :: (Content lo, Content up, TriDiag diag, C sh, Floating a) => Triangular lo diag up sh a -> Triangular lo (PowerDiag lo up diag) up sh a
- Numeric.LAPACK.Matrix.Triangular: squareGeneric :: (Content lo, Content up, TriDiag diag, C sh, Eq sh, Floating a) => Triangular lo diag up sh a -> Triangular lo (PowerDiag lo up diag) up sh a
- Numeric.LAPACK.Orthogonal.Householder: Inverted :: Inversion
- Numeric.LAPACK.Orthogonal.Householder: NonInverted :: Inversion
- Numeric.LAPACK.Orthogonal.Householder: data Householder vert horiz height width a
- Numeric.LAPACK.Orthogonal.Householder: data Inversion
- Numeric.LAPACK.Vector: complexFromReal :: (C sh, Real a) => Vector sh a -> Vector sh (Complex a)
- Numeric.LAPACK.Vector: complexToImaginaryPart :: (C sh, Real a) => Vector sh (Complex a) -> Vector sh a
- Numeric.LAPACK.Vector: complexToRealPart :: (C sh, Real a) => Vector sh (Complex a) -> Vector sh a
+ Numeric.LAPACK.Example.EconomicAllocation: balances0 :: Vector ZeroInt2
+ Numeric.LAPACK.Example.EconomicAllocation: compensated :: (C sh0, Eq sh0, C sh1, Eq sh1) => Matrix sh1 (sh0 :+: sh1) -> Vector (sh0 :+: sh1) -> Vector sh0
+ Numeric.LAPACK.Example.EconomicAllocation: completeIdSquare :: (C sh0, Eq sh0, C sh1, Eq sh1) => Matrix sh1 (sh0 :+: sh1) -> SquareMatrix (sh0 :+: sh1)
+ Numeric.LAPACK.Example.EconomicAllocation: expenses0 :: Matrix ShapeInt ZeroInt2
+ Numeric.LAPACK.Example.EconomicAllocation: iterated :: (C sh0, Eq sh0, C sh1, Eq sh1) => Matrix sh1 (sh0 :+: sh1) -> Vector (sh0 :+: sh1) -> Vector (sh0 :+: sh1)
+ Numeric.LAPACK.Example.EconomicAllocation: main :: IO ()
+ Numeric.LAPACK.Example.EconomicAllocation: normalize :: (Eq height, C height, C width) => Matrix height width -> Matrix height width
+ Numeric.LAPACK.Example.EconomicAllocation: normalizeSplit :: (C sh0, C sh1, Eq sh1) => Matrix sh1 (sh0 :+: sh1) -> (Matrix sh0 sh1, SquareMatrix sh1)
+ Numeric.LAPACK.Example.EconomicAllocation: type Matrix height width = General height width Double
+ Numeric.LAPACK.Example.EconomicAllocation: type SquareMatrix size = Square size Double
+ Numeric.LAPACK.Example.EconomicAllocation: type Vector sh = Vector sh Double
+ Numeric.LAPACK.Example.EconomicAllocation: type ZeroInt2 = ShapeInt :+: ShapeInt
+ Numeric.LAPACK.Format: class FormatMatrix typ
+ Numeric.LAPACK.Format: formatMatrix :: (FormatMatrix typ, Floating a, Output out) => String -> Matrix typ a -> out
+ Numeric.LAPACK.Format: hyper :: Format a => String -> a -> Graphic
+ Numeric.LAPACK.Format: instance (FormatMatrix typ, Floating a) => Format (Matrix typ a)
+ Numeric.LAPACK.Format: instance C sh => Format (Permutation sh)
+ Numeric.LAPACK.Linear.LowerUpper: multiplyFull :: (C vert, C horiz, C height, Eq height, C width, C fuse, Eq fuse, Floating a) => LowerUpper vert horiz height fuse a -> Full vert horiz fuse width a -> Full vert horiz height width a
+ Numeric.LAPACK.Linear.LowerUpper: type LowerUpper vert horiz height width = Matrix (LU vert horiz height width)
+ Numeric.LAPACK.Linear.LowerUpper: type Tall height width = LowerUpper Big Small height width
+ Numeric.LAPACK.Linear.LowerUpper: type Wide height width = LowerUpper Small Big height width
+ Numeric.LAPACK.Matrix: (##*#) :: (MultiplySquare typ, WidthOf typ ~ width, Eq width, C height, C horiz, C vert, Floating a) => Full vert horiz height width a -> Matrix typ a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: (##/#) :: (Solve typ, WidthOf typ ~ width, Eq width, C height, C horiz, C vert, Floating a) => Full vert horiz height width a -> Matrix typ a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: (#*##) :: (MultiplySquare typ, HeightOf typ ~ height, Eq height, C width, C horiz, C vert, Floating a) => Matrix typ a -> Full vert horiz height width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: (#*#) :: (Multiply typA typB, Floating a) => Matrix typA a -> Matrix typB a -> Matrix (Multiplied typA typB) a
+ Numeric.LAPACK.Matrix: (#*\) :: (C vert, C horiz, C height, C width, Eq width, Floating a) => Full vert horiz height width a -> Vector width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: (#*|) :: (MultiplyVector typ, WidthOf typ ~ width, Eq width, Floating a) => Matrix typ a -> Vector width a -> Vector (HeightOf typ) a
+ Numeric.LAPACK.Matrix: (#+#) :: (Additive shape, Floating a) => ArrayMatrix shape a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix: (#-#) :: (Additive shape, Floating a) => ArrayMatrix shape a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix: (#/\) :: (C vert, C horiz, C height, C width, Eq width, Floating a) => Full vert horiz height width a -> Vector width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: (#\##) :: (Solve typ, HeightOf typ ~ height, Eq height, C width, C horiz, C vert, Floating a) => Matrix typ a -> Full vert horiz height width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: (#\|) :: (Solve typ, HeightOf typ ~ height, Eq height, Floating a) => Matrix typ a -> Vector height a -> Vector height a
+ Numeric.LAPACK.Matrix: (-*#) :: (MultiplyVector typ, HeightOf typ ~ height, Eq height, Floating a) => Vector height a -> Matrix typ a -> Vector (WidthOf typ) a
+ Numeric.LAPACK.Matrix: (-/#) :: (Solve typ, HeightOf typ ~ height, Eq height, Floating a) => Vector height a -> Matrix typ a -> Vector height a
+ Numeric.LAPACK.Matrix: (.*#) :: (Scale shape, Floating a) => a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix: (\*#) :: (C vert, C horiz, C height, Eq height, C width, Floating a) => Vector height a -> Full vert horiz height width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: (\\#) :: (C vert, C horiz, C height, Eq height, C width, Floating a) => Vector height a -> Full vert horiz height width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: (|*-) :: (C height, Eq height, C width, Eq width, Floating a) => Vector height a -> Vector width a -> General height width a
+ Numeric.LAPACK.Matrix: NonTransposed :: Transposition
+ Numeric.LAPACK.Matrix: Transposed :: Transposition
+ Numeric.LAPACK.Matrix: above :: (C horizA, C horizB, C horizC, C width, Eq width, C heightA, C heightB, Floating a) => OrderBias -> AppendMode horizA horizB horizC width heightA heightB -> Full Big horizA heightA width a -> Full Big horizB heightB width a -> Full Big horizC (heightA :+: heightB) width a
+ Numeric.LAPACK.Matrix: asGeneral :: General height width a -> General height width a
+ Numeric.LAPACK.Matrix: asTall :: Tall height width a -> Tall height width a
+ Numeric.LAPACK.Matrix: asWide :: Wide height width a -> Wide height width a
+ Numeric.LAPACK.Matrix: beside :: (C vertA, C vertB, C vertC, C height, Eq height, C widthA, C widthB, Floating a) => OrderBias -> AppendMode vertA vertB vertC height widthA widthB -> Full vertA Big height widthA a -> Full vertB Big height widthB a -> Full vertC Big height (widthA :+: widthB) a
+ Numeric.LAPACK.Matrix: class Box typ where type family HeightOf typ type family WidthOf typ
+ Numeric.LAPACK.Matrix: class Complex typ
+ Numeric.LAPACK.Matrix: class (Box typ, HeightOf typ ~ WidthOf typ) => Determinant typ
+ Numeric.LAPACK.Matrix: class (Box typ, HeightOf typ ~ WidthOf typ) => MultiplySquare typ where transposableSquare NonTransposed a b = squareFull a b transposableSquare Transposed a b = transpose $ fullSquare (transpose b) a squareFull = transposableSquare NonTransposed fullSquare b a = transpose $ transposableSquare Transposed a $ transpose b
+ Numeric.LAPACK.Matrix: class Box typ => MultiplyVector typ
+ Numeric.LAPACK.Matrix: class (Box typ, HeightOf typ ~ WidthOf typ) => Power typ
+ Numeric.LAPACK.Matrix: class SquareShape typ
+ Numeric.LAPACK.Matrix: columnArgAbsMaximums :: (C vert, C horiz, InvIndexed height, C width, Index height ~ ix, Storable ix, Floating a) => Full vert horiz height width a -> (Vector width ix, Vector width a)
+ Numeric.LAPACK.Matrix: conjugate :: (Complex typ, Floating a) => Matrix typ a -> Matrix typ a
+ Numeric.LAPACK.Matrix: contiguousBias :: OrderBias
+ Numeric.LAPACK.Matrix: data OrderBias
+ Numeric.LAPACK.Matrix: data Transposition
+ Numeric.LAPACK.Matrix: determinant :: (Determinant typ, Floating a) => Matrix typ a -> a
+ Numeric.LAPACK.Matrix: fromColumnContainer :: (C f, C height, Eq height, Storable a) => height -> f (Vector height a) -> General height (Shape f) a
+ Numeric.LAPACK.Matrix: fromColumnsNonEmptyContainer :: (f ~ T g, C g, C height, Eq height, Storable a) => f (Vector height a) -> General height (Shape f) a
+ Numeric.LAPACK.Matrix: fromReal :: (Complex typ, Floating a) => Matrix typ (RealOf a) -> Matrix typ a
+ Numeric.LAPACK.Matrix: fromRowContainer :: (C f, C width, Eq width, Storable a) => width -> f (Vector width a) -> General (Shape f) width a
+ Numeric.LAPACK.Matrix: fromRowsNonEmptyContainer :: (f ~ T g, C g, C width, Eq width, Storable a) => f (Vector width a) -> General (Shape f) width a
+ Numeric.LAPACK.Matrix: identityFrom :: (SquareShape shape, ShapeOrder shape, Floating a) => ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix: identityFromHeight :: (ShapeOrder shape, Box shape, HeightOf shape ~ HeightOf typ, SquareShape typ, Floating a) => ArrayMatrix shape a -> Matrix typ a
+ Numeric.LAPACK.Matrix: identityFromWidth :: (ShapeOrder shape, Box shape, WidthOf shape ~ HeightOf typ, SquareShape typ, Floating a) => ArrayMatrix shape a -> Matrix typ a
+ Numeric.LAPACK.Matrix: indices :: (Box typ, HeightOf typ ~ height, Indexed height, WidthOf typ ~ width, Indexed width) => Matrix typ a -> [(Index height, Index width)]
+ Numeric.LAPACK.Matrix: kronecker :: (C vert, C horiz, C heightA, C widthA, C heightB, C widthB, Floating a) => Full vert horiz heightA widthA a -> Full vert horiz heightB widthB a -> Full vert horiz (heightA, heightB) (widthA, widthB) a
+ Numeric.LAPACK.Matrix: leftBias :: OrderBias
+ Numeric.LAPACK.Matrix: map :: (C vert, C horiz, C height, C width, Storable a, Storable b) => (a -> b) -> Full vert horiz height width a -> Full vert horiz height width b
+ Numeric.LAPACK.Matrix: mapShape :: (C sh0, C sh1) => (sh0 -> sh1) -> ArrayMatrix sh0 a -> ArrayMatrix sh1 a
+ Numeric.LAPACK.Matrix: multiplySquare :: (MultiplySquare typ, HeightOf typ ~ height, Eq height, C width, C horiz, C vert, Floating a) => Transposition -> Matrix typ a -> Full vert horiz height width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: negate :: (Homogeneous shape, Floating a) => ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix: power :: (Power typ, Floating a) => Int -> Matrix typ a -> Matrix typ a
+ Numeric.LAPACK.Matrix: reshape :: (C sh0, C sh1) => sh1 -> ArrayMatrix sh0 a -> ArrayMatrix sh1 a
+ Numeric.LAPACK.Matrix: rightBias :: OrderBias
+ Numeric.LAPACK.Matrix: rowArgAbsMaximums :: (C vert, C horiz, C height, InvIndexed width, Index width ~ ix, Storable ix, Floating a) => Full vert horiz height width a -> (Vector height ix, Vector height a)
+ Numeric.LAPACK.Matrix: scale :: (Scale shape, Floating a) => a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix: scaleReal :: (Homogeneous shape, Floating a) => RealOf a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix: scaleRealReal :: (Homogeneous shape, Real a) => a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix: shapeInt :: Int -> ShapeInt
+ Numeric.LAPACK.Matrix: solveLeft :: (Solve typ, WidthOf typ ~ width, Eq width, C height, C horiz, C vert, Floating a) => Full vert horiz height width a -> Matrix typ a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: solveRight :: (Solve typ, HeightOf typ ~ height, Eq height, C width, C horiz, C vert, Floating a) => Matrix typ a -> Full vert horiz height width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: square :: (Power typ, Floating a) => Matrix typ a -> Matrix typ a
+ Numeric.LAPACK.Matrix: takeBottom :: (C vert, C height0, C height1, C width, Floating a) => Full vert Big (height0 :+: height1) width a -> Full vert Big height1 width a
+ Numeric.LAPACK.Matrix: takeDiagonal :: (SquareShape typ, HeightOf typ ~ sh, Floating a) => Matrix typ a -> Vector sh a
+ Numeric.LAPACK.Matrix: takeLeft :: (C vert, C height, C width0, C width1, Floating a) => Full Big vert height (width0 :+: width1) a -> Full Big vert height width0 a
+ Numeric.LAPACK.Matrix: takeRight :: (C vert, C height, C width0, C width1, Floating a) => Full Big vert height (width0 :+: width1) a -> Full Big vert height width1 a
+ Numeric.LAPACK.Matrix: takeTop :: (C vert, C height0, C height1, C width, Floating a) => Full vert Big (height0 :+: height1) width a -> Full vert Big height0 width a
+ Numeric.LAPACK.Matrix: tallFromGeneral :: (C height, C width, Storable a) => General height width a -> Tall height width a
+ Numeric.LAPACK.Matrix: toColumnContainer :: (C vert, C horiz, C height, C f, Floating a) => Full vert horiz height (Shape f) a -> f (Vector height a)
+ Numeric.LAPACK.Matrix: toComplex :: (Complex typ, Floating a) => Matrix typ a -> Matrix typ (ComplexOf a)
+ Numeric.LAPACK.Matrix: toRowContainer :: (C vert, C horiz, C f, C width, Floating a) => Full vert horiz (Shape f) width a -> f (Vector width a)
+ Numeric.LAPACK.Matrix: toSquare :: (SquareShape typ, HeightOf typ ~ sh, Floating a) => Matrix typ a -> Square sh a
+ Numeric.LAPACK.Matrix: trace :: (SquareShape typ, HeightOf typ ~ sh, C sh, Floating a) => Matrix typ a -> a
+ Numeric.LAPACK.Matrix: type Diagonal sh = FlexDiagonal NonUnit sh
+ Numeric.LAPACK.Matrix: type Hermitian sh = ArrayMatrix (Hermitian sh)
+ Numeric.LAPACK.Matrix: type Lower sh = FlexLower NonUnit sh
+ Numeric.LAPACK.Matrix: type Permutation sh = Matrix (Permutation sh)
+ Numeric.LAPACK.Matrix: type ShapeInt = ZeroBased Int
+ Numeric.LAPACK.Matrix: type Square sh = ArrayMatrix (Square sh)
+ Numeric.LAPACK.Matrix: type Symmetric sh = FlexSymmetric NonUnit sh
+ Numeric.LAPACK.Matrix: type Triangular lo diag up sh = ArrayMatrix (Triangular lo diag up sh)
+ Numeric.LAPACK.Matrix: type Upper sh = FlexUpper NonUnit sh
+ Numeric.LAPACK.Matrix: wideFromGeneral :: (C height, C width, Storable a) => General height width a -> Wide height width a
+ Numeric.LAPACK.Matrix: zero :: (Homogeneous shape, Floating a) => shape -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix.Array: (#+#) :: (Additive shape, Floating a) => ArrayMatrix shape a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix.Array: (#-#) :: (Additive shape, Floating a) => ArrayMatrix shape a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix.Array: (.*#) :: (Scale shape, Floating a) => a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix.Array: adaptOrder :: (ShapeOrder shape, Floating a) => ArrayMatrix shape a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix.Array: add :: (Additive shape, Floating a) => ArrayMatrix shape a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix.Array: class (Homogeneous shape, Eq shape) => Additive shape where sub a = add a . negate
+ Numeric.LAPACK.Matrix.Array: class C shape => Complex shape where conjugate = conjugate fromReal = fromReal toComplex = toComplex
+ Numeric.LAPACK.Matrix.Array: class SquareShape shape => Determinant shape
+ Numeric.LAPACK.Matrix.Array: class C shape => Homogeneous shape where zero = zero negate = negate scaleReal = scaleReal
+ Numeric.LAPACK.Matrix.Array: class (Solve shape, Power shape) => Inverse shape
+ Numeric.LAPACK.Matrix.Array: class (C shapeA, C shapeB) => Multiply shapeA shapeB
+ Numeric.LAPACK.Matrix.Array: class SquareShape shape => MultiplySquare shape where transposableSquare NonTransposed a b = squareFull a b transposableSquare Transposed a b = transpose $ fullSquare (transpose b) a squareFull = transposableSquare NonTransposed fullSquare = swapMultiply $ transposableSquare Transposed
+ Numeric.LAPACK.Matrix.Array: class Box shape => MultiplyVector shape
+ Numeric.LAPACK.Matrix.Array: class SquareShape shape => Power shape
+ Numeric.LAPACK.Matrix.Array: class C shape => ShapeOrder shape
+ Numeric.LAPACK.Matrix.Array: class SquareShape shape => Solve shape where solve NonTransposed a b = solveRight a b solve Transposed a b = transpose $ solveLeft (transpose b) a solveRight = solve NonTransposed solveLeft = swapMultiply $ solve Transposed
+ Numeric.LAPACK.Matrix.Array: class (Box shape, HeightOf shape ~ WidthOf shape) => SquareShape shape
+ Numeric.LAPACK.Matrix.Array: data Array shape
+ Numeric.LAPACK.Matrix.Array: forceOrder :: (ShapeOrder shape, Floating a) => Order -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix.Array: fromVector :: (Admissible sh, Floating a) => Array sh a -> ArrayMatrix sh a
+ Numeric.LAPACK.Matrix.Array: instance (Show shape, Show a, Storable a, C shape) => Show (Matrix (Array shape) a)
+ Numeric.LAPACK.Matrix.Array: instance Box sh => Box (Array sh)
+ Numeric.LAPACK.Matrix.Array: instance FormatArray sh => FormatMatrix (Array sh)
+ Numeric.LAPACK.Matrix.Array: instance MultiplySame sh => MultiplySame (Array sh)
+ Numeric.LAPACK.Matrix.Array: instance NFData shape => NFData (Array shape)
+ Numeric.LAPACK.Matrix.Array: lift0 :: Array shA a -> ArrayMatrix shA a
+ Numeric.LAPACK.Matrix.Array: lift1 :: (Array shA a -> Array shB b) -> ArrayMatrix shA a -> ArrayMatrix shB b
+ Numeric.LAPACK.Matrix.Array: lift2 :: (Array shA a -> Array shB b -> Array shC c) -> ArrayMatrix shA a -> ArrayMatrix shB b -> ArrayMatrix shC c
+ Numeric.LAPACK.Matrix.Array: lift3 :: (Array shA a -> Array shB b -> Array shC c -> Array shD d) -> ArrayMatrix shA a -> ArrayMatrix shB b -> ArrayMatrix shC c -> ArrayMatrix shD d
+ Numeric.LAPACK.Matrix.Array: lift4 :: (Array shA a -> Array shB b -> Array shC c -> Array shD d -> Array shE e) -> ArrayMatrix shA a -> ArrayMatrix shB b -> ArrayMatrix shC c -> ArrayMatrix shD d -> ArrayMatrix shE e
+ Numeric.LAPACK.Matrix.Array: mapShape :: (C sh0, C sh1) => (sh0 -> sh1) -> ArrayMatrix sh0 a -> ArrayMatrix sh1 a
+ Numeric.LAPACK.Matrix.Array: negate :: (Homogeneous shape, Floating a) => ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix.Array: reshape :: (C sh0, C sh1) => sh1 -> ArrayMatrix sh0 a -> ArrayMatrix sh1 a
+ Numeric.LAPACK.Matrix.Array: scale :: (Scale shape, Floating a) => a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix.Array: scaleReal :: (Homogeneous shape, Floating a) => RealOf a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix.Array: scaleRealReal :: (Homogeneous shape, Real a) => a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix.Array: shape :: ArrayMatrix sh a -> sh
+ Numeric.LAPACK.Matrix.Array: shapeOrder :: ShapeOrder shape => shape -> Order
+ Numeric.LAPACK.Matrix.Array: sub :: (Additive shape, Floating a) => ArrayMatrix shape a -> ArrayMatrix shape a -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix.Array: toVector :: ArrayMatrix sh a -> Array sh a
+ Numeric.LAPACK.Matrix.Array: type ArrayMatrix shape = Matrix (Array shape)
+ Numeric.LAPACK.Matrix.Array: type Full vert horiz height width = ArrayMatrix (Full vert horiz height width)
+ Numeric.LAPACK.Matrix.Array: type General height width = ArrayMatrix (General height width)
+ Numeric.LAPACK.Matrix.Array: type Square sh = ArrayMatrix (Square sh)
+ Numeric.LAPACK.Matrix.Array: type Tall height width = ArrayMatrix (Tall height width)
+ Numeric.LAPACK.Matrix.Array: type Wide height width = ArrayMatrix (Wide height width)
+ Numeric.LAPACK.Matrix.Array: unlift1 :: (ArrayMatrix shA a -> ArrayMatrix shB b) -> Array shA a -> Array shB b
+ Numeric.LAPACK.Matrix.Array: unlift2 :: (ArrayMatrix shA a -> ArrayMatrix shB b -> ArrayMatrix shC c) -> Array shA a -> Array shB b -> Array shC c
+ Numeric.LAPACK.Matrix.Array: unliftColumn :: Order -> (General height0 () a -> General height1 () b) -> Vector height0 a -> Vector height1 b
+ Numeric.LAPACK.Matrix.Array: unliftRow :: Order -> (General () height0 a -> General () height1 b) -> Vector height0 a -> Vector height1 b
+ Numeric.LAPACK.Matrix.Array: zero :: (Homogeneous shape, Floating a) => shape -> ArrayMatrix shape a
+ Numeric.LAPACK.Matrix.Banded: type Hermitian offDiag sh = ArrayMatrix (BandedHermitian offDiag sh)
+ Numeric.LAPACK.Matrix.BandedHermitian: gramian :: (C size, Eq size, Floating a, Natural sub, Natural super) => Square sub super size a -> BandedHermitian (sub :+: super) size a
+ Numeric.LAPACK.Matrix.BandedHermitian: size :: BandedHermitian offDiag sh a -> sh
+ Numeric.LAPACK.Matrix.Extent: appendAny :: (C vertA, C vertB) => AppendMode vertA vertB (Append vertA vertB) height widthA widthB
+ Numeric.LAPACK.Matrix.Extent: appendLeft :: C vert => AppendMode vert Big vert height widthA widthB
+ Numeric.LAPACK.Matrix.Extent: appendRight :: C vert => AppendMode Big vert vert height widthA widthB
+ Numeric.LAPACK.Matrix.Extent: appendSame :: C vert => AppendMode vert vert vert height widthA widthB
+ Numeric.LAPACK.Matrix.Extent: class (C vert, C horiz) => GeneralTallWide vert horiz
+ Numeric.LAPACK.Matrix.Extent: data AppendMode vertA vertB vertC height widthA widthB
+ Numeric.LAPACK.Matrix.Hermitian: (*%%%#) :: (C sh0, Eq sh0, C sh1, Eq sh1, Floating a) => (Hermitian sh0 a, General sh0 sh1 a) -> Hermitian sh1 a -> Hermitian (sh0 :+: sh1) a
+ Numeric.LAPACK.Matrix.Hermitian: anticommutator :: (C vert, C horiz, C height, Eq height, C width, Eq width, Floating a) => Full vert horiz height width a -> Full vert horiz height width a -> Hermitian width a
+ Numeric.LAPACK.Matrix.Hermitian: anticommutatorAdjoint :: (C vert, C horiz, C height, Eq height, C width, Eq width, Floating a) => Full vert horiz height width a -> Full vert horiz height width a -> Hermitian height a
+ Numeric.LAPACK.Matrix.Hermitian: congruence :: (C height, Eq height, C width, Floating a) => Hermitian height a -> General height width a -> Hermitian width a
+ Numeric.LAPACK.Matrix.Hermitian: congruenceAdjoint :: (C height, C width, Eq width, Floating a) => General height width a -> Hermitian width a -> Hermitian height a
+ Numeric.LAPACK.Matrix.Hermitian: congruenceDiagonal :: (C height, Eq height, C width, Floating a) => Vector height (RealOf a) -> General height width a -> Hermitian width a
+ Numeric.LAPACK.Matrix.Hermitian: congruenceDiagonalAdjoint :: (C height, C width, Eq width, Floating a) => General height width a -> Vector width (RealOf a) -> Hermitian height a
+ Numeric.LAPACK.Matrix.Hermitian: gramian :: (C height, C width, Floating a) => General height width a -> Hermitian width a
+ Numeric.LAPACK.Matrix.Hermitian: gramianAdjoint :: (C height, C width, Floating a) => General height width a -> Hermitian height a
+ Numeric.LAPACK.Matrix.Hermitian: size :: Hermitian sh a -> sh
+ Numeric.LAPACK.Matrix.Hermitian: split :: (C sh0, C sh1, Floating a) => Hermitian (sh0 :+: sh1) a -> (Hermitian sh0 a, General sh0 sh1 a, Hermitian sh1 a)
+ Numeric.LAPACK.Matrix.Hermitian: takeBottomRight :: (C sh0, C sh1, Floating a) => Hermitian (sh0 :+: sh1) a -> Hermitian sh1 a
+ Numeric.LAPACK.Matrix.Hermitian: takeTopLeft :: (C sh0, C sh1, Floating a) => Hermitian (sh0 :+: sh1) a -> Hermitian sh0 a
+ Numeric.LAPACK.Matrix.Hermitian: takeTopRight :: (C sh0, C sh1, Floating a) => Hermitian (sh0 :+: sh1) a -> General sh0 sh1 a
+ Numeric.LAPACK.Matrix.Permutation: Inverted :: Inversion
+ Numeric.LAPACK.Matrix.Permutation: NonInverted :: Inversion
+ Numeric.LAPACK.Matrix.Permutation: data Inversion
+ Numeric.LAPACK.Matrix.Permutation: data Permutation sh
+ Numeric.LAPACK.Matrix.Permutation: determinant :: (C sh, Floating a) => Matrix (Permutation sh) a -> a
+ Numeric.LAPACK.Matrix.Permutation: fromPermutation :: C sh => Permutation sh -> Matrix (Permutation sh) a
+ Numeric.LAPACK.Matrix.Permutation: identity :: C sh => sh -> Matrix (Permutation sh) a
+ Numeric.LAPACK.Matrix.Permutation: inversionFromTransposition :: Transposition -> Inversion
+ Numeric.LAPACK.Matrix.Permutation: multiplyFull :: (C vert, C horiz, C height, Eq height, C width, Floating a) => Inversion -> Matrix (Permutation height) a -> Full vert horiz height width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix.Permutation: multiplyVector :: (C size, Eq size, Floating a) => Inversion -> Matrix (Permutation size) a -> Vector size a -> Vector size a
+ Numeric.LAPACK.Matrix.Permutation: size :: Matrix (Permutation sh) a -> sh
+ Numeric.LAPACK.Matrix.Permutation: toMatrix :: (C sh, Floating a) => Matrix (Permutation sh) a -> Square sh a
+ Numeric.LAPACK.Matrix.Permutation: toPermutation :: C sh => Matrix (Permutation sh) a -> Permutation sh
+ Numeric.LAPACK.Matrix.Permutation: transpose :: C sh => Matrix (Permutation sh) a -> Matrix (Permutation sh) a
+ Numeric.LAPACK.Matrix.Shape: switchDiagUpLo :: DiagUpLoC lo up => f Empty Empty -> f Empty Filled -> f Filled Empty -> f lo up
+ Numeric.LAPACK.Matrix.Special: type Inverse typ = Matrix (Inverse typ)
+ Numeric.LAPACK.Matrix.Special: type Scale sh = Matrix (Scale sh)
+ Numeric.LAPACK.Matrix.Square: (|=|) :: (C vert, C horiz, C sizeA, Eq sizeA, C sizeB, Eq sizeB, Floating a) => (Square sizeA a, Full vert horiz sizeA sizeB a) -> (Full horiz vert sizeB sizeA a, Square sizeB a) -> Square (sizeA :+: sizeB) a
+ Numeric.LAPACK.Matrix.Square: congruence :: (C height, Eq height, C width, Floating a) => Square height a -> General height width a -> Square width a
+ Numeric.LAPACK.Matrix.Square: congruenceAdjoint :: (C height, C width, Eq width, Floating a) => General height width a -> Square width a -> Square height a
+ Numeric.LAPACK.Matrix.Square: mapSize :: (sh0 -> sh1) -> Square sh0 a -> Square sh1 a
+ Numeric.LAPACK.Matrix.Square: schurComplex :: (C sh, Real a, Complex a ~ ac) => Square sh ac -> (Square sh ac, Upper sh ac)
+ Numeric.LAPACK.Matrix.Square: stack :: (C vert, C horiz, C sizeA, Eq sizeA, C sizeB, Eq sizeB, Floating a) => Square sizeA a -> Full vert horiz sizeA sizeB a -> Full horiz vert sizeB sizeA a -> Square sizeB a -> Square (sizeA :+: sizeB) a
+ Numeric.LAPACK.Matrix.Triangular: (#%%%#) :: (TriDiag diag, C sh0, Eq sh0, C sh1, Eq sh1, Floating a) => (FlexSymmetric diag sh0 a, General sh0 sh1 a) -> FlexSymmetric diag sh1 a -> FlexSymmetric diag (sh0 :+: sh1) a
+ Numeric.LAPACK.Matrix.Triangular: (#%%%) :: (TriDiag diag, C sh0, Eq sh0, C sh1, Eq sh1, Floating a) => FlexLower diag sh0 a -> (General sh1 sh0 a, FlexLower diag sh1 a) -> FlexLower diag (sh0 :+: sh1) a
+ Numeric.LAPACK.Matrix.Triangular: (%%%#) :: (TriDiag diag, C sh0, Eq sh0, C sh1, Eq sh1, Floating a) => (FlexUpper diag sh0 a, General sh0 sh1 a) -> FlexUpper diag sh1 a -> FlexUpper diag (sh0 :+: sh1) a
+ Numeric.LAPACK.Matrix.Triangular: (%%%) :: (TriDiag diag, C sh0, C sh1, Floating a) => FlexDiagonal diag sh0 a -> FlexDiagonal diag sh1 a -> FlexDiagonal diag (sh0 :+: sh1) a
+ Numeric.LAPACK.Matrix.Triangular: requireNonUnitDiagonal :: Triangular lo NonUnit up sh a -> Triangular lo NonUnit up sh a
+ Numeric.LAPACK.Matrix.Triangular: requireUnitDiagonal :: Triangular lo Unit up sh a -> Triangular lo Unit up sh a
+ Numeric.LAPACK.Matrix.Triangular: splitDiagonal :: (TriDiag diag, C sh0, C sh1, Floating a) => FlexDiagonal diag (sh0 :+: sh1) a -> (FlexDiagonal diag sh0 a, FlexDiagonal diag sh1 a)
+ Numeric.LAPACK.Matrix.Triangular: splitLower :: (TriDiag diag, C sh0, Eq sh0, C sh1, Eq sh1, Floating a) => FlexLower diag (sh0 :+: sh1) a -> (FlexLower diag sh0 a, General sh1 sh0 a, FlexLower diag sh1 a)
+ Numeric.LAPACK.Matrix.Triangular: splitSymmetric :: (TriDiag diag, C sh0, Eq sh0, C sh1, Eq sh1, Floating a) => FlexSymmetric diag (sh0 :+: sh1) a -> (FlexSymmetric diag sh0 a, General sh0 sh1 a, FlexSymmetric diag sh1 a)
+ Numeric.LAPACK.Matrix.Triangular: splitUpper :: (TriDiag diag, C sh0, Eq sh0, C sh1, Eq sh1, Floating a) => FlexUpper diag (sh0 :+: sh1) a -> (FlexUpper diag sh0 a, General sh0 sh1 a, FlexUpper diag sh1 a)
+ Numeric.LAPACK.Matrix.Triangular: stackDiagonal :: (TriDiag diag, C sh0, C sh1, Floating a) => FlexDiagonal diag sh0 a -> FlexDiagonal diag sh1 a -> FlexDiagonal diag (sh0 :+: sh1) a
+ Numeric.LAPACK.Matrix.Triangular: takeBottomLeft :: (TriDiag diag, Content up, C sh0, C sh1, Floating a) => Triangular Filled diag up (sh0 :+: sh1) a -> General sh1 sh0 a
+ Numeric.LAPACK.Matrix.Triangular: takeBottomRight :: (Content lo, TriDiag diag, Content up, C sh0, C sh1, Floating a) => Triangular lo diag up (sh0 :+: sh1) a -> Triangular lo diag up sh1 a
+ Numeric.LAPACK.Matrix.Triangular: takeTopLeft :: (Content lo, TriDiag diag, Content up, C sh0, C sh1, Floating a) => Triangular lo diag up (sh0 :+: sh1) a -> Triangular lo diag up sh0 a
+ Numeric.LAPACK.Matrix.Triangular: takeTopRight :: (Content lo, TriDiag diag, C sh0, C sh1, Floating a) => Triangular lo diag Filled (sh0 :+: sh1) a -> General sh0 sh1 a
+ Numeric.LAPACK.Matrix.Triangular: type FlexDiagonal diag sh = ArrayMatrix (Triangular Empty diag Empty sh)
+ Numeric.LAPACK.Matrix.Triangular: type PowerContentDiag lo diag up = (Content lo, Content up, TriDiag diag, PowerDiag lo up diag ~ diag, PowerDiag up lo diag ~ diag)
+ Numeric.LAPACK.Orthogonal: householderTall :: (C vert, C height, C width, Floating a) => Full vert Small height width a -> (Full vert Small height width a, Upper width a)
+ Numeric.LAPACK.Orthogonal.Householder: type Householder vert horiz height width = Matrix (Hh vert horiz height width)
+ Numeric.LAPACK.Output: (/+/) :: Output out => out -> out -> out
+ Numeric.LAPACK.Output: (<+>) :: Output out => out -> out -> out
+ Numeric.LAPACK.Output: above :: Output out => out -> out -> out
+ Numeric.LAPACK.Output: beside :: Output out => out -> out -> out
+ Numeric.LAPACK.Output: class Output out
+ Numeric.LAPACK.Output: formatAligned :: (Output out, Foldable f) => [[f out]] -> out
+ Numeric.LAPACK.Output: formatRow, formatColumn :: Output out => [out] -> out
+ Numeric.LAPACK.Output: formatSeparateTriangle :: (Output out, Foldable f) => [[f out]] -> out
+ Numeric.LAPACK.Output: hyper :: Html -> Graphic
+ Numeric.LAPACK.Output: instance Eq Separator
+ Numeric.LAPACK.Output: instance Ord Separator
+ Numeric.LAPACK.Output: instance Output Box
+ Numeric.LAPACK.Output: instance Output Html
+ Numeric.LAPACK.Output: instance Show Separator
+ Numeric.LAPACK.Output: text :: Output out => String -> out
+ Numeric.LAPACK.Permutation: Element :: CInt -> Element sh
+ Numeric.LAPACK.Permutation: Negative :: Sign
+ Numeric.LAPACK.Permutation: Positive :: Sign
+ Numeric.LAPACK.Permutation: Shape :: sh -> Shape sh
+ Numeric.LAPACK.Permutation: data Sign
+ Numeric.LAPACK.Permutation: identity :: C sh => sh -> Permutation sh
+ Numeric.LAPACK.Permutation: inversionFromTransposition :: Transposition -> Inversion
+ Numeric.LAPACK.Permutation: newtype Element sh
+ Numeric.LAPACK.Permutation: newtype Shape sh
+ Numeric.LAPACK.Permutation: size :: Permutation sh -> sh
+ Numeric.LAPACK.Scalar: equal :: Floating a => a -> a -> Bool
+ Numeric.LAPACK.Scalar: toComplex :: Floating a => a -> ComplexOf a
+ Numeric.LAPACK.Shape: Min :: sh0 -> sh1 -> Min sh0 sh1
+ Numeric.LAPACK.Shape: data Min sh0 sh1
+ Numeric.LAPACK.Shape: instance (C sh0, C sh1) => C (Min sh0 sh1)
+ Numeric.LAPACK.Shape: instance (C sh0, Indexed sh1) => Indexed (Min sh0 sh1)
+ Numeric.LAPACK.Shape: instance (C sh0, InvIndexed sh1) => InvIndexed (Min sh0 sh1)
+ Numeric.LAPACK.Shape: instance (Eq sh0, Eq sh1) => Eq (Min sh0 sh1)
+ Numeric.LAPACK.Shape: instance (Show sh0, Show sh1) => Show (Min sh0 sh1)
+ Numeric.LAPACK.Shape: minShape0 :: Min sh0 sh1 -> sh0
+ Numeric.LAPACK.Shape: minShape1 :: Min sh0 sh1 -> sh1
+ Numeric.LAPACK.ShapeStatic: instance Natural n => Static (ZeroBased n)
+ Numeric.LAPACK.Singular: decomposePolar :: (C vert, C horiz, C height, C width, Floating a) => Full vert horiz height width a -> (Full vert horiz height width a, Hermitian width a)
+ Numeric.LAPACK.Vector: (+++) :: (C shx, C shy, Storable a) => Vector shx a -> Vector shy a -> Vector (shx :+: shy) a
+ Numeric.LAPACK.Vector: (-*|) :: (C sh, Eq sh, Floating a) => Vector sh a -> Vector sh a -> a
+ Numeric.LAPACK.Vector: (.*|) :: (C sh, Floating a) => a -> Vector sh a -> Vector sh a
+ Numeric.LAPACK.Vector: (|+|) :: (C sh, Eq sh, Floating a) => Vector sh a -> Vector sh a -> Vector sh a
+ Numeric.LAPACK.Vector: (|-|) :: (C sh, Eq sh, Floating a) => Vector sh a -> Vector sh a -> Vector sh a
+ Numeric.LAPACK.Vector: argLimits :: (InvIndexed sh, Index sh ~ ix, Real a) => Vector sh a -> ((ix, a), (ix, a))
+ Numeric.LAPACK.Vector: argMaximum :: (InvIndexed sh, Index sh ~ ix, Real a) => Vector sh a -> (ix, a)
+ Numeric.LAPACK.Vector: argMinimum :: (InvIndexed sh, Index sh ~ ix, Real a) => Vector sh a -> (ix, a)
+ Numeric.LAPACK.Vector: divide :: (C sh, Eq sh, Floating a) => Vector sh a -> Vector sh a -> Vector sh a
+ Numeric.LAPACK.Vector: foldMap :: (C sh, Storable a, Ord a, Semigroup m) => (a -> m) -> Array sh a -> m
+ Numeric.LAPACK.Vector: foldl :: (C sh, Storable a) => (b -> a -> b) -> b -> Array sh a -> b
+ Numeric.LAPACK.Vector: foldl1 :: (C sh, Storable a) => (a -> a -> a) -> Array sh a -> a
+ Numeric.LAPACK.Vector: imaginaryPart :: (C sh, Real a) => Vector sh (Complex a) -> Vector sh a
+ Numeric.LAPACK.Vector: limits :: (C sh, Real a) => Vector sh a -> (a, a)
+ Numeric.LAPACK.Vector: maximum :: (C sh, Real a) => Vector sh a -> a
+ Numeric.LAPACK.Vector: minimum :: (C sh, Real a) => Vector sh a -> a
+ Numeric.LAPACK.Vector: negate :: (C sh, Floating a) => Vector sh a -> Vector sh a
+ Numeric.LAPACK.Vector: norm2Squared :: (C sh, Floating a) => Vector sh a -> RealOf a
+ Numeric.LAPACK.Vector: one :: (C sh, Floating a) => sh -> Vector sh a
+ Numeric.LAPACK.Vector: raise :: (C sh, Floating a) => a -> Array sh a -> Array sh a
+ Numeric.LAPACK.Vector: recip :: (C sh, Floating a) => Vector sh a -> Vector sh a
+ Numeric.LAPACK.Vector: zero :: (C sh, Floating a) => sh -> Vector sh a
- Numeric.LAPACK.Format: format :: Format a => String -> a -> Box
+ Numeric.LAPACK.Format: format :: (Format a, Output out) => String -> a -> out
- Numeric.LAPACK.Format: formatArray :: (FormatArray sh, Floating a) => String -> Array sh a -> Box
+ Numeric.LAPACK.Format: formatArray :: (FormatArray sh, Floating a, Output out) => String -> Array sh a -> out
- Numeric.LAPACK.Linear.LowerUpper: determinant :: (C sh, Floating a, Eq a) => Square sh a -> a
+ Numeric.LAPACK.Linear.LowerUpper: determinant :: (C sh, Floating a) => Square sh a -> a
- Numeric.LAPACK.Linear.LowerUpper: extractP :: (C vert, C horiz, C height) => Inversion -> LowerUpper vert horiz height width a -> Permutation height
+ Numeric.LAPACK.Linear.LowerUpper: extractP :: (C vert, C horiz, C height, C width) => Inversion -> LowerUpper vert horiz height width a -> Permutation height a
- Numeric.LAPACK.Matrix: (#!) :: (Indexed sh, Floating a) => Array sh a -> (Index (HeightOf sh), Index (WidthOf sh)) -> a
+ Numeric.LAPACK.Matrix: (#!) :: (Indexed typ, Floating a) => Matrix typ a -> (Index (HeightOf typ), Index (WidthOf typ)) -> a
- Numeric.LAPACK.Matrix: (===) :: (C horiz, C width, Eq width, C heighta, C heightb, Floating a) => Full Big horiz heighta width a -> Full Big horiz heightb width a -> Full Big horiz (heighta :+: heightb) width a
+ Numeric.LAPACK.Matrix: (===) :: (C horizA, C horizB, C horizC, Append horizA horizB ~ horizC, C width, Eq width, C heightA, C heightB, Floating a) => Full Big horizA heightA width a -> Full Big horizB heightB width a -> Full Big horizC (heightA :+: heightB) width a
- Numeric.LAPACK.Matrix: (|||) :: (C vert, C height, Eq height, C widtha, C widthb, Floating a) => Full vert Big height widtha a -> Full vert Big height widthb a -> Full vert Big height (widtha :+: widthb) a
+ Numeric.LAPACK.Matrix: (|||) :: (C vertA, C vertB, C vertC, Append vertA vertB ~ vertC, C height, Eq height, C widthA, C widthB, Floating a) => Full vertA Big height widthA a -> Full vertB Big height widthB a -> Full vertC Big height (widthA :+: widthB) a
- Numeric.LAPACK.Matrix: adaptOrder :: (C vert, C horiz, C height, C width, Floating a) => Full vert horiz height width a -> Full vert horiz height width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: adaptOrder :: (ShapeOrder shape, Floating a) => ArrayMatrix shape a -> ArrayMatrix shape a -> ArrayMatrix shape a
- Numeric.LAPACK.Matrix: add :: (C vert, C horiz, C height, C width, Eq height, Eq width, Floating a) => Full vert horiz height width a -> Full vert horiz height width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: add :: (Additive shape, Floating a) => ArrayMatrix shape a -> ArrayMatrix shape a -> ArrayMatrix shape a
- Numeric.LAPACK.Matrix: class Box sh => Indexed sh
+ Numeric.LAPACK.Matrix: class Box typ => Indexed typ
- Numeric.LAPACK.Matrix: class Solve shape => Inverse shape
+ Numeric.LAPACK.Matrix: class (Solve typ, Power typ) => Inverse typ
- Numeric.LAPACK.Matrix: class (C shapeA, C shapeB) => Multiply shapeA shapeB
+ Numeric.LAPACK.Matrix: class (Box typA, Box typB) => Multiply typA typB
- Numeric.LAPACK.Matrix: class C shape => Solve shape
+ Numeric.LAPACK.Matrix: class (Box typ, HeightOf typ ~ WidthOf typ) => Solve typ where solve NonTransposed a b = solveRight a b solve Transposed a b = transpose $ solveLeft (transpose b) a solveRight = solve NonTransposed solveLeft = swapMultiply $ solve Transposed
- Numeric.LAPACK.Matrix: dropColumns :: (C horiz, C height, Floating a) => Int -> Full Big horiz height ZeroInt a -> Full Big horiz height ZeroInt a
+ Numeric.LAPACK.Matrix: dropColumns :: (C horiz, C height, Floating a) => Int -> Full Big horiz height ShapeInt a -> Full Big horiz height ShapeInt a
- Numeric.LAPACK.Matrix: dropEqually :: (C vert, C horiz, Floating a) => Int -> Full vert horiz ZeroInt ZeroInt a -> Full vert horiz ZeroInt ZeroInt a
+ Numeric.LAPACK.Matrix: dropEqually :: (C vert, C horiz, Floating a) => Int -> Full vert horiz ShapeInt ShapeInt a -> Full vert horiz ShapeInt ShapeInt a
- Numeric.LAPACK.Matrix: dropRows :: (C vert, C width, Floating a) => Int -> Full vert Big ZeroInt width a -> Full vert Big ZeroInt width a
+ Numeric.LAPACK.Matrix: dropRows :: (C vert, C width, Floating a) => Int -> Full vert Big ShapeInt width a -> Full vert Big ShapeInt width a
- Numeric.LAPACK.Matrix: forceOrder :: (C vert, C horiz, C height, C width, Floating a) => Order -> Full vert horiz height width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: forceOrder :: (ShapeOrder shape, Floating a) => Order -> ArrayMatrix shape a -> ArrayMatrix shape a
- Numeric.LAPACK.Matrix: fromColumns :: (C height, Eq height, Storable a) => height -> [Vector height a] -> General height ZeroInt a
+ Numeric.LAPACK.Matrix: fromColumns :: (C height, Eq height, Storable a) => height -> [Vector height a] -> General height ShapeInt a
- Numeric.LAPACK.Matrix: fromColumnsNonEmpty :: (C height, Eq height, Storable a) => T [] (Vector height a) -> General height ZeroInt a
+ Numeric.LAPACK.Matrix: fromColumnsNonEmpty :: (C height, Eq height, Storable a) => T [] (Vector height a) -> General height ShapeInt a
- Numeric.LAPACK.Matrix: fromRows :: (C width, Eq width, Storable a) => width -> [Vector width a] -> General ZeroInt width a
+ Numeric.LAPACK.Matrix: fromRows :: (C width, Eq width, Storable a) => width -> [Vector width a] -> General ShapeInt width a
- Numeric.LAPACK.Matrix: fromRowsNonEmpty :: (C width, Eq width, Storable a) => T [] (Vector width a) -> General ZeroInt width a
+ Numeric.LAPACK.Matrix: fromRowsNonEmpty :: (C width, Eq width, Storable a) => T [] (Vector width a) -> General ShapeInt width a
- Numeric.LAPACK.Matrix: height :: Box shape => Array shape a -> HeightOf shape
+ Numeric.LAPACK.Matrix: height :: Box typ => Matrix typ a -> HeightOf typ
- Numeric.LAPACK.Matrix: inverse :: (Inverse shape, Floating a) => Array shape a -> Array shape a
+ Numeric.LAPACK.Matrix: inverse :: (Inverse typ, Floating a) => Matrix typ a -> Matrix typ a
- Numeric.LAPACK.Matrix: reverseColumns :: (C vert, C horiz, C height, Floating a) => Full vert horiz height ZeroInt a -> Full vert horiz height ZeroInt a
+ Numeric.LAPACK.Matrix: reverseColumns :: (C vert, C horiz, C height, Floating a) => Full vert horiz height ShapeInt a -> Full vert horiz height ShapeInt a
- Numeric.LAPACK.Matrix: reverseRows :: (C vert, C horiz, C width, Floating a) => Full vert horiz ZeroInt width a -> Full vert horiz ZeroInt width a
+ Numeric.LAPACK.Matrix: reverseRows :: (C vert, C horiz, C width, Floating a) => Full vert horiz ShapeInt width a -> Full vert horiz ShapeInt width a
- Numeric.LAPACK.Matrix: solve :: (Solve shape, Floating a, HeightOf shape ~ height, Eq height, C horiz, C vert, C nrhs) => Array shape a -> Full vert horiz height nrhs a -> Full vert horiz height nrhs a
+ Numeric.LAPACK.Matrix: solve :: (Solve typ, HeightOf typ ~ height, Eq height, C width, C horiz, C vert, Floating a) => Transposition -> Matrix typ a -> Full vert horiz height width a -> Full vert horiz height width a
- Numeric.LAPACK.Matrix: solveVector :: (Solve shape, HeightOf shape ~ height, Eq height, Floating a) => Array shape a -> Vector height a -> Vector height a
+ Numeric.LAPACK.Matrix: solveVector :: (Solve typ, HeightOf typ ~ height, Eq height, Floating a) => Transposition -> Matrix typ a -> Vector height a -> Vector height a
- Numeric.LAPACK.Matrix: sub :: (C vert, C horiz, C height, C width, Eq height, Eq width, Floating a) => Full vert horiz height width a -> Full vert horiz height width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix: sub :: (Additive shape, Floating a) => ArrayMatrix shape a -> ArrayMatrix shape a -> ArrayMatrix shape a
- Numeric.LAPACK.Matrix: takeColumns :: (C horiz, C height, Floating a) => Int -> Full Big horiz height ZeroInt a -> Full Big horiz height ZeroInt a
+ Numeric.LAPACK.Matrix: takeColumns :: (C horiz, C height, Floating a) => Int -> Full Big horiz height ShapeInt a -> Full Big horiz height ShapeInt a
- Numeric.LAPACK.Matrix: takeEqually :: (C vert, C horiz, Floating a) => Int -> Full vert horiz ZeroInt ZeroInt a -> Full vert horiz ZeroInt ZeroInt a
+ Numeric.LAPACK.Matrix: takeEqually :: (C vert, C horiz, Floating a) => Int -> Full vert horiz ShapeInt ShapeInt a -> Full vert horiz ShapeInt ShapeInt a
- Numeric.LAPACK.Matrix: takeRows :: (C vert, C width, Floating a) => Int -> Full vert Big ZeroInt width a -> Full vert Big ZeroInt width a
+ Numeric.LAPACK.Matrix: takeRows :: (C vert, C width, Floating a) => Int -> Full vert Big ShapeInt width a -> Full vert Big ShapeInt width a
- Numeric.LAPACK.Matrix: type Full vert horiz height width = Array (Full vert horiz height width)
+ Numeric.LAPACK.Matrix: type Full vert horiz height width = ArrayMatrix (Full vert horiz height width)
- Numeric.LAPACK.Matrix: type General height width = Array (General height width)
+ Numeric.LAPACK.Matrix: type General height width = ArrayMatrix (General height width)
- Numeric.LAPACK.Matrix: type Tall height width = Array (Tall height width)
+ Numeric.LAPACK.Matrix: type Tall height width = ArrayMatrix (Tall height width)
- Numeric.LAPACK.Matrix: type Wide height width = Array (Wide height width)
+ Numeric.LAPACK.Matrix: type Wide height width = ArrayMatrix (Wide height width)
- Numeric.LAPACK.Matrix: width :: Box shape => Array shape a -> WidthOf shape
+ Numeric.LAPACK.Matrix: width :: Box typ => Matrix typ a -> WidthOf typ
- Numeric.LAPACK.Matrix.Banded: adjoint :: (Natural super, Natural sub, C vert, C horiz, C width, C height, Floating a) => Banded sub super vert horiz height width a -> Banded super sub horiz vert width height a
+ Numeric.LAPACK.Matrix.Banded: adjoint :: (Natural sub, Natural super, C vert, C horiz, C height, C width, Floating a) => Banded sub super vert horiz height width a -> Banded super sub horiz vert width height a
- Numeric.LAPACK.Matrix.Banded: diagonal :: (C sh, Floating a) => Vector sh a -> Diagonal sh a
+ Numeric.LAPACK.Matrix.Banded: diagonal :: (C sh, Floating a) => Order -> Vector sh a -> Diagonal sh a
- Numeric.LAPACK.Matrix.Banded: type Banded sub super vert horiz height width = Array (Banded sub super vert horiz height width)
+ Numeric.LAPACK.Matrix.Banded: type Banded sub super vert horiz height width = ArrayMatrix (Banded sub super vert horiz height width)
- Numeric.LAPACK.Matrix.Banded: type General sub super height width = Array (BandedGeneral sub super height width)
+ Numeric.LAPACK.Matrix.Banded: type General sub super height width = ArrayMatrix (BandedGeneral sub super height width)
- Numeric.LAPACK.Matrix.Banded: type Square sub super size = Array (BandedSquare sub super size)
+ Numeric.LAPACK.Matrix.Banded: type Square sub super size = ArrayMatrix (BandedSquare sub super size)
- Numeric.LAPACK.Matrix.BandedHermitian: multiplyFull :: (Natural offDiag, C vert, C horiz, C height, Eq height, C width, Eq width, Floating a) => Transposition -> BandedHermitian offDiag height a -> Full vert horiz height width a -> Full vert horiz height width a
+ Numeric.LAPACK.Matrix.BandedHermitian: multiplyFull :: (Natural offDiag, C vert, C horiz, C height, Eq height, C width, Floating a) => Transposition -> BandedHermitian offDiag height a -> Full vert horiz height width a -> Full vert horiz height width a
- Numeric.LAPACK.Matrix.BandedHermitian: type BandedHermitian offDiag size = Array (BandedHermitian offDiag size)
+ Numeric.LAPACK.Matrix.BandedHermitian: type BandedHermitian offDiag sh = Hermitian offDiag sh
- Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite: decompose :: (Natural offDiag, C size, Floating a) => BandedHermitian offDiag size a -> Upper offDiag size a
+ Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite: decompose :: (Natural offDiag, C size, Floating a) => Hermitian offDiag size a -> Upper offDiag size a
- Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite: determinant :: (Natural offDiag, C size, Floating a) => BandedHermitian offDiag size a -> RealOf a
+ Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite: determinant :: (Natural offDiag, C size, Floating a) => Hermitian offDiag size a -> RealOf a
- Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite: solve :: (Natural offDiag, C size, Eq size, C vert, C horiz, C nrhs, Floating a) => BandedHermitian offDiag size a -> Full vert horiz size nrhs a -> Full vert horiz size nrhs a
+ Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite: solve :: (Natural offDiag, C size, Eq size, C vert, C horiz, C nrhs, Floating a) => Hermitian offDiag size a -> Full vert horiz size nrhs a -> Full vert horiz size nrhs a
- Numeric.LAPACK.Matrix.Hermitian: autoFromList :: Storable a => Order -> [a] -> Hermitian ZeroInt a
+ Numeric.LAPACK.Matrix.Hermitian: autoFromList :: Storable a => Order -> [a] -> Hermitian ShapeInt a
- Numeric.LAPACK.Matrix.Hermitian: type Hermitian sh = Array (Hermitian sh)
+ Numeric.LAPACK.Matrix.Hermitian: type Hermitian sh = ArrayMatrix (Hermitian sh)
- Numeric.LAPACK.Matrix.Square: autoFromList :: Storable a => [a] -> Square ZeroInt a
+ Numeric.LAPACK.Matrix.Square: autoFromList :: Storable a => [a] -> Square ShapeInt a
- Numeric.LAPACK.Matrix.Square: eigensystem :: (C sh, Floating a) => Square sh a -> (Square sh (ComplexOf a), Vector sh (ComplexOf a), Square sh (ComplexOf a))
+ Numeric.LAPACK.Matrix.Square: eigensystem :: (C sh, Floating a, ComplexOf a ~ ac) => Square sh a -> (Square sh ac, Vector sh ac, Square sh ac)
- Numeric.LAPACK.Matrix.Square: type Square sh = Array (Square sh)
+ Numeric.LAPACK.Matrix.Square: type Square sh = ArrayMatrix (Square sh)
- Numeric.LAPACK.Matrix.Triangular: autoDiagonalFromList :: Storable a => Order -> [a] -> Diagonal ZeroInt a
+ Numeric.LAPACK.Matrix.Triangular: autoDiagonalFromList :: Storable a => Order -> [a] -> Diagonal ShapeInt a
- Numeric.LAPACK.Matrix.Triangular: autoFromList :: (Content lo, Content up, Storable a) => Order -> [a] -> Triangular lo NonUnit up ZeroInt a
+ Numeric.LAPACK.Matrix.Triangular: autoFromList :: (Content lo, Content up, Storable a) => Order -> [a] -> Triangular lo NonUnit up ShapeInt a
- Numeric.LAPACK.Matrix.Triangular: autoLowerFromList :: Storable a => Order -> [a] -> Lower ZeroInt a
+ Numeric.LAPACK.Matrix.Triangular: autoLowerFromList :: Storable a => Order -> [a] -> Lower ShapeInt a
- Numeric.LAPACK.Matrix.Triangular: autoSymmetricFromList :: Storable a => Order -> [a] -> Symmetric ZeroInt a
+ Numeric.LAPACK.Matrix.Triangular: autoSymmetricFromList :: Storable a => Order -> [a] -> Symmetric ShapeInt a
- Numeric.LAPACK.Matrix.Triangular: autoUpperFromList :: Storable a => Order -> [a] -> Upper ZeroInt a
+ Numeric.LAPACK.Matrix.Triangular: autoUpperFromList :: Storable a => Order -> [a] -> Upper ShapeInt a
- Numeric.LAPACK.Matrix.Triangular: inverse :: (DiagUpLo lo up, TriDiag diag, C sh, Floating a) => Triangular lo diag up sh a -> Triangular lo diag up sh a
+ Numeric.LAPACK.Matrix.Triangular: inverse :: (Content lo, Content up, TriDiag diag, C sh, Floating a) => Triangular lo diag up sh a -> Triangular lo (PowerDiag lo up diag) up sh a
- Numeric.LAPACK.Matrix.Triangular: square :: (DiagUpLo lo up, TriDiag diag, C sh, Eq sh, Floating a) => Triangular lo diag up sh a -> Triangular lo diag up sh a
+ Numeric.LAPACK.Matrix.Triangular: square :: (Content lo, Content up, TriDiag diag, C sh, Eq sh, Floating a) => Triangular lo diag up sh a -> Triangular lo (PowerDiag lo up diag) up sh a
- Numeric.LAPACK.Matrix.Triangular: type FlexLower diag sh = Array (LowerTriangular diag sh)
+ Numeric.LAPACK.Matrix.Triangular: type FlexLower diag sh = ArrayMatrix (LowerTriangular diag sh)
- Numeric.LAPACK.Matrix.Triangular: type FlexSymmetric diag sh = Array (FlexSymmetric diag sh)
+ Numeric.LAPACK.Matrix.Triangular: type FlexSymmetric diag sh = ArrayMatrix (FlexSymmetric diag sh)
- Numeric.LAPACK.Matrix.Triangular: type FlexUpper diag sh = Array (UpperTriangular diag sh)
+ Numeric.LAPACK.Matrix.Triangular: type FlexUpper diag sh = ArrayMatrix (UpperTriangular diag sh)
- Numeric.LAPACK.Matrix.Triangular: type Symmetric sh = Array (Symmetric sh)
+ Numeric.LAPACK.Matrix.Triangular: type Symmetric sh = FlexSymmetric NonUnit sh
- Numeric.LAPACK.Matrix.Triangular: type Triangular lo diag up sh = Array (Triangular lo diag up sh)
+ Numeric.LAPACK.Matrix.Triangular: type Triangular lo diag up sh = ArrayMatrix (Triangular lo diag up sh)
- Numeric.LAPACK.Orthogonal: complement :: (C height, C width, Floating a) => Tall height width a -> Tall height ZeroInt a
+ Numeric.LAPACK.Orthogonal: complement :: (C height, C width, Floating a) => Tall height width a -> Tall height ShapeInt a
- Numeric.LAPACK.Orthogonal: pseudoInverseRCond :: (C vert, C horiz, C height, Eq height, C width, Eq width, Floating a) => RealOf a -> Full vert horiz height width a -> (Int, Full horiz vert width height a)
+ Numeric.LAPACK.Orthogonal: pseudoInverseRCond :: (C vert, C horiz, C height, C width, Floating a) => RealOf a -> Full vert horiz height width a -> (Int, Full horiz vert width height a)
- Numeric.LAPACK.Orthogonal.Householder: multiplyQ :: (C vertA, C horizA, C widthA, C vertB, C horizB, C widthB, C height, Eq height, Floating a) => Inversion -> Householder vertA horizA height widthA a -> Full vertB horizB height widthB a -> Full vertB horizB height widthB a
+ Numeric.LAPACK.Orthogonal.Householder: multiplyQ :: (C vertA, C horizA, C widthA, C vertB, C horizB, C widthB, C height, Eq height, Floating a) => Transposition -> Conjugation -> Householder vertA horizA height widthA a -> Full vertB horizB height widthB a -> Full vertB horizB height widthB a
- Numeric.LAPACK.Orthogonal.Householder: type General = Householder Big Big
+ Numeric.LAPACK.Orthogonal.Householder: type General height width = Householder Big Big height width
- Numeric.LAPACK.Orthogonal.Householder: type Tall = Householder Big Small
+ Numeric.LAPACK.Orthogonal.Householder: type Tall height width = Householder Big Small height width
- Numeric.LAPACK.Orthogonal.Householder: type Wide = Householder Small Big
+ Numeric.LAPACK.Orthogonal.Householder: type Wide height width = Householder Small Big height width
- Numeric.LAPACK.Permutation: apply :: (C vert, C horiz, C height, Eq height, C width, Floating a) => Bool -> Permutation height -> Full vert horiz height width a -> Full vert horiz height width a
+ Numeric.LAPACK.Permutation: apply :: (C vert, C horiz, C height, Eq height, C width, Floating a) => Inversion -> Permutation height -> Full vert horiz height width a -> Full vert horiz height width a
- Numeric.LAPACK.Permutation: fromPivots :: C sh => Inversion -> sh -> Vector ZeroInt CInt -> Permutation sh
+ Numeric.LAPACK.Permutation: fromPivots :: C sh => Inversion -> Vector (Shape sh) (Element sh) -> Permutation sh
- Numeric.LAPACK.Permutation: toPivots :: C sh => Inversion -> Permutation sh -> Vector sh CInt
+ Numeric.LAPACK.Permutation: toPivots :: C sh => Inversion -> Permutation sh -> Vector sh (Element sh)
- Numeric.LAPACK.Singular: decompose :: (C height, C width, Floating a) => General height width a -> (Square height a, Vector ZeroInt (RealOf a), Square width a)
+ Numeric.LAPACK.Singular: decompose :: (C height, C width, Floating a) => General height width a -> (Square height a, Vector (Min height width) (RealOf a), Square width a)
- Numeric.LAPACK.Singular: decomposeTall :: (C horiz, C height, C width, Floating a) => Full horiz Small height width a -> (Full horiz Small height width a, Vector width (RealOf a), Square width a)
+ Numeric.LAPACK.Singular: decomposeTall :: (C vert, C height, C width, Floating a) => Full vert Small height width a -> (Full vert Small height width a, Vector width (RealOf a), Square width a)
- Numeric.LAPACK.Singular: decomposeWide :: (C vert, C height, C width, Floating a) => Full Small vert height width a -> (Square height a, Vector height (RealOf a), Full Small vert height width a)
+ Numeric.LAPACK.Singular: decomposeWide :: (C horiz, C height, C width, Floating a) => Full Small horiz height width a -> (Square height a, Vector height (RealOf a), Full Small horiz height width a)
- Numeric.LAPACK.Singular: pseudoInverseRCond :: (C vert, C horiz, C height, Eq height, C width, Eq width, Floating a) => RealOf a -> Full vert horiz height width a -> (Int, Full horiz vert width height a)
+ Numeric.LAPACK.Singular: pseudoInverseRCond :: (C vert, C horiz, C height, C width, Floating a) => RealOf a -> Full vert horiz height width a -> (Int, Full horiz vert width height a)
- Numeric.LAPACK.Singular: values :: (C height, C width, Floating a) => General height width a -> Vector ZeroInt (RealOf a)
+ Numeric.LAPACK.Singular: values :: (C height, C width, Floating a) => General height width a -> Vector (Min height width) (RealOf a)
- Numeric.LAPACK.Vector: append :: (C shx, C shy, Storable a) => Vector shx a -> Vector shy a -> Vector (shx :+: shy) a
+ Numeric.LAPACK.Vector: append :: (C shx, C shy, Storable a) => Array shx a -> Array shy a -> Array (:+: shx shy) a
- Numeric.LAPACK.Vector: drop :: Storable a => Int -> Vector ZeroInt a -> Vector ZeroInt a
+ Numeric.LAPACK.Vector: drop :: (Integral n, Storable a) => n -> Array (ZeroBased n) a -> Array (ZeroBased n) a
- Numeric.LAPACK.Vector: singleton :: Storable a => a -> Vector () a
+ Numeric.LAPACK.Vector: singleton :: Storable a => a -> Array () a
- Numeric.LAPACK.Vector: take :: Storable a => Int -> Vector ZeroInt a -> Vector ZeroInt a
+ Numeric.LAPACK.Vector: take :: (Integral n, Storable a) => n -> Array (ZeroBased n) a -> Array (ZeroBased n) a
- Numeric.LAPACK.Vector: takeLeft :: (C sh0, C sh1, Storable a) => Vector (sh0 :+: sh1) a -> Vector sh0 a
+ Numeric.LAPACK.Vector: takeLeft :: (C sh0, C sh1, Storable a) => Array (:+: sh0 sh1) a -> Array sh0 a
- Numeric.LAPACK.Vector: takeRight :: (C sh0, C sh1, Storable a) => Vector (sh0 :+: sh1) a -> Vector sh1 a
+ Numeric.LAPACK.Vector: takeRight :: (C sh0, C sh1, Storable a) => Array (:+: sh0 sh1) a -> Array sh1 a

Files

+ Changes.md view
@@ -0,0 +1,15 @@+# Change log for the `lapack` package++## 0.3++ * Matrix data family++ * `Matrix`: `ZeroInt` -> `ShapeInt`, `zeroInt` -> `shapeInt`++ * `Hermitian`, `BandedHermitian`: `covariance` -> `gramian`++ * `Square.eigensystem`:+   Return left eigenvectors as rows of the last matrix.+   This is adjoint with respect to the definition in `lapack-0.2`+   but it is consistent+   with the other eigenvalue and singular value decompositions.
Makefile view
@@ -1,6 +1,10 @@+all:	ReadMe.html Changes.html+ run-test: 	runhaskell Setup configure --user --enable-tests -fbuildExamples 	runhaskell Setup build 	runhaskell Setup haddock 	./dist/build/lapack-test/lapack-test-	./dist/build/lapack-economic/lapack-economic++%.html: %.md+	pandoc --output=$@ $<
+ ReadMe.md view
@@ -0,0 +1,225 @@+## Installation++Before installing the Haskell bindings+you need to install the BLAS and LAPACK packages.+Please note, that additionally to the reference implementation in FORTRAN 77+there are alternative optimized implementations+like OpenBLAS, ATLAS, Intel MKL.++### Debian, Ubuntu++~~~~+sudo apt-get install libblas-dev liblapack-dev+~~~~++### MacOS++You may install pkgconfig and LAPACK via MacPorts:++~~~~+sudo port install pkgconfig lapack+~~~~++However, the pkg-config files for LAPACK+seem to be installed in a non-standard location.+You must make them visible to pkg-config by++~~~~+export PKG_CONFIG_PATH=/opt/local/lib/lapack/pkgconfig:$PKG_CONFIG_PATH+~~~~++You may set the search PATH permanently by adding+the above command line to your `$HOME/.profile` file.++Alternatively, a solution for all users of your machine+would be to set symbolic links:++~~~~+sudo ln -s /opt/local/lib/lapack/pkgconfig/blas.pc /opt/local/lib/pkgconfig/blas.pc+sudo ln -s /opt/local/lib/lapack/pkgconfig/lapack.pc /opt/local/lib/pkgconfig/lapack.pc+~~~~+++## Introduction++Here is a small example for constructing and formatting matrices:++~~~~+Prelude> import qualified Numeric.LAPACK.Matrix as Matrix+Prelude Matrix> import Numeric.LAPACK.Format as Fmt ((##))+Prelude Matrix Fmt> let a = Matrix.fromList (Matrix.shapeInt 3) (Matrix.shapeInt 4) [(0::Float)..]+Prelude Matrix Fmt> a ## "%.4f"+ 0.0000 1.0000  2.0000  3.0000+ 4.0000 5.0000  6.0000  7.0000+ 8.0000 9.0000 10.0000 11.0000+Prelude Matrix Fmt> import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape+Prelude Matrix Fmt MatrixShape> import qualified Numeric.LAPACK.Matrix.Triangular as Triangular+Prelude Matrix Fmt MatrixShape Triangular> let u = Triangular.upperFromList MatrixShape.RowMajor (Matrix.shapeInt 4) [(0::Float)..]+Prelude Matrix Fmt MatrixShape Triangular> (u, Triangular.transpose u) ## "%.4f"+ 0.0000 1.0000 2.0000 3.0000+        4.0000 5.0000 6.0000+               7.0000 8.0000+                      9.0000++ 0.0000+ 1.0000 4.0000+ 2.0000 5.0000 7.0000+ 3.0000 6.0000 8.0000 9.0000+~~~~++You may find a more complex introductory example at:+<http://code.henning-thielemann.de/bob2019/main.pdf>+++## Formatting++We do not try to do fancy formatting for the `Show` instance.+The `Show` instances of matrices emit plain valid Haskell code in one line+where all numbers are printed in full precision.+If matrices are part of larger Haskell data structures+this kind of formatting works best.+For human-friendly formatting in GHCi you need to add something like `## "%.4f"`+after a matrix or vector expression.+It means: Print all numbers in fixed point representation+using four digits for the fractional part.+You can use the formatting placeholders provided by `printf`.+The matrices have `Hyper` instances for easy usage in+[HyperHaskell](https://hackage.haskell.org/package/hyper-haskell-server).++Formatting is based on the `Output` type class+that currently supports output as+[Text boxes](https://hackage.haskell.org/package/boxes)+for GHCi and+[HTML](https://hackage.haskell.org/package/blaze-html)+for HyperHaskell.+++## Matrix vs. Vector++Vectors are `Storable.Array`s from the+[comfort-array](https://hackage.haskell.org/package/comfort-array) package.+An array can have a fancy shape+like a shape defined by an Haskell enumeration type,+the shape of two appended arrays,+a shape that is compatible to a Haskell container type,+a rectangular or triangular shape.++All operations check dynamically+whether corresponding shapes match structurally.+E.g. `a|||b === c|||d` composes a matrix from four quadrants `a`, `b`, `c`, `d`.+It is not enough that `a|||b` and `c|||d` have the same width,+but the widths of `a` and `c` as well as `b` and `d` must match.+The type variables for shapes show which dimensions must be compatible.+We recommend to use type variables for the shapes as long as possible+because this increases type safety even+if you eventually use only `ShapeInt`.+If you use statically sized shapes you get static size checks.++A matrix can have any of these shapes as height and as width.+E.g. it is no problem to define a matrix+that maps a triangular shaped array to a rectangular shaped one.+There are actually practical applications to such matrices.+A matrix can be treated as vector, but there are limitations.+E.g. if you scale a Hermitian matrix by a complex factor+it will in general be no longer Hermitian.+Another problem: Two equally sized rectangular matrices+may differ in the element order (row major vs. column major).+You cannot simply add them by adding the flattened arrays element-wise.+Thus if you want to perform vector operations on a matrix+the package requires you to "unpack" a matrix to a vector+using `Matrix.Array.toVector`.+This conversion is almost a no-op and preserves most of the shape information.+The reverse operation is `Matrix.Array.fromVector`.++There are more matrix types that are not based on a single array.+E.g. we provide a symbolic inverse, a scaling matrix, a permutation matrix.+We also support arrays that represent factors of a matrix factorization.+You obtain these by LU and QR decompositions.+You can extract the matrix factors of it,+but you can also multiply the factors to other matrices+or use the decompositions for solving simultaneous linear equations.+++## Type tags for content constraints++Full matrices have additional type tags to distinguish+between four cases of the size relations between+the height and the width of a full matrix.+In a matrix of type `Matrix.Full vert horiz height width a`+the type variables mean:++~~~~+vert  height+Small Small - Square matrix   height==width+Big   Small - Tall matrix     size height >= size width+Small Big   - Wide matrix     size height <= size width+Big   Big   - General matrix  height and width arbitrary+~~~~++The relations are defined using two type tags+in order to support matrix transposition flawlessly.+Using `Small Small` for square matrices+and `Big Big` for general matrices appears to be arbitrary,+but is chosen such that altering `Small` to `Big`+generalizes the size relation.++Likewise we use the `Triangular` matrix type+also to represent diagonal and symmetric matrices.+For `Matrix.Triangular lo diag up size a` we have the cases:++~~~~+lo    up+Empty Empty - Diagonal matrix+Empty Full  - Upper triangular matrix+Full  Empty - Lower triangular matrix+Full  Full  - Symmetric matrix+~~~~++The `diag` type tag can be `NonUnit` or `Unit`.+`Unit` can be used for matrices+that always have a unit diagonal by construction.+The property of a unit diagonal is preserved by some operations+and enables some optimizations by LAPACK.+`NonUnit` is a bit of a misnomer.+A `NonUnit` matrix can still have a unit diagonal,+but in general it has not and no optimizations will take place.+++## Infix operators++The package provides fancy infix operators like `#*|` and `\*#`.+They symbolize both operands and operations.+E.g. in `#*|` the hash means Matrix, the star means Multiplication+and the bar means Column Vector.++Possible operations are:++  * `a_*_b` - `a` multiplied by `b`++  * `a_/_b` - `a` multiplied by `inverse b`++  * `a_\_b` - `inverse a` multiplied by `b`++Possible operands are:++  * `#` - a matrix that is generalized through a type class++  * `##` - a full matrix++  * `\` - a diagonal matrix represented by a `Vector`++  * `-` - a row vector++  * `|` - a column vector++  * `.` - a scalar++For multiplication of equally shaped matrices+we also provide instances of `Semigroup.<>`.++Precedence of the operators is chosen analogously to plain `*` and `/`.+Associativity is chosen such that the same operator can be applied+multiple times without parentheses.+But sometimes this may mean that you have to mix+left and right associative operators,+and thus you may still need parentheses.
− example/EconomicAllocation.hs
@@ -1,71 +0,0 @@-{-# LANGUAGE TypeOperators #-}-module Main where--import qualified Numeric.LAPACK.Matrix.Square as Square-import qualified Numeric.LAPACK.Matrix as Matrix-import qualified Numeric.LAPACK.Vector as Vector-import Numeric.LAPACK.Matrix (ZeroInt, (#>), (|||))-import Numeric.LAPACK.Format ((##))--import qualified Data.Array.Comfort.Storable as Array-import qualified Data.Array.Comfort.Shape as Shape-import Data.Array.Comfort.Shape ((:+:)((:+:)))-import Data.Function.HT (nest)---type ZeroInt2 = ZeroInt:+:ZeroInt-type Vector sh = Vector.Vector sh Double-type Matrix height width = Matrix.General height width Double-type SquareMatrix size = Square.Square size Double---balances :: Vector ZeroInt2-balances =-   Vector.fromList (Matrix.zeroInt 2 :+: Matrix.zeroInt 2)-      [100000, 90000, -50000, -120000]--expenses :: Matrix ZeroInt ZeroInt2-expenses =-   Matrix.fromList (Matrix.zeroInt 2) (Matrix.zeroInt 2 :+: Matrix.zeroInt 2) $-   [16000,  4000,  8000, 12000,-    10000, 30000, 40000, 20000]--normalize ::-   (Eq height, Shape.C height, Shape.C width) =>-   Matrix height width -> Matrix height width-normalize x = Matrix.scaleRows (Array.map recip (Matrix.rowSums x)) x---subtractIdentity :: (Eq sh, Shape.C sh) => SquareMatrix sh -> SquareMatrix sh-subtractIdentity x = Matrix.sub x $ Square.identityFrom x--completeIdSquare :: Matrix ZeroInt2 ZeroInt -> SquareMatrix ZeroInt2-completeIdSquare x =-   Square.fromGeneral $-      (Matrix.takeLeftColumns $ Matrix.fromFull $ Square.identityFromHeight x)-      |||-      x--iterationMatrix :: SquareMatrix ZeroInt2-iterationMatrix =-   completeIdSquare $ Matrix.transpose $ normalize expenses--iterated :: Vector ZeroInt2-iterated = nest 30 (iterationMatrix #>) balances----compensated :: Vector ZeroInt-compensated =-   let a = Matrix.transpose $ normalize expenses-       p = Matrix.takeTopRows a-       k = Square.fromGeneral $ Matrix.takeBottomRows a-       x = Vector.takeLeft balances-       y = Vector.takeRight balances-   in Vector.sub x $ p #> Matrix.solveVector (subtractIdentity k) y---main :: IO ()-main = do-   Array.mapShape (Shape.ZeroBased . Shape.size) iterated ## "%10.2f"-   compensated ## "%10.2f"
lapack.cabal view
@@ -1,5 +1,5 @@ Name:             lapack-Version:          0.2.4+Version:          0.3 License:          BSD3 License-File:     LICENSE Author:           Henning Thielemann <haskell@henning-thielemann.de>@@ -28,24 +28,27 @@   .   * Works with matrices and vectors with zero dimensions.   .+  * No automatic (and dangerous) implicit expansion+    of singleton vectors or matrices.+    Instead there are special operators for scaling of vectors and matrices.+  .   * Separate formatting operator @(##)@:     Works better for tuples of matrices and vectors than 'show'.     'Show' is used for code one-liners     that can be copied back into Haskell modules.+    Support for nice formatting in HyperHaskell.   .   See also: @hmatrix@. Tested-With:      GHC==7.4.2, GHC==7.8.4, GHC==8.2.2 Cabal-Version:    >=1.8 Build-Type:       Simple Extra-Source-Files:+  ReadMe.md+  Changes.md   Makefile -Flag buildExamples-  description: Build example executables-  default:     False- Source-Repository this-  Tag:         0.2.4+  Tag:         0.3   Type:        darcs   Location:    http://hub.darcs.net/thielema/lapack/ @@ -58,15 +61,18 @@     lapack-ffi >=0.0.1 && <0.1,     blas-ffi >=0.0 && <0.2,     netlib-ffi >=0.1.1 && <0.2,-    comfort-array >=0.3 && <0.4,+    comfort-array >=0.4 && <0.5,     guarded-allocation >=0.0 && <0.1,+    hyper >=0.1 && <0.2,+    blaze-html >=0.7 && <0.10,+    text >=1.2 && <1.3,     boxes >=0.1.5 && <0.2,     deepseq >=1.3 && <1.5,     lazyio >=0.1 && <0.2,-    transformers >=0.3 && <0.6,+    transformers >=0.4 && <0.6,     tfp >=1.0.1 && <1.1,     fixed-length >=0.2 && <0.3,-    semigroups >=0.18.3 && <0.19,+    semigroups >=0.18.3 && <1.0,     non-empty >=0.3 && <0.4,     utility-ht >=0.0.10 && <0.1,     base >=4.5 && <5@@ -75,6 +81,8 @@   Hs-Source-Dirs:   src   Exposed-Modules:     Numeric.LAPACK.Matrix+    Numeric.LAPACK.Matrix.Special+    Numeric.LAPACK.Matrix.Array     Numeric.LAPACK.Matrix.Extent     Numeric.LAPACK.Matrix.Shape.Box     Numeric.LAPACK.Matrix.Shape@@ -85,6 +93,7 @@     Numeric.LAPACK.Matrix.Banded     Numeric.LAPACK.Matrix.BandedHermitian     Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite+    Numeric.LAPACK.Matrix.Permutation     Numeric.LAPACK.Vector     Numeric.LAPACK.Scalar     Numeric.LAPACK.Orthogonal@@ -93,9 +102,15 @@     Numeric.LAPACK.Linear.LowerUpper     Numeric.LAPACK.Singular     Numeric.LAPACK.ShapeStatic+    Numeric.LAPACK.Shape     Numeric.LAPACK.Format+    Numeric.LAPACK.Output+    Numeric.LAPACK.Example.EconomicAllocation   Other-Modules:+    Numeric.LAPACK.Singular.Plain+    Numeric.LAPACK.Orthogonal.Plain     Numeric.LAPACK.Orthogonal.Private+    Numeric.LAPACK.Linear.Plain     Numeric.LAPACK.Linear.Private     Numeric.LAPACK.Split     Numeric.LAPACK.Permutation.Private@@ -120,12 +135,28 @@     Numeric.LAPACK.Matrix.Shape.Private     Numeric.LAPACK.Matrix.Extent.Private     Numeric.LAPACK.Matrix.Extent.Kind-    Numeric.LAPACK.Matrix.Multiply     Numeric.LAPACK.Matrix.Divide-    Numeric.LAPACK.Matrix.Indexed+    Numeric.LAPACK.Matrix.Multiply+    Numeric.LAPACK.Matrix.Class     Numeric.LAPACK.Matrix.Basic+    Numeric.LAPACK.Matrix.Plain.Class+    Numeric.LAPACK.Matrix.Plain.Divide+    Numeric.LAPACK.Matrix.Plain.Multiply+    Numeric.LAPACK.Matrix.Plain.Indexed+    Numeric.LAPACK.Matrix.Plain.Format+    Numeric.LAPACK.Matrix.Plain+    Numeric.LAPACK.Matrix.Indexed+    Numeric.LAPACK.Matrix.Type+    Numeric.LAPACK.Matrix.Inverse+    Numeric.LAPACK.Matrix.Array.Banded+    Numeric.LAPACK.Matrix.Array.Triangular+    Numeric.LAPACK.Matrix.Array.Basic+    Numeric.LAPACK.Matrix.Modifier+    Numeric.LAPACK.Matrix.RowMajor     Numeric.LAPACK.Matrix.Private+    Numeric.LAPACK.Vector.Private     Numeric.LAPACK.Private+    Numeric.LAPACK.Shape.Private     Numeric.LAPACK.Wrapper  Test-Suite lapack-test@@ -142,7 +173,7 @@     QuickCheck >=2.5 && <3,     ChasingBottoms >=1.2.2 && <1.4,     transformers,-    monoid-transformer >=0.0.3 && <0.1,+    monoid-transformer >=0.0.4 && <0.1,     semigroups,     non-empty >=0.3.1,     utility-ht,@@ -153,7 +184,11 @@   Main-Is:          Main.hs   Other-Modules:     Test.Shape+    Test.Example     Test.Indexed+    Test.Divide+    Test.Multiply+    Test.Generic     Test.Permutation     Test.Vector     Test.Matrix@@ -161,6 +196,7 @@     Test.Triangular     Test.Hermitian     Test.Orthogonal+    Test.LowerUpper     Test.Banded     Test.BandedHermitian     Test.Banded.Utility@@ -169,17 +205,3 @@     Test.Logic     Test.Format     Test.Utility--Executable lapack-economic-  If flag(buildExamples)-    Build-Depends:-      lapack,-      comfort-array,-      utility-ht,-      base-  Else-    Buildable: False--  GHC-Options:      -Wall-  Hs-Source-Dirs:   example-  Main-Is:          EconomicAllocation.hs
+ src/Numeric/LAPACK/Example/EconomicAllocation.hs view
@@ -0,0 +1,81 @@+{-# LANGUAGE TypeOperators #-}+{- |+Do not import this module. It is only for demonstration purposes.+-}+module Numeric.LAPACK.Example.EconomicAllocation where++import qualified Numeric.LAPACK.Matrix.Square as Square+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix as Matrix+import qualified Numeric.LAPACK.Vector as Vector+import Numeric.LAPACK.Matrix.Square ((|=|))+import Numeric.LAPACK.Matrix (ShapeInt, shapeInt, (#-#), (#*|), (#\|), (\\#))+import Numeric.LAPACK.Vector ((|-|))+import Numeric.LAPACK.Format ((##))++import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Shape ((:+:)((:+:)))+++type ZeroInt2 = ShapeInt:+:ShapeInt+type Vector sh = Vector.Vector sh Double+type Matrix height width = Matrix.General height width Double+type SquareMatrix size = Square.Square size Double+++balances0 :: Vector ZeroInt2+balances0 =+   Vector.fromList (shapeInt 2 :+: shapeInt 2)+      [100000, 90000, -50000, -120000]++expenses0 :: Matrix ShapeInt ZeroInt2+expenses0 =+   Matrix.fromList (shapeInt 2) (shapeInt 2 :+: shapeInt 2) $+   [16000,  4000,  8000, 12000,+    10000, 30000, 40000, 20000]++normalize ::+   (Eq height, Shape.C height, Shape.C width) =>+   Matrix height width -> Matrix height width+normalize x = Matrix.rowSums x \\# x++normalizeSplit ::+   (Shape.C sh0, Shape.C sh1, Eq sh1) =>+   Matrix sh1 (sh0:+:sh1) -> (Matrix sh0 sh1, SquareMatrix sh1)+normalizeSplit expenses =+   let a = Matrix.transpose $ normalize expenses+   in (Matrix.takeTop a, Square.fromGeneral $ Matrix.takeBottom a)+++completeIdSquare ::+   (Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1) =>+   Matrix sh1 (sh0:+:sh1) -> SquareMatrix (sh0:+:sh1)+completeIdSquare x =+   let (p,k) = normalizeSplit x+   in (Square.identityFromHeight p, p)+      |=|+      (Matrix.zero $ ArrMatrix.shape $ Matrix.transpose p, k)++iterated ::+   (Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1) =>+   Matrix sh1 (sh0:+:sh1) -> Vector (sh0:+:sh1) -> Vector (sh0:+:sh1)+iterated expenses =+   -- 'Stream.head' would be total+   head . dropWhile ((>=1e-5) . Vector.normInf . Vector.takeRight) .+   iterate (completeIdSquare expenses #*|)+++compensated ::+   (Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1) =>+   Matrix sh1 (sh0:+:sh1) -> Vector (sh0:+:sh1) -> Vector sh0+compensated expenses balances =+   let (p,k) = normalizeSplit expenses+       x = Vector.takeLeft balances+       y = Vector.takeRight balances+   in x |-| p #*| (k #-# Square.identityFrom k) #\| y+++main :: IO ()+main = do+   iterated expenses0 balances0 ## "%10.2f"+   compensated expenses0 balances0 ## "%10.2f"
src/Numeric/LAPACK/Format.hs view
@@ -2,43 +2,33 @@ {-# LANGUAGE ConstraintKinds #-} module Numeric.LAPACK.Format (    (##),+   hyper,    Format(format),    FormatArray(formatArray),-   deflt,+   Type.FormatMatrix(formatMatrix),+   ArrFormat.deflt,    ) where -import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape-import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent-import Numeric.LAPACK.Matrix.Shape.Private-         (Order(RowMajor, ColumnMajor), Filled(Filled), UnaryProxy)-import Numeric.LAPACK.Matrix.Private (Full)-import Numeric.LAPACK.Scalar (conjugate)-import Numeric.LAPACK.Wrapper (Flip(Flip, getFlip))+import qualified Numeric.LAPACK.Matrix.Plain.Format as ArrFormat+import qualified Numeric.LAPACK.Matrix.Type as Type+import qualified Numeric.LAPACK.Output as Output+import qualified Numeric.LAPACK.Permutation.Private as Perm+import Numeric.LAPACK.Matrix.Plain.Format+         (FormatArray, formatArray, printfComplex)+import Numeric.LAPACK.Output (Output, (/+/))  import qualified Numeric.Netlib.Class as Class -import qualified Type.Data.Num.Unary.Literal as TypeNum-import qualified Type.Data.Num.Unary as Unary-import Type.Data.Num (integralFromProxy)--import qualified Data.Array.Comfort.Storable.Unchecked as Array import qualified Data.Array.Comfort.Shape as Shape import Data.Array.Comfort.Storable (Array)  import qualified Text.PrettyPrint.Boxes as TextBox-import Text.PrettyPrint.Boxes (Box, (/+/))-import Text.Printf (PrintfArg, printf)+import qualified Hyper+import Text.Printf (printf)  import qualified Data.List.Reverse.StrictSpine as ListRev-import qualified Data.List.Match as Match-import qualified Data.List.HT as ListHT-import qualified Data.List as List-import Data.Functor.Compose (Compose(Compose, getCompose))-import Data.Foldable (foldMap)-import Data.List (mapAccumL, transpose)-import Data.Complex (Complex((:+)))-import Data.Maybe.HT (toMaybe)-import Data.Maybe (fromMaybe)+import Data.Foldable (fold)+import Data.Complex (Complex) import Data.Char (isSpace)  @@ -50,28 +40,27 @@ trim :: String -> String trim = unlines . map (ListRev.dropWhile isSpace) . lines --deflt :: String-deflt = "%.4g"+hyper :: (Format a) => String -> a -> Hyper.Graphic+hyper fmt = Output.hyper . format fmt   class Format a where-   format :: String -> a -> Box+   format :: (Output out) => String -> a -> out  instance Format Int where-   format _fmt = TextBox.text . show+   format _fmt = Output.text . show  instance Format Float where-   format fmt = TextBox.text . printf fmt+   format fmt = Output.text . printf fmt  instance Format Double where-   format fmt = TextBox.text . printf fmt+   format fmt = Output.text . printf fmt  instance (Class.Real a) => Format (Complex a) where-   format fmt = TextBox.text . concat . printfComplex fmt+   format fmt = Output.text . fold . printfComplex fmt  instance (Format a) => Format [a] where-   format fmt = TextBox.vsep 1 TextBox.right . map (format fmt)+   format fmt = Output.formatColumn . map (format fmt)  instance (Format a, Format b) => Format (a,b) where    format fmt (a,b) = format fmt a /+/ format fmt b@@ -79,296 +68,13 @@ instance (Format a, Format b, Format c) => Format (a,b,c) where    format fmt (a,b,c) = format fmt a /+/ format fmt b /+/ format fmt c +instance (Shape.C sh) => Format (Perm.Permutation sh) where+   format _fmt = Perm.format+ instance (FormatArray sh, Class.Floating a) => Format (Array sh a) where    format = formatArray --class (Shape.C sh) => FormatArray sh where-   {--   We use constraint @(Class.Floating a)@ and not @(Format a)@-   because it allows us to align the components of complex numbers.-   -}-   formatArray :: (Class.Floating a) => String -> Array sh a -> Box--instance (Integral i) => FormatArray (Shape.ZeroBased i) where-   formatArray = formatVector--instance (Integral i) => FormatArray (Shape.OneBased i) where-   formatArray = formatVector--formatVector :: (Shape.C sh, Class.Floating a) => String -> Array sh a -> Box-formatVector fmt =-   TextBox.hsep 1 TextBox.right .-   map (TextBox.text . concat . printfFloating fmt) . Array.toList- instance-   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>-      FormatArray (MatrixShape.Full vert horiz height width) where-   formatArray = formatFull--formatFull ::-   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,-    Class.Floating a) =>-   String -> Full vert horiz height width a -> Box-formatFull fmt m =-   let MatrixShape.Full order extent = Array.shape m-   in  formatAligned (printfFloating fmt) $-       splitRows order (Extent.dimensions extent) $ Array.toList m--instance-   (Eq lower, Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>-      FormatArray (MatrixShape.Split lower vert horiz height width) where-   formatArray = formatHouseholder--formatHouseholder ::-   (Eq lower, Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,-    Class.Floating a) =>-   String -> Array (MatrixShape.Split lower vert horiz height width) a -> Box-formatHouseholder fmt m =-   let MatrixShape.Split _ order extent = Array.shape m-   in formatSeparateTriangle (printfFloating fmt) $-      splitRows order (Extent.dimensions extent) $ Array.toList m--instance (Shape.C size) => FormatArray (MatrixShape.Hermitian size) where-   formatArray = formatHermitian--formatHermitian ::-   (Shape.C size, Class.Floating a) =>-   String -> Array (MatrixShape.Hermitian size) a -> Box-formatHermitian fmt m =-   let MatrixShape.Hermitian order size = Array.shape m-   in  formatSeparateTriangle (printfFloating fmt) $-       complementTriangle conjugate order (Shape.size size) $ Array.toList m--formatSymmetric ::-   (Shape.C size, Class.Floating a) =>-   String -> Array (MatrixShape.Symmetric size) a -> Box-formatSymmetric fmt m =-   let MatrixShape.Triangular _diag (Filled, Filled) order size = Array.shape m-   in  formatSeparateTriangle (printfFloating fmt) $-       complementTriangle id order (Shape.size size) $ Array.toList m--complementTriangle ::-   (Class.Floating a) => (a -> a) -> Order -> Int -> [a] -> [[a]]-complementTriangle adapt order n xs =-   let mergeTriangles lower upper =-         zipWith (++) (map (map adapt . init) lower) upper-   in case order of-         RowMajor ->-            let tri = slice (take n $ iterate pred n) xs-                trans = reverse $ transpose $ map reverse tri-            in  mergeTriangles trans tri-         ColumnMajor ->-            let tri = slice (take n [1..]) xs-            in  mergeTriangles tri (transpose tri)--instance-   (MatrixShape.Content lo, MatrixShape.Content up,-    MatrixShape.TriDiag diag, Shape.C size) =>-      FormatArray (MatrixShape.Triangular lo diag up size) where-   formatArray fmt =-      getFormatTriangular $-      MatrixShape.switchDiagUpLoSym-         (FormatTriangular $ \m ->-            let MatrixShape.Triangular _diag _uplo order size = Array.shape m-                n0 = Unary.unary TypeNum.u0-            in formatAligned (printfFloatingMaybe fmt) $-               formatBanded (n0,n0) order (size,size) $ Array.toList m)-         (FormatTriangular $ formatTriangular fmt)-         (FormatTriangular $ formatTriangular fmt)-         (FormatTriangular $-            formatSymmetric fmt .-            Array.mapShape MatrixShape.strictNonUnitDiagonal)--newtype FormatTriangular diag size a b lo up =-   FormatTriangular {-      getFormatTriangular ::-         Array (MatrixShape.Triangular lo diag up size) a -> b-   }--formatTriangular ::-   (MatrixShape.TriDiag diag, MatrixShape.UpLo lo up,-    Shape.C size, Class.Floating a) =>-   String -> Array (MatrixShape.Triangular lo diag up size) a -> Box-formatTriangular fmt m =-   let MatrixShape.Triangular _diag uplo order size = Array.shape m-   in  formatAligned (printfFloatingMaybe fmt) $-       MatrixShape.caseLoUp uplo-         padLowerTriangle padUpperTriangle order (Shape.size size) $-       Array.toList m--padUpperTriangle :: Order -> Int -> [a] -> [[Maybe a]]-padUpperTriangle order n xs =-   let mxs = map Just xs-       nothings = iterate (Nothing:) []-   in case order of-         RowMajor ->-            zipWith (++) nothings (slice (take n $ iterate pred n) mxs)-         ColumnMajor ->-            transpose $-            zipWith (++)-               (slice (take n [1..]) mxs)-               (reverse $ take n nothings)--padLowerTriangle :: Order -> Int -> [a] -> [[Maybe a]]-padLowerTriangle order n xs =-   map (map Just) $-   case order of-      RowMajor -> slice (take n [1..]) xs-      ColumnMajor ->-         foldr (\(y:ys) zs -> [y] : zipWith (:) ys zs) []-            (slice (take n $ iterate pred n) xs)--slice :: [Int] -> [a] -> [[a]]-slice ns xs =-   snd $ mapAccumL (\ys n -> let (vs,ws) = splitAt n ys in (ws,vs)) xs ns--formatSeparateTriangle :: (a -> [String]) -> [[a]] -> Box-formatSeparateTriangle printFmt =-   alignSeparated . map concat .-   zipWith-      (zipWith (\sep -> attachSeparators sep . printFmt))-      (ListHT.outerProduct-         (\row col -> if row==col then Bar else Space)-         [(0::Int)..] [0..])---instance-   (Unary.Natural sub, Unary.Natural super,-    Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>-      FormatArray (MatrixShape.Banded sub super vert horiz height width) where-   formatArray fmt m =-      let MatrixShape.Banded offDiag order extent = Array.shape m-      in  formatAligned (printfFloatingMaybe fmt) $-          formatBanded offDiag order (Extent.dimensions extent) $-          Array.toList m--formatBanded ::-   (Shape.C height, Shape.C width, Unary.Natural sub, Unary.Natural super) =>-   (UnaryProxy sub, UnaryProxy super) -> Order ->-   (height, width) -> [a] -> [[Maybe a]]-formatBanded (sub,super) order (height,width) xs =-   let slices =-         ListHT.sliceVertical (MatrixShape.bandedBreadth (sub,super)) xs-       m = Shape.size height-       n = Shape.size width-   in case order of-         RowMajor ->-            map (take n) $-            zipWith (shiftRow Nothing)-               (iterate (1+) (- integralFromProxy sub))-               (map (map Just) slices)-         ColumnMajor ->-            let ku = integralFromProxy super-            in take m $ drop ku $-               foldr-                  (\col mat ->-                     zipWith (:) (map Just col ++ repeat Nothing) ([]:mat))-                  (replicate (ku + m - n) [])-                  slices---instance-   (Unary.Natural offDiag, Shape.C size) =>-      FormatArray (MatrixShape.BandedHermitian offDiag size) where-   formatArray fmt m =-      let MatrixShape.BandedHermitian offDiag order size = Array.shape m-      in  formatSeparateTriangle (printfFloatingMaybe fmt) $-          formatBandedHermitian offDiag order size $ Array.toList m--formatBandedHermitian ::-   (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>-   UnaryProxy offDiag -> Order -> size -> [a] -> [[Maybe a]]-formatBandedHermitian offDiag order _size xs =-   let k = integralFromProxy offDiag-       slices = ListHT.sliceVertical (k + 1) xs-   in case order of-         RowMajor ->-            foldr-               (\row square ->-                  Match.take ([]:square) (map Just row)-                  :-                  zipWith (:)-                     (tail $ map (Just . conjugate) row ++ repeat Nothing)-                     square)-               [] slices-         ColumnMajor ->-            zipWith (shiftRow Nothing) (iterate (1+) (-k)) $ map (map Just) $-            zipWith (++)-               (map (map conjugate . init) slices)-               (drop k $-                foldr-                  (\column band ->-                     zipWith (++) (map (:[]) column ++ repeat []) ([]:band))-                  (replicate k [])-                  slices)--shiftRow :: a -> Int -> [a] -> [a]-shiftRow pad k = if k<=0 then drop (-k) else (replicate k pad ++)--splitRows ::-   (Shape.C height, Shape.C width) =>-   Order -> (height, width) -> [a] -> [[a]]-splitRows order (height,width) =-   case order of-      RowMajor -> ListHT.sliceVertical (Shape.size width)-      ColumnMajor -> ListHT.sliceHorizontal (Shape.size height)--formatAligned :: (a -> [String]) -> [[a]] -> Box-formatAligned printFmt =-   alignSeparated . map (concatMap (attachSeparators Space . printFmt))---data Separator = Empty | Space | Bar-   deriving (Eq, Ord, Show)--alignSeparated :: [[(Separator, String)]] -> Box-alignSeparated =-   TextBox.hcat TextBox.top .-   map (TextBox.vcat TextBox.right . map TextBox.text) .-   concatMap ((\(seps,column) -> [map formatSeparator seps, column]) . unzip) .-   List.unfoldr (viewLAll (Empty,""))--viewLAll :: a -> [[a]] -> Maybe ([a], [[a]])-viewLAll x0 xs =-   toMaybe (any (not.null) xs)-      (unzip $ map (fromMaybe (x0,[]) . ListHT.viewL) xs)--formatSeparator :: Separator -> String-formatSeparator sep = case sep of Empty -> ""; Space -> " "; Bar -> "|"--attachSeparators :: Separator -> [str] -> [(Separator, str)]-attachSeparators sep = zip (sep:repeat Empty)---printfFloating :: (Class.Floating a) => String -> a -> [String]-printfFloating fmt =-   getFlip $-   Class.switchFloating-      (Flip $ (:[]) . printf fmt)-      (Flip $ (:[]) . printf fmt)-      (Flip $ printfComplex fmt)-      (Flip $ printfComplex fmt)--printfFloatingMaybe :: (Class.Floating a) => String -> Maybe a -> [String]-printfFloatingMaybe fmt =-   getFlip $ getCompose $-   Class.switchFloating-      (Compose $ Flip $ (:[]) . foldMap (printf fmt))-      (Compose $ Flip $ (:[]) . foldMap (printf fmt))-      (Compose $ Flip $ maybe ["",""] (printfComplex fmt))-      (Compose $ Flip $ maybe ["",""] (printfComplex fmt))--printfComplex :: (Class.Real a) => String -> Complex a -> [String]-printfComplex fmt =-   getFlip $ getCompose $-   Class.switchReal-      (Compose $ Flip $ printfComplexAux fmt)-      (Compose $ Flip $ printfComplexAux fmt)--printfComplexAux ::-   (PrintfArg a, Class.Real a) => String -> Complex a -> [String]-printfComplexAux fmt (r:+i) =-   if i<0 || isNegativeZero i-     then [printf (fmt ++ "-") r, printf (fmt ++ "i") (-i)]-     else [printf (fmt ++ "+") r, printf (fmt ++ "i") i]+   (Type.FormatMatrix typ, Class.Floating a) =>+      Format (Type.Matrix typ a) where+   format = Type.formatMatrix
src/Numeric/LAPACK/Linear/LowerUpper.hs view
@@ -1,16 +1,19 @@+{-# LANGUAGE TypeFamilies #-} module Numeric.LAPACK.Linear.LowerUpper (    LowerUpper,-   Square,-   Transposition(..),-   Conjugation(..),-   Inversion(..),-   mapExtent,+   Plain.Square,+   Plain.Tall,+   Plain.Wide,+   Plain.Transposition(..),+   Plain.Conjugation(..),+   Plain.Inversion(..),+   Plain.mapExtent,    fromMatrix,    toMatrix,    solve,-   multiplyFullRight,+   multiplyFull, -   determinant,+   Plain.determinant,     extractP,    multiplyP,@@ -25,154 +28,55 @@    tallMultiplyU,    tallSolveU, -   caseTallWide,+   Plain.caseTallWide,    ) where -import qualified Numeric.LAPACK.Matrix.Multiply as MM-import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Linear.Plain as Plain+import Numeric.LAPACK.Linear.Plain (LowerUpper)++import qualified Numeric.LAPACK.Matrix.Array.Triangular as Tri+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent-import qualified Numeric.LAPACK.Matrix.Basic as Basic-import qualified Numeric.LAPACK.Matrix.Private as Matrix-import qualified Numeric.LAPACK.Permutation.Private as Perm-import qualified Numeric.LAPACK.Split as Split-import Numeric.LAPACK.Matrix.Triangular.Basic (UnitLower, Upper)-import Numeric.LAPACK.Matrix.Shape.Private-         (Order(RowMajor, ColumnMajor), Triangle(Triangle))-import Numeric.LAPACK.Matrix.Private-         (Full, ZeroInt, zeroInt,-          Transposition(NonTransposed, Transposed),-          Conjugation(NonConjugated, Conjugated),-          Inversion(NonInverted, Inverted), flipInversion)-import Numeric.LAPACK.Linear.Private (solver, withInfo)-import Numeric.LAPACK.Vector (Vector)-import Numeric.LAPACK.Format (Format(format))-import Numeric.LAPACK.Private-         (pointerSeq, peekCInt,-          copyBlock, copyTransposed, copyToColumnMajor)+import qualified Numeric.LAPACK.Matrix.Permutation as PermMatrix+import qualified Numeric.LAPACK.Matrix as Matrix+import Numeric.LAPACK.Matrix.Array (Full)+import Numeric.LAPACK.Matrix.Modifier (Transposition, Conjugation, Inversion) -import qualified Numeric.LAPACK.FFI.Generic as LapackGen-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.Marshal.Array (advancePtr)-import Foreign.C.Types (CInt)-import Foreign.ForeignPtr (withForeignPtr)-import Foreign.Ptr (Ptr) -import Control.Monad.Trans.Cont (ContT(ContT), evalContT)-import Control.Monad.IO.Class (liftIO)-import Control.Monad (forM_)-import Control.Applicative ((<$>))---data LowerUpper vert horiz height width a =-   LowerUpper {-      _pivot :: Vector ZeroInt CInt,-      split_ ::-         Array-            (MatrixShape.Split MatrixShape.Triangle vert horiz height width) a-   } deriving (Show)--type Square sh = LowerUpper Extent.Small Extent.Small sh sh--instance-   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,-    Class.Floating a) =>-      Format (LowerUpper vert horiz height width a) where-   format fmt lu@(LowerUpper _ipiv m) = format fmt (extractP NonInverted lu, m)--mapExtent ::-   (Extent.C vertA, Extent.C horizA) =>-   (Extent.C vertB, Extent.C horizB) =>-   Extent.Map vertA horizA vertB horizB height width ->-   LowerUpper vertA horizA height width a ->-   LowerUpper vertB horizB height width a-mapExtent f (LowerUpper pivot split) =-   LowerUpper pivot $ Array.mapShape (MatrixShape.splitMapExtent f) split- {- | @LowerUpper.fromMatrix a@ computes the LU decomposition of matrix @a@ with row pivotisation. -You can reconstruct @a@ from @lu@ depending on wether @a@ is tall or wide.+You can reconstruct @a@ from @lu@ depending on whether @a@ is tall or wide. -> LU.multiplyP False lu $ LU.extractL lu <#> LU.tallExtractU lu-> LU.multiplyP False lu $ LU.wideExtractL lu <#> LU.extractU lu+> LU.multiplyP NonInverted lu $ LU.extractL lu ##*# LU.tallExtractU lu+> LU.multiplyP NonInverted lu $ LU.wideExtractL lu #*## LU.extractU lu -} fromMatrix ::    (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,     Class.Floating a) =>    Full vert horiz height width a ->    LowerUpper vert horiz height width a-fromMatrix (Array (MatrixShape.Full order extent) a) =-   let (height,width) = Extent.dimensions extent-       m = Shape.size height-       n = Shape.size width-   in uncurry LowerUpper $-      Array.unsafeCreateWithSizeAndResult (zeroInt $ min m n) $ \_ ipivPtr ->-      ArrayIO.unsafeCreate-         (MatrixShape.Split MatrixShape.Triangle ColumnMajor extent) $ \luPtr ->--   evalContT $ do-      mPtr <- Call.cint m-      nPtr <- Call.cint n-      aPtr <- ContT $ withForeignPtr a-      ldaPtr <- Call.leadingDim m-      liftIO $ do-         copyToColumnMajor order m n aPtr luPtr-         withInfo "getrf" $ LapackGen.getrf mPtr nPtr luPtr ldaPtr ipivPtr+fromMatrix = Plain.fromMatrix . ArrMatrix.toVector  solve ::    (Extent.C vert, Extent.C horiz, Eq height, Shape.C height, Shape.C width,     Class.Floating a) =>-   Square height a ->+   Plain.Square height a ->    Full vert horiz height width a ->    Full vert horiz height width a-solve-   (LowerUpper-      (Array _ ipiv)-      (Array (MatrixShape.Split MatrixShape.Triangle orderLU extentLU) lu)) =--   solver "LowerUpper.solve" (Extent.squareSize extentLU) $-         \n nPtr nrhsPtr xPtr ldxPtr -> do-      let lda = n-      transPtr <- Call.char 'N'-      aPtr <--         case orderLU of-            RowMajor -> do-               aPtr <- ContT $ withForeignPtr lu-               atmpPtr <- Call.allocaArray (n*n)-               liftIO $ copyToColumnMajor orderLU n n aPtr atmpPtr-               return atmpPtr-            ColumnMajor -> ContT $ withForeignPtr lu-      ldaPtr <- Call.leadingDim lda-      ipivPtr <- ContT $ withForeignPtr ipiv-      liftIO $-         withInfo "getrs" $-            LapackGen.getrs transPtr-               nPtr nrhsPtr aPtr ldaPtr ipivPtr xPtr ldxPtr--{- |-Caution:-@LU.determinant . LU.fromMatrix@ will fail for singular matrices.--}-determinant :: (Shape.C sh, Class.Floating a, Eq a) => Square sh a -> a-determinant (LowerUpper ipiv split) =-   let det = Split.determinantR split-   in if Split.oddPermutation $ Array.toList ipiv then -det else det+solve = ArrMatrix.lift1 . Plain.solve   extractP ::-   (Extent.C vert, Extent.C horiz, Shape.C height) =>-   Inversion -> LowerUpper vert horiz height width a -> Perm.Permutation height-extractP inverted (LowerUpper ipiv (Array shape _)) =-   Perm.fromPivots (flipInversion inverted) (MatrixShape.splitHeight shape) ipiv+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+   Inversion -> LowerUpper vert horiz height width a ->+   Matrix.Permutation height a+extractP inverted = PermMatrix.fromPermutation . Plain.extractP inverted  multiplyP ::    (Extent.C vertA, Extent.C horizA, Extent.C vertB, Extent.C horizB,@@ -182,56 +86,7 @@    LowerUpper vertA horizA height widthA a ->    Full vertB horizB height widthB a ->    Full vertB horizB height widthB a-multiplyP inverted-      (LowerUpper (Array shapeIPiv ipiv)-         (Array (MatrixShape.Split _ _ extentLU) _lu))-      (Array shape@(MatrixShape.Full order extent) a) =-   Array.unsafeCreate shape $ \bPtr -> do--   Call.assert "multiplyP: heights mismatch"-      (Extent.height extentLU == Extent.height extent)--   let (height,width) = Extent.dimensions extent-   let m = Shape.size height-   let n = Shape.size width-   let k = Shape.size shapeIPiv--   evalContT $ do-      aPtr <- ContT $ withForeignPtr a-      ipivPtr <- ContT $ withForeignPtr ipiv-      liftIO $ copyBlock (n*m) aPtr bPtr-      case order of-         ColumnMajor -> do-            nPtr <- Call.cint n-            ldaPtr <- Call.leadingDim m-            k1Ptr <- Call.cint 1-            k2Ptr <- Call.cint k-            incxPtr <--               Call.cint $-               case inverted of-                  Inverted -> 1-                  NonInverted -> -1-            liftIO $-               LapackGen.laswp nPtr bPtr ldaPtr k1Ptr k2Ptr ipivPtr incxPtr-         RowMajor ->-            liftIO $ swapColumns m bPtr $ take k $-            case inverted of-               Inverted -> zip [0..] $ pointerSeq 1 ipivPtr-               NonInverted ->-                  zip (iterate (subtract 1) (k-1)) $-                  pointerSeq (-1) (advancePtr ipivPtr (k-1))--{-# INLINE swapColumns #-}-swapColumns ::-   (Class.Floating a) =>-   Int -> Ptr a -> [(Int, Ptr CInt)] -> IO ()-swapColumns m xPtr ptrs = evalContT $ do-   mPtr <- Call.cint m-   incPtr <- Call.cint 1-   let columnPtr k = advancePtr xPtr (m*k)-   liftIO $ forM_ ptrs $ \(i,ipivPtr) -> do-      j <- subtract 1 <$> peekCInt ipivPtr-      BlasGen.swap mPtr (columnPtr i) incPtr (columnPtr j) incPtr+multiplyP inverted = ArrMatrix.lift1 . Plain.multiplyP inverted   @@ -240,19 +95,19 @@     Class.Floating a) =>    LowerUpper vert horiz height width a ->    Full vert horiz height width a-extractL = Split.extractTriangle (Left Triangle) . split_+extractL = ArrMatrix.lift0 . Plain.extractL  wideExtractL ::    (Extent.C horiz, Shape.C height, Shape.C width, Class.Floating a) =>-   LowerUpper Extent.Small horiz height width a -> UnitLower height a-wideExtractL = Split.wideExtractL . split_+   LowerUpper Extent.Small horiz height width a -> Tri.UnitLower height a+wideExtractL = ArrMatrix.lift0 . Plain.wideExtractL  {- | @wideMultiplyL transposed lu a@ multiplies the square part of @lu@ containing the lower triangular matrix with @a@. -> wideMultiplyL False lu a == wideExtractL lu <#> a-> wideMultiplyL True lu a == wideExtractL (Tri.transposeUp lu) <#> a+> wideMultiplyL NonTransposed lu a == wideExtractL lu #*## a+> wideMultiplyL Transposed lu a == Tri.transpose (wideExtractL lu) #*## a -} wideMultiplyL ::    (Extent.C horizA, Extent.C vert, Extent.C horiz, Shape.C height, Eq height,@@ -261,7 +116,7 @@    LowerUpper Extent.Small horizA height widthA a ->    Full vert horiz height widthB a ->    Full vert horiz height widthB a-wideMultiplyL transposed = Split.wideMultiplyL transposed . split_+wideMultiplyL transposed = ArrMatrix.lift1 . Plain.wideMultiplyL transposed  wideSolveL ::    (Extent.C horizA, Extent.C vert, Extent.C horiz,@@ -270,7 +125,7 @@    LowerUpper Extent.Small horizA height width a ->    Full vert horiz height nrhs a -> Full vert horiz height nrhs a wideSolveL transposed conjugated =-   Split.wideSolveL transposed conjugated . split_+   ArrMatrix.lift1 . Plain.wideSolveL transposed conjugated   extractU ::@@ -278,19 +133,19 @@     Class.Floating a) =>    LowerUpper vert horiz height width a ->    Full vert horiz height width a-extractU = Split.extractTriangle (Right Triangle) . split_+extractU = ArrMatrix.lift0 . Plain.extractU  tallExtractU ::    (Extent.C vert, Shape.C height, Shape.C width, Class.Floating a) =>-   LowerUpper vert Extent.Small height width a -> Upper width a-tallExtractU = Split.tallExtractR . split_+   LowerUpper vert Extent.Small height width a -> Tri.Upper width a+tallExtractU = ArrMatrix.lift0 . Plain.tallExtractU  {- | @tallMultiplyU transposed lu a@ multiplies the square part of @lu@ containing the upper triangular matrix with @a@. -> tallMultiplyU False lu a == tallExtractU lu <#> a-> tallMultiplyU True lu a == tallExtractU (Tri.transposeDown lu) <#> a+> tallMultiplyU NonTransposed lu a == tallExtractU lu #*## a+> tallMultiplyU Transposed lu a == Tri.transpose (tallExtractU lu) #*## a -} tallMultiplyU ::    (Extent.C vertA, Extent.C vert, Extent.C horiz, Shape.C height, Eq height,@@ -299,7 +154,7 @@    LowerUpper vertA Extent.Small heightA height a ->    Full vert horiz height widthB a ->    Full vert horiz height widthB a-tallMultiplyU transposed = Split.tallMultiplyR transposed . split_+tallMultiplyU transposed = ArrMatrix.lift1 . Plain.tallMultiplyU transposed  tallSolveU ::    (Extent.C vertA, Extent.C vert, Extent.C horiz,@@ -308,7 +163,7 @@    LowerUpper vertA Extent.Small height width a ->    Full vert horiz width nrhs a -> Full vert horiz width nrhs a tallSolveU transposed conjugated =-   Split.tallSolveR transposed conjugated . split_+   ArrMatrix.lift1 . Plain.tallSolveU transposed conjugated   @@ -317,121 +172,14 @@     Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>    LowerUpper vert horiz height width a ->    Full vert horiz height width a-toMatrix =-   getToMatrix $-   Extent.switchTagPair-      (ToMatrix wideToMatrix)-      (ToMatrix wideToMatrix)-      (ToMatrix tallToMatrix)-      (ToMatrix $-         either-            (Matrix.fromFull . tallToMatrix)-            (Matrix.fromFull . wideToMatrix) .-         caseTallWide)--newtype ToMatrix height width a vert horiz =-   ToMatrix {-      getToMatrix ::-         LowerUpper vert horiz height width a ->-         Full vert horiz height width a-   }--tallToMatrix ::-   (Extent.C vert, Shape.C height, Shape.C width, Eq height, Eq width,-    Class.Floating a) =>-   LowerUpper vert Extent.Small height width a ->-   Full vert Extent.Small height width a-tallToMatrix a =-   multiplyP NonInverted a $ Basic.transpose $-   tallMultiplyU Transposed a $ Basic.transpose $ extractL a--wideToMatrix ::-   (Extent.C horiz, Shape.C height, Shape.C width, Eq height, Eq width,-    Class.Floating a) =>-   LowerUpper Extent.Small horiz height width a ->-   Full Extent.Small horiz height width a-wideToMatrix a =-   multiplyP NonInverted a $ wideMultiplyL NonTransposed a $ extractU a+toMatrix = ArrMatrix.lift0 . Plain.toMatrix  -multiplyFullRight ::+multiplyFull ::    (Extent.C vert, Extent.C horiz,     Shape.C height, Eq height, Shape.C width, Shape.C fuse, Eq fuse,     Class.Floating a) =>    LowerUpper vert horiz height fuse a ->    Full vert horiz fuse width a ->    Full vert horiz height width a-multiplyFullRight =-   getMultiplyFullRight $-   Extent.switchTagPair-      (MultiplyFullRight wideMultiplyFullRight)-      (MultiplyFullRight wideMultiplyFullRight)-      (MultiplyFullRight tallMultiplyFullRight)-      (MultiplyFullRight $-         either tallMultiplyFullRight wideMultiplyFullRight . caseTallWide)--newtype MultiplyFullRight height fuse width a vert horiz =-   MultiplyFullRight {-      getMultiplyFullRight ::-         LowerUpper vert horiz height fuse a ->-         Full vert horiz fuse width a ->-         Full vert horiz height width a-   }--tallMultiplyFullRight ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.C width, Shape.C fuse, Eq height, Eq fuse,-    Class.Floating a) =>-   LowerUpper vert Extent.Small height fuse a ->-   Full vert horiz fuse width a ->-   Full vert horiz height width a-tallMultiplyFullRight a =-   multiplyP NonInverted a .-   MM.multiply (Matrix.generalizeTall (extractL a)) .-   tallMultiplyU NonTransposed a--wideMultiplyFullRight ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.C width, Shape.C fuse, Eq height, Eq fuse,-    Class.Floating a) =>-   LowerUpper Extent.Small horiz height fuse a ->-   Full vert horiz fuse width a ->-   Full vert horiz height width a-wideMultiplyFullRight a =-   multiplyP NonInverted a . wideMultiplyL NonTransposed a .-   MM.multiply (Matrix.generalizeWide (extractU a))---type Tall = LowerUpper Extent.Big Extent.Small-type Wide = LowerUpper Extent.Small Extent.Big--caseTallWide ::-   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>-   LowerUpper vert horiz height width a ->-   Either (Tall height width a) (Wide height width a)-caseTallWide (LowerUpper ipiv (Array shape a)) =-   either-      (Left . LowerUpper ipiv . flip Array a)-      (Right . LowerUpper ipiv . flip Array a) $-   MatrixShape.caseTallWideSplit shape---_toRowMajor ::-   (Extent.C vert, Extent.C horiz, Eq height, Shape.C height, Shape.C width,-    Class.Floating a) =>-   LowerUpper vert horiz height width a ->-   LowerUpper vert horiz height width a-_toRowMajor-   (LowerUpper ipiv-      arr@(Array (MatrixShape.Split MatrixShape.Triangle order extent) a)) =-   LowerUpper ipiv $-   case order of-      RowMajor -> arr-      ColumnMajor ->-         Array.unsafeCreate-            (MatrixShape.Split MatrixShape.Triangle RowMajor extent) $ \bPtr ->-         withForeignPtr a $ \aPtr -> do-            let (height, width) = Extent.dimensions extent-            let n = Shape.size width-            let m = Shape.size height-            copyTransposed n m aPtr n bPtr+multiplyFull = ArrMatrix.lift1 . Plain.multiplyFull
+ src/Numeric/LAPACK/Linear/Plain.hs view
@@ -0,0 +1,522 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE EmptyDataDecls #-}+module Numeric.LAPACK.Linear.Plain (+   LowerUpper,+   Square, Tall, Wide,+   Transposition(..),+   Conjugation(..),+   Inversion(..),+   mapExtent,+   fromMatrix,+   toMatrix,+   solve,+   multiplyFull,++   determinant,++   extractP,+   multiplyP,++   extractL,+   wideExtractL,+   wideMultiplyL,+   wideSolveL,++   extractU,+   tallExtractU,+   tallMultiplyU,+   tallSolveU,++   caseTallWide,+   ) where++import qualified Numeric.LAPACK.Matrix.Divide as Divide+import qualified Numeric.LAPACK.Matrix.Multiply as Multiply+import qualified Numeric.LAPACK.Matrix.Type as Type+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import qualified Numeric.LAPACK.Matrix.Extent as ExtentMap+import qualified Numeric.LAPACK.Matrix.Basic as Basic+import qualified Numeric.LAPACK.Matrix.Private as Matrix+import qualified Numeric.LAPACK.Permutation.Private as Perm+import qualified Numeric.LAPACK.Shape as ExtShape+import qualified Numeric.LAPACK.Split as Split+import Numeric.LAPACK.Output ((/+/))+import Numeric.LAPACK.Matrix.Plain.Format (formatArray)+import Numeric.LAPACK.Matrix.Type (FormatMatrix(formatMatrix))+import Numeric.LAPACK.Matrix.Triangular.Basic (UnitLower, Upper)+import Numeric.LAPACK.Matrix.Shape.Private+         (Order(RowMajor, ColumnMajor), Triangle(Triangle))+import Numeric.LAPACK.Matrix.Modifier+         (Transposition(NonTransposed, Transposed),+          Conjugation(NonConjugated, Conjugated),+          Inversion(NonInverted, Inverted))+import Numeric.LAPACK.Matrix.Private (Full)+import Numeric.LAPACK.Linear.Private (solver, withInfo)+import Numeric.LAPACK.Vector (Vector)+import Numeric.LAPACK.Private (copyBlock, copyTransposed, copyToColumnMajor)++import qualified Numeric.LAPACK.FFI.Generic as LapackGen+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.Marshal.Array (advancePtr)+import Foreign.ForeignPtr (withForeignPtr)+import Foreign.Ptr (Ptr)++import Control.Monad.Trans.Cont (ContT(ContT), evalContT)+import Control.Monad.IO.Class (liftIO)+import Control.Monad (forM_)++import Data.Monoid ((<>))+++data LU vert horiz height width++data instance Type.Matrix (LU vert horiz height width) a =+   LowerUpper {+      _pivot ::+         Vector (ExtShape.Min width (Perm.Shape height)) (Perm.Element height),+      split_ ::+         Array+            (MatrixShape.Split MatrixShape.Triangle vert horiz height width) a+   } deriving (Show)++type LowerUpper vert horiz height width =+         Type.Matrix (LU vert horiz height width)+type Square sh = LowerUpper Extent.Small Extent.Small sh sh+type Tall height width = LowerUpper Extent.Big Extent.Small height width+type Wide height width = LowerUpper Extent.Small Extent.Big height width++instance+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+      FormatMatrix (LU vert horiz height width) where+   formatMatrix fmt lu@(LowerUpper _ipiv m) =+      Perm.format (extractP NonInverted lu)+      /+/+      formatArray fmt m++mapExtent ::+   (Extent.C vertA, Extent.C horizA) =>+   (Extent.C vertB, Extent.C horizB) =>+   Extent.Map vertA horizA vertB horizB height width ->+   LowerUpper vertA horizA height width a ->+   LowerUpper vertB horizB height width a+mapExtent f (LowerUpper pivot split) =+   LowerUpper pivot $ Array.mapShape (MatrixShape.splitMapExtent f) split++fromMatrix ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>+   Full vert horiz height width a ->+   LowerUpper vert horiz height width a+fromMatrix (Array (MatrixShape.Full order extent) a) =+   let (height,width) = Extent.dimensions extent+   in uncurry LowerUpper $+      Array.unsafeCreateWithSizeAndResult+         (ExtShape.Min width $ Perm.Shape height) $ \_ ipivPtr ->+      ArrayIO.unsafeCreate+         (MatrixShape.Split MatrixShape.Triangle ColumnMajor extent) $ \luPtr ->++   evalContT $ do+      let m = Shape.size height+      let n = Shape.size width+      mPtr <- Call.cint m+      nPtr <- Call.cint n+      aPtr <- ContT $ withForeignPtr a+      ldaPtr <- Call.leadingDim m+      liftIO $ do+         copyToColumnMajor order m n aPtr luPtr+         withInfo "getrf" $+            LapackGen.getrf mPtr nPtr luPtr ldaPtr+               (Perm.deconsElementPtr ipivPtr)++solve ::+   (Extent.C vert, Extent.C horiz, Eq height, Shape.C height, Shape.C width,+    Class.Floating a) =>+   Square height a ->+   Full vert horiz height width a ->+   Full vert horiz height width a+solve = solveTrans NonTransposed++solveTrans ::+   (Extent.C vert, Extent.C horiz, Eq height, Shape.C height, Shape.C width,+    Class.Floating a) =>+   Transposition -> Square height a ->+   Full vert horiz height width a ->+   Full vert horiz height width a+solveTrans trans+   (LowerUpper+      (Array _ ipiv)+      (Array (MatrixShape.Split MatrixShape.Triangle orderLU extentLU) lu)) =++   solver "LowerUpper.solve" (Extent.squareSize extentLU) $+         \n nPtr nrhsPtr xPtr ldxPtr -> do+      let lda = n+      transPtr <- Call.char $+         case trans of+            NonTransposed -> 'N'+            Transposed -> 'T'+      aPtr <-+         case orderLU of+            RowMajor -> do+               aPtr <- ContT $ withForeignPtr lu+               atmpPtr <- Call.allocaArray (n*n)+               liftIO $ copyToColumnMajor orderLU n n aPtr atmpPtr+               return atmpPtr+            ColumnMajor -> ContT $ withForeignPtr lu+      ldaPtr <- Call.leadingDim lda+      ipivPtr <- fmap Perm.deconsElementPtr $ ContT $ withForeignPtr ipiv+      liftIO $+         withInfo "getrs" $+            LapackGen.getrs transPtr+               nPtr nrhsPtr aPtr ldaPtr ipivPtr xPtr ldxPtr++{- |+Caution:+@LU.determinant . LU.fromMatrix@ will fail for singular matrices.+-}+determinant :: (Shape.C sh, Class.Floating a) => Square sh a -> a+determinant (LowerUpper ipiv split) =+   Perm.condNegate (map Perm.deconsElement $ Array.toList ipiv) $+   Split.determinantR split+++extractP ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+   Inversion -> LowerUpper vert horiz height width a -> Perm.Permutation height+extractP inverted (LowerUpper ipiv _) =+   Perm.fromTruncatedPivots (Inverted <> inverted) ipiv++multiplyP ::+   (Extent.C vertA, Extent.C horizA, Extent.C vertB, Extent.C horizB,+    Eq height, Shape.C height, Shape.C widthA, Shape.C widthB,+    Class.Floating a) =>+   Inversion ->+   LowerUpper vertA horizA height widthA a ->+   Full vertB horizB height widthB a ->+   Full vertB horizB height widthB a+multiplyP inverted+      (LowerUpper ipiv@(Array shapeIPiv ipivFPtr)+         (Array (MatrixShape.Split _ _ extentLU) _lu))+      (Array shape@(MatrixShape.Full order extent) a) =+   Array.unsafeCreate shape $ \bPtr -> do++   Call.assert "multiplyP: heights mismatch"+      (Extent.height extentLU == Extent.height extent)++   let (height,width) = Extent.dimensions extent+   let m = Shape.size height+   let n = Shape.size width+   let k = Shape.size shapeIPiv++   evalContT $ do+      aPtr <- ContT $ withForeignPtr a+      ipivPtr <- ContT $ withForeignPtr ipivFPtr+      liftIO $ copyBlock (n*m) aPtr bPtr+      case order of+         ColumnMajor -> do+            nPtr <- Call.cint n+            ldaPtr <- Call.leadingDim m+            k1Ptr <- Call.cint 1+            k2Ptr <- Call.cint k+            incxPtr <-+               Call.cint $+               case inverted of+                  Inverted -> 1+                  NonInverted -> -1+            liftIO $+               LapackGen.laswp nPtr bPtr ldaPtr k1Ptr k2Ptr+                  (Perm.deconsElementPtr ipivPtr) incxPtr+         RowMajor ->+            liftIO $ swapColumns height n bPtr ipiv $+            Perm.indices (Inverted <> inverted) shapeIPiv++{-# INLINE swapColumns #-}+swapColumns ::+   (Shape.C sh, Shape.C width, Class.Floating a) =>+   sh -> Int -> Ptr a ->+   Array (ExtShape.Min width (Perm.Shape sh)) (Perm.Element sh) ->+   [Perm.Element sh] -> IO ()+swapColumns sh n xPtr ipiv is = evalContT $ do+   nPtr <- Call.cint n+   incPtr <- Call.cint 1+   let columnPtr ix =+         advancePtr xPtr (n * Shape.uncheckedOffset (Perm.Shape sh) ix)+   liftIO $ forM_ is $ \i ->+      BlasGen.swap nPtr (columnPtr i) incPtr (columnPtr (ipiv!i)) incPtr++++extractL ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>+   LowerUpper vert horiz height width a ->+   Full vert horiz height width a+extractL = Split.extractTriangle (Left Triangle) . split_++wideExtractL ::+   (Extent.C horiz, Shape.C height, Shape.C width, Class.Floating a) =>+   LowerUpper Extent.Small horiz height width a -> UnitLower height a+wideExtractL = Split.wideExtractL . split_++wideMultiplyL ::+   (Extent.C horizA, Extent.C vert, Extent.C horiz, Shape.C height, Eq height,+    Shape.C widthA, Shape.C widthB, Class.Floating a) =>+   Transposition ->+   LowerUpper Extent.Small horizA height widthA a ->+   Full vert horiz height widthB a ->+   Full vert horiz height widthB a+wideMultiplyL transposed = Split.wideMultiplyL transposed . split_++wideSolveL ::+   (Extent.C horizA, Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Shape.C nrhs, Class.Floating a) =>+   Transposition -> Conjugation ->+   LowerUpper Extent.Small horizA height width a ->+   Full vert horiz height nrhs a -> Full vert horiz height nrhs a+wideSolveL transposed conjugated =+   Split.wideSolveL transposed conjugated . split_+++extractU ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>+   LowerUpper vert horiz height width a ->+   Full vert horiz height width a+extractU = Split.extractTriangle (Right Triangle) . split_++tallExtractU ::+   (Extent.C vert, Shape.C height, Shape.C width, Class.Floating a) =>+   LowerUpper vert Extent.Small height width a -> Upper width a+tallExtractU = Split.tallExtractR . split_++tallMultiplyU ::+   (Extent.C vertA, Extent.C vert, Extent.C horiz, Shape.C height, Eq height,+    Shape.C heightA, Shape.C widthB, Class.Floating a) =>+   Transposition ->+   LowerUpper vertA Extent.Small heightA height a ->+   Full vert horiz height widthB a ->+   Full vert horiz height widthB a+tallMultiplyU transposed = Split.tallMultiplyR transposed . split_++tallSolveU ::+   (Extent.C vertA, Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Eq width, Shape.C nrhs, Class.Floating a) =>+   Transposition -> Conjugation ->+   LowerUpper vertA Extent.Small height width a ->+   Full vert horiz width nrhs a -> Full vert horiz width nrhs a+tallSolveU transposed conjugated =+   Split.tallSolveR transposed conjugated . split_++++toMatrix ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+   LowerUpper vert horiz height width a ->+   Full vert horiz height width a+toMatrix =+   getToMatrix $+   Extent.switchTagPair+      (ToMatrix wideToMatrix)+      (ToMatrix wideToMatrix)+      (ToMatrix tallToMatrix)+      (ToMatrix $+         either+            (Matrix.fromFull . tallToMatrix)+            (Matrix.fromFull . wideToMatrix) .+         caseTallWide)++newtype ToMatrix height width a vert horiz =+   ToMatrix {+      getToMatrix ::+         LowerUpper vert horiz height width a ->+         Full vert horiz height width a+   }++tallToMatrix ::+   (Extent.C vert, Shape.C height, Shape.C width, Eq height, Eq width,+    Class.Floating a) =>+   LowerUpper vert Extent.Small height width a ->+   Full vert Extent.Small height width a+tallToMatrix a =+   multiplyP NonInverted a $ Basic.transpose $+   tallMultiplyU Transposed a $ Basic.transpose $ extractL a++wideToMatrix ::+   (Extent.C horiz, Shape.C height, Shape.C width, Eq height, Eq width,+    Class.Floating a) =>+   LowerUpper Extent.Small horiz height width a ->+   Full Extent.Small horiz height width a+wideToMatrix a =+   multiplyP NonInverted a $ wideMultiplyL NonTransposed a $ extractU a+++multiplyFull ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Shape.C fuse, Eq fuse,+    Class.Floating a) =>+   LowerUpper vert horiz height fuse a ->+   Full vert horiz fuse width a ->+   Full vert horiz height width a+multiplyFull =+   getMultiplyFullRight $+   Extent.switchTagPair+      {-+      We cannot simply use squareFull here,+      because this requires height~width.+      -}+      (MultiplyFullRight wideMultiplyFullRight)+      (MultiplyFullRight wideMultiplyFullRight)+      (MultiplyFullRight tallMultiplyFullRight)+      (MultiplyFullRight $+         either tallMultiplyFullRight wideMultiplyFullRight . caseTallWide)++newtype MultiplyFullRight height fuse width a vert horiz =+   MultiplyFullRight {+      getMultiplyFullRight ::+         LowerUpper vert horiz height fuse a ->+         Full vert horiz fuse width a ->+         Full vert horiz height width a+   }++tallMultiplyFullRight ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Shape.C fuse, Eq height, Eq fuse,+    Class.Floating a) =>+   LowerUpper vert Extent.Small height fuse a ->+   Full vert horiz fuse width a ->+   Full vert horiz height width a+tallMultiplyFullRight a =+   multiplyP NonInverted a .+   Basic.multiply (Matrix.generalizeTall (extractL a)) .+   tallMultiplyU NonTransposed a++wideMultiplyFullRight ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Shape.C fuse, Eq height, Eq fuse,+    Class.Floating a) =>+   LowerUpper Extent.Small horiz height fuse a ->+   Full vert horiz fuse width a ->+   Full vert horiz height width a+wideMultiplyFullRight a =+   multiplyP NonInverted a . wideMultiplyL NonTransposed a .+   Basic.multiply (Matrix.generalizeWide (extractU a))+++tallTransMultiplyFullRight ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Shape.C fuse, Eq height, Eq fuse,+    Class.Floating a) =>+   LowerUpper horiz Extent.Small fuse height a ->+   Full vert horiz fuse width a ->+   Full vert horiz height width a+tallTransMultiplyFullRight a =+   tallMultiplyU Transposed a .+   Basic.multiply (Basic.transpose $ Matrix.generalizeTall $ extractL a) .+   multiplyP Inverted a++wideTransMultiplyFullRight ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Shape.C fuse, Eq height, Eq fuse,+    Class.Floating a) =>+   LowerUpper Extent.Small vert fuse height a ->+   Full vert horiz fuse width a ->+   Full vert horiz height width a+wideTransMultiplyFullRight a =+   Basic.multiply (Basic.transpose $ Matrix.generalizeWide $ extractU a) .+   wideMultiplyL Transposed a .+   multiplyP Inverted a+++caseTallWide ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+   LowerUpper vert horiz height width a ->+   Either (Tall height width a) (Wide height width a)+caseTallWide (LowerUpper ipiv (Array shape a)) =+   either+      (Left . LowerUpper ipiv . flip Array a)+      (Right . LowerUpper ipiv . flip Array a) $+   MatrixShape.caseTallWideSplit shape+++_toRowMajor ::+   (Extent.C vert, Extent.C horiz, Eq height, Shape.C height, Shape.C width,+    Class.Floating a) =>+   LowerUpper vert horiz height width a ->+   LowerUpper vert horiz height width a+_toRowMajor+   (LowerUpper ipiv+      arr@(Array (MatrixShape.Split MatrixShape.Triangle order extent) a)) =+   LowerUpper ipiv $+   case order of+      RowMajor -> arr+      ColumnMajor ->+         Array.unsafeCreate+            (MatrixShape.Split MatrixShape.Triangle RowMajor extent) $ \bPtr ->+         withForeignPtr a $ \aPtr -> do+            let (height, width) = Extent.dimensions extent+            let n = Shape.size width+            let m = Shape.size height+            copyTransposed n m aPtr n bPtr+++instance+   (Extent.C vert, Extent.C horiz) =>+      Type.Box (LU vert horiz height width) where+   type HeightOf (LU vert horiz height width) = height+   type WidthOf (LU vert horiz height width) = width+   height = MatrixShape.splitHeight . Array.shape . split_+   width = MatrixShape.splitWidth . Array.shape . split_++instance+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Eq width) =>+      Multiply.MultiplyVector (LU vert horiz height width) where+   matrixVector lu x =+      Basic.unliftColumn MatrixShape.ColumnMajor+         (multiplyFull (mapExtent ExtentMap.toGeneral lu)) x+   vectorMatrix x lu =+      Basic.unliftColumn MatrixShape.ColumnMajor+         (either tallTransMultiplyFullRight wideTransMultiplyFullRight $+          caseTallWide lu)+         x++instance+   (vert ~ Extent.Small, horiz ~ Extent.Small,+    Shape.C height, height ~ width) =>+      Multiply.MultiplySquare (LU vert horiz height width) where++   squareFull lu =+      ArrMatrix.lift1 $+         multiplyP NonInverted lu .+         wideMultiplyL NonTransposed lu .+         tallMultiplyU NonTransposed lu++   fullSquare = flip $ \lu ->+      ArrMatrix.lift1 $+         Basic.transpose .+         tallMultiplyU Transposed lu .+         wideMultiplyL Transposed lu .+         multiplyP Inverted lu .+         Basic.transpose++instance+   (vert ~ Extent.Small, horiz ~ Extent.Small,+    Shape.C height, height ~ width) =>+      Divide.Determinant (LU vert horiz height width) where+   determinant = determinant++instance+   (vert ~ Extent.Small, horiz ~ Extent.Small,+    Shape.C height, height ~ width) =>+      Divide.Solve (LU vert horiz height width) where+   solve trans = ArrMatrix.lift1 . solveTrans trans
src/Numeric/LAPACK/Matrix.hs view
@@ -1,926 +1,768 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} module Numeric.LAPACK.Matrix (-   Full,-   General, Tall, Wide,-   ZeroInt, zeroInt,-   transpose, adjoint,-   Matrix.height, Matrix.width,-   caseTallWide,-   fromScalar, toScalar,-   fromList,-   mapExtent, fromFull,-   generalizeTall, generalizeWide,-   mapHeight, mapWidth,-   identity,-   diagonal,-   fromRowsNonEmpty,    fromRowArray,    fromRows,-   fromColumnsNonEmpty, fromColumnArray, fromColumns,-   Basic.singleRow,   Basic.singleColumn,-   Basic.flattenRow,  Basic.flattenColumn,-   Basic.liftRow,     Basic.liftColumn,-   Basic.unliftRow,   Basic.unliftColumn,-   toRows, toColumns,-   toRowArray, toColumnArray,-   takeRow, takeColumn,-   takeRows, takeColumns, takeEqually,-   dropRows, dropColumns, dropEqually,-   takeTopRows, takeBottomRows,-   takeLeftColumns, takeRightColumns,-   takeRowArray, takeColumnArray,-   swapRows, swapColumns,-   reverseRows, reverseColumns,-   fromRowMajor, toRowMajor, flatten,-   forceOrder, adaptOrder,-   (|||),-   (===),--   tensorProduct,-   outer,-   sumRank1,--   RealOf,-   add, sub,-   rowSums, columnSums,-   scaleRows, scaleColumns,-   scaleRowsComplex, scaleColumnsComplex,-   scaleRowsReal, scaleColumnsReal,-   multiply,-   multiplyVector,--   Multiply, (<#>),-   MultiplyLeft, (<#),-   MultiplyRight, (#>),-   Indexed, (#!),--   Solve, solve, solveVector,-   Inverse, inverse,-   ) where--import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape-import qualified Numeric.LAPACK.Matrix.Square.Basic as Square-import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent-import qualified Numeric.LAPACK.Matrix.Basic as Basic-import qualified Numeric.LAPACK.Matrix.Private as Matrix-import qualified Numeric.LAPACK.Vector as Vector-import qualified Numeric.LAPACK.Private as Private-import Numeric.LAPACK.Matrix.Shape.Private (Order(RowMajor, ColumnMajor))-import Numeric.LAPACK.Matrix.Multiply-         (Multiply((<#>)), MultiplyLeft((<#)), MultiplyRight((#>)),-          multiplyVector, multiply, multiplyVectorUnchecked)-import Numeric.LAPACK.Matrix.Indexed (Indexed((#!)))-import Numeric.LAPACK.Matrix.Divide-         (Solve(solve), solveVector, Inverse(inverse))-import Numeric.LAPACK.Matrix.Basic-         (transpose, forceOrder, forceRowMajor, scaleRows, scaleColumns)-import Numeric.LAPACK.Matrix.Private-         (Full, Tall, Wide, General, argGeneral, ZeroInt, zeroInt,-          mapExtent, fromFull, generalizeTall, generalizeWide)-import Numeric.LAPACK.Vector (Vector)-import Numeric.LAPACK.Scalar (RealOf, zero, one)-import Numeric.LAPACK.Private-         (pointerSeq, fill, copyTransposed, copySubMatrix, copyBlock)--import qualified Numeric.LAPACK.FFI.Generic as LapackGen-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.Boxed as BoxedArray-import qualified Data.Array.Comfort.Storable.Unchecked as Array-import qualified Data.Array.Comfort.Storable as CheckedArray-import qualified Data.Array.Comfort.Shape as Shape-import Data.Array.Comfort.Storable.Unchecked (Array(Array))-import Data.Array.Comfort.Shape ((:+:)((:+:)))--import Foreign.Marshal.Array (copyArray, advancePtr, pokeArray)-import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)-import Foreign.Ptr (Ptr, castPtr)-import Foreign.Storable (Storable, poke, peek)--import System.IO.Unsafe (unsafePerformIO)--import Control.Monad.Trans.Cont (ContT(ContT), evalContT)-import Control.Monad.IO.Class (liftIO)-import Control.Monad (when, mfilter)--import qualified Data.NonEmpty.Mixed as NonEmptyM-import qualified Data.NonEmpty as NonEmpty-import Data.Complex (Complex)-import Data.Foldable (forM_)-import Data.Maybe (listToMaybe)-import Data.Bool.HT (if')---{- |-conjugate transpose--Problem: @adjoint a <#> a@ is always square,-but how to convince the type checker to choose the Square type?-Anser: Use @Hermitian.toSquare $ Hermitian.covariance a@ instead.--}-adjoint ::-   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,-    Class.Floating a) =>-   Full vert horiz height width a -> Full horiz vert width height a-adjoint = transpose . Vector.conjugate---{- |-Square matrices will be classified as 'Tall'.--}-caseTallWide ::-   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>-   Full vert horiz height width a ->-   Either (Tall height width a) (Wide height width a)-caseTallWide (Array shape a) =-   either (Left . flip Array a) (Right . flip Array a) $-   MatrixShape.caseTallWide shape---fromScalar :: (Storable a) => a -> General () () a-fromScalar = Square.toGeneral . Square.fromScalar--toScalar :: (Storable a) => General () () a -> a-toScalar = argGeneral $ \_ () () a ->-   unsafePerformIO $ withForeignPtr a peek--fromList ::-   (Shape.C height, Shape.C width, Storable a) =>-   height -> width -> [a] -> General height width a-fromList height width =-   CheckedArray.fromList (MatrixShape.general RowMajor height width)---identity ::-   (Shape.C sh, Class.Floating a) =>-   sh -> General sh sh a-identity = Square.toGeneral . Square.identity--diagonal ::-   (Shape.C sh, Class.Floating a) =>-   Vector sh a -> General sh sh a-diagonal = Square.toGeneral . Square.diagonal---{- |-The number of rows must be maintained by the height mapping function.--}-mapHeight ::-   (Shape.C heightA, Shape.C heightB,-    Extent.GeneralTallWide vert horiz,-    Extent.GeneralTallWide horiz vert) =>-   (heightA -> heightB) ->-   Full vert horiz heightA width a ->-   Full vert horiz heightB width a-mapHeight f = Basic.mapHeight $ withSizeCheck "mapHeight" f--{- |-The number of columns must be maintained by the width mapping function.--}-mapWidth ::-   (Shape.C widthA, Shape.C widthB,-    Extent.GeneralTallWide vert horiz,-    Extent.GeneralTallWide horiz vert) =>-   (widthA -> widthB) ->-   Full vert horiz height widthA a ->-   Full vert horiz height widthB a-mapWidth f = Basic.mapWidth $ withSizeCheck "mapWidth" f--withSizeCheck ::-   (Shape.C sha, Shape.C shb) =>-   String -> (sha -> shb) -> sha -> shb-withSizeCheck name f sizeA =-   let sizeB = f sizeA-   in if Shape.size sizeA == Shape.size sizeB-         then sizeB-         else error $ name ++ ": sizes mismatch"---fromRowsNonEmpty ::-   (Shape.C width, Eq width, Storable a) =>-   NonEmpty.T [] (Vector width a) -> General ZeroInt width a-fromRowsNonEmpty (NonEmpty.Cons row rows) =-   fromRows (Array.shape row) (row:rows)--fromRowArray ::-   (Shape.C height, Shape.C width, Eq width, Storable a) =>-   width -> BoxedArray.Array height (Vector width a) -> General height width a-fromRowArray width rows =-   Basic.mapHeight (const $ BoxedArray.shape rows) $-   fromRows width $ BoxedArray.toList rows--fromRows ::-   (Shape.C width, Eq width, Storable a) =>-   width -> [Vector width a] -> General ZeroInt width a-fromRows width rows =-   Array.unsafeCreate-      (MatrixShape.general RowMajor (zeroInt $ length rows) width)-      (gather width rows)--fromColumnsNonEmpty ::-   (Shape.C height, Eq height, Storable a) =>-   NonEmpty.T [] (Vector height a) -> General height ZeroInt a-fromColumnsNonEmpty (NonEmpty.Cons column columns) =-   fromColumns (Array.shape column) (column:columns)--fromColumnArray ::-   (Shape.C height, Eq height, Shape.C width, Storable a) =>-   height -> BoxedArray.Array width (Vector height a) -> General height width a-fromColumnArray height columns =-   Basic.mapWidth (const $ BoxedArray.shape columns) $-   fromColumns height $ BoxedArray.toList columns--fromColumns ::-   (Shape.C height, Eq height, Storable a) =>-   height -> [Vector height a] -> General height ZeroInt a-fromColumns height columns =-   Array.unsafeCreate-      (MatrixShape.general ColumnMajor height (zeroInt $ length columns))-      (gather height columns)--gather ::-   (Shape.C width, Eq width, Storable a) =>-   width -> [Array width a] -> Ptr a -> IO ()-gather width rows dstPtr =-   let widthSize = Shape.size width-   in forM_ (zip (pointerSeq widthSize dstPtr) rows) $-         \(dstRowPtr, Array.Array rowWidth srcFPtr) ->-         withForeignPtr srcFPtr $ \srcPtr -> do-            Call.assert-               "Matrix.fromRows/fromColumnsNonEmpty: non-matching vector size"-               (width == rowWidth)-            copyArray dstRowPtr srcPtr widthSize---toRows ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.C width, Class.Floating a) =>-   Full vert horiz height width a -> [Vector width a]-toRows a =-   let ad = Basic.mapHeight Shape.Deferred $ fromFull a-   in map (takeRow ad) $ Shape.indices $ Matrix.height ad--toColumns ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.C width, Class.Floating a) =>-   Full vert horiz height width a -> [Vector height a]-toColumns a =-   let ad = Basic.mapWidth Shape.Deferred $ fromFull a-   in map (takeColumn ad) $ Shape.indices $ Matrix.width ad--toRowArray ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.C width, Class.Floating a) =>-   Full vert horiz height width a -> BoxedArray.Array height (Vector width a)-toRowArray a = BoxedArray.fromList (Matrix.height a) (toRows a)--toColumnArray ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.C width, Class.Floating a) =>-   Full vert horiz height width a -> BoxedArray.Array width (Vector height a)-toColumnArray a = BoxedArray.fromList (Matrix.width a) (toColumns a)---takeRow ::-   (Extent.C vert, Extent.C horiz,-    Shape.Indexed height, Shape.C width, Shape.Index height ~ ix,-    Class.Floating a) =>-   Full vert horiz height width a -> ix -> Vector width a-takeRow (Array (MatrixShape.Full order extent) x) ix =-   let (height,width) = Extent.dimensions extent-   in case order of-         RowMajor -> pickConsecutive height width x ix-         ColumnMajor -> pickScattered width height x ix--takeColumn ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.Indexed width, Shape.Index width ~ ix,-    Class.Floating a) =>-   Full vert horiz height width a -> ix -> Vector height a-takeColumn (Array (MatrixShape.Full order extent) x) ix =-   let (height,width) = Extent.dimensions extent-   in case order of-         RowMajor -> pickScattered height width x ix-         ColumnMajor -> pickConsecutive width height x ix--pickConsecutive ::-   (Shape.Indexed height, Shape.C width, Shape.Index height ~ ix,-    Class.Floating a) =>-   height -> width -> ForeignPtr a -> ix -> Vector width a-pickConsecutive height width x ix =-   Array.unsafeCreateWithSize width $ \n yPtr -> evalContT $ do-      let offset = Shape.offset height ix-      nPtr <- Call.cint n-      xPtr <- ContT $ withForeignPtr x-      incxPtr <- Call.cint 1-      incyPtr <- Call.cint 1-      liftIO $-         BlasGen.copy nPtr (advancePtr xPtr (n*offset)) incxPtr yPtr incyPtr--pickScattered ::-   (Shape.C height, Shape.Indexed width, Shape.Index width ~ ix,-    Class.Floating a) =>-   height -> width -> ForeignPtr a -> ix -> Vector height a-pickScattered height width x ix =-   Array.unsafeCreateWithSize height $ \n yPtr -> evalContT $ do-      let offset = Shape.offset width ix-      nPtr <- Call.cint n-      xPtr <- ContT $ withForeignPtr x-      incxPtr <- Call.cint $ Shape.size width-      incyPtr <- Call.cint 1-      liftIO $-         BlasGen.copy nPtr (advancePtr xPtr offset) incxPtr yPtr incyPtr---takeTopRows ::-   (Extent.C vert, Shape.C height0, Shape.C height1, Shape.C width,-    Class.Floating a) =>-   Full vert Extent.Big (height0:+:height1) width a ->-   Full vert Extent.Big height0 width a-takeTopRows (Array (MatrixShape.Full order extentA) a) =-   let (heightA@(heightB:+:_), width) = Extent.dimensions extentA-       extentB = Extent.reduceWideHeight heightB extentA-       ma = Shape.size heightA-       mb = Shape.size heightB-       n = Shape.size width-   in Array.unsafeCreateWithSize (MatrixShape.Full order extentB) $-            \blockSize bPtr ->-      withForeignPtr a $ \aPtr ->-      case order of-         RowMajor -> copyBlock blockSize aPtr bPtr-         ColumnMajor -> copySubMatrix mb n ma aPtr mb bPtr--takeBottomRows ::-   (Extent.C vert, Shape.C height0, Shape.C height1, Shape.C width,-    Class.Floating a) =>-   Full vert Extent.Big (height0:+:height1) width a ->-   Full vert Extent.Big height1 width a-takeBottomRows (Array (MatrixShape.Full order extentA) a) =-   let (heightA@(height0:+:heightB), width) = Extent.dimensions extentA-       extentB = Extent.reduceWideHeight heightB extentA-       k = Shape.size height0-       ma = Shape.size heightA-       mb = Shape.size heightB-       n = Shape.size width-   in Array.unsafeCreateWithSize (MatrixShape.Full order extentB) $-            \blockSize bPtr ->-      withForeignPtr a $ \aPtr ->-      case order of-         RowMajor -> copyBlock blockSize (advancePtr aPtr (k*n)) bPtr-         ColumnMajor -> copySubMatrix mb n ma (advancePtr aPtr k) mb bPtr--takeLeftColumns ::-   (Extent.C vert, Shape.C height, Shape.C width0, Shape.C width1,-    Class.Floating a) =>-   Full Extent.Big vert height (width0:+:width1) a ->-   Full Extent.Big vert height width0 a-takeLeftColumns = transpose . takeTopRows . transpose--takeRightColumns ::-   (Extent.C vert, Shape.C height, Shape.C width0, Shape.C width1,-    Class.Floating a) =>-   Full Extent.Big vert height (width0:+:width1) a ->-   Full Extent.Big vert height width1 a-takeRightColumns = transpose . takeBottomRows . transpose---splitRows ::-   (Extent.C vert, Shape.C width, Class.Floating a) =>-   Int ->-   Full vert Extent.Big ZeroInt width a ->-   Full vert Extent.Big (ZeroInt:+:ZeroInt) width a-splitRows k =-   Array.mapShape-      (\(MatrixShape.Full order extentA) ->-         let (Shape.ZeroBased heightA) = Extent.height extentA-             heightB = min k heightA-         in if' (k<0) (error "split: negative number") $-            MatrixShape.Full order $-            Extent.reduceWideHeight-               (Shape.ZeroBased heightB :+: Shape.ZeroBased (heightA-heightB))-               extentA)--takeRows, dropRows ::-   (Extent.C vert, Shape.C width, Class.Floating a) =>-   Int ->-   Full vert Extent.Big ZeroInt width a ->-   Full vert Extent.Big ZeroInt width a-takeRows k = takeTopRows . splitRows k-dropRows k = takeBottomRows . splitRows k--takeColumns, dropColumns ::-   (Extent.C horiz, Shape.C height, Class.Floating a) =>-   Int ->-   Full Extent.Big horiz height ZeroInt a ->-   Full Extent.Big horiz height ZeroInt a-takeColumns k = transpose . takeRows k . transpose-dropColumns k = transpose . dropRows k . transpose---{- |-Take a left-top aligned square or as much as possible of it.-The advantange of this function is that it maintains the matrix size relation,-e.g. Square remains Square, Tall remains Tall.--}-takeEqually ::-   (Extent.C vert, Extent.C horiz, Class.Floating a) =>-   Int ->-   Full vert horiz ZeroInt ZeroInt a ->-   Full vert horiz ZeroInt ZeroInt a-takeEqually k (Array (MatrixShape.Full order extentA) a) =-   let (Shape.ZeroBased heightA, Shape.ZeroBased widthA) =-         Extent.dimensions extentA-       heightB = min k heightA-       widthB  = min k widthA-       extentB =-         Extent.reduceConsistent-            (Shape.ZeroBased heightB) (Shape.ZeroBased widthB) extentA-   in if' (k<0) (error "take: negative number") $-      Array.unsafeCreate (MatrixShape.Full order extentB) $ \bPtr ->-      withForeignPtr a $ \aPtr ->-      case order of-         RowMajor -> copySubMatrix widthB heightB widthA aPtr widthB bPtr-         ColumnMajor -> copySubMatrix heightB widthB heightA aPtr heightB bPtr--{- |-Drop the same number of top-most rows and left-most columns.-The advantange of this function is that it maintains the matrix size relation,-e.g. Square remains Square, Tall remains Tall.--}-dropEqually ::-   (Extent.C vert, Extent.C horiz, Class.Floating a) =>-   Int ->-   Full vert horiz ZeroInt ZeroInt a ->-   Full vert horiz ZeroInt ZeroInt a-dropEqually k (Array (MatrixShape.Full order extentA) a) =-   let (Shape.ZeroBased heightA, Shape.ZeroBased widthA) =-         Extent.dimensions extentA-       heightB = heightA - top; top  = min k heightA-       widthB  = widthA - left; left = min k widthA-       extentB =-         Extent.reduceConsistent-            (Shape.ZeroBased heightB) (Shape.ZeroBased widthB) extentA-   in if' (k<0) (error "drop: negative number") $-      Array.unsafeCreate (MatrixShape.Full order extentB) $ \bPtr ->-      withForeignPtr a $ \aPtr ->-      case order of-         RowMajor ->-            copySubMatrix widthB heightB-               widthA (advancePtr aPtr (top*widthA+left)) widthB bPtr-         ColumnMajor ->-            copySubMatrix heightB widthB-               heightA (advancePtr aPtr (left*heightA+top)) heightB bPtr---swapRows ::-   (Extent.C vert, Extent.C horiz,-    Shape.Indexed height, Shape.C width, Class.Floating a) =>-   Shape.Index height -> Shape.Index height ->-   Full vert horiz height width a -> Full vert horiz height width a-swapRows i j (Array shape@(MatrixShape.Full order extent) a) =-   Array.unsafeCreateWithSize shape $ \blockSize bPtr -> evalContT $ do-      let (height,width) = Extent.dimensions extent-      let m = Shape.size height-      let n = Shape.size width-      nPtr <- Call.cint n-      aPtr <- ContT $ withForeignPtr a-      let offsetI = Shape.offset height i-      let offsetJ = Shape.offset height j-      let (incVert,incHoriz) =-            case order of-               RowMajor -> (n,1)-               ColumnMajor -> (1,m)-      incPtr <- Call.cint incHoriz-      liftIO $ do-         copyBlock blockSize aPtr bPtr-         when (offsetI/=offsetJ) $-            BlasGen.swap nPtr-               (advancePtr bPtr (incVert*offsetI)) incPtr-               (advancePtr bPtr (incVert*offsetJ)) incPtr--swapColumns ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.Indexed width, Class.Floating a) =>-   Shape.Index width -> Shape.Index width ->-   Full vert horiz height width a -> Full vert horiz height width a-swapColumns i j = transpose . swapRows i j . transpose----- alternative: laswp-reverseRows ::-   (Extent.C vert, Extent.C horiz, Shape.C width, Class.Floating a) =>-   Full vert horiz ZeroInt width a -> Full vert horiz ZeroInt width a-reverseRows (Array shape@(MatrixShape.Full order extent) a) =-   Array.unsafeCreateWithSize shape $ \blockSize bPtr -> evalContT $ do-      let (height,width) = Extent.dimensions extent-      let n = Shape.size height-      let m = Shape.size width-      fwdPtr <- Call.bool True-      nPtr <- Call.cint n-      mPtr <- Call.cint m-      kPtr <- Call.allocaArray n-      aPtr <- ContT $ withForeignPtr a-      liftIO $ do-         copyBlock blockSize aPtr bPtr-         pokeArray kPtr $ take n $ iterate (subtract 1) $ fromIntegral n-         case order of-            RowMajor -> LapackGen.lapmt fwdPtr mPtr nPtr bPtr mPtr kPtr-            ColumnMajor -> LapackGen.lapmr fwdPtr nPtr mPtr bPtr nPtr kPtr--reverseColumns ::-   (Extent.C vert, Extent.C horiz, Shape.C height, Class.Floating a) =>-   Full vert horiz height ZeroInt a -> Full vert horiz height ZeroInt a-reverseColumns = transpose . reverseRows . transpose---{--The function is optimized for blocks of consecutive rows.-For scattered rows in column major order-the function has quite ugly memory access patterns.--}-takeRowArray ::-   (Shape.Indexed height, Shape.C width, Shape.C sh, Class.Floating a) =>-   BoxedArray.Array sh (Shape.Index height) ->-   General height width a -> General sh width a-takeRowArray ixs (Array (MatrixShape.Full order extent) a) =-   let (heightA, width) = Extent.dimensions extent-       heightB = BoxedArray.shape ixs-       offsets = map (Shape.offset heightA) $ BoxedArray.toList ixs-       startBlocks blocks = zip (scanl (+) 0 $ map fst blocks) blocks-       ma = Shape.size heightA-       mb = Shape.size heightB-       n = Shape.size width-   in Array.unsafeCreate (MatrixShape.general order heightB width) $ \bPtr ->-      withForeignPtr a $ \aPtr ->-      case order of-         RowMajor -> do-            forM_ (startBlocks $ chopRowBlocks offsets) $-               \(dest, (numRows, (start,step))) ->-                  copySubMatrix n numRows-                     (step*n) (advancePtr aPtr (start*n))-                     n (advancePtr bPtr (dest*n))-         ColumnMajor -> do-            forM_ (startBlocks $ chopColumnBlocks offsets) $-               \(dest, (numRows, start)) ->-                  copySubMatrix numRows n-                     ma (advancePtr aPtr start)-                     mb (advancePtr bPtr dest)--chopRowBlocks :: (Integral i) => [i] -> [(Int,(i,i))]-chopRowBlocks =-   let go [] = []-       go is@(i0:is0) =-         case mfilter (i0<) $ listToMaybe is0 of-            Nothing -> (1,(i0,0)) : go is0-            Just i1 ->-               let (consecutive,remainder) =-                     span (uncurry (==)) $ zip [i0,i1..] is-               in (length consecutive, (i0,i1-i0)) : go (map snd remainder)-   in go--chopColumnBlocks :: (Integral i) => [i] -> [(Int,i)]-chopColumnBlocks =-   map (\is -> (length $ NonEmpty.flatten is, NonEmpty.head is)) .-   NonEmptyM.groupBy (\i j -> i+1 == j)---takeColumnArray ::-   (Shape.C height, Shape.Indexed width, Shape.C sh, Class.Floating a) =>-   BoxedArray.Array sh (Shape.Index width) ->-   General height width a -> General height sh a-takeColumnArray ixs = transpose . takeRowArray ixs . transpose----fromRowMajor ::-   (Shape.C height, Shape.C width, Class.Floating a) =>-   Array (height,width) a -> General height width a-fromRowMajor = Array.mapShape (uncurry $ MatrixShape.general RowMajor)--toRowMajor ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.C width, Class.Floating a) =>-   Full vert horiz height width a -> Array (height,width) a-toRowMajor =-   Array.mapShape-      (\shape -> (MatrixShape.fullHeight shape, MatrixShape.fullWidth shape)) .-   forceRowMajor--{- |-@adaptOrder x y@ contains the data of @y@ with the layout of @x@.--}-adaptOrder ::-   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,-    Class.Floating a) =>-   Full vert horiz height width a ->-   Full vert horiz height width a ->-   Full vert horiz height width a-adaptOrder x = forceOrder (MatrixShape.fullOrder $ Array.shape x)--flatten ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.C width, Class.Floating a) =>-   Full vert horiz height width a -> Vector ZeroInt a-flatten = Array.mapShape (zeroInt . Shape.size) . toRowMajor---infixl 3 |||-infixl 2 ===--(|||) ::-   (Extent.C vert, Shape.C height, Eq height, Shape.C widtha, Shape.C widthb,-    Class.Floating a) =>-   Full vert Extent.Big height widtha a ->-   Full vert Extent.Big height widthb a ->-   Full vert Extent.Big height (widtha:+:widthb) a-(|||)-      (Array (MatrixShape.Full orderA extentA) a)-      (Array (MatrixShape.Full orderB extentB) b) =-   let (heightA,widthA) = Extent.dimensions extentA-       (heightB,widthB) = Extent.dimensions extentB-       extent = Extent.widen (widthA:+:widthB) extentA-       shape order = MatrixShape.Full order extent-   in-    if heightA /= heightB-      then error "(|||): mismatching heights"-      else-         case (orderA,orderB) of-            (RowMajor,RowMajor) ->-               Array.unsafeCreate (shape RowMajor) $-               \cPtr -> evalContT $ do-                  let n = Shape.size heightA-                  let ma = Shape.size widthA-                  let mb = Shape.size widthB-                  let m = ma+mb-                  maPtr <- Call.cint ma-                  mbPtr <- Call.cint mb-                  aPtr <- ContT $ withForeignPtr a-                  bPtr <- ContT $ withForeignPtr b-                  incxPtr <- Call.cint 1-                  incyPtr <- Call.cint 1-                  liftIO $-                     sequence_ $ take n $-                     zipWith3-                        (\akPtr bkPtr ckPtr -> do-                           BlasGen.copy maPtr akPtr incxPtr ckPtr incyPtr-                           BlasGen.copy mbPtr bkPtr incxPtr-                              (ckPtr `advancePtr` ma) incyPtr)-                        (pointerSeq ma aPtr)-                        (pointerSeq mb bPtr)-                        (pointerSeq m cPtr)-            (RowMajor,ColumnMajor) ->-               Array.unsafeCreate (shape ColumnMajor) $-               \cPtr -> evalContT $ do-                  let n = Shape.size heightA-                  let ma = Shape.size widthA-                  let mb = Shape.size widthB-                  aPtr <- ContT $ withForeignPtr a-                  bPtr <- ContT $ withForeignPtr b-                  liftIO $ do-                     copyTransposed n ma aPtr n cPtr-                     copyBlock (n*mb) bPtr (advancePtr cPtr (n*ma))-            (ColumnMajor,RowMajor) ->-               Array.unsafeCreate (shape ColumnMajor) $-               \cPtr -> evalContT $ do-                  let n = Shape.size heightA-                  let ma = Shape.size widthA-                  let mb = Shape.size widthB-                  let volA = n*ma-                  aPtr <- ContT $ withForeignPtr a-                  bPtr <- ContT $ withForeignPtr b-                  liftIO $ do-                     copyBlock volA aPtr cPtr-                     copyTransposed n mb bPtr n (advancePtr cPtr volA)-            (ColumnMajor,ColumnMajor) ->-               Array.unsafeCreate (shape ColumnMajor) $-               \cPtr -> evalContT $ do-                  let n = Shape.size heightA-                  let na = n * Shape.size widthA-                  let nb = n * Shape.size widthB-                  naPtr <- Call.cint na-                  nbPtr <- Call.cint nb-                  aPtr <- ContT $ withForeignPtr a-                  bPtr <- ContT $ withForeignPtr b-                  incxPtr <- Call.cint 1-                  incyPtr <- Call.cint 1-                  liftIO $ do-                     BlasGen.copy naPtr aPtr incxPtr cPtr incyPtr-                     BlasGen.copy nbPtr bPtr incxPtr-                        (cPtr `advancePtr` na) incyPtr--(===) ::-   (Extent.C horiz, Shape.C width, Eq width, Shape.C heighta, Shape.C heightb,-    Class.Floating a) =>-   Full Extent.Big horiz heighta width a ->-   Full Extent.Big horiz heightb width a ->-   Full Extent.Big horiz (heighta:+:heightb) width a-(===) a b = transpose (transpose a ||| transpose b)---add, sub ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.C width, Eq height, Eq width,-    Class.Floating a) =>-   Full vert horiz height width a ->-   Full vert horiz height width a ->-   Full vert horiz height width a-add x y = Vector.add (adaptOrder y x) y-sub x y = Vector.sub (adaptOrder y x) y---rowSums ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.C width, Class.Floating a) =>-   Full vert horiz height width a -> Vector height a-rowSums m =-   let width = MatrixShape.fullWidth $ Array.shape m-   in  multiplyVectorUnchecked m (Vector.constant width one)--columnSums ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.C width, Class.Floating a) =>-   Full vert horiz height width a -> Vector width a-columnSums m =-   let height = MatrixShape.fullHeight $ Array.shape m-   in  multiplyVectorUnchecked (transpose m) (Vector.constant height one)---scaleRowsComplex ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Eq height, Shape.C width, Class.Real a) =>-   Vector height a ->-   Full vert horiz height width (Complex a) ->-   Full vert horiz height width (Complex a)-scaleRowsComplex-   (Array heightX x) (Array shape@(MatrixShape.Full order extent) a) =-      Array.unsafeCreate shape $ \bComplexPtr -> do-   let (height,width) = Extent.dimensions extent-   Call.assert "scaleRowsComplex: sizes mismatch" (heightX == height)-   let bPtr = castPtr bComplexPtr-   case order of-      RowMajor -> evalContT $ do-         let m = Shape.size height-         let n = Shape.size width * 2-         alphaPtr <- Call.alloca-         nPtr <- Call.cint n-         xPtr <- ContT $ withForeignPtr x-         aPtr <- fmap castPtr $ ContT $ withForeignPtr a-         incaPtr <- Call.cint 1-         incbPtr <- Call.cint 1-         liftIO $ sequence_ $ take m $-            zipWith3-               (\xkPtr akPtr bkPtr -> do-                  poke alphaPtr =<< peek xkPtr-                  BlasGen.copy nPtr akPtr incaPtr bkPtr incbPtr-                  BlasGen.scal nPtr alphaPtr bkPtr incbPtr)-               (pointerSeq 1 xPtr)-               (pointerSeq n aPtr)-               (pointerSeq n bPtr)-      ColumnMajor -> evalContT $ do-         let m = Shape.size width-         let nr = Shape.size height-         let n = 2*nr-         transPtr <- Call.char 'N'-         nrPtr <- Call.cint nr-         nPtr <- Call.cint n-         klPtr <- Call.cint 0-         kuPtr <- Call.cint 0-         alphaPtr <- Call.number one-         xrPtr <- ContT $ withForeignPtr x-         xPtr <- Call.allocaArray n-         incxrPtr <- Call.cint 1-         incxPtr <- Call.cint 2-         ldxPtr <- Call.leadingDim 1-         aPtr <- fmap castPtr $ ContT $ withForeignPtr a-         incaPtr <- Call.cint 1-         betaPtr <- Call.number zero-         incbPtr <- Call.cint 1-         liftIO $ do-            BlasGen.copy nrPtr xrPtr incxrPtr xPtr incxPtr-            BlasGen.copy nrPtr xrPtr incxrPtr (advancePtr xPtr 1) incxPtr-            sequence_ $ take m $-               zipWith-                  (\akPtr bkPtr ->-                     Private.gbmv transPtr-                        nPtr nPtr klPtr kuPtr alphaPtr xPtr ldxPtr-                        akPtr incaPtr betaPtr bkPtr incbPtr)-                  (pointerSeq n aPtr)-                  (pointerSeq n bPtr)--scaleColumnsComplex ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.C width, Eq width, Class.Real a) =>-   Vector width a ->-   Full vert horiz height width (Complex a) ->-   Full vert horiz height width (Complex a)-scaleColumnsComplex x = transpose . scaleRowsComplex x . transpose---scaleRowsReal ::-   (Extent.C vert, Extent.C horiz, Shape.C height, Eq height, Shape.C width,-    Class.Floating a) =>-   Vector height (RealOf a) ->-   Full vert horiz height width a ->-   Full vert horiz height width a-scaleRowsReal =-   getScaleRowsReal $-   Class.switchFloating-      (ScaleRowsReal scaleRows)-      (ScaleRowsReal scaleRows)-      (ScaleRowsReal scaleRowsComplex)-      (ScaleRowsReal scaleRowsComplex)--newtype ScaleRowsReal f g a =-   ScaleRowsReal {getScaleRowsReal :: f (RealOf a) -> g a -> g a}--scaleColumnsReal ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Shape.C width, Eq width, Class.Floating a) =>-   Vector width (RealOf a) ->-   Full vert horiz height width a ->-   Full vert horiz height width a-scaleColumnsReal x = transpose . scaleRowsReal x . transpose---{- |-> tensorProduct order x y = singleColumn order x <#> singleRow order y--}-tensorProduct ::-   (Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>-   Order -> Vector height a -> Vector width a -> General height width a-tensorProduct order x y =-   case order of-      ColumnMajor -> tensorProd 'T' order x y-      RowMajor -> transpose $ tensorProd 'T' order y x--{- |-> outer order x y = tensorProduct order x (Vector.conjugate y)--}-outer ::-   (Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>-   Order -> Vector height a -> Vector width a -> General height width a-outer order x y =-   case order of-      ColumnMajor -> tensorProd 'C' ColumnMajor x y-      RowMajor -> transpose $ tensorProd 'C' RowMajor y x--{-# INLINE tensorProd #-}-tensorProd ::-   (Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>-   Char -> Order ->-   Vector height a -> Vector width a -> General height width a-tensorProd trans order (Array shX x) (Array shY y) =-   Array.unsafeCreate (MatrixShape.general MatrixShape.ColumnMajor shX shY) $-      \cPtr -> do-   let m = Shape.size shX-   let n = Shape.size shY-   let ((transa,transb),(lda,ldb)) =-         case order of-            ColumnMajor -> (('N',trans),(m,n))-            RowMajor -> ((trans,'N'),(1,1))-   evalContT $ do-      transaPtr <- Call.char transa-      transbPtr <- Call.char transb-      mPtr <- Call.cint m-      nPtr <- Call.cint n-      kPtr <- Call.cint 1-      alphaPtr <- Call.number one-      aPtr <- ContT $ withForeignPtr x-      ldaPtr <- Call.leadingDim lda-      bPtr <- ContT $ withForeignPtr y-      ldbPtr <- Call.leadingDim ldb-      betaPtr <- Call.number zero-      ldcPtr <- Call.leadingDim m-      liftIO $-         BlasGen.gemm-            transaPtr transbPtr mPtr nPtr kPtr alphaPtr-            aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr---sumRank1 ::-   (Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>-   (height,width) ->-   [(a, (Vector height a, Vector width a))] -> General height width a-sumRank1 (height,width) xys =-   Array.unsafeCreateWithSize (MatrixShape.general ColumnMajor height width) $-      \size aPtr ->-   evalContT $ do-      let m = Shape.size height-      let n = Shape.size width-      mPtr <- Call.cint m-      nPtr <- Call.cint n-      alphaPtr <- Call.alloca-      incxPtr <- Call.cint 1-      incyPtr <- Call.cint 1-      ldaPtr <- Call.leadingDim m-      liftIO $ do-         fill zero size aPtr-         forM_ xys $ \(alpha, (Array shX x, Array shY y)) ->-            withForeignPtr x $ \xPtr ->-            withForeignPtr y $ \yPtr -> do-               Call.assert "Matrix.sumRank1: non-matching height" (height==shX)-               Call.assert "Matrix.sumRank1: non-matching width" (width==shY)-               poke alphaPtr alpha-               BlasGen.gerc mPtr nPtr-                  alphaPtr xPtr incxPtr yPtr incyPtr aPtr ldaPtr+   Type.Matrix,+   Full,+   General, Tall, Wide, Square.Square,+   Triangular.Triangular, Triangular.Upper, Triangular.Lower,+   Triangular.Diagonal, Triangular.Symmetric,+   Hermitian.Hermitian,+   Permutation,++   ShapeInt, shapeInt,+   transpose, adjoint,+   Type.height, Type.width,+   Type.HeightOf, Type.WidthOf,+   Type.Box, Type.indices,+   ArrMatrix.reshape,+   ArrMatrix.mapShape,+   caseTallWide,+   fromScalar, toScalar,+   fromList,+   mapExtent, fromFull,+   asGeneral, asTall, asWide,+   tallFromGeneral, wideFromGeneral,+   generalizeTall, generalizeWide,+   mapHeight, mapWidth,+   identity,+   diagonal,+   fromRowsNonEmpty,    fromRowArray,    fromRows,+   fromRowsNonEmptyContainer,    fromRowContainer,+   fromColumnsNonEmpty, fromColumnArray, fromColumns,+   fromColumnsNonEmptyContainer, fromColumnContainer,+   singleRow,   singleColumn,+   flattenRow,  flattenColumn,+   liftRow,     liftColumn,+   unliftRow,   unliftColumn,+   toRows, toColumns,+   toRowArray, toColumnArray,+   toRowContainer, toColumnContainer,+   takeRow, takeColumn,+   takeRows, takeColumns, takeEqually,+   dropRows, dropColumns, dropEqually,+   takeTop, takeBottom,+   takeLeft, takeRight,+   takeRowArray, takeColumnArray,+   swapRows, swapColumns,+   reverseRows, reverseColumns,+   fromRowMajor, toRowMajor,+   ArrMatrix.forceOrder, ArrMatrix.adaptOrder,+   Basic.OrderBias, leftBias, rightBias, contiguousBias,+   (|||), beside,+   (===), above,++   (|*-),+   tensorProduct,+   outer,+   kronecker,+   sumRank1,++   map,+   MatrixClass.Complex, MatrixClass.conjugate,+   MatrixClass.fromReal, MatrixClass.toComplex,+   MatrixClass.SquareShape, MatrixClass.toSquare,+   MatrixClass.identityFrom,+   MatrixClass.identityFromHeight, MatrixClass.identityFromWidth,+   MatrixClass.takeDiagonal, MatrixClass.trace,++   RealOf,+   rowSums, columnSums,+   rowArgAbsMaximums, columnArgAbsMaximums,+   scaleRows, scaleColumns,+   scaleRowsReal, scaleColumnsReal,+   (\*#), (#*\),+   (\\#), (#/\),+   multiply,+   multiplyVector,++   ArrMatrix.zero, ArrMatrix.negate,+   ArrMatrix.scale, ArrMatrix.scaleReal, ArrMatrix.scaleRealReal,+   (ArrMatrix..*#),+   ArrMatrix.add, ArrMatrix.sub,+   (ArrMatrix.#+#), (ArrMatrix.#-#),+   Multiply.Multiply, (Multiply.#*#),+   Multiply.MultiplyVector, (Multiply.#*|), (Multiply.-*#),+   Multiply.MultiplySquare, multiplySquare,+   Multiply.Power, Multiply.square, Multiply.power,+   (Multiply.##*#), (Multiply.#*##),+   Indexed.Indexed, (Indexed.#!),++   Divide.Determinant, Divide.determinant,+   Divide.Solve, Divide.solve, Divide.solveLeft, Divide.solveRight,+   (Divide.##/#), (Divide.#\##),+   Divide.solveVector, (Divide.-/#), (Divide.#\|),+   Divide.Inverse, Divide.inverse,+   Mod.Transposition(..),+   ) where++import qualified Numeric.LAPACK.Matrix.Permutation as PermMatrix+import qualified Numeric.LAPACK.Matrix.Triangular as Triangular+import qualified Numeric.LAPACK.Matrix.Hermitian as Hermitian+import qualified Numeric.LAPACK.Matrix.Square as Square++import qualified Numeric.LAPACK.Matrix.Extent as Extent+import qualified Numeric.LAPACK.Matrix.Basic as Basic+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Type as Type+import qualified Numeric.LAPACK.Matrix.Plain as Plain+import qualified Numeric.LAPACK.Matrix.Modifier as Mod+import qualified Numeric.LAPACK.Matrix.Divide as Divide+import qualified Numeric.LAPACK.Matrix.Multiply as Multiply+import qualified Numeric.LAPACK.Matrix.Indexed as Indexed+import qualified Numeric.LAPACK.Matrix.Class as MatrixClass+import qualified Numeric.LAPACK.Matrix.Private as Matrix+import qualified Numeric.LAPACK.Vector as Vector+import Numeric.LAPACK.Matrix.Shape.Private (Order)+import Numeric.LAPACK.Matrix.Array (Full, General, Tall, Wide)+import Numeric.LAPACK.Matrix.Private (ShapeInt, shapeInt)+import Numeric.LAPACK.Vector (Vector)+import Numeric.LAPACK.Scalar (RealOf)++import qualified Numeric.Netlib.Class as Class++import qualified Data.Array.Comfort.Storable as Array+import qualified Data.Array.Comfort.Boxed as BoxedArray+import qualified Data.Array.Comfort.Container as Container+import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Storable.Unchecked (Array, (!))+import Data.Array.Comfort.Shape ((:+:))++import Foreign.Storable (Storable)++import qualified Data.NonEmpty as NonEmpty+import qualified Data.Either.HT as EitherHT++import Prelude hiding (map)+++type Permutation sh = Type.Matrix (PermMatrix.Permutation sh)++mapExtent ::+   (Extent.C vertA, Extent.C horizA) =>+   (Extent.C vertB, Extent.C horizB) =>+   Extent.Map vertA horizA vertB horizB height width ->+   Full vertA horizA height width a -> Full vertB horizB height width a+mapExtent = ArrMatrix.lift1 . Plain.mapExtent++fromFull ::+   (Extent.C vert, Extent.C horiz) =>+   Full vert horiz height width a -> General height width a+fromFull = ArrMatrix.lift1 Plain.fromFull++tallFromGeneral ::+   (Shape.C height, Shape.C width, Storable a) =>+   General height width a -> Tall height width a+tallFromGeneral = ArrMatrix.lift1 Plain.tallFromGeneral++wideFromGeneral ::+   (Shape.C height, Shape.C width, Storable a) =>+   General height width a -> Wide height width a+wideFromGeneral = ArrMatrix.lift1 Plain.wideFromGeneral++generalizeTall ::+   (Extent.C vert, Extent.C horiz) =>+   Full vert Extent.Small height width a -> Full vert horiz height width a+generalizeTall = mapExtent Extent.generalizeTall++generalizeWide ::+   (Extent.C vert, Extent.C horiz) =>+   Full Extent.Small horiz height width a -> Full vert horiz height width a+generalizeWide = mapExtent Extent.generalizeWide+++asGeneral :: General height width a -> General height width a+asGeneral = id++asTall :: Tall height width a -> Tall height width a+asTall = id++asWide :: Wide height width a -> Wide height width a+asWide = id++++fromScalar :: (Storable a) => a -> General () () a+fromScalar = fromFull . Square.fromScalar++toScalar :: (Storable a) => General () () a -> a+toScalar a = either id id (Matrix.revealOrder (ArrMatrix.toVector a)) ! ((),())++fromList ::+   (Shape.C height, Shape.C width, Storable a) =>+   height -> width -> [a] -> General height width a+fromList height width = ArrMatrix.lift0 . Plain.fromList height width+++identity ::+   (Shape.C sh, Class.Floating a) =>+   sh -> General sh sh a+identity = ArrMatrix.lift0 . Plain.identity++diagonal ::+   (Shape.C sh, Class.Floating a) =>+   Vector sh a -> General sh sh a+diagonal = ArrMatrix.lift0 . Plain.diagonal+++{- |+Square matrices will be classified as 'Tall'.+-}+caseTallWide ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+   Full vert horiz height width a ->+   Either (Tall height width a) (Wide height width a)+caseTallWide =+   EitherHT.mapBoth ArrMatrix.lift0 ArrMatrix.lift0 .+   Basic.caseTallWide . ArrMatrix.toVector+++transpose ::+   (Extent.C vert, Extent.C horiz) =>+   Full vert horiz height width a -> Full horiz vert width height a+transpose = ArrMatrix.lift1 Basic.transpose++{- |+conjugate transpose++Problem: @adjoint a \<\> a@ is always square,+but how to convince the type checker to choose the Square type?+Anser: Use @Hermitian.toSquare $ Hermitian.gramian a@ instead.+-}+adjoint ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>+   Full vert horiz height width a -> Full horiz vert width height a+adjoint = ArrMatrix.lift1 Basic.adjoint+++{- |+The number of rows must be maintained by the height mapping function.+-}+mapHeight ::+   (Shape.C heightA, Shape.C heightB,+    Extent.GeneralTallWide vert horiz,+    Extent.GeneralTallWide horiz vert) =>+   (heightA -> heightB) ->+   Full vert horiz heightA width a ->+   Full vert horiz heightB width a+mapHeight = ArrMatrix.lift1 . Plain.mapHeight++{- |+The number of columns must be maintained by the width mapping function.+-}+mapWidth ::+   (Shape.C widthA, Shape.C widthB,+    Extent.GeneralTallWide vert horiz,+    Extent.GeneralTallWide horiz vert) =>+   (widthA -> widthB) ->+   Full vert horiz height widthA a ->+   Full vert horiz height widthB a+mapWidth = ArrMatrix.lift1 . Plain.mapWidth+++singleRow :: Order -> Vector width a -> General () width a+singleRow order = ArrMatrix.lift0 . Basic.singleRow order++singleColumn :: Order -> Vector height a -> General height () a+singleColumn order = ArrMatrix.lift0 . Basic.singleColumn order++flattenRow :: General () width a -> Vector width a+flattenRow = Basic.flattenRow . ArrMatrix.toVector++flattenColumn :: General height () a -> Vector height a+flattenColumn = Basic.flattenColumn . ArrMatrix.toVector++liftRow ::+   Order ->+   (Vector height0 a -> Vector height1 b) ->+   General () height0 a -> General () height1 b+liftRow order = ArrMatrix.lift1 . Basic.liftRow order++liftColumn ::+   Order ->+   (Vector height0 a -> Vector height1 b) ->+   General height0 () a -> General height1 () b+liftColumn order = ArrMatrix.lift1 . Basic.liftColumn order++unliftRow ::+   Order ->+   (General () height0 a -> General () height1 b) ->+   Vector height0 a -> Vector height1 b+unliftRow order = Basic.unliftRow order .  ArrMatrix.unlift1++unliftColumn ::+   Order ->+   (General height0 () a -> General height1 () b) ->+   Vector height0 a -> Vector height1 b+unliftColumn order = Basic.unliftColumn order . ArrMatrix.unlift1+++fromRowsNonEmpty ::+   (Shape.C width, Eq width, Storable a) =>+   NonEmpty.T [] (Vector width a) -> General ShapeInt width a+fromRowsNonEmpty = ArrMatrix.lift0 . Plain.fromRowsNonEmpty++fromRowArray ::+   (Shape.C height, Shape.C width, Eq width, Storable a) =>+   width -> BoxedArray.Array height (Vector width a) -> General height width a+fromRowArray width = ArrMatrix.lift0 . Plain.fromRowArray width++-- ToDo: generalize to a new NonEmpty.Head class+fromRowsNonEmptyContainer ::+   (f ~ NonEmpty.T g, Container.C g,+    Shape.C width, Eq width, Storable a) =>+   f (Vector width a) -> General (Container.Shape f) width a+fromRowsNonEmptyContainer = ArrMatrix.lift0 . Plain.fromRowsNonEmptyContainer++fromRowContainer ::+   (Container.C f, Shape.C width, Eq width, Storable a) =>+   width -> f (Vector width a) -> General (Container.Shape f) width a+fromRowContainer width = ArrMatrix.lift0 . Plain.fromRowContainer width++fromRows ::+   (Shape.C width, Eq width, Storable a) =>+   width -> [Vector width a] -> General ShapeInt width a+fromRows width = ArrMatrix.lift0 . Plain.fromRows width+++fromColumnsNonEmpty ::+   (Shape.C height, Eq height, Storable a) =>+   NonEmpty.T [] (Vector height a) -> General height ShapeInt a+fromColumnsNonEmpty = ArrMatrix.lift0 . Plain.fromColumnsNonEmpty++fromColumnArray ::+   (Shape.C height, Eq height, Shape.C width, Storable a) =>+   height -> BoxedArray.Array width (Vector height a) -> General height width a+fromColumnArray height = ArrMatrix.lift0 . Plain.fromColumnArray height++fromColumnsNonEmptyContainer ::+   (f ~ NonEmpty.T g, Container.C g,+    Shape.C height, Eq height, Storable a) =>+   f (Vector height a) -> General height (Container.Shape f) a+fromColumnsNonEmptyContainer =+   ArrMatrix.lift0 . Plain.fromColumnsNonEmptyContainer++fromColumnContainer ::+   (Container.C f, Shape.C height, Eq height, Storable a) =>+   height -> f (Vector height a) -> General height (Container.Shape f) a+fromColumnContainer height = ArrMatrix.lift0 . Plain.fromColumnContainer height++fromColumns ::+   (Shape.C height, Eq height, Storable a) =>+   height -> [Vector height a] -> General height ShapeInt a+fromColumns height = ArrMatrix.lift0 . Plain.fromColumns height+++toRows ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> [Vector width a]+toRows = Plain.toRows . ArrMatrix.toVector++toColumns ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> [Vector height a]+toColumns = Plain.toColumns . ArrMatrix.toVector++toRowArray ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> BoxedArray.Array height (Vector width a)+toRowArray = Plain.toRowArray . ArrMatrix.toVector++toColumnArray ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> BoxedArray.Array width (Vector height a)+toColumnArray = Plain.toColumnArray . ArrMatrix.toVector++toRowContainer ::+   (Extent.C vert, Extent.C horiz,+    Container.C f, Shape.C width, Class.Floating a) =>+   Full vert horiz (Container.Shape f) width a -> f (Vector width a)+toRowContainer = Plain.toRowContainer . ArrMatrix.toVector++toColumnContainer ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Container.C f, Class.Floating a) =>+   Full vert horiz height (Container.Shape f) a -> f (Vector height a)+toColumnContainer = Plain.toColumnContainer . ArrMatrix.toVector++++{-+The parameter order is swapped with respect to 'takeRowArray'+but it is the order that is used most oftenly.+-}+takeRow ::+   (Extent.C vert, Extent.C horiz,+    Shape.Indexed height, Shape.C width, Shape.Index height ~ ix,+    Class.Floating a) =>+   Full vert horiz height width a -> ix -> Vector width a+takeRow = Plain.takeRow . ArrMatrix.toVector++takeColumn ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.Indexed width, Shape.Index width ~ ix,+    Class.Floating a) =>+   Full vert horiz height width a -> ix -> Vector height a+takeColumn = Plain.takeColumn . ArrMatrix.toVector+++takeTop ::+   (Extent.C vert, Shape.C height0, Shape.C height1, Shape.C width,+    Class.Floating a) =>+   Full vert Extent.Big (height0:+:height1) width a ->+   Full vert Extent.Big height0 width a+takeTop = ArrMatrix.lift1 Basic.takeTop++takeBottom ::+   (Extent.C vert, Shape.C height0, Shape.C height1, Shape.C width,+    Class.Floating a) =>+   Full vert Extent.Big (height0:+:height1) width a ->+   Full vert Extent.Big height1 width a+takeBottom = ArrMatrix.lift1 Basic.takeBottom++takeLeft ::+   (Extent.C vert, Shape.C height, Shape.C width0, Shape.C width1,+    Class.Floating a) =>+   Full Extent.Big vert height (width0:+:width1) a ->+   Full Extent.Big vert height width0 a+takeLeft = ArrMatrix.lift1 Basic.takeLeft++takeRight ::+   (Extent.C vert, Shape.C height, Shape.C width0, Shape.C width1,+    Class.Floating a) =>+   Full Extent.Big vert height (width0:+:width1) a ->+   Full Extent.Big vert height width1 a+takeRight = ArrMatrix.lift1 Basic.takeRight++takeRows, dropRows ::+   (Extent.C vert, Shape.C width, Class.Floating a) =>+   Int ->+   Full vert Extent.Big ShapeInt width a ->+   Full vert Extent.Big ShapeInt width a+takeRows = ArrMatrix.lift1 . Basic.takeRows+dropRows = ArrMatrix.lift1 . Basic.dropRows++takeColumns, dropColumns ::+   (Extent.C horiz, Shape.C height, Class.Floating a) =>+   Int ->+   Full Extent.Big horiz height ShapeInt a ->+   Full Extent.Big horiz height ShapeInt a+takeColumns = ArrMatrix.lift1 . Basic.takeColumns+dropColumns = ArrMatrix.lift1 . Basic.dropColumns+++{- |+Take a left-top aligned square or as much as possible of it.+The advantange of this function is that it maintains the matrix size relation,+e.g. Square remains Square, Tall remains Tall.+-}+takeEqually ::+   (Extent.C vert, Extent.C horiz, Class.Floating a) =>+   Int ->+   Full vert horiz ShapeInt ShapeInt a ->+   Full vert horiz ShapeInt ShapeInt a+takeEqually = ArrMatrix.lift1 . Plain.takeEqually++{- |+Drop the same number of top-most rows and left-most columns.+The advantange of this function is that it maintains the matrix size relation,+e.g. Square remains Square, Tall remains Tall.+-}+dropEqually ::+   (Extent.C vert, Extent.C horiz, Class.Floating a) =>+   Int ->+   Full vert horiz ShapeInt ShapeInt a ->+   Full vert horiz ShapeInt ShapeInt a+dropEqually = ArrMatrix.lift1 . Plain.dropEqually+++swapRows ::+   (Extent.C vert, Extent.C horiz,+    Shape.Indexed height, Shape.C width, Class.Floating a) =>+   Shape.Index height -> Shape.Index height ->+   Full vert horiz height width a -> Full vert horiz height width a+swapRows i j = ArrMatrix.lift1 $ Plain.swapRows i j++swapColumns ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.Indexed width, Class.Floating a) =>+   Shape.Index width -> Shape.Index width ->+   Full vert horiz height width a -> Full vert horiz height width a+swapColumns i j =  ArrMatrix.lift1 $ Plain.swapColumns i j+++reverseRows ::+   (Extent.C vert, Extent.C horiz, Shape.C width, Class.Floating a) =>+   Full vert horiz ShapeInt width a -> Full vert horiz ShapeInt width a+reverseRows = ArrMatrix.lift1 Plain.reverseRows++reverseColumns ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Class.Floating a) =>+   Full vert horiz height ShapeInt a -> Full vert horiz height ShapeInt a+reverseColumns = ArrMatrix.lift1 Plain.reverseColumns+++{- |+The function is optimized for blocks of consecutive rows.+For scattered rows in column major order+the function has quite ugly memory access patterns.+-}+takeRowArray ::+   (Shape.Indexed height, Shape.C width, Shape.C sh, Class.Floating a) =>+   BoxedArray.Array sh (Shape.Index height) ->+   General height width a -> General sh width a+takeRowArray = ArrMatrix.lift1 . Plain.takeRowArray++takeColumnArray ::+   (Shape.C height, Shape.Indexed width, Shape.C sh, Class.Floating a) =>+   BoxedArray.Array sh (Shape.Index width) ->+   General height width a -> General height sh a+takeColumnArray = ArrMatrix.lift1 . Plain.takeColumnArray++++fromRowMajor ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   Array (height,width) a -> General height width a+fromRowMajor = ArrMatrix.lift0 . Plain.fromRowMajor++toRowMajor ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> Array (height,width) a+toRowMajor = Plain.toRowMajor . ArrMatrix.toVector+++infixr 3 |||+infixr 2 ===++(|||) ::+   (Extent.C vertA, Extent.C vertB, Extent.C vertC,+    Extent.Append vertA vertB ~ vertC,+    Shape.C height, Eq height, Shape.C widthA, Shape.C widthB,+    Class.Floating a) =>+   Full vertA Extent.Big height widthA a ->+   Full vertB Extent.Big height widthB a ->+   Full vertC Extent.Big height (widthA:+:widthB) a+(|||) = beside rightBias Extent.appendAny++(===) ::+   (Extent.C horizA, Extent.C horizB, Extent.C horizC,+    Extent.Append horizA horizB ~ horizC,+    Shape.C width, Eq width, Shape.C heightA, Shape.C heightB,+    Class.Floating a) =>+   Full Extent.Big horizA heightA width a ->+   Full Extent.Big horizB heightB width a ->+   Full Extent.Big horizC (heightA:+:heightB) width a+(===) = above rightBias Extent.appendAny++beside ::+   (Extent.C vertA, Extent.C vertB, Extent.C vertC,+    Shape.C height, Eq height, Shape.C widthA, Shape.C widthB,+    Class.Floating a) =>+   Basic.OrderBias ->+   Extent.AppendMode vertA vertB vertC height widthA widthB ->+   Full vertA Extent.Big height widthA a ->+   Full vertB Extent.Big height widthB a ->+   Full vertC Extent.Big height (widthA:+:widthB) a+beside orderBias = ArrMatrix.lift2 . Basic.beside orderBias++above ::+   (Extent.C horizA, Extent.C horizB, Extent.C horizC,+    Shape.C width, Eq width, Shape.C heightA, Shape.C heightB,+    Class.Floating a) =>+   Basic.OrderBias ->+   Extent.AppendMode horizA horizB horizC width heightA heightB ->+   Full Extent.Big horizA heightA width a ->+   Full Extent.Big horizB heightB width a ->+   Full Extent.Big horizC (heightA:+:heightB) width a+above orderBias = ArrMatrix.lift2 . Basic.above orderBias++{- |+Use the element order of the first operand.+-}+leftBias :: Basic.OrderBias+leftBias = Basic.LeftBias++{- |+Use the element order of the second operand.+-}+rightBias :: Basic.OrderBias+rightBias = Basic.RightBias++{- |+Choose element order such that, if possible,+one part can be copied as one block.+For 'above' this means that 'RowMajor' is chosen+whenever at least one operand is 'RowMajor'+and 'ColumnMajor' is chosen when both operands are 'ColumnMajor'.+-}+contiguousBias :: Basic.OrderBias+contiguousBias = Basic.ContiguousBias+++rowSums ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> Vector height a+rowSums = Plain.rowSums . ArrMatrix.toVector++columnSums ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> Vector width a+columnSums = Plain.columnSums . ArrMatrix.toVector+++rowArgAbsMaximums ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.InvIndexed width, Shape.Index width ~ ix, Storable ix,+    Class.Floating a) =>+   Full vert horiz height width a -> (Vector height ix, Vector height a)+rowArgAbsMaximums = Plain.rowArgAbsMaximums . ArrMatrix.toVector++columnArgAbsMaximums ::+   (Extent.C vert, Extent.C horiz,+    Shape.InvIndexed height, Shape.C width,+    Shape.Index height ~ ix, Storable ix,+    Class.Floating a) =>+   Full vert horiz height width a -> (Vector width ix, Vector width a)+columnArgAbsMaximums = Plain.columnArgAbsMaximums . ArrMatrix.toVector+++map ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Storable a, Storable b) =>+   (a -> b) ->+   Full vert horiz height width a -> Full vert horiz height width b+map = ArrMatrix.lift1 . Array.map+++infixl 7 |*-++(|*-) ::+   (Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+   Vector height a -> Vector width a -> General height width a+x|*-y = ArrMatrix.lift0 $ x Plain.|*- y++{- |+> tensorProduct order x y = singleColumn order x #*# singleRow order y+-}+tensorProduct ::+   (Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+   Order -> Vector height a -> Vector width a -> General height width a+tensorProduct order x y = ArrMatrix.lift0 $ Plain.tensorProduct order x y++{- |+> outer order x y = tensorProduct order x (Vector.conjugate y)+-}+outer ::+   (Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+   Order -> Vector height a -> Vector width a -> General height width a+outer order x y = ArrMatrix.lift0 $ Plain.outer order x y++kronecker ::+   (Extent.C vert, Extent.C horiz,+    Shape.C heightA, Shape.C widthA, Shape.C heightB, Shape.C widthB,+    Class.Floating a) =>+   Full vert horiz heightA widthA a ->+   Full vert horiz heightB widthB a ->+   Full vert horiz (heightA,heightB) (widthA,widthB) a+kronecker = ArrMatrix.lift2 Plain.kronecker++sumRank1 ::+   (Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+   (height,width) ->+   [(a, (Vector height a, Vector width a))] -> General height width a+sumRank1 dims = ArrMatrix.lift0 . Plain.sumRank1 dims+++infixl 7 #*\, #/\+infixr 7 \*#, \\#++scaleRows, (\*#) ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Class.Floating a) =>+   Vector height a ->+   Full vert horiz height width a ->+   Full vert horiz height width a+scaleRows = ArrMatrix.lift1 . Basic.scaleRows+(\*#) = scaleRows++scaleColumns ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Eq width, Class.Floating a) =>+   Vector width a ->+   Full vert horiz height width a ->+   Full vert horiz height width a+scaleColumns = ArrMatrix.lift1 . Basic.scaleColumns++(#*\) ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Eq width, Class.Floating a) =>+   Full vert horiz height width a ->+   Vector width a ->+   Full vert horiz height width a+(#*\) = flip scaleColumns++scaleRowsReal ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Eq height, Shape.C width,+    Class.Floating a) =>+   Vector height (RealOf a) ->+   Full vert horiz height width a ->+   Full vert horiz height width a+scaleRowsReal = ArrMatrix.lift1 . Basic.scaleRowsReal++scaleColumnsReal ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Eq width, Class.Floating a) =>+   Vector width (RealOf a) ->+   Full vert horiz height width a ->+   Full vert horiz height width a+scaleColumnsReal = ArrMatrix.lift1 . Basic.scaleColumnsReal++(\\#) ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Class.Floating a) =>+   Vector height a ->+   Full vert horiz height width a ->+   Full vert horiz height width a+(\\#) = scaleRows . Vector.recip++(#/\) ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Eq width, Class.Floating a) =>+   Full vert horiz height width a ->+   Vector width a ->+   Full vert horiz height width a+(#/\) a x = scaleColumns (Vector.recip x) a+++multiplySquare ::+   (Multiply.MultiplySquare typ,+    Type.HeightOf typ ~ height, Eq height, Shape.C width,+    Extent.C horiz, Extent.C vert, Class.Floating a) =>+   Mod.Transposition -> Type.Matrix typ a ->+   Full vert horiz height width a -> Full vert horiz height width a+multiplySquare = Multiply.transposableSquare++multiplyVector ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width, Eq width,+    Class.Floating a) =>+   Full vert horiz height width a -> Vector width a -> Vector height a+multiplyVector = Basic.multiplyVector . ArrMatrix.toVector++multiply ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height,+    Shape.C fuse, Eq fuse,+    Shape.C width,+    Class.Floating a) =>+   Full vert horiz height fuse a ->+   Full vert horiz fuse width a ->+   Full vert horiz height width a+multiply = ArrMatrix.lift2 Basic.multiply
+ src/Numeric/LAPACK/Matrix/Array.hs view
@@ -0,0 +1,237 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE EmptyDataDecls #-}+module Numeric.LAPACK.Matrix.Array (+   Matrix(Array),+   ArrayMatrix,+   Array,++   Full,+   General,+   Tall,+   Wide,+   Square,++   shape,+   reshape,+   mapShape,+   toVector,+   fromVector,+   lift0,+   lift1,+   lift2,+   lift3,+   lift4,+   unlift1,+   unlift2,+   unliftRow,+   unliftColumn,++   Plain.Homogeneous, zero, negate, scaleReal, scale, scaleRealReal, (.*#),+   Plain.ShapeOrder, forceOrder, Plain.shapeOrder, adaptOrder,+   Plain.Additive, add, sub, (#+#), (#-#),+   Plain.Complex,+   Plain.SquareShape,+   Multiply.MultiplyVector,+   Multiply.MultiplySquare,+   Multiply.Power,+   Multiply.Multiply,+   Divide.Determinant,+   Divide.Solve,+   Divide.Inverse,+   ) where++import qualified Numeric.LAPACK.Matrix.Plain.Divide as Divide+import qualified Numeric.LAPACK.Matrix.Plain.Multiply as Multiply+import qualified Numeric.LAPACK.Matrix.Plain.Class as Plain+import qualified Numeric.LAPACK.Matrix.Type as Type+import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Shape.Box as Box+import qualified Numeric.LAPACK.Matrix.Basic as Basic+import Numeric.LAPACK.Matrix.Plain.Format (FormatArray, formatArray)+import Numeric.LAPACK.Matrix.Type (Matrix)+import Numeric.LAPACK.Vector (Vector)+import Numeric.LAPACK.Scalar (RealOf)++import qualified Numeric.Netlib.Class as Class++import qualified Control.DeepSeq as DeepSeq++import qualified Data.Array.Comfort.Storable.Unchecked as Array+import qualified Data.Array.Comfort.Storable as CheckedArray+import qualified Data.Array.Comfort.Shape as Shape++import Prelude hiding (negate)+++data Array shape+newtype instance Matrix (Array shape) a = Array (Array.Array shape a)+   deriving (Show)++type ArrayMatrix shape = Matrix (Array shape)+++type Full vert horiz height width =+         ArrayMatrix (MatrixShape.Full vert horiz height width)+type General height width = ArrayMatrix (MatrixShape.General height width)+type Tall height width = ArrayMatrix (MatrixShape.Tall height width)+type Wide height width = ArrayMatrix (MatrixShape.Wide height width)+type Square sh = ArrayMatrix (MatrixShape.Square sh)+++instance (DeepSeq.NFData shape) => Type.NFData (Array shape) where+   rnf (Array arr) = DeepSeq.rnf arr++instance (Box.Box sh) => Type.Box (Array sh) where+   type HeightOf (Array sh) = Box.HeightOf sh+   type WidthOf (Array sh) = Box.WidthOf sh+   height (Array arr) = Box.height $ Array.shape arr+   width (Array arr) = Box.width $ Array.shape arr+++shape :: ArrayMatrix sh a -> sh+shape (Array a) = Array.shape a++reshape ::+   (Shape.C sh0, Shape.C sh1) =>+   sh1 -> ArrayMatrix sh0 a -> ArrayMatrix sh1 a+reshape = lift1 . CheckedArray.reshape++mapShape ::+   (Shape.C sh0, Shape.C sh1) =>+   (sh0 -> sh1) -> ArrayMatrix sh0 a -> ArrayMatrix sh1 a+mapShape = lift1 . CheckedArray.mapShape+++toVector :: ArrayMatrix sh a -> Array.Array sh a+toVector (Array a) = a++fromVector ::+   (Plain.Admissible sh, Class.Floating a) =>+   Array.Array sh a -> ArrayMatrix sh a+fromVector arr =+   Array $+   case Plain.check arr of+      Nothing -> arr+      Just msg -> error $ "Matrix.Array.fromVector: " ++ msg++{- |+'lift0' is a synonym for 'fromVector' but lacks the admissibility check.+You may thus fool the type tags.+This applies to the other lift functions, too.+-}+lift0 :: Array.Array shA a -> ArrayMatrix shA a+lift0 = Array++lift1 ::+   (Array.Array shA a -> Array.Array shB b) ->+   ArrayMatrix shA a -> ArrayMatrix shB b+lift1 f (Array a) = Array $ f a++lift2 ::+   (Array.Array shA a -> Array.Array shB b -> Array.Array shC c) ->+   ArrayMatrix shA a -> ArrayMatrix shB b -> ArrayMatrix shC c+lift2 f (Array a) (Array b) = Array $ f a b++lift3 ::+   (Array.Array shA a -> Array.Array shB b ->+    Array.Array shC c -> Array.Array shD d) ->+   ArrayMatrix shA a -> ArrayMatrix shB b ->+   ArrayMatrix shC c -> ArrayMatrix shD d+lift3 f (Array a) (Array b) (Array c) = Array $ f a b c++lift4 ::+   (Array.Array shA a -> Array.Array shB b ->+    Array.Array shC c -> Array.Array shD d ->+    Array.Array shE e) ->+   ArrayMatrix shA a -> ArrayMatrix shB b ->+   ArrayMatrix shC c -> ArrayMatrix shD d ->+   ArrayMatrix shE e+lift4 f (Array a) (Array b) (Array c) (Array d) = Array $ f a b c d+++unlift1 ::+   (ArrayMatrix shA a -> ArrayMatrix shB b) ->+   Array.Array shA a -> Array.Array shB b+unlift1 f a = toVector $ f $ Array a++unlift2 ::+   (ArrayMatrix shA a -> ArrayMatrix shB b -> ArrayMatrix shC c) ->+   Array.Array shA a -> Array.Array shB b -> Array.Array shC c+unlift2 f a b = toVector $ f (Array a) (Array b)+++unliftRow ::+   MatrixShape.Order ->+   (General () height0 a -> General () height1 b) ->+   Vector height0 a -> Vector height1 b+unliftRow order = Basic.unliftRow order . unlift1++unliftColumn ::+   MatrixShape.Order ->+   (General height0 () a -> General height1 () b) ->+   Vector height0 a -> Vector height1 b+unliftColumn order = Basic.unliftColumn order . unlift1+++instance (FormatArray sh) => Type.FormatMatrix (Array sh) where+   formatMatrix fmt (Array a) = formatArray fmt a++instance (Multiply.MultiplySame sh) => Type.MultiplySame (Array sh) where+   multiplySame = lift2 Multiply.same+++zero ::+   (Plain.Homogeneous shape, Class.Floating a) => shape -> ArrayMatrix shape a+zero = lift0 . Plain.zero++negate ::+   (Plain.Homogeneous shape, Class.Floating a) =>+   ArrayMatrix shape a -> ArrayMatrix shape a+negate = lift1 Plain.negate++scaleReal ::+   (Plain.Homogeneous shape, Class.Floating a) =>+   RealOf a -> ArrayMatrix shape a -> ArrayMatrix shape a+scaleReal = lift1 . Plain.scaleReal++newtype ScaleReal f a = ScaleReal {getScaleReal :: a -> f a -> f a}++scaleRealReal ::+   (Plain.Homogeneous shape, Class.Real a) =>+   a -> ArrayMatrix shape a -> ArrayMatrix shape a+scaleRealReal =+   getScaleReal $ Class.switchReal (ScaleReal scaleReal) (ScaleReal scaleReal)+++scale, (.*#) ::+   (Multiply.Scale shape, Class.Floating a) =>+   a -> ArrayMatrix shape a -> ArrayMatrix shape a+scale = lift1 . Multiply.scale+(.*#) = scale++infixl 7 .*#+++forceOrder ::+   (Plain.ShapeOrder shape, Class.Floating a) =>+   MatrixShape.Order -> ArrayMatrix shape a -> ArrayMatrix shape a+forceOrder = lift1 . Plain.forceOrder++{- |+@adaptOrder x y@ contains the data of @y@ with the layout of @x@.+-}+adaptOrder ::+   (Plain.ShapeOrder shape, Class.Floating a) =>+   ArrayMatrix shape a -> ArrayMatrix shape a -> ArrayMatrix shape a+adaptOrder = lift2 Plain.adaptOrder+++infixl 6 #+#, #-#, `add`, `sub`++add, sub, (#+#), (#-#) ::+   (Plain.Additive shape, Class.Floating a) =>+   ArrayMatrix shape a -> ArrayMatrix shape a -> ArrayMatrix shape a+add = lift2 Plain.add+sub = lift2 Plain.sub+(#+#) = add+(#-#) = sub
+ src/Numeric/LAPACK/Matrix/Array/Banded.hs view
@@ -0,0 +1,24 @@+module Numeric.LAPACK.Matrix.Array.Banded where++import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import Numeric.LAPACK.Matrix.Array (ArrayMatrix)++import qualified Type.Data.Num.Unary.Literal as TypeNum+++type Banded sub super vert horiz height width =+      ArrayMatrix (MatrixShape.Banded sub super vert horiz height width)++type General sub super height width =+      ArrayMatrix (MatrixShape.BandedGeneral sub super height width)++type Square sub super size =+      ArrayMatrix (MatrixShape.BandedSquare sub super size)++type Lower sub size = Square sub TypeNum.U0 size+type Upper super size = Square TypeNum.U0 super size++type Diagonal size = Square TypeNum.U0 TypeNum.U0 size++type Hermitian offDiag sh =+         ArrayMatrix (MatrixShape.BandedHermitian offDiag sh)
+ src/Numeric/LAPACK/Matrix/Array/Basic.hs view
@@ -0,0 +1,22 @@+module Numeric.LAPACK.Matrix.Array.Basic where++import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Basic as Basic+import qualified Numeric.LAPACK.Matrix.Extent as Extent+import Numeric.LAPACK.Matrix.Array (Full)+++transpose ::+   (Extent.C vert, Extent.C horiz) =>+   Full vert horiz height width a -> Full horiz vert width height a+transpose = ArrMatrix.lift1 Basic.transpose++swapMultiply ::+   (Extent.C vertA, Extent.C vertB, Extent.C horizA, Extent.C horizB) =>+   (matrix ->+    Full horizA vertA widthA heightA a ->+    Full horizB vertB widthB heightB a) ->+   Full vertA horizA heightA widthA a ->+   matrix ->+   Full vertB horizB heightB widthB a+swapMultiply multiplyTrans a b = transpose $ multiplyTrans b $ transpose a
+ src/Numeric/LAPACK/Matrix/Array/Triangular.hs view
@@ -0,0 +1,26 @@+module Numeric.LAPACK.Matrix.Array.Triangular where++import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import Numeric.LAPACK.Matrix.Array (ArrayMatrix)+import Numeric.LAPACK.Matrix.Shape.Private (NonUnit, Unit)+++type Hermitian sh = ArrayMatrix (MatrixShape.Hermitian sh)++type Lower sh = FlexLower NonUnit sh+type Upper sh = FlexUpper NonUnit sh+type Symmetric sh = FlexSymmetric NonUnit sh+type Diagonal sh = FlexDiagonal NonUnit sh++type UnitLower sh = FlexLower Unit sh+type UnitUpper sh = FlexUpper Unit sh++type FlexDiagonal diag sh =+      ArrayMatrix+         (MatrixShape.Triangular MatrixShape.Empty diag MatrixShape.Empty sh)+type FlexLower diag sh = ArrayMatrix (MatrixShape.LowerTriangular diag sh)+type FlexUpper diag sh = ArrayMatrix (MatrixShape.UpperTriangular diag sh)+type FlexSymmetric diag sh = ArrayMatrix (MatrixShape.FlexSymmetric diag sh)++type Triangular lo diag up sh =+         ArrayMatrix (MatrixShape.Triangular lo diag up sh)
src/Numeric/LAPACK/Matrix/Banded.hs view
@@ -1,28 +1,184 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} module Numeric.LAPACK.Matrix.Banded (-   module Numeric.LAPACK.Matrix.Banded.Basic,+   Banded,+   General,+   Square,+   Upper,+   Lower,+   Diagonal,+   Hermitian,    height, width,+   fromList,+   squareFromList,+   lowerFromList,+   upperFromList,+   mapExtent,+   diagonal,+   takeDiagonal,+   toFull,+   toLowerTriangular,+   toUpperTriangular,+   transpose,+   adjoint,+   multiplyVector,+   multiply,+   multiplyFull,     solve,    determinant,    ) where -import Numeric.LAPACK.Matrix.Banded.Basic-import Numeric.LAPACK.Matrix.Banded.Linear+import qualified Numeric.LAPACK.Matrix.Banded.Linear as Linear+import qualified Numeric.LAPACK.Matrix.Banded.Basic as Basic +import qualified Numeric.LAPACK.Matrix.Array.Triangular as Tri+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import Numeric.LAPACK.Matrix.Array.Banded+         (Banded, General, Square, Lower, Upper, Diagonal, Hermitian)+import Numeric.LAPACK.Matrix.Array (Full)+import Numeric.LAPACK.Matrix.Shape.Private (Order, UnaryProxy)+import Numeric.LAPACK.Vector (Vector) -import qualified Data.Array.Comfort.Storable as Array+import qualified Numeric.Netlib.Class as Class +import qualified Type.Data.Num.Unary as Unary+import Type.Data.Num.Unary ((:+:)) +import qualified Data.Array.Comfort.Shape as Shape++import Foreign.Storable (Storable)++ height ::    (Extent.C vert, Extent.C horiz) =>    Banded sub super vert horiz height width a -> height-height = MatrixShape.bandedHeight . Array.shape+height = MatrixShape.bandedHeight . ArrMatrix.shape  width ::    (Extent.C vert, Extent.C horiz) =>    Banded sub super vert horiz height width a -> width-width = MatrixShape.bandedWidth . Array.shape+width = MatrixShape.bandedWidth . ArrMatrix.shape++++fromList ::+   (Unary.Natural sub, Unary.Natural super,+    Shape.C height, Shape.C width, Storable a) =>+   (UnaryProxy sub, UnaryProxy super) -> Order -> height -> width -> [a] ->+   General sub super height width a+fromList offDiag order height_ width_ =+   ArrMatrix.lift0 . Basic.fromList offDiag order height_ width_++squareFromList ::+   (Unary.Natural sub, Unary.Natural super, Shape.C size, Storable a) =>+   (UnaryProxy sub, UnaryProxy super) -> Order -> size -> [a] ->+   Square sub super size a+squareFromList offDiag order size =+   ArrMatrix.lift0 . Basic.squareFromList offDiag order size++lowerFromList ::+   (Unary.Natural sub, Shape.C size, Storable a) =>+   UnaryProxy sub -> Order -> size -> [a] -> Lower sub size a+lowerFromList numOff order size =+   ArrMatrix.lift0 . Basic.lowerFromList numOff order size++upperFromList ::+   (Unary.Natural super, Shape.C size, Storable a) =>+   UnaryProxy super -> Order -> size -> [a] -> Upper super size a+upperFromList numOff order size =+   ArrMatrix.lift0 . Basic.upperFromList numOff order size++mapExtent ::+   (Extent.C vertA, Extent.C horizA) =>+   (Extent.C vertB, Extent.C horizB) =>+   Extent.Map vertA horizA vertB horizB height width ->+   Banded super sub vertA horizA height width a ->+   Banded super sub vertB horizB height width a+mapExtent = ArrMatrix.lift1 . Basic.mapExtent++transpose ::+   (Extent.C vert, Extent.C horiz) =>+   Banded sub super vert horiz height width a ->+   Banded super sub horiz vert width height a+transpose = ArrMatrix.lift1 Basic.transpose++adjoint ::+   (Unary.Natural sub, Unary.Natural super, Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Banded sub super vert horiz height width a ->+   Banded super sub horiz vert width height a+adjoint = ArrMatrix.lift1 Basic.adjoint++diagonal ::+   (Shape.C sh, Class.Floating a) => Order -> Vector sh a -> Diagonal sh a+diagonal order = ArrMatrix.lift0 . Basic.diagonal order++takeDiagonal ::+   (Unary.Natural sub, Unary.Natural super, Shape.C sh, Class.Floating a) =>+   Square sub super sh a -> Vector sh a+takeDiagonal = Basic.takeDiagonal . ArrMatrix.toVector++multiplyVector ::+   (Unary.Natural sub, Unary.Natural super,+    Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width, Eq width,+    Class.Floating a) =>+   Banded sub super vert horiz height width a ->+   Vector width a -> Vector height a+multiplyVector = Basic.multiplyVector . ArrMatrix.toVector++multiply ::+   (Unary.Natural subA, Unary.Natural superA,+    Unary.Natural subB, Unary.Natural superB,+    (subA :+: subB) ~ subC,+    (superA :+: superB) ~ superC,+    Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Shape.C fuse, Eq fuse,+    Class.Floating a) =>+   Banded subA superA vert horiz height fuse a ->+   Banded subB superB vert horiz fuse width a ->+   Banded subC superC vert horiz height width a+multiply = ArrMatrix.lift2 Basic.multiply++multiplyFull ::+   (Unary.Natural sub, Unary.Natural super,+    Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Shape.C fuse, Eq fuse,+    Class.Floating a) =>+   Banded sub super vert horiz height fuse a ->+   Full vert horiz fuse width a -> Full vert horiz height width a+multiplyFull = ArrMatrix.lift2 Basic.multiplyFull++toLowerTriangular ::+   (Unary.Natural sub, Shape.C sh, Class.Floating a) =>+   Lower sub sh a -> Tri.Lower sh a+toLowerTriangular = ArrMatrix.lift1 Basic.toLowerTriangular++toUpperTriangular ::+   (Unary.Natural super, Shape.C sh, Class.Floating a) =>+   Upper super sh a -> Tri.Upper sh a+toUpperTriangular = ArrMatrix.lift1 Basic.toUpperTriangular++toFull ::+   (Unary.Natural sub, Unary.Natural super,+    Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>+   Banded sub super vert horiz height width a ->+   Full vert horiz height width a+toFull = ArrMatrix.lift1 Basic.toFull++++solve ::+   (Unary.Natural sub, Unary.Natural super, Extent.C vert, Extent.C horiz,+    Shape.C sh, Eq sh, Shape.C nrhs, Class.Floating a) =>+   Square sub super sh a ->+   Full vert horiz sh nrhs a -> Full vert horiz sh nrhs a+solve = ArrMatrix.lift2 Linear.solve++determinant ::+   (Unary.Natural sub, Unary.Natural super, Shape.C sh, Class.Floating a) =>+   Square sub super sh a -> a+determinant = Linear.determinant . ArrMatrix.toVector
src/Numeric/LAPACK/Matrix/Banded/Basic.hs view
@@ -12,7 +12,11 @@    lowerFromList,    upperFromList,    mapExtent,+   mapHeight,+   mapWidth,+   identityFatOrder,    diagonal,+   fromDiagonal,    takeDiagonal,    toFull,    toLowerTriangular,@@ -28,12 +32,15 @@ import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent import qualified Numeric.LAPACK.Matrix.Triangular.Private as TriangularPriv import qualified Numeric.LAPACK.Matrix.Triangular.Basic as Triangular+import qualified Numeric.LAPACK.Matrix.RowMajor as RowMajor import qualified Numeric.LAPACK.Matrix.Private as Matrix import qualified Numeric.LAPACK.Vector as Vector import qualified Numeric.LAPACK.Private as Private+import qualified Numeric.LAPACK.ShapeStatic as ShapeStatic import Numeric.LAPACK.Matrix.Shape.Private          (Order(RowMajor,ColumnMajor), transposeFromOrder, swapOnRowMajor,           UnaryProxy, addOffDiagonals)+import Numeric.LAPACK.Matrix.Modifier (Conjugation(NonConjugated)) import Numeric.LAPACK.Vector (Vector) import Numeric.LAPACK.Scalar (zero, one) import Numeric.LAPACK.Private@@ -132,6 +139,28 @@    Banded super sub vertB horizB height width a mapExtent f = Array.mapShape $ MatrixShape.bandedMapExtent f +mapHeight ::+   (Extent.GeneralTallWide vert horiz,+    Extent.GeneralTallWide horiz vert) =>+   (heightA -> heightB) ->+   Banded super sub vert horiz heightA width a ->+   Banded super sub vert horiz heightB width a+mapHeight f =+   Array.mapShape+      (\(MatrixShape.Banded offDiag order extent) ->+         MatrixShape.Banded offDiag order $ Extent.mapHeight f extent)++mapWidth ::+   (Extent.GeneralTallWide vert horiz,+    Extent.GeneralTallWide horiz vert) =>+   (widthA -> widthB) ->+   Banded super sub vert horiz height widthA a ->+   Banded super sub vert horiz height widthB a+mapWidth f =+   Array.mapShape+      (\(MatrixShape.Banded offDiag order extent) ->+         MatrixShape.Banded offDiag order $ Extent.mapWidth f extent)+ transpose ::    (Extent.C vert, Extent.C horiz) =>    Banded sub super vert horiz height width a ->@@ -139,16 +168,67 @@ transpose = Array.mapShape MatrixShape.bandedTranspose  adjoint ::-   (Unary.Natural super, Unary.Natural sub, Extent.C vert, Extent.C horiz,-    Shape.C width, Shape.C height, Class.Floating a) =>+   (Unary.Natural sub, Unary.Natural super, Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>    Banded sub super vert horiz height width a ->    Banded super sub horiz vert width height a adjoint = Vector.conjugate . transpose  -diagonal :: (Shape.C sh, Class.Floating a) => Vector sh a -> Diagonal sh a-diagonal (Array sh x) =-   Array (MatrixShape.bandedSquare (Proxy,Proxy) ColumnMajor sh) x+identityFatOrder ::+   (Unary.Natural sub, Unary.Natural super, Shape.C size, Class.Floating a) =>+   Order -> size -> Square sub super size a+identityFatOrder order =+   case order of+      RowMajor -> fromRowMajor Extent.square . identityStripe+      ColumnMajor -> fromColumnMajor Extent.square . identityStripe++type Section sub super =+      ShapeStatic.ZeroBased sub Shape.:+: ()+         Shape.:+: ShapeStatic.ZeroBased super++identityStripe ::+   (Unary.Natural sub, Unary.Natural super, Shape.C height, Class.Floating a) =>+   height -> RowMajor.Matrix height (Section sub super) a+identityStripe sh =+   RowMajor.tensorProduct (Left NonConjugated)+      (Vector.one sh) (Vector.unit Shape.static $ Right (Left ()))++fromRowMajor ::+   (Unary.Natural sub, Unary.Natural super, Shape.C height) =>+   (height -> Extent.Extent vert horiz height width) ->+   RowMajor.Matrix height (Section sub super) a ->+   Banded sub super vert horiz height width a+fromRowMajor extent =+   Array.mapShape+      (\(size,+         ShapeStatic.ZeroBased kl Shape.:+: ()+            Shape.:+: ShapeStatic.ZeroBased ku) ->+         MatrixShape.Banded (kl,ku) RowMajor $ extent size)++fromColumnMajor ::+   (Unary.Natural sub, Unary.Natural super, Shape.C width) =>+   (width -> Extent.Extent vert horiz height width) ->+   RowMajor.Matrix width (Section super sub) a ->+   Banded sub super vert horiz height width a+fromColumnMajor extent =+   Array.mapShape+      (\(size,+         ShapeStatic.ZeroBased ku Shape.:+: ()+            Shape.:+: ShapeStatic.ZeroBased kl) ->+         MatrixShape.Banded (kl,ku) ColumnMajor $ extent size)+++diagonal ::+   (Shape.C sh, Class.Floating a) => Order -> Vector sh a -> Diagonal sh a+diagonal order (Array sh x) =+   Array (MatrixShape.bandedSquare (Proxy,Proxy) order sh) x++fromDiagonal ::+   (Shape.C sh, Class.Floating a) =>+   TriangularPriv.FlexDiagonal diag sh a -> Diagonal sh a+fromDiagonal (Array (MatrixShape.Triangular _diag _uplo order sh) x) =+   Array (MatrixShape.bandedSquare (Proxy,Proxy) order sh) x  takeDiagonal ::    (Unary.Natural sub, Unary.Natural super, Shape.C sh, Class.Floating a) =>
src/Numeric/LAPACK/Matrix/Banded/Linear.hs view
@@ -8,7 +8,7 @@ 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 qualified Numeric.LAPACK.Split as Split+import qualified Numeric.LAPACK.Permutation.Private as Perm import qualified Numeric.LAPACK.Private as Private import Numeric.LAPACK.Linear.Private (solver, withDeterminantInfo, withInfo) import Numeric.LAPACK.Matrix.Shape.Private@@ -112,4 +112,4 @@             (do                det <- Private.product n (advancePtr abPtr (kl+ku)) ldab                ipiv <- peekArray n ipivPtr-               return $ if Split.oddPermutation ipiv then -det else det)+               return $ Perm.condNegate ipiv det)
src/Numeric/LAPACK/Matrix/BandedHermitian.hs view
@@ -1,34 +1,131 @@ {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} module Numeric.LAPACK.Matrix.BandedHermitian (-   module Numeric.LAPACK.Matrix.BandedHermitian.Basic,+   BandedHermitian,+   Transposition(..),+   size,+   fromList,+   identity,+   diagonal,+   takeDiagonal,+   toHermitian,+   toBanded,+   multiplyVector,+   multiplyFull,+   gramian,+   sumRank1,     eigenvalues,    eigensystem,    ) where  import qualified Numeric.LAPACK.Matrix.BandedHermitian.Eigen as Eigen-import Numeric.LAPACK.Matrix.BandedHermitian.Basic+import qualified Numeric.LAPACK.Matrix.BandedHermitian.Basic as Basic -import qualified Numeric.LAPACK.Matrix.Private as Matrix+import qualified Numeric.LAPACK.Matrix.Array.Banded as Banded+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Extent as Extent+import Numeric.LAPACK.Matrix.Array.Banded (Square)+import Numeric.LAPACK.Matrix.Array.Triangular (Hermitian)+import Numeric.LAPACK.Matrix.Array (Full)+import Numeric.LAPACK.Matrix.Shape.Private (Order, UnaryProxy)+import Numeric.LAPACK.Matrix.Modifier (Transposition(NonTransposed, Transposed)) import Numeric.LAPACK.Vector (Vector) import Numeric.LAPACK.Scalar (RealOf)  import qualified Numeric.Netlib.Class as Class +import qualified Type.Data.Num.Unary.Literal as TypeNum import qualified Type.Data.Num.Unary as Unary+import Type.Data.Num.Unary ((:+:))  import qualified Data.Array.Comfort.Shape as Shape +import Foreign.Storable (Storable) +import Data.Tuple.HT (mapFst)+++type BandedHermitian offDiag sh = Banded.Hermitian offDiag sh+type Diagonal size = BandedHermitian TypeNum.U0 size+++size :: BandedHermitian offDiag sh a -> sh+size = MatrixShape.bandedHermitianSize . ArrMatrix.shape+++fromList ::+   (Unary.Natural offDiag, Shape.C size, Storable a) =>+   UnaryProxy offDiag -> Order -> size -> [a] ->+   BandedHermitian offDiag size a+fromList numOff order size_ =+   ArrMatrix.lift0 . Basic.fromList numOff order size_++identity :: (Shape.C sh, Class.Floating a) => sh -> Diagonal sh a+identity = ArrMatrix.lift0 . Basic.identity++diagonal ::+   (Shape.C sh, Class.Floating a) => Vector sh (RealOf a) -> Diagonal sh a+diagonal = ArrMatrix.lift0 . Basic.diagonal++takeDiagonal ::+   (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>+   BandedHermitian offDiag size a -> Vector size (RealOf a)+takeDiagonal = Basic.takeDiagonal . ArrMatrix.toVector++toHermitian ::+   (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>+   BandedHermitian offDiag size a -> Hermitian size a+toHermitian = ArrMatrix.lift1 Basic.toHermitian++toBanded ::+   (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>+   BandedHermitian offDiag size a ->+   Square offDiag offDiag size a+toBanded = ArrMatrix.lift1 Basic.toBanded++multiplyVector ::+   (Unary.Natural offDiag, Shape.C size, Eq size, Class.Floating a) =>+   Transposition -> BandedHermitian offDiag size a ->+   Vector size a -> Vector size a+multiplyVector transposed = Basic.multiplyVector transposed .  ArrMatrix.toVector++gramian ::+   (Shape.C size, Eq size, Class.Floating a,+    Unary.Natural sub, Unary.Natural super) =>+   Square sub super size a ->+   BandedHermitian (sub :+: super) size a+gramian = ArrMatrix.lift1 Basic.gramian++multiplyFull ::+   (Unary.Natural offDiag, Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Class.Floating a) =>+   Transposition -> BandedHermitian offDiag height a ->+   Full vert horiz height width a ->+   Full vert horiz height width a+multiplyFull = ArrMatrix.lift2 . Basic.multiplyFull++{- |+The list represents ragged rows of a sparse matrix.+-}+sumRank1 ::+   (Unary.Natural k, Shape.Indexed sh, Class.Floating a) =>+   Order -> sh ->+   [(RealOf a, (Shape.Index sh, Basic.StaticVector (Unary.Succ k) a))] ->+   BandedHermitian k sh a+sumRank1 order sh = ArrMatrix.lift0 . Basic.sumRank1 order sh++ eigenvalues ::    (Unary.Natural offDiag, Shape.C sh, Class.Floating a) =>    BandedHermitian offDiag sh a -> Vector sh (RealOf a)-eigenvalues = Eigen.values+eigenvalues = Eigen.values . ArrMatrix.toVector  {- | For symmetric eigenvalue problems, @eigensystem@ and @schur@ coincide. -} eigensystem ::    (Unary.Natural offDiag, Shape.C sh, Class.Floating a) =>-   BandedHermitian offDiag sh a -> (Matrix.Square sh a, Vector sh (RealOf a))-eigensystem = Eigen.decompose+   BandedHermitian offDiag sh a -> (ArrMatrix.Square sh a, Vector sh (RealOf a))+eigensystem = mapFst ArrMatrix.lift0 . Eigen.decompose . ArrMatrix.toVector
src/Numeric/LAPACK/Matrix/BandedHermitian/Basic.hs view
@@ -3,37 +3,44 @@ {-# LANGUAGE GADTs #-} module Numeric.LAPACK.Matrix.BandedHermitian.Basic (    BandedHermitian,+   StaticVector,    Transposition(..),    fromList,    identity,+   identityFatOrder,    diagonal,    takeDiagonal,    toHermitian,    toBanded,    multiplyVector,    multiplyFull,-   covariance,+   gramian,    sumRank1,+   takeUpper,    ) where -import qualified Numeric.LAPACK.ShapeStatic as ShapeStatic import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape import qualified Numeric.LAPACK.Matrix.Extent as Extent import qualified Numeric.LAPACK.Matrix.Banded.Basic as Banded import qualified Numeric.LAPACK.Matrix.Triangular.Private as TriangularPriv+import qualified Numeric.LAPACK.Matrix.RowMajor as RowMajor import qualified Numeric.LAPACK.Matrix.Private as Matrix+import qualified Numeric.LAPACK.Vector.Private as VectorPriv import qualified Numeric.LAPACK.Vector as Vector+import qualified Numeric.LAPACK.ShapeStatic as ShapeStatic import Numeric.LAPACK.Matrix.Hermitian.Private (TakeDiagonal(..)) import Numeric.LAPACK.Matrix.Hermitian.Basic (Hermitian) import Numeric.LAPACK.Matrix.Shape.Private          (Order(RowMajor,ColumnMajor), flipOrder, uploFromOrder,           UnaryProxy, natFromProxy)-import Numeric.LAPACK.Matrix.Private-         (Transposition(NonTransposed, Transposed), transposeOrder)+import Numeric.LAPACK.Matrix.Modifier+         (Transposition(NonTransposed, Transposed), transposeOrder,+          Conjugation(NonConjugated), conjugatedOnRowMajor) import Numeric.LAPACK.Vector (Vector) import Numeric.LAPACK.Scalar (RealOf, zero, one) import Numeric.LAPACK.Private-         (fill, lacgv, copyConjugate, condConjugateToTemp,+         (fill, lacgv, caseRealComplexFunc, realPtr,+          copyConjugate, condConjugate, condConjugateToTemp,           pointerSeq, pokeCInt, copySubMatrix)  import qualified Numeric.BLAS.FFI.Generic as BlasGen@@ -57,12 +64,11 @@ import Foreign.Marshal.Array (advancePtr) import Foreign.C.Types (CInt, CChar) import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)-import Foreign.Ptr (Ptr, castPtr)+import Foreign.Ptr (Ptr) import Foreign.Storable (Storable, poke, peek, peekElemOff)  import Control.Monad.Trans.Cont (ContT(ContT), evalContT) import Control.Monad.IO.Class (liftIO)-import Control.Monad (when)  import Data.Foldable (for_) import Data.Tuple.HT (mapPair)@@ -83,11 +89,42 @@ fromList numOff order size =    CheckedArray.fromList (MatrixShape.BandedHermitian numOff order size) +identityFatOrder ::+   (Unary.Natural offDiag, Shape.C sh, Class.Floating a) =>+   Order -> sh -> BandedHermitian offDiag sh a+identityFatOrder order sh =+   case order of+      RowMajor ->+         fromRowMajor $+         RowMajor.tensorProduct (Left NonConjugated)+            (Vector.one sh) (Vector.unit Shape.static $ Left ())+      ColumnMajor ->+         fromColumnMajor $+         RowMajor.tensorProduct (Left NonConjugated)+            (Vector.one sh) (Vector.unit Shape.static $ Right ())++fromRowMajor ::+   (Unary.Natural offDiag, Shape.C size) =>+   RowMajor.Matrix size (() Shape.:+: ShapeStatic.ZeroBased offDiag) a ->+   BandedHermitian offDiag size a+fromRowMajor =+   Array.mapShape+      (\(size, () Shape.:+: ShapeStatic.ZeroBased k) ->+         MatrixShape.BandedHermitian k RowMajor size)++fromColumnMajor ::+   (Unary.Natural offDiag, Shape.C size) =>+   RowMajor.Matrix size (ShapeStatic.ZeroBased offDiag Shape.:+: ()) a ->+   BandedHermitian offDiag size a+fromColumnMajor =+   Array.mapShape+      (\(size, ShapeStatic.ZeroBased k Shape.:+: ()) ->+         MatrixShape.BandedHermitian k ColumnMajor size)+ identity ::    (Shape.C sh, Class.Floating a) => sh -> Diagonal sh a-identity sh =-   Array.mapShape (MatrixShape.BandedHermitian Proxy ColumnMajor) $-   Vector.constant sh one+identity =+   Array.mapShape (MatrixShape.BandedHermitian Proxy ColumnMajor) . Vector.one  diagonal ::    (Shape.C sh, Class.Floating a) => Vector sh (RealOf a) -> Diagonal sh a@@ -101,24 +138,24 @@ takeDiagonal =    runTakeDiagonal $    Class.switchFloating-      (TakeDiagonal $ takeDiagonalAux 1) (TakeDiagonal $ takeDiagonalAux 1)-      (TakeDiagonal $ takeDiagonalAux 2) (TakeDiagonal $ takeDiagonalAux 2)+      (TakeDiagonal takeDiagonalAux) (TakeDiagonal takeDiagonalAux)+      (TakeDiagonal takeDiagonalAux) (TakeDiagonal takeDiagonalAux)  takeDiagonalAux ::    (Unary.Natural offDiag, Shape.C size,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Int -> BandedHermitian offDiag size a -> Vector size ar-takeDiagonalAux dim (Array (MatrixShape.BandedHermitian numOff order size) a) =+   BandedHermitian offDiag size a -> Vector size ar+takeDiagonalAux (Array (MatrixShape.BandedHermitian numOff order size) a) =    let k = integralFromProxy numOff    in Array.unsafeCreateWithSize size $ \n yPtr -> evalContT $ do          nPtr <- Call.cint n          aPtr <- ContT $ withForeignPtr a          let xPtr =-               castPtr $ advancePtr aPtr $+               realPtr $ advancePtr aPtr $                case order of                   RowMajor -> 0                   ColumnMajor -> k-         incxPtr <- Call.cint (dim * (k+1))+         incxPtr <- Call.cint (caseRealComplexFunc aPtr 1 2 * (k+1))          incyPtr <- Call.cint 1          liftIO $ BlasGen.copy nPtr xPtr incxPtr yPtr incyPtr @@ -210,7 +247,7 @@       (size == sizeX)    let k = integralFromProxy numOff    evalContT $ do-      let conj = transposeOrder transposed order == RowMajor+      let conj = conjugatedOnRowMajor $ transposeOrder transposed order       uploPtr <- Call.char $ uploFromOrder order       nPtr <- Call.cint n       kPtr <- Call.cint k@@ -224,15 +261,15 @@       liftIO $ do          BlasGen.hbmv uploPtr nPtr kPtr             alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr-         when conj $ lacgv nPtr yPtr incyPtr+         condConjugate conj nPtr yPtr incyPtr  -covariance ::+gramian ::    (Shape.C size, Eq size, Class.Floating a,     Unary.Natural sub, Unary.Natural super) =>    Banded.Square sub super size a ->    BandedHermitian (sub :+: super) size a-covariance a =+gramian a =    case mapPair (natFromProxy,natFromProxy) $         MatrixShape.bandedOffDiagonals $ Array.shape a of       (sub,super) ->@@ -259,7 +296,7 @@  multiplyFull ::    (Unary.Natural offDiag, Extent.C vert, Extent.C horiz,-    Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+    Shape.C height, Eq height, Shape.C width, Class.Floating a) =>    Transposition -> BandedHermitian offDiag height a ->    Matrix.Full vert horiz height width a ->    Matrix.Full vert horiz height width a@@ -332,7 +369,7 @@  multiplyFullGeneric ::    (Unary.Natural offDiag, Extent.C vert, Extent.C horiz,-    Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+    Shape.C height, Eq height, Shape.C width, Class.Floating a) =>    Transposition -> BandedHermitian offDiag height a ->    Matrix.Full vert horiz height width a ->    Matrix.Full vert horiz height width a@@ -342,9 +379,9 @@          case transposed of             Transposed -> (Banded.transpose upper, Banded.transpose lower)             NonTransposed -> (lower,upper)-   in Banded.multiplyFull (Banded.mapExtent Extent.fromSquare lowerT) b-      `Vector.add`-      Banded.multiplyFull (Banded.mapExtent Extent.fromSquare upperT) b+   in VectorPriv.mac one+         (Banded.multiplyFull (Banded.mapExtent Extent.fromSquare lowerT) b)+         (Banded.multiplyFull (Banded.mapExtent Extent.fromSquare upperT) b)  takeUpper ::    (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>@@ -380,9 +417,6 @@  type StaticVector n = Vector (ShapeStatic.ZeroBased n) -{--The list represents ragged rows of a sparse matrix.--} sumRank1 ::    (Unary.Natural k, Shape.Indexed sh, Class.Floating a) =>    Order -> sh ->@@ -430,9 +464,7 @@             let bPtr = advancePtr aPtr (lda*i)             hbr order k alpha                uploPtr mPtr kPtr alphaPtr xPtr incxPtr bPtr incxPtr ldbPtr-      case order of-         RowMajor -> lacgv bSizePtr aPtr incxPtr-         ColumnMajor -> return ()+      condConjugate (conjugatedOnRowMajor order) bSizePtr aPtr incxPtr   type HBR_ ar a =@@ -466,14 +498,14 @@    case order of       ColumnMajor -> do          let aPtr = advancePtr a0Ptr k-         let alphaRealPtr = castPtr alphaPtr+         let alphaRealPtr = realPtr alphaPtr          poke alphaRealPtr alpha          BlasComplex.her uploPtr kPtr alphaRealPtr xPtr incxPtr aPtr ldaPtr          poke alphaPtr . fmap (alpha*) . conjugate =<< peekElemOff xPtr k          BlasGen.axpy nPtr alphaPtr xPtr incxPtr (advancePtr aPtr (k*k)) incaPtr       RowMajor -> do          let aPtr = a0Ptr-         let alphaRealPtr = castPtr alphaPtr+         let alphaRealPtr = realPtr alphaPtr          poke alphaPtr . fmap (alpha*) . conjugate =<< peek xPtr          BlasGen.axpy nPtr alphaPtr xPtr incxPtr aPtr incaPtr          poke alphaRealPtr alpha
src/Numeric/LAPACK/Matrix/BandedHermitian/Eigen.hs view
@@ -9,8 +9,8 @@ import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape import qualified Numeric.LAPACK.Matrix.Private as Matrix import Numeric.LAPACK.Matrix.Hermitian.Private (TakeDiagonal(..))-import Numeric.LAPACK.Matrix.Shape.Private-         (Order(RowMajor,ColumnMajor), uploFromOrder)+import Numeric.LAPACK.Matrix.Shape.Private (Order(ColumnMajor), uploFromOrder)+import Numeric.LAPACK.Matrix.Modifier (conjugatedOnRowMajor) import Numeric.LAPACK.Vector (Vector) import Numeric.LAPACK.Scalar (RealOf) import Numeric.LAPACK.Private@@ -96,7 +96,7 @@       jobzPtr <- Call.char 'V'       uploPtr <- Call.char $ uploFromOrder order       kPtr <- Call.cint k-      aPtr <- copyCondConjugateToTemp (order==RowMajor) (n*lda) a+      aPtr <- copyCondConjugateToTemp (conjugatedOnRowMajor order) (n*lda) a       ldaPtr <- Call.leadingDim lda       ldzPtr <- Call.leadingDim n       liftIO $ withInfo eigenMsg "hbev" $
src/Numeric/LAPACK/Matrix/BandedHermitianPositiveDefinite.hs view
@@ -1,5 +1,52 @@ module Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite (-   module Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite.Linear,+   solve,+   solveDecomposed,+   decompose,+   determinant,    ) where -import Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite.Linear+import qualified Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite.Linear+                                                                  as Linear+import qualified Numeric.LAPACK.Matrix.Array.Banded as Banded+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Extent as Extent+import Numeric.LAPACK.Matrix.Array (Full)+import Numeric.LAPACK.Scalar (RealOf)++import qualified Numeric.Netlib.Class as Class++import qualified Type.Data.Num.Unary as Unary++import qualified Data.Array.Comfort.Shape as Shape+++solve ::+   (Unary.Natural offDiag, Shape.C size, Eq size,+    Extent.C vert, Extent.C horiz, Shape.C nrhs, Class.Floating a) =>+   Banded.Hermitian offDiag size a ->+   Full vert horiz size nrhs a -> Full vert horiz size nrhs a+solve = ArrMatrix.lift2 Linear.solve++{- |+> solve a b == solveDecomposed (decompose a) b+> solve (gramian u) b == solveDecomposed u b+-}+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 = ArrMatrix.lift2 Linear.solveDecomposed++{- |+Cholesky decomposition+-}+decompose ::+   (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>+   Banded.Hermitian offDiag size a -> Banded.Upper offDiag size a+decompose = ArrMatrix.lift1 Linear.decompose++determinant ::+   (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>+   Banded.Hermitian offDiag size a -> RealOf a+determinant = Linear.determinant . ArrMatrix.toVector
src/Numeric/LAPACK/Matrix/BandedHermitianPositiveDefinite/Linear.hs view
@@ -14,7 +14,8 @@ 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.Matrix.Modifier (Conjugation(Conjugated))+import Numeric.LAPACK.Matrix.Private (Full) import Numeric.LAPACK.Scalar (RealOf, realPart) import Numeric.LAPACK.Private (copyBlock, withInfo, rankMsg, definiteMsg) @@ -53,10 +54,6 @@          withInfo definiteMsg "pbsv" $             LapackGen.pbsv uploPtr nPtr kPtr nrhsPtr aPtr ldaPtr xPtr ldxPtr -{- |-> solve a b == solveDecomposed (decompose a) b-> solve (covariance u) b == solveDecomposed u b--} solveDecomposed ::    (Unary.Natural offDiag, Shape.C size, Eq size,     Extent.C vert, Extent.C horiz, Shape.C nrhs, Class.Floating a) =>@@ -76,9 +73,6 @@             LapackGen.pbtrs uploPtr nPtr kPtr nrhsPtr aPtr ldaPtr xPtr ldxPtr  -{- |-Cholesky decomposition--} decompose ::    (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>    BandedHermitian offDiag size a -> Banded.Upper offDiag size a
src/Numeric/LAPACK/Matrix/Basic.hs view
@@ -4,12 +4,19 @@  import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import qualified Numeric.LAPACK.Matrix.RowMajor as RowMajor+import qualified Numeric.LAPACK.Vector as Vector import qualified Numeric.LAPACK.Private as Private-import Numeric.LAPACK.Matrix.Shape.Private (Order(RowMajor, ColumnMajor))-import Numeric.LAPACK.Matrix.Private (Full, General)+import Numeric.LAPACK.Matrix.Shape.Private+         (Order(RowMajor, ColumnMajor), transposeFromOrder, flipOrder)+import Numeric.LAPACK.Matrix.Modifier (Conjugation(NonConjugated))+import Numeric.LAPACK.Matrix.Private+         (Full, Tall, Wide, General, ShapeInt, revealOrder) import Numeric.LAPACK.Vector (Vector)-import Numeric.LAPACK.Scalar (zero, one)-import Numeric.LAPACK.Private (pointerSeq)+import Numeric.LAPACK.Scalar (RealOf, zero, one)+import Numeric.LAPACK.Shape.Private (Unchecked(Unchecked))+import Numeric.LAPACK.Private+         (pointerSeq, copyTransposed, copySubMatrix, copyBlock)  import qualified Numeric.BLAS.FFI.Generic as BlasGen import qualified Numeric.Netlib.Utility as Call@@ -18,19 +25,49 @@ 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 Data.Array.Comfort.Shape ((:+:)((:+:))) -import Foreign.ForeignPtr (withForeignPtr)-import Foreign.Storable (poke, peek)+import Foreign.Marshal.Array (advancePtr)+import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)  import Control.Monad.Trans.Cont (ContT(ContT), evalContT) import Control.Monad.IO.Class (liftIO) +import Data.Complex (Complex) ++caseTallWide ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+   Full vert horiz height width a ->+   Either (Tall height width a) (Wide height width a)+caseTallWide (Array shape a) =+   either (Left . flip Array a) (Right . flip Array a) $+   MatrixShape.caseTallWide shape++ transpose ::    (Extent.C vert, Extent.C horiz) =>    Full vert horiz height width a -> Full horiz vert width height a transpose = Array.mapShape MatrixShape.transpose +adjoint ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>+   Full vert horiz height width a -> Full horiz vert width height a+adjoint = transpose . Vector.conjugate+++swapMultiply ::+   (Extent.C vertA, Extent.C vertB, Extent.C horizA, Extent.C horizB) =>+   (matrix ->+    Full horizA vertA widthA heightA a ->+    Full horizB vertB widthB heightB a) ->+   Full vertA horizA heightA widthA a ->+   matrix ->+   Full vertB horizB heightB widthB a+swapMultiply multiplyTrans a b = transpose $ multiplyTrans b $ transpose a++ mapHeight ::    (Extent.GeneralTallWide vert horiz,     Extent.GeneralTallWide horiz vert) =>@@ -53,7 +90,25 @@       (\(MatrixShape.Full order extent) ->          MatrixShape.Full order $ Extent.mapWidth f extent) +uncheck ::+   (Extent.C vert, Extent.C horiz) =>+   Full vert horiz height width a ->+   Full vert horiz (Unchecked height) (Unchecked width) a+uncheck =+   Array.mapShape+      (\(MatrixShape.Full order extent) ->+         MatrixShape.Full order $ Extent.mapWrap Unchecked Unchecked extent) +recheck ::+   (Extent.C vert, Extent.C horiz) =>+   Full vert horiz (Unchecked height) (Unchecked width) a ->+   Full vert horiz height width a+recheck =+   Array.mapShape+      (\(MatrixShape.Full order extent) ->+         MatrixShape.Full order $ Extent.recheck extent)++ singleRow :: Order -> Vector width a -> General () width a singleRow order = Array.mapShape (MatrixShape.general order ()) @@ -119,58 +174,200 @@       ColumnMajor -> transpose . forceRowMajor . transpose  +takeSub ::+   (Extent.C vert, Extent.C horiz,+    Shape.C heightA, Shape.C height, Shape.C width, Class.Floating a) =>+   heightA -> Int -> ForeignPtr a ->+   MatrixShape.Full vert horiz height width ->+   Full vert horiz height width a+takeSub heightA k a shape@(MatrixShape.Full order extentB) =+   Array.unsafeCreateWithSize shape $ \blockSize bPtr ->+   withForeignPtr a $ \aPtr ->+   let ma = Shape.size heightA+       mb = Shape.size $ Extent.height extentB+       n  = Shape.size $ Extent.width  extentB+   in case order of+         RowMajor -> copyBlock blockSize (advancePtr aPtr (k*n)) bPtr+         ColumnMajor -> copySubMatrix mb n ma (advancePtr aPtr k) mb bPtr++takeTop ::+   (Extent.C vert, Shape.C height0, Shape.C height1, Shape.C width,+    Class.Floating a) =>+   Full vert Extent.Big (height0:+:height1) width a ->+   Full vert Extent.Big height0 width a+takeTop (Array (MatrixShape.Full order extentA) a) =+   let heightA@(heightB:+:_) = Extent.height extentA+       extentB = Extent.reduceWideHeight heightB extentA+   in takeSub heightA 0 a $ MatrixShape.Full order extentB++takeBottom ::+   (Extent.C vert, Shape.C height0, Shape.C height1, Shape.C width,+    Class.Floating a) =>+   Full vert Extent.Big (height0:+:height1) width a ->+   Full vert Extent.Big height1 width a+takeBottom (Array (MatrixShape.Full order extentA) a) =+   let heightA@(height0:+:heightB) = Extent.height extentA+       extentB = Extent.reduceWideHeight heightB extentA+   in takeSub heightA (Shape.size height0) a $ MatrixShape.Full order extentB++takeLeft ::+   (Extent.C vert, Shape.C height, Shape.C width0, Shape.C width1,+    Class.Floating a) =>+   Full Extent.Big vert height (width0:+:width1) a ->+   Full Extent.Big vert height width0 a+takeLeft = transpose . takeTop . transpose++takeRight ::+   (Extent.C vert, Shape.C height, Shape.C width0, Shape.C width1,+    Class.Floating a) =>+   Full Extent.Big vert height (width0:+:width1) a ->+   Full Extent.Big vert height width1 a+takeRight = transpose . takeBottom . transpose+++splitRows ::+   (Extent.C vert, Shape.C width, Class.Floating a) =>+   Int ->+   Full vert Extent.Big ShapeInt width a ->+   Full vert Extent.Big (ShapeInt:+:ShapeInt) width a+splitRows k =+   Array.mapShape+      (\(MatrixShape.Full order extent) ->+         MatrixShape.Full order $+         Extent.reduceWideHeight+            (Shape.zeroBasedSplit k $ Extent.height extent)+            extent)++takeRows, dropRows ::+   (Extent.C vert, Shape.C width, Class.Floating a) =>+   Int ->+   Full vert Extent.Big ShapeInt width a ->+   Full vert Extent.Big ShapeInt width a+takeRows k = takeTop . splitRows k+dropRows k = takeBottom . splitRows k++takeColumns, dropColumns ::+   (Extent.C horiz, Shape.C height, Class.Floating a) =>+   Int ->+   Full Extent.Big horiz height ShapeInt a ->+   Full Extent.Big horiz height ShapeInt a+takeColumns k = transpose . takeRows k . transpose+dropColumns k = transpose . dropRows k . transpose+++data OrderBias = LeftBias | RightBias | ContiguousBias+   deriving (Eq, Ord, Enum, Show)++beside ::+   (Extent.C vertA, Extent.C vertB, Extent.C vertC,+    Shape.C height, Eq height, Shape.C widthA, Shape.C widthB,+    Class.Floating a) =>+   OrderBias ->+   Extent.AppendMode vertA vertB vertC height widthA widthB ->+   Full vertA Extent.Big height widthA a ->+   Full vertB Extent.Big height widthB a ->+   Full vertC Extent.Big height (widthA:+:widthB) a+beside orderBias (Extent.AppendMode appendMode)+      (Array (MatrixShape.Full orderA extentA) a)+      (Array (MatrixShape.Full orderB extentB) b) =+   let (heightA,widthA) = Extent.dimensions extentA+       (heightB,widthB) = Extent.dimensions extentB+       n = Shape.size heightA+       ma = Shape.size widthA; volA = n*ma+       mb = Shape.size widthB; volB = n*mb+       m = ma+mb+       create order act =+          Array.unsafeCreate+             (MatrixShape.Full order $ appendMode extentA extentB) $ \cPtr ->+          withForeignPtr a $ \aPtr ->+          withForeignPtr b $ \bPtr ->+          act aPtr bPtr cPtr $ advancePtr cPtr $+          case order of+             RowMajor -> ma+             ColumnMajor -> volA+   in+    if heightA /= heightB+      then error "beside: mismatching heights"+      else+         case (orderA,orderB) of+            (RowMajor,RowMajor) ->+               create RowMajor $ \aPtr bPtr cPtr _ -> evalContT $ do+                  maPtr <- Call.cint ma+                  mbPtr <- Call.cint mb+                  incxPtr <- Call.cint 1+                  incyPtr <- Call.cint 1+                  liftIO $+                     sequence_ $ take n $+                     zipWith3+                        (\akPtr bkPtr ckPtr -> do+                           BlasGen.copy maPtr akPtr incxPtr ckPtr incyPtr+                           BlasGen.copy mbPtr bkPtr incxPtr+                              (ckPtr `advancePtr` ma) incyPtr)+                        (pointerSeq ma aPtr)+                        (pointerSeq mb bPtr)+                        (pointerSeq m cPtr)+            (RowMajor,ColumnMajor) ->+               case orderBias of+                  LeftBias ->+                     create RowMajor $ \aPtr bPtr clPtr crPtr -> do+                        copySubMatrix ma n ma aPtr m clPtr+                        copyTransposed mb n bPtr m crPtr+                  _ ->+                     create ColumnMajor $ \aPtr bPtr clPtr crPtr -> do+                        copyTransposed n ma aPtr n clPtr+                        copyBlock volB bPtr crPtr+            (ColumnMajor,RowMajor) ->+               case orderBias of+                  RightBias ->+                     create RowMajor $ \aPtr bPtr clPtr crPtr -> do+                        copyTransposed ma n aPtr m clPtr+                        copySubMatrix mb n mb bPtr m crPtr+                  _ ->+                     create ColumnMajor $ \aPtr bPtr clPtr crPtr -> do+                        copyBlock volA aPtr clPtr+                        copyTransposed n mb bPtr n crPtr+            (ColumnMajor,ColumnMajor) ->+               create ColumnMajor $ \aPtr bPtr clPtr crPtr -> evalContT $ do+                  naPtr <- Call.cint volA+                  nbPtr <- Call.cint volB+                  incxPtr <- Call.cint 1+                  incyPtr <- Call.cint 1+                  liftIO $ do+                     BlasGen.copy naPtr aPtr incxPtr clPtr incyPtr+                     BlasGen.copy nbPtr bPtr incxPtr crPtr incyPtr++above ::+   (Extent.C horizA, Extent.C horizB, Extent.C horizC,+    Shape.C width, Eq width, Shape.C heightA, Shape.C heightB,+    Class.Floating a) =>+   OrderBias ->+   Extent.AppendMode horizA horizB horizC width heightA heightB ->+   Full Extent.Big horizA heightA width a ->+   Full Extent.Big horizB heightB width a ->+   Full Extent.Big horizC (heightA:+:heightB) width a+above orderBias appendMode a b =+   transpose $ beside orderBias appendMode (transpose a) (transpose b)+++liftRowMajor ::+   (Extent.C vert, Extent.C horiz) =>+   (Array (height, width) a -> Array (height, width) b) ->+   (Array (width, height) a -> Array (width, height) b) ->+   Full vert horiz height width a ->+   Full vert horiz height width b+liftRowMajor fr fc a =+   either+      (Array.reshape (Array.shape a) . fr)+      (Array.reshape (Array.shape a) . fc) $+   revealOrder a+ scaleRows ::    (Extent.C vert, Extent.C horiz,     Shape.C height, Eq height, Shape.C width, Class.Floating a) =>    Vector height a ->    Full vert horiz height width a ->    Full vert horiz height width a-scaleRows-   (Array heightX x) (Array shape@(MatrixShape.Full order extent) a) =-      Array.unsafeCreate shape $ \bPtr -> do-   let (height,width) = Extent.dimensions extent-   Call.assert "scaleRows: sizes mismatch" (heightX == height)-   case order of-      RowMajor -> evalContT $ do-         let m = Shape.size height-         let n = Shape.size width-         alphaPtr <- Call.alloca-         nPtr <- Call.cint n-         xPtr <- ContT $ withForeignPtr x-         aPtr <- ContT $ withForeignPtr a-         incaPtr <- Call.cint 1-         incbPtr <- Call.cint 1-         liftIO $ sequence_ $ take m $-            zipWith3-               (\xkPtr akPtr bkPtr -> do-                  poke alphaPtr =<< peek xkPtr-                  BlasGen.copy nPtr akPtr incaPtr bkPtr incbPtr-                  BlasGen.scal nPtr alphaPtr bkPtr incbPtr)-               (pointerSeq 1 xPtr)-               (pointerSeq n aPtr)-               (pointerSeq n bPtr)-      ColumnMajor -> evalContT $ do-         let m = Shape.size width-         let n = Shape.size height-         transPtr <- Call.char 'N'-         nPtr <- Call.cint n-         klPtr <- Call.cint 0-         kuPtr <- Call.cint 0-         alphaPtr <- Call.number one-         xPtr <- ContT $ withForeignPtr x-         ldxPtr <- Call.leadingDim 1-         aPtr <- ContT $ withForeignPtr a-         incaPtr <- Call.cint 1-         betaPtr <- Call.number zero-         incbPtr <- Call.cint 1-         liftIO $ sequence_ $ take m $-            zipWith-               (\akPtr bkPtr ->-                  Private.gbmv transPtr-                     nPtr nPtr klPtr kuPtr alphaPtr xPtr ldxPtr-                     akPtr incaPtr betaPtr bkPtr incbPtr)-               (pointerSeq n aPtr)-               (pointerSeq n bPtr)+scaleRows x = liftRowMajor (RowMajor.scaleRows x) (RowMajor.scaleColumns x)  scaleColumns ::    (Extent.C vert, Extent.C horiz,@@ -179,3 +376,145 @@    Full vert horiz height width a ->    Full vert horiz height width a scaleColumns x = transpose . scaleRows x . transpose+++scaleRowsComplex ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Class.Real a) =>+   Vector height a ->+   Full vert horiz height width (Complex a) ->+   Full vert horiz height width (Complex a)+scaleRowsComplex x =+   liftRowMajor+      (RowMajor.recomplex . RowMajor.scaleRows x . RowMajor.decomplex)+      (RowMajor.recomplex .+       RowMajor.scaleColumns+         (RowMajor.tensorProduct (Left NonConjugated) x+            (Vector.one Shape.Enumeration)) .+       RowMajor.decomplex)++scaleColumnsComplex ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Eq width, Class.Real a) =>+   Vector width a ->+   Full vert horiz height width (Complex a) ->+   Full vert horiz height width (Complex a)+scaleColumnsComplex x = transpose . scaleRowsComplex x . transpose+++scaleRowsReal ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Eq height, Shape.C width,+    Class.Floating a) =>+   Vector height (RealOf a) ->+   Full vert horiz height width a ->+   Full vert horiz height width a+scaleRowsReal =+   getScaleRowsReal $+   Class.switchFloating+      (ScaleRowsReal scaleRows)+      (ScaleRowsReal scaleRows)+      (ScaleRowsReal scaleRowsComplex)+      (ScaleRowsReal scaleRowsComplex)++newtype ScaleRowsReal f g a =+   ScaleRowsReal {getScaleRowsReal :: f (RealOf a) -> g a -> g a}++scaleColumnsReal ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Eq width, Class.Floating a) =>+   Vector width (RealOf a) ->+   Full vert horiz height width a ->+   Full vert horiz height width a+scaleColumnsReal x = transpose . scaleRowsReal x . transpose++++multiplyVector ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width, Eq width,+    Class.Floating a) =>+   Full vert horiz height width a -> Vector width a -> Vector height a+multiplyVector a x =+   let width = MatrixShape.fullWidth $ Array.shape a+   in if width == Array.shape x+         then multiplyVectorUnchecked a x+         else error "multiplyVector: width shapes mismatch"++multiplyVectorUnchecked ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>+   Full vert horiz height width a -> Vector width a -> Vector height a+multiplyVectorUnchecked+   (Array shape@(MatrixShape.Full order extent) a) (Array _ x) =+      Array.unsafeCreate (Extent.height extent) $ \yPtr -> do+   let (m,n) = MatrixShape.dimensions shape+   let lda = m+   evalContT $ do+      transPtr <- Call.char $ transposeFromOrder order+      mPtr <- Call.cint m+      nPtr <- Call.cint n+      alphaPtr <- Call.number one+      aPtr <- ContT $ withForeignPtr a+      ldaPtr <- Call.leadingDim lda+      xPtr <- ContT $ withForeignPtr x+      incxPtr <- Call.cint 1+      betaPtr <- Call.number zero+      incyPtr <- Call.cint 1+      liftIO $+         Private.gemv+            transPtr mPtr nPtr alphaPtr aPtr ldaPtr+            xPtr incxPtr betaPtr yPtr incyPtr++{- |+Multiply two matrices with the same dimension constraints.+E.g. you can multiply 'General' and 'General' matrices,+or 'Square' and 'Square' matrices.+It may seem to be overly strict in this respect,+but that design supports type inference the best.+You can lift the restrictions by generalizing operands+with 'Square.toFull', 'Matrix.fromFull',+'Matrix.generalizeTall' or 'Matrix.generalizeWide'.+-}+multiply, multiplyColumnMajor ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height,+    Shape.C fuse, Eq fuse,+    Shape.C width,+    Class.Floating a) =>+   Full vert horiz height fuse a ->+   Full vert horiz fuse width a ->+   Full vert horiz height width a+-- preserve order of the right factor+multiply+   (Array (MatrixShape.Full orderA extentA) a)+   (Array (MatrixShape.Full orderB extentB) b) =+   case Extent.fuse extentA extentB of+      Nothing -> error "multiply: fuse shapes mismatch"+      Just extent ->+         Array.unsafeCreate (MatrixShape.Full orderB extent) $ \cPtr -> do++      let (height,fuse) = Extent.dimensions extentA+      let width = Extent.width extentB+      let m = Shape.size height+      let n = Shape.size width+      let k = Shape.size fuse+      case orderB of+         RowMajor ->+            Private.multiplyMatrix (flipOrder orderB) (flipOrder orderA)+               n k m b a cPtr+         ColumnMajor -> Private.multiplyMatrix orderA orderB m k n a b cPtr++-- always return ColumnMajor+multiplyColumnMajor+   (Array (MatrixShape.Full orderA extentA) a)+   (Array (MatrixShape.Full orderB extentB) b) =+   case Extent.fuse extentA extentB of+      Nothing -> error "multiply: fuse shapes mismatch"+      Just extent ->+         Array.unsafeCreate (MatrixShape.Full ColumnMajor extent) $ \cPtr -> do++      let (height,fuse) = Extent.dimensions extentA+      let width = Extent.width extentB+      let m = Shape.size height+      let n = Shape.size width+      let k = Shape.size fuse+      Private.multiplyMatrix orderA orderB m k n a b cPtr
+ src/Numeric/LAPACK/Matrix/Class.hs view
@@ -0,0 +1,107 @@+{-# LANGUAGE TypeFamilies #-}+module Numeric.LAPACK.Matrix.Class (+   SquareShape(toSquare, identityOrder, takeDiagonal),+   identityFrom,+   identityFromHeight,+   identityFromWidth,+   trace,+   Complex(conjugate, fromReal, toComplex),+   ) where++import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Type as Type+import qualified Numeric.LAPACK.Matrix.Plain.Class as Plain+import qualified Numeric.LAPACK.Matrix.Triangular as Triangular+import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape+import qualified Numeric.LAPACK.Matrix.Permutation as Permutation+import qualified Numeric.LAPACK.Permutation.Private as Perm+import qualified Numeric.LAPACK.Vector as Vector+import qualified Numeric.LAPACK.Scalar as Scalar+import Numeric.LAPACK.Matrix.Array (ArrayMatrix)+import Numeric.LAPACK.Vector (Vector)+import Numeric.LAPACK.Scalar (RealOf, ComplexOf)++import qualified Numeric.Netlib.Class as Class++import qualified Data.Array.Comfort.Shape as Shape+++class Complex typ where+   conjugate ::+      (Class.Floating a) => Type.Matrix typ a -> Type.Matrix typ a+   fromReal ::+      (Class.Floating a) => Type.Matrix typ (RealOf a) -> Type.Matrix typ a+   toComplex ::+      (Class.Floating a) => Type.Matrix typ a -> Type.Matrix typ (ComplexOf a)++instance (Plain.Complex sh) => Complex (ArrMatrix.Array sh) where+   conjugate = ArrMatrix.lift1 Plain.conjugate+   fromReal  = ArrMatrix.lift1 Plain.fromReal+   toComplex = ArrMatrix.lift1 Plain.toComplex++instance (Shape.C shape) => Complex (Type.Scale shape) where+   conjugate (Type.Scale sh m) = Type.Scale sh $ Scalar.conjugate m+   fromReal (Type.Scale sh m) = Type.Scale sh $ Scalar.fromReal m+   toComplex (Type.Scale sh m) = Type.Scale sh $ Scalar.toComplex m++instance (Shape.C shape) => Complex (Perm.Permutation shape) where+   conjugate = id+   fromReal (Type.Permutation p) = Type.Permutation p+   toComplex (Type.Permutation p) = Type.Permutation p+++class SquareShape typ where+   toSquare ::+      (Type.HeightOf typ ~ sh, Class.Floating a) =>+      Type.Matrix typ a -> ArrMatrix.Square sh a+   identityOrder ::+      (Type.HeightOf typ ~ sh, Class.Floating a) =>+      MatrixShape.Order -> sh -> Type.Matrix typ a+   takeDiagonal ::+      (Type.HeightOf typ ~ sh, Class.Floating a) =>+      Type.Matrix typ a -> Vector sh a++instance (ArrMatrix.SquareShape sh) => SquareShape (ArrMatrix.Array sh) where+   toSquare = ArrMatrix.lift1 Plain.toSquare+   identityOrder order = ArrMatrix.lift0 . Plain.identityOrder order+   takeDiagonal = Plain.takeDiagonal . ArrMatrix.toVector++instance (Shape.C sh) => SquareShape (Type.Scale sh) where+   toSquare (Type.Scale sh a) =+      Triangular.toSquare $ Triangular.asDiagonal $+      Triangular.diagonal MatrixShape.RowMajor $ Vector.constant sh a+   identityOrder _ sh = Type.Scale sh Scalar.one+   takeDiagonal (Type.Scale sh a) = Vector.constant sh a++instance (Shape.C sh) => SquareShape (Perm.Permutation sh) where+   toSquare = Permutation.toMatrix+   identityOrder _ = Permutation.identity+   takeDiagonal = Perm.takeDiagonal . Permutation.toPermutation+++identityFrom ::+   (Plain.SquareShape shape, ArrMatrix.ShapeOrder shape, Class.Floating a) =>+   ArrayMatrix shape a -> ArrayMatrix shape a+identityFrom m =+   identityOrder (ArrMatrix.shapeOrder $ ArrMatrix.shape m) (Type.height m)++identityFromHeight ::+   (ArrMatrix.ShapeOrder shape, MatrixShape.Box shape,+    MatrixShape.HeightOf shape ~ Type.HeightOf typ, SquareShape typ,+    Class.Floating a) =>+   ArrayMatrix shape a -> Type.Matrix typ a+identityFromHeight m =+   identityOrder (ArrMatrix.shapeOrder $ ArrMatrix.shape m) (Type.height m)++identityFromWidth ::+   (ArrMatrix.ShapeOrder shape, MatrixShape.Box shape,+    MatrixShape.WidthOf shape ~ Type.HeightOf typ, SquareShape typ,+    Class.Floating a) =>+   ArrayMatrix shape a -> Type.Matrix typ a+identityFromWidth m =+   identityOrder (ArrMatrix.shapeOrder $ ArrMatrix.shape m) (Type.width m)++trace ::+   (SquareShape typ, Type.HeightOf typ ~ sh, Shape.C sh, Class.Floating a) =>+   Type.Matrix typ a -> a+trace = Vector.sum . takeDiagonal
src/Numeric/LAPACK/Matrix/Divide.hs view
@@ -1,97 +1,131 @@ {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE UndecidableInstances #-} module Numeric.LAPACK.Matrix.Divide where -import qualified Numeric.LAPACK.Matrix.Square.Linear-                                           as Square-import qualified Numeric.LAPACK.Matrix.Triangular.Linear-                                           as Triangular-import qualified Numeric.LAPACK.Matrix.Hermitian.Linear-                                           as Hermitian-import qualified Numeric.LAPACK.Matrix.Banded.Linear-                                           as Banded-import qualified Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite.Linear-                                           as BandedHermitianPositiveDefinite--import qualified Numeric.LAPACK.Matrix.Basic as Basic+import qualified Numeric.LAPACK.Matrix.Plain.Divide as ArrDivide+import qualified Numeric.LAPACK.Matrix.Array.Basic as Basic+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Permutation as PermMatrix+import qualified Numeric.LAPACK.Matrix.Multiply as Multiply+import qualified Numeric.LAPACK.Matrix.Type as Type import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape-import qualified Numeric.LAPACK.Matrix.Shape.Box as Box import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent-import Numeric.LAPACK.Matrix.Extent.Private (Small)-import Numeric.LAPACK.Matrix.Private (Full)+import qualified Numeric.LAPACK.Vector as Vector+import Numeric.LAPACK.Matrix.Array (Full)+import Numeric.LAPACK.Matrix.Type (Matrix, scaleWithCheck)+import Numeric.LAPACK.Matrix.Modifier+         (Transposition(NonTransposed,Transposed),+          Inversion(Inverted)) import Numeric.LAPACK.Vector (Vector)  import qualified Numeric.Netlib.Class as Class -import qualified Type.Data.Num.Unary as Unary- import qualified Data.Array.Comfort.Shape as Shape-import Data.Array.Comfort.Storable (Array) +import Data.Semigroup ((<>)) -class (Shape.C shape) => Solve shape where++class+   (Type.Box typ, Type.HeightOf typ ~ Type.WidthOf typ) =>+      Determinant typ where+   determinant :: (Class.Floating a) => Matrix typ a -> a++class (Type.Box typ, Type.HeightOf typ ~ Type.WidthOf typ) => Solve typ where+   {-# MINIMAL solve | solveLeft,solveRight #-}    solve ::-      (Class.Floating a, Box.HeightOf shape ~ height, Eq height,-       Extent.C horiz, Extent.C vert, Shape.C nrhs) =>-      Array shape a ->-      Full vert horiz height nrhs a -> Full vert horiz height nrhs a+      (Type.HeightOf typ ~ height, Eq height, Shape.C width,+       Extent.C horiz, Extent.C vert, Class.Floating a) =>+      Transposition -> Matrix typ a ->+      Full vert horiz height width a -> Full vert horiz height width a+   solve NonTransposed a b = solveRight a b+   solve Transposed a b = Basic.transpose $ solveLeft (Basic.transpose b) a -class (Solve shape) => Inverse shape where-   inverse :: (Class.Floating a) => Array shape a -> Array shape a+   solveRight ::+      (Type.HeightOf typ ~ height, Eq height, Shape.C width,+       Extent.C horiz, Extent.C vert, Class.Floating a) =>+      Matrix typ a ->+      Full vert horiz height width a -> Full vert horiz height width a+   solveRight = solve NonTransposed +   solveLeft ::+      (Type.WidthOf typ ~ width, Eq width, Shape.C height,+       Extent.C horiz, Extent.C vert, Class.Floating a) =>+      Full vert horiz height width a ->+      Matrix typ a -> Full vert horiz height width a+   solveLeft = Basic.swapMultiply $ solve Transposed++class (Solve typ, Multiply.Power typ) => Inverse typ where+   inverse :: (Class.Floating a) => Matrix typ a -> Matrix typ a++infixl 7 ##/#+infixr 7 #\##++(#\##) ::+   (Solve typ, Type.HeightOf typ ~ height, Eq height, Shape.C width,+    Extent.C horiz, Extent.C vert, Class.Floating a) =>+   Matrix typ a ->+   Full vert horiz height width a -> Full vert horiz height width a+(#\##) = solveRight++(##/#) ::+   (Solve typ, Type.WidthOf typ ~ width, Eq width, Shape.C height,+    Extent.C horiz, Extent.C vert, Class.Floating a) =>+   Full vert horiz height width a ->+   Matrix typ a -> Full vert horiz height width a+(##/#) = solveLeft++ solveVector ::-   (Solve shape, Box.HeightOf shape ~ height, Eq height, Class.Floating a) =>-   Array shape a -> Vector height a -> Vector height a-solveVector m =-   Basic.flattenColumn . solve m . Basic.singleColumn MatrixShape.ColumnMajor+   (Solve typ, Type.HeightOf typ ~ height, Eq height, Class.Floating a) =>+   Transposition -> Matrix typ a -> Vector height a -> Vector height a+solveVector trans =+   ArrMatrix.unliftColumn MatrixShape.ColumnMajor . solve trans +infixl 7 -/#+infixr 7 #\| -instance-   (vert ~ Small, horiz ~ Small,-    Shape.C width, Shape.C height, height ~ width) =>-      Solve (MatrixShape.Full vert horiz height width) where-   solve = Square.solve+(#\|) ::+   (Solve typ, Type.HeightOf typ ~ height, Eq height, Class.Floating a) =>+   Matrix typ a -> Vector height a -> Vector height a+(#\|) = solveVector NonTransposed -instance-   (vert ~ Small, horiz ~ Small,-    Shape.C width, Shape.C height, height ~ width) =>-      Inverse (MatrixShape.Full vert horiz height width) where-   inverse = Square.inverse+(-/#) ::+   (Solve typ, Type.HeightOf typ ~ height, Eq height, Class.Floating a) =>+   Vector height a -> Matrix typ a -> Vector height a+(-/#) = flip $ solveVector Transposed  -instance (Shape.C shape) => Solve (MatrixShape.Hermitian shape) where-   solve = Hermitian.solve+instance (Shape.C shape, Eq shape) => Determinant (Type.Scale shape) where+   determinant (Type.Scale sh a) = a ^ Shape.size sh -instance (Shape.C shape) => Inverse (MatrixShape.Hermitian shape) where-   inverse = Hermitian.inverse+instance (Shape.C shape, Eq shape) => Solve (Type.Scale shape) where+   solve _trans =+      scaleWithCheck "Matrix.Scale.solve" Type.height $+         ArrMatrix.lift1 . Vector.scale . recip +instance (Shape.C shape, Eq shape) => Inverse (Type.Scale shape) where+   inverse (Type.Scale shape a) = Type.Scale shape $ recip a -instance-   (MatrixShape.Content lo, MatrixShape.Content up,-    MatrixShape.TriDiag diag, Shape.C shape) =>-      Solve (MatrixShape.Triangular lo diag up shape) where-   solve = Triangular.solve -instance-   (MatrixShape.DiagUpLo lo up,-    MatrixShape.TriDiag diag, Shape.C shape) =>-      Inverse (MatrixShape.Triangular lo diag up shape) where-   inverse = Triangular.inverse+instance (Shape.C shape) => Determinant (PermMatrix.Permutation shape) where+   determinant = PermMatrix.determinant +instance (Shape.C shape) => Solve (PermMatrix.Permutation shape) where+   solve trans =+      PermMatrix.multiplyFull+         (Inverted <> PermMatrix.inversionFromTransposition trans) -instance-   (Unary.Natural sub, Unary.Natural super, vert ~ Small, horiz ~ Small,-    Shape.C width, Shape.C height, width ~ height) =>-      Solve (MatrixShape.Banded sub super vert horiz height width) where-   solve = Banded.solve+instance (Shape.C shape) => Inverse (PermMatrix.Permutation shape) where+   inverse = PermMatrix.transpose  -{- |-There is no solver for indefinite matrices.-Thus the instance will fail for indefinite but solvable systems.--} instance-   (Unary.Natural offDiag, Shape.C size) =>-      Solve (MatrixShape.BandedHermitian offDiag size) where-   solve = BandedHermitianPositiveDefinite.solve+      (ArrDivide.Determinant shape) => Determinant (ArrMatrix.Array shape) where+   determinant = ArrDivide.determinant . ArrMatrix.toVector++instance (ArrDivide.Solve shape) => Solve (ArrMatrix.Array shape) where+   solve = ArrMatrix.lift2 . ArrDivide.solve+   solveLeft = ArrMatrix.lift2 ArrDivide.solveLeft+   solveRight = ArrMatrix.lift2 ArrDivide.solveRight++instance (ArrDivide.Inverse shape) => Inverse (ArrMatrix.Array shape) where+   inverse = ArrMatrix.lift1 ArrDivide.inverse
src/Numeric/LAPACK/Matrix/Extent.hs view
@@ -17,14 +17,21 @@    fromSquareLiberal,    generalizeTall,    generalizeWide,+   Extent.GeneralTallWide,++   Extent.AppendMode,+   Extent.appendSame,+   Extent.appendLeft,+   Extent.appendRight,+   Extent.Append,+   Extent.appendAny,    ) where  import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent import Numeric.LAPACK.Matrix.Extent.Private (C, Small, Big, Map(Map))  -toGeneral ::-   (C vert, C horiz) => Map vert horiz Big Big height width+toGeneral :: (C vert, C horiz) => Map vert horiz Big Big height width toGeneral = Map Extent.toGeneral  fromSquare :: (C vert, C horiz) => Map Small Small vert horiz size size
src/Numeric/LAPACK/Matrix/Extent/Private.hs view
@@ -1,11 +1,15 @@ {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE GADTs #-} module Numeric.LAPACK.Matrix.Extent.Private where  import qualified Numeric.LAPACK.Matrix.Extent.Kind as EK+import Numeric.LAPACK.Shape.Private (Unchecked(deconsUnchecked)) import Numeric.LAPACK.Wrapper (Flip(Flip, getFlip)) +import Data.Array.Comfort.Shape ((:+:)((:+:)))+ import Control.DeepSeq (NFData, rnf)  import Data.Maybe.HT (toMaybe)@@ -382,8 +386,60 @@       (Adapt $ \(Extent o (EK.Tall h w)) -> Extent o (EK.Tall h (f w)))       (Adapt $ \(Extent o (EK.General h w)) -> Extent o (EK.General h (f w))) +mapSquareSize :: (shA -> shB) -> Square shA -> Square shB+mapSquareSize f (Extent o (EK.Square s)) = Extent o (EK.Square (f s))  +mapWrap ::+   (C vert, C horiz) =>+   (height -> f height) ->+   (width -> f width) ->+   Extent vert horiz height width ->+   Extent vert horiz (f height) (f width)+mapWrap fh fw =+   getAdapt $+   switchTagPair+      (Adapt $ \(Extent o (EK.Square h)) -> Extent o (EK.Square (fh h)))+      (Adapt $ \(Extent o (EK.Wide h w)) -> Extent o (EK.Wide (fh h) (fw w)))+      (Adapt $ \(Extent o (EK.Tall h w)) -> Extent o (EK.Tall (fh h) (fw w)))+      (Adapt $ \(Extent o (EK.General h w)) ->+                  Extent o (EK.General (fh h) (fw w)))++{- only admissible since GHC-7.8+mapUnwrap ::+   (C vert, C horiz) =>+   (f height -> height) ->+   (f width -> width) ->+   Extent vert horiz (f height) (f width) ->+   Extent vert horiz height width+mapUnwrap fh fw =+   getAdapt $+   switchTagPair+      (Adapt $ \(Extent o (EK.Square h)) -> Extent o (EK.Square (fh h)))+      (Adapt $ \(Extent o (EK.Wide h w)) -> Extent o (EK.Wide (fh h) (fw w)))+      (Adapt $ \(Extent o (EK.Tall h w)) -> Extent o (EK.Tall (fh h) (fw w)))+      (Adapt $ \(Extent o (EK.General h w)) ->+                  Extent o (EK.General (fh h) (fw w)))+-}++recheck ::+   (C vert, C horiz) =>+   Extent vert horiz (Unchecked height) (Unchecked width) ->+   Extent vert horiz height width+recheck =+   getAdapt $+   switchTagPair+      (Adapt $ \(Extent o (EK.Square h)) ->+         Extent o (EK.Square (deconsUnchecked h)))+      (Adapt $ \(Extent o (EK.Wide h w)) ->+         Extent o (EK.Wide (deconsUnchecked h) (deconsUnchecked w)))+      (Adapt $ \(Extent o (EK.Tall h w)) ->+         Extent o (EK.Tall (deconsUnchecked h) (deconsUnchecked w)))+      (Adapt $ \(Extent o (EK.General h w)) ->+         Extent o (EK.General (deconsUnchecked h) (deconsUnchecked w)))+++ newtype Fuse height fuse width vert horiz =    Fuse {       getFuse ::@@ -412,6 +468,100 @@       (Fuse $        \(Extent o (EK.General h f0)) (Extent _ (EK.General f1 w)) ->          toMaybe (f0==f1) $ Extent o (EK.General h w))+++newtype Kronecker heightA widthA heightB widthB vert horiz =+   Kronecker {+      getKronecker ::+         Extent vert horiz heightA widthA ->+         Extent vert horiz heightB widthB ->+         Extent vert horiz (heightA,heightB) (widthA,widthB)+   }++kronecker ::+   (C vert, C horiz) =>+   Extent vert horiz heightA widthA ->+   Extent vert horiz heightB widthB ->+   Extent vert horiz (heightA,heightB) (widthA,widthB)+kronecker =+   getKronecker $+   switchTagPair+      (Kronecker $+       \(Extent o (EK.Square s0)) (Extent _ (EK.Square s1)) ->+         Extent o (EK.Square (s0,s1)))+      (Kronecker $+       \(Extent o (EK.Wide h0 w0)) (Extent _ (EK.Wide h1 w1)) ->+         Extent o (EK.Wide (h0,h1) (w0,w1)))+      (Kronecker $+       \(Extent o (EK.Tall h0 w0)) (Extent _ (EK.Tall h1 w1)) ->+         Extent o (EK.Tall (h0,h1) (w0,w1)))+      (Kronecker $+       \(Extent o (EK.General h0 w0)) (Extent _ (EK.General h1 w1)) ->+         Extent o (EK.General (h0,h1) (w0,w1)))++++{-+Tag table for 'beside'.++Small Small  Small Small -> Small Big+Small Small  Small Big   -> Small Big+Small Small  Big   Small -> Small Big+Small Small  Big   Big   -> Small Big+Small Big    Small Small -> Small Big+Small Big    Small Big   -> Small Big+Small Big    Big   Small -> Small Big+Small Big    Big   Big   -> Small Big+Big   Small  Small Small -> Small Big+Big   Small  Small Big   -> Small Big+Big   Small  Big   Small -> Big   Big+Big   Small  Big   Big   -> Big   Big+Big   Big    Small Small -> Small Big+Big   Big    Small Big   -> Small Big+Big   Big    Big   Small -> Big   Big+Big   Big    Big   Big   -> Big   Big+-}+newtype AppendMode vertA vertB vertC height widthA widthB =+   AppendMode (+      Extent vertA Big height widthA ->+      Extent vertB Big height widthB ->+      Extent vertC Big height (widthA:+:widthB)+   )++appendLeftAux ::+   (C vertA, C vertB) => AppendMode vertA vertB vertA height widthA widthB+appendLeftAux =+   AppendMode $ \extentA extentB ->+      widen (width extentA :+: width extentB) extentA++appendSame :: (C vert) => AppendMode vert vert vert height widthA widthB+appendSame = appendLeftAux++appendLeft :: (C vert) => AppendMode vert Big vert height widthA widthB+appendLeft = appendLeftAux++appendRight :: (C vert) => AppendMode Big vert vert height widthA widthB+appendRight =+   AppendMode $ \extentA extentB ->+      widen (width extentA :+: width extentB) extentB++type family Append a b+type instance Append Small b = Small+type instance Append Big   b = b++newtype+   AppendAny vertB height widthA widthB vertA =+      AppendAny {+         getAppendAny ::+            AppendMode vertA vertB (Append vertA vertB) height widthA widthB+      }++appendAny ::+   (C vertA, C vertB) =>+   AppendMode vertA vertB (Append vertA vertB) height widthA widthB+appendAny =+   getAppendAny $ switchTag (AppendAny appendLeftAux) (AppendAny appendRight)+   type family Multiply a b
src/Numeric/LAPACK/Matrix/Hermitian.hs view
@@ -1,29 +1,310 @@ {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} module Numeric.LAPACK.Matrix.Hermitian (-   module Numeric.LAPACK.Matrix.Hermitian.Basic,-   module Numeric.LAPACK.Matrix.Hermitian.Linear,+   Hermitian,+   Transposition(..), +   size,+   fromList,+   autoFromList,+   identity,+   diagonal,+   takeDiagonal,+   forceOrder,++   stack, (*%%%#),+   split,+   takeTopLeft,+   takeTopRight,+   takeBottomRight,++   multiplyVector,+   square,+   multiplyFull,+   outer,+   sumRank1, sumRank1NonEmpty,+   sumRank2, sumRank2NonEmpty,++   toSquare,+   gramian,            gramianAdjoint,+   congruenceDiagonal, congruenceDiagonalAdjoint,+   congruence,         congruenceAdjoint,+   anticommutator,     anticommutatorAdjoint,+   addAdjoint,++   solve,+   inverse,+   determinant,+    eigenvalues,    eigensystem,    ) where  import qualified Numeric.LAPACK.Matrix.Hermitian.Eigen as Eigen-import Numeric.LAPACK.Matrix.Hermitian.Basic-import Numeric.LAPACK.Matrix.Hermitian.Linear--import Numeric.LAPACK.Matrix.Private (Square)+import qualified Numeric.LAPACK.Matrix.Hermitian.Linear as Linear+import qualified Numeric.LAPACK.Matrix.Hermitian.Basic as Basic+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Extent as Extent+import Numeric.LAPACK.Matrix.Array.Triangular (Hermitian)+import Numeric.LAPACK.Matrix.Array (Full, General, Square)+import Numeric.LAPACK.Matrix.Shape.Private (Order)+import Numeric.LAPACK.Matrix.Modifier (Transposition(NonTransposed, Transposed))+import Numeric.LAPACK.Matrix.Private (ShapeInt) import Numeric.LAPACK.Vector (Vector)-import Numeric.LAPACK.Scalar (RealOf)+import Numeric.LAPACK.Scalar (RealOf, one)  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.Shape ((:+:)) +import Foreign.Storable (Storable) +import qualified Data.NonEmpty as NonEmpty+import Data.Tuple.HT (mapFst)+++size :: Hermitian sh a -> sh+size = MatrixShape.hermitianSize . ArrMatrix.shape++fromList :: (Shape.C sh, Storable a) => Order -> sh -> [a] -> Hermitian sh a+fromList order sh = ArrMatrix.lift0 . Basic.fromList order sh++autoFromList :: (Storable a) => Order -> [a] -> Hermitian ShapeInt a+autoFromList order = ArrMatrix.lift0 . Basic.autoFromList order++identity :: (Shape.C sh, Class.Floating a) => Order -> sh -> Hermitian sh a+identity order = ArrMatrix.lift0 . Basic.identity order++diagonal ::+   (Shape.C sh, Class.Floating a) =>+   Order -> Vector sh (RealOf a) -> Hermitian sh a+diagonal order = ArrMatrix.lift0 . Basic.diagonal order++takeDiagonal ::+   (Shape.C sh, Class.Floating a) =>+   Hermitian sh a -> Vector sh (RealOf a)+takeDiagonal = Basic.takeDiagonal . ArrMatrix.toVector++forceOrder ::+   (Shape.C sh, Class.Floating a) =>+   Order -> Hermitian sh a -> Hermitian sh a+forceOrder = ArrMatrix.lift1 . Basic.forceOrder++{- |+> toSquare (stack a b c)+>+> =+>+> toSquare a ||| b+> ===+> adjoint b ||| toSquare c++It holds @order (stack a b c) = order b@.+The function is most efficient when the order of all blocks match.+-}+stack ::+   (Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>+   Hermitian sh0 a -> General sh0 sh1 a -> Hermitian sh1 a ->+   Hermitian (sh0:+:sh1) a+stack = ArrMatrix.lift3 Basic.stack++infixr 2 *%%%#++(*%%%#) ::+   (Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>+   (Hermitian sh0 a, General sh0 sh1 a) -> Hermitian sh1 a ->+   Hermitian (sh0:+:sh1) a+(*%%%#) = uncurry stack+++split ::+   (Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Hermitian (sh0:+:sh1) a ->+   (Hermitian sh0 a, General sh0 sh1 a, Hermitian sh1 a)+split a = (takeTopLeft a, takeTopRight a, takeBottomRight a)++takeTopLeft ::+   (Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Hermitian (sh0:+:sh1) a -> Hermitian sh0 a+takeTopLeft = ArrMatrix.lift1 Basic.takeTopLeft++takeTopRight ::+   (Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Hermitian (sh0:+:sh1) a -> General sh0 sh1 a+takeTopRight = ArrMatrix.lift1 Basic.takeTopRight++takeBottomRight ::+   (Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Hermitian (sh0:+:sh1) a -> Hermitian sh1 a+takeBottomRight = ArrMatrix.lift1 Basic.takeBottomRight+++multiplyVector ::+   (Shape.C sh, Eq sh, Class.Floating a) =>+   Transposition -> Hermitian sh a -> Vector sh a -> Vector sh a+multiplyVector order = Basic.multiplyVector order . ArrMatrix.toVector++square ::+   (Shape.C sh, Eq sh, Class.Floating a) => Hermitian sh a -> Hermitian sh a+square = ArrMatrix.lift1 Basic.square++multiplyFull ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width,+    Class.Floating a) =>+   Transposition -> Hermitian height a ->+   Full vert horiz height width a ->+   Full vert horiz height width a+multiplyFull = ArrMatrix.lift2 . Basic.multiplyFull++outer ::+   (Shape.C sh, Class.Floating a) => Order -> Vector sh a -> Hermitian sh a+outer order = ArrMatrix.lift0 . Basic.outer order++sumRank1 ::+   (Shape.C sh, Eq sh, Class.Floating a) =>+   Order -> sh -> [(RealOf a, Vector sh a)] -> Hermitian sh a+sumRank1 order sh = ArrMatrix.lift0 . Basic.sumRank1 order sh++sumRank1NonEmpty ::+   (Shape.C sh, Eq sh, Class.Floating a) =>+   Order -> NonEmpty.T [] (RealOf a, Vector sh a) -> Hermitian sh a+sumRank1NonEmpty order (NonEmpty.Cons x xs) =+   sumRank1 order (Array.shape $ snd x) (x:xs)++sumRank2 ::+   (Shape.C sh, Eq sh, Class.Floating a) =>+   Order -> sh -> [(a, (Vector sh a, Vector sh a))] -> Hermitian sh a+sumRank2 order sh = ArrMatrix.lift0 . Basic.sumRank2 order sh++sumRank2NonEmpty ::+   (Shape.C sh, Eq sh, Class.Floating a) =>+   Order -> NonEmpty.T [] (a, (Vector sh a, Vector sh a)) -> Hermitian sh a+sumRank2NonEmpty order (NonEmpty.Cons xy xys) =+   sumRank2 order (Array.shape $ fst $ snd xy) (xy:xys)++toSquare ::+   (Shape.C sh, Class.Floating a) => Hermitian sh a -> Square sh a+toSquare = ArrMatrix.lift1 Basic.toSquare++{- |+gramian A = A^H * A+-}+gramian ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   General height width a -> Hermitian width a+gramian = ArrMatrix.lift1 Basic.gramian++{- |+gramianAdjoint A = A * A^H = gramian (A^H)+-}+gramianAdjoint ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   General height width a -> Hermitian height a+gramianAdjoint = ArrMatrix.lift1 Basic.gramianAdjoint++{- |+congruenceDiagonal D A = A^H * D * A+-}+congruenceDiagonal ::+   (Shape.C height, Eq height, Shape.C width, Class.Floating a) =>+   Vector height (RealOf a) -> General height width a -> Hermitian width a+congruenceDiagonal = ArrMatrix.lift1 . Basic.congruenceDiagonal++{- |+congruenceDiagonalAdjoint A D = A * D * A^H+-}+congruenceDiagonalAdjoint ::+   (Shape.C height, Shape.C width, Eq width, Class.Floating a) =>+   General height width a -> Vector width (RealOf a) -> Hermitian height a+congruenceDiagonalAdjoint a =+   ArrMatrix.lift0 . Basic.congruenceDiagonalAdjoint (ArrMatrix.toVector a)++{- |+congruence B A = A^H * B * A+-}+congruence ::+   (Shape.C height, Eq height, Shape.C width, Class.Floating a) =>+   Hermitian height a -> General height width a -> Hermitian width a+congruence = ArrMatrix.lift2 Basic.congruence++{- |+congruenceAdjoint B A = A * B * A^H+-}+congruenceAdjoint ::+   (Shape.C height, Shape.C width, Eq width, Class.Floating a) =>+   General height width a -> Hermitian width a -> Hermitian height a+congruenceAdjoint = ArrMatrix.lift2 Basic.congruenceAdjoint+++{- |+anticommutator A B  =  A^H * B + B^H * A++Not exactly a matrix anticommutator,+thus I like to call it Hermitian anticommutator.+-}+anticommutator ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Eq width,+    Class.Floating a) =>+   Full vert horiz height width a ->+   Full vert horiz height width a -> Hermitian width a+anticommutator = ArrMatrix.lift2 $ Basic.scaledAnticommutator one++{- |+anticommutatorAdjoint A B+   = A * B^H + B * A^H+   = anticommutator (adjoint A) (adjoint B)+-}+anticommutatorAdjoint ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Eq width,+    Class.Floating a) =>+   Full vert horiz height width a ->+   Full vert horiz height width a -> Hermitian height a+anticommutatorAdjoint = ArrMatrix.lift2 $ Basic.scaledAnticommutatorAdjoint one++{- |+scaledAnticommutator alpha A B  =  alpha * A^H * B + conj alpha * B^H * A+-}+_scaledAnticommutator ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Eq width,+    Class.Floating a) =>+   a ->+   Full vert horiz height width a ->+   Full vert horiz height width a -> Hermitian width a+_scaledAnticommutator = ArrMatrix.lift2 . Basic.scaledAnticommutator++{- |+addAdjoint A = A^H + A+-}+addAdjoint :: (Shape.C sh, Class.Floating a) => Square sh a -> Hermitian sh a+addAdjoint = ArrMatrix.lift1 Basic.addAdjoint++++solve ::+   (Extent.C vert, Extent.C horiz,+    Shape.C sh, Eq sh, Shape.C nrhs, Class.Floating a) =>+   Hermitian sh a -> Full vert horiz sh nrhs a -> Full vert horiz sh nrhs a+solve = ArrMatrix.lift2 Linear.solve++inverse :: (Shape.C sh, Class.Floating a) => Hermitian sh a -> Hermitian sh a+inverse = ArrMatrix.lift1 Linear.inverse++determinant :: (Shape.C sh, Class.Floating a) => Hermitian sh a -> RealOf a+determinant = Linear.determinant . ArrMatrix.toVector+++ eigenvalues ::    (Shape.C sh, Class.Floating a) =>    Hermitian sh a -> Vector sh (RealOf a)-eigenvalues = Eigen.values+eigenvalues = Eigen.values . ArrMatrix.toVector  {- | For symmetric eigenvalue problems, @eigensystem@ and @schur@ coincide.@@ -31,4 +312,4 @@ eigensystem ::    (Shape.C sh, Class.Floating a) =>    Hermitian sh a -> (Square sh a, Vector sh (RealOf a))-eigensystem = Eigen.decompose+eigensystem = mapFst ArrMatrix.lift0 . Eigen.decompose . ArrMatrix.toVector
src/Numeric/LAPACK/Matrix/Hermitian/Basic.hs view
@@ -5,22 +5,32 @@    Transposition(..),    fromList,    autoFromList,+   recheck,    identity,    diagonal,    takeDiagonal,    forceOrder,+    stack,+   takeTopLeft,+   takeTopRight,+   takeBottomRight,     multiplyVector,-   square,    multiplyFull,+   square, power,    outer,-   sumRank1, sumRank1NonEmpty,-   sumRank2, sumRank2NonEmpty,+   sumRank1,+   sumRank2,     toSquare,-   covariance,+   gramian,              gramianAdjoint,+   congruenceDiagonal,   congruenceDiagonalAdjoint,+   congruence,           congruenceAdjoint,+   scaledAnticommutator, scaledAnticommutatorAdjoint,    addAdjoint,++   takeUpper,    ) where  import qualified Numeric.LAPACK.Matrix.Symmetric.Private as Symmetric@@ -28,22 +38,26 @@ import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent import qualified Numeric.LAPACK.Matrix.Basic as Basic+import qualified Numeric.LAPACK.Split as Split import Numeric.LAPACK.Matrix.Hermitian.Private (Diagonal(..), TakeDiagonal(..)) import Numeric.LAPACK.Matrix.Triangular.Private-         (forPointers, pack, packRect, unpack, unpackToTemp,+         (forPointers, pack, unpack, unpackToTemp,           diagonalPointers, diagonalPointerPairs,           rowMajorPointers, columnMajorPointers) import Numeric.LAPACK.Matrix.Shape.Private          (Order(RowMajor,ColumnMajor), flipOrder, sideSwapFromOrder,           uploFromOrder)+import Numeric.LAPACK.Matrix.Modifier+         (Transposition(NonTransposed, Transposed), transposeOrder,+          Conjugation(Conjugated), conjugatedOnRowMajor) import Numeric.LAPACK.Matrix.Private-         (Full, General, argGeneral, Square, argSquare, ZeroInt, zeroInt,-          Transposition(NonTransposed, Transposed), transposeOrder,-          Conjugation(Conjugated))+         (Full, General, Square, argSquare, ShapeInt, shapeInt) import Numeric.LAPACK.Vector (Vector)-import Numeric.LAPACK.Scalar (RealOf, zero, one, fromReal, realPart)+import Numeric.LAPACK.Scalar (RealOf, zero, one)+import Numeric.LAPACK.Shape.Private (Unchecked(Unchecked)) import Numeric.LAPACK.Private-         (fill, lacgv, copyConjugate, conjugateToTemp, condConjugateToTemp)+         (fill, lacgv, realPtr,+          copyConjugate, condConjugate, conjugateToTemp, condConjugateToTemp)  import qualified Numeric.BLAS.FFI.Generic as BlasGen import qualified Numeric.BLAS.FFI.Complex as BlasComplex@@ -55,10 +69,10 @@ import qualified Data.Array.Comfort.Storable as CheckedArray import qualified Data.Array.Comfort.Shape as Shape import Data.Array.Comfort.Storable.Unchecked (Array(Array))-import Data.Array.Comfort.Shape ((:+:))+import Data.Array.Comfort.Shape ((:+:)((:+:)))  import Foreign.C.Types (CInt, CChar)-import Foreign.ForeignPtr (withForeignPtr)+import Foreign.ForeignPtr (ForeignPtr, withForeignPtr) import Foreign.Ptr (Ptr) import Foreign.Storable (Storable, poke, peek) @@ -66,10 +80,11 @@ import Control.Monad.IO.Class (liftIO) import Control.Monad (when) -import qualified Data.NonEmpty as NonEmpty import Data.Foldable (forM_) +import Data.Function.HT (powerAssociative) + type Hermitian sh = Array (MatrixShape.Hermitian sh)  @@ -77,14 +92,26 @@ fromList order sh =    CheckedArray.fromList (MatrixShape.Hermitian order sh) -autoFromList :: (Storable a) => Order -> [a] -> Hermitian ZeroInt a+autoFromList :: (Storable a) => Order -> [a] -> Hermitian ShapeInt a autoFromList order xs =    fromList order-      (zeroInt $ MatrixShape.triangleExtent "Hermitian.autoFromList" $+      (shapeInt $ MatrixShape.triangleExtent "Hermitian.autoFromList" $        length xs)       xs +uncheck :: Hermitian sh a -> Hermitian (Unchecked sh) a+uncheck =+   Array.mapShape $+      \(MatrixShape.Hermitian order sh) ->+         MatrixShape.Hermitian order (Unchecked sh) +recheck :: Hermitian (Unchecked sh) a -> Hermitian sh a+recheck =+   Array.mapShape $+      \(MatrixShape.Hermitian order (Unchecked sh)) ->+         MatrixShape.Hermitian order sh++ identity :: (Shape.C sh, Class.Floating a) => Order -> sh -> Hermitian sh a identity order sh =    Array.unsafeCreateWithSize (MatrixShape.Hermitian order sh) $@@ -110,7 +137,7 @@    fill zero triSize aPtr    withForeignPtr x $ \xPtr ->       forM_ (diagonalPointerPairs order (Shape.size sh) xPtr aPtr) $-         \(srcPtr,dstPtr) -> poke dstPtr . fromReal =<< peek srcPtr+         \(srcPtr,dstPtr) -> poke (realPtr dstPtr) =<< peek srcPtr   takeDiagonal ::@@ -123,13 +150,13 @@       (TakeDiagonal takeDiagonalAux) (TakeDiagonal takeDiagonalAux)  takeDiagonalAux ::-   (Shape.C sh, Class.Floating a, RealOf a ~ ar, Storable ar) =>+   (Shape.C sh, Storable a, RealOf a ~ ar, Storable ar) =>    Hermitian sh a -> Vector sh ar takeDiagonalAux (Array (MatrixShape.Hermitian order sh) a) =    Array.unsafeCreateWithSize sh $ \n xPtr ->    withForeignPtr a $ \aPtr ->       forM_ (diagonalPointerPairs order n xPtr aPtr) $-         \(dstPtr,srcPtr) -> poke dstPtr . realPart =<< peek srcPtr+         \(dstPtr,srcPtr) -> poke dstPtr =<< peek (realPtr srcPtr)   {-@@ -149,27 +176,23 @@ fromUpperPart ::    (Extent.C vert, Shape.C height, Shape.C width, Class.Floating a) =>    Full vert Extent.Small height width a -> Hermitian width a-fromUpperPart (Array (MatrixShape.Full order extent) a) =-   let (height,width) = Extent.dimensions extent-       m = Shape.size height-       n = Shape.size width-       k = case order of RowMajor -> n; ColumnMajor -> m-   in Array.unsafeCreate (MatrixShape.Hermitian order width) $ \bPtr ->-      withForeignPtr a $ \aPtr -> packRect order n k aPtr bPtr+fromUpperPart = Triangular.fromUpperPart MatrixShape.Hermitian +{-+Naming is inconsistent to Triangular.takeUpper,+because here Hermitian is the input+and in Triangular.takeUpper, Triangular is the output.+-}+takeUpper ::+   (Shape.C sh, Class.Floating a) =>+   Hermitian sh a ->+   Array (MatrixShape.UpperTriangular MatrixShape.NonUnit sh) a+takeUpper =+   Array.mapShape+      (\(MatrixShape.Hermitian order sh) ->+         MatrixShape.Triangular MatrixShape.NonUnit MatrixShape.upper order sh) -{- |-> toSquare (stack a b c)->-> =->-> toSquare a ||| b-> ===-> adjoint b ||| toSquare c -It holds @order (stack a b c) = order b@.-The function is most efficient when the order of all blocks match.--} stack ::    (Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>    Hermitian sh0 a -> General sh0 sh1 a -> Hermitian sh1 a ->@@ -179,7 +202,29 @@    in Triangular.stack "Hermitian" (MatrixShape.Hermitian order)          (forceOrder order a) b (forceOrder order c) +takeTopLeft ::+   (Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Hermitian (sh0:+:sh1) a -> Hermitian sh0 a+takeTopLeft =+   Triangular.takeTopLeft+      (\(MatrixShape.Hermitian order sh@(sh0:+:_sh1)) ->+         (MatrixShape.Hermitian order sh0, (order,sh))) +takeTopRight ::+   (Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Hermitian (sh0:+:sh1) a -> General sh0 sh1 a+takeTopRight =+   Triangular.takeTopRight (\(MatrixShape.Hermitian order sh) -> (order,sh))++takeBottomRight ::+   (Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Hermitian (sh0:+:sh1) a -> Hermitian sh1 a+takeBottomRight =+   Triangular.takeBottomRight+      (\(MatrixShape.Hermitian order sh@(_sh0:+:sh1)) ->+         (MatrixShape.Hermitian order sh1, (order,sh)))++ multiplyVector ::    (Shape.C sh, Eq sh, Class.Floating a) =>    Transposition -> Hermitian sh a -> Vector sh a -> Vector sh a@@ -188,7 +233,7 @@       Array.unsafeCreateWithSize shX $ \n yPtr -> do    Call.assert "Hermitian.multiplyVector: width shapes mismatch" (shA == shX)    evalContT $ do-      let conj = transposeOrder transposed order == RowMajor+      let conj = conjugatedOnRowMajor $ transposeOrder transposed order       uploPtr <- Call.char $ uploFromOrder order       nPtr <- Call.cint n       alphaPtr <- Call.number one@@ -200,17 +245,28 @@       liftIO $ do          BlasGen.hpmv             uploPtr nPtr alphaPtr aPtr xPtr incxPtr betaPtr yPtr incyPtr-         when conj $ lacgv nPtr yPtr incyPtr+         condConjugate conj nPtr yPtr incyPtr  -square ::-   (Shape.C sh, Eq sh, Class.Floating a) =>-   Hermitian sh a -> Hermitian sh a+square :: (Shape.C sh, Class.Floating a) => Hermitian sh a -> Hermitian sh a square (Array shape@(MatrixShape.Hermitian order sh) a) =    Array.unsafeCreate shape $       Symmetric.square Conjugated order (Shape.size sh) a +{-+Requires frequent unpacking and packing of triangles.+-}+power ::+   (Shape.C sh, Class.Floating a) => Integer -> Hermitian sh a -> Hermitian sh a+power n a0@(Array (MatrixShape.Hermitian order sh) _) =+   recheck $+   powerAssociative+      (\a b -> fromUpperPart $ multiplyFull NonTransposed a $ toSquare b)+      (identity order $ Unchecked sh)+      (uncheck a0)+      n + multiplyFull ::    (Extent.C vert, Extent.C horiz,     Shape.C height, Eq height, Shape.C width,@@ -263,26 +319,15 @@    liftIO $ do       fill zero triSize aPtr       act uploPtr nPtr incxPtr-      case order of-         RowMajor -> lacgv sizePtr aPtr incxPtr-         ColumnMajor -> return ()+      condConjugate (conjugatedOnRowMajor order) sizePtr aPtr incxPtr  outer ::    (Shape.C sh, Class.Floating a) => Order -> Vector sh a -> Hermitian sh a-outer order =-   getMap $-   Class.switchFloating-      (Map $ outerAux order) (Map $ outerAux order)-      (Map $ outerAux order) (Map $ outerAux order)--outerAux ::-   (Shape.C sh, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Order -> Vector sh a -> Hermitian sh a-outerAux order (Array sh x) =+outer order (Array sh x) =    Array.unsafeCreateWithSize (MatrixShape.Hermitian order sh) $       \triSize aPtr ->    evalContT $ do-      alphaPtr <- Call.real one+      alphaPtr <- realOneArg aPtr       xPtr <- ContT $ withForeignPtr x       withConjBuffer order sh triSize aPtr $ \uploPtr nPtr incxPtr ->          hpr uploPtr nPtr alphaPtr xPtr incxPtr aPtr@@ -302,7 +347,7 @@ newtype SumRank1 sh a = SumRank1 {getSumRank1 :: SumRank1_ sh (RealOf a) a}  sumRank1Aux ::-   (Shape.C sh, Eq sh, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Shape.C sh, Eq sh, Class.Floating a, RealOf a ~ ar, Storable ar) =>    SumRank1_ sh ar a sumRank1Aux order sh xs =    Array.unsafeCreateWithSize (MatrixShape.Hermitian order sh) $@@ -318,13 +363,6 @@                hpr uploPtr nPtr alphaPtr xPtr incxPtr aPtr  -sumRank1NonEmpty ::-   (Shape.C sh, Eq sh, Class.Floating a) =>-   Order -> NonEmpty.T [] (RealOf a, Vector sh a) -> Hermitian sh a-sumRank1NonEmpty order (NonEmpty.Cons x xs) =-   sumRank1 order (Array.shape $ snd x) (x:xs)-- type HPR_ a =    Ptr CChar -> Ptr CInt ->    Ptr (RealOf a) -> Ptr a -> Ptr CInt -> Ptr a -> IO ()@@ -358,13 +396,7 @@                poke alphaPtr alpha                BlasGen.hpr2 uploPtr nPtr alphaPtr xPtr incPtr yPtr incPtr aPtr -sumRank2NonEmpty ::-   (Shape.C sh, Eq sh, Class.Floating a) =>-   Order -> NonEmpty.T [] (a, (Vector sh a, Vector sh a)) -> Hermitian sh a-sumRank2NonEmpty order (NonEmpty.Cons xy xys) =-   sumRank2 order (Array.shape $ fst $ snd xy) (xy:xys) - {- It is not strictly necessary to keep the 'order'. It would be neither more complicated nor less efficient@@ -388,56 +420,85 @@       Symmetric.unpack Conjugated order (Shape.size sh) aPtr bPtr  -{- |-A^H * A--}-covariance ::-   (Shape.C height, Shape.C width, Eq width, Class.Floating a) =>+gramian ::+   (Shape.C height, Shape.C width, Class.Floating a) =>    General height width a -> Hermitian width a-covariance =-   getMap $-   Class.switchFloating-      (Map covarianceAux) (Map covarianceAux)-      (Map covarianceAux) (Map covarianceAux)+gramian (Array (MatrixShape.Full order extent) a) =+   Array.unsafeCreate (MatrixShape.Hermitian order $ Extent.width extent) $+   \bPtr -> gramianIO order a bPtr $ gramianParameters order extent -newtype Map f g a = Map {getMap :: f a -> g a}+gramianParameters ::+   (Extent.C horiz, Extent.C vert, Shape.C height, Shape.C width) =>+   Order ->+   Extent.Extent vert horiz height width ->+   ((Int, Int), (Char, Char, Int))+gramianParameters order extent =+   let (height, width) = Extent.dimensions extent+       n = Shape.size width+       k = Shape.size height+    in ((n,k),+         case order of+            ColumnMajor -> ('U', 'C', k)+            RowMajor -> ('L', 'N', n)) -covarianceAux ::-   (Shape.C height, Shape.C width, Eq width,-    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   General height width a -> Hermitian width a-covarianceAux = argGeneral $ \order height width a ->-   Array.unsafeCreate (MatrixShape.Hermitian order width) $ \bPtr -> do -   let n = Shape.size width-   let k = Shape.size height+gramianAdjoint ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   General height width a -> Hermitian height a+gramianAdjoint (Array (MatrixShape.Full order extent) a) =+   Array.unsafeCreate (MatrixShape.Hermitian order $ Extent.height extent) $+   \bPtr -> gramianIO order a bPtr $ gramianAdjointParameters order extent++gramianAdjointParameters ::+   (Extent.C horiz, Extent.C vert, Shape.C height, Shape.C width) =>+   Order ->+   Extent.Extent vert horiz height width ->+   ((Int, Int), (Char, Char, Int))+gramianAdjointParameters order extent =+   let (height, width) = Extent.dimensions extent+       n = Shape.size height+       k = Shape.size width+   in ((n,k),+         case order of+            ColumnMajor -> ('U', 'N', n)+            RowMajor -> ('L', 'C', k))++{-+Another way to unify 'gramian' and 'gramianAdjoint'+would have been this function:++> gramianConjugation ::+>    Conjugation -> General height width a -> Hermitian width a++with++> gramianAdjoint a = gramianConjugation (transpose a)++but I would like to have++> order (gramianAdjoint a) = order a+-}+gramianIO ::+   (Class.Floating a) =>+   Order ->+   ForeignPtr a -> Ptr a ->+   ((Int, Int), (Char, Char, Int)) -> IO ()+gramianIO order a bPtr ((n,k), (uplo,trans,lda)) =    evalContT $ do+      uploPtr <- Call.char uplo+      transPtr <- Call.char trans       nPtr <- Call.cint n       kPtr <- Call.cint k-      alphaPtr <- Call.number one+      alphaPtr <- realOneArg a       aPtr <- ContT $ withForeignPtr a-      betaPtr <- Call.number zero+      ldaPtr <- Call.leadingDim lda+      betaPtr <- realZeroArg a       cPtr <- Call.allocaArray (n*n)       ldcPtr <- Call.leadingDim n--      case order of-         ColumnMajor -> do-            uploPtr <- Call.char 'U'-            transPtr <- Call.char 'C'-            ldaPtr <- Call.leadingDim k-            liftIO $ do-               herk uploPtr transPtr-                  nPtr kPtr alphaPtr aPtr ldaPtr betaPtr cPtr ldcPtr-               pack ColumnMajor n cPtr bPtr--         RowMajor -> do-            uploPtr <- Call.char 'L'-            transPtr <- Call.char 'N'-            ldaPtr <- Call.leadingDim n-            liftIO $ do-               herk uploPtr transPtr-                  nPtr kPtr alphaPtr aPtr ldaPtr betaPtr cPtr ldcPtr-               pack RowMajor n cPtr bPtr+      liftIO $ do+         herk uploPtr transPtr+            nPtr kPtr alphaPtr aPtr ldaPtr betaPtr cPtr ldcPtr+         pack order n cPtr bPtr   type HERK_ a =@@ -456,9 +517,142 @@       (HERK BlasComplex.herk)  +skipCheckCongruence ::+   ((sh -> Unchecked sh) -> matrix0 -> matrix1) ->+   (matrix1 -> Hermitian (Unchecked sh) a) -> matrix0 -> Hermitian sh a+skipCheckCongruence mapSize f a =+   recheck $ f $ mapSize Unchecked a+++congruenceDiagonal ::+   (Shape.C height, Eq height, Shape.C width, Class.Floating a) =>+   Vector height (RealOf a) -> General height width a -> Hermitian width a+congruenceDiagonal d =+   skipCheckCongruence Basic.mapWidth $ \a ->+      scaledAnticommutator 0.5 a $ Basic.scaleRowsReal d a++congruenceDiagonalAdjoint ::+   (Shape.C height, Shape.C width, Eq width, Class.Floating a) =>+   General height width a -> Vector width (RealOf a) -> Hermitian height a+congruenceDiagonalAdjoint =+   flip $ \d -> skipCheckCongruence Basic.mapHeight $ \a ->+      scaledAnticommutatorAdjoint 0.5 a $ Basic.scaleColumnsReal d a+++congruence ::+   (Shape.C height, Eq height, Shape.C width, Class.Floating a) =>+   Hermitian height a -> General height width a -> Hermitian width a+congruence b =+   skipCheckCongruence Basic.mapWidth $ \a ->+      scaledAnticommutator one a $+      Split.tallMultiplyR NonTransposed (takeHalf b) a++congruenceAdjoint ::+   (Shape.C height, Shape.C width, Eq width, Class.Floating a) =>+   General height width a -> Hermitian width a -> Hermitian height a+congruenceAdjoint =+   flip $ \b -> skipCheckCongruence Basic.mapHeight $ \a ->+      scaledAnticommutatorAdjoint one a $+      Basic.swapMultiply (Split.tallMultiplyR Transposed) a (takeHalf b)+++data Corrupt = Corrupt+   deriving (Eq)+ {- |-A^H + A+> let b = takeHalf a+> ==>+> isTriangular b && a == addAdjoint b -}+takeHalf ::+   (Shape.C sh, Class.Floating a) =>+   Hermitian sh a -> Split.Square Corrupt sh a+takeHalf (Array (MatrixShape.Hermitian order sh) a) =+   Array.unsafeCreate (MatrixShape.Split Corrupt order (Extent.square sh)) $+      \bPtr -> evalContT $ do+   let n = Shape.size sh+   aPtr <- ContT $ withForeignPtr a+   nPtr <- Call.cint n+   alphaPtr <- Call.number 0.5+   incxPtr <- Call.cint (n+1)+   liftIO $ do+      unpack order n aPtr bPtr+      BlasGen.scal nPtr alphaPtr bPtr incxPtr+++scaledAnticommutator ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+   a ->+   Full vert horiz height width a ->+   Full vert horiz height width a -> Hermitian width a+scaledAnticommutator alpha arr (Array (MatrixShape.Full order extentB) b) = do+   let (Array (MatrixShape.Full _ extentA) a) = Basic.forceOrder order arr+   Array.unsafeCreate (MatrixShape.Hermitian order $ Extent.width extentB) $+         \cpPtr -> do+      Call.assert "Hermitian.anticommutator: extents mismatch"+         (extentA==extentB)+      scaledAnticommutatorIO alpha order a b cpPtr $+         gramianParameters order extentB++scaledAnticommutatorAdjoint ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+   a ->+   Full vert horiz height width a ->+   Full vert horiz height width a -> Hermitian height a+scaledAnticommutatorAdjoint+      alpha arr (Array (MatrixShape.Full order extentB) b) = do+   let (Array (MatrixShape.Full _ extentA) a) = Basic.forceOrder order arr+   Array.unsafeCreate (MatrixShape.Hermitian order $ Extent.height extentB) $+         \cpPtr -> do+      Call.assert "Hermitian.anticommutatorAdjoint: extents mismatch"+         (extentA==extentB)+      scaledAnticommutatorIO alpha order a b cpPtr $+         gramianAdjointParameters order extentB++scaledAnticommutatorIO ::+   (Class.Floating a) =>+   a ->+   Order -> ForeignPtr a -> ForeignPtr a -> Ptr a ->+   ((Int, Int), (Char, Char, Int)) -> IO ()+scaledAnticommutatorIO alpha order a b cpPtr ((n,k), (uplo,trans,lda)) =+   evalContT $ do+      uploPtr <- Call.char uplo+      transPtr <- Call.char trans+      nPtr <- Call.cint n+      kPtr <- Call.cint k+      alphaPtr <- Call.number alpha+      aPtr <- ContT $ withForeignPtr a+      ldaPtr <- Call.leadingDim lda+      bPtr <- ContT $ withForeignPtr b+      let ldbPtr = ldaPtr+      betaPtr <- realZeroArg aPtr+      cPtr <- Call.allocaArray (n*n)+      ldcPtr <- Call.leadingDim n+      liftIO $ do+         her2k uploPtr transPtr nPtr kPtr alphaPtr+            aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr+         pack order n cPtr cpPtr+++type HER2K_ a =+   Ptr CChar -> Ptr CChar -> Ptr CInt -> Ptr CInt -> Ptr a ->+   Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt ->+   Ptr (RealOf a) -> Ptr a -> Ptr CInt -> IO ()++newtype HER2K a = HER2K {getHER2K :: HER2K_ a}++her2k :: Class.Floating a => HER2K_ a+her2k =+   getHER2K $+   Class.switchFloating+      (HER2K BlasReal.syr2k)+      (HER2K BlasReal.syr2k)+      (HER2K BlasComplex.her2k)+      (HER2K BlasComplex.her2k)++ addAdjoint, _addAdjoint ::    (Shape.C sh, Class.Floating a) => Square sh a -> Hermitian sh a _addAdjoint =@@ -513,3 +707,23 @@                forPointers (rowMajorPointers n fullPtr packedPtr) $                   \nPtr (srcPtr,dstPtr) ->                      BlasGen.copy nPtr srcPtr incxPtr dstPtr incxPtr+++realZeroArg, realOneArg ::+   (Class.Floating a) => f a -> ContT r IO (Ptr (RealOf a))+realZeroArg =+   runRealArg $+   Class.switchFloating+      (RealArg $ const $ Call.number zero)+      (RealArg $ const $ Call.number zero)+      (RealArg $ const $ Call.number zero)+      (RealArg $ const $ Call.number zero)+realOneArg =+   runRealArg $+   Class.switchFloating+      (RealArg $ const $ Call.number one)+      (RealArg $ const $ Call.number one)+      (RealArg $ const $ Call.number one)+      (RealArg $ const $ Call.number one)++newtype RealArg f g a = RealArg {runRealArg :: f a -> g (Ptr (RealOf a))}
src/Numeric/LAPACK/Matrix/Hermitian/Eigen.hs view
@@ -4,13 +4,12 @@    decompose,    ) where -import Numeric.LAPACK.Matrix.Hermitian.Basic (Hermitian)-import Numeric.LAPACK.Matrix.Square.Basic (Square)- import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import Numeric.LAPACK.Matrix.Hermitian.Basic (Hermitian) import Numeric.LAPACK.Matrix.Hermitian.Private (TakeDiagonal(..))-import Numeric.LAPACK.Matrix.Shape.Private-         (Order(RowMajor,ColumnMajor), uploFromOrder)+import Numeric.LAPACK.Matrix.Square.Basic (Square)+import Numeric.LAPACK.Matrix.Shape.Private (Order(ColumnMajor), uploFromOrder)+import Numeric.LAPACK.Matrix.Modifier (conjugatedOnRowMajor) import Numeric.LAPACK.Vector (Vector) import Numeric.LAPACK.Scalar (RealOf) import Numeric.LAPACK.Private@@ -84,7 +83,8 @@    evalContT $ do       jobzPtr <- Call.char 'V'       uploPtr <- Call.char $ uploFromOrder order-      aPtr <- copyCondConjugateToTemp (order==RowMajor) (triangleSize n) a+      aPtr <-+         copyCondConjugateToTemp (conjugatedOnRowMajor order) (triangleSize n) a       ldzPtr <- Call.leadingDim n       liftIO $ withInfo eigenMsg "hpev" $          hpev jobzPtr uploPtr n aPtr wPtr zPtr ldzPtr
src/Numeric/LAPACK/Matrix/Hermitian/Linear.hs view
@@ -5,15 +5,15 @@    determinant,    ) where -import Numeric.LAPACK.Matrix.Hermitian.Basic (Hermitian)-import Numeric.LAPACK.Matrix.Private (Full)- import qualified Numeric.LAPACK.Matrix.Symmetric.Private as Symmetric import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import Numeric.LAPACK.Matrix.Hermitian.Basic (Hermitian) import Numeric.LAPACK.Matrix.Hermitian.Private (Determinant(..))-import Numeric.LAPACK.Matrix.Private (Conjugation(Conjugated))+import Numeric.LAPACK.Matrix.Modifier (Conjugation(Conjugated))+import Numeric.LAPACK.Matrix.Private (Full) import Numeric.LAPACK.Scalar (RealOf, absoluteSquared)+import Numeric.LAPACK.Private (realPtr)  import qualified Numeric.Netlib.Class as Class @@ -23,28 +23,25 @@  import System.IO.Unsafe (unsafePerformIO) -import Foreign.Ptr (Ptr, castPtr)+import Foreign.Ptr (Ptr) import Foreign.Storable (peek)   solve ::    (Extent.C vert, Extent.C horiz,     Shape.C sh, Eq sh, Shape.C nrhs, Class.Floating a) =>-   Hermitian sh a ->-   Full vert horiz sh nrhs a -> Full vert horiz sh nrhs a+   Hermitian sh a -> Full vert horiz sh nrhs a -> Full vert horiz sh nrhs a solve (Array (MatrixShape.Hermitian orderA shA) a) =    Symmetric.solve "Hermitian.solve" Conjugated orderA shA a  -inverse ::-   (Shape.C sh, Class.Floating a) => Hermitian sh a -> Hermitian sh a+inverse :: (Shape.C sh, Class.Floating a) => Hermitian sh a -> Hermitian sh a inverse (Array shape@(MatrixShape.Hermitian order sh) a) =    Array.unsafeCreateWithSize shape $       Symmetric.inverse Conjugated order (Shape.size sh) a  -determinant ::-   (Shape.C sh, Class.Floating a) => Hermitian sh a -> RealOf a+determinant :: (Shape.C sh, Class.Floating a) => Hermitian sh a -> RealOf a determinant =    getDeterminant $    Class.switchFloating@@ -63,7 +60,7 @@    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    (Ptr a, Maybe (Ptr a, Ptr a)) -> IO ar peekBlockDeterminant (a0Ptr,ext) = do-   let peekReal = peek . castPtr+   let peekReal = peek . realPtr    a0 <- peekReal a0Ptr    case ext of       Nothing -> return a0
src/Numeric/LAPACK/Matrix/Hermitian/Private.hs view
@@ -1,14 +1,12 @@ {-# LANGUAGE TypeFamilies #-} module Numeric.LAPACK.Matrix.Hermitian.Private where -import Numeric.LAPACK.Vector (Vector) import Numeric.LAPACK.Scalar (RealOf)  -newtype Diagonal f sh a =-   Diagonal {runDiagonal :: Vector sh (RealOf a) -> f a}+newtype Diagonal f g a = Diagonal {runDiagonal :: g (RealOf a) -> f a} -newtype TakeDiagonal f sh a =-   TakeDiagonal {runTakeDiagonal :: f a -> Vector sh (RealOf a)}+newtype TakeDiagonal f g a =+   TakeDiagonal {runTakeDiagonal :: f a -> g (RealOf a)}  newtype Determinant f a = Determinant {getDeterminant :: f a -> RealOf a}
src/Numeric/LAPACK/Matrix/HermitianPositiveDefinite.hs view
@@ -1,5 +1,48 @@ module Numeric.LAPACK.Matrix.HermitianPositiveDefinite (-   module Numeric.LAPACK.Matrix.HermitianPositiveDefinite.Linear,+   solve,+   solveDecomposed,+   inverse,+   decompose,+   determinant,    ) where -import Numeric.LAPACK.Matrix.HermitianPositiveDefinite.Linear+import qualified Numeric.LAPACK.Matrix.HermitianPositiveDefinite.Linear+                                                                  as Linear+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Extent as Extent+import Numeric.LAPACK.Matrix.Array.Triangular (Hermitian, Upper)+import Numeric.LAPACK.Matrix.Array (Full)+import Numeric.LAPACK.Scalar (RealOf)++import qualified Numeric.Netlib.Class as Class++import qualified Data.Array.Comfort.Shape as Shape+++solve ::+   (Extent.C vert, Extent.C horiz,+    Shape.C sh, Eq sh, Shape.C nrhs, Class.Floating a) =>+   Hermitian sh a -> Full vert horiz sh nrhs a -> Full vert horiz sh nrhs a+solve = ArrMatrix.lift2 Linear.solve++{- |+> solve a b == solveDecomposed (decompose a) b+> solve (gramian u) b == solveDecomposed u b+-}+solveDecomposed ::+   (Extent.C vert, Extent.C horiz,+    Shape.C sh, Eq sh, Shape.C nrhs, Class.Floating a) =>+   Upper sh a -> Full vert horiz sh nrhs a -> Full vert horiz sh nrhs a+solveDecomposed = ArrMatrix.lift2 Linear.solveDecomposed++inverse :: (Shape.C sh, Class.Floating a) => Hermitian sh a -> Hermitian sh a+inverse = ArrMatrix.lift1 Linear.inverse++{- |+Cholesky decomposition+-}+decompose :: (Shape.C sh, Class.Floating a) => Hermitian sh a -> Upper sh a+decompose = ArrMatrix.lift1 Linear.decompose++determinant :: (Shape.C sh, Class.Floating a) => Hermitian sh a -> RealOf a+determinant = Linear.determinant . ArrMatrix.toVector
src/Numeric/LAPACK/Matrix/HermitianPositiveDefinite/Linear.hs view
@@ -7,16 +7,15 @@    determinant,    ) where -import Numeric.LAPACK.Matrix.Hermitian.Basic (Hermitian)-import Numeric.LAPACK.Matrix.Triangular.Basic (Upper, takeDiagonal)-import Numeric.LAPACK.Matrix.Private (Full)- import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import Numeric.LAPACK.Matrix.Hermitian.Basic (Hermitian) import Numeric.LAPACK.Matrix.Hermitian.Private (Determinant(..))+import Numeric.LAPACK.Matrix.Triangular.Basic (Upper, takeDiagonal) import Numeric.LAPACK.Matrix.Triangular.Private (copyTriangleToTemp) import Numeric.LAPACK.Matrix.Shape.Private (NonUnit(NonUnit), uploFromOrder)-import Numeric.LAPACK.Matrix.Private (Conjugation(Conjugated))+import Numeric.LAPACK.Matrix.Modifier (Conjugation(Conjugated))+import Numeric.LAPACK.Matrix.Private (Full) import Numeric.LAPACK.Linear.Private (solver) import Numeric.LAPACK.Scalar (RealOf, realPart) import Numeric.LAPACK.Private (copyBlock, withInfo, rankMsg, definiteMsg)@@ -49,10 +48,6 @@          withInfo definiteMsg "ppsv" $             LapackGen.ppsv uploPtr nPtr nrhsPtr apPtr xPtr ldxPtr -{- |-> solve a b == solveDecomposed (decompose a) b-> solve (covariance u) b == solveDecomposed u b--} solveDecomposed ::    (Extent.C vert, Extent.C horiz,     Shape.C sh, Eq sh, Shape.C nrhs, Class.Floating a) =>@@ -80,9 +75,6 @@          withInfo definiteMsg "pptrf" $ LapackGen.pptrf uploPtr nPtr bPtr          withInfo rankMsg "pptri" $ LapackGen.pptri uploPtr nPtr bPtr -{- |-Cholesky decomposition--} decompose ::    (Shape.C sh, Class.Floating a) => Hermitian sh a -> Upper sh a decompose@@ -111,4 +103,5 @@    (Shape.C sh, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    Hermitian sh a -> ar determinantAux =-   (^(2::Int)) . product . map realPart . Array.toList . takeDiagonal . decompose+   (^(2::Int)) . product . map realPart .+   Array.toList . takeDiagonal . decompose
src/Numeric/LAPACK/Matrix/Indexed.hs view
@@ -1,86 +1,38 @@ {-# LANGUAGE TypeFamilies #-} module Numeric.LAPACK.Matrix.Indexed 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 Numeric.LAPACK.Scalar (conjugate, zero)+import qualified Numeric.LAPACK.Matrix.Plain.Indexed as ArrIndexed+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Type as Type+import qualified Numeric.LAPACK.Permutation as Perm+import Numeric.LAPACK.Matrix.Type (Matrix)+import Numeric.LAPACK.Scalar (one, zero)+import Numeric.LAPACK.Permutation.Private (Permutation(Permutation))  import qualified Numeric.Netlib.Class as Class -import qualified Type.Data.Num.Unary as Unary- import qualified Data.Array.Comfort.Storable.Unchecked as UArray import qualified Data.Array.Comfort.Shape as Shape-import Data.Array.Comfort.Storable (Array, (!))--import Data.Tuple.HT (swap)-import Data.Bool.HT (if')+import Data.Array.Comfort.Storable ((!))   infixl 9 #! -class (Box.Box sh) => Indexed sh where+class (Type.Box typ) => Indexed typ where    (#!) ::       (Class.Floating a) =>-      Array sh a ->-      (Shape.Index (Box.HeightOf sh), Shape.Index (Box.WidthOf sh)) -> a--instance-   (Extent.C vert, Extent.C horiz, Shape.Indexed height, Shape.Indexed width) =>-      Indexed (MatrixShape.Full vert horiz height width) where-   (#!) = (!)--instance (Shape.Indexed size) => Indexed (MatrixShape.Hermitian size) where-   arr#!ij =-      if Shape.inBounds (UArray.shape arr) ij-         then arr UArray.! ij-         else conjugate $ arr ! swap ij--instance-   (MatrixShape.Content lo, MatrixShape.TriDiag diag, MatrixShape.Content up,-    Shape.Indexed size) =>-      Indexed (MatrixShape.Triangular lo diag up size) where-   arr#!ij =-      let sh = UArray.shape arr-      in if Shape.inBounds sh ij-            then arr UArray.! ij-            else-               MatrixShape.caseDiagUpLoSym (MatrixShape.triangularUplo sh)-                  (checkedZero "Diagonal" sh ij)-                  (checkedZero "UpperTriangular" sh ij)-                  (checkedZero "LowerTriangular" sh ij)-                  (arr ! swap ij)+      Matrix typ a ->+      (Shape.Index (Type.HeightOf typ), Shape.Index (Type.WidthOf typ)) -> a -instance-   (Unary.Natural sub, Unary.Natural super,-    Extent.C vert, Extent.C horiz, Shape.Indexed height, Shape.Indexed width) =>-      Indexed (MatrixShape.Banded sub super vert horiz height width) where-   arr#!ij =-      let boxIx = uncurry MatrixShape.InsideBox-          sh = UArray.shape arr-      in if Shape.inBounds sh $ boxIx ij-            then arr UArray.! boxIx ij-            else checkedZero "Banded" sh ij+instance (ArrIndexed.Indexed sh) => Indexed (ArrMatrix.Array sh) where+   ArrMatrix.Array arr #! ij = arr ArrIndexed.#! ij -instance-   (Unary.Natural off, Shape.Indexed size) =>-      Indexed (MatrixShape.BandedHermitian off size) where-   arr#!ij =-      let boxIx = uncurry MatrixShape.InsideBox-          sh = UArray.shape arr-      in if' (Shape.inBounds sh $ boxIx ij)-            (arr UArray.! boxIx ij) $-         if' (Shape.inBounds sh $ boxIx $ swap ij)-            (conjugate $ arr UArray.! boxIx (swap ij))-         (checkedZero "BandedHermitian" sh ij)+instance (Shape.Indexed size) => Indexed (Type.Scale size) where+   Type.Scale sh a #! (i,j) =+      if Shape.offset sh i == Shape.offset sh j then a else zero -checkedZero ::-   (Box.Box shape, Class.Floating a,-    Box.HeightOf shape ~ height, Shape.Indexed height,-    Box.WidthOf shape ~ width, Shape.Indexed width) =>-   String -> shape -> (Shape.Index height, Shape.Index width) -> a-checkedZero name sh ij =-   if Shape.inBounds (Box.height sh, Box.width sh) ij-      then zero-      else error $ "Matrix.Indexed." ++ name ++ ": index out of range"+instance (Shape.Indexed size) => Indexed (Permutation size) where+   Type.Permutation (Permutation perm) #! (i,j) =+      let psh@(Perm.Shape sh) = UArray.shape perm+          reindex = Shape.indexFromOffset psh . Shape.offset sh+      in if perm ! reindex i == reindex j then one else zero
+ src/Numeric/LAPACK/Matrix/Inverse.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE EmptyDataDecls #-}+module Numeric.LAPACK.Matrix.Inverse where++import qualified Numeric.LAPACK.Matrix.Type as Type+import qualified Numeric.LAPACK.Matrix.Class as MatrixClass+import qualified Numeric.LAPACK.Matrix.Divide as Divide+import qualified Numeric.LAPACK.Matrix.Multiply as Multiply+import Numeric.LAPACK.Matrix.Divide ((#\|), (-/#))+++data Inverse typ+newtype instance Type.Matrix (Inverse typ) a = Inverse (Type.Matrix typ a)+++instance (Type.MultiplySame typ) => Type.MultiplySame (Inverse typ) where+   multiplySame (Inverse a) (Inverse b) = Inverse $ Type.multiplySame b a++instance (Type.Box typ) => Type.Box (Inverse typ) where+   type HeightOf (Inverse typ) = Type.HeightOf typ+   type WidthOf (Inverse typ) = Type.WidthOf typ+   height (Inverse m) = Type.height m+   width (Inverse m) = Type.width m++instance (MatrixClass.Complex typ) => MatrixClass.Complex (Inverse typ) where+   conjugate (Inverse m) = Inverse $ MatrixClass.conjugate m+   fromReal (Inverse m) = Inverse $ MatrixClass.fromReal m+   toComplex (Inverse m) = Inverse $ MatrixClass.toComplex m+++instance (Divide.Solve typ) => Multiply.MultiplyVector (Inverse typ) where+   matrixVector (Inverse a) x = a#\|x+   vectorMatrix x (Inverse a) = x-/#a++instance (Divide.Solve typ) => Multiply.MultiplySquare (Inverse typ) where+   transposableSquare trans (Inverse a) b = Divide.solve trans a b+   squareFull (Inverse a) b = Divide.solveRight a b+   fullSquare b (Inverse a) = Divide.solveLeft b a++instance (Multiply.Power typ) => Multiply.Power (Inverse typ) where+   square (Inverse a) = Inverse $ Multiply.square a+   power n (Inverse a) = Inverse $ Multiply.power n a+++instance (Divide.Determinant typ) => Divide.Determinant (Inverse typ) where+   determinant (Inverse a) = recip $ Divide.determinant a++instance (Multiply.MultiplySquare typ) => Divide.Solve (Inverse typ) where+   solve trans (Inverse a) b = Multiply.transposableSquare trans a b+   solveRight (Inverse a) b = Multiply.squareFull a b+   solveLeft b (Inverse a) = Multiply.fullSquare b a++instance+   (Divide.Inverse typ, Multiply.MultiplySquare typ) =>+      Divide.Inverse (Inverse typ) where+   inverse (Inverse a) = Inverse $ Divide.inverse a
+ src/Numeric/LAPACK/Matrix/Modifier.hs view
@@ -0,0 +1,49 @@+module Numeric.LAPACK.Matrix.Modifier where++import Numeric.LAPACK.Matrix.Shape.Private+         (Order(RowMajor,ColumnMajor), flipOrder)++import Data.Monoid (Monoid, mempty, mappend)+import Data.Semigroup (Semigroup, (<>))++++data Transposition = NonTransposed | Transposed+   deriving (Eq, Show, Enum, Bounded)++instance Semigroup Transposition where+   x<>y = if x==y then NonTransposed else Transposed++instance Monoid Transposition where+   mempty = NonTransposed+   mappend = (<>)++transposeOrder :: Transposition -> Order -> Order+transposeOrder NonTransposed = id+transposeOrder Transposed = flipOrder+++data Conjugation = NonConjugated | Conjugated+   deriving (Eq, Show, Enum, Bounded)++instance Semigroup Conjugation where+   x<>y = if x==y then NonConjugated else Conjugated++instance Monoid Conjugation where+   mempty = NonConjugated+   mappend = (<>)++conjugatedOnRowMajor :: Order -> Conjugation+conjugatedOnRowMajor RowMajor = Conjugated+conjugatedOnRowMajor ColumnMajor = NonConjugated+++data Inversion = NonInverted | Inverted+   deriving (Eq, Show, Enum, Bounded)++instance Semigroup Inversion where+   x<>y = if x==y then NonInverted else Inverted++instance Monoid Inversion where+   mempty = NonInverted+   mappend = (<>)
src/Numeric/LAPACK/Matrix/Multiply.hs view
@@ -1,623 +1,206 @@ {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE UndecidableInstances #-} module Numeric.LAPACK.Matrix.Multiply where -import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Plain.Multiply as ArrMultiply+import qualified Numeric.LAPACK.Matrix.Array.Basic as Basic+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Permutation as PermMatrix+import qualified Numeric.LAPACK.Matrix.Type as Type+import qualified Numeric.LAPACK.Matrix.Modifier as Mod import qualified Numeric.LAPACK.Matrix.Shape.Box as Box-import qualified Numeric.LAPACK.Matrix.Extent.Private as ExtentPriv 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.Private as Private-import Numeric.LAPACK.Matrix.Shape.Private-         (Empty, Filled, Unit, NonUnit,-          Order(RowMajor,ColumnMajor), flipOrder, transposeFromOrder)-import Numeric.LAPACK.Matrix.Extent.Private (Small)-import Numeric.LAPACK.Matrix.Triangular.Basic (Triangular)-import Numeric.LAPACK.Matrix.Basic (transpose)-import Numeric.LAPACK.Matrix.Private-         (Square, Full, mapExtent,-          Transposition(NonTransposed, Transposed))+import qualified Numeric.LAPACK.Permutation.Private as Perm+import qualified Numeric.LAPACK.Vector as Vector+import Numeric.LAPACK.Matrix.Array (Full)+import Numeric.LAPACK.Matrix.Type (Matrix, scaleWithCheck)+import Numeric.LAPACK.Matrix.Modifier (Transposition(NonTransposed,Transposed)) import Numeric.LAPACK.Vector (Vector)-import Numeric.LAPACK.Scalar (zero, one) -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.Unary ((:+:))--import qualified Data.Array.Comfort.Storable.Unchecked as Array+import qualified Data.Array.Comfort.Storable 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) --multiplyVector ::-   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width, Eq width,-    Class.Floating a) =>-   Full vert horiz height width a -> Vector width a -> Vector height a-multiplyVector a x =-   let width = MatrixShape.fullWidth $ Array.shape a-   in if width == Array.shape x-         then multiplyVectorUnchecked a x-         else error "multiplyVector: width shapes mismatch"+infixl 7 -*#+infixr 7 #*| -multiplyVectorUnchecked ::-   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+(#*|) ::+   (MultiplyVector typ, Type.WidthOf typ ~ width, Eq width,     Class.Floating a) =>-   Full vert horiz height width a -> Vector width a -> Vector height a-multiplyVectorUnchecked-   (Array shape@(MatrixShape.Full order extent) a) (Array _ x) =-      Array.unsafeCreate (Extent.height extent) $ \yPtr -> do-   let (m,n) = MatrixShape.dimensions shape-   let lda = m-   evalContT $ do-      transPtr <- Call.char $ transposeFromOrder order-      mPtr <- Call.cint m-      nPtr <- Call.cint n-      alphaPtr <- Call.number one-      aPtr <- ContT $ withForeignPtr a-      ldaPtr <- Call.leadingDim lda-      xPtr <- ContT $ withForeignPtr x-      incxPtr <- Call.cint 1-      betaPtr <- Call.number zero-      incyPtr <- Call.cint 1-      liftIO $-         Private.gemv-            transPtr mPtr nPtr alphaPtr aPtr ldaPtr-            xPtr incxPtr betaPtr yPtr incyPtr+   Matrix typ a -> Vector width a -> Vector (Type.HeightOf typ) a+(#*|) = matrixVector -{- |-Multiply two matrices with the same dimension constraints.-E.g. you can multiply 'General' and 'General' matrices,-or 'Square' and 'Square' matrices.-It may seem to be overly strict in this respect,-but that design supports type inference the best.-You can lift the restrictions by generalizing operands-with 'Square.toFull', 'Matrix.fromFull',-'Matrix.generalizeTall' or 'Matrix.generalizeWide'.--}-multiply, multiplyColumnMajor ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height,-    Shape.C fuse, Eq fuse,-    Shape.C width,+(-*#) ::+   (MultiplyVector typ, Type.HeightOf typ ~ height, Eq height,     Class.Floating a) =>-   Full vert horiz height fuse a ->-   Full vert horiz fuse width a ->-   Full vert horiz height width a--- preserve order of the right factor-multiply-   (Array (MatrixShape.Full orderA extentA) a)-   (Array (MatrixShape.Full orderB extentB) b) =-   case Extent.fuse extentA extentB of-      Nothing -> error "multiply: fuse shapes mismatch"-      Just extent ->-         Array.unsafeCreate (MatrixShape.Full orderB extent) $ \cPtr -> do--      let (height,fuse) = Extent.dimensions extentA-      let width = Extent.width extentB-      let m = Shape.size height-      let n = Shape.size width-      let k = Shape.size fuse-      case orderB of-         RowMajor ->-            Private.multiplyMatrix (flipOrder orderB) (flipOrder orderA)-               n k m b a cPtr-         ColumnMajor -> Private.multiplyMatrix orderA orderB m k n a b cPtr---- always return ColumnMajor-multiplyColumnMajor-   (Array (MatrixShape.Full orderA extentA) a)-   (Array (MatrixShape.Full orderB extentB) b) =-   case Extent.fuse extentA extentB of-      Nothing -> error "multiply: fuse shapes mismatch"-      Just extent ->-         Array.unsafeCreate (MatrixShape.Full ColumnMajor extent) $ \cPtr -> do--      let (height,fuse) = Extent.dimensions extentA-      let width = Extent.width extentB-      let m = Shape.size height-      let n = Shape.size width-      let k = Shape.size fuse-      Private.multiplyMatrix orderA orderB m k n a b cPtr+   Vector height a -> Matrix typ a -> Vector (Type.WidthOf typ) a+(-*#) = vectorMatrix  -infixl 7 <#, <#>-infixr 7 #>--class (Shape.C shape) => MultiplyRight shape where-   (#>) ::-      (Class.Floating a) =>-      Array shape a ->-      Vector (Box.WidthOf shape) a ->-      Vector (Box.HeightOf shape) a+class (Type.Box typ) => MultiplyVector typ where+   matrixVector ::+      (Type.WidthOf typ ~ width, Eq width, Class.Floating a) =>+      Matrix typ a -> Vector width a -> Vector (Type.HeightOf typ) a+   vectorMatrix ::+      (Type.HeightOf typ ~ height, Eq height, Class.Floating a) =>+      Vector height a -> Matrix typ a -> Vector (Type.WidthOf typ) a -class (Shape.C shape) => MultiplyLeft shape where-   (<#) ::-      (Class.Floating a) =>-      Vector (Box.HeightOf shape) a ->-      Array shape a ->-      Vector (Box.WidthOf shape) a+instance (Shape.C shape) => MultiplyVector (Type.Scale shape) where+   matrixVector =+      scaleWithCheck "Matrix.Multiply.matrixVector Scale"+         Array.shape Vector.scale+   vectorMatrix =+      flip $+      scaleWithCheck "Matrix.Multiply.vectorMatrix Scale"+         Array.shape Vector.scale +instance (Shape.C shape) => MultiplyVector (PermMatrix.Permutation shape) where+   matrixVector = PermMatrix.multiplyVector Mod.NonInverted+   vectorMatrix = flip $ PermMatrix.multiplyVector Mod.Inverted  instance-   (Extent.C vert, Extent.C horiz, Eq width, Shape.C width, Shape.C height) =>-      MultiplyRight (MatrixShape.Full vert horiz height width) where-   (#>) = multiplyVector+   (ArrMultiply.MultiplyVector shape) =>+      MultiplyVector (ArrMatrix.Array shape) where+   matrixVector (ArrMatrix.Array a) x = ArrMultiply.matrixVector a x+   vectorMatrix x (ArrMatrix.Array a) = ArrMultiply.vectorMatrix x a -instance-   (Extent.C vert, Extent.C horiz, Eq height, Shape.C width, Shape.C height) =>-      MultiplyLeft (MatrixShape.Full vert horiz height width) where-   v <# m = multiplyVector (transpose m) v  -instance-   (Eq shape, Shape.C shape) =>-      MultiplyRight (MatrixShape.Hermitian shape) where-   (#>) = Hermitian.multiplyVector NonTransposed--instance-   (Eq shape, Shape.C shape) =>-      MultiplyLeft (MatrixShape.Hermitian shape) where-   (<#) = flip $ Hermitian.multiplyVector Transposed---instance-   (MatrixShape.Content lo, MatrixShape.Content up,-    MatrixShape.TriDiag diag, Eq shape, Shape.C shape) =>-      MultiplyRight (MatrixShape.Triangular lo diag up shape) where-   m #> v = Triangular.multiplyVector m v--instance-   (MatrixShape.Content lo, MatrixShape.Content up,-    MatrixShape.TriDiag diag, Eq shape, Shape.C shape) =>-      MultiplyLeft (MatrixShape.Triangular lo diag up shape) where-   v <# m = Triangular.multiplyVector (Triangular.transpose m) v---instance-   (Unary.Natural sub, Unary.Natural super,-    Extent.C vert, Extent.C horiz, Eq width, Shape.C width, Shape.C height) =>-      MultiplyRight (MatrixShape.Banded sub super vert horiz height width) where-   m #> v = Banded.multiplyVector m v--instance-   (Unary.Natural sub, Unary.Natural super,-    Extent.C vert, Extent.C horiz, Eq height, Shape.C width, Shape.C height) =>-      MultiplyLeft (MatrixShape.Banded sub super vert horiz height width) where-   v <# m = Banded.multiplyVector (Banded.transpose m) v---instance-   (Unary.Natural offDiag, Shape.C size, Eq size) =>-      MultiplyRight (MatrixShape.BandedHermitian offDiag size) where-   (#>) = BandedHermitian.multiplyVector NonTransposed+class+   (Type.Box typ, Type.HeightOf typ ~ Type.WidthOf typ) =>+      MultiplySquare typ where+   {-# MINIMAL transposableSquare | fullSquare,squareFull #-}+   transposableSquare ::+      (Type.HeightOf typ ~ height, Eq height, Shape.C width,+       Extent.C horiz, Extent.C vert, Class.Floating a) =>+      Transposition -> Matrix typ a ->+      Full vert horiz height width a -> Full vert horiz height width a+   transposableSquare NonTransposed a b = squareFull a b+   transposableSquare Transposed a b =+      Basic.transpose $ fullSquare (Basic.transpose b) a -instance-   (Unary.Natural offDiag, Shape.C size, Eq size) =>-      MultiplyLeft (MatrixShape.BandedHermitian offDiag size) where-   (<#) = flip $ BandedHermitian.multiplyVector Transposed+   squareFull ::+      (Type.HeightOf typ ~ height, Eq height, Shape.C width,+       Extent.C horiz, Extent.C vert, Class.Floating a) =>+      Matrix typ a ->+      Full vert horiz height width a -> Full vert horiz height width a+   squareFull = transposableSquare NonTransposed +   fullSquare ::+      (Type.WidthOf typ ~ width, Eq width, Shape.C height,+       Extent.C horiz, Extent.C vert, Class.Floating a) =>+      Full vert horiz height width a ->+      Matrix typ a -> Full vert horiz height width a+   fullSquare b a =+      Basic.transpose $ transposableSquare Transposed a $ Basic.transpose b -{- |-This class allows to multiply two matrices of arbitrary special features-and returns the most special matrix type possible.-At the first glance, this is handy.-At the second glance, this has some problems.-First of all, we may refine the types in future-and then multiplication may return a different, more special type than before.-Second, if you write code with polymorphic matrix types,-then '<#>' may leave you with constraints like-@ExtentPriv.Multiply vert vert ~ vert@.-That constraint is always fulfilled but the compiler cannot infer that.-Because of these problems-you may instead consider using specialised 'multiply' functions-from the various modules for production use.-Btw. 'MultiplyLeft' and 'MultiplyRight' are much less problematic,-because the input and output are always dense vectors.--}-class (Shape.C shapeA, Shape.C shapeB) => Multiply shapeA shapeB where-   type Multiplied shapeA shapeB-   (<#>) ::-      (Class.Floating a) =>-      Array shapeA a -> Array shapeB a -> Array (Multiplied shapeA shapeB) a+infixl 7 ##*#, #*#+infixr 7 #*## -instance-   (Shape.C heightA, Shape.C widthA, Shape.C widthB,-    widthA ~ heightB, Eq heightB,-    Extent.C vertA, Extent.C horizA, Extent.C vertB, Extent.C horizB) =>-      Multiply-         (MatrixShape.Full vertA horizA heightA widthA)-         (MatrixShape.Full vertB horizB heightB widthB) where-   type Multiplied-         (MatrixShape.Full vertA horizA heightA widthA)-         (MatrixShape.Full vertB horizB heightB widthB) =-            MatrixShape.Full-               (ExtentPriv.Multiply vertA vertB)-               (ExtentPriv.Multiply horizA horizB)-               heightA widthB-   a <#> b =-      case unifyFactors (fullExtent a) (fullExtent b) of-         ((ExtentPriv.TagFact, ExtentPriv.TagFact), (unifyLeft, unifyRight)) ->-            multiply-               (mapExtent unifyLeft a)-               (mapExtent unifyRight b)+(#*##) ::+   (MultiplySquare typ, Type.HeightOf typ ~ height, Eq height, Shape.C width,+    Extent.C horiz, Extent.C vert, Class.Floating a) =>+   Matrix typ a ->+   Full vert horiz height width a -> Full vert horiz height width a+(#*##) = squareFull -fullExtent ::+(##*#) ::+   (MultiplySquare typ, Type.WidthOf typ ~ width, Eq width, Shape.C height,+    Extent.C horiz, Extent.C vert, Class.Floating a) =>    Full vert horiz height width a ->-   Extent.Extent vert horiz height width-fullExtent = MatrixShape.fullExtent . Array.shape+   Matrix typ a -> Full vert horiz height width a+(##*#) = fullSquare -unifyFactors ::-   (Extent.C vertA, Extent.C horizA, Extent.C vertB, Extent.C horizB) =>-   (ExtentPriv.Multiply vertA vertB ~ vertC) =>-   (ExtentPriv.Multiply horizA horizB ~ horizC) =>-   Extent.Extent vertA horizA height fuse ->-   Extent.Extent vertB horizB fuse width ->-   ((ExtentPriv.TagFact vertC, ExtentPriv.TagFact horizC),-    (Extent.Map vertA horizA vertC horizC height fuse,-     Extent.Map vertB horizB vertC horizC fuse width))-unifyFactors a b =-   ((ExtentPriv.multiplyTagLaw-         (ExtentPriv.heightFact a) (ExtentPriv.heightFact b),-     ExtentPriv.multiplyTagLaw-         (ExtentPriv.widthFact a) (ExtentPriv.widthFact b)),-    (ExtentPriv.Map $ flip ExtentPriv.unifyLeft b,-     ExtentPriv.Map $ ExtentPriv.unifyRight a))+instance (Shape.C shape) => MultiplySquare (Type.Scale shape) where+   transposableSquare _trans =+      scaleWithCheck "Matrix.Multiply.transposableSquare" Type.height $+         ArrMatrix.lift1 . Vector.scale +instance (Shape.C shape) => MultiplySquare (PermMatrix.Permutation shape) where+   transposableSquare =+      PermMatrix.multiplyFull . Perm.inversionFromTransposition  instance-   (Extent.C vert, Extent.C horiz,-    Shape.C size, size ~ width, Eq width, Shape.C height) =>-      Multiply-         (MatrixShape.Full vert horiz height width)-         (MatrixShape.Hermitian size)-            where-   type Multiplied-         (MatrixShape.Full vert horiz height width)-         (MatrixShape.Hermitian size) =-            MatrixShape.Full vert horiz height width-   a <#> b = transpose $ Hermitian.multiplyFull Transposed b (transpose a)+   (ArrMultiply.MultiplySquare shape) =>+      MultiplySquare (ArrMatrix.Array shape) where+   transposableSquare = ArrMatrix.lift2 . ArrMultiply.transposableSquare+   fullSquare = ArrMatrix.lift2 ArrMultiply.fullSquare+   squareFull = ArrMatrix.lift2 ArrMultiply.squareFull -instance-   (Extent.C vert, Extent.C horiz,-    Shape.C size, size ~ height, Eq height, Shape.C width) =>-      Multiply-         (MatrixShape.Hermitian size)-         (MatrixShape.Full vert horiz height width)-            where-   type Multiplied-         (MatrixShape.Hermitian size)-         (MatrixShape.Full vert horiz height width) =-            MatrixShape.Full vert horiz height width-   (<#>) = Hermitian.multiplyFull NonTransposed -instance-   (Shape.C shapeA, shapeA ~ shapeB, Eq shapeB) =>-      Multiply (MatrixShape.Hermitian shapeA) (MatrixShape.Hermitian shapeB)-         where-   type Multiplied-         (MatrixShape.Hermitian shapeA) (MatrixShape.Hermitian shapeB) =-            MatrixShape.Square shapeA-   a <#> b = Hermitian.multiplyFull NonTransposed a (Hermitian.toSquare b) +class (Type.Box typ, Type.HeightOf typ ~ Type.WidthOf typ) => Power typ where+   square :: (Class.Floating a) => Matrix typ a -> Matrix typ a+   power :: (Class.Floating a) => Int -> Matrix typ a -> Matrix typ a -instance-   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,-    Extent.C vert, Extent.C horiz,-    Shape.C size, size ~ width, Eq width, Shape.C height) =>-      Multiply-         (MatrixShape.Full vert horiz height width)-         (MatrixShape.Triangular lo diag up size)-            where-   type Multiplied-         (MatrixShape.Full vert horiz height width)-         (MatrixShape.Triangular lo diag up size) =-            MatrixShape.Full vert horiz height width-   a <#> b =-      transpose $ Triangular.multiplyFull (Triangular.transpose b) (transpose a)+instance (Shape.C shape) => Power (Type.Scale shape) where+   square (Type.Scale sh a) = Type.Scale sh (a*a)+   power n (Type.Scale sh a) = Type.Scale sh (a^n) -instance-   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,-    Extent.C vert, Extent.C horiz,-    Shape.C size, size ~ height, Eq height, Shape.C width) =>-      Multiply-         (MatrixShape.Triangular lo diag up size)-         (MatrixShape.Full vert horiz height width)-            where-   type Multiplied-         (MatrixShape.Triangular lo diag up size)-         (MatrixShape.Full vert horiz height width) =-            MatrixShape.Full vert horiz height width-   (<#>) = Triangular.multiplyFull+instance (Shape.C shape) => Power (PermMatrix.Permutation shape) where+   square (Type.Permutation p) = Type.Permutation $ Perm.square p+   power n (Type.Permutation p) =+      Type.Permutation $ Perm.power (fromIntegral n) p -instance-   (Shape.C sizeA, sizeA ~ sizeB, Eq sizeB,-    MultiplyTriangular loA upA loB upB,-    MatrixShape.TriDiag diagA, MatrixShape.TriDiag diagB) =>-      Multiply-         (MatrixShape.Triangular loA diagA upA sizeA)-         (MatrixShape.Triangular loB diagB upB sizeB) where-   type Multiplied-         (MatrixShape.Triangular loA diagA upA sizeA)-         (MatrixShape.Triangular loB diagB upB sizeB) =-            -- requires UndecidableInstances-            MultipliedTriangular loA diagA upA loB diagB upB sizeB-   (<#>) = multiplyTriangular+instance (ArrMatrix.Power shape) => Power (ArrMatrix.Array shape) where+   square = ArrMatrix.lift1 ArrMultiply.square+   power = ArrMatrix.lift1 . ArrMultiply.power -class-   (MatrixShape.Content loA, MatrixShape.Content upA,-    MatrixShape.Content loB, MatrixShape.Content upB) =>-      MultiplyTriangular loA upA loB upB where-   multiplyTriangular ::-      (Class.Floating a, Shape.C size, Eq size,-       MatrixShape.TriDiag diagA, MatrixShape.TriDiag diagB) =>-      Triangular loA diagA upA size a ->-      Triangular loB diagB upB size a ->-      Array (MultipliedTriangular loA diagA upA loB diagB upB size) a  -type MultipliedTriangular loA diagA upA loB diagB upB size =-   ComposedTriangular-      (MultipliedPart loA loB)-      (MultipliedDiag diagA diagB)-      (MultipliedPart upA upB)-      size--type family MultipliedPart a b :: *-type instance MultipliedPart Empty b = b-type instance MultipliedPart Filled b = Filled--type family MultipliedDiag a b :: *-type instance MultipliedDiag Unit b = b-type instance MultipliedDiag NonUnit b = NonUnit--type family ComposedTriangular lo diag up size :: *-type instance ComposedTriangular Empty diag up size =-         MatrixShape.Triangular Empty diag up size-type instance ComposedTriangular Filled diag Empty size =-         MatrixShape.LowerTriangular diag size-type instance ComposedTriangular Filled diag Filled size =-         MatrixShape.Square size---instance MultiplyTriangular Empty Empty Empty Empty where-   multiplyTriangular = multiplyTriangularConform--instance MultiplyTriangular Empty Empty Filled Filled where-   multiplyTriangular a = Triangular.multiplyFull a . Triangular.toSquare--instance MultiplyTriangular Empty Filled Filled Filled where-   multiplyTriangular a = Triangular.multiplyFull a . Triangular.toSquare--instance MultiplyTriangular Filled Empty Filled Filled where-   multiplyTriangular a = Triangular.multiplyFull a . Triangular.toSquare--instance MultiplyTriangular Empty Filled Empty Filled where-   multiplyTriangular = multiplyTriangularConform--instance MultiplyTriangular Filled Empty Filled Empty where-   multiplyTriangular = multiplyTriangularConform--instance MultiplyTriangular Filled Empty Empty Filled where-   multiplyTriangular a = Triangular.multiplyFull a . Triangular.toSquare--instance MultiplyTriangular Empty Filled Filled Empty where-   multiplyTriangular a = Triangular.multiplyFull a . Triangular.toSquare--instance MultiplyTriangular Filled Filled Empty Empty where-   multiplyTriangular = multiplyTriangularToSquare--instance MultiplyTriangular Filled Filled Empty Filled where-   multiplyTriangular = multiplyTriangularToSquare--instance MultiplyTriangular Filled Filled Filled Empty where-   multiplyTriangular = multiplyTriangularToSquare--instance MultiplyTriangular Filled Filled Filled Filled where-   multiplyTriangular = multiplyTriangularToSquare--multiplyTriangularToSquare ::-   (MatrixShape.Content loA, MatrixShape.Content upA, MatrixShape.TriDiag diagA,-    MatrixShape.Content loB, MatrixShape.Content upB, MatrixShape.TriDiag diagB,-    Shape.C size, Eq size, Class.Floating a) =>-   Triangular loA diagA upA size a ->-   Triangular loB diagB upB size a ->-   Square size a-multiplyTriangularToSquare a b =-   transpose $ Triangular.multiplyFull (Triangular.transpose b) $-   transpose $ Triangular.toSquare a---newtype MultiplyTriangularConform lo up size a diagB diagA =-   MultiplyTriangularConform {-      getMultiplyTriangularConform ::-         Triangular lo diagA up size a ->-         Triangular lo diagB up size a ->-         Triangular lo (MultipliedDiag diagA diagB) up size a-   }--multiplyTriangularConform ::-   (Shape.C size, Eq size, Class.Floating a,-    MatrixShape.DiagUpLo lo up,-    MatrixShape.TriDiag diagA, MatrixShape.TriDiag diagB) =>-   (MultipliedDiag diagA diagB ~ diagC) =>-   Triangular lo diagA up size a ->-   Triangular lo diagB up size a ->-   Triangular lo diagC up size a-multiplyTriangularConform =-   getMultiplyTriangularConform $-   MatrixShape.switchTriDiag-      (MultiplyTriangularConform $ \a b ->-         Triangular.multiply (Triangular.relaxUnitDiagonal a) b)-      (MultiplyTriangularConform $ \a b ->-         Triangular.multiply a (Triangular.strictNonUnitDiagonal b))+(#*#) ::+   (Multiply typA typB, Class.Floating a) =>+   Matrix typA a -> Matrix typB a -> Matrix (Multiplied typA typB) a+(#*#) = matrixMatrix +class (Type.Box typA, Type.Box typB) => Multiply typA typB where+   type Multiplied typA typB+   matrixMatrix ::+      (Class.Floating a) =>+      Matrix typA a -> Matrix typB a -> Matrix (Multiplied typA typB) a  instance-   (Unary.Natural sub, Unary.Natural super,-    Extent.C vertA, Extent.C horizA,-    Extent.C vertB, Extent.C horizB,-    Shape.C heightA, Shape.C widthA, Shape.C widthB,-    widthA ~ heightB, Eq heightB) =>-      Multiply-         (MatrixShape.Full vertA horizA heightA widthA)-         (MatrixShape.Banded sub super vertB horizB heightB widthB)-            where-   type Multiplied-         (MatrixShape.Full vertA horizA heightA widthA)-         (MatrixShape.Banded sub super vertB horizB heightB widthB) =-            MatrixShape.Full-               (ExtentPriv.Multiply vertA vertB)-               (ExtentPriv.Multiply horizA horizB)-               heightA widthB-   a <#> b =-      case unifyFactors (fullExtent a) (bandedExtent b) of-         ((ExtentPriv.TagFact, ExtentPriv.TagFact), (unifyLeft, unifyRight)) ->-            transpose $-            Banded.multiplyFull-               (Banded.transpose $ Banded.mapExtent unifyRight b)-               (transpose $ mapExtent unifyLeft a)+   (Box.Box shapeA, Box.Box shapeB, ArrMultiply.Multiply shapeA shapeB) =>+      Multiply (ArrMatrix.Array shapeA) (ArrMatrix.Array shapeB) where+   type Multiplied (ArrMatrix.Array shapeA) (ArrMatrix.Array shapeB) =+         ArrMatrix.Array (ArrMultiply.Multiplied shapeA shapeB)+   matrixMatrix (ArrMatrix.Array a) (ArrMatrix.Array b) =+      ArrMatrix.Array $ ArrMultiply.matrixMatrix a b -instance-   (Unary.Natural sub, Unary.Natural super,-    Extent.C vertA, Extent.C horizA,-    Extent.C vertB, Extent.C horizB,-    Shape.C heightA, Shape.C widthA, Shape.C widthB,-    widthA ~ heightB, Eq heightB) =>-      Multiply-         (MatrixShape.Banded sub super vertA horizA heightA widthA)-         (MatrixShape.Full vertB horizB heightB widthB)-            where-   type Multiplied-         (MatrixShape.Banded sub super vertA horizA heightA widthA)-         (MatrixShape.Full vertB horizB heightB widthB) =-            MatrixShape.Full-               (ExtentPriv.Multiply vertA vertB)-               (ExtentPriv.Multiply horizA horizB)-               heightA widthB-   a <#> b =-      case unifyFactors (bandedExtent a) (fullExtent b) of-         ((ExtentPriv.TagFact, ExtentPriv.TagFact), (unifyLeft, unifyRight)) ->-            Banded.multiplyFull-               (Banded.mapExtent unifyLeft a)-               (mapExtent unifyRight b)  instance-   (Unary.Natural subA, Unary.Natural superA,-    Unary.Natural subB, Unary.Natural superB,-    Extent.C vertA, Extent.C horizA,-    Extent.C vertB, Extent.C horizB,-    Shape.C heightA, Shape.C widthA, Shape.C widthB,-    widthA ~ heightB, Eq heightB) =>-      Multiply-         (MatrixShape.Banded subA superA vertA horizA heightA widthA)-         (MatrixShape.Banded subB superB vertB horizB heightB widthB) where-   type Multiplied-         (MatrixShape.Banded subA superA vertA horizA heightA widthA)-         (MatrixShape.Banded subB superB vertB horizB heightB widthB) =-            MatrixShape.Banded-               (subA :+: subB) (superA :+: superB)-               (ExtentPriv.Multiply vertA vertB)-               (ExtentPriv.Multiply horizA horizB)-               heightA widthB-   a <#> b =-      case unifyFactors (bandedExtent a) (bandedExtent b) of-         ((ExtentPriv.TagFact, ExtentPriv.TagFact), (unifyLeft, unifyRight)) ->-            Banded.multiply-               (Banded.mapExtent unifyLeft a)-               (Banded.mapExtent unifyRight b)--bandedExtent ::-   Banded.Banded sup super vert horiz height width a ->-   Extent.Extent vert horiz height width-bandedExtent = MatrixShape.bandedExtent . Array.shape-+   (Shape.C shapeA, Eq shapeA, shapeA ~ shapeB, Shape.C shapeB) =>+      Multiply (Type.Scale shapeA) (Type.Scale shapeB) where+   type Multiplied (Type.Scale shapeA) (Type.Scale shapeB) = Type.Scale shapeB+   matrixMatrix = Type.multiplySame  instance-   (Unary.Natural offDiag, Extent.C vert, Extent.C horiz,-    Shape.C size, size ~ width, Eq width, Shape.C height, Eq height) =>-      Multiply-         (MatrixShape.Full vert horiz height width)-         (MatrixShape.BandedHermitian offDiag size)-            where-   type Multiplied-         (MatrixShape.Full vert horiz height width)-         (MatrixShape.BandedHermitian offDiag size) =-            MatrixShape.Full vert horiz height width-   a <#> b = transpose $ BandedHermitian.multiplyFull Transposed b (transpose a)+   (Shape.C shapeA, Eq shapeA, shapeA ~ Box.HeightOf shapeB,+    Box.Box shapeB, ArrMultiply.Scale shapeB) =>+      Multiply (Type.Scale shapeA) (ArrMatrix.Array shapeB) where+   type Multiplied (Type.Scale shapeA) (ArrMatrix.Array shapeB) =+         ArrMatrix.Array shapeB+   matrixMatrix =+      scaleWithCheck "Matrix.Multiply.multiply Scale" Type.height+         ArrMatrix.scale  instance-   (Unary.Natural offDiag, Extent.C vert, Extent.C horiz,-    Shape.C size, size ~ height, Eq height, Shape.C width, Eq width) =>-      Multiply-         (MatrixShape.BandedHermitian offDiag size)-         (MatrixShape.Full vert horiz height width)-            where-   type Multiplied-         (MatrixShape.BandedHermitian offDiag size)-         (MatrixShape.Full vert horiz height width) =-            MatrixShape.Full vert horiz height width-   (<#>) = BandedHermitian.multiplyFull NonTransposed+   (Box.Box shapeA, ArrMultiply.Scale shapeA, Box.WidthOf shapeA ~ shapeB,+    Shape.C shapeB, Eq shapeB) =>+      Multiply (ArrMatrix.Array shapeA) (Type.Scale shapeB) where+   type Multiplied (ArrMatrix.Array shapeA) (Type.Scale shapeB) =+         ArrMatrix.Array shapeA+   matrixMatrix = flip $+      scaleWithCheck "Matrix.Multiply.multiply Scale" Type.width+         ArrMatrix.scale -instance-   (Unary.Natural offDiag, Unary.Natural sub, Unary.Natural super,-    Extent.C vert, Extent.C horiz,-    Shape.C size, size ~ width, Eq width, Shape.C height, Eq height) =>-      Multiply-         (MatrixShape.Banded sub super vert horiz height width)-         (MatrixShape.BandedHermitian offDiag size)-            where-   type Multiplied-         (MatrixShape.Banded sub super vert horiz height width)-         (MatrixShape.BandedHermitian offDiag size) =-            MatrixShape.Banded-               (sub:+:offDiag) (super:+:offDiag) vert horiz height width-   a <#> b =-      Banded.multiply-         a (Banded.mapExtent Extent.fromSquare (BandedHermitian.toBanded b))  instance-   (Unary.Natural offDiag, Unary.Natural sub, Unary.Natural super,-    Extent.C vert, Extent.C horiz,-    Shape.C size, size ~ height, Eq height, Shape.C width, Eq width) =>-      Multiply-         (MatrixShape.BandedHermitian offDiag size)-         (MatrixShape.Banded sub super vert horiz height width)-            where-   type Multiplied-         (MatrixShape.BandedHermitian offDiag size)-         (MatrixShape.Banded sub super vert horiz height width) =-            MatrixShape.Banded-               (offDiag:+:sub) (offDiag:+:super) vert horiz height width-   a <#> b =-      Banded.multiply-         (Banded.mapExtent Extent.fromSquare (BandedHermitian.toBanded a)) b--instance-   (Unary.Natural offDiagA, Unary.Natural offDiagB,-    Shape.C sizeA, sizeA ~ sizeB, Shape.C sizeB, Eq sizeB) =>-      Multiply-         (MatrixShape.BandedHermitian offDiagA sizeA)-         (MatrixShape.BandedHermitian offDiagB sizeB)-            where-   type Multiplied-         (MatrixShape.BandedHermitian offDiagA sizeA)-         (MatrixShape.BandedHermitian offDiagB sizeB) =-            MatrixShape.Banded-               (offDiagA:+:offDiagB) (offDiagA:+:offDiagB)-               Small Small sizeA sizeB-   a <#> b =-      Banded.multiply (BandedHermitian.toBanded a) (BandedHermitian.toBanded b)+   (Shape.C shapeA, Eq shapeA, shapeA ~ shapeB, Shape.C shapeB) =>+      Multiply (Perm.Permutation shapeA) (Perm.Permutation shapeB) where+   type Multiplied (Perm.Permutation shapeA) (Perm.Permutation shapeB) =+         Perm.Permutation shapeB+   matrixMatrix = Type.multiplySame
+ src/Numeric/LAPACK/Matrix/Permutation.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE TypeFamilies #-}+module Numeric.LAPACK.Matrix.Permutation (+   Permutation,+   size,+   identity,+   Mod.Inversion(NonInverted,Inverted),+   Perm.inversionFromTransposition,+   fromPermutation,+   toPermutation,+   toMatrix,+   determinant,+   transpose,+   multiplyVector,+   multiplyFull,+   ) where++import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import qualified Numeric.LAPACK.Matrix.Modifier as Mod+import qualified Numeric.LAPACK.Permutation as Perm+import Numeric.LAPACK.Permutation (Permutation)+import Numeric.LAPACK.Matrix.Type (Matrix(Permutation))+import Numeric.LAPACK.Vector (Vector)++import qualified Numeric.Netlib.Class as Class++import qualified Data.Array.Comfort.Shape as Shape+++size :: Matrix (Permutation sh) a -> sh+size (Permutation perm) = Perm.size perm++identity :: (Shape.C sh) => sh -> Matrix (Permutation sh) a+identity = Permutation . Perm.identity++fromPermutation ::+   (Shape.C sh) => Perm.Permutation sh -> Matrix (Permutation sh) a+fromPermutation = Permutation++toPermutation ::+   (Shape.C sh) => Matrix (Permutation sh) a -> Perm.Permutation sh+toPermutation (Permutation perm) = perm++determinant :: (Shape.C sh, Class.Floating a) => Matrix (Permutation sh) a -> a+determinant (Permutation perm) = Perm.numberFromSign $ Perm.determinant perm+++transpose ::+   (Shape.C sh) => Matrix (Permutation sh) a -> Matrix (Permutation sh) a+transpose (Permutation perm) = Permutation $ Perm.transpose perm++toMatrix ::+   (Shape.C sh, Class.Floating a) =>+   Matrix (Permutation sh) a -> ArrMatrix.Square sh a+toMatrix (Permutation perm) = Perm.toMatrix perm++multiplyVector ::+   (Shape.C size, Eq size, Class.Floating a) =>+   Mod.Inversion -> Matrix (Permutation size) a ->+   Vector size a -> Vector size a+multiplyVector inverted (Permutation perm) =+   ArrMatrix.unliftColumn MatrixShape.ColumnMajor (Perm.apply inverted perm)++multiplyFull ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Class.Floating a) =>+   Mod.Inversion -> Matrix (Permutation height) a ->+   ArrMatrix.Full vert horiz height width a ->+   ArrMatrix.Full vert horiz height width a+multiplyFull inverted (Permutation perm) = Perm.apply inverted perm
+ src/Numeric/LAPACK/Matrix/Plain.hs view
@@ -0,0 +1,629 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+module Numeric.LAPACK.Matrix.Plain (+   Full,+   General, Tall, Wide,+   ShapeInt, shapeInt,+   transpose, adjoint,+   Matrix.height, Matrix.width,+   Basic.caseTallWide,+   fromList,+   mapExtent, fromFull,+   tallFromGeneral, wideFromGeneral,+   generalizeTall, generalizeWide,+   mapHeight, mapWidth,+   identity,+   diagonal,+   fromRowsNonEmpty,    fromRowArray,    fromRows,+   fromRowsNonEmptyContainer,    fromRowContainer,+   fromColumnsNonEmpty, fromColumnArray, fromColumns,+   fromColumnsNonEmptyContainer, fromColumnContainer,+   Basic.singleRow,   Basic.singleColumn,+   Basic.flattenRow,  Basic.flattenColumn,+   Basic.liftRow,     Basic.liftColumn,+   Basic.unliftRow,   Basic.unliftColumn,+   toRows, toColumns,+   toRowArray, toColumnArray,+   toRowContainer, toColumnContainer,+   takeRow, takeColumn,+   Basic.takeRows, Basic.takeColumns, takeEqually,+   Basic.dropRows, Basic.dropColumns, dropEqually,+   Basic.takeTop, Basic.takeBottom,+   Basic.takeLeft, Basic.takeRight,+   takeRowArray, takeColumnArray,+   swapRows, swapColumns,+   reverseRows, reverseColumns,+   fromRowMajor, toRowMajor,+   forceOrder, adaptOrder,++   (|*-),+   tensorProduct,+   outer,+   kronecker,+   sumRank1,++   add, sub,+   rowSums, columnSums,+   rowArgAbsMaximums, columnArgAbsMaximums,+   Basic.scaleRows, Basic.scaleColumns,+   Basic.scaleRowsComplex, Basic.scaleColumnsComplex,+   Basic.scaleRowsReal, Basic.scaleColumnsReal,+   ) where++import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Square.Basic as Square+import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import qualified Numeric.LAPACK.Matrix.Basic as Basic+import qualified Numeric.LAPACK.Matrix.RowMajor as RowMajor+import qualified Numeric.LAPACK.Matrix.Private as Matrix+import qualified Numeric.LAPACK.Vector.Private as VectorPriv+import qualified Numeric.LAPACK.Vector as Vector+import Numeric.LAPACK.Matrix.Shape.Private+         (Order(RowMajor, ColumnMajor), transposeFromOrder)+import Numeric.LAPACK.Matrix.Basic+         (transpose, adjoint, forceOrder, forceRowMajor)+import Numeric.LAPACK.Matrix.Private+         (Full, Tall, Wide, General, ShapeInt, shapeInt,+          mapExtent, fromFull, generalizeTall, generalizeWide)+import Numeric.LAPACK.Matrix.Modifier (Conjugation(NonConjugated,Conjugated))+import Numeric.LAPACK.Vector (Vector)+import Numeric.LAPACK.Scalar (zero, one)+import Numeric.LAPACK.Private (pointerSeq, fill, copySubMatrix, copyBlock)++import qualified Numeric.LAPACK.FFI.Generic as LapackGen+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.Boxed as BoxedArray+import qualified Data.Array.Comfort.Storable.Unchecked.Monadic as ArrayIO+import qualified Data.Array.Comfort.Storable.Unchecked as Array+import qualified Data.Array.Comfort.Storable as CheckedArray+import qualified Data.Array.Comfort.Container as Container+import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Storable.Unchecked (Array(Array))++import Foreign.Marshal.Array (advancePtr, pokeArray)+import Foreign.ForeignPtr (withForeignPtr)+import Foreign.Storable (Storable, poke, peekElemOff)++import Control.Monad.Trans.Cont (ContT(ContT), evalContT)+import Control.Monad.IO.Class (liftIO)+import Control.Monad (when, mfilter)+import Control.Applicative ((<$>))++import qualified Data.NonEmpty.Mixed as NonEmptyM+import qualified Data.NonEmpty as NonEmpty+import qualified Data.Foldable as Fold+import Data.Foldable (forM_)+import Data.Maybe (listToMaybe)+import Data.Bool.HT (if')+++fromList ::+   (Shape.C height, Shape.C width, Storable a) =>+   height -> width -> [a] -> General height width a+fromList height width =+   CheckedArray.fromList (MatrixShape.general RowMajor height width)++tallFromGeneral ::+   (Shape.C height, Shape.C width, Storable a) =>+   General height width a -> Tall height width a+tallFromGeneral =+   Array.mapShape $ \(MatrixShape.Full order extent) ->+      uncurry (MatrixShape.tall order) (Extent.dimensions extent)++wideFromGeneral ::+   (Shape.C height, Shape.C width, Storable a) =>+   General height width a -> Wide height width a+wideFromGeneral =+   Array.mapShape $ \(MatrixShape.Full order extent) ->+      uncurry (MatrixShape.wide order) (Extent.dimensions extent)+++identity ::+   (Shape.C sh, Class.Floating a) =>+   sh -> General sh sh a+identity = Square.toFull . Square.identity++diagonal ::+   (Shape.C sh, Class.Floating a) =>+   Vector sh a -> General sh sh a+diagonal = Square.toFull . Square.diagonal+++mapHeight ::+   (Shape.C heightA, Shape.C heightB,+    Extent.GeneralTallWide vert horiz,+    Extent.GeneralTallWide horiz vert) =>+   (heightA -> heightB) ->+   Full vert horiz heightA width a ->+   Full vert horiz heightB width a+mapHeight f = Basic.mapHeight $ MatrixShape.mapChecked "mapHeight" f++mapWidth ::+   (Shape.C widthA, Shape.C widthB,+    Extent.GeneralTallWide vert horiz,+    Extent.GeneralTallWide horiz vert) =>+   (widthA -> widthB) ->+   Full vert horiz height widthA a ->+   Full vert horiz height widthB a+mapWidth f = Basic.mapWidth $ MatrixShape.mapChecked "mapWidth" f+++fromRowsNonEmpty ::+   (Shape.C width, Eq width, Storable a) =>+   NonEmpty.T [] (Vector width a) -> General ShapeInt width a+fromRowsNonEmpty (NonEmpty.Cons row rows) =+   fromRows (Array.shape row) (row:rows)++fromRowArray ::+   (Shape.C height, Shape.C width, Eq width, Storable a) =>+   width -> BoxedArray.Array height (Vector width a) -> General height width a+fromRowArray width rows =+   Basic.mapHeight (const $ BoxedArray.shape rows) $+   fromRows width $ BoxedArray.toList rows++fromRowsNonEmptyContainer ::+   (f ~ NonEmpty.T g, Container.C g,+    Shape.C width, Eq width, Storable a) =>+   f (Vector width a) -> General (Container.Shape f) width a+fromRowsNonEmptyContainer rows =+   fromRowContainer (Array.shape $ NonEmpty.head rows) rows++fromRowContainer ::+   (Container.C f, Shape.C width, Eq width, Storable a) =>+   width -> f (Vector width a) -> General (Container.Shape f) width a+fromRowContainer width rows =+   Basic.mapHeight (const $ Container.toShape rows) $+   fromRows width $ Fold.toList rows++fromRows ::+   (Shape.C width, Eq width, Storable a) =>+   width -> [Vector width a] -> General ShapeInt width a+fromRows width = fromRowMajor . RowMajor.fromRows width+++fromColumnsNonEmpty ::+   (Shape.C height, Eq height, Storable a) =>+   NonEmpty.T [] (Vector height a) -> General height ShapeInt a+fromColumnsNonEmpty (NonEmpty.Cons column columns) =+   fromColumns (Array.shape column) (column:columns)++fromColumnArray ::+   (Shape.C height, Eq height, Shape.C width, Storable a) =>+   height -> BoxedArray.Array width (Vector height a) -> General height width a+fromColumnArray height columns =+   Basic.mapWidth (const $ BoxedArray.shape columns) $+   fromColumns height $ BoxedArray.toList columns++fromColumnsNonEmptyContainer ::+   (f ~ NonEmpty.T g, Container.C g,+    Shape.C height, Eq height, Storable a) =>+   f (Vector height a) -> General height (Container.Shape f) a+fromColumnsNonEmptyContainer columns =+   fromColumnContainer (Array.shape $ NonEmpty.head columns) columns++fromColumnContainer ::+   (Shape.C height, Eq height, Container.C f, Storable a) =>+   height -> f (Vector height a) -> General height (Container.Shape f) a+fromColumnContainer height columns =+   Basic.mapWidth (const $ Container.toShape columns) $+   fromColumns height $ Fold.toList columns++fromColumns ::+   (Shape.C height, Eq height, Storable a) =>+   height -> [Vector height a] -> General height ShapeInt a+fromColumns height = transpose . fromRowMajor . RowMajor.fromRows height+++toRows ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> [Vector width a]+toRows a =+   let ad = Basic.mapHeight Shape.Deferred $ fromFull a+   in map (takeRow ad) $ Shape.indices $ Matrix.height ad++toColumns ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> [Vector height a]+toColumns a =+   let ad = Basic.mapWidth Shape.Deferred $ fromFull a+   in map (takeColumn ad) $ Shape.indices $ Matrix.width ad++toRowArray ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> BoxedArray.Array height (Vector width a)+toRowArray a = BoxedArray.fromList (Matrix.height a) (toRows a)++toColumnArray ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> BoxedArray.Array width (Vector height a)+toColumnArray a = BoxedArray.fromList (Matrix.width a) (toColumns a)++toRowContainer ::+   (Extent.C vert, Extent.C horiz,+    Container.C f, Shape.C width, Class.Floating a) =>+   Full vert horiz (Container.Shape f) width a -> f (Vector width a)+toRowContainer a = Container.fromList (Matrix.height a) (toRows a)++toColumnContainer ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Container.C f, Class.Floating a) =>+   Full vert horiz height (Container.Shape f) a -> f (Vector height a)+toColumnContainer a = Container.fromList (Matrix.width a) (toColumns a)+++takeRow ::+   (Extent.C vert, Extent.C horiz,+    Shape.Indexed height, Shape.C width, Shape.Index height ~ ix,+    Class.Floating a) =>+   Full vert horiz height width a -> ix -> Vector width a+takeRow x ix =+   either (RowMajor.takeRow ix) (RowMajor.takeColumn ix) $+   Matrix.revealOrder x++takeColumn ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.Indexed width, Shape.Index width ~ ix,+    Class.Floating a) =>+   Full vert horiz height width a -> ix -> Vector height a+takeColumn x ix =+   either (RowMajor.takeColumn ix) (RowMajor.takeRow ix) $+   Matrix.revealOrder x+++takeEqually ::+   (Extent.C vert, Extent.C horiz, Class.Floating a) =>+   Int ->+   Full vert horiz ShapeInt ShapeInt a ->+   Full vert horiz ShapeInt ShapeInt a+takeEqually k (Array (MatrixShape.Full order extentA) a) =+   let (Shape.ZeroBased heightA, Shape.ZeroBased widthA) =+         Extent.dimensions extentA+       heightB = min k heightA+       widthB  = min k widthA+       extentB =+         Extent.reduceConsistent+            (Shape.ZeroBased heightB) (Shape.ZeroBased widthB) extentA+   in if' (k<0) (error "take: negative number") $+      Array.unsafeCreate (MatrixShape.Full order extentB) $ \bPtr ->+      withForeignPtr a $ \aPtr ->+      case order of+         RowMajor -> copySubMatrix widthB heightB widthA aPtr widthB bPtr+         ColumnMajor -> copySubMatrix heightB widthB heightA aPtr heightB bPtr++dropEqually ::+   (Extent.C vert, Extent.C horiz, Class.Floating a) =>+   Int ->+   Full vert horiz ShapeInt ShapeInt a ->+   Full vert horiz ShapeInt ShapeInt a+dropEqually k (Array (MatrixShape.Full order extentA) a) =+   let (Shape.ZeroBased heightA, Shape.ZeroBased widthA) =+         Extent.dimensions extentA+       heightB = heightA - top; top  = min k heightA+       widthB  = widthA - left; left = min k widthA+       extentB =+         Extent.reduceConsistent+            (Shape.ZeroBased heightB) (Shape.ZeroBased widthB) extentA+   in if' (k<0) (error "drop: negative number") $+      Array.unsafeCreate (MatrixShape.Full order extentB) $ \bPtr ->+      withForeignPtr a $ \aPtr ->+      case order of+         RowMajor ->+            copySubMatrix widthB heightB+               widthA (advancePtr aPtr (top*widthA+left)) widthB bPtr+         ColumnMajor ->+            copySubMatrix heightB widthB+               heightA (advancePtr aPtr (left*heightA+top)) heightB bPtr+++swapRows ::+   (Extent.C vert, Extent.C horiz,+    Shape.Indexed height, Shape.C width, Class.Floating a) =>+   Shape.Index height -> Shape.Index height ->+   Full vert horiz height width a -> Full vert horiz height width a+swapRows i j (Array shape@(MatrixShape.Full order extent) a) =+   Array.unsafeCreateWithSize shape $ \blockSize bPtr -> evalContT $ do+      let (height,width) = Extent.dimensions extent+      let m = Shape.size height+      let n = Shape.size width+      nPtr <- Call.cint n+      aPtr <- ContT $ withForeignPtr a+      let offsetI = Shape.offset height i+      let offsetJ = Shape.offset height j+      let (incVert,incHoriz) =+            case order of+               RowMajor -> (n,1)+               ColumnMajor -> (1,m)+      incPtr <- Call.cint incHoriz+      liftIO $ do+         copyBlock blockSize aPtr bPtr+         when (offsetI/=offsetJ) $+            BlasGen.swap nPtr+               (advancePtr bPtr (incVert*offsetI)) incPtr+               (advancePtr bPtr (incVert*offsetJ)) incPtr++swapColumns ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.Indexed width, Class.Floating a) =>+   Shape.Index width -> Shape.Index width ->+   Full vert horiz height width a -> Full vert horiz height width a+swapColumns i j = transpose . swapRows i j . transpose+++-- alternative: laswp+reverseRows ::+   (Extent.C vert, Extent.C horiz, Shape.C width, Class.Floating a) =>+   Full vert horiz ShapeInt width a -> Full vert horiz ShapeInt width a+reverseRows (Array shape@(MatrixShape.Full order extent) a) =+   Array.unsafeCreateWithSize shape $ \blockSize bPtr -> evalContT $ do+      let (height,width) = Extent.dimensions extent+      let n = Shape.size height+      let m = Shape.size width+      fwdPtr <- Call.bool True+      nPtr <- Call.cint n+      mPtr <- Call.cint m+      kPtr <- Call.allocaArray n+      aPtr <- ContT $ withForeignPtr a+      liftIO $ do+         copyBlock blockSize aPtr bPtr+         pokeArray kPtr $ take n $ iterate (subtract 1) $ fromIntegral n+         case order of+            RowMajor -> LapackGen.lapmt fwdPtr mPtr nPtr bPtr mPtr kPtr+            ColumnMajor -> LapackGen.lapmr fwdPtr nPtr mPtr bPtr nPtr kPtr++reverseColumns ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Class.Floating a) =>+   Full vert horiz height ShapeInt a -> Full vert horiz height ShapeInt a+reverseColumns = transpose . reverseRows . transpose+++{-+The function is optimized for blocks of consecutive rows.+For scattered rows in column major order+the function has quite ugly memory access patterns.+-}+takeRowArray ::+   (Shape.Indexed height, Shape.C width, Shape.C sh, Class.Floating a) =>+   BoxedArray.Array sh (Shape.Index height) ->+   General height width a -> General sh width a+takeRowArray ixs (Array (MatrixShape.Full order extent) a) =+   let (heightA, width) = Extent.dimensions extent+       heightB = BoxedArray.shape ixs+       offsets = map (Shape.offset heightA) $ BoxedArray.toList ixs+       startBlocks blocks = zip (scanl (+) 0 $ map fst blocks) blocks+       ma = Shape.size heightA+       mb = Shape.size heightB+       n = Shape.size width+   in Array.unsafeCreate (MatrixShape.general order heightB width) $ \bPtr ->+      withForeignPtr a $ \aPtr ->+      case order of+         RowMajor -> do+            forM_ (startBlocks $ chopRowBlocks offsets) $+               \(dest, (numRows, (start,step))) ->+                  copySubMatrix n numRows+                     (step*n) (advancePtr aPtr (start*n))+                     n (advancePtr bPtr (dest*n))+         ColumnMajor -> do+            forM_ (startBlocks $ chopColumnBlocks offsets) $+               \(dest, (numRows, start)) ->+                  copySubMatrix numRows n+                     ma (advancePtr aPtr start)+                     mb (advancePtr bPtr dest)++chopRowBlocks :: (Integral i) => [i] -> [(Int,(i,i))]+chopRowBlocks =+   let go [] = []+       go is@(i0:is0) =+         case mfilter (i0<) $ listToMaybe is0 of+            Nothing -> (1,(i0,0)) : go is0+            Just i1 ->+               let (consecutive,remainder) =+                     span (uncurry (==)) $ zip [i0,i1..] is+               in (length consecutive, (i0,i1-i0)) : go (map snd remainder)+   in go++chopColumnBlocks :: (Integral i) => [i] -> [(Int,i)]+chopColumnBlocks =+   map (\is -> (length $ NonEmpty.flatten is, NonEmpty.head is)) .+   NonEmptyM.groupBy (\i j -> i+1 == j)+++takeColumnArray ::+   (Shape.C height, Shape.Indexed width, Shape.C sh, Class.Floating a) =>+   BoxedArray.Array sh (Shape.Index width) ->+   General height width a -> General height sh a+takeColumnArray ixs = transpose . takeRowArray ixs . transpose++++fromRowMajor ::+   (Shape.C height, Shape.C width, Storable a) =>+   Array (height,width) a -> General height width a+fromRowMajor = Array.mapShape (uncurry $ MatrixShape.general RowMajor)++toRowMajor ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> Array (height,width) a+toRowMajor =+   Array.mapShape+      (\shape -> (MatrixShape.fullHeight shape, MatrixShape.fullWidth shape)) .+   forceRowMajor++adaptOrder ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>+   Full vert horiz height width a ->+   Full vert horiz height width a ->+   Full vert horiz height width a+adaptOrder x = forceOrder (MatrixShape.fullOrder $ Array.shape x)+++add, sub ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Eq height, Eq width,+    Class.Floating a) =>+   Full vert horiz height width a ->+   Full vert horiz height width a ->+   Full vert horiz height width a+add x y = Vector.add (adaptOrder y x) y+sub x y = Vector.sub (adaptOrder y x) y+++rowSums ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> Vector height a+rowSums m = Basic.multiplyVectorUnchecked m $ Vector.one $ Matrix.width m++-- Does not work because incx must not be zero+_rowSums ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> Vector height a+_rowSums (Array shape@(MatrixShape.Full order extent) a) =+      Array.unsafeCreate (Extent.height extent) $ \yPtr -> do+   let (m,n) = MatrixShape.dimensions shape+   let lda = m+   evalContT $ do+      transPtr <- Call.char $ transposeFromOrder order+      mPtr <- Call.cint m+      nPtr <- Call.cint n+      alphaPtr <- Call.number one+      aPtr <- ContT $ withForeignPtr a+      ldaPtr <- Call.leadingDim lda+      xPtr <- Call.number one+      incxPtr <- Call.cint 0+      betaPtr <- Call.number zero+      incyPtr <- Call.cint 1+      liftIO $+         BlasGen.gemv+            transPtr mPtr nPtr alphaPtr aPtr ldaPtr+            xPtr incxPtr betaPtr yPtr incyPtr++columnSums ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert horiz height width a -> Vector width a+columnSums m =+   Basic.multiplyVectorUnchecked (transpose m) $ Vector.one $ Matrix.height m+++rowArgAbsMaximums ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.InvIndexed width, Shape.Index width ~ ix, Storable ix,+    Class.Floating a) =>+   Full vert horiz height width a -> (Vector height ix, Vector height a)+rowArgAbsMaximums (Array (MatrixShape.Full order extent) a) =+   let (height,width) = Extent.dimensions extent+   in Array.unsafeCreateWithSizeAndResult height $ \m ixPtr ->+      ArrayIO.unsafeCreate height $ \bPtr -> evalContT $ do+      let n = Shape.size width+      let (inca,incx) =+            case order of+               {-+               It would be more CPU friendly to compute the maximum row by row.+               Unfortunately BLAS does not support this mode.+               -}+               ColumnMajor -> (1,m)+               RowMajor -> (n,1)+      nPtr <- Call.cint n+      aPtr <- ContT $ withForeignPtr a+      incxPtr <- Call.cint incx+      liftIO $ do+         Call.assert "rowArgAbsMaximums: no columns" (n>0)+         forM_ (take m $ zip (pointerSeq inca aPtr) $+                zip (pointerSeq 1 ixPtr) (pointerSeq 1 bPtr)) $+               \(aiPtr,(ixiPtr,biPtr)) -> do+            ix <- pred . fromIntegral <$> VectorPriv.absMax nPtr aiPtr incxPtr+            poke ixiPtr $ Shape.indexFromOffset width ix+            poke biPtr =<< peekElemOff aiPtr (ix*incx)++columnArgAbsMaximums ::+   (Extent.C vert, Extent.C horiz,+    Shape.InvIndexed height, Shape.C width,+    Shape.Index height ~ ix, Storable ix,+    Class.Floating a) =>+   Full vert horiz height width a -> (Vector width ix, Vector width a)+columnArgAbsMaximums = rowArgAbsMaximums . transpose+++infixl 7 |*-++(|*-) ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   Vector height a -> Vector width a -> General height width a+(|*-) = tensorProduct RowMajor++tensorProduct ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   Order -> Vector height a -> Vector width a -> General height width a+tensorProduct = tensorProductAux NonConjugated++outer ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   Order -> Vector height a -> Vector width a -> General height width a+outer = tensorProductAux Conjugated++tensorProductAux ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   Conjugation -> Order ->+   Vector height a -> Vector width a -> General height width a+tensorProductAux conjugated order x y =+   case order of+      ColumnMajor ->+         transpose $+         fromRowMajor $ RowMajor.tensorProduct (Right conjugated) y x+      RowMajor -> fromRowMajor $ RowMajor.tensorProduct (Left conjugated) x y+++kronecker ::+   (Extent.C vert, Extent.C horiz,+    Shape.C heightA, Shape.C widthA, Shape.C heightB, Shape.C widthB,+    Class.Floating a) =>+   Full vert horiz heightA widthA a ->+   Full vert horiz heightB widthB a ->+   Full vert horiz (heightA,heightB) (widthA,widthB) a+kronecker a b =+   let MatrixShape.Full orderB extentB = Array.shape b+       shc =+         MatrixShape.Full orderB $+         Extent.kronecker (MatrixShape.fullExtent $ Array.shape a) extentB+   in either+         (Array.reshape shc . RowMajor.kronecker a)+         (Array.reshape shc . RowMajor.kronecker (transpose a)) $+      Matrix.revealOrder b+++sumRank1 ::+   (Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+   (height,width) ->+   [(a, (Vector height a, Vector width a))] -> General height width a+sumRank1 (height,width) xys =+   Array.unsafeCreateWithSize (MatrixShape.general ColumnMajor height width) $+      \size aPtr ->+   evalContT $ do+      let m = Shape.size height+      let n = Shape.size width+      mPtr <- Call.cint m+      nPtr <- Call.cint n+      alphaPtr <- Call.alloca+      incxPtr <- Call.cint 1+      incyPtr <- Call.cint 1+      ldaPtr <- Call.leadingDim m+      liftIO $ do+         fill zero size aPtr+         forM_ xys $ \(alpha, (Array shX x, Array shY y)) ->+            withForeignPtr x $ \xPtr ->+            withForeignPtr y $ \yPtr -> do+               Call.assert "Matrix.sumRank1: non-matching height" (height==shX)+               Call.assert "Matrix.sumRank1: non-matching width" (width==shY)+               poke alphaPtr alpha+               BlasGen.gerc mPtr nPtr+                  alphaPtr xPtr incxPtr yPtr incyPtr aPtr ldaPtr
+ src/Numeric/LAPACK/Matrix/Plain/Class.hs view
@@ -0,0 +1,298 @@+{-# 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++instance+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+      Admissible (MatrixShape.Full vert horiz height width) where+   check _ = Nothing++instance (Shape.C size) => Admissible (MatrixShape.Hermitian size) where+   check =+      flip toMaybe "Hermitian with non-real diagonal" .+      isReal . Triangular.takeDiagonal . Hermitian.takeUpper++instance+   (MatrixShape.Content lo, MatrixShape.TriDiag diag, MatrixShape.Content up,+    Shape.C size) =>+      Admissible (MatrixShape.Triangular lo diag up size) where+   check =+      getCheckDiag $+      MatrixShape.switchTriDiag+         (CheckDiag $ const Nothing)+         (CheckDiag checkUnitDiagonal)++newtype CheckDiag lo up sh a b diag =+   CheckDiag {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 =+   flip toMaybe "Triangular.Unit with non-unit diagonal elements" .+   all (Scalar.equal Scalar.one) . Vector.toList . 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 arr0 =+      let arr =+            Banded.mapHeight Shape.Deferred $+            Banded.mapWidth Shape.Deferred $+            Banded.mapExtent Extent.toGeneral arr0+      in flip toMaybe "Banded with non-zero unused elements" $+         all (Scalar.isZero . (arr!)) $+         filter+            (\ix -> case ix of MatrixShape.InsideBox _ _ -> False; _ -> True) $+         Shape.indices $ Array.shape arr++instance+   (Unary.Natural off, Shape.C size) =>+      Admissible (MatrixShape.BandedHermitian off size) where+   check arr =+      let u = BandedHermitian.takeUpper arr+      in check u <|>+         (flip toMaybe "BandedHermitian with non-real diagonal" .+          isReal . Banded.takeDiagonal $ u)++isReal :: (Shape.C sh, Class.Floating a) => Vector sh a -> Bool+isReal =+   getFlip $ getCompose $+   Class.switchFloating+      (Compose $ Flip $ const True)+      (Compose $ Flip $ const True)+      (Compose $ Flip isComplexReal)+      (Compose $ Flip isComplexReal)++isComplexReal ::+   (Shape.C sh, Class.Real a) => Vector sh (Complex.Complex a) -> Bool+isComplexReal = all Scalar.isZero . Vector.toList . Vector.imaginaryPart+++class (Shape.C shape) => Complex shape where+   conjugate ::+      (Class.Floating a) => Array shape a -> Array shape a+   conjugate = Vector.conjugate+   fromReal ::+      (Class.Floating a) =>+      Array shape (RealOf a) -> Array shape a+   fromReal = Vector.fromReal+   toComplex ::+      (Class.Floating a) =>+      Array shape a -> Array shape (ComplexOf a)+   toComplex = 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 = Vector.zero+   negate :: (Class.Floating a) => Array shape a -> Array shape a+   negate = Vector.negate+   scaleReal :: (Class.Floating a) =>+      RealOf a -> Array shape a -> Array shape a+   scaleReal = 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 = forceOrder . shapeOrder . Array.shape++instance+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+      ShapeOrder (MatrixShape.Full vert horiz height width) where+   forceOrder = Basic.forceOrder+   shapeOrder = MatrixShape.fullOrder++instance (Shape.C size) => ShapeOrder (MatrixShape.Hermitian size) where+   forceOrder = Hermitian.forceOrder+   shapeOrder = MatrixShape.hermitianOrder++instance+   (MatrixShape.Content lo,+    MatrixShape.TriDiag diag,+    MatrixShape.Content up, Shape.C size) =>+      ShapeOrder (MatrixShape.Triangular lo diag up size) where+   forceOrder = Triangular.forceOrder+   shapeOrder = 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 a = add 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 = addGen+   sub = subGen++instance (Shape.C size, Eq size) => Additive (MatrixShape.Hermitian size) where+   add = addGen+   sub = 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 = addGen+   sub = subGen++addGen, subGen ::+   (ShapeOrder shape, Eq shape, Class.Floating a) =>+   Array shape a -> Array shape a -> Array shape a+addGen a b = Vector.add (adaptOrder b a) b+subGen a b = Vector.sub (adaptOrder b 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 = id+   identityOrder = Square.identityOrder+   takeDiagonal = Square.takeDiagonal++instance (Shape.C size) => SquareShape (MatrixShape.Hermitian size) where+   toSquare = Hermitian.toSquare+   identityOrder = Hermitian.identity+   takeDiagonal = Vector.fromReal . Hermitian.takeDiagonal++instance+   (MatrixShape.Content lo, MatrixShape.TriDiag diag, MatrixShape.Content up,+    Shape.C size) =>+      SquareShape (MatrixShape.Triangular lo diag up size) where+   toSquare = Triangular.toSquare+   identityOrder order =+      Triangular.relaxUnitDiagonal . Triangular.identity order+   takeDiagonal = 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 = Banded.toFull+   identityOrder = Banded.identityFatOrder+   takeDiagonal = Banded.takeDiagonal++instance+   (Unary.Natural offDiag, Shape.C size) =>+      SquareShape (MatrixShape.BandedHermitian offDiag size) where+   toSquare = Banded.toFull . BandedHermitian.toBanded+   identityOrder = BandedHermitian.identityFatOrder+   takeDiagonal = Vector.fromReal . BandedHermitian.takeDiagonal
+ src/Numeric/LAPACK/Matrix/Plain/Divide.hs view
@@ -0,0 +1,162 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE UndecidableInstances #-}+module Numeric.LAPACK.Matrix.Plain.Divide where++import qualified Numeric.LAPACK.Matrix.Plain.Multiply as Multiply++import qualified Numeric.LAPACK.Matrix.Square.Linear+                                           as Square+import qualified Numeric.LAPACK.Matrix.Square.Basic+                                           as Square+import qualified Numeric.LAPACK.Matrix.Triangular.Linear+                                           as Triangular+import qualified Numeric.LAPACK.Matrix.Triangular.Basic+                                           as Triangular+import qualified Numeric.LAPACK.Matrix.Hermitian.Linear+                                           as Hermitian+import qualified Numeric.LAPACK.Matrix.Banded.Linear+                                           as Banded+import qualified Numeric.LAPACK.Matrix.Banded.Basic+                                           as Banded+import qualified Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite.Linear+                                           as BandedHermitianPositiveDefinite++import qualified Numeric.LAPACK.Matrix.Plain.Class as Plain+import qualified Numeric.LAPACK.Matrix.Basic as Basic+import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Shape.Box as Box+import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import qualified Numeric.LAPACK.Vector as Vector+import qualified Numeric.LAPACK.Scalar as Scalar+import Numeric.LAPACK.Matrix.Extent.Private (Small)+import Numeric.LAPACK.Matrix.Basic (swapMultiply)+import Numeric.LAPACK.Matrix.Modifier (Transposition(Transposed, NonTransposed))+import Numeric.LAPACK.Matrix.Private (Full)+import Numeric.LAPACK.Vector (Vector)++import qualified Numeric.Netlib.Class as Class++import qualified Type.Data.Num.Unary as Unary++import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Storable (Array)+++class (Plain.SquareShape shape) => Determinant shape where+   determinant :: (Class.Floating a) => Array shape a -> a++class (Plain.SquareShape shape) => Solve shape where+   {-# MINIMAL solve | solveLeft,solveRight #-}+   solve ::+      (Class.Floating a, Box.HeightOf shape ~ height, Eq height,+       Extent.C horiz, Extent.C vert, Shape.C width) =>+      Transposition -> Array shape a ->+      Full vert horiz height width a -> Full vert horiz height width a+   solve NonTransposed a b = solveRight a b+   solve Transposed a b = Basic.transpose $ solveLeft (Basic.transpose b) a++   solveRight ::+      (Class.Floating a, Box.HeightOf shape ~ height, Eq height,+       Extent.C horiz, Extent.C vert, Shape.C width) =>+      Array shape a ->+      Full vert horiz height width a -> Full vert horiz height width a+   solveRight = solve NonTransposed++   solveLeft ::+      (Class.Floating a, Box.HeightOf shape ~ width, Eq width,+       Extent.C horiz, Extent.C vert, Shape.C height) =>+      Full vert horiz height width a ->+      Array shape a ->+      Full vert horiz height width a+   solveLeft = swapMultiply $ solve Transposed++class (Solve shape, Multiply.Power shape) => Inverse shape where+   inverse :: (Class.Floating a) => Array shape a -> Array shape a++solveVector ::+   (Solve shape, Box.HeightOf shape ~ height, Eq height, Class.Floating a) =>+   Transposition -> Array shape a -> Vector height a -> Vector height a+solveVector trans = Basic.unliftColumn MatrixShape.ColumnMajor . solve trans+++instance+   (vert ~ Small, horiz ~ Small, Shape.C height, height ~ width) =>+      Determinant (MatrixShape.Full vert horiz height width) where+   determinant = Square.determinant++instance+   (vert ~ Small, horiz ~ Small, Shape.C height, height ~ width) =>+      Solve (MatrixShape.Full vert horiz height width) where+   solveRight = Square.solve+   solveLeft = swapMultiply $ Square.solve . Square.transpose++instance+   (vert ~ Small, horiz ~ Small, Shape.C height, height ~ width) =>+      Inverse (MatrixShape.Full vert horiz height width) where+   inverse = Square.inverse+++instance (Shape.C shape) => Determinant (MatrixShape.Hermitian shape) where+   determinant = Scalar.fromReal . Hermitian.determinant++instance (Shape.C shape) => Solve (MatrixShape.Hermitian shape) where+   solveRight = Hermitian.solve+   solveLeft = swapMultiply $ Hermitian.solve . Vector.conjugate++instance (Shape.C shape) => Inverse (MatrixShape.Hermitian shape) where+   inverse = Hermitian.inverse+++instance+   (MatrixShape.Content lo, MatrixShape.Content up,+    MatrixShape.TriDiag diag, Shape.C shape) =>+      Determinant (MatrixShape.Triangular lo diag up shape) where+   determinant = Triangular.determinant++instance+   (MatrixShape.Content lo, MatrixShape.Content up,+    MatrixShape.TriDiag diag, Shape.C shape) =>+      Solve (MatrixShape.Triangular lo diag up shape) where+   solveRight = Triangular.solve+   solveLeft = swapMultiply $ Triangular.solve . Triangular.transpose++instance+   (Triangular.PowerContentDiag lo diag up, Shape.C shape) =>+      Inverse (MatrixShape.Triangular lo diag up shape) where+   inverse = Triangular.inverse+++instance+   (Unary.Natural sub, Unary.Natural super, vert ~ Small, horiz ~ Small,+    Shape.C width, Shape.C height, width ~ height) =>+      Determinant (MatrixShape.Banded sub super vert horiz height width) where+   determinant = Banded.determinant++instance+   (Unary.Natural sub, Unary.Natural super, vert ~ Small, horiz ~ Small,+    Shape.C width, Shape.C height, width ~ height) =>+      Solve (MatrixShape.Banded sub super vert horiz height width) where+   solveRight = Banded.solve+   solveLeft = swapMultiply $ Banded.solve . Banded.transpose+++{- |+There is no solver for general banded Hermitian matrices.+Thus the instance will fail for an indefinite matrix.+-}+instance+   (Unary.Natural offDiag, Shape.C size) =>+      Determinant (MatrixShape.BandedHermitian offDiag size) where+   determinant = Scalar.fromReal . BandedHermitianPositiveDefinite.determinant++{- |+There is no solver for indefinite matrices.+Thus the instance will fail for indefinite but solvable systems.+-}+instance+   (Unary.Natural offDiag, Shape.C size) =>+      Solve (MatrixShape.BandedHermitian offDiag size) where+   solveRight = BandedHermitianPositiveDefinite.solve+   solveLeft =+      swapMultiply $ BandedHermitianPositiveDefinite.solve . Vector.conjugate
+ src/Numeric/LAPACK/Matrix/Plain/Format.hs view
@@ -0,0 +1,348 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE ConstraintKinds #-}+module Numeric.LAPACK.Matrix.Plain.Format where++import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import qualified Numeric.LAPACK.Vector as Vector+import qualified Numeric.LAPACK.Output as Output+import Numeric.LAPACK.Output (Output, formatRow, (<+>))+import Numeric.LAPACK.Matrix.Shape.Private+         (Order(RowMajor, ColumnMajor), Filled(Filled), UnaryProxy)+import Numeric.LAPACK.Matrix.Private (Full)+import Numeric.LAPACK.Scalar (conjugate)+import Numeric.LAPACK.Private (caseRealComplexFunc)++import qualified Numeric.Netlib.Class as Class++import qualified Type.Data.Num.Unary.Literal as TypeNum+import qualified Type.Data.Num.Unary as Unary+import Type.Data.Num (integralFromProxy)++import qualified Data.Array.Comfort.Storable.Unchecked as Array+import qualified Data.Array.Comfort.Boxed as BoxedArray+import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Storable (Array)+import Data.Array.Comfort.Shape ((:+:))++import Text.Printf (PrintfArg, printf)++import qualified Data.List.Match as Match+import qualified Data.List.HT as ListHT+import Data.Functor.Compose (Compose(Compose, getCompose))+import Data.Foldable (Foldable, fold)+import Data.List (mapAccumL, transpose)+import Data.Complex (Complex((:+)))+import Data.Ix (Ix)+++deflt :: String+deflt = "%.4g"+++class (Shape.C sh) => FormatArray sh where+   {-+   We use constraint @(Class.Floating a)@ and not @(Format a)@+   because it allows us to align the components of complex numbers.+   -}+   formatArray :: (Class.Floating a, Output out) => String -> Array sh a -> out++instance (Integral i) => FormatArray (Shape.ZeroBased i) where+   formatArray = formatVector++instance (Integral i) => FormatArray (Shape.OneBased i) where+   formatArray = formatVector++instance (Ix i) => FormatArray (Shape.Range i) where+   formatArray = formatVector++instance (Integral i) => FormatArray (Shape.Shifted i) where+   formatArray = formatVector++instance (Enum enum, Bounded enum) => FormatArray (Shape.Enumeration enum) where+   formatArray = formatVector++instance (FormatArray sh) => FormatArray (Shape.Deferred sh) where+   formatArray fmt =+      formatArray fmt . Array.mapShape (\(Shape.Deferred sh) -> sh)++instance (FormatArray sh0, FormatArray sh1) => FormatArray (sh0:+:sh1) where+   formatArray fmt v =+      formatArray fmt (Vector.takeLeft v)+      <+>+      formatArray fmt (Vector.takeRight v)++formatVector ::+   (Shape.C sh, Class.Floating a, Output out) => String -> Array sh a -> out+formatVector fmt =+   formatRow . map (Output.text . fold . printfFloating fmt) . Array.toList++instance+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+      FormatArray (MatrixShape.Full vert horiz height width) where+   formatArray = formatFull++formatFull ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Output out, Class.Floating a) =>+   String -> Full vert horiz height width a -> out+formatFull fmt m =+   let MatrixShape.Full order extent = Array.shape m+   in  formatAligned (printfFloating fmt) $+       splitRows order (Extent.dimensions extent) $ Array.toList m++instance+   (Eq lower, Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+      FormatArray (MatrixShape.Split lower vert horiz height width) where+   formatArray = formatHouseholder++formatHouseholder ::+   (Eq lower, Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a, Output out) =>+   String -> Array (MatrixShape.Split lower vert horiz height width) a -> out+formatHouseholder fmt m =+   let MatrixShape.Split _ order extent = Array.shape m+   in formatSeparateTriangle (printfFloating fmt) $+      splitRows order (Extent.dimensions extent) $ Array.toList m++instance (Shape.C size) => FormatArray (MatrixShape.Hermitian size) where+   formatArray = formatHermitian++formatHermitian ::+   (Shape.C size, Class.Floating a, Output out) =>+   String -> Array (MatrixShape.Hermitian size) a -> out+formatHermitian fmt m =+   let MatrixShape.Hermitian order size = Array.shape m+   in  formatSeparateTriangle (printfFloating fmt) $+       complementTriangle conjugate order (Shape.size size) $ Array.toList m++formatSymmetric ::+   (Shape.C size, Class.Floating a, Output out) =>+   String -> Array (MatrixShape.Symmetric size) a -> out+formatSymmetric fmt m =+   let MatrixShape.Triangular _diag (Filled, Filled) order size = Array.shape m+   in  formatSeparateTriangle (printfFloating fmt) $+       complementTriangle id order (Shape.size size) $ Array.toList m++complementTriangle ::+   (Class.Floating a) => (a -> a) -> Order -> Int -> [a] -> [[a]]+complementTriangle adapt order n xs =+   let mergeTriangles lower upper =+         zipWith (++) (map (map adapt . init) lower) upper+   in case order of+         RowMajor ->+            let tri = slice (take n $ iterate pred n) xs+                trans = reverse $ transpose $ map reverse tri+            in  mergeTriangles trans tri+         ColumnMajor ->+            let tri = slice (take n [1..]) xs+            in  mergeTriangles tri (transpose tri)++instance+   (MatrixShape.Content lo, MatrixShape.Content up,+    MatrixShape.TriDiag diag, Shape.C size) =>+      FormatArray (MatrixShape.Triangular lo diag up size) where+   formatArray fmt =+      getFormatTriangular $+      MatrixShape.switchDiagUpLoSym+         (FormatTriangular $ \m ->+            let MatrixShape.Triangular _diag _uplo order size = Array.shape m+            in formatDiagonal fmt order size $ Array.toList m)+         (FormatTriangular $ formatTriangular fmt)+         (FormatTriangular $ formatTriangular fmt)+         (FormatTriangular $+            formatSymmetric fmt .+            Array.mapShape MatrixShape.strictNonUnitDiagonal)++formatDiagonal ::+   (Shape.C size, Class.Floating a, Output out) =>+   String -> Order -> size -> [a] -> out+formatDiagonal fmt order size xs =+   let n0 = Unary.unary TypeNum.u0+   in formatAligned (printfFloatingMaybe fmt) $+      padBanded (n0,n0) order (size,size) xs+++newtype FormatTriangular diag size a b lo up =+   FormatTriangular {+      getFormatTriangular ::+         Array (MatrixShape.Triangular lo diag up size) a -> b+   }++formatTriangular ::+   (MatrixShape.TriDiag diag, MatrixShape.UpLo lo up,+    Shape.C size, Class.Floating a, Output out) =>+   String -> Array (MatrixShape.Triangular lo diag up size) a -> out+formatTriangular fmt m =+   let MatrixShape.Triangular _diag uplo order size = Array.shape m+   in  formatAligned (printfFloatingMaybe fmt) $+       MatrixShape.caseLoUp uplo+         padLowerTriangle padUpperTriangle order (Shape.size size) $+       Array.toList m++padUpperTriangle :: Order -> Int -> [a] -> [[Maybe a]]+padUpperTriangle order n xs =+   let mxs = map Just xs+       nothings = iterate (Nothing:) []+   in case order of+         RowMajor ->+            zipWith (++) nothings (slice (take n $ iterate pred n) mxs)+         ColumnMajor ->+            transpose $+            zipWith (++)+               (slice (take n [1..]) mxs)+               (reverse $ take n nothings)++padLowerTriangle :: Order -> Int -> [a] -> [[Maybe a]]+padLowerTriangle order n xs =+   map (map Just) $+   case order of+      RowMajor -> slice (take n [1..]) xs+      ColumnMajor ->+         foldr (\(y:ys) zs -> [y] : zipWith (:) ys zs) []+            (slice (take n $ iterate pred n) xs)++slice :: [Int] -> [a] -> [[a]]+slice ns xs =+   snd $ mapAccumL (\ys n -> let (vs,ws) = splitAt n ys in (ws,vs)) xs ns+++instance+   (Unary.Natural sub, Unary.Natural super,+    Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+      FormatArray (MatrixShape.Banded sub super vert horiz height width) where+   formatArray fmt m =+      let MatrixShape.Banded offDiag order extent = Array.shape m+      in  formatAligned (printfFloatingMaybe fmt) $+          padBanded offDiag order (Extent.dimensions extent) $+          Array.toList m++padBanded ::+   (Shape.C height, Shape.C width, Unary.Natural sub, Unary.Natural super) =>+   (UnaryProxy sub, UnaryProxy super) -> Order ->+   (height, width) -> [a] -> [[Maybe a]]+padBanded (sub,super) order (height,width) xs =+   let slices =+         ListHT.sliceVertical (MatrixShape.bandedBreadth (sub,super)) xs+       m = Shape.size height+       n = Shape.size width+   in case order of+         RowMajor ->+            map (take n) $+            zipWith (shiftRow Nothing)+               (iterate (1+) (- integralFromProxy sub))+               (map (map Just) slices)+         ColumnMajor ->+            let ku = integralFromProxy super+            in take m $ drop ku $+               foldr+                  (\col mat ->+                     zipWith (:) (map Just col ++ repeat Nothing) ([]:mat))+                  (replicate (ku + m - n) [])+                  slices+++instance+   (Unary.Natural offDiag, Shape.C size) =>+      FormatArray (MatrixShape.BandedHermitian offDiag size) where+   formatArray fmt m =+      let MatrixShape.BandedHermitian offDiag order size = Array.shape m+      in  formatSeparateTriangle (printfFloatingMaybe fmt) $+          padBandedHermitian offDiag order size $ Array.toList m++padBandedHermitian ::+   (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>+   UnaryProxy offDiag -> Order -> size -> [a] -> [[Maybe a]]+padBandedHermitian offDiag order _size xs =+   let k = integralFromProxy offDiag+       slices = ListHT.sliceVertical (k + 1) xs+   in case order of+         RowMajor ->+            foldr+               (\row square ->+                  Match.take ([]:square) (map Just row)+                  :+                  zipWith (:)+                     (tail $ map (Just . conjugate) row ++ repeat Nothing)+                     square)+               [] slices+         ColumnMajor ->+            zipWith (shiftRow Nothing) (iterate (1+) (-k)) $ map (map Just) $+            zipWith (++)+               (map (map conjugate . init) slices)+               (drop k $+                foldr+                  (\column band ->+                     zipWith (++) (map (:[]) column ++ repeat []) ([]:band))+                  (replicate k [])+                  slices)++shiftRow :: a -> Int -> [a] -> [a]+shiftRow pad k = if k<=0 then drop (-k) else (replicate k pad ++)++splitRows ::+   (Shape.C height, Shape.C width) =>+   Order -> (height, width) -> [a] -> [[a]]+splitRows order (height,width) =+   case order of+      RowMajor -> ListHT.sliceVertical (Shape.size width)+      ColumnMajor -> ListHT.sliceHorizontal (Shape.size height)+++formatAligned ::+   (Functor f, Foldable f) => Output out => (a -> f String) -> [[a]] -> out+formatAligned printFmt =+   Output.formatAligned . map (map (fmap Output.text . printFmt))++formatSeparateTriangle ::+   (Functor f, Foldable f) => Output out => (a -> f String) -> [[a]] -> out+formatSeparateTriangle printFmt =+   Output.formatSeparateTriangle . map (map (fmap Output.text . printFmt))++++data TupleShape a = TupleShape++instance (Class.Floating a) => Shape.C (TupleShape a) where+   size sh = caseRealComplexFunc sh 1 2++type Tuple a = BoxedArray.Array (TupleShape a)++fillTuple :: (Class.Floating a) => b -> Tuple a b+fillTuple = BoxedArray.replicate TupleShape+++newtype ToTuple a = ToTuple {getToTuple :: a -> Tuple a String}++printfFloating :: (Class.Floating a) => String -> a -> Tuple a String+printfFloating fmt =+   getToTuple $+   Class.switchFloating+      (ToTuple $ fillTuple . printf fmt)+      (ToTuple $ fillTuple . printf fmt)+      (ToTuple $ printfComplex fmt)+      (ToTuple $ printfComplex fmt)++printfFloatingMaybe ::+   (Class.Floating a) => String -> Maybe a -> Tuple a String+printfFloatingMaybe = maybe (fillTuple "") . printfFloating++printfComplex ::+   (Class.Real a) => String -> Complex a -> Tuple (Complex a) String+printfComplex fmt =+   getToTuple $ getCompose $+   Class.switchReal+      (Compose $ ToTuple $ printfComplexAux fmt)+      (Compose $ ToTuple $ printfComplexAux fmt)++printfComplexAux ::+   (PrintfArg a, Class.Real a) =>+   String -> Complex a -> Tuple (Complex a) String+printfComplexAux fmt (r:+i) =+   if i<0 || isNegativeZero i+     then complexTuple (printf (fmt ++ "-") r) (printf (fmt ++ "i") (-i))+     else complexTuple (printf (fmt ++ "+") r) (printf (fmt ++ "i") i)++complexTuple :: (Class.Real a) => b -> b -> Tuple (Complex a) b+complexTuple b0 b1 = BoxedArray.fromList TupleShape [b0,b1]
+ src/Numeric/LAPACK/Matrix/Plain/Indexed.hs view
@@ -0,0 +1,86 @@+{-# LANGUAGE TypeFamilies #-}+module Numeric.LAPACK.Matrix.Plain.Indexed 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 Numeric.LAPACK.Scalar (conjugate, zero)++import qualified Numeric.Netlib.Class as Class++import qualified Type.Data.Num.Unary as Unary++import qualified Data.Array.Comfort.Storable.Unchecked as UArray+import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Storable (Array, (!))++import Data.Tuple.HT (swap)+import Data.Bool.HT (if')+++infixl 9 #!++class (Box.Box sh) => Indexed sh where+   (#!) ::+      (Class.Floating a) =>+      Array sh a ->+      (Shape.Index (Box.HeightOf sh), Shape.Index (Box.WidthOf sh)) -> a++instance+   (Extent.C vert, Extent.C horiz, Shape.Indexed height, Shape.Indexed width) =>+      Indexed (MatrixShape.Full vert horiz height width) where+   (#!) = (!)++instance (Shape.Indexed size) => Indexed (MatrixShape.Hermitian size) where+   arr#!ij =+      if Shape.inBounds (UArray.shape arr) ij+         then arr UArray.! ij+         else conjugate $ arr ! swap ij++instance+   (MatrixShape.Content lo, MatrixShape.TriDiag diag, MatrixShape.Content up,+    Shape.Indexed size) =>+      Indexed (MatrixShape.Triangular lo diag up size) where+   arr#!ij =+      let sh = UArray.shape arr+      in if Shape.inBounds sh ij+            then arr UArray.! ij+            else+               MatrixShape.caseDiagUpLoSym (MatrixShape.triangularUplo sh)+                  (checkedZero "Diagonal" sh ij)+                  (checkedZero "UpperTriangular" sh ij)+                  (checkedZero "LowerTriangular" sh ij)+                  (arr ! swap ij)++instance+   (Unary.Natural sub, Unary.Natural super,+    Extent.C vert, Extent.C horiz, Shape.Indexed height, Shape.Indexed width) =>+      Indexed (MatrixShape.Banded sub super vert horiz height width) where+   arr#!ij =+      let boxIx = uncurry MatrixShape.InsideBox+          sh = UArray.shape arr+      in if Shape.inBounds sh $ boxIx ij+            then arr UArray.! boxIx ij+            else checkedZero "Banded" sh ij++instance+   (Unary.Natural off, Shape.Indexed size) =>+      Indexed (MatrixShape.BandedHermitian off size) where+   arr#!ij =+      let boxIx = uncurry MatrixShape.InsideBox+          sh = UArray.shape arr+      in if' (Shape.inBounds sh $ boxIx ij)+            (arr UArray.! boxIx ij) $+         if' (Shape.inBounds sh $ boxIx $ swap ij)+            (conjugate $ arr UArray.! boxIx (swap ij))+         (checkedZero "BandedHermitian" sh ij)++checkedZero ::+   (Box.Box shape, Class.Floating a,+    Box.HeightOf shape ~ height, Shape.Indexed height,+    Box.WidthOf shape ~ width, Shape.Indexed width) =>+   String -> shape -> (Shape.Index height, Shape.Index width) -> a+checkedZero name sh ij =+   if Shape.inBounds (Box.height sh, Box.width sh) ij+      then zero+      else error $ "Matrix.Indexed." ++ name ++ ": index out of range"
+ src/Numeric/LAPACK/Matrix/Plain/Multiply.hs view
@@ -0,0 +1,608 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE UndecidableInstances #-}+module Numeric.LAPACK.Matrix.Plain.Multiply where++import qualified Numeric.LAPACK.Matrix.Plain.Class as Plain+import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Shape.Box as Box+import qualified Numeric.LAPACK.Matrix.Extent.Private as ExtentPriv+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 Numeric.LAPACK.Matrix.Shape.Private (Empty, Filled, Unit, NonUnit)+import Numeric.LAPACK.Matrix.Extent.Private (Small)+import Numeric.LAPACK.Matrix.Triangular.Basic (Triangular)+import Numeric.LAPACK.Matrix.Basic (swapMultiply, transpose)+import Numeric.LAPACK.Matrix.Modifier (Transposition(NonTransposed, Transposed))+import Numeric.LAPACK.Matrix.Private (Square, Full, mapExtent)+import Numeric.LAPACK.Vector (Vector)++import qualified Numeric.Netlib.Class as Class++import qualified Type.Data.Num.Unary as Unary+import Type.Data.Num.Unary ((:+:))++import qualified Data.Array.Comfort.Storable.Unchecked as Array+import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Storable.Unchecked (Array)++++class (Box.Box shape) => Scale shape where+   scale :: (Class.Floating a) => a -> Array shape a -> Array shape a+   scale = Vector.scale++instance+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+      Scale (MatrixShape.Full vert horiz height width) where++instance+   (MatrixShape.Content lo, MatrixShape.Content up,+    diag ~ NonUnit, Shape.C size) =>+      Scale (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) =>+      Scale (MatrixShape.Banded sub super vert horiz height width) where+++class (Box.Box shape) => MultiplyVector shape where+   matrixVector ::+      (Box.WidthOf shape ~ width, Eq width, Class.Floating a) =>+      Array shape a -> Vector width a -> Vector (Box.HeightOf shape) a+   vectorMatrix ::+      (Box.HeightOf shape ~ height, Eq height, Class.Floating a) =>+      Vector height a -> Array shape a -> Vector (Box.WidthOf shape) a+++instance+   (Extent.C vert, Extent.C horiz, Shape.C width, Shape.C height) =>+      MultiplyVector (MatrixShape.Full vert horiz height width) where+   matrixVector = Basic.multiplyVector+   vectorMatrix v m = Basic.multiplyVector (transpose m) v+++instance (Shape.C shape) => MultiplyVector (MatrixShape.Hermitian shape) where+   matrixVector = Hermitian.multiplyVector NonTransposed+   vectorMatrix = flip $ Hermitian.multiplyVector Transposed+++instance+   (MatrixShape.Content lo, MatrixShape.Content up,+    MatrixShape.TriDiag diag, Shape.C shape) =>+      MultiplyVector (MatrixShape.Triangular lo diag up shape) where+   matrixVector m v = Triangular.multiplyVector m v+   vectorMatrix v m = Triangular.multiplyVector (Triangular.transpose m) v+++instance+   (Unary.Natural sub, Unary.Natural super,+    Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+      MultiplyVector (MatrixShape.Banded sub super vert horiz height width) where+   matrixVector m v = Banded.multiplyVector m v+   vectorMatrix v m = Banded.multiplyVector (Banded.transpose m) v+++instance+   (Unary.Natural offDiag, Shape.C size) =>+      MultiplyVector (MatrixShape.BandedHermitian offDiag size) where+   matrixVector = BandedHermitian.multiplyVector NonTransposed+   vectorMatrix = flip $ BandedHermitian.multiplyVector Transposed++++class (Plain.SquareShape shape) => MultiplySquare shape where+   {-# MINIMAL transposableSquare | fullSquare,squareFull #-}+   transposableSquare ::+      (Box.HeightOf shape ~ height, Eq height, Shape.C width,+       Extent.C horiz, Extent.C vert, Class.Floating a) =>+      Transposition -> Array shape a ->+      Full vert horiz height width a -> Full vert horiz height width a+   transposableSquare NonTransposed a b = squareFull a b+   transposableSquare Transposed a b = transpose $ fullSquare (transpose b) a++   squareFull ::+      (Box.HeightOf shape ~ height, Eq height, Shape.C width,+       Extent.C horiz, Extent.C vert, Class.Floating a) =>+      Array shape a ->+      Full vert horiz height width a -> Full vert horiz height width a+   squareFull = transposableSquare NonTransposed++   fullSquare ::+      (Box.WidthOf shape ~ width, Eq width, Shape.C height,+       Extent.C horiz, Extent.C vert, Class.Floating a) =>+      Full vert horiz height width a ->+      Array shape a -> Full vert horiz height width a+   fullSquare = swapMultiply $ transposableSquare Transposed++instance+   (vert ~ Small, horiz ~ Small, Shape.C height, height ~ width) =>+      MultiplySquare (MatrixShape.Full vert horiz height width) where+   transposableSquare NonTransposed = squareFull+   transposableSquare Transposed = squareFull . transpose+   squareFull a b = Basic.multiply (mapExtent Extent.fromSquare a) b++instance (Shape.C shape) => MultiplySquare (MatrixShape.Hermitian shape) where+   transposableSquare = Hermitian.multiplyFull++instance+   (MatrixShape.Content lo, MatrixShape.Content up,+    MatrixShape.TriDiag diag, Shape.C shape) =>+      MultiplySquare (MatrixShape.Triangular lo diag up shape) where+   squareFull = Triangular.multiplyFull+   fullSquare =+      swapMultiply $ Triangular.multiplyFull . Triangular.transpose++instance+   (Unary.Natural sub, Unary.Natural super,+    vert ~ Small, horiz ~ Small, Shape.C height, height ~ width) =>+      MultiplySquare+         (MatrixShape.Banded sub super vert horiz height width) where+   squareFull = Banded.multiplyFull . bandedGenSquare+   fullSquare =+      swapMultiply $ Banded.multiplyFull . bandedGenSquare . Banded.transpose++bandedGenSquare ::+   (Extent.C vert, Extent.C horiz) =>+   Banded.Square sub super size a ->+   Banded.Banded sub super vert horiz size size a+bandedGenSquare = Banded.mapExtent Extent.fromSquare++instance+   (Unary.Natural offDiag, Shape.C size) =>+      MultiplySquare (MatrixShape.BandedHermitian offDiag size) where+   transposableSquare = BandedHermitian.multiplyFull+++class (Plain.SquareShape shape) => Power shape where+   square :: (Class.Floating a) => Array shape a -> Array shape a+   power :: (Class.Floating a) => Int -> Array shape a -> Array shape a++instance+   (Extent.Small ~ vert, Extent.Small ~ horiz,+    Shape.C height, height ~ width) =>+      Power (MatrixShape.Full vert horiz height width) where+   square = Square.square+   power = Square.power . fromIntegral++instance (Shape.C size) => Power (MatrixShape.Hermitian size) where+   square = Hermitian.square+   power = Hermitian.power . fromIntegral++instance+   (Triangular.PowerContentDiag lo diag up, Shape.C size) =>+      Power (MatrixShape.Triangular lo diag up size) where+   square = Triangular.square+   power = Triangular.power+++class (Box.Box shape) => MultiplySame shape where+   same ::+      (Class.Floating a) => Array shape a -> Array shape a -> Array shape a++instance+   (Extent.C vert, Extent.C horiz, Shape.C height, Eq height, height ~ width) =>+      MultiplySame (MatrixShape.Full vert horiz height width) where+   same = Basic.multiply++instance+   (MatrixShape.DiagUpLo lo up, MatrixShape.TriDiag diag,+    Shape.C size, Eq size) =>+      MultiplySame (MatrixShape.Triangular lo diag up size) where+   same = Triangular.multiply+++{- |+This class allows to Basic.multiply two matrices of arbitrary special features+and returns the most special matrix type possible.+At the first glance, this is handy.+At the second glance, this has some problems.+First of all, we may refine the types in future+and then multiplication may return a different, more special type than before.+Second, if you write code with polymorphic matrix types,+then 'matrixMatrix' may leave you with constraints like+@ExtentPriv.Multiply vert vert ~ vert@.+That constraint is always fulfilled but the compiler cannot infer that.+Because of these problems+you may instead consider using specialised 'Basic.multiply' functions+from the various modules for production use.+Btw. 'MultiplyVector' and 'MultiplySquare'+are much less problematic,+because the input and output are always dense vectors or dense matrices.+-}+class (Shape.C shapeA, Shape.C shapeB) => Multiply shapeA shapeB where+   type Multiplied shapeA shapeB+   matrixMatrix ::+      (Class.Floating a) =>+      Array shapeA a -> Array shapeB a -> Array (Multiplied shapeA shapeB) a++instance+   (Shape.C heightA, Shape.C widthA, Shape.C widthB,+    widthA ~ heightB, Eq heightB,+    Extent.C vertA, Extent.C horizA, Extent.C vertB, Extent.C horizB) =>+      Multiply+         (MatrixShape.Full vertA horizA heightA widthA)+         (MatrixShape.Full vertB horizB heightB widthB) where+   type Multiplied+         (MatrixShape.Full vertA horizA heightA widthA)+         (MatrixShape.Full vertB horizB heightB widthB) =+            MatrixShape.Full+               (ExtentPriv.Multiply vertA vertB)+               (ExtentPriv.Multiply horizA horizB)+               heightA widthB+   matrixMatrix a b =+      case unifyFactors (fullExtent a) (fullExtent b) of+         ((ExtentPriv.TagFact, ExtentPriv.TagFact), (unifyLeft, unifyRight)) ->+            Basic.multiply+               (mapExtent unifyLeft a)+               (mapExtent unifyRight b)++fullExtent ::+   Full vert horiz height width a ->+   Extent.Extent vert horiz height width+fullExtent = MatrixShape.fullExtent . Array.shape++unifyFactors ::+   (Extent.C vertA, Extent.C horizA, Extent.C vertB, Extent.C horizB) =>+   (ExtentPriv.Multiply vertA vertB ~ vertC) =>+   (ExtentPriv.Multiply horizA horizB ~ horizC) =>+   Extent.Extent vertA horizA height fuse ->+   Extent.Extent vertB horizB fuse width ->+   ((ExtentPriv.TagFact vertC, ExtentPriv.TagFact horizC),+    (Extent.Map vertA horizA vertC horizC height fuse,+     Extent.Map vertB horizB vertC horizC fuse width))+unifyFactors a b =+   ((ExtentPriv.multiplyTagLaw+         (ExtentPriv.heightFact a) (ExtentPriv.heightFact b),+     ExtentPriv.multiplyTagLaw+         (ExtentPriv.widthFact a) (ExtentPriv.widthFact b)),+    (ExtentPriv.Map $ flip ExtentPriv.unifyLeft b,+     ExtentPriv.Map $ ExtentPriv.unifyRight a))+++instance+   (Extent.C vert, Extent.C horiz,+    Shape.C size, size ~ width, Eq width, Shape.C height) =>+      Multiply+         (MatrixShape.Full vert horiz height width)+         (MatrixShape.Hermitian size)+            where+   type Multiplied+         (MatrixShape.Full vert horiz height width)+         (MatrixShape.Hermitian size) =+            MatrixShape.Full vert horiz height width+   matrixMatrix = fullSquare++instance+   (Extent.C vert, Extent.C horiz,+    Shape.C size, size ~ height, Eq height, Shape.C width) =>+      Multiply+         (MatrixShape.Hermitian size)+         (MatrixShape.Full vert horiz height width)+            where+   type Multiplied+         (MatrixShape.Hermitian size)+         (MatrixShape.Full vert horiz height width) =+            MatrixShape.Full vert horiz height width+   matrixMatrix = squareFull++instance+   (Shape.C shapeA, shapeA ~ shapeB, Eq shapeB) =>+      Multiply (MatrixShape.Hermitian shapeA) (MatrixShape.Hermitian shapeB)+         where+   type Multiplied+         (MatrixShape.Hermitian shapeA) (MatrixShape.Hermitian shapeB) =+            MatrixShape.Square shapeA+   matrixMatrix a = squareFull a . Hermitian.toSquare+++instance+   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,+    Extent.C vert, Extent.C horiz,+    Shape.C size, size ~ width, Eq width, Shape.C height) =>+      Multiply+         (MatrixShape.Full vert horiz height width)+         (MatrixShape.Triangular lo diag up size)+            where+   type Multiplied+         (MatrixShape.Full vert horiz height width)+         (MatrixShape.Triangular lo diag up size) =+            MatrixShape.Full vert horiz height width+   matrixMatrix = fullSquare++instance+   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,+    Extent.C vert, Extent.C horiz,+    Shape.C size, size ~ height, Eq height, Shape.C width) =>+      Multiply+         (MatrixShape.Triangular lo diag up size)+         (MatrixShape.Full vert horiz height width)+            where+   type Multiplied+         (MatrixShape.Triangular lo diag up size)+         (MatrixShape.Full vert horiz height width) =+            MatrixShape.Full vert horiz height width+   matrixMatrix = squareFull++instance+   (Shape.C sizeA, sizeA ~ sizeB, Eq sizeB,+    MultiplyTriangular loA upA loB upB,+    MatrixShape.TriDiag diagA, MatrixShape.TriDiag diagB) =>+      Multiply+         (MatrixShape.Triangular loA diagA upA sizeA)+         (MatrixShape.Triangular loB diagB upB sizeB) where+   type Multiplied+         (MatrixShape.Triangular loA diagA upA sizeA)+         (MatrixShape.Triangular loB diagB upB sizeB) =+            -- requires UndecidableInstances+            MultipliedTriangular loA diagA upA loB diagB upB sizeB+   matrixMatrix = triangularTriangular++class+   (MatrixShape.Content loA, MatrixShape.Content upA,+    MatrixShape.Content loB, MatrixShape.Content upB) =>+      MultiplyTriangular loA upA loB upB where+   triangularTriangular ::+      (Class.Floating a, Shape.C size, Eq size,+       MatrixShape.TriDiag diagA, MatrixShape.TriDiag diagB) =>+      Triangular loA diagA upA size a ->+      Triangular loB diagB upB size a ->+      Array (MultipliedTriangular loA diagA upA loB diagB upB size) a+++type MultipliedTriangular loA diagA upA loB diagB upB size =+   ComposedTriangular+      (MultipliedPart loA loB)+      (MultipliedDiag diagA diagB)+      (MultipliedPart upA upB)+      size++type family MultipliedPart a b :: *+type instance MultipliedPart Empty b = b+type instance MultipliedPart Filled b = Filled++type family MultipliedDiag a b :: *+type instance MultipliedDiag Unit b = b+type instance MultipliedDiag NonUnit b = NonUnit++type family ComposedTriangular lo diag up size :: *+type instance ComposedTriangular Empty diag up size =+         MatrixShape.Triangular Empty diag up size+type instance ComposedTriangular Filled diag Empty size =+         MatrixShape.LowerTriangular diag size+type instance ComposedTriangular Filled diag Filled size =+         MatrixShape.Square size+++instance MultiplyTriangular Empty Empty Empty Empty where+   triangularTriangular = triangularTriangularConform++instance MultiplyTriangular Empty Empty Filled Filled where+   triangularTriangular a = Triangular.multiplyFull a . Triangular.toSquare++instance MultiplyTriangular Empty Filled Filled Filled where+   triangularTriangular a = Triangular.multiplyFull a . Triangular.toSquare++instance MultiplyTriangular Filled Empty Filled Filled where+   triangularTriangular a = Triangular.multiplyFull a . Triangular.toSquare++instance MultiplyTriangular Empty Filled Empty Filled where+   triangularTriangular = triangularTriangularConform++instance MultiplyTriangular Filled Empty Filled Empty where+   triangularTriangular = triangularTriangularConform++instance MultiplyTriangular Filled Empty Empty Filled where+   triangularTriangular a = Triangular.multiplyFull a . Triangular.toSquare++instance MultiplyTriangular Empty Filled Filled Empty where+   triangularTriangular a = Triangular.multiplyFull a . Triangular.toSquare++instance MultiplyTriangular Filled Filled Empty Empty where+   triangularTriangular = triangularTriangularToSquare++instance MultiplyTriangular Filled Filled Empty Filled where+   triangularTriangular = triangularTriangularToSquare++instance MultiplyTriangular Filled Filled Filled Empty where+   triangularTriangular = triangularTriangularToSquare++instance MultiplyTriangular Filled Filled Filled Filled where+   triangularTriangular = triangularTriangularToSquare++triangularTriangularToSquare ::+   (MatrixShape.Content loA, MatrixShape.Content upA, MatrixShape.TriDiag diagA,+    MatrixShape.Content loB, MatrixShape.Content upB, MatrixShape.TriDiag diagB,+    Shape.C size, Eq size, Class.Floating a) =>+   Triangular loA diagA upA size a ->+   Triangular loB diagB upB size a ->+   Square size a+triangularTriangularToSquare = fullSquare . Triangular.toSquare+++newtype TriangularTriangularConform lo up size a diagB diagA =+   TriangularTriangularConform {+      getTriangularTriangularConform ::+         Triangular lo diagA up size a ->+         Triangular lo diagB up size a ->+         Triangular lo (MultipliedDiag diagA diagB) up size a+   }++triangularTriangularConform ::+   (Shape.C size, Eq size, Class.Floating a,+    MatrixShape.DiagUpLo lo up,+    MatrixShape.TriDiag diagA, MatrixShape.TriDiag diagB) =>+   (MultipliedDiag diagA diagB ~ diagC) =>+   Triangular lo diagA up size a ->+   Triangular lo diagB up size a ->+   Triangular lo diagC up size a+triangularTriangularConform =+   getTriangularTriangularConform $+   MatrixShape.switchTriDiag+      (TriangularTriangularConform $ \a b ->+         Triangular.multiply (Triangular.relaxUnitDiagonal a) b)+      (TriangularTriangularConform $ \a b ->+         Triangular.multiply a (Triangular.strictNonUnitDiagonal b))+++instance+   (Unary.Natural sub, Unary.Natural super,+    Extent.C vertA, Extent.C horizA,+    Extent.C vertB, Extent.C horizB,+    Shape.C heightA, Shape.C widthA, Shape.C widthB,+    widthA ~ heightB, Eq heightB) =>+      Multiply+         (MatrixShape.Full vertA horizA heightA widthA)+         (MatrixShape.Banded sub super vertB horizB heightB widthB)+            where+   type Multiplied+         (MatrixShape.Full vertA horizA heightA widthA)+         (MatrixShape.Banded sub super vertB horizB heightB widthB) =+            MatrixShape.Full+               (ExtentPriv.Multiply vertA vertB)+               (ExtentPriv.Multiply horizA horizB)+               heightA widthB+   matrixMatrix a b =+      case unifyFactors (fullExtent a) (bandedExtent b) of+         ((ExtentPriv.TagFact, ExtentPriv.TagFact), (unifyLeft, unifyRight)) ->+            swapMultiply (Banded.multiplyFull . Banded.transpose)+               (mapExtent unifyLeft a)+               (Banded.mapExtent unifyRight b)++instance+   (Unary.Natural sub, Unary.Natural super,+    Extent.C vertA, Extent.C horizA,+    Extent.C vertB, Extent.C horizB,+    Shape.C heightA, Shape.C widthA, Shape.C widthB,+    widthA ~ heightB, Eq heightB) =>+      Multiply+         (MatrixShape.Banded sub super vertA horizA heightA widthA)+         (MatrixShape.Full vertB horizB heightB widthB)+            where+   type Multiplied+         (MatrixShape.Banded sub super vertA horizA heightA widthA)+         (MatrixShape.Full vertB horizB heightB widthB) =+            MatrixShape.Full+               (ExtentPriv.Multiply vertA vertB)+               (ExtentPriv.Multiply horizA horizB)+               heightA widthB+   matrixMatrix a b =+      case unifyFactors (bandedExtent a) (fullExtent b) of+         ((ExtentPriv.TagFact, ExtentPriv.TagFact), (unifyLeft, unifyRight)) ->+            Banded.multiplyFull+               (Banded.mapExtent unifyLeft a)+               (mapExtent unifyRight b)++instance+   (Unary.Natural subA, Unary.Natural superA,+    Unary.Natural subB, Unary.Natural superB,+    Extent.C vertA, Extent.C horizA,+    Extent.C vertB, Extent.C horizB,+    Shape.C heightA, Shape.C widthA, Shape.C widthB,+    widthA ~ heightB, Eq heightB) =>+      Multiply+         (MatrixShape.Banded subA superA vertA horizA heightA widthA)+         (MatrixShape.Banded subB superB vertB horizB heightB widthB) where+   type Multiplied+         (MatrixShape.Banded subA superA vertA horizA heightA widthA)+         (MatrixShape.Banded subB superB vertB horizB heightB widthB) =+            MatrixShape.Banded+               (subA :+: subB) (superA :+: superB)+               (ExtentPriv.Multiply vertA vertB)+               (ExtentPriv.Multiply horizA horizB)+               heightA widthB+   matrixMatrix a b =+      case unifyFactors (bandedExtent a) (bandedExtent b) of+         ((ExtentPriv.TagFact, ExtentPriv.TagFact), (unifyLeft, unifyRight)) ->+            Banded.multiply+               (Banded.mapExtent unifyLeft a)+               (Banded.mapExtent unifyRight b)++bandedExtent ::+   Banded.Banded sup super vert horiz height width a ->+   Extent.Extent vert horiz height width+bandedExtent = MatrixShape.bandedExtent . Array.shape+++instance+   (Unary.Natural offDiag, Extent.C vert, Extent.C horiz,+    Shape.C size, size ~ width, Eq width, Shape.C height, Eq height) =>+      Multiply+         (MatrixShape.Full vert horiz height width)+         (MatrixShape.BandedHermitian offDiag size)+            where+   type Multiplied+         (MatrixShape.Full vert horiz height width)+         (MatrixShape.BandedHermitian offDiag size) =+            MatrixShape.Full vert horiz height width+   matrixMatrix = fullSquare++instance+   (Unary.Natural offDiag, Extent.C vert, Extent.C horiz,+    Shape.C size, size ~ height, Eq height, Shape.C width, Eq width) =>+      Multiply+         (MatrixShape.BandedHermitian offDiag size)+         (MatrixShape.Full vert horiz height width)+            where+   type Multiplied+         (MatrixShape.BandedHermitian offDiag size)+         (MatrixShape.Full vert horiz height width) =+            MatrixShape.Full vert horiz height width+   matrixMatrix = squareFull++instance+   (Unary.Natural offDiag, Unary.Natural sub, Unary.Natural super,+    Extent.C vert, Extent.C horiz,+    Shape.C size, size ~ width, Eq width, Shape.C height, Eq height) =>+      Multiply+         (MatrixShape.Banded sub super vert horiz height width)+         (MatrixShape.BandedHermitian offDiag size)+            where+   type Multiplied+         (MatrixShape.Banded sub super vert horiz height width)+         (MatrixShape.BandedHermitian offDiag size) =+            MatrixShape.Banded+               (sub:+:offDiag) (super:+:offDiag) vert horiz height width+   matrixMatrix a b =+      Banded.multiply a (bandedGenSquare $ BandedHermitian.toBanded b)++instance+   (Unary.Natural offDiag, Unary.Natural sub, Unary.Natural super,+    Extent.C vert, Extent.C horiz,+    Shape.C size, size ~ height, Eq height, Shape.C width, Eq width) =>+      Multiply+         (MatrixShape.BandedHermitian offDiag size)+         (MatrixShape.Banded sub super vert horiz height width)+            where+   type Multiplied+         (MatrixShape.BandedHermitian offDiag size)+         (MatrixShape.Banded sub super vert horiz height width) =+            MatrixShape.Banded+               (offDiag:+:sub) (offDiag:+:super) vert horiz height width+   matrixMatrix a b =+      Banded.multiply (bandedGenSquare $ BandedHermitian.toBanded a) b++instance+   (Unary.Natural offDiagA, Unary.Natural offDiagB,+    Shape.C sizeA, sizeA ~ sizeB, Shape.C sizeB, Eq sizeB) =>+      Multiply+         (MatrixShape.BandedHermitian offDiagA sizeA)+         (MatrixShape.BandedHermitian offDiagB sizeB)+            where+   type Multiplied+         (MatrixShape.BandedHermitian offDiagA sizeA)+         (MatrixShape.BandedHermitian offDiagB sizeB) =+            MatrixShape.Banded+               (offDiagA:+:offDiagB) (offDiagA:+:offDiagB)+               Small Small sizeA sizeB+   matrixMatrix a b =+      Banded.multiply (BandedHermitian.toBanded a) (BandedHermitian.toBanded b)
src/Numeric/LAPACK/Matrix/Private.hs view
@@ -3,7 +3,6 @@ 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 Numeric.LAPACK.Matrix.Shape.Private (Order, flipOrder)  import qualified Data.Array.Comfort.Storable.Unchecked as Array import qualified Data.Array.Comfort.Shape as Shape@@ -33,10 +32,10 @@    f order (Extent.squareSize extent) a  -type ZeroInt = Shape.ZeroBased Int+type ShapeInt = Shape.ZeroBased Int -zeroInt :: Int -> ZeroInt-zeroInt = Shape.ZeroBased+shapeInt :: Int -> ShapeInt+shapeInt = Shape.ZeroBased   mapExtent ::@@ -69,19 +68,12 @@ width = Box.width . Array.shape  -data Transposition = NonTransposed | Transposed-   deriving (Eq, Show, Enum, Bounded)--transposeOrder :: Transposition -> Order -> Order-transposeOrder NonTransposed = id-transposeOrder Transposed = flipOrder--data Conjugation = NonConjugated | Conjugated-   deriving (Eq, Show, Enum, Bounded)--data Inversion = NonInverted | Inverted-   deriving (Eq, Show, Enum, Bounded)--flipInversion :: Inversion -> Inversion-flipInversion NonInverted = Inverted-flipInversion Inverted = NonInverted+revealOrder ::+   (Extent.C horiz, Extent.C vert) =>+   Full vert horiz height width a ->+   Either (Array (height,width) a) (Array (width,height) a)+revealOrder (Array (MatrixShape.Full order extent) a) =+   let (h,w) = Extent.dimensions extent+   in case order of+         MatrixShape.RowMajor -> Left $ Array (h,w) a+         MatrixShape.ColumnMajor -> Right $ Array (w,h) a
+ src/Numeric/LAPACK/Matrix/RowMajor.hs view
@@ -0,0 +1,212 @@+{-# LANGUAGE TypeFamilies #-}+module Numeric.LAPACK.Matrix.RowMajor where++import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import qualified Numeric.LAPACK.Private as Private+import Numeric.LAPACK.Matrix.Shape.Private (Order(RowMajor, ColumnMajor))+import Numeric.LAPACK.Matrix.Private (Full, ShapeInt, shapeInt)+import Numeric.LAPACK.Matrix.Modifier (Conjugation(NonConjugated,Conjugated))+import Numeric.LAPACK.Scalar (zero, one)+import Numeric.LAPACK.Private (ComplexPart, pointerSeq)++import qualified Numeric.BLAS.FFI.Generic as BlasGen+import qualified Numeric.Netlib.Utility as Call+import qualified Numeric.Netlib.Class as Class++import Foreign.Marshal.Array (copyArray, advancePtr)+import Foreign.ForeignPtr (withForeignPtr, castForeignPtr)+import Foreign.Storable (Storable)++import Control.Monad.Trans.Cont (ContT(ContT), evalContT)+import Control.Monad.IO.Class (liftIO)+import Control.Applicative (liftA2)++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 Data.Complex (Complex)+import Data.Foldable (forM_)+++type Matrix height width = Array (height,width)+type Vector = Array++takeRow ::+   (Shape.Indexed height, Shape.C width, Shape.Index height ~ ix,+    Storable a) =>+   ix -> Matrix height width a -> Vector width a+takeRow ix (Array (height,width) x) =+   Array.unsafeCreateWithSize width $ \n yPtr ->+   withForeignPtr x $ \xPtr ->+      copyArray yPtr (advancePtr xPtr (n * Shape.offset height ix)) n++takeColumn ::+   (Shape.C height, Shape.Indexed width, Shape.Index width ~ ix,+    Class.Floating a) =>+   ix -> Matrix height width a -> Vector height a+takeColumn ix (Array (height,width) x) =+   Array.unsafeCreateWithSize height $ \n yPtr -> evalContT $ do+      let offset = Shape.offset width ix+      nPtr <- Call.cint n+      xPtr <- ContT $ withForeignPtr x+      incxPtr <- Call.cint $ Shape.size width+      incyPtr <- Call.cint 1+      liftIO $ BlasGen.copy nPtr (advancePtr xPtr offset) incxPtr yPtr incyPtr+++fromRows ::+   (Shape.C width, Eq width, Storable a) =>+   width -> [Vector width a] -> Matrix ShapeInt width a+fromRows width rows =+   Array.unsafeCreate (shapeInt $ length rows, width) $ \dstPtr ->+   let widthSize = Shape.size width+   in forM_ (zip (pointerSeq widthSize dstPtr) rows) $+         \(dstRowPtr, Array.Array rowWidth srcFPtr) ->+         withForeignPtr srcFPtr $ \srcPtr -> do+            Call.assert+               "Matrix.fromRows: non-matching vector size"+               (width == rowWidth)+            copyArray dstRowPtr srcPtr widthSize+++tensorProduct ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   Either Conjugation Conjugation ->+   Vector height a -> Vector width a -> Matrix height width a+tensorProduct side (Array height x) (Array width y) =+   Array.unsafeCreate (height,width) $ \cPtr -> do+   let m = Shape.size width+   let n = Shape.size height+   let trans conjugated =+         case conjugated of NonConjugated -> 'T'; Conjugated -> 'C'+   let ((transa,transb),(lda,ldb)) =+         case side of+            Left c -> ((trans c, 'N'),(1,1))+            Right c -> (('N', trans c),(m,n))+   evalContT $ do+      transaPtr <- Call.char transa+      transbPtr <- Call.char transb+      mPtr <- Call.cint m+      nPtr <- Call.cint n+      kPtr <- Call.cint 1+      alphaPtr <- Call.number one+      aPtr <- ContT $ withForeignPtr y+      ldaPtr <- Call.leadingDim lda+      bPtr <- ContT $ withForeignPtr x+      ldbPtr <- Call.leadingDim ldb+      betaPtr <- Call.number zero+      ldcPtr <- Call.leadingDim m+      liftIO $+         BlasGen.gemm+            transaPtr transbPtr mPtr nPtr kPtr alphaPtr+            aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr+++decomplex ::+   (Class.Real a) =>+   Matrix height width (Complex a) ->+   Matrix height (width, Shape.Enumeration ComplexPart) a+decomplex (Array (height,width) a) =+   Array (height, (width, Shape.Enumeration)) (castForeignPtr a)++recomplex ::+   (Class.Real a) =>+   Matrix height (width, Shape.Enumeration ComplexPart) a ->+   Matrix height width (Complex a)+recomplex (Array (height, (width, Shape.Enumeration)) a) =+   Array (height,width) (castForeignPtr a)+++scaleRows ::+   (Shape.C height, Eq height, Shape.C width, Class.Floating a) =>+   Vector height a -> Matrix height width a -> Matrix height width a+scaleRows (Array heightX x) (Array shape@(height,width) a) =+      Array.unsafeCreate shape $ \bPtr -> do+   Call.assert "scaleRows: sizes mismatch" (heightX == height)+   evalContT $ do+      let m = Shape.size height+      let n = Shape.size width+      nPtr <- Call.cint n+      xPtr <- ContT $ withForeignPtr x+      aPtr <- ContT $ withForeignPtr a+      incaPtr <- Call.cint 1+      incbPtr <- Call.cint 1+      liftIO $ sequence_ $ take m $+         zipWith3+            (\xkPtr akPtr bkPtr -> do+               BlasGen.copy nPtr akPtr incaPtr bkPtr incbPtr+               BlasGen.scal nPtr xkPtr bkPtr incbPtr)+            (pointerSeq 1 xPtr)+            (pointerSeq n aPtr)+            (pointerSeq n bPtr)++scaleColumns ::+   (Shape.C height, Shape.C width, Eq width, Class.Floating a) =>+   Vector width a -> Matrix height width a -> Matrix height width a+scaleColumns (Array widthX x) (Array shape@(height,width) a) =+      Array.unsafeCreate shape $ \bPtr -> do+   Call.assert "scaleColumns: sizes mismatch" (widthX == width)+   evalContT $ do+      let m = Shape.size height+      let n = Shape.size width+      transPtr <- Call.char 'N'+      nPtr <- Call.cint n+      klPtr <- Call.cint 0+      kuPtr <- Call.cint 0+      alphaPtr <- Call.number one+      xPtr <- ContT $ withForeignPtr x+      ldxPtr <- Call.leadingDim 1+      aPtr <- ContT $ withForeignPtr a+      incaPtr <- Call.cint 1+      betaPtr <- Call.number zero+      incbPtr <- Call.cint 1+      liftIO $ sequence_ $ take m $+         zipWith+            (\akPtr bkPtr ->+               Private.gbmv transPtr+                  nPtr nPtr klPtr kuPtr alphaPtr xPtr ldxPtr+                  akPtr incaPtr betaPtr bkPtr incbPtr)+            (pointerSeq n aPtr)+            (pointerSeq n bPtr)+++kronecker ::+   (Extent.C vert, Extent.C horiz,+    Shape.C heightA, Shape.C widthA, Shape.C heightB, Shape.C widthB,+    Class.Floating a) =>+   Full vert horiz heightA widthA a ->+   Matrix heightB widthB a ->+   Matrix (heightA,heightB) (widthA,widthB) a+kronecker+      (Array (MatrixShape.Full orderA extentA) a) (Array (heightB,widthB) b) =+   let (heightA,widthA) = Extent.dimensions extentA+   in Array.unsafeCreate ((heightA,heightB), (widthA,widthB)) $ \cPtr ->+      evalContT $ do+   let (ma,na) = (Shape.size heightA, Shape.size widthA)+   let (mb,nb) = (Shape.size heightB, Shape.size widthB)+   let (lda,istep) =+         case orderA of+            RowMajor -> (1,na)+            ColumnMajor -> (ma,1)+   transaPtr <- Call.char 'N'+   transbPtr <- Call.char 'T'+   mPtr <- Call.cint na+   nPtr <- Call.cint nb+   kPtr <- Call.cint 1+   alphaPtr <- Call.number one+   aPtr <- ContT $ withForeignPtr a+   ldaPtr <- Call.leadingDim lda+   bPtr <- ContT $ withForeignPtr b+   ldbPtr <- Call.leadingDim 1+   betaPtr <- Call.number zero+   ldcPtr <- Call.leadingDim nb+   liftIO $+      forM_ (liftA2 (,) (take ma [0..]) (take mb [0..])) $ \(i,j) -> do+         let aiPtr = advancePtr aPtr (istep*i)+         let bjPtr = advancePtr bPtr (nb*j)+         let cijPtr = advancePtr cPtr (na*nb*(j+mb*i))+         BlasGen.gemm+            transbPtr transaPtr nPtr mPtr kPtr alphaPtr+            bjPtr ldbPtr aiPtr ldaPtr betaPtr cijPtr ldcPtr
src/Numeric/LAPACK/Matrix/Shape.hs view
@@ -33,6 +33,7 @@    autoDiag,    autoUplo,    DiagUpLo,+   switchDiagUpLo,    switchDiagUpLoSym,    TriDiag,    switchTriDiag,
src/Numeric/LAPACK/Matrix/Shape/Private.hs view
@@ -55,6 +55,16 @@    in (side,(m,n))  +mapChecked ::+   (Shape.C sha, Shape.C shb) =>+   String -> (sha -> shb) -> sha -> shb+mapChecked name f sizeA =+   let sizeB = f sizeA+   in if Shape.size sizeA == Shape.size sizeB+         then sizeB+         else error $ name ++ ": sizes mismatch"++ data Full vert horiz height width =    Full {       fullOrder :: Order,@@ -71,7 +81,7 @@  instance    (Extent.C vert, Extent.C horiz, NFData height, NFData width) =>-       NFData (Full vert horiz height width) where+      NFData (Full vert horiz height width) where    rnf (Full order extent) = rnf (order, extent)  instance
+ src/Numeric/LAPACK/Matrix/Special.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE TypeFamilies #-}+module Numeric.LAPACK.Matrix.Special (+   Type.Matrix(Scale,Inverse), Scale, Inverse,+   ) where++import qualified Numeric.LAPACK.Matrix.Inverse as Inverse+import qualified Numeric.LAPACK.Matrix.Type as Type+++type Scale sh = Type.Matrix (Type.Scale sh)+type Inverse typ = Type.Matrix (Inverse.Inverse typ)
src/Numeric/LAPACK/Matrix/Square.hs view
@@ -1,51 +1,279 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} module Numeric.LAPACK.Matrix.Square (-   module Numeric.LAPACK.Matrix.Square.Basic,-   module Numeric.LAPACK.Matrix.Square.Linear,+   Square,+   size,+   mapSize,+   toFull,+   toGeneral,+   fromGeneral,+   fromScalar,+   toScalar,+   fromList,+   autoFromList, +   transpose,+   adjoint,++   identity,+   identityFrom,+   identityFromWidth,+   identityFromHeight,+   diagonal,+   takeDiagonal,+   trace,++   stack, (|=|),++   multiply,+   square,+   power,+   congruence,+   congruenceAdjoint,++   solve,+   inverse,+   determinant,+    eigenvalues,-   Eigen.schur,+   schur,+   schurComplex,    eigensystem,    ComplexOf,    ) where +import qualified Numeric.LAPACK.Matrix.Triangular as Triangular import qualified Numeric.LAPACK.Matrix.Square.Eigen as Eigen-import Numeric.LAPACK.Matrix.Square.Basic-import Numeric.LAPACK.Matrix.Square.Linear+import qualified Numeric.LAPACK.Matrix.Square.Linear as Linear+import qualified Numeric.LAPACK.Matrix.Square.Basic as Basic+import qualified Numeric.LAPACK.Matrix.Basic as FullBasic +import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Extent as Extent+import Numeric.LAPACK.Matrix.Array (Full, General, Square)+import Numeric.LAPACK.Matrix.Private (ShapeInt) import Numeric.LAPACK.Vector (Vector) import Numeric.LAPACK.Scalar (ComplexOf)  import qualified Numeric.Netlib.Class as Class  import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Shape ((:+:)) +import Foreign.Storable (Storable) +import Data.Tuple.HT (mapPair, mapSnd, mapTriple)+import Data.Complex (Complex)+++size :: Square sh a -> sh+size = MatrixShape.fullHeight . ArrMatrix.shape++mapSize :: (sh0 -> sh1) -> Square sh0 a -> Square sh1 a+mapSize = ArrMatrix.lift1 . Basic.mapSize++toGeneral :: Square sh a -> General sh sh a+toGeneral = toFull++toFull ::+   (Extent.C vert, Extent.C horiz) => Square sh a -> Full vert horiz sh sh a+toFull = ArrMatrix.lift1 Basic.toFull++fromGeneral :: (Eq sh) => General sh sh a -> Square sh a+fromGeneral = ArrMatrix.lift1 Basic.fromGeneral+++fromScalar :: (Storable a) => a -> Square () a+fromScalar = ArrMatrix.lift0 . Basic.fromScalar++toScalar :: (Storable a) => Square () a -> a+toScalar = Basic.toScalar . ArrMatrix.toVector++fromList :: (Shape.C sh, Storable a) => sh -> [a] -> Square sh a+fromList sh = ArrMatrix.lift0 . Basic.fromList sh++autoFromList :: (Storable a) => [a] -> Square ShapeInt a+autoFromList = ArrMatrix.lift0 . Basic.autoFromList++transpose :: Square sh a -> Square sh a+transpose = ArrMatrix.lift1 Basic.transpose++{- |+conjugate transpose+-}+adjoint :: (Shape.C sh, Class.Floating a) => Square sh a -> Square sh a+adjoint = ArrMatrix.lift1 Basic.adjoint++identity :: (Shape.C sh, Class.Floating a) => sh -> Square sh a+identity = ArrMatrix.lift0 . Basic.identity++identityFrom :: (Shape.C sh, Class.Floating a) => Square sh a -> Square sh a+identityFrom = ArrMatrix.lift1 Basic.identityFrom++identityFromWidth ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   General height width a -> Square width a+identityFromWidth = ArrMatrix.lift1 Basic.identityFromWidth++identityFromHeight ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   General height width a -> Square height a+identityFromHeight = ArrMatrix.lift1 Basic.identityFromHeight++diagonal :: (Shape.C sh, Class.Floating a) => Vector sh a -> Square sh a+diagonal = ArrMatrix.lift0 . Basic.diagonal++takeDiagonal :: (Shape.C sh, Class.Floating a) => Square sh a -> Vector sh a+takeDiagonal = Basic.takeDiagonal . ArrMatrix.toVector++trace :: (Shape.C sh, Class.Floating a) => Square sh a -> a+trace = Basic.trace . ArrMatrix.toVector++infix 3 |=|++(|=|) ::+   (Extent.C vert, Extent.C horiz,+    Shape.C sizeA, Eq sizeA, Shape.C sizeB, Eq sizeB, Class.Floating a) =>+   (Square sizeA a, Full vert horiz sizeA sizeB a) ->+   (Full horiz vert sizeB sizeA a, Square sizeB a) ->+   Square (sizeA:+:sizeB) a+(a,b) |=| (c,d)  =  stack a b c d++stack ::+   (Extent.C vert, Extent.C horiz,+    Shape.C sizeA, Eq sizeA, Shape.C sizeB, Eq sizeB, Class.Floating a) =>+   Square sizeA a -> Full vert horiz sizeA sizeB a ->+   Full horiz vert sizeB sizeA a -> Square sizeB a ->+   Square (sizeA:+:sizeB) a+stack = ArrMatrix.lift4 Basic.stack++multiply ::+   (Shape.C sh, Eq sh, Class.Floating a) =>+   Square sh a -> Square sh a -> Square sh a+multiply = ArrMatrix.lift2 FullBasic.multiply++square :: (Shape.C sh, Class.Floating a) => Square sh a -> Square sh a+square = ArrMatrix.lift1 Basic.square++power ::+   (Shape.C sh, Class.Floating a) =>+   Integer -> Square sh a -> Square sh a+power = ArrMatrix.lift1 . Basic.power++{- |+congruence B A = A^H * B * A+++The meaning and order of matrix factors of these functions is consistent:++* 'Numeric.LAPACK.Matrix.Square.congruence'+* 'Numeric.LAPACK.Matrix.Hermitian.gramian'+* 'Numeric.LAPACK.Matrix.Hermitian.anticommutator'+* 'Numeric.LAPACK.Matrix.Hermitian.congruence'+* 'Numeric.LAPACK.Matrix.Hermitian.congruenceDiagonal'+-}+congruence ::+   (Shape.C height, Eq height, Shape.C width, Class.Floating a) =>+   Square height a -> General height width a -> Square width a+congruence = ArrMatrix.lift2 Basic.congruence++{- |+congruenceAdjoint A B = A * B * A^H+-}+congruenceAdjoint ::+   (Shape.C height, Shape.C width, Eq width, Class.Floating a) =>+   General height width a -> Square width a -> Square height a+congruenceAdjoint = ArrMatrix.lift2 Basic.congruenceAdjoint++++solve ::+   (Extent.C vert, Extent.C horiz,+    Shape.C sh, Eq sh, Shape.C nrhs, Class.Floating a) =>+   Square sh a -> Full vert horiz sh nrhs a -> Full vert horiz sh nrhs a+solve = ArrMatrix.lift2 Linear.solve++inverse :: (Shape.C sh, Class.Floating a) => Square sh a -> Square sh a+inverse = ArrMatrix.lift1 Linear.inverse++determinant :: (Shape.C sh, Class.Floating a) => Square sh a -> a+determinant = Linear.determinant . ArrMatrix.toVector+++ eigenvalues ::    (Shape.C sh, Class.Floating a) =>    Square sh a -> Vector sh (ComplexOf a)-eigenvalues = Eigen.values+eigenvalues = Eigen.values . ArrMatrix.toVector  {- |-@(vr,d,vl) = eigensystem a@+If @(q,r) = schur a@, then @a = q \<\> r \<\> adjoint q@,+where @q@ is unitary (orthogonal)+and @r@ is a right-upper triangular matrix for complex @a@+and a 1x1-or-2x2-block upper triangular matrix for real @a@.+With @takeDiagonal r@ you get all eigenvalues of @a@ if @a@ is complex+and the real parts of the eigenvalues if @a@ is real.+Complex conjugated eigenvalues of a real matrix @a@+are encoded as 2x2 blocks along the diagonal. -Counterintuitively, @vr@ contains the right eigenvectors-and @vl@ contains the left eigenvectors as columns.++The meaning and order of matrix factors of these functions is consistent:++* 'Numeric.LAPACK.Matrix.Square.schur'+* 'Numeric.LAPACK.Matrix.Square.schurComplex'+* 'Numeric.LAPACK.Matrix.Hermitian.eigensystem'+* 'Numeric.LAPACK.Matrix.BandedHermitian.eigensystem'+* 'Numeric.LAPACK.Matrix.Square.congruenceAdjoint'+* 'Numeric.LAPACK.Matrix.Hermitian.gramianAdjoint'+* 'Numeric.LAPACK.Matrix.Hermitian.anticommutatorAdjoint'+* 'Numeric.LAPACK.Matrix.Hermitian.congruenceAdjoint'+* 'Numeric.LAPACK.Matrix.Hermitian.congruenceDiagonalAdjoint'+-}+schur ::+   (Shape.C sh, Class.Floating a) =>+   Square sh a -> (Square sh a, Square sh a)+schur =+   mapPair (ArrMatrix.lift0, ArrMatrix.lift0) . Eigen.schur . ArrMatrix.toVector++schurComplex ::+   (Shape.C sh, Class.Real a, Complex a ~ ac) =>+   Square sh ac -> (Square sh ac, Triangular.Upper sh ac)+schurComplex = mapSnd Triangular.takeUpper . schur+++{- |+@(vr,d,vlAdj) = eigensystem a@++Counterintuitively, @vr@ contains the right eigenvectors as columns+and @vlAdj@ contains the left conjugated eigenvectors as rows. The idea is to provide a decomposition of @a@.-If @a@ is diagonalizable, then @vr@ and @vl@ are almost inverse to each other.-More precisely, @adjoint vl \<#\> vr@ is a diagonal matrix.+If @a@ is diagonalizable, then @vr@ and @vlAdj@+are almost inverse to each other.+More precisely, @vlAdj \<\> vr@ is a diagonal matrix,+but not necessarily an identity matrix. This is because all eigenvectors are normalized to Euclidean norm 1. With the following scaling, the decomposition becomes perfect: -> let scal = Array.map recip $ takeDiagonal $ adjoint vl <#> vr-> a == vr <#> diagonal d <#> diagonal scal <#> adjoint vl+> let scal = takeDiagonal $ vlAdj <> vr+> a == vr #*\ Vector.divide d scal ##*# vlAdj -If @a@ is non-diagonalizable then some columns of @vr@ and @vl@ are left zero+If @a@ is non-diagonalizable+then some columns of @vr@ and corresponding rows of @vlAdj@ are left zero and the above property does not hold.+++The meaning and order of result matrices of these functions is consistent:++* 'Numeric.LAPACK.Matrix.Square.eigensystem'+* 'Numeric.LAPACK.Matrix.Triangular.eigensystem'+* 'Numeric.LAPACK.Singular.decompose'+* 'Numeric.LAPACK.Singular.decomposeTall'+* 'Numeric.LAPACK.Singular.decomposeWide' -} eigensystem ::-   (Shape.C sh, Class.Floating a) =>-   Square sh a ->-   (Square sh (ComplexOf a),-    Vector sh (ComplexOf a),-    Square sh (ComplexOf a))-eigensystem = Eigen.decompose+   (Shape.C sh, Class.Floating a, ComplexOf a ~ ac) =>+   Square sh a -> (Square sh ac, Vector sh ac, Square sh ac)+eigensystem =+   mapTriple (ArrMatrix.lift0, id, ArrMatrix.lift0) .+   Eigen.decompose . ArrMatrix.toVector
src/Numeric/LAPACK/Matrix/Square/Basic.hs view
@@ -1,8 +1,8 @@+{-# LANGUAGE TypeOperators #-} module Numeric.LAPACK.Matrix.Square.Basic (    Square,-   size,+   mapSize,    toFull,-   toGeneral,    fromGeneral,    fromScalar,    toScalar,@@ -13,6 +13,7 @@    adjoint,     identity,+   identityOrder,    identityFrom,    identityFromWidth,    identityFromHeight,@@ -20,25 +21,30 @@    takeDiagonal,    trace, -   multiply,+   stack,+    square,    power,+   congruence,+   congruenceAdjoint,    ) where  -import qualified Numeric.LAPACK.Matrix.Multiply as Mult import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape import qualified Numeric.LAPACK.Matrix.Extent.Private as ExtentPriv import qualified Numeric.LAPACK.Matrix.Extent as Extent+import qualified Numeric.LAPACK.Matrix.Basic as Basic+import qualified Numeric.LAPACK.Matrix.Private as Matrix import qualified Numeric.LAPACK.Vector as Vector import qualified Numeric.LAPACK.Private as Private import Numeric.LAPACK.Matrix.Shape.Private          (Order(RowMajor, ColumnMajor), swapOnRowMajor) import Numeric.LAPACK.Matrix.Private          (Full, mapExtent,-          General, argGeneral, Square, argSquare, ZeroInt, zeroInt)+          General, argGeneral, Square, argSquare, ShapeInt, shapeInt) import Numeric.LAPACK.Vector (Vector) import Numeric.LAPACK.Scalar (zero, one)+import Numeric.LAPACK.Shape.Private (Unchecked(Unchecked)) import Numeric.LAPACK.Private (pokeCInt)  import qualified Numeric.LAPACK.FFI.Generic as LapackGen@@ -50,6 +56,7 @@ import qualified Data.Array.Comfort.Storable as CheckedArray import qualified Data.Array.Comfort.Shape as Shape import Data.Array.Comfort.Storable.Unchecked (Array(Array))+import Data.Array.Comfort.Shape ((:+:))  import Foreign.ForeignPtr (withForeignPtr) import Foreign.Storable (Storable, peek, poke)@@ -62,11 +69,11 @@ import Data.Function.HT (powerAssociative)  -size :: Square sh a -> sh-size = MatrixShape.fullHeight . Array.shape--toGeneral :: Square sh a -> General sh sh a-toGeneral = toFull+mapSize :: (sh0 -> sh1) -> Square sh0 a -> Square sh1 a+mapSize f =+   Array.mapShape+      (\(MatrixShape.Full order extent) ->+         MatrixShape.Full order $ ExtentPriv.mapSquareSize f extent)  toFull ::    (Extent.C vert, Extent.C horiz) => Square sh a -> Full vert horiz sh sh a@@ -88,27 +95,24 @@ fromList sh =    CheckedArray.fromList (MatrixShape.square RowMajor sh) -autoFromList :: (Storable a) => [a] -> Square ZeroInt a+autoFromList :: (Storable a) => [a] -> Square ShapeInt a autoFromList xs =    let n = length xs        m = round $ sqrt (fromIntegral n :: Double)    in if n == m*m-        then fromList (zeroInt m) xs+        then fromList (shapeInt m) xs         else error "Square.autoFromList: no quadratic number of elements"   transpose :: Square sh a -> Square sh a transpose = Array.mapShape MatrixShape.transpose -{- |-conjugate transpose--} adjoint :: (Shape.C sh, Class.Floating a) => Square sh a -> Square sh a adjoint = transpose . Vector.conjugate   identity :: (Shape.C sh, Class.Floating a) => sh -> Square sh a-identity = identityOrder ColumnMajor+identity = identityOrder RowMajor  identityFrom :: (Shape.C sh, Class.Floating a) => Square sh a -> Square sh a identityFrom = argSquare $ \order sh _ -> identityOrder order sh@@ -186,11 +190,21 @@    withForeignPtr x $ \xPtr -> Private.sum n xPtr (n+1)  -multiply ::-   (Shape.C sh, Eq sh, Class.Floating a) =>-   Square sh a -> Square sh a -> Square sh a-multiply = Mult.multiply+stack ::+   (Extent.C vert, Extent.C horiz,+    Shape.C sizeA, Eq sizeA, Shape.C sizeB, Eq sizeB, Class.Floating a) =>+   Square sizeA a -> Full vert horiz sizeA sizeB a ->+   Full horiz vert sizeB sizeA a -> Square sizeB a ->+   Square (sizeA:+:sizeB) a+stack a b c d =+   fromGeneral $+   Basic.above Basic.RightBias Extent.appendAny+      (Basic.beside Basic.RightBias Extent.appendAny+         (Matrix.fromFull a) (Matrix.fromFull b))+      (Basic.beside Basic.RightBias Extent.appendAny+         (Matrix.fromFull c) (Matrix.fromFull d)) + square :: (Shape.C sh, Class.Floating a) => Square sh a -> Square sh a square a = multiplyCommutativeUnchecked a a @@ -199,6 +213,22 @@    Integer -> Square sh a -> Square sh a power n a =    powerAssociative multiplyCommutativeUnchecked (identityFrom a) a n++congruence ::+   (Shape.C height, Eq height, Shape.C width, Class.Floating a) =>+   Square height a -> General height width a -> Square width a+congruence b a0 =+   let a = Basic.mapWidth Unchecked a0+   in mapSize (\(Unchecked sh) -> sh) $ fromGeneral $+      Basic.multiply (Basic.adjoint a) $ Basic.multiply (toFull b) a++congruenceAdjoint ::+   (Shape.C height, Shape.C width, Eq width, Class.Floating a) =>+   General height width a -> Square width a -> Square height a+congruenceAdjoint a0 b =+   let a = Basic.mapHeight Unchecked a0+   in mapSize (\(Unchecked sh) -> sh) $ fromGeneral $+      Basic.multiply a $ Basic.multiply (toFull b) $ Basic.adjoint a  {- orderA and orderB must be equal but this is not checked.
src/Numeric/LAPACK/Matrix/Square/Eigen.hs view
@@ -7,13 +7,14 @@    ) where  import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Basic as Basic import Numeric.LAPACK.Matrix.Shape.Private (Order(ColumnMajor), swapOnRowMajor) import Numeric.LAPACK.Matrix.Private (Square, argSquare) import Numeric.LAPACK.Vector (Vector) import Numeric.LAPACK.Scalar (ComplexOf, RealOf, zero) import Numeric.LAPACK.Private          (copyConjugate, copyToTemp, copyToColumnMajor,-          withAutoWorkspaceInfo)+          realPtr, withAutoWorkspaceInfo)  import qualified Numeric.LAPACK.FFI.Complex as LapackComplex import qualified Numeric.LAPACK.FFI.Real as LapackReal@@ -29,12 +30,13 @@ import Foreign.Marshal.Array (advancePtr, peekArray) import Foreign.C.Types (CInt, CChar) import Foreign.ForeignPtr (withForeignPtr)-import Foreign.Ptr (Ptr, nullPtr, nullFunPtr, castPtr)+import Foreign.Ptr (Ptr, nullPtr, nullFunPtr) import Foreign.Storable (Storable)  import Control.Monad.Trans.Cont (ContT(ContT), evalContT) import Control.Monad.IO.Class (liftIO) +import Data.Tuple.HT (mapThd3) import Data.Complex (Complex)  @@ -73,16 +75,6 @@             wPtr vsPtr ldvsPtr workPtr lworkPtr bworkPtr infoPtr  -{- |-If @(q,r) = schur a@, then @a = q \<#\> r \<#\> adjoint q@,-where @q@ is unitary (orthogonal)-and @r@ is a right-upper triangular matrix for complex @a@-and a 1x1-or-2x2-block upper triangular matrix for real @a@.-With @takeDiagonal r@ you get all eigenvalues of @a@ if @a@ is complex-and the real parts of the eigenvalues if @a@ is real.-Complex conjugated eigenvalues of a real matrix @a@-are encoded as 2x2 blocks along the diagonal.--} schur ::    (Shape.C sh, Class.Floating a) =>    Square sh a -> (Square sh a, Square sh a)@@ -168,18 +160,15 @@   decompose ::-   (Shape.C sh, Class.Floating a) =>-   Square sh a ->-   (Square sh (ComplexOf a),-    Vector sh (ComplexOf a),-    Square sh (ComplexOf a))+   (Shape.C sh, Class.Floating a, ComplexOf a ~ ac) =>+   Square sh a -> (Square sh ac, Vector sh ac, Square sh ac) decompose =    getDecompose $    Class.switchFloating-      (Decompose decomposeReal)-      (Decompose decomposeReal)-      (Decompose decomposeComplex)-      (Decompose decomposeComplex)+      (Decompose $ mapThd3 Basic.adjoint . decomposeReal)+      (Decompose $ mapThd3 Basic.adjoint . decomposeReal)+      (Decompose $ mapThd3 Basic.adjoint . decomposeComplex)+      (Decompose $ mapThd3 Basic.adjoint . decomposeComplex)  newtype Decompose sh a =    Decompose {@@ -191,9 +180,8 @@    }  decomposeReal ::-   (Shape.C sh, Class.Real a) =>-   Square sh a ->-   (Square sh (Complex a), Vector sh (Complex a), Square sh (Complex a))+   (Shape.C sh, Class.Real a, Complex a ~ ac) =>+   Square sh a -> (Square sh ac, Vector sh ac, Square sh ac) decomposeReal = argSquare $ \order size a ->    (\(w, (vlc,vrc)) -> (vlc, w, vrc)) $    Array.unsafeCreateWithSizeAndResult size $ \n wPtr ->@@ -231,7 +219,7 @@    liftIO $ do       let go _ _ [] = return ()           go xPtr yPtr (False:wi) = do-            let yrPtr = castPtr yPtr+            let yrPtr = realPtr yPtr             let yiPtr = advancePtr yrPtr 1             BlasReal.copy nPtr xPtr    inc1Ptr yrPtr inc2Ptr             BlasReal.copy nPtr zeroPtr inc0Ptr yiPtr inc2Ptr@@ -239,7 +227,7 @@           go xPtr yPtr (True:True:wi) = do             let xrPtr = xPtr             let xiPtr = advancePtr xPtr n-            let yrPtr = castPtr yPtr+            let yrPtr = realPtr yPtr             let yiPtr = advancePtr yrPtr 1             let y1Ptr = advancePtr yPtr n             BlasReal.copy nPtr xrPtr inc1Ptr yrPtr inc2Ptr@@ -251,9 +239,8 @@       go vPtr vcPtr . map (zero/=) =<< peekArray n wiPtr  decomposeComplex ::-   (Shape.C sh, Class.Real a) =>-   Square sh (Complex a) ->-   (Square sh (Complex a), Vector sh (Complex a), Square sh (Complex a))+   (Shape.C sh, Class.Real a, Complex a ~ ac) =>+   Square sh ac -> (Square sh ac, Vector sh ac, Square sh ac) decomposeComplex = argSquare $ \order size a ->    (\(w, (vlc,vrc)) -> (vlc, w, vrc)) $    Array.unsafeCreateWithSizeAndResult size $ \n wPtr ->@@ -284,7 +271,7 @@       nPtr <- Call.cint n       incxPtr <- Call.cint 1       incyPtr <- Call.cint 2-      let yPtr = castPtr vc+      let yPtr = realPtr vc       liftIO $ BlasReal.copy nPtr vr incxPtr yPtr incyPtr       liftIO $ BlasReal.copy nPtr vi incxPtr (advancePtr yPtr 1) incyPtr 
src/Numeric/LAPACK/Matrix/Square/Linear.hs view
@@ -5,15 +5,14 @@    determinant,    ) where -import Numeric.LAPACK.Matrix.Private (Full, Square, argSquare)- import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent-import qualified Numeric.LAPACK.Split as Split+import qualified Numeric.LAPACK.Permutation.Private as Perm import qualified Numeric.LAPACK.Private as Private import Numeric.LAPACK.Linear.Private          (solver, withDeterminantInfo, withInfo, diagonalMsg) import Numeric.LAPACK.Matrix.Shape.Private (transposeFromOrder)+import Numeric.LAPACK.Matrix.Private (Full, Square, argSquare) import Numeric.LAPACK.Private          (withAutoWorkspaceInfo, copyBlock, copyToTemp, copyToColumnMajor) @@ -95,4 +94,4 @@          (do             det <- Private.product n aPtr (n+1)             ipiv <- peekArray n ipivPtr-            return $ if Split.oddPermutation ipiv then -det else det)+            return $ Perm.condNegate ipiv det)
src/Numeric/LAPACK/Matrix/Symmetric/Private.hs view
@@ -6,8 +6,8 @@           forPointers, pack, unpackToTemp, copyTriangleToTemp) import Numeric.LAPACK.Matrix.Shape.Private          (Order(RowMajor,ColumnMajor), uploFromOrder)-import Numeric.LAPACK.Matrix.Private-         (Full, Conjugation(NonConjugated, Conjugated))+import Numeric.LAPACK.Matrix.Modifier (Conjugation(NonConjugated, Conjugated))+import Numeric.LAPACK.Matrix.Private (Full) import Numeric.LAPACK.Linear.Private (solver, withDeterminantInfo, withInfo) import Numeric.LAPACK.Scalar (zero, one) import Numeric.LAPACK.Private (copyBlock, copyToTemp, copyCondConjugate)@@ -42,14 +42,12 @@       RowMajor ->          forPointers (rowMajorPointers n fullPtr packedPtr) $                \nPtr (dstPtr,srcPtr) -> do-            copyCondConjugate (conj==Conjugated)-               nPtr srcPtr incxPtr dstPtr incyPtr+            copyCondConjugate conj nPtr srcPtr incxPtr dstPtr incyPtr             BlasGen.copy nPtr srcPtr incxPtr dstPtr incxPtr       ColumnMajor ->          forPointers (columnMajorPointers n fullPtr packedPtr) $                \nPtr ((dstRowPtr,dstColumnPtr),srcPtr) -> do-            copyCondConjugate (conj==Conjugated)-               nPtr srcPtr incxPtr dstRowPtr incyPtr+            copyCondConjugate conj nPtr srcPtr incxPtr dstRowPtr incyPtr             BlasGen.copy nPtr srcPtr incxPtr dstColumnPtr incxPtr  
src/Numeric/LAPACK/Matrix/Triangular.hs view
@@ -1,36 +1,443 @@ {-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE TypeOperators #-} module Numeric.LAPACK.Matrix.Triangular (-   module Numeric.LAPACK.Matrix.Triangular.Basic,-   module Numeric.LAPACK.Matrix.Triangular.Linear,+   Triangular, MatrixShape.UpLo,+   Diagonal, FlexDiagonal,+   Upper, FlexUpper, UnitUpper,+   Lower, FlexLower, UnitLower,+   Symmetric, FlexSymmetric,    size,+   fromList, autoFromList,+   diagonalFromList, autoDiagonalFromList,+   lowerFromList, autoLowerFromList,+   upperFromList, autoUpperFromList,+   symmetricFromList, autoSymmetricFromList,+   asDiagonal, asLower, asUpper, asSymmetric,+   requireUnitDiagonal, requireNonUnitDiagonal,+   relaxUnitDiagonal, strictNonUnitDiagonal,+   identity,+   diagonal,+   takeDiagonal,+   transpose,+   adjoint, +   stackDiagonal, (%%%),+   stackLower, (#%%%),+   stackUpper, (%%%#),+   stackSymmetric, (#%%%#),+   splitDiagonal,+   splitLower,+   splitUpper,+   splitSymmetric,+   takeTopLeft,+   takeTopRight,+   takeBottomLeft,+   takeBottomRight,++   toSquare,+   takeLower,+   takeUpper,++   fromLowerRowMajor, toLowerRowMajor,+   fromUpperRowMajor, toUpperRowMajor,+   forceOrder, adaptOrder,++   add, sub,++   Tri.PowerDiag,+   Tri.PowerContentDiag,+   multiplyVector,+   square,+   multiply,+   multiplyFull,++   solve,+   inverse,+   determinant,+    eigenvalues,    eigensystem,    ) where  import qualified Numeric.LAPACK.Matrix.Triangular.Eigen as Eigen-import Numeric.LAPACK.Matrix.Triangular.Basic-import Numeric.LAPACK.Matrix.Triangular.Linear+import qualified Numeric.LAPACK.Matrix.Triangular.Linear as Linear+import qualified Numeric.LAPACK.Matrix.Triangular.Basic as Basic+import qualified Numeric.LAPACK.Matrix.Triangular.Private as Tri +import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape-import Numeric.LAPACK.Matrix.Shape.Private (NonUnit)+import qualified Numeric.LAPACK.Matrix.Extent as Extent+import Numeric.LAPACK.Matrix.Array.Triangular (+   Triangular,+   Diagonal,  FlexDiagonal,+   Lower,     FlexLower,     UnitLower,+   Upper,     FlexUpper,     UnitUpper,+   Symmetric, FlexSymmetric,+   )+import Numeric.LAPACK.Matrix.Array (Full, General, Square)+import Numeric.LAPACK.Matrix.Shape.Private (NonUnit, Unit, Order)+import Numeric.LAPACK.Matrix.Private (ShapeInt) import Numeric.LAPACK.Vector (Vector)  import qualified Numeric.Netlib.Class as Class -import qualified Data.Array.Comfort.Storable as Array import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Storable (Array)+import Data.Array.Comfort.Shape ((:+:)) +import Foreign.Storable (Storable) +import Data.Tuple.HT (mapTriple)++ size :: Triangular lo diag up sh a -> sh-size = MatrixShape.triangularSize . Array.shape+size = MatrixShape.triangularSize . ArrMatrix.shape +transpose ::+   (MatrixShape.Content lo, MatrixShape.Content up,+    MatrixShape.TriDiag diag) =>+   Triangular lo diag up sh a -> Triangular up diag lo sh a+transpose = ArrMatrix.lift1 Basic.transpose +adjoint ::+   (MatrixShape.Content lo, MatrixShape.Content up,+    MatrixShape.TriDiag diag, Shape.C sh, Class.Floating a) =>+   Triangular lo diag up sh a -> Triangular up diag lo sh a+adjoint = ArrMatrix.lift1 Basic.adjoint++fromList ::+   (MatrixShape.Content lo, MatrixShape.Content up, Shape.C sh, Storable a) =>+   Order -> sh -> [a] -> Triangular lo NonUnit up sh a+fromList order sh = ArrMatrix.lift0 . Basic.fromList order sh++lowerFromList :: (Shape.C sh, Storable a) => Order -> sh -> [a] -> Lower sh a+lowerFromList = fromList++upperFromList :: (Shape.C sh, Storable a) => Order -> sh -> [a] -> Upper sh a+upperFromList = fromList++symmetricFromList ::+   (Shape.C sh, Storable a) => Order -> sh -> [a] -> Symmetric sh a+symmetricFromList = fromList++diagonalFromList ::+   (Shape.C sh, Storable a) => Order -> sh -> [a] -> Diagonal sh a+diagonalFromList = fromList+++autoFromList ::+   (MatrixShape.Content lo, MatrixShape.Content up, Storable a) =>+   Order -> [a] -> Triangular lo NonUnit up ShapeInt a+autoFromList order = ArrMatrix.lift0 . Basic.autoFromList order++autoLowerFromList :: (Storable a) => Order -> [a] -> Lower ShapeInt a+autoLowerFromList = autoFromList++autoUpperFromList :: (Storable a) => Order -> [a] -> Upper ShapeInt a+autoUpperFromList = autoFromList++autoSymmetricFromList :: (Storable a) => Order -> [a] -> Symmetric ShapeInt a+autoSymmetricFromList = autoFromList++autoDiagonalFromList :: (Storable a) => Order -> [a] -> Diagonal ShapeInt a+autoDiagonalFromList = autoFromList+++asDiagonal :: FlexDiagonal diag sh a -> FlexDiagonal diag sh a+asDiagonal = id++asLower :: FlexLower diag sh a -> FlexLower diag sh a+asLower = id++asUpper :: FlexUpper diag sh a -> FlexUpper diag sh a+asUpper = id++asSymmetric :: FlexSymmetric diag sh a -> FlexSymmetric diag sh a+asSymmetric = id++requireUnitDiagonal :: Triangular lo Unit up sh a -> Triangular lo Unit up sh a+requireUnitDiagonal = id++requireNonUnitDiagonal ::+   Triangular lo NonUnit up sh a -> Triangular lo NonUnit up sh a+requireNonUnitDiagonal = id+++toSquare ::+   (MatrixShape.Content lo, MatrixShape.Content up,+    Shape.C sh, Class.Floating a) =>+   Triangular lo diag up sh a -> Square sh a+toSquare = ArrMatrix.lift1 Basic.toSquare++takeLower ::+   (Extent.C horiz, Shape.C height, Shape.C width, Class.Floating a) =>+   Full Extent.Small horiz height width a -> Lower height a+takeLower = ArrMatrix.lift1 Basic.takeLower++takeUpper ::+   (Extent.C vert, Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert Extent.Small height width a -> Upper width a+takeUpper = ArrMatrix.lift1 Basic.takeUpper++fromLowerRowMajor ::+   (Shape.C sh, Class.Floating a) =>+   Array (Shape.Triangular Shape.Lower sh) a -> Lower sh a+fromLowerRowMajor = ArrMatrix.lift0 . Basic.fromLowerRowMajor++fromUpperRowMajor ::+   (Shape.C sh, Class.Floating a) =>+   Array (Shape.Triangular Shape.Upper sh) a -> Upper sh a+fromUpperRowMajor = ArrMatrix.lift0 . Basic.fromUpperRowMajor++toLowerRowMajor ::+   (Shape.C sh, Class.Floating a) =>+   Lower sh a -> Array (Shape.Triangular Shape.Lower sh) a+toLowerRowMajor = Basic.toLowerRowMajor . ArrMatrix.toVector++toUpperRowMajor ::+   (Shape.C sh, Class.Floating a) =>+   Upper sh a -> Array (Shape.Triangular Shape.Upper sh) a+toUpperRowMajor = Basic.toUpperRowMajor . ArrMatrix.toVector++forceOrder ::+   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,+    Shape.C sh, Class.Floating a) =>+   Order -> Triangular lo diag up sh a -> Triangular lo diag up sh a+forceOrder = ArrMatrix.lift1 . Basic.forceOrder++{- |+@adaptOrder x y@ contains the data of @y@ with the layout of @x@.+-}+adaptOrder ::+   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,+    Shape.C sh, Class.Floating a) =>+   Triangular lo diag up sh a ->+   Triangular lo diag up sh a ->+   Triangular lo diag up sh a+adaptOrder = ArrMatrix.lift2 Basic.adaptOrder++add, sub ::+   (MatrixShape.Content lo, MatrixShape.Content up,+    Eq lo, Eq up, Eq sh, Shape.C sh, Class.Floating a) =>+   Triangular lo NonUnit up sh a ->+   Triangular lo NonUnit up sh a ->+   Triangular lo NonUnit up sh a+add = ArrMatrix.lift2 Basic.add+sub = ArrMatrix.lift2 Basic.sub+++identity ::+   (MatrixShape.Content lo, MatrixShape.Content up,+    Shape.C sh, Class.Floating a) =>+   Order -> sh -> Triangular lo Unit up sh a+identity order = ArrMatrix.lift0 . Basic.identity order++diagonal ::+   (MatrixShape.Content lo, MatrixShape.Content up,+    Shape.C sh, Class.Floating a) =>+   Order -> Vector sh a -> Triangular lo NonUnit up sh a+diagonal order = ArrMatrix.lift0 . Basic.diagonal order++takeDiagonal ::+   (MatrixShape.Content lo, MatrixShape.Content up,+    Shape.C sh, Class.Floating a) =>+   Triangular lo diag up sh a -> Vector sh a+takeDiagonal = Basic.takeDiagonal . ArrMatrix.toVector++relaxUnitDiagonal ::+   (MatrixShape.TriDiag diag) =>+   Triangular lo Unit up sh a -> Triangular lo diag up sh a+relaxUnitDiagonal = ArrMatrix.lift1 Basic.relaxUnitDiagonal++strictNonUnitDiagonal ::+   (MatrixShape.TriDiag diag) =>+   Triangular lo diag up sh a -> Triangular lo NonUnit up sh a+strictNonUnitDiagonal = ArrMatrix.lift1 Basic.strictNonUnitDiagonal+++infixr 2 %%%, %%%#, #%%%#+infixl 2 #%%%++stackDiagonal, (%%%) ::+   (MatrixShape.TriDiag diag, Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   FlexDiagonal diag sh0 a ->+   FlexDiagonal diag sh1 a ->+   FlexDiagonal diag (sh0:+:sh1) a+stackDiagonal = ArrMatrix.lift2 Basic.stackDiagonal+(%%%) = stackDiagonal++stackLower ::+   (MatrixShape.TriDiag diag,+    Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>+   FlexLower diag sh0 a ->+   General sh1 sh0 a ->+   FlexLower diag sh1 a ->+   FlexLower diag (sh0:+:sh1) a+stackLower = ArrMatrix.lift3 Basic.stackLower++(#%%%) ::+   (MatrixShape.TriDiag diag,+    Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>+   FlexLower diag sh0 a ->+   (General sh1 sh0 a, FlexLower diag sh1 a) ->+   FlexLower diag (sh0:+:sh1) a+(#%%%) = uncurry . stackLower++stackUpper ::+   (MatrixShape.TriDiag diag,+    Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>+   FlexUpper diag sh0 a ->+   General sh0 sh1 a ->+   FlexUpper diag sh1 a ->+   FlexUpper diag (sh0:+:sh1) a+stackUpper = ArrMatrix.lift3 Basic.stackUpper++(%%%#) ::+   (MatrixShape.TriDiag diag,+    Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>+   (FlexUpper diag sh0 a, General sh0 sh1 a) ->+   FlexUpper diag sh1 a ->+   FlexUpper diag (sh0:+:sh1) a+(%%%#) = uncurry stackUpper++stackSymmetric ::+   (MatrixShape.TriDiag diag,+    Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>+   FlexSymmetric diag sh0 a ->+   General sh0 sh1 a ->+   FlexSymmetric diag sh1 a ->+   FlexSymmetric diag (sh0:+:sh1) a+stackSymmetric = ArrMatrix.lift3 Basic.stackSymmetric++(#%%%#) ::+   (MatrixShape.TriDiag diag,+    Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>+   (FlexSymmetric diag sh0 a, General sh0 sh1 a) ->+   FlexSymmetric diag sh1 a ->+   FlexSymmetric diag (sh0:+:sh1) a+(#%%%#) = uncurry stackSymmetric+++splitDiagonal ::+   (MatrixShape.TriDiag diag, Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   FlexDiagonal diag (sh0:+:sh1) a ->+   (FlexDiagonal diag sh0 a, FlexDiagonal diag sh1 a)+splitDiagonal a = (takeTopLeft a, takeBottomRight a)++splitLower ::+   (MatrixShape.TriDiag diag,+    Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>+   FlexLower diag (sh0:+:sh1) a ->+   (FlexLower diag sh0 a, General sh1 sh0 a, FlexLower diag sh1 a)+splitLower a = (takeTopLeft a, takeBottomLeft a, takeBottomRight a)++splitUpper ::+   (MatrixShape.TriDiag diag,+    Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>+   FlexUpper diag (sh0:+:sh1) a ->+   (FlexUpper diag sh0 a, General sh0 sh1 a, FlexUpper diag sh1 a)+splitUpper a = (takeTopLeft a, takeTopRight a, takeBottomRight a)++splitSymmetric ::+   (MatrixShape.TriDiag diag,+    Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>+   FlexSymmetric diag (sh0:+:sh1) a ->+   (FlexSymmetric diag sh0 a, General sh0 sh1 a, FlexSymmetric diag sh1 a)+splitSymmetric a = (takeTopLeft a, takeTopRight a, takeBottomRight a)+++takeTopLeft ::+   (MatrixShape.Content lo, MatrixShape.TriDiag diag, MatrixShape.Content up,+    Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Triangular lo diag up (sh0:+:sh1) a ->+   Triangular lo diag up sh0 a+takeTopLeft = ArrMatrix.lift1 Basic.takeTopLeft++takeBottomLeft ::+   (MatrixShape.TriDiag diag, MatrixShape.Content up,+    Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Triangular MatrixShape.Filled diag up (sh0:+:sh1) a ->+   General sh1 sh0 a+takeBottomLeft = ArrMatrix.lift1 Basic.takeBottomLeft++takeTopRight ::+   (MatrixShape.Content lo, MatrixShape.TriDiag diag,+    Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Triangular lo diag MatrixShape.Filled (sh0:+:sh1) a ->+   General sh0 sh1 a+takeTopRight = ArrMatrix.lift1 Basic.takeTopRight++takeBottomRight ::+   (MatrixShape.Content lo, MatrixShape.TriDiag diag, MatrixShape.Content up,+    Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Triangular lo diag up (sh0:+:sh1) a ->+   Triangular lo diag up sh1 a+takeBottomRight = ArrMatrix.lift1 Basic.takeBottomRight+++multiplyVector ::+   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,+    Shape.C sh, Eq sh, Class.Floating a) =>+   Triangular lo diag up sh a -> Vector sh a -> Vector sh a+multiplyVector = Basic.multiplyVector . ArrMatrix.toVector++{- |+Include symmetric matrices.+However, symmetric matrices do not preserve unit diagonals.+-}+square ::+   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,+    Shape.C sh, Eq sh, Class.Floating a) =>+   Triangular lo diag up sh a ->+   Triangular lo (Tri.PowerDiag lo up diag) up sh a+square = ArrMatrix.lift1 Basic.square++multiply ::+   (MatrixShape.DiagUpLo lo up, MatrixShape.TriDiag diag,+    Shape.C sh, Eq sh, Class.Floating a) =>+   Triangular lo diag up sh a -> Triangular lo diag up sh a ->+   Triangular lo diag up sh a+multiply = ArrMatrix.lift2 Basic.multiply++multiplyFull ::+   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,+    Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width,+    Class.Floating a) =>+   Triangular lo diag up height a ->+   Full vert horiz height width a ->+   Full vert horiz height width a+multiplyFull = ArrMatrix.lift2 Basic.multiplyFull++++solve ::+   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,+    Extent.C vert, Extent.C horiz,+    Shape.C sh, Eq sh, Shape.C nrhs, Class.Floating a) =>+   Triangular lo diag up sh a ->+   Full vert horiz sh nrhs a -> Full vert horiz sh nrhs a+solve = ArrMatrix.lift2 Linear.solve++inverse ::+   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,+    Shape.C sh, Class.Floating a) =>+   Triangular lo diag up sh a ->+   Triangular lo (Basic.PowerDiag lo up diag) up sh a+inverse = ArrMatrix.lift1 Linear.inverse++determinant ::+   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,+    Shape.C sh, Class.Floating a) =>+   Triangular lo diag up sh a -> a+determinant = Linear.determinant . ArrMatrix.toVector+++ eigenvalues ::    (MatrixShape.DiagUpLo lo up, Shape.C sh, Class.Floating a) =>    Triangular lo diag up sh a -> Vector sh a-eigenvalues = Eigen.values-+eigenvalues = Eigen.values . ArrMatrix.toVector  {- | @(vr,d,vlAdj) = eigensystem a@@@ -40,12 +447,14 @@ The idea is to provide a decomposition of @a@. If @a@ is diagonalizable, then @vr@ and @vlAdj@ are almost inverse to each other.-More precisely, @vlAdj \<#\> vr@ is a diagonal matrix.-This is because the eigenvectors are not normalized.+More precisely, @vlAdj \<\> vr@ is a diagonal matrix,+but not necessarily an identity matrix.+This is because all eigenvectors are normalized+such that 'Numeric.LAPACK.Vector.normInf1' is 1. With the following scaling, the decomposition becomes perfect: -> let scal = Array.map recip $ takeDiagonal $ vlAdj <#> vr-> a == vr <#> diagonal d <#> diagonal scal <#> vlAdj+> let scal = takeDiagonal $ vlAdj <> vr+> a == vr <> diagonal (Vector.divide d scal) <> vlAdj  If @a@ is non-diagonalizable then some columns of @vr@ and corresponding rows of @vlAdj@ are left zero@@ -55,4 +464,6 @@    (MatrixShape.DiagUpLo lo up, Shape.C sh, Class.Floating a) =>    Triangular lo NonUnit up sh a ->    (Triangular lo NonUnit up sh a, Vector sh a, Triangular lo NonUnit up sh a)-eigensystem = Eigen.decompose+eigensystem =+   mapTriple (ArrMatrix.lift0, id, ArrMatrix.lift0) .+   Eigen.decompose . ArrMatrix.toVector
src/Numeric/LAPACK/Matrix/Triangular/Basic.hs view
@@ -8,21 +8,21 @@    Lower, FlexLower, UnitLower,    Symmetric, FlexSymmetric,    fromList, autoFromList,-   lowerFromList, autoLowerFromList,-   upperFromList, autoUpperFromList,-   symmetricFromList, autoSymmetricFromList,-   diagonalFromList, autoDiagonalFromList,    relaxUnitDiagonal, strictNonUnitDiagonal,-   asDiagonal, asLower, asUpper, asSymmetric,-   forceUnitDiagonal, forceNonUnitDiagonal,    identity,    diagonal,    takeDiagonal,    transpose,    adjoint,++   stackDiagonal,    stackLower,    stackUpper,    stackSymmetric,+   takeTopLeft,+   takeTopRight,+   takeBottomLeft,+   takeBottomRight,     toSquare,    takeLower,@@ -35,8 +35,9 @@    add, sub,     Tri.PowerDiag,+   Tri.PowerContentDiag,    multiplyVector,-   square, squareGeneric,+   square, power,    multiply,    multiplyFull,    ) where@@ -47,6 +48,7 @@ import qualified Numeric.LAPACK.Matrix.Basic as Basic import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import qualified Numeric.LAPACK.Vector.Private as VectorPriv import qualified Numeric.LAPACK.Vector as Vector import Numeric.LAPACK.Matrix.Triangular.Private          (Triangular, FlexDiagonal, diagonalPointers, diagonalPointerPairs,@@ -55,10 +57,11 @@          (Order(RowMajor,ColumnMajor),           flipOrder, transposeFromOrder, uploFromOrder, uploOrder,           Unit(Unit), NonUnit(NonUnit), charFromTriDiag)-import Numeric.LAPACK.Matrix.Private-         (Full, Square, ZeroInt, zeroInt, Conjugation(NonConjugated))+import Numeric.LAPACK.Matrix.Modifier (Conjugation(NonConjugated))+import Numeric.LAPACK.Matrix.Private (Full, Square, ShapeInt, shapeInt) import Numeric.LAPACK.Vector (Vector) import Numeric.LAPACK.Scalar (zero, one)+import Numeric.LAPACK.Shape.Private (Unchecked(Unchecked)) import Numeric.LAPACK.Private (fill, copyBlock)  import qualified Numeric.LAPACK.FFI.Complex as LapackComplex@@ -71,7 +74,7 @@ import qualified Data.Array.Comfort.Storable as CheckedArray import qualified Data.Array.Comfort.Shape as Shape import Data.Array.Comfort.Storable.Unchecked (Array(Array))-import Data.Array.Comfort.Shape ((:+:))+import Data.Array.Comfort.Shape ((:+:)((:+:)))  import Foreign.C.Types (CChar, CInt) import Foreign.ForeignPtr (withForeignPtr)@@ -81,21 +84,23 @@ import Control.Monad.Trans.Cont (ContT(ContT), evalContT) import Control.Monad.IO.Class (liftIO) +import Data.Function.HT (powerAssociative) import Data.Foldable (forM_)+import Data.Tuple.HT (double)   type Lower sh = FlexLower NonUnit sh type Upper sh = FlexUpper NonUnit sh-type Symmetric sh = Array (MatrixShape.Symmetric sh)+type Symmetric sh = FlexSymmetric NonUnit sh type Diagonal sh = FlexDiagonal NonUnit sh +type UnitLower sh = FlexLower Unit sh+type UnitUpper sh = FlexUpper Unit sh+ type FlexLower diag sh = Array (MatrixShape.LowerTriangular diag sh) type FlexUpper diag sh = Array (MatrixShape.UpperTriangular diag sh) type FlexSymmetric diag sh = Array (MatrixShape.FlexSymmetric diag sh) -type UnitLower sh = FlexLower Unit sh-type UnitUpper sh = FlexUpper Unit sh- transpose ::    (MatrixShape.Content lo, MatrixShape.Content up,     MatrixShape.TriDiag diag) =>@@ -117,24 +122,10 @@    CheckedArray.fromList       (MatrixShape.Triangular NonUnit MatrixShape.autoUplo order sh) -lowerFromList :: (Shape.C sh, Storable a) => Order -> sh -> [a] -> Lower sh a-lowerFromList = fromList -upperFromList :: (Shape.C sh, Storable a) => Order -> sh -> [a] -> Upper sh a-upperFromList = fromList--symmetricFromList ::-   (Shape.C sh, Storable a) => Order -> sh -> [a] -> Symmetric sh a-symmetricFromList = fromList--diagonalFromList ::-   (Shape.C sh, Storable a) => Order -> sh -> [a] -> Diagonal sh a-diagonalFromList = fromList-- autoFromList ::    (MatrixShape.Content lo, MatrixShape.Content up, Storable a) =>-   Order -> [a] -> Triangular lo NonUnit up ZeroInt a+   Order -> [a] -> Triangular lo NonUnit up ShapeInt a autoFromList order xs =    let n = length xs        triSize = MatrixShape.triangleExtent "Triangular.autoFromList" n@@ -142,42 +133,10 @@        size = MatrixShape.caseDiagUpLoSym uplo n triSize triSize triSize    in Array.fromList          (MatrixShape.Triangular-            MatrixShape.autoDiag uplo order (zeroInt size))+            MatrixShape.autoDiag uplo order (shapeInt size))          xs -autoLowerFromList :: (Storable a) => Order -> [a] -> Lower ZeroInt a-autoLowerFromList = autoFromList -autoUpperFromList :: (Storable a) => Order -> [a] -> Upper ZeroInt a-autoUpperFromList = autoFromList--autoSymmetricFromList :: (Storable a) => Order -> [a] -> Symmetric ZeroInt a-autoSymmetricFromList = autoFromList--autoDiagonalFromList :: (Storable a) => Order -> [a] -> Diagonal ZeroInt a-autoDiagonalFromList = autoFromList---asDiagonal :: FlexDiagonal diag sh a -> FlexDiagonal diag sh a-asDiagonal = id--asLower :: FlexLower diag sh a -> FlexLower diag sh a-asLower = id--asUpper :: FlexUpper diag sh a -> FlexUpper diag sh a-asUpper = id--asSymmetric :: FlexSymmetric diag sh a -> FlexSymmetric diag sh a-asSymmetric = id--forceUnitDiagonal :: Triangular lo Unit up sh a -> Triangular lo Unit up sh a-forceUnitDiagonal = id--forceNonUnitDiagonal ::-   Triangular lo NonUnit up sh a -> Triangular lo NonUnit up sh a-forceNonUnitDiagonal = id-- toSquare ::    (MatrixShape.Content lo, MatrixShape.Content up,     Shape.C sh, Class.Floating a) =>@@ -278,7 +237,7 @@     Shape.C sh, Class.Floating a) =>    Order ->    (Square sh a -> Triangular lo NonUnit up sh a) ->-   Tri.Map diag sh a lo up+   Tri.Map diag sh sh a lo up forceOrderMap newOrder f = Tri.Map $ \a ->    if MatrixShape.triangularOrder (Array.shape a) == newOrder       then a@@ -291,9 +250,6 @@ uncheckedRelaxNonUnitDiagonal =    Array.mapShape (\sh -> sh{MatrixShape.triangularDiag = MatrixShape.autoDiag}) -{- |-@adaptOrder x y@ contains the data of @y@ with the layout of @x@.--} adaptOrder ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Shape.C sh, Class.Floating a) =>@@ -383,6 +339,19 @@ strictNonUnitDiagonal = Array.mapShape MatrixShape.strictNonUnitDiagonal  +liftDiagonal ::+   (Vector sh0 a -> Vector sh1 a) ->+   FlexDiagonal diag sh0 a -> FlexDiagonal diag sh1 a+liftDiagonal f (Array (MatrixShape.Triangular diag uplo order sh0) a) =+   Array.mapShape (MatrixShape.Triangular diag uplo order) $ f $ Array sh0 a++stackDiagonal ::+   (MatrixShape.TriDiag diag, Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   FlexDiagonal diag sh0 a ->+   FlexDiagonal diag sh1 a ->+   FlexDiagonal diag (sh0:+:sh1) a+stackDiagonal a = liftDiagonal (Vector.append $ takeDiagonal a)+ {- It does not make much sense to put 'stackLower', 'stackUpper', 'stackSymmetric' in one function@@ -400,22 +369,6 @@    transpose $    stackAux "LowerTriangular" (transpose a) (Basic.transpose b) (transpose c) -{- |-For upper triangular matrices it holds:--> toSquare (stack a b c)->-> =->-> toSquare a ||| b-> ===-> constant 0 ||| toSquare c--For the other triangular flavors it holds accordingly--It holds @order (stack a b c) = order b@.-The function is most efficient when the order of all blocks match.--} stackUpper ::    (MatrixShape.TriDiag diag,     Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Class.Floating a) =>@@ -451,7 +404,69 @@                MatrixShape.triangularSize = sh})          (forceOrder order a) b (forceOrder order c) +takeTopLeft ::+   (MatrixShape.Content lo, MatrixShape.TriDiag diag, MatrixShape.Content up,+    Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Triangular lo diag up (sh0:+:sh1) a ->+   Triangular lo diag up sh0 a+takeTopLeft =+   Tri.getMap $+   MatrixShape.switchDiagUpLoSym+      (Tri.Map $ liftDiagonal Vector.takeLeft)+      (Tri.Map $ takeTopLeftAux)+      (Tri.Map $ transpose . takeTopLeftAux . transpose)+      (Tri.Map $ takeTopLeftAux) +takeTopLeftAux ::+   (MatrixShape.Content lo, MatrixShape.TriDiag diag,+    Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Triangular lo diag MatrixShape.Filled (sh0:+:sh1) a ->+   Triangular lo diag MatrixShape.Filled sh0 a+takeTopLeftAux =+   Tri.takeTopLeft+      (\(MatrixShape.Triangular diag uplo order sh@(sh0:+:_sh1)) ->+         (MatrixShape.Triangular diag uplo order sh0, (order,sh)))++takeBottomLeft ::+   (MatrixShape.TriDiag diag, MatrixShape.Content up,+    Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Triangular MatrixShape.Filled diag up (sh0:+:sh1) a ->+   Matrix.General sh1 sh0 a+takeBottomLeft = Basic.transpose . takeTopRight . transpose++takeTopRight ::+   (MatrixShape.Content lo, MatrixShape.TriDiag diag,+    Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Triangular lo diag MatrixShape.Filled (sh0:+:sh1) a ->+   Matrix.General sh0 sh1 a+takeTopRight =+   Tri.takeTopRight+      (\(MatrixShape.Triangular _diag _uplo order sh) -> (order,sh))++takeBottomRight ::+   (MatrixShape.Content lo, MatrixShape.TriDiag diag, MatrixShape.Content up,+    Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Triangular lo diag up (sh0:+:sh1) a ->+   Triangular lo diag up sh1 a+takeBottomRight =+   Tri.getMap $+   MatrixShape.switchDiagUpLoSym+      (Tri.Map $ liftDiagonal Vector.takeRight)+      (Tri.Map $ takeBottomRightAux)+      (Tri.Map $ transpose . takeBottomRightAux . transpose)+      (Tri.Map $ takeBottomRightAux)++takeBottomRightAux ::+   (MatrixShape.Content lo, MatrixShape.TriDiag diag,+    Shape.C sh0, Shape.C sh1, Class.Floating a) =>+   Triangular lo diag MatrixShape.Filled (sh0:+:sh1) a ->+   Triangular lo diag MatrixShape.Filled sh1 a+takeBottomRightAux =+   Tri.takeBottomRight+      (\(MatrixShape.Triangular diag uplo order sh@(_sh0:+:sh1)) ->+         (MatrixShape.Triangular diag uplo order sh1, (order,sh)))++ multiplyVector ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Shape.C sh, Eq sh, Class.Floating a) =>@@ -459,11 +474,7 @@ multiplyVector =    Tri.getMultiplyRight $    MatrixShape.switchDiagUpLoSym-      (Tri.MultiplyRight $-       Tri.multiplyDiagonal-         "multiplyVector.diagonal: sizes mismatch"-         Array.shape-         (Vector.mul . takeDiagonal))+      (Tri.MultiplyRight $ Vector.mul . takeDiagonal)       (Tri.MultiplyRight multiplyVectorTriangular)       (Tri.MultiplyRight multiplyVectorTriangular)       (Tri.MultiplyRight multiplyVectorTriangular)@@ -516,27 +527,11 @@   square ::-   (MatrixShape.DiagUpLo lo up, MatrixShape.TriDiag diag,-    Shape.C sh, Eq sh, Class.Floating a) =>-   Triangular lo diag up sh a -> Triangular lo diag up sh a-square =-   Tri.getMap $-   MatrixShape.switchDiagUpLo-      (Tri.Map squareDiagonal)-      (Tri.Map squareTriangular)-      (Tri.Map squareTriangular)---{- |-Include symmetric matrices.-However, symmetric matrices do not preserve unit diagonals.--}-squareGeneric ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,-    Shape.C sh, Eq sh, Class.Floating a) =>+    Shape.C sh, Class.Floating a) =>    Triangular lo diag up sh a ->    Triangular lo (Tri.PowerDiag lo up diag) up sh a-squareGeneric =+square =    Tri.getPower $    MatrixShape.switchDiagUpLoSym       (Tri.Power squareDiagonal)@@ -546,12 +541,14 @@   squareDiagonal ::-   (MatrixShape.TriDiag diag,-    Shape.C sh, Eq sh, Class.Floating a) =>+   (MatrixShape.TriDiag diag, Shape.C sh, Class.Floating a) =>    FlexDiagonal diag sh a -> FlexDiagonal diag sh a squareDiagonal =    getMapDiag $-   MatrixShape.switchTriDiag (MapDiag id) (MapDiag $ \a -> Vector.mul a a)+   MatrixShape.switchTriDiag+      (MapDiag id)+      (MapDiag $+       VectorPriv.recheck . uncurry Vector.mul . double . VectorPriv.uncheck)  newtype MapDiag lo up sh a diag =    MapDiag {@@ -562,7 +559,7 @@  squareTriangular ::    (MatrixShape.UpLo lo up, MatrixShape.TriDiag diag,-    Shape.C sh, Eq sh, Class.Floating a) =>+    Shape.C sh, Class.Floating a) =>    Triangular lo diag up sh a -> Triangular lo diag up sh a squareTriangular    (Array shape@(MatrixShape.Triangular diag uplo order sh) a) =@@ -585,13 +582,66 @@          pack realOrder n bPtr bpPtr  squareSymmetric ::-   (Shape.C sh, Eq sh, Class.Floating a) =>-   Symmetric sh a -> Symmetric sh a+   (Shape.C sh, Class.Floating a) => Symmetric sh a -> Symmetric sh a squareSymmetric (Array shape@(MatrixShape.Triangular _diag _uplo order sh) a) =    Array.unsafeCreate shape $       Symmetric.square NonConjugated order (Shape.size sh) a  +uncheck :: Triangular lo diag up sh a -> Triangular lo diag up (Unchecked sh) a+uncheck =+   Array.mapShape $+      \(MatrixShape.Triangular diag uplo order sh) ->+         MatrixShape.Triangular diag uplo order (Unchecked sh)++recheck :: Triangular lo diag up (Unchecked sh) a -> Triangular lo diag up sh a+recheck =+   Array.mapShape $+      \(MatrixShape.Triangular diag uplo order (Unchecked sh)) ->+         MatrixShape.Triangular diag uplo order sh++{-+Requires frequent unpacking and packing of triangles.+-}+power ::+   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,+    Shape.C sh, Class.Floating a) =>+   Int ->+   Triangular lo diag up sh a ->+   Triangular lo (Tri.PowerDiag lo up diag) up sh a+power n =+   Tri.getPower $+   MatrixShape.switchDiagUpLoSym+      (Tri.Power $ Array.map (^n))+      (Tri.Power $ powerTriangular (fromIntegral n))+      (Tri.Power $ powerTriangular (fromIntegral n))+      (Tri.Power $ powerSymmetric (fromIntegral n) . strictNonUnitDiagonal)++powerTriangular ::+   (MatrixShape.UpLo lo up, MatrixShape.TriDiag diag,+    Shape.C sh, Class.Floating a) =>+   Integer -> Triangular lo diag up sh a -> Triangular lo diag up sh a+powerTriangular n a@(Array (MatrixShape.Triangular _diag _uplo order sh) _) =+   recheck $+   powerAssociative multiplyTriangular+      (relaxUnitDiagonal $ identity order $ Unchecked sh)+      (uncheck a)+      n++powerSymmetric ::+   (Shape.C sh, Class.Floating a) => Integer -> Symmetric sh a -> Symmetric sh a+powerSymmetric n a0@(Array (MatrixShape.Triangular _diag _uplo order sh) _) =+   recheck $+   powerAssociative+      (\a b ->+         Tri.fromUpperPart+            (MatrixShape.Triangular NonUnit MatrixShape.autoUplo) $+         multiplyFullTriangular a $ toSquare b)+      (relaxUnitDiagonal $ identity order $ Unchecked sh)+      (uncheck a0)+      n++ multiply ::    (MatrixShape.DiagUpLo lo up, MatrixShape.TriDiag diag,     Shape.C sh, Eq sh, Class.Floating a) =>@@ -600,16 +650,7 @@ multiply =    getMultiply $    MatrixShape.switchDiagUpLo-      (Multiply $-       Tri.multiplyDiagonal-         "multiply.diagonal: sizes mismatch"-         (MatrixShape.triangularSize . Array.shape)-         (\a b ->-            Array.mapShape-               (MatrixShape.Triangular-                  MatrixShape.autoDiag MatrixShape.autoUplo-                  (MatrixShape.triangularOrder $ Array.shape b)) $-            Vector.mul (takeDiagonal a) (takeDiagonal b)))+      (Multiply $ liftDiagonal . Vector.mul . takeDiagonal)       (Multiply multiplyTriangular)       (Multiply multiplyTriangular) @@ -664,11 +705,7 @@ multiplyFull =    Tri.getMultiplyRight $    MatrixShape.switchDiagUpLoSym-      (Tri.MultiplyRight $-       Tri.multiplyDiagonal-         "multiplyFull.diagonal: sizes mismatch"-         (MatrixShape.fullHeight . Array.shape)-         (Basic.scaleRows . takeDiagonal))+      (Tri.MultiplyRight $ Basic.scaleRows . takeDiagonal)       (Tri.MultiplyRight multiplyFullTriangular)       (Tri.MultiplyRight multiplyFullTriangular)       (Tri.MultiplyRight multiplyFullTriangular)
src/Numeric/LAPACK/Matrix/Triangular/Linear.hs view
@@ -3,7 +3,6 @@ module Numeric.LAPACK.Matrix.Triangular.Linear (    solve,    inverse,-   inverseGeneric,    determinant,    ) where @@ -11,16 +10,16 @@ import qualified Numeric.LAPACK.Matrix.Banded.Basic as Banded import qualified Numeric.LAPACK.Matrix.Symmetric.Private as Symmetric import qualified Numeric.LAPACK.Matrix.Triangular.Private as Tri+import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import qualified Numeric.LAPACK.Vector as Vector import Numeric.LAPACK.Linear.Private (solver, withInfo) import Numeric.LAPACK.Matrix.Triangular.Basic          (Triangular, Symmetric, PowerDiag, takeDiagonal, strictNonUnitDiagonal)-import Numeric.LAPACK.Matrix.Private (Full)--import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape-import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent import Numeric.LAPACK.Matrix.Shape.Private          (transposeFromOrder, uploFromOrder, uploOrder, charFromTriDiag)-import Numeric.LAPACK.Matrix.Private (Conjugation(NonConjugated))+import Numeric.LAPACK.Matrix.Modifier (Conjugation(NonConjugated))+import Numeric.LAPACK.Matrix.Private (Full) import Numeric.LAPACK.Private (copyBlock, copyToTemp)  import qualified Numeric.LAPACK.FFI.Generic as LapackGen@@ -51,11 +50,7 @@ solve =    Tri.getMultiplyRight $    MatrixShape.switchDiagUpLoSym-      (Tri.MultiplyRight $-       Tri.multiplyDiagonal-         "solve.diagonal: sizes mismatch"-         (MatrixShape.fullHeight . Array.shape)-         (BandedLin.solve . Banded.diagonal . takeDiagonal))+      (Tri.MultiplyRight $ BandedLin.solve . Banded.fromDiagonal)       (Tri.MultiplyRight solveTriangular)       (Tri.MultiplyRight solveTriangular)       (Tri.MultiplyRight $ solveSymmetric . strictNonUnitDiagonal)@@ -87,22 +82,11 @@   inverse ::-   (MatrixShape.DiagUpLo lo up, MatrixShape.TriDiag diag,-    Shape.C sh, Class.Floating a) =>-   Triangular lo diag up sh a -> Triangular lo diag up sh a-inverse =-   Tri.getMap $-   MatrixShape.switchDiagUpLo-      (Tri.Map inverseDiagonal)-      (Tri.Map inverseTriangular)-      (Tri.Map inverseTriangular)--inverseGeneric ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Shape.C sh, Class.Floating a) =>    Triangular lo diag up sh a ->    Triangular lo (PowerDiag lo up diag) up sh a-inverseGeneric =+inverse =    Tri.getPower $    MatrixShape.switchDiagUpLoSym       (Tri.Power inverseDiagonal)@@ -113,7 +97,10 @@ inverseDiagonal ::    (MatrixShape.TriDiag diag, Shape.C sh, Class.Floating a) =>    Tri.FlexDiagonal diag sh a -> Tri.FlexDiagonal diag sh a-inverseDiagonal = Tri.caseTriDiagArray id (Array.map recip)+inverseDiagonal a =+   MatrixShape.caseTriDiag+      (MatrixShape.triangularDiag $ Array.shape a)+      a (Vector.recip a)  inverseTriangular ::    (MatrixShape.UpLo lo up, MatrixShape.TriDiag diag,
src/Numeric/LAPACK/Matrix/Triangular/Private.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}+{-# LANGUAGE ConstraintKinds #-} module Numeric.LAPACK.Matrix.Triangular.Private where  import qualified Numeric.LAPACK.Matrix.Private as Matrix@@ -9,7 +10,8 @@ import Numeric.LAPACK.Matrix.Shape.Private          (Order(RowMajor,ColumnMajor), flipOrder, uploFromOrder,           Empty, Filled, NonUnit)-import Numeric.LAPACK.Matrix.Private (Full, Conjugation(Conjugated))+import Numeric.LAPACK.Matrix.Modifier (Conjugation(NonConjugated))+import Numeric.LAPACK.Matrix.Private (Full) import Numeric.LAPACK.Scalar (zero) import Numeric.LAPACK.Private          (pointerSeq, copyBlock, copyCondConjugateToTemp,@@ -80,7 +82,10 @@    Class.Floating a =>    Conjugation -> Order -> Int -> ForeignPtr a -> ContT r IO (Ptr a) copyTriangleToTemp conj order =-   copyCondConjugateToTemp (order==RowMajor && conj==Conjugated)+   copyCondConjugateToTemp $+   case order of+      RowMajor -> conj+      ColumnMajor -> NonConjugated   unpackToTemp ::@@ -144,64 +149,98 @@ stack name consShape       (Array sha a) (Array (MatrixShape.Full order extent) b) (Array shc c) =    let (height,width) = Extent.dimensions extent-   in Array.unsafeCreate (consShape (height :+: width)) $ \xPtr ->-   withForeignPtr b $ \bPtr -> do+   in Array.unsafeCreate (consShape (height :+: width)) $ \xPtr -> do       Call.assert (name++".stack: height shapes mismatch") $          height == Box.height sha       Call.assert (name++".stack: width shapes mismatch") $          width == Box.width shc       let m = Shape.size height       let n = Shape.size width-      copyTriangleA order m n a xPtr-      copyRectangle order m n bPtr xPtr-      copyTriangleC order m n c xPtr+      withForeignPtr a $ \aPtr -> copyTriangleA copyBlock order m n aPtr xPtr+      withForeignPtr b $ \bPtr -> copyRectangle copyBlock order m n bPtr xPtr+      withForeignPtr c $ \cPtr -> copyTriangleC copyBlock order m n cPtr xPtr +takeTopRight ::+   (Shape.C sh, Shape.C height, Shape.C width, Class.Floating a) =>+   (sh -> (MatrixShape.Order, height:+:width)) ->+   Array sh a -> Matrix.General height width a+takeTopRight getShapes (Array sh x) =+   let (order, height:+:width) = getShapes sh+   in Array.unsafeCreate (MatrixShape.general order height width) $ \bPtr -> do+      let m = Shape.size height+      let n = Shape.size width+      withForeignPtr x $ copyRectangle (flip . copyBlock) order m n bPtr++takeTopLeft ::+   (Shape.C sh, Shape.C sha, Shape.C height, Shape.C width, Class.Floating a) =>+   (sh -> (sha, (MatrixShape.Order, height:+:width))) ->+   Array sh a -> Array sha a+takeTopLeft getShapes (Array sh x) =+   let (sha, (order, height:+:width)) = getShapes sh+   in Array.unsafeCreate sha $ \aPtr -> do+      let m = Shape.size height+      let n = Shape.size width+      withForeignPtr x $ copyTriangleA (flip . copyBlock) order m n aPtr++takeBottomRight ::+   (Shape.C sh, Shape.C shc, Shape.C height, Shape.C width, Class.Floating a) =>+   (sh -> (shc, (MatrixShape.Order, height:+:width))) ->+   Array sh a -> Array shc a+takeBottomRight getShapes (Array sh x) =+   let (shc, (order, height:+:width)) = getShapes sh+   in Array.unsafeCreate shc $ \cPtr -> do+      let m = Shape.size height+      let n = Shape.size width+      withForeignPtr x $ copyTriangleC (flip . copyBlock) order m n cPtr++{-# INLINE copyTriangleA #-} copyTriangleA ::    (Class.Floating a) =>-   Order -> Int -> Int -> ForeignPtr a -> Ptr a -> IO ()-copyTriangleA order m n a xPtr =-   withForeignPtr a $ \aPtr ->-      case order of-         ColumnMajor -> copyBlock (Shape.triangleSize m) aPtr xPtr-         RowMajor ->-            forM_ (zip (iterate pred m) $-                   zip (diagonalPointers order m aPtr)-                       (diagonalPointers order (m+n) xPtr)) $-               \(k,(aiPtr,xiPtr)) -> copyBlock k aiPtr xiPtr+   (Int -> Ptr a -> Ptr a -> IO ()) ->+   Order -> Int -> Int -> Ptr a -> Ptr a -> IO ()+copyTriangleA copy order m n aPtr xPtr =+   case order of+      ColumnMajor -> copy (Shape.triangleSize m) aPtr xPtr+      RowMajor ->+         forM_ (zip (iterate pred m) $+                zip (diagonalPointers order m aPtr)+                    (diagonalPointers order (m+n) xPtr)) $+            \(k,(aiPtr,xiPtr)) -> copy k aiPtr xiPtr +{-# INLINE copyTriangleC #-} copyTriangleC ::    (Class.Floating a) =>-   Order -> Int -> Int -> ForeignPtr a -> Ptr a -> IO ()-copyTriangleC order m n c xPtr =-   withForeignPtr c $ \cPtr ->-      case order of-         RowMajor ->-            let triSize = Shape.triangleSize n-            in copyBlock triSize cPtr-                  (advancePtr xPtr $ Shape.triangleSize (m+n) - triSize)-         ColumnMajor ->-            forM_ (zip (iterate succ 0) $-                   zip (diagonalPointers order n cPtr)-                       (drop m $ diagonalPointers order (m+n) xPtr)) $-               \(k,(aiPtr,xiPtr)) ->-                  copyBlock (k+1)-                     (advancePtr aiPtr (-k)) (advancePtr xiPtr (-k))+   (Int -> Ptr a -> Ptr a -> IO ()) ->+   Order -> Int -> Int -> Ptr a -> Ptr a -> IO ()+copyTriangleC copy order m n cPtr xPtr =+   case order of+      RowMajor ->+         let triSize = Shape.triangleSize n+         in copy triSize cPtr+               (advancePtr xPtr $ Shape.triangleSize (m+n) - triSize)+      ColumnMajor ->+         forM_ (zip (iterate succ 0) $+                zip (diagonalPointers order n cPtr)+                    (drop m $ diagonalPointers order (m+n) xPtr)) $+            \(k,(aiPtr,xiPtr)) ->+               copy (k+1) (advancePtr aiPtr (-k)) (advancePtr xiPtr (-k)) +{-# INLINE copyRectangle #-} copyRectangle ::-   (Class.Floating a) => Order -> Int -> Int -> Ptr a -> Ptr a -> IO ()-copyRectangle order m n bPtr xPtr =+   (Class.Floating a) =>+   (Int -> Ptr a -> Ptr a -> IO ()) ->+   Order -> Int -> Int -> Ptr a -> Ptr a -> IO ()+copyRectangle copy order m n bPtr xPtr =    case order of       RowMajor ->          forM_ (take m $ zip (iterate pred m) $                 zip (pointerSeq n bPtr) (diagonalPointers order (m+n) xPtr)) $-            \(k,(biPtr,xiPtr)) ->-               copyBlock n biPtr (advancePtr xiPtr k)+            \(k,(biPtr,xiPtr)) -> copy n biPtr (advancePtr xiPtr k)       ColumnMajor ->          forM_ (take n $ zip (iterate succ m) $                 zip (pointerSeq m bPtr)                     (drop m $ diagonalPointers order (m+n) xPtr)) $-            \(k,(biPtr,xiPtr)) ->-               copyBlock m biPtr (advancePtr xiPtr (-k))+            \(k,(biPtr,xiPtr)) -> copy m biPtr (advancePtr xiPtr (-k))   @@ -213,8 +252,8 @@ newtype MultiplyRight diag sh a b lo up =    MultiplyRight {getMultiplyRight :: Triangular lo diag up sh a -> b} -newtype Map diag sh a lo up =-   Map {getMap :: Triangular lo diag up sh a -> Triangular lo diag up sh a}+newtype Map diag sh0 sh1 a lo up =+   Map {getMap :: Triangular lo diag up sh0 a -> Triangular lo diag up sh1 a}  newtype Power diag sh a lo up =    Power {@@ -228,28 +267,9 @@ type instance PowerDiag Filled Empty diag = diag type instance PowerDiag Filled Filled diag = NonUnit -caseTriDiagArray ::-   (MatrixShape.TriDiag diag) =>-   (Triangular lo diag up sh a -> b) ->-   (Triangular lo diag up sh a -> b) ->-   (Triangular lo diag up sh a -> b)-caseTriDiagArray fu fn a =-   MatrixShape.caseTriDiag-      (MatrixShape.triangularDiag $ Array.shape a)-      (fu a) (fn a)--multiplyDiagonal ::-   (Eq sh, MatrixShape.TriDiag diag) =>-   String ->-   (b -> sh) ->-   (Triangular lo diag up sh a -> b -> b) ->-   (Triangular lo diag up sh a -> b -> b)-multiplyDiagonal msg shape =-   caseTriDiagArray-      (\a b ->-         if MatrixShape.triangularSize (Array.shape a) == shape b-           then b-           else error ("Triangular." ++ msg))+type PowerContentDiag lo diag up =+      (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,+       PowerDiag lo up diag ~ diag, PowerDiag up lo diag ~ diag)   fromBanded ::@@ -290,3 +310,17 @@          let dstOrder = flipOrder order          packRect dstOrder m k aPtr lPtr          fillDiag dstOrder m lPtr+++fromUpperPart ::+   (Extent.C vert, Shape.C height, Shape.C width, Shape.C shape,+    Class.Floating a) =>+   (Order -> width -> shape) ->+   Full vert Extent.Small height width a -> Array shape a+fromUpperPart shape (Array (MatrixShape.Full order extent) a) =+   let (height,width) = Extent.dimensions extent+       m = Shape.size height+       n = Shape.size width+       k = case order of RowMajor -> n; ColumnMajor -> m+   in Array.unsafeCreate (shape order width) $ \bPtr ->+      withForeignPtr a $ \aPtr -> packRect order n k aPtr bPtr
+ src/Numeric/LAPACK/Matrix/Type.hs view
@@ -0,0 +1,117 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE EmptyDataDecls #-}+module Numeric.LAPACK.Matrix.Type where++import qualified Numeric.LAPACK.Matrix.Plain.Format as ArrFormat+import qualified Numeric.LAPACK.Output as Output+import qualified Numeric.LAPACK.Permutation.Private as Perm+import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import Numeric.LAPACK.Output (Output)++import qualified Numeric.Netlib.Class as Class++import qualified Hyper++import qualified Control.DeepSeq as DeepSeq++import qualified Data.Array.Comfort.Shape as Shape++import Data.Semigroup (Semigroup, (<>))++++data family Matrix typ a+++data Scale shape+data instance Matrix (Scale shape) a = Scale shape a+++newtype instance Matrix (Perm.Permutation sh) a =+   Permutation (Perm.Permutation sh)+      deriving (Show)++++instance (NFData typ, DeepSeq.NFData a) => DeepSeq.NFData (Matrix typ a) where+   rnf = rnf++class NFData typ where+   rnf :: (DeepSeq.NFData a) => Matrix typ a -> ()++++instance+   (FormatMatrix typ, Class.Floating a) =>+      Hyper.Display (Matrix typ a) where+   display = Output.hyper . formatMatrix ArrFormat.deflt+++class FormatMatrix typ where+   {-+   We use constraint @(Class.Floating a)@ and not @(Format a)@+   because it allows us to align the components of complex numbers.+   -}+   formatMatrix ::+      (Class.Floating a, Output out) => String -> Matrix typ a -> out++instance (Shape.C sh) => FormatMatrix (Scale sh) where+   formatMatrix fmt (Scale shape a) =+      ArrFormat.formatDiagonal fmt MatrixShape.RowMajor shape $+      replicate (Shape.size shape) a++instance (Shape.C sh) => FormatMatrix (Perm.Permutation sh) where+   formatMatrix _fmt (Permutation perm) = Perm.format perm++++instance (MultiplySame typ, Class.Floating a) => Semigroup (Matrix typ a) where+   (<>) = multiplySame++class MultiplySame typ where+   multiplySame ::+      (Class.Floating a) => Matrix typ a -> Matrix typ a -> Matrix typ a++instance (Eq shape) => MultiplySame (Scale shape) where+   multiplySame =+      scaleWithCheck "Scale.multiplySame" height+         (\a (Scale shape b) -> Scale shape $ a*b)++instance (Shape.C sh, Eq sh) => MultiplySame (Perm.Permutation sh) where+   multiplySame (Permutation a) (Permutation b) =+      Permutation $ Perm.multiply b a+++scaleWithCheck :: (Eq shape) =>+   String -> (b -> shape) ->+   (a -> b -> c) -> Matrix (Scale shape) a -> b -> c+scaleWithCheck name getSize f (Scale shape a) b =+   if shape == getSize b+      then f a b+      else error $ name ++ ": dimensions mismatch"+++class Box typ where+   type HeightOf typ+   type WidthOf typ+   height :: Matrix typ a -> HeightOf typ+   width :: Matrix typ a -> WidthOf typ++instance Box (Scale sh) where+   type HeightOf (Scale sh) = sh+   type WidthOf (Scale sh) = sh+   height (Scale shape _) = shape+   width (Scale shape _) = shape++instance Box (Perm.Permutation sh) where+   type HeightOf (Perm.Permutation sh) = sh+   type WidthOf (Perm.Permutation sh) = sh+   height (Permutation perm) = Perm.size perm+   width (Permutation perm) = Perm.size perm++indices ::+   (Box typ,+    HeightOf typ ~ height, Shape.Indexed height,+    WidthOf typ ~ width, Shape.Indexed width) =>+   Matrix typ a -> [(Shape.Index height, Shape.Index width)]+indices sh = Shape.indices (height sh, width sh)
src/Numeric/LAPACK/Orthogonal.hs view
@@ -10,48 +10,24 @@    complement,     householder,+   householderTall,    ) where -import qualified Numeric.LAPACK.Orthogonal.Private as HH+import qualified Numeric.LAPACK.Orthogonal.Householder as HH+import qualified Numeric.LAPACK.Orthogonal.Plain as Plain -import qualified Numeric.LAPACK.Matrix.Square.Basic as Square-import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import qualified Numeric.LAPACK.Matrix.Triangular as Triangular+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix.Basic as Basic-import Numeric.LAPACK.Matrix.Square.Basic (Square)-import Numeric.LAPACK.Matrix.Private (Full, Tall, ZeroInt, zeroInt)-import Numeric.LAPACK.Matrix (transpose, dropColumns)--import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape-import qualified Numeric.LAPACK.Matrix as Matrix-import qualified Numeric.LAPACK.Vector as Vector-import Numeric.LAPACK.Matrix.Shape.Private (Order(RowMajor,ColumnMajor))-import Numeric.LAPACK.Scalar (RealOf, zero, absolute)-import Numeric.LAPACK.Private-         (lacgv, peekCInt,-          copySubMatrix, copyToTemp, copyToColumnMajor, copyToSubColumnMajor,-          withAutoWorkspaceInfo, rankMsg, errorCodeMsg, createHigherArray)+import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import Numeric.LAPACK.Matrix.Array (Full, Tall, Square)+import Numeric.LAPACK.Matrix.Private (ShapeInt)+import Numeric.LAPACK.Scalar (RealOf) -import qualified Numeric.LAPACK.FFI.Generic as LapackGen-import qualified Numeric.LAPACK.FFI.Complex as LapackComplex-import qualified Numeric.LAPACK.FFI.Real as LapackReal-import qualified Numeric.Netlib.Utility as Call 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.Unchecked (Array(Array)) -import System.IO.Unsafe (unsafePerformIO)--import Foreign.Marshal.Array (pokeArray)-import Foreign.C.Types (CInt, CChar)-import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)-import Foreign.Ptr (Ptr)--import Control.Monad.Trans.Cont (ContT(ContT), evalContT)-import Control.Monad.IO.Class (liftIO)--import Data.Complex (Complex) import Data.Tuple.HT (mapSnd)  @@ -67,37 +43,7 @@    Full horiz Extent.Small height width a ->    Full vert horiz height nrhs a ->    Full vert horiz width nrhs a-leastSquares-   (Array shapeA@(MatrixShape.Full orderA extentA) a)-   (Array shapeB@(MatrixShape.Full orderB extentB) b) =-- case Extent.fuse (Extent.generalizeWide $ Extent.transpose extentA) extentB of-  Nothing -> error "leastSquares: height shapes mismatch"-  Just extent ->-      Array.unsafeCreate (MatrixShape.Full ColumnMajor extent) $ \xPtr -> do--   let widthA = Extent.width extentA-   let (height,widthB) = Extent.dimensions extentB-   let (m,n) = MatrixShape.dimensions shapeA-   let lda = m-   let nrhs = Shape.size widthB-   let ldb = Shape.size height-   let ldx = Shape.size widthA-   evalContT $ do-      mPtr <- Call.cint m-      nPtr <- Call.cint n-      nrhsPtr <- Call.cint nrhs-      (transPtr,aPtr) <- transposeA orderA (m*n) a-      ldaPtr <- Call.leadingDim lda-      bPtr <- ContT $ withForeignPtr b-      ldbPtr <- Call.leadingDim ldb-      let bSize = Shape.size shapeB-      btmpPtr <- Call.allocaArray bSize-      liftIO $ copyToColumnMajor orderB ldb nrhs bPtr btmpPtr-      liftIO $ withAutoWorkspaceInfo rankMsg "gels" $-         LapackGen.gels transPtr-            mPtr nPtr nrhsPtr aPtr ldaPtr btmpPtr ldbPtr-      liftIO $ copySubMatrix ldx nrhs ldb btmpPtr ldx xPtr+leastSquares = ArrMatrix.lift2 Plain.leastSquares  {- | The vector @x@ with @x = minimumNorm a b@@@ -112,57 +58,13 @@    Full Extent.Small vert height width a ->    Full vert horiz height nrhs a ->    Full vert horiz width nrhs a-minimumNorm-   (Array shapeA@(MatrixShape.Full orderA extentA) a)-   (Array        (MatrixShape.Full orderB extentB) b) =-- case Extent.fuse (Extent.generalizeTall $ Extent.transpose extentA) extentB of-  Nothing -> error "minimumNorm: height shapes mismatch"-  Just extent ->-      Array.unsafeCreate (MatrixShape.Full ColumnMajor extent) $ \xPtr -> do--   let widthA = Extent.width extentA-   let (height,widthB) = Extent.dimensions extentB-   let (m,n) = MatrixShape.dimensions shapeA-   let lda = m-   let nrhs = Shape.size widthB-   let ldb = Shape.size height-   let ldx = Shape.size widthA-   evalContT $ do-      mPtr <- Call.cint m-      nPtr <- Call.cint n-      nrhsPtr <- Call.cint nrhs-      (transPtr,aPtr) <- transposeA orderA (m*n) a-      ldaPtr <- Call.leadingDim lda-      bPtr <- ContT $ withForeignPtr b-      ldxPtr <- Call.leadingDim ldx-      liftIO $ copyToSubColumnMajor orderB ldb nrhs bPtr ldx xPtr-      liftIO $ withAutoWorkspaceInfo rankMsg "gels" $-         LapackGen.gels transPtr-            mPtr nPtr nrhsPtr aPtr ldaPtr xPtr ldxPtr---transposeA ::-   Class.Floating a =>-   Order -> Int -> ForeignPtr a -> ContT r IO (Ptr CChar, Ptr a)-transposeA order size a = do-   aPtr <- copyToTemp size a-   trans <--      case order of-         RowMajor -> do-            sizePtr <- Call.cint size-            incPtr <- Call.cint 1-            liftIO $ lacgv sizePtr aPtr incPtr-            return $ HH.invChar a-         ColumnMajor -> return 'N'-   transPtr <- Call.char trans-   return (transPtr, aPtr)+minimumNorm = ArrMatrix.lift2 Plain.minimumNorm   {- | If @(rank,x) = leastSquaresMinimumNormRCond rcond a b@ then @x@ is the vector with minimum @Vector.norm2 x@-that minimizes @Vector.norm2 (a#>x `sub` b)@.+that minimizes @Vector.norm2 (a #*| x `sub` b)@.  Matrix @a@ can have any rank but you must specify the reciprocal condition of the rank-truncated matrix.@@ -174,117 +76,22 @@    Full horiz vert height width a ->    Full vert horiz height nrhs a ->    (Int, Full vert horiz width nrhs a)-leastSquaresMinimumNormRCond rcond-      (Array (MatrixShape.Full orderA extentA) a)-      (Array (MatrixShape.Full orderB extentB) b) =-   case Extent.fuse (Extent.transpose extentA) extentB of-      Nothing -> error "leastSquaresMinimumNormRCond: height shapes mismatch"-      Just extent ->-         let widthA = Extent.width extentA-             (height,widthB) = Extent.dimensions extentB-             shapeX = MatrixShape.Full ColumnMajor extent-             m = Shape.size height-             n = Shape.size widthA-             nrhs = Shape.size widthB-         in  if m == 0-                then (0, Vector.constant shapeX zero)-                else-                  if nrhs == 0-                     then-                        (fst $ unsafePerformIO $-                         case Vector.constant height zero of-                           Array _ b1 ->-                              leastSquaresMinimumNormIO rcond-                                 (MatrixShape.general ColumnMajor widthA ())-                                 orderA a orderB b1 m n 1,-                         Vector.constant shapeX zero)-                     else-                        unsafePerformIO $-                        leastSquaresMinimumNormIO rcond shapeX-                           orderA a orderB b m n nrhs--leastSquaresMinimumNormIO ::-   (Shape.C sh, Class.Floating a) =>-   RealOf a -> sh ->-   Order -> ForeignPtr a ->-   Order -> ForeignPtr a ->-   Int -> Int -> Int -> IO (Int, Array sh a)-leastSquaresMinimumNormIO rcond shapeX orderA a orderB b m n nrhs =-   createHigherArray shapeX m n nrhs $ \(tmpPtr,ldtmp) -> do--   let aSize = m*n-   let lda = m-   evalContT $ do-      aPtr <- ContT $ withForeignPtr a-      atmpPtr <- Call.allocaArray aSize-      liftIO $ copyToColumnMajor orderA m n aPtr atmpPtr-      ldaPtr <- Call.leadingDim lda-      ldtmpPtr <- Call.leadingDim ldtmp-      bPtr <- ContT $ withForeignPtr b-      liftIO $ copyToSubColumnMajor orderB m nrhs bPtr ldtmp tmpPtr-      jpvtPtr <- Call.allocaArray n-      liftIO $ pokeArray jpvtPtr (replicate n 0)-      rankPtr <- Call.alloca-      gelsy m n nrhs atmpPtr ldaPtr tmpPtr ldtmpPtr jpvtPtr rcond rankPtr-      liftIO $ peekCInt rankPtr---type GELSY_ r ar a =-   Int -> Int -> Int -> Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt ->-   Ptr CInt -> ar -> Ptr CInt -> ContT r IO ()--newtype GELSY r a = GELSY {getGELSY :: GELSY_ r (RealOf a) a}--gelsy :: (Class.Floating a) => GELSY_ r (RealOf a) a-gelsy =-   getGELSY $-   Class.switchFloating-      (GELSY gelsyReal)-      (GELSY gelsyReal)-      (GELSY gelsyComplex)-      (GELSY gelsyComplex)--gelsyReal :: (Class.Real a) => GELSY_ r a a-gelsyReal m n nrhs aPtr ldaPtr bPtr ldbPtr jpvtPtr rcond rankPtr = do-   mPtr <- Call.cint m-   nPtr <- Call.cint n-   nrhsPtr <- Call.cint nrhs-   rcondPtr <- Call.real rcond-   liftIO $ withAutoWorkspaceInfo errorCodeMsg "gelsy" $-      LapackReal.gelsy mPtr nPtr nrhsPtr-         aPtr ldaPtr bPtr ldbPtr jpvtPtr rcondPtr rankPtr--gelsyComplex :: (Class.Real a) => GELSY_ r a (Complex a)-gelsyComplex m n nrhs aPtr ldaPtr bPtr ldbPtr jpvtPtr rcond rankPtr = do-   mPtr <- Call.cint m-   nPtr <- Call.cint n-   nrhsPtr <- Call.cint nrhs-   rcondPtr <- Call.real rcond-   rworkPtr <- Call.allocaArray (2*n)-   liftIO $-      withAutoWorkspaceInfo errorCodeMsg "gelsy" $ \workPtr lworkPtr infoPtr ->-      LapackComplex.gelsy mPtr nPtr nrhsPtr-         aPtr ldaPtr bPtr ldbPtr jpvtPtr rcondPtr rankPtr-         workPtr lworkPtr rworkPtr infoPtr+leastSquaresMinimumNormRCond rcond a b =+   mapSnd ArrMatrix.lift0 $+   Plain.leastSquaresMinimumNormRCond+      rcond (ArrMatrix.toVector a) (ArrMatrix.toVector b)   pseudoInverseRCond ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>    RealOf a ->    Full vert horiz height width a ->    (Int, Full horiz vert width height a)-pseudoInverseRCond rcond a =-   case Matrix.caseTallWide a of-      Left _ ->-         mapSnd transpose $-         leastSquaresMinimumNormRCond rcond (transpose a) $-         Square.toFull $ Square.identity $-         MatrixShape.fullWidth $ Array.shape a-      Right _ ->-         leastSquaresMinimumNormRCond rcond a $-         Square.toFull $ Square.identity $-         MatrixShape.fullHeight $ Array.shape a+pseudoInverseRCond rcond =+   mapSnd (ArrMatrix.lift0 . Basic.recheck) .+   Plain.pseudoInverseRCond rcond .+   Basic.uncheck . ArrMatrix.toVector   {-@@ -300,7 +107,15 @@    let hh = HH.fromMatrix a    in  (HH.extractQ hh, HH.extractR hh) +householderTall ::+   (Extent.C vert, Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert Extent.Small height width a ->+   (Full vert Extent.Small height width a, Triangular.Upper width a)+householderTall a =+   let hh = HH.fromMatrix a+   in  (HH.tallExtractQ hh, HH.tallExtractR hh) + determinant :: (Shape.C sh, Class.Floating a) => Square sh a -> a determinant = HH.determinant . HH.fromMatrix @@ -308,16 +123,13 @@ Gramian determinant - works also for non-square matrices, but is sensitive to transposition. -> determinantAbsolute a = sqrt (Herm.determinant (Herm.covariance a))+> determinantAbsolute a = sqrt (Herm.determinant (Herm.gramian a)) -} determinantAbsolute ::    (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,     Class.Floating a) =>    Full vert horiz height width a -> RealOf a-determinantAbsolute =-   absolute .-   either (HH.determinantR . HH.fromMatrix) (const zero) .-   Matrix.caseTallWide+determinantAbsolute = Plain.determinantAbsolute . ArrMatrix.toVector   {- |@@ -331,8 +143,5 @@ -} complement ::    (Shape.C height, Shape.C width, Class.Floating a) =>-   Tall height width a -> Tall height ZeroInt a-complement a =-   dropColumns (Shape.size $ MatrixShape.fullWidth $ Array.shape a) $-   Basic.mapWidth (zeroInt . Shape.size) $ Square.toFull $-   HH.extractQ $ HH.fromMatrix a+   Tall height width a -> Tall height ShapeInt a+complement = ArrMatrix.lift1 Plain.complement
src/Numeric/LAPACK/Orthogonal/Householder.hs view
@@ -1,19 +1,18 @@ module Numeric.LAPACK.Orthogonal.Householder (-   Householder,-   General,-   Tall,-   Wide,-   Square,-   mapExtent,+   Basic.Householder,+   Basic.General,+   Basic.Tall,+   Basic.Wide,+   Basic.Square,+   Basic.mapExtent,    fromMatrix,-   determinant,-   determinantAbsolute,+   Basic.determinant,+   Basic.determinantAbsolute,    leastSquares,    minimumNorm, -   Matrix.Transposition(..),-   Matrix.Conjugation(..),-   Matrix.Inversion(..),+   Mod.Transposition(..),+   Mod.Conjugation(..),    extractQ,    extractR,    multiplyQ,@@ -26,5 +25,122 @@    tallSolveR,    ) where -import qualified Numeric.LAPACK.Matrix.Private as Matrix-import Numeric.LAPACK.Orthogonal.Private+import qualified Numeric.LAPACK.Orthogonal.Private as Basic+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Extent as Extent+import qualified Numeric.LAPACK.Matrix.Modifier as Mod+import Numeric.LAPACK.Orthogonal.Private (Householder)+import Numeric.LAPACK.Matrix.Array.Triangular (Upper)+import Numeric.LAPACK.Matrix.Array (Full, Square)+import Numeric.LAPACK.Matrix.Modifier (Transposition, Conjugation)++import qualified Numeric.Netlib.Class as Class++import qualified Data.Array.Comfort.Shape as Shape+++fromMatrix ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>+   Full vert horiz height width a ->+   Householder vert horiz height width a+fromMatrix = Basic.fromMatrix . ArrMatrix.toVector++leastSquares ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Eq width, Shape.C nrhs,+    Class.Floating a) =>+   Householder horiz Extent.Small height width a ->+   Full vert horiz height nrhs a ->+   Full vert horiz width nrhs a+leastSquares = ArrMatrix.lift1 . Basic.leastSquares++{- |+@+HH.minimumNorm (HH.fromMatrix a) b+==+Ortho.minimumNorm (adjoint a) b+@+-}+minimumNorm ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Eq width, Shape.C nrhs,+    Class.Floating a) =>+   Householder vert Extent.Small width height a ->+   Full vert horiz height nrhs a ->+   Full vert horiz width nrhs a+minimumNorm = ArrMatrix.lift1 . Basic.minimumNorm+++extractQ ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>+   Householder vert horiz height width a -> Square height a+extractQ = ArrMatrix.lift0 . Basic.extractQ++tallExtractQ ::+   (Extent.C vert, Shape.C height, Shape.C width, Class.Floating a) =>+   Householder vert Extent.Small height width a ->+   Full vert Extent.Small height width a+tallExtractQ = ArrMatrix.lift0 . Basic.tallExtractQ+++tallMultiplyQ ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Shape.C fuse, Eq fuse,+    Class.Floating a) =>+   Householder vert Extent.Small height fuse a ->+   Full vert horiz fuse width a ->+   Full vert horiz height width a+tallMultiplyQ = ArrMatrix.lift1 . Basic.tallMultiplyQ++tallMultiplyQAdjoint ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Shape.C fuse, Eq fuse, Class.Floating a) =>+   Householder horiz Extent.Small fuse height a ->+   Full vert horiz fuse width a ->+   Full vert horiz height width a+tallMultiplyQAdjoint = ArrMatrix.lift1 . Basic.tallMultiplyQAdjoint+++multiplyQ ::+   (Extent.C vertA, Extent.C horizA, Shape.C widthA,+    Extent.C vertB, Extent.C horizB, Shape.C widthB,+    Shape.C height, Eq height, Class.Floating a) =>+   Transposition -> Conjugation ->+   Householder vertA horizA height widthA a ->+   Full vertB horizB height widthB a ->+   Full vertB horizB height widthB a+multiplyQ transposed conjugated =+   ArrMatrix.lift1 . Basic.multiplyQ transposed conjugated+++extractR ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>+   Householder vert horiz height width a ->+   Full vert horiz height width a+extractR = ArrMatrix.lift0 . Basic.extractR++tallExtractR ::+   (Extent.C vert, Shape.C height, Shape.C width, Class.Floating a) =>+   Householder vert Extent.Small height width a -> Upper width a+tallExtractR = ArrMatrix.lift0 . Basic.tallExtractR++tallMultiplyR ::+   (Extent.C vertA, Extent.C vert, Extent.C horiz, Shape.C height, Eq height,+    Shape.C heightA, Shape.C widthB, Class.Floating a) =>+   Transposition ->+   Householder vertA Extent.Small heightA height a ->+   Full vert horiz height widthB a ->+   Full vert horiz height widthB a+tallMultiplyR transposed = ArrMatrix.lift1 . Basic.tallMultiplyR transposed++tallSolveR ::+   (Extent.C vertA, Extent.C vert, Extent.C horiz,+    Shape.C height, Shape.C width, Eq width, Shape.C nrhs, Class.Floating a) =>+   Transposition -> Conjugation ->+   Householder vertA Extent.Small height width a ->+   Full vert horiz width nrhs a -> Full vert horiz width nrhs a+tallSolveR transposed conjugated =+   ArrMatrix.lift1 . Basic.tallSolveR transposed conjugated
+ src/Numeric/LAPACK/Orthogonal/Plain.hs view
@@ -0,0 +1,278 @@+{-# LANGUAGE TypeFamilies #-}+module Numeric.LAPACK.Orthogonal.Plain (+   leastSquares,+   minimumNorm,+   leastSquaresMinimumNormRCond,+   pseudoInverseRCond,++   determinantAbsolute,+   complement,+   ) where++import qualified Numeric.LAPACK.Orthogonal.Private as HH++import qualified Numeric.LAPACK.Matrix.Square.Basic as Square+import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import qualified Numeric.LAPACK.Matrix.Basic as Basic+import qualified Numeric.LAPACK.Vector as Vector+import Numeric.LAPACK.Matrix.Shape.Private (Order(RowMajor,ColumnMajor))+import Numeric.LAPACK.Matrix.Private (Full, Tall, ShapeInt, shapeInt)+import Numeric.LAPACK.Scalar (RealOf, zero, absolute)+import Numeric.LAPACK.Private+         (lacgv, peekCInt,+          copySubMatrix, copyToTemp, copyToColumnMajor, copyToSubColumnMajor,+          withAutoWorkspaceInfo, rankMsg, errorCodeMsg, createHigherArray)++import qualified Numeric.LAPACK.FFI.Generic as LapackGen+import qualified Numeric.LAPACK.FFI.Complex as LapackComplex+import qualified Numeric.LAPACK.FFI.Real as LapackReal+import qualified Numeric.Netlib.Utility as Call+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.Unchecked (Array(Array))++import System.IO.Unsafe (unsafePerformIO)++import Foreign.Marshal.Array (pokeArray)+import Foreign.C.Types (CInt, CChar)+import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)+import Foreign.Ptr (Ptr)++import Control.Monad.Trans.Cont (ContT(ContT), evalContT)+import Control.Monad.IO.Class (liftIO)++import Data.Complex (Complex)+import Data.Tuple.HT (mapSnd)+++leastSquares ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Shape.C nrhs, Class.Floating a) =>+   Full horiz Extent.Small height width a ->+   Full vert horiz height nrhs a ->+   Full vert horiz width nrhs a+leastSquares+   (Array shapeA@(MatrixShape.Full orderA extentA) a)+   (Array shapeB@(MatrixShape.Full orderB extentB) b) =++ case Extent.fuse (Extent.generalizeWide $ Extent.transpose extentA) extentB of+  Nothing -> error "leastSquares: height shapes mismatch"+  Just extent ->+      Array.unsafeCreate (MatrixShape.Full ColumnMajor extent) $ \xPtr -> do++   let widthA = Extent.width extentA+   let (height,widthB) = Extent.dimensions extentB+   let (m,n) = MatrixShape.dimensions shapeA+   let lda = m+   let nrhs = Shape.size widthB+   let ldb = Shape.size height+   let ldx = Shape.size widthA+   evalContT $ do+      mPtr <- Call.cint m+      nPtr <- Call.cint n+      nrhsPtr <- Call.cint nrhs+      (transPtr,aPtr) <- adjointA orderA (m*n) a+      ldaPtr <- Call.leadingDim lda+      bPtr <- ContT $ withForeignPtr b+      ldbPtr <- Call.leadingDim ldb+      let bSize = Shape.size shapeB+      btmpPtr <- Call.allocaArray bSize+      liftIO $ copyToColumnMajor orderB ldb nrhs bPtr btmpPtr+      liftIO $ withAutoWorkspaceInfo rankMsg "gels" $+         LapackGen.gels transPtr+            mPtr nPtr nrhsPtr aPtr ldaPtr btmpPtr ldbPtr+      liftIO $ copySubMatrix ldx nrhs ldb btmpPtr ldx xPtr++minimumNorm ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Shape.C nrhs, Class.Floating a) =>+   Full Extent.Small vert height width a ->+   Full vert horiz height nrhs a ->+   Full vert horiz width nrhs a+minimumNorm+   (Array shapeA@(MatrixShape.Full orderA extentA) a)+   (Array        (MatrixShape.Full orderB extentB) b) =++ case Extent.fuse (Extent.generalizeTall $ Extent.transpose extentA) extentB of+  Nothing -> error "minimumNorm: height shapes mismatch"+  Just extent ->+      Array.unsafeCreate (MatrixShape.Full ColumnMajor extent) $ \xPtr -> do++   let widthA = Extent.width extentA+   let (height,widthB) = Extent.dimensions extentB+   let (m,n) = MatrixShape.dimensions shapeA+   let lda = m+   let nrhs = Shape.size widthB+   let ldb = Shape.size height+   let ldx = Shape.size widthA+   evalContT $ do+      mPtr <- Call.cint m+      nPtr <- Call.cint n+      nrhsPtr <- Call.cint nrhs+      (transPtr,aPtr) <- adjointA orderA (m*n) a+      ldaPtr <- Call.leadingDim lda+      bPtr <- ContT $ withForeignPtr b+      ldxPtr <- Call.leadingDim ldx+      liftIO $ copyToSubColumnMajor orderB ldb nrhs bPtr ldx xPtr+      liftIO $ withAutoWorkspaceInfo rankMsg "gels" $+         LapackGen.gels transPtr+            mPtr nPtr nrhsPtr aPtr ldaPtr xPtr ldxPtr+++adjointA ::+   Class.Floating a =>+   Order -> Int -> ForeignPtr a -> ContT r IO (Ptr CChar, Ptr a)+adjointA order size a = do+   aPtr <- copyToTemp size a+   trans <-+      case order of+         RowMajor -> do+            sizePtr <- Call.cint size+            incPtr <- Call.cint 1+            liftIO $ lacgv sizePtr aPtr incPtr+            return $ HH.invChar a+         ColumnMajor -> return 'N'+   transPtr <- Call.char trans+   return (transPtr, aPtr)+++leastSquaresMinimumNormRCond ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Shape.C nrhs, Class.Floating a) =>+   RealOf a ->+   Full horiz vert height width a ->+   Full vert horiz height nrhs a ->+   (Int, Full vert horiz width nrhs a)+leastSquaresMinimumNormRCond rcond+      (Array (MatrixShape.Full orderA extentA) a)+      (Array (MatrixShape.Full orderB extentB) b) =+   case Extent.fuse (Extent.transpose extentA) extentB of+      Nothing -> error "leastSquaresMinimumNormRCond: height shapes mismatch"+      Just extent ->+         let widthA = Extent.width extentA+             (height,widthB) = Extent.dimensions extentB+             shapeX = MatrixShape.Full ColumnMajor extent+             m = Shape.size height+             n = Shape.size widthA+             nrhs = Shape.size widthB+         in  if m == 0+                then (0, Vector.zero shapeX)+                else+                  if nrhs == 0+                     then+                        (fst $ unsafePerformIO $+                         case Vector.zero height of+                           Array _ b1 ->+                              leastSquaresMinimumNormIO rcond+                                 (MatrixShape.general ColumnMajor widthA ())+                                 orderA a orderB b1 m n 1,+                         Vector.zero shapeX)+                     else+                        unsafePerformIO $+                        leastSquaresMinimumNormIO rcond shapeX+                           orderA a orderB b m n nrhs++leastSquaresMinimumNormIO ::+   (Shape.C sh, Class.Floating a) =>+   RealOf a -> sh ->+   Order -> ForeignPtr a ->+   Order -> ForeignPtr a ->+   Int -> Int -> Int -> IO (Int, Array sh a)+leastSquaresMinimumNormIO rcond shapeX orderA a orderB b m n nrhs =+   createHigherArray shapeX m n nrhs $ \(tmpPtr,ldtmp) -> do++   let aSize = m*n+   let lda = m+   evalContT $ do+      aPtr <- ContT $ withForeignPtr a+      atmpPtr <- Call.allocaArray aSize+      liftIO $ copyToColumnMajor orderA m n aPtr atmpPtr+      ldaPtr <- Call.leadingDim lda+      ldtmpPtr <- Call.leadingDim ldtmp+      bPtr <- ContT $ withForeignPtr b+      liftIO $ copyToSubColumnMajor orderB m nrhs bPtr ldtmp tmpPtr+      jpvtPtr <- Call.allocaArray n+      liftIO $ pokeArray jpvtPtr (replicate n 0)+      rankPtr <- Call.alloca+      gelsy m n nrhs atmpPtr ldaPtr tmpPtr ldtmpPtr jpvtPtr rcond rankPtr+      liftIO $ peekCInt rankPtr+++type GELSY_ r ar a =+   Int -> Int -> Int -> Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt ->+   Ptr CInt -> ar -> Ptr CInt -> ContT r IO ()++newtype GELSY r a = GELSY {getGELSY :: GELSY_ r (RealOf a) a}++gelsy :: (Class.Floating a) => GELSY_ r (RealOf a) a+gelsy =+   getGELSY $+   Class.switchFloating+      (GELSY gelsyReal)+      (GELSY gelsyReal)+      (GELSY gelsyComplex)+      (GELSY gelsyComplex)++gelsyReal :: (Class.Real a) => GELSY_ r a a+gelsyReal m n nrhs aPtr ldaPtr bPtr ldbPtr jpvtPtr rcond rankPtr = do+   mPtr <- Call.cint m+   nPtr <- Call.cint n+   nrhsPtr <- Call.cint nrhs+   rcondPtr <- Call.real rcond+   liftIO $ withAutoWorkspaceInfo errorCodeMsg "gelsy" $+      LapackReal.gelsy mPtr nPtr nrhsPtr+         aPtr ldaPtr bPtr ldbPtr jpvtPtr rcondPtr rankPtr++gelsyComplex :: (Class.Real a) => GELSY_ r a (Complex a)+gelsyComplex m n nrhs aPtr ldaPtr bPtr ldbPtr jpvtPtr rcond rankPtr = do+   mPtr <- Call.cint m+   nPtr <- Call.cint n+   nrhsPtr <- Call.cint nrhs+   rcondPtr <- Call.real rcond+   rworkPtr <- Call.allocaArray (2*n)+   liftIO $+      withAutoWorkspaceInfo errorCodeMsg "gelsy" $ \workPtr lworkPtr infoPtr ->+      LapackComplex.gelsy mPtr nPtr nrhsPtr+         aPtr ldaPtr bPtr ldbPtr jpvtPtr rcondPtr rankPtr+         workPtr lworkPtr rworkPtr infoPtr+++pseudoInverseRCond ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+   RealOf a ->+   Full vert horiz height width a ->+   (Int, Full horiz vert width height a)+pseudoInverseRCond rcond a =+   case Basic.caseTallWide a of+      Left _ ->+         mapSnd Basic.transpose $+         leastSquaresMinimumNormRCond rcond (Basic.transpose a) $+         Square.toFull $ Square.identity $+         MatrixShape.fullWidth $ Array.shape a+      Right _ ->+         leastSquaresMinimumNormRCond rcond a $+         Square.toFull $ Square.identity $+         MatrixShape.fullHeight $ Array.shape a+++determinantAbsolute ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>+   Full vert horiz height width a -> RealOf a+determinantAbsolute =+   absolute .+   either (HH.determinantR . HH.fromMatrix) (const zero) .+   Basic.caseTallWide+++complement ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   Tall height width a -> Tall height ShapeInt a+complement a =+   Basic.dropColumns (Shape.size $ MatrixShape.fullWidth $ Array.shape a) $+   Basic.mapWidth (shapeInt . Shape.size) $ Square.toFull $+   HH.extractQ $ HH.fromMatrix a
src/Numeric/LAPACK/Orthogonal/Private.hs view
@@ -1,25 +1,33 @@ {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE EmptyDataDecls #-} module Numeric.LAPACK.Orthogonal.Private where +import qualified Numeric.LAPACK.Matrix.Divide as Divide+import qualified Numeric.LAPACK.Matrix.Multiply as Multiply+import qualified Numeric.LAPACK.Matrix.Type as Type+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Basic as Basic import qualified Numeric.LAPACK.Matrix.Private as Matrix import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape import qualified Numeric.LAPACK.Matrix.Extent.Private as ExtentPriv import qualified Numeric.LAPACK.Matrix.Extent as Extent import qualified Numeric.LAPACK.Split as Split+import qualified Numeric.LAPACK.Shape as ExtShape+import Numeric.LAPACK.Output ((/+/))+import Numeric.LAPACK.Matrix.Plain.Format (formatArray)+import Numeric.LAPACK.Matrix.Type (FormatMatrix(formatMatrix)) import Numeric.LAPACK.Matrix.Triangular.Basic (Upper) import Numeric.LAPACK.Matrix.Shape.Private          (Order(RowMajor, ColumnMajor), sideSwapFromOrder) import Numeric.LAPACK.Matrix.Extent.Private (Extent)-import Numeric.LAPACK.Matrix.Private-         (Full, ZeroInt, zeroInt,-          Transposition(NonTransposed, Transposed),-          Conjugation(NonConjugated, Conjugated),-          Inversion(NonInverted, Inverted), flipInversion)+import Numeric.LAPACK.Matrix.Modifier+         (Transposition(NonTransposed, Transposed),+          Conjugation(NonConjugated, Conjugated))+import Numeric.LAPACK.Matrix.Private (Full) import Numeric.LAPACK.Vector (Vector)-import Numeric.LAPACK.Format (Format(format)) import Numeric.LAPACK.Scalar (RealOf, zero, isZero, absolute, conjugate) import Numeric.LAPACK.Private-         (fill, copySubMatrix, copyBlock, conjugateToTemp,+         (fill, copySubMatrix, copyBlock, conjugateToTemp, caseRealComplexFunc,           withAutoWorkspaceInfo, errorCodeMsg)  import qualified Numeric.LAPACK.FFI.Generic as LapackGen@@ -37,22 +45,27 @@ import Control.Monad.Trans.Cont (ContT(ContT), evalContT) import Control.Monad.IO.Class (liftIO) import Control.Monad (when)-import Control.Applicative (Const(Const,getConst), liftA3)+import Control.Applicative (liftA2)  import qualified Data.List as List+import Data.Monoid ((<>))  -data Householder vert horiz height width a =+data Hh vert horiz height width++data instance Type.Matrix (Hh vert horiz height width) a =    Householder {-      tau_ :: Vector ZeroInt a,+      tau_ :: Vector (ExtShape.Min height width) a,       split_ ::          Array             (MatrixShape.Split MatrixShape.Reflector vert horiz height width) a    } deriving (Show) -type General = Householder Extent.Big Extent.Big-type Tall = Householder Extent.Big Extent.Small-type Wide = Householder Extent.Small Extent.Big+type Householder vert horiz height width =+         Type.Matrix (Hh vert horiz height width)+type General height width = Householder Extent.Big Extent.Big height width+type Tall height width = Householder Extent.Big Extent.Small height width+type Wide height width = Householder Extent.Small Extent.Big height width type Square sh = Householder Extent.Small Extent.Small sh sh  @@ -82,10 +95,12 @@   instance-   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,-    Class.Floating a) =>-      Format (Householder vert horiz height width a) where-   format fmt (Householder tau m) = format fmt (tau, m)+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>+      FormatMatrix (Hh vert horiz height width) where+   formatMatrix fmt (Householder tau m) =+      formatArray fmt (Array.mapShape (Shape.ZeroBased . Shape.size) tau)+      /+/+      formatArray fmt m  fromMatrix ::    (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,@@ -93,13 +108,14 @@    Full vert horiz height width a ->    Householder vert horiz height width a fromMatrix (Array shape@(MatrixShape.Full order extent) a) =-   let (m,n) = MatrixShape.dimensions shape-   in uncurry Householder $-      Array.unsafeCreateWithSizeAndResult (zeroInt $ min m n) $ \_ tauPtr ->-      ArrayIO.unsafeCreate-         (MatrixShape.Split MatrixShape.Reflector order extent) $ \qrPtr ->+   uncurry Householder $+   Array.unsafeCreateWithSizeAndResult+      (uncurry ExtShape.Min $ Extent.dimensions extent) $ \_ tauPtr ->+   ArrayIO.unsafeCreate+      (MatrixShape.Split MatrixShape.Reflector order extent) $ \qrPtr ->     evalContT $ do+      let (m,n) = MatrixShape.dimensions shape       mPtr <- Call.cint m       nPtr <- Call.cint n       aPtr <- ContT $ withForeignPtr a@@ -177,13 +193,6 @@ leastSquares qr =    tallSolveR NonTransposed NonConjugated qr . tallMultiplyQAdjoint qr -{- |-@-HH.minimumNorm (HH.fromMatrix a) b-==-Ortho.minimumNorm (adjoint a) b-@--} minimumNorm ::    (Extent.C vert, Extent.C horiz,     Shape.C height, Eq height, Shape.C width, Eq width, Shape.C nrhs,@@ -193,7 +202,6 @@    Full vert horiz width nrhs a minimumNorm qr = tallMultiplyQ qr . tallSolveR Transposed Conjugated qr --- cf. Matrix.takeRows takeRows ::    (Extent.C vert, Extent.C horiz,     Eq fuse, Shape.C fuse, Shape.C height, Shape.C width, Class.Floating a) =>@@ -204,16 +212,8 @@    case Extent.fuse (ExtentPriv.generalizeWide extentA) extentB of       Nothing -> error "Householder.takeRows: heights mismatch"       Just extentC ->-         Array.unsafeCreateWithSize (MatrixShape.Full order extentC) $-            \blockSize cPtr ->-         withForeignPtr b $ \bPtr ->-         case order of-            RowMajor -> copyBlock blockSize bPtr cPtr-            ColumnMajor ->-               let n  = Shape.size $ Extent.width  extentB-                   mb = Shape.size $ Extent.height extentB-                   mc = Shape.size $ Extent.height extentC-               in  copySubMatrix mc n mb bPtr mc cPtr+         Basic.takeSub+            (Extent.height extentB) 0 b (MatrixShape.Full order extentC)  addRows ::    (Extent.C vert, Extent.C horiz,@@ -271,7 +271,7 @@    (Extent.C vert, Extent.C horiz,     Shape.C height, Shape.C width, Shape.C widthQR,     Class.Floating a) =>-   Vector ZeroInt a -> widthQR ->+   Vector (ExtShape.Min height widthQR) a -> widthQR ->    Order -> Extent vert horiz height width -> ForeignPtr a ->    Full vert horiz height width a extractQAux (Array widthTau tau) widthQR order extent qr =@@ -309,7 +309,8 @@    Householder vert Extent.Small height fuse a ->    Full vert horiz fuse width a ->    Full vert horiz height width a-tallMultiplyQ qr = multiplyQ NonInverted qr . addRows (extent_ qr)+tallMultiplyQ qr =+   multiplyQ NonTransposed NonConjugated qr . addRows (extent_ qr)  tallMultiplyQAdjoint ::    (Extent.C vert, Extent.C horiz,@@ -318,18 +319,19 @@    Full vert horiz fuse width a ->    Full vert horiz height width a tallMultiplyQAdjoint qr =-   takeRows (Extent.transpose $ extent_ qr) . multiplyQ Inverted qr+   takeRows (Extent.transpose $ extent_ qr) .+   multiplyQ Transposed Conjugated qr   multiplyQ ::    (Extent.C vertA, Extent.C horizA, Shape.C widthA,     Extent.C vertB, Extent.C horizB, Shape.C widthB,     Shape.C height, Eq height, Class.Floating a) =>-   Inversion ->+   Transposition -> Conjugation ->    Householder vertA horizA height widthA a ->    Full vertB horizB height widthB a ->    Full vertB horizB height widthB a-multiplyQ inverted+multiplyQ transposed conjugated    (Householder       (Array widthTau tau)       (Array shapeA@(MatrixShape.Split _ orderA extentA) qr))@@ -351,17 +353,21 @@       nPtr <- Call.cint n       let k = Shape.size widthTau       kPtr <- Call.cint k-      (transPtr,qrPtr,tauPtr) <--         if orderA==orderB-           then-               liftA3 (,,)-                  (Call.char $ transposeFromInversion qr inverted)+      transPtr <-+         Call.char $ adjointFromTranspose qr $+         transposed <> if orderA==orderB then NonTransposed else Transposed+      (qrPtr,tauPtr) <-+         if (orderA==orderB)+            ==+            (transposed==NonTransposed && conjugated==NonConjugated+             ||+             transposed==Transposed && conjugated==Conjugated)+            then+               liftA2 (,)                   (ContT $ withForeignPtr qr)                   (ContT $ withForeignPtr tau)-           else-               liftA3 (,,)-                  (Call.char $-                   transposeFromInversion qr $ flipInversion inverted)+            else+               liftA2 (,)                   (conjugateToTemp (Shape.size shapeA) qr)                   (conjugateToTemp k tau)       bPtr <- ContT $ withForeignPtr b@@ -381,19 +387,12 @@                LapackGen.unmlq sidePtr transPtr                   mPtr nPtr kPtr qrPtr ldaPtr tauPtr cPtr ldcPtr -transposeFromInversion :: (Class.Floating a) => f a -> Inversion -> Char-transposeFromInversion qr Inverted = invChar qr-transposeFromInversion _ NonInverted = 'N'+adjointFromTranspose :: (Class.Floating a) => f a -> Transposition -> Char+adjointFromTranspose qr Transposed = invChar qr+adjointFromTranspose _ NonTransposed = 'N'  invChar :: (Class.Floating a) => f a -> Char-invChar f = getConst $ asFuncTypeOf f inverseChar--asFuncTypeOf :: f a -> g a -> g a-asFuncTypeOf = const id--inverseChar :: (Class.Floating a) => Const Char a-inverseChar =-   Class.switchFloating (Const 'T') (Const 'T') (Const 'C') (Const 'C')+invChar f = caseRealComplexFunc f 'T' 'C'   extractR ::@@ -425,3 +424,59 @@    Full vert horiz width nrhs a -> Full vert horiz width nrhs a tallSolveR transposed conjugated =    Split.tallSolveR transposed conjugated . split_+++instance+   (Extent.C vert, Extent.C horiz) =>+      Type.Box (Hh vert horiz height width) where+   type HeightOf (Hh vert horiz height width) = height+   type WidthOf (Hh vert horiz height width) = width+   height = MatrixShape.splitHeight . Array.shape . split_+   width = MatrixShape.splitWidth . Array.shape . split_++instance+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Eq width) =>+      Multiply.MultiplyVector (Hh vert horiz height width) where+   matrixVector qr x =+      Basic.unliftColumn MatrixShape.ColumnMajor+         (multiplyQ NonTransposed NonConjugated qr) $+      Basic.multiplyVector (extractR qr) x+   vectorMatrix x qr =+      Basic.multiplyVector (Basic.transpose $ extractR qr) $+      Basic.unliftColumn MatrixShape.ColumnMajor+         (multiplyQ Transposed NonConjugated qr) x++instance+   (vert ~ Extent.Small, horiz ~ Extent.Small,+    Shape.C height, height ~ width) =>+      Multiply.MultiplySquare (Hh vert horiz height width) where++   squareFull qr =+      ArrMatrix.lift1 $+         multiplyQ NonTransposed NonConjugated qr .+         tallMultiplyR NonTransposed qr++   fullSquare = flip $ \qr ->+      ArrMatrix.lift1 $+         Basic.transpose .+         tallMultiplyR Transposed qr .+         multiplyQ Transposed NonConjugated qr .+         Basic.transpose++instance+   (vert ~ Extent.Small, horiz ~ Extent.Small,+    Shape.C height, height ~ width) =>+      Divide.Determinant (Hh vert horiz height width) where+   determinant = determinant++instance+   (vert ~ Extent.Small, horiz ~ Extent.Small,+    Shape.C height, height ~ width) =>+      Divide.Solve (Hh vert horiz height width) where+   solveRight = ArrMatrix.lift1 . leastSquares . mapExtent Extent.generalizeWide+   solveLeft =+      flip $ \a -> ArrMatrix.lift1 $+         Basic.adjoint .+         minimumNorm (mapExtent Extent.generalizeWide a) .+         Basic.adjoint
+ src/Numeric/LAPACK/Output.hs view
@@ -0,0 +1,107 @@+module Numeric.LAPACK.Output (+   Output+      (text, above, beside, formatRow, formatColumn,+       formatAligned, formatSeparateTriangle),++   (/+/),+   (<+>),+   hyper,+   ) where++import qualified Hyper+import qualified Text.Blaze.Html4.Transitional as Html+import qualified Text.Blaze.Html4.Transitional.Attributes as Attr+import qualified Text.Blaze.Html.Renderer.Text as RenderHtml+import Text.Blaze.Html ((!))++import qualified Text.PrettyPrint.Boxes as TextBox+import Text.PrettyPrint.Boxes (Box)++import qualified Data.Text.Lazy as TextLazy+import qualified Data.Foldable as Fold+import qualified Data.List.HT as ListHT+import qualified Data.List as List+import Data.Foldable (Foldable)+import Data.String (fromString)+import Data.Maybe.HT (toMaybe)+import Data.Maybe (fromMaybe)+++class Output out where+   text :: String -> out+   above :: out -> out -> out+   beside :: out -> out -> out+   formatRow, formatColumn :: [out] -> out+   formatAligned :: (Foldable f) => [[f out]] -> out+   formatSeparateTriangle :: (Foldable f) => [[f out]] -> out++(/+/) :: (Output out) => out -> out -> out+(/+/) = above++(<+>) :: (Output out) => out -> out -> out+(<+>) = beside+++newtype Html = Html {unHtml :: Html.Html}++hyper :: Html -> Hyper.Graphic+hyper = Hyper.html . TextLazy.toStrict . RenderHtml.renderHtml . unHtml++instance Output Html where+   text = Html . Html.toHtml+   above (Html a) (Html b) = Html $ a >> Html.br >> b+   beside (Html a) (Html b) = Html $ a >> Html.string " " >> b+   formatRow = Html . Html.table . Html.tr . mapM_ (td . unHtml)+   formatColumn = Html . Html.table . mapM_ (Html.tr . td . unHtml)+   formatAligned =+      Html . Html.table .+      mapM_ (Html.tr . mapM_ (td . unHtml) . concatMap Fold.toList)+   formatSeparateTriangle =+      Html . Html.table .+      mapM_ (Html.tr . mapM_ td . concat) .+      zipWith+         (zipWith $ \it -> map (it . unHtml) . Fold.toList)+         (iterate (Html.i:) (repeat id))++td :: Html.Html -> Html.Html+td = Html.td ! Attr.align (fromString "right")+++instance Output Box where+   text = TextBox.text+   above = (TextBox./+/)+   beside = (TextBox.<+>)+   formatRow = TextBox.hsep 1 TextBox.right+   formatColumn = TextBox.vsep 1 TextBox.right+   formatAligned = alignSeparated . map (concatMap (attachSeparators Space))+   formatSeparateTriangle =+      alignSeparated . map concat .+      zipWith+         (zipWith attachSeparators)+         (ListHT.outerProduct+            (\row col -> if row==col then Bar else Space)+            [(0::Int)..] [0..])+++data Separator = Empty | Space | Bar+   deriving (Eq, Ord, Show)++alignSeparated :: [[(Separator, Box)]] -> Box+alignSeparated =+   TextBox.hcat TextBox.top .+   map (TextBox.vcat TextBox.right) .+   concatMap+      ((\(seps,column) -> [map (TextBox.text . formatSeparator) seps, column])+         . unzip) .+   List.unfoldr (viewLAll (Empty, TextBox.text ""))++viewLAll :: a -> [[a]] -> Maybe ([a], [[a]])+viewLAll x0 xs =+   toMaybe (any (not.null) xs)+      (unzip $ map (fromMaybe (x0,[]) . ListHT.viewL) xs)++formatSeparator :: Separator -> String+formatSeparator sep = case sep of Empty -> ""; Space -> " "; Bar -> "|"++attachSeparators :: (Foldable f) => Separator -> f str -> [(Separator, str)]+attachSeparators sep = zip (sep:repeat Empty) . Fold.toList
src/Numeric/LAPACK/Permutation.hs view
@@ -1,15 +1,40 @@ module Numeric.LAPACK.Permutation (-   Permutation,-   Matrix.Inversion(..),-   fromPivots,-   toPivots,+   Plain.Permutation,+   Plain.Shape(Shape), Plain.Element(Element),+   Plain.size,+   Plain.identity,+   Mod.Inversion(NonInverted,Inverted),+   Plain.fromPivots,+   Plain.toPivots,    toMatrix,-   determinant,-   numberFromSign,-   transpose,-   multiply,+   Plain.Sign(Positive,Negative),+   Plain.determinant,+   Plain.numberFromSign,+   Plain.transpose,+   Plain.inversionFromTransposition,+   Plain.multiply,    apply,    ) where -import Numeric.LAPACK.Permutation.Private-import qualified Numeric.LAPACK.Matrix.Private as Matrix+import qualified Numeric.LAPACK.Permutation.Private as Plain+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Modifier as Mod+import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import Numeric.LAPACK.Permutation.Private (Permutation)+import Numeric.LAPACK.Matrix.Array (Full, Square)++import qualified Numeric.Netlib.Class as Class++import qualified Data.Array.Comfort.Shape as Shape+++toMatrix :: (Shape.C sh, Class.Floating a) => Permutation sh -> Square sh a+toMatrix = ArrMatrix.lift0 . Plain.toMatrix++apply ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Class.Floating a) =>+   Mod.Inversion -> Permutation height ->+   Full vert horiz height width a ->+   Full vert horiz height width a+apply inverted = ArrMatrix.lift1 . Plain.apply inverted
src/Numeric/LAPACK/Permutation/Private.hs view
@@ -1,108 +1,134 @@+{-# LANGUAGE TypeFamilies #-} module Numeric.LAPACK.Permutation.Private where  import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent-import qualified Numeric.LAPACK.Split as Split+import qualified Numeric.LAPACK.Shape as ExtShape+import qualified Numeric.LAPACK.Output as Output+import Numeric.LAPACK.Output (Output, formatAligned) import Numeric.LAPACK.Matrix.Shape.Private (Order(RowMajor, ColumnMajor))-import Numeric.LAPACK.Matrix.Private-         (Full, Square, ZeroInt, Inversion(NonInverted, Inverted))+import Numeric.LAPACK.Matrix.Modifier+         (Transposition(NonTransposed,Transposed),+          Inversion(NonInverted,Inverted))+import Numeric.LAPACK.Matrix.Private (Full, Square, shapeInt) import Numeric.LAPACK.Vector (Vector)-import Numeric.LAPACK.Format (Format(format)) import Numeric.LAPACK.Scalar (zero, one)-import Numeric.LAPACK.Private (fill, pointerSeq, copyBlock, copyToTemp)+import Numeric.LAPACK.Private (copyBlock, copyToTemp)  import qualified Numeric.LAPACK.FFI.Generic as LapackGen import qualified Numeric.Netlib.Utility as Call import qualified Numeric.Netlib.Class as Class +import qualified Data.Array.Comfort.Storable.Mutable.Unchecked as MutArray import qualified Data.Array.Comfort.Storable.Unchecked as Array+import qualified Data.Array.Comfort.Storable as CheckedArray import qualified Data.Array.Comfort.Shape as Shape-import Data.Array.Comfort.Storable.Unchecked (Array(Array))--import qualified Text.PrettyPrint.Boxes as TextBox+import Data.Array.Comfort.Storable.Unchecked (Array(Array), (!)) -import qualified Foreign.Marshal.Array.Guarded as ForeignArray-import Foreign.Marshal.Array (advancePtr, copyArray) import Foreign.C.Types (CInt) import Foreign.ForeignPtr (withForeignPtr)-import Foreign.Ptr (Ptr)-import Foreign.Storable (Storable, poke, peek, pokeElemOff, peekElemOff)+import Foreign.Ptr (Ptr, castPtr)+import Foreign.Storable (Storable, sizeOf, alignment, poke, peek)  import Control.Monad.Trans.Cont (ContT(ContT), evalContT) import Control.Monad.IO.Class (liftIO)+import Control.Monad.ST (ST, runST) import Control.Monad (when, forM_)-import Control.Applicative ((<$>))+import Control.Applicative (liftA2, (<$>)) -import Data.Bool.HT (if')+import qualified Data.Tuple.HT as Tuple+import Data.Function.HT (powerAssociative) import Data.Monoid (Monoid, mempty, mappend) import Data.Semigroup (Semigroup, (<>)) +import Prelude hiding (odd) -newtype Permutation sh = Permutation (Vector sh CInt)++newtype Permutation sh = Permutation (Vector (Shape sh) (Element sh))    deriving (Show) -instance (Shape.C sh) => Format (Permutation sh) where-   format _fmt (Permutation perm) =-      let n = Shape.size $ Array.shape perm-      in TextBox.vcat TextBox.top $-         map (TextBox.hsep 1 TextBox.right . map TextBox.char) $-         map (\k -> (replicate (k-1) '.' ++ '1' : replicate (n-k) '.')) $-         map fromIntegral $ Array.toList perm+format :: (Shape.C sh, Output out) => Permutation sh -> out+format (Permutation perm) =+   let n = Shape.size $ Array.shape perm+   in formatAligned $+      map (map ((:[]) . Output.text . (:""))) $+      map (\k -> (replicate (k-1) '.' ++ '1' : replicate (n-k) '.')) $+      map (fromIntegral . deconsElement) $ Array.toList perm  +size :: Permutation sh -> sh+size (Permutation (Array (Shape shape) _perm)) = shape++identity :: (Shape.C sh) => sh -> Permutation sh+identity shape = Permutation $ CheckedArray.sample (Shape shape) id++fromPivots ::+   (Shape.C sh) =>+   Inversion -> Vector (Shape sh) (Element sh) -> Permutation sh+fromPivots inverted ipiv =+   fromPivotsGen inverted (Array.shape ipiv) ipiv+ {- We could use laswp if it would be available for CInt elements. -}-{- |-The pivot array must be at most as long as @Shape.size sh@.--}-fromPivots :: (Shape.C sh) =>-   Inversion -> sh -> Vector ZeroInt CInt -> Permutation sh-fromPivots inverted sh (Array (Shape.ZeroBased numIPiv) ipiv) =+fromTruncatedPivots ::+   (Shape.C sh, Shape.C sh1) =>+   Inversion ->+   Vector (ExtShape.Min sh1 (Shape sh)) (Element sh) -> Permutation sh+fromTruncatedPivots inverted ipiv =+   fromPivotsGen inverted (ExtShape.minShape1 $ Array.shape ipiv) ipiv++fromPivotsGen ::+   (Shape.C sh, Shape.Indexed small, Shape.Index small ~ Element sh) =>+   Inversion -> Shape sh -> Vector small (Element sh) -> Permutation sh+fromPivotsGen inverted sh ipiv =    Permutation $-   if' (numIPiv > Shape.size sh)-      (error "Permutation.fromPivots: too many pivots") $-   Array.unsafeCreateWithSize sh $ \n permPtr ->-   withForeignPtr ipiv $ \ipivPtr -> do-      sequence_ $ take n $ zipWith poke (pointerSeq 1 permPtr) (iterate (1+) 1)-      let is =-            case inverted of-               Inverted -> tail $ iterate (subtract 1) numIPiv-               NonInverted -> iterate (1+) 0-      forM_ (take numIPiv is) $ \i ->-         swapElem permPtr i =<< peek1 ipivPtr i+   runST (do+      perm <- initMutable sh $ \perm i -> MutArray.write perm i i+      forM_ (indices inverted $ Array.shape ipiv) $ \i -> swap perm i (ipiv!i)+      MutArray.unsafeFreeze perm) -swapElem :: (Storable a) => Ptr a -> Int -> Int -> IO ()-swapElem ptr i j = swap (advancePtr ptr i) (advancePtr ptr j)+swap ::+   (Shape.Indexed sh, Shape.Index sh ~ ix, Storable a) =>+   MutArray.Array (ST s) sh a -> ix -> ix -> ST s ()+swap arr i j = do+   a <- MutArray.read arr i+   MutArray.write arr i =<< MutArray.read arr j+   MutArray.write arr j a -swap :: (Storable a) => Ptr a -> Ptr a -> IO ()-swap ptr0 ptr1 = do-   a <- peek ptr0-   poke ptr0 =<< peek ptr1-   poke ptr1 a+indices ::+   (Shape.C sh, Shape.Indexed small, Shape.Index small ~ Element sh) =>+   Inversion -> small -> [Element sh]+indices inverted sh =+   let numIPiv = Shape.size sh+   in take numIPiv $ map Element $+      case inverted of+         Inverted -> iterate (subtract 1) (fromIntegral numIPiv)+         NonInverted -> iterate (1+) 1  -toPivots :: (Shape.C sh) => Inversion -> Permutation sh -> Vector sh CInt-toPivots inverted (Permutation (Array sh perm)) =-   Array.unsafeCreateWithSize sh $ \n invPtr ->-   withForeignPtr perm $ \perm0Ptr ->-   ForeignArray.alloca n $ \permPtr -> do-      case inverted of-         Inverted -> do-            copyArray permPtr perm0Ptr n-            transposeIO n permPtr invPtr-         NonInverted -> do-            copyArray invPtr perm0Ptr n-            transposeIO n perm0Ptr permPtr-      forM_ (take n $ iterate (1+) 0) $ \i -> do-         j <- peek1 invPtr i-         k <- peek1 permPtr i-         poke1 permPtr j k-         poke1 invPtr k j+toPivots ::+   (Shape.C sh) => Inversion -> Permutation sh -> Vector sh (Element sh)+toPivots inverted (Permutation a) =+   let sh = Array.shape a+   in Array.reshape (deconsShape sh) $+      runST (do+         (inv,perm) <-+            (case inverted of Inverted -> Tuple.swap; NonInverted -> id)+            <$>+            liftA2 (,)+               (MutArray.thaw a)+               (transposeToMutable a)+         forM_ (Shape.indices sh) $ \i -> do+            j <- MutArray.read inv i+            k <- MutArray.read perm i+            MutArray.write perm j k+            MutArray.write inv k j+         MutArray.unsafeFreeze inv)  -data Sign = Negative | Positive-   deriving (Eq, Show)+data Sign = Positive | Negative+   deriving (Eq, Show, Enum, Bounded)  instance Semigroup Sign where    x<>y = if x==y then Positive else Negative@@ -117,8 +143,11 @@ determinant :: (Shape.C sh) => Permutation sh -> Sign determinant =    (\oddp -> if oddp then Negative else Positive) .-   Split.oddPermutation . Array.toList . toPivots NonInverted+   odd . map deconsElement . Array.toList . toPivots NonInverted +{- |+> numberFromSign s == (-1)^fromEnum s+-} numberFromSign :: (Class.Floating a) => Sign -> a numberFromSign s =    case s of@@ -126,61 +155,79 @@       Positive -> 1  +condNegate :: (Class.Floating a) => [CInt] -> a -> a+condNegate ipiv = if odd ipiv then negate else id++odd :: [CInt] -> Bool+odd = not . null . dropEven . filter id . zipWith (/=) [1..]++dropEven :: [a] -> [a]+dropEven (_:_:xs) = dropEven xs+dropEven xs = xs++ transpose :: (Shape.C sh) => Permutation sh -> Permutation sh-transpose (Permutation (Array shape perm)) =-   Permutation $-   Array.unsafeCreateWithSize shape $ \n dstPtr ->-   withForeignPtr perm $ \srcPtr ->-   transposeIO n srcPtr dstPtr+transpose (Permutation perm) =+   Permutation $ runST (MutArray.unsafeFreeze =<< transposeToMutable perm) -transposeIO :: Int -> Ptr CInt -> Ptr CInt -> IO ()-transposeIO n srcPtr dstPtr =-   forM_ (take n $ iterate (1+) 0) $ \i -> do-      j <- peek1 srcPtr i-      poke1 dstPtr j i+transposeToMutable ::+   (Shape.Indexed sh, Shape.Index sh ~ ix, Storable ix) =>+   Array sh ix -> ST s (MutArray.Array (ST s) sh ix)+transposeToMutable perm =+   initMutable (Array.shape perm) $ \inv i -> MutArray.write inv (perm!i) i +inversionFromTransposition :: Transposition -> Inversion+inversionFromTransposition trans =+   case trans of+      NonTransposed -> NonInverted+      Transposed -> Inverted + multiply :: (Shape.C sh, Eq sh) =>    Permutation sh -> Permutation sh -> Permutation sh-multiply (Permutation (Array shape permA)) (Permutation (Array shapeB permB)) =-   if shape /= shapeB+multiply a b =+   if size a /= size b       then error "Permutation.multiply: sizes mismatch"-      else-         Permutation $-         Array.unsafeCreateWithSize shape $ \n cPtr ->-         withForeignPtr permA $ \aPtr ->-         withForeignPtr permB $ \bPtr ->-         forM_ (take n $ iterate (1+) 0) $ \i ->-            poke1 cPtr i =<< peek1 bPtr =<< peek1 aPtr i+      else multiplyUnchecked a b +square :: (Shape.C sh) => Permutation sh -> Permutation sh+square p = multiplyUnchecked p p -toMatrix :: (Shape.C sh, Class.Floating a) => Permutation sh -> Square sh a-toMatrix (Permutation (Array shape perm)) =-   Array.unsafeCreate (MatrixShape.square RowMajor shape) $ \aPtr ->-   withForeignPtr perm $ \permPtr -> do-      let n = Shape.size shape-      fill zero (n*n) aPtr-      forM_ (take n $ zip (iterate (1+) 0) (pointerSeq n aPtr)) $-         \(k,rowPtr) -> do-            i <- peek1 permPtr k-            pokeElemOff rowPtr i one+power :: (Shape.C sh) => Integer -> Permutation sh -> Permutation sh+power n p = powerAssociative multiplyUnchecked (identity $ size p) p n +multiplyUnchecked :: (Shape.C sh) =>+   Permutation sh -> Permutation sh -> Permutation sh+multiplyUnchecked (Permutation a) (Permutation b) =+   Permutation $ CheckedArray.sample (Array.shape a) $ \i -> b!(a!i) -peek1 :: Ptr CInt -> Int -> IO Int-peek1 ptr i = subtract 1 . fromIntegral <$> peekElemOff ptr i -poke1 :: Ptr CInt -> Int -> Int -> IO ()-poke1 ptr i j = pokeElemOff ptr i (fromIntegral (j+1))+takeDiagonal ::+   (Shape.C sh, Class.Floating a) => Permutation sh -> Vector sh a+takeDiagonal (Permutation a) =+   Array.mapShape deconsShape $+   CheckedArray.sample (Array.shape a) $ \i -> if a!i == i then 1 else 0  +toMatrix :: (Shape.C sh, Class.Floating a) => Permutation sh -> Square sh a+toMatrix (Permutation perm) =+   let shape = Array.shape perm+   in Array.reshape (MatrixShape.square RowMajor $ deconsShape shape) $+      runST (do+         a <- MutArray.new (shape,shape) zero+         forM_ (Shape.indices $ Array.shape perm) $ \k ->+            MutArray.write a (k, perm!k) one+         MutArray.unsafeFreeze a)++ apply ::    (Extent.C vert, Extent.C horiz,     Shape.C height, Eq height, Shape.C width, Class.Floating a) =>-   Bool -> Permutation height ->+   Inversion -> Permutation height ->    Full vert horiz height width a ->    Full vert horiz height width a apply inverted-      (Permutation (Array shapeP perm))+      (Permutation (Array (Shape shapeP) perm))       (Array shape@(MatrixShape.Full order extent) a) =     Array.unsafeCreateWithSize shape $ \blockSize bPtr -> do@@ -190,10 +237,10 @@    let m = Shape.size height    let n = Shape.size width    evalContT $ do-      fwdPtr <- Call.bool $ not inverted+      fwdPtr <- Call.bool $ inverted==NonInverted       mPtr <- Call.cint m       nPtr <- Call.cint n-      kPtr <- copyToTemp m perm+      kPtr <- deconsElementPtr <$> copyToTemp m perm       aPtr <- ContT $ withForeignPtr a       liftIO $ do          copyBlock blockSize aPtr bPtr@@ -201,3 +248,54 @@             case order of                RowMajor -> LapackGen.lapmt fwdPtr nPtr mPtr bPtr nPtr kPtr                ColumnMajor -> LapackGen.lapmr fwdPtr mPtr nPtr bPtr mPtr kPtr+++initMutable ::+   (Shape.Indexed sh, Shape.Index sh ~ ix, Storable a) =>+   sh -> (MutArray.Array (ST s) sh a -> ix -> ST s ()) ->+   ST s (MutArray.Array (ST s) sh a)+initMutable sh f = do+   arr <- MutArray.unsafeCreate sh (\ _ -> return ())+   mapM_ (f arr) $ Shape.indices sh+   return arr++++-- cf. Shape.Deferred+newtype Shape sh = Shape {deconsShape :: sh}+   deriving (Eq, Show)++newtype Element sh = Element {deconsElement :: CInt}+   deriving (Eq, Show)++deconsElementPtr :: Ptr (Element sh) -> Ptr CInt+deconsElementPtr = castPtr++instance (Shape.C sh) => Shape.C (Shape sh) where+   size (Shape sh) = Shape.size sh+   uncheckedSize (Shape sh) = Shape.uncheckedSize sh++instance (Shape.C sh) => Shape.Indexed (Shape sh) where+   type Index (Shape sh) = Element sh+   indices (Shape sh) = map Element $ take (Shape.size sh) [1 ..]+   offset (Shape sh) (Element k) =+      Shape.offset (shapeInt $ Shape.size sh) (fromIntegral k - 1)+   uncheckedOffset _ (Element k) = fromIntegral k - 1+   inBounds (Shape sh) (Element k) =+      Shape.inBounds (shapeInt $ Shape.size sh) (fromIntegral k - 1)++instance (Shape.C sh) => Shape.InvIndexed (Shape sh) where+   indexFromOffset (Shape sh) k =+      Element $+         1 + fromIntegral (Shape.indexFromOffset (shapeInt $ Shape.size sh) k)+   uncheckedIndexFromOffset _sh = Element . (1+) . fromIntegral++instance Storable (Element sh) where+   {-# INLINE sizeOf #-}+   {-# INLINE alignment #-}+   {-# INLINE peek #-}+   {-# INLINE poke #-}+   sizeOf (Element k) = sizeOf k+   alignment (Element k) = alignment k+   poke p (Element k) = poke (deconsElementPtr p) k+   peek p = fmap Element $ peek (deconsElementPtr p)
src/Numeric/LAPACK/Private.hs view
@@ -11,23 +11,25 @@ import qualified Numeric.BLAS.FFI.Generic as BlasGen import qualified Numeric.Netlib.Utility as Call import qualified Numeric.Netlib.Class as Class-import Numeric.LAPACK.Scalar (zero, one, isZero)+import Numeric.LAPACK.Matrix.Modifier (Conjugation(NonConjugated, Conjugated))+import Numeric.LAPACK.Scalar (RealOf, zero, one, isZero) +import qualified Foreign.Marshal.Array.Guarded as ForeignArray import qualified Foreign.Marshal.Utils as Marshal import qualified Foreign.C.String as CStr import Foreign.Marshal.Array (copyArray, advancePtr) import Foreign.Marshal.Alloc (alloca) import Foreign.C.Types (CChar, CInt) import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)-import Foreign.Ptr (Ptr)-import Foreign.Storable (Storable, poke, peek)+import Foreign.Ptr (Ptr, castPtr)+import Foreign.Storable (Storable, poke, peek, pokeElemOff, peekElemOff)  import Text.Printf (printf)  import Control.Monad.Trans.Cont (ContT(ContT), evalContT, runContT) import Control.Monad.IO.Class (liftIO)-import Control.Monad (when, foldM)-import Control.Applicative ((<$>))+import Control.Monad (when)+import Control.Applicative (Const(Const,getConst), liftA2, (<$>))  import qualified Data.Array.Comfort.Storable.Unchecked.Monadic as ArrayIO import qualified Data.Array.Comfort.Shape as Shape@@ -40,6 +42,10 @@ import Prelude hiding (sum)  +realPtr :: Ptr a -> Ptr (RealOf a)+realPtr = castPtr++ fill :: (Class.Floating a) => a -> Int -> Ptr a -> IO () fill a n dstPtr = evalContT $ do    nPtr <- Call.cint n@@ -91,6 +97,11 @@    return xPtr  +condConjugate ::+   (Class.Floating a) => Conjugation -> Ptr CInt -> Ptr a -> Ptr CInt -> IO ()+condConjugate conj nPtr yPtr incyPtr =+   when (conj==Conjugated) $ lacgv nPtr yPtr incyPtr+ copyConjugate ::    (Class.Floating a) =>    Ptr CInt -> Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt -> IO ()@@ -100,20 +111,22 @@  copyCondConjugate ::    (Class.Floating a) =>-   Bool -> Ptr CInt -> Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt -> IO ()+   Conjugation -> Ptr CInt -> Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt -> IO () copyCondConjugate conj nPtr xPtr incxPtr yPtr incyPtr = do    BlasGen.copy nPtr xPtr incxPtr yPtr incyPtr-   when conj $ lacgv nPtr yPtr incyPtr+   condConjugate conj nPtr yPtr incyPtr  condConjugateToTemp ::    (Class.Floating a) =>-   Bool -> Int -> ForeignPtr a -> ContT r IO (Ptr a)+   Conjugation -> Int -> ForeignPtr a -> ContT r IO (Ptr a) condConjugateToTemp conj n x =-   if conj then conjugateToTemp n x else ContT $ withForeignPtr x+   case conj of+      NonConjugated -> ContT $ withForeignPtr x+      Conjugated -> conjugateToTemp n x  copyCondConjugateToTemp ::    (Class.Floating a) =>-   Bool -> Int -> ForeignPtr a -> ContT r IO (Ptr a)+   Conjugation -> Int -> ForeignPtr a -> ContT r IO (Ptr a) copyCondConjugateToTemp conj n a = do    bPtr <- Call.allocaArray n    liftIO $ evalContT $ do@@ -222,35 +235,117 @@       incyPtr <- Call.cint 0       liftIO $ BlasReal.dot nPtr xPtr incxPtr yPtr incyPtr -sumComplex :: Class.Real a => Int -> Ptr (Complex a) -> Int -> IO (Complex a)+sumComplex, sumComplexAlt ::+   Class.Real a => Int -> Ptr (Complex a) -> Int -> IO (Complex a) sumComplex n xPtr incx =    evalContT $ do+      nPtr <- Call.cint n+      let sxPtr = realPtr xPtr+      incxPtr <- Call.cint (2*incx)+      yPtr <- Call.real one+      incyPtr <- Call.cint 0+      liftIO $+         liftA2 (Complex.:+)+            (BlasReal.dot nPtr sxPtr incxPtr yPtr incyPtr)+            (BlasReal.dot nPtr (advancePtr sxPtr 1) incxPtr yPtr incyPtr)++sumComplexAlt n aPtr inca =+   evalContT $ do       transPtr <- Call.char 'N'-      mPtr <- Call.cint 1+      mPtr <- Call.cint 2       nPtr <- Call.cint n-      alphaPtr <- Call.number one       onePtr <- Call.number one-      zeroincPtr <- Call.cint 0-      aPtr <- Call.allocaArray n-      ldaPtr <- Call.leadingDim 1-      incxPtr <- Call.cint incx+      inc0Ptr <- Call.cint 0+      let saPtr = realPtr aPtr+      ldaPtr <- Call.leadingDim (2*inca)+      sxPtr <- Call.allocaArray n+      incxPtr <- Call.cint 1       betaPtr <- Call.number zero       yPtr <- Call.alloca+      let syPtr = realPtr yPtr       incyPtr <- Call.cint 1       liftIO $ do-         BlasGen.copy nPtr onePtr zeroincPtr aPtr incyPtr+         BlasGen.copy nPtr onePtr inc0Ptr sxPtr incxPtr          gemv-            transPtr mPtr nPtr alphaPtr aPtr ldaPtr-            xPtr incxPtr betaPtr yPtr incyPtr+            transPtr mPtr nPtr onePtr saPtr ldaPtr+            sxPtr incxPtr betaPtr syPtr incyPtr          peek yPtr  -product :: Class.Floating a => Int -> Ptr a -> Int -> IO a-product n xPtr incx =-   foldM (\x ptr -> do y <- peek ptr; return $! x*y) one $-   take n $ pointerSeq incx xPtr+mulReal ::+   (Class.Floating a) =>+   Int -> Ptr a -> Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()+mulReal n aPtr inca xPtr incx yPtr incy = evalContT $ do+   uploPtr <- Call.char 'U'+   nPtr <- Call.cint n+   kPtr <- Call.cint 0+   alphaPtr <- Call.number one+   ldaPtr <- Call.leadingDim inca+   incxPtr <- Call.cint incx+   betaPtr <- Call.number zero+   incyPtr <- Call.cint incy+   liftIO $+      BlasGen.hbmv uploPtr+         nPtr kPtr alphaPtr aPtr ldaPtr+         xPtr incxPtr betaPtr yPtr incyPtr +mul ::+   (Class.Floating a) =>+   Int -> Ptr a -> Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()+mul n aPtr inca xPtr incx yPtr incy = evalContT $ do+   transPtr <- Call.char 'N'+   nPtr <- Call.cint n+   klPtr <- Call.cint 0+   kuPtr <- Call.cint 0+   alphaPtr <- Call.number one+   ldaPtr <- Call.leadingDim inca+   incxPtr <- Call.cint incx+   betaPtr <- Call.number zero+   incyPtr <- Call.cint incy+   liftIO $+      BlasGen.gbmv transPtr+         nPtr nPtr klPtr kuPtr alphaPtr aPtr ldaPtr+         xPtr incxPtr betaPtr yPtr incyPtr +{- |+Use the foldBalanced trick.+-}+product :: (Class.Floating a) => Int -> Ptr a -> Int -> IO a+product n aPtr inca =+   case compare n 1 of+      LT -> return one+      EQ -> peek aPtr+      GT -> let n2 = div n 2; new = n-n2+            in ForeignArray.alloca (2*new-1) $ \xPtr -> do+         mulPairs n2 aPtr inca xPtr 1+         when (odd n) $ pokeElemOff xPtr n2 =<< peekElemOff aPtr ((n-1)*inca)+         productLoop new xPtr++{- |+If 'mul' would be based on a scalar loop+we would not need to cut the vector into chunks.++The invariance is:+When calling @productLoop n xPtr@,+starting from xPtr there is storage allocated for 2*n-1 elements.+-}+productLoop :: (Class.Floating a) => Int -> Ptr a -> IO a+productLoop n xPtr =+   if n==1+      then peek xPtr+      else do+         let n2 = div n 2+         mulPairs n2 xPtr 1 (advancePtr xPtr n) 1+         productLoop (n-n2) (advancePtr xPtr (2*n2))++mulPairs ::+   (Class.Floating a) =>+   Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()+mulPairs n aPtr inca xPtr incx =+   let inca2 = 2*inca+   in mul n aPtr inca2 (advancePtr aPtr inca) inca2 xPtr incx++ newtype LACGV a = LACGV {getLACGV :: Ptr CInt -> Ptr a -> Ptr CInt -> IO ()}  lacgv :: Class.Floating a => Ptr CInt -> Ptr a -> Ptr CInt -> IO ()@@ -396,3 +491,16 @@       (Flip ceiling)       (Flip $ ceiling . Complex.realPart)       (Flip $ ceiling . Complex.realPart)+++caseRealComplexFunc :: (Class.Floating a) => f a -> b -> b -> b+caseRealComplexFunc f r c =+   getConstFunc f $+   Class.switchFloating (Const r) (Const r) (Const c) (Const c)++getConstFunc :: f c -> Const a c -> a+getConstFunc _ = getConst+++data ComplexPart = RealPart | ImaginaryPart+   deriving (Eq, Ord, Show, Enum, Bounded)
src/Numeric/LAPACK/Scalar.hs view
@@ -9,7 +9,9 @@    selectReal,    selectFloating, +   equal,    fromReal,+   toComplex,    absolute,    absoluteSquared,    norm1,@@ -57,6 +59,15 @@       (Identity rf) (Identity rd) (Identity cf) (Identity cd)  ++newtype Equal a = Equal {getEqual :: a -> a -> Bool}++equal :: (Class.Floating a) => a -> a -> Bool+equal =+   getEqual $+   Class.switchFloating (Equal (==)) (Equal (==)) (Equal (==)) (Equal (==))++ isZero :: Class.Floating a => a -> Bool isZero =    getFlip $@@ -75,6 +86,17 @@       (FromReal id)       (FromReal (:+0))       (FromReal (:+0))++newtype ToComplex f a = ToComplex {getToComplex :: a -> ComplexOf a}++toComplex :: (Class.Floating a) => a -> ComplexOf a+toComplex =+   getToComplex $+   Class.switchFloating+      (ToComplex (:+0))+      (ToComplex (:+0))+      (ToComplex id)+      (ToComplex id)  newtype ToReal a = ToReal {getToReal :: a -> RealOf a} 
+ src/Numeric/LAPACK/Shape.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE TypeFamilies #-}+module Numeric.LAPACK.Shape where++import qualified Data.Array.Comfort.Shape as Shape+++{- |+Uses the indices of the second shape,+but the list of indices is restricted by the size of the first shape.+-}+data Min sh0 sh1 = Min {minShape0 :: sh0, minShape1 :: sh1}+   deriving (Eq, Show)++instance (Shape.C sh0, Shape.C sh1) => Shape.C (Min sh0 sh1) where+   size (Min sh0 sh1) = min (Shape.size sh0) (Shape.size sh1)+   uncheckedSize (Min sh0 sh1) =+      min (Shape.uncheckedSize sh0) (Shape.uncheckedSize sh1)++instance (Shape.C sh0, Shape.Indexed sh1) => Shape.Indexed (Min sh0 sh1) where+   type Index (Min sh0 sh1) = Shape.Index sh1+   indices (Min sh0 sh1) = take (Shape.size sh0) $ Shape.indices sh1+   offset (Min sh0 sh1) ix =+      let k = Shape.uncheckedOffset sh1 ix+      in if k<Shape.size sh0+            then k+            else error "Shape.Min.offset: index exceeds size of first shape"+   uncheckedOffset (Min _sh0 sh1) ix = Shape.uncheckedOffset sh1 ix+   inBounds (Min sh0 sh1) ix =+      Shape.inBounds sh1 ix  &&  Shape.uncheckedOffset sh1 ix < Shape.size sh0++instance+   (Shape.C sh0, Shape.InvIndexed sh1) =>+      Shape.InvIndexed (Min sh0 sh1) where+   indexFromOffset (Min sh0 sh1) k =+      if k<Shape.size sh0+         then Shape.indexFromOffset sh1 k+         else error+               "Shape.Min.indexFromOffset: offset exceeds size of first shape"+   uncheckedIndexFromOffset (Min _sh0 sh1) k =+      Shape.uncheckedIndexFromOffset sh1 k
+ src/Numeric/LAPACK/Shape/Private.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE TypeFamilies #-}+module Numeric.LAPACK.Shape.Private where++import qualified Data.Array.Comfort.Shape as Shape+++newtype Unchecked sh = Unchecked {deconsUnchecked :: sh}+   deriving (Show)++instance Eq (Unchecked sh) where+   Unchecked _ == Unchecked _   =  True++instance (Shape.C sh) => Shape.C (Unchecked sh) where+   size (Unchecked sh) = Shape.size sh+   uncheckedSize (Unchecked sh) = Shape.uncheckedSize sh
src/Numeric/LAPACK/ShapeStatic.hs view
@@ -44,6 +44,9 @@             error $             printf "indexFromOffset (ShapeStatic.ZeroBased): index %d out of range" k +instance (Unary.Natural n) => Shape.Static (ZeroBased n) where+   static = ZeroBased Proxy+  vector :: (Unary.Natural n, Storable a) => FL.T n a -> Array (ZeroBased n) a vector = Array.fromList (ZeroBased Proxy) . FL.toList
src/Numeric/LAPACK/Singular.hs view
@@ -9,277 +9,92 @@    determinantAbsolute,    leastSquaresMinimumNormRCond,    pseudoInverseRCond,+   decomposePolar,    RealOf,    ) where -import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape-import qualified Numeric.LAPACK.Matrix.Square.Basic as Square+import qualified Numeric.LAPACK.Singular.Plain as Plain++import qualified Numeric.LAPACK.Matrix.Hermitian.Basic as HermitianBasic+import qualified Numeric.LAPACK.Matrix.Hermitian as Hermitian+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import qualified Numeric.LAPACK.Matrix.Basic as Basic import qualified Numeric.LAPACK.Matrix as Matrix-import qualified Numeric.LAPACK.Vector as Vector-import qualified Numeric.LAPACK.Private as Private-import Numeric.LAPACK.Matrix.Hermitian.Private-         (TakeDiagonal(..), Determinant(..))-import Numeric.LAPACK.Matrix.Extent.Private (Extent)-import Numeric.LAPACK.Matrix.Square.Basic (Square)-import Numeric.LAPACK.Matrix.Shape.Private (Order(ColumnMajor), swapOnRowMajor)-import Numeric.LAPACK.Matrix (scaleRowsReal)-import Numeric.LAPACK.Matrix.Private (Full, General, ZeroInt, zeroInt)+import qualified Numeric.LAPACK.Shape as ExtShape+import Numeric.LAPACK.Matrix.Array (ArrayMatrix, Full, General, Square)+import Numeric.LAPACK.Matrix.Multiply ((##*#), (#*##)) import Numeric.LAPACK.Vector (Vector)-import Numeric.LAPACK.Scalar (RealOf, zero)-import Numeric.LAPACK.Private-         (withAutoWorkspace, peekCInt, createHigherArray,-          copyToTemp, copyToColumnMajor, copyToSubColumnMajor)+import Numeric.LAPACK.Scalar (RealOf) -import qualified Numeric.LAPACK.FFI.Complex as LapackComplex-import qualified Numeric.LAPACK.FFI.Real as LapackReal-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 System.IO.Unsafe (unsafePerformIO)--import qualified Foreign.Marshal.Array.Guarded as ForeignArray-import qualified Foreign.Marshal.Utils as Marshal-import Foreign.C.Types (CInt, CChar)-import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)-import Foreign.Ptr (Ptr, nullPtr)-import Foreign.Storable (Storable)--import Control.Monad.Trans.Cont (evalContT)-import Control.Monad.IO.Class (liftIO)+import Data.Array.Comfort.Storable (Array) -import Data.Complex (Complex)-import Data.Tuple.HT (mapSnd)-import Data.Bool.HT (if')+import Data.Tuple.HT (mapFst, mapSnd, mapPair, mapTriple)   values ::    (Shape.C height, Shape.C width, Class.Floating a) =>-   General height width a -> Vector ZeroInt (RealOf a)-values =-   valuesGen $ \extent ->-      zeroInt $-      min-         (Shape.size $ Extent.height extent)-         (Shape.size $ Extent.width extent)+   General height width a -> Vector (ExtShape.Min height width) (RealOf a)+values = Plain.values . ArrMatrix.toVector  valuesTall ::    (Extent.C vert, Shape.C height, Shape.C width, Class.Floating a) =>    Full vert Extent.Small height width a -> Vector width (RealOf a)-valuesTall = valuesGen Extent.width+valuesTall = Plain.valuesTall . ArrMatrix.toVector  valuesWide ::    (Extent.C horiz, Shape.C height, Shape.C width, Class.Floating a) =>    Full Extent.Small horiz height width a -> Vector height (RealOf a)-valuesWide = valuesTall . Matrix.transpose--valuesGen ::-   (Extent.C vert, Extent.C horiz, Shape.C width, Shape.C height,-    Shape.C shape, Class.Floating a) =>-   (Extent vert horiz height width -> shape) ->-   Full vert horiz height width a -> Vector shape (RealOf a)-valuesGen resultShape =-   runTakeDiagonal $-   Class.switchFloating-      (TakeDiagonal $ valuesAux resultShape)-      (TakeDiagonal $ valuesAux resultShape)-      (TakeDiagonal $ valuesAux resultShape)-      (TakeDiagonal $ valuesAux resultShape)--valuesAux ::-   (Extent.C vert, Extent.C horiz, Shape.C width, Shape.C height,-    Shape.C shape, Class.Floating a, RealOf a ~ ar, Storable ar) =>-   (Extent vert horiz height width -> shape) ->-   Full vert horiz height width a -> Vector shape ar-valuesAux resultShape (Array shape@(MatrixShape.Full _order extent) a) =-   Array.unsafeCreateWithSize (resultShape extent) $ \mn sPtr -> do-   let (m,n) = MatrixShape.dimensions shape-   let lda = m-   evalContT $ do-      jobuPtr <- Call.char 'N'-      jobvtPtr <- Call.char 'N'-      mPtr <- Call.cint m-      nPtr <- Call.cint n-      aPtr <- copyToTemp (m*n) a-      ldaPtr <- Call.leadingDim lda-      let uPtr = nullPtr-      let vtPtr = nullPtr-      lduPtr <- Call.leadingDim m-      ldvtPtr <- Call.leadingDim n-      liftIO $-         withInfo "gesvd" $ \infoPtr ->-         gesvd jobuPtr jobvtPtr mPtr nPtr-            aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr mn infoPtr+valuesWide = Plain.valuesWide . ArrMatrix.toVector   determinantAbsolute ::    (Shape.C height, Shape.C width, Class.Floating a) =>    General height width a -> RealOf a-determinantAbsolute =-   getDeterminant $-   Class.switchFloating-      (Determinant determinantAbsoluteAux)-      (Determinant determinantAbsoluteAux)-      (Determinant determinantAbsoluteAux)-      (Determinant determinantAbsoluteAux)--determinantAbsoluteAux ::-   (Shape.C height, Shape.C width,-    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   General height width a -> ar-determinantAbsoluteAux =-   either (Vector.product . valuesTall) (const zero)-   .-   Matrix.caseTallWide+determinantAbsolute = Plain.determinantAbsolute . ArrMatrix.toVector   decompose ::    (Shape.C height, Shape.C width, Class.Floating a) =>    General height width a ->-   (Square height a, Vector ZeroInt (RealOf a), Square width a)-decompose =-   getDecompose $-   Class.switchFloating-      (Decompose decomposeAux)-      (Decompose decomposeAux)-      (Decompose decomposeAux)-      (Decompose decomposeAux)--newtype Decompose m f v g a =-   Decompose {getDecompose :: m a -> (f a, v (RealOf a), g a)}--decomposeAux ::-   (Shape.C height, Shape.C width,-    Class.Floating a, RealOf a ~ ar, Storable ar) =>-   General height width a ->-   (Square height a, Vector ZeroInt ar, Square width a)-decomposeAux arr@(Array shape@(MatrixShape.Full order extent) a) =--   let (height,width) = Extent.dimensions extent-       (m,n) = MatrixShape.dimensions shape-       mn = min m n--   in (if' (mn==0)-         (Square.identityFromHeight arr,-          Vector.autoFromList [],-          Square.identityFromWidth arr)) $-      (\(u,(s,vt)) -> (u,s,vt)) $-      Array.unsafeCreateWithSizeAndResult (MatrixShape.square order height) $-         \ _ uPtr0 ->-      ArrayIO.unsafeCreateWithSizeAndResult (zeroInt mn) $ \ _ sPtr ->-      ArrayIO.unsafeCreate (MatrixShape.square order width) $ \vtPtr0 ->--   evalContT $ do-      let (uPtr,vtPtr) = swapOnRowMajor order (uPtr0,vtPtr0)-      let lda = m-      jobuPtr <- Call.char 'A'-      jobvtPtr <- Call.char 'A'-      mPtr <- Call.cint m-      nPtr <- Call.cint n-      aPtr <- copyToTemp (m*n) a-      ldaPtr <- Call.leadingDim lda-      lduPtr <- Call.leadingDim m-      ldvtPtr <- Call.leadingDim n-      liftIO $-         withInfo "gesvd" $ \infoPtr ->-         gesvd jobuPtr jobvtPtr mPtr nPtr-            aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr mn infoPtr-+   (Square height a,+    Vector (ExtShape.Min height width) (RealOf a),+    Square width a)+decompose = liftDecompose Plain.decompose +{- |+> let (u,s,vt) = Singular.decomposeWide a+> in a  ==  u #*## Matrix.scaleRowsReal s vt+-} decomposeWide ::-   (Extent.C vert, Shape.C height, Shape.C width, Class.Floating a) =>-   Full Extent.Small vert height width a ->+   (Extent.C horiz, Shape.C height, Shape.C width, Class.Floating a) =>+   Full Extent.Small horiz height width a ->    (Square height a, Vector height (RealOf a),-      Full Extent.Small vert height width a)-decomposeWide a =-   let (u,s,vt) = decomposeTall $ Matrix.transpose a-   in  (Square.transpose vt, s, Matrix.transpose u)+      Full Extent.Small horiz height width a)+decomposeWide = liftDecompose Plain.decomposeWide +{- |+> let (u,s,vt) = Singular.decomposeTall a+> in a  ==  u ##*# Matrix.scaleRowsReal s vt+-} decomposeTall ::-   (Extent.C horiz, Shape.C height, Shape.C width, Class.Floating a) =>-   Full horiz Extent.Small height width a ->-   (Full horiz Extent.Small height width a,+   (Extent.C vert, Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert Extent.Small height width a ->+   (Full vert Extent.Small height width a,       Vector width (RealOf a), Square width a)-decomposeTall =-   getDecompose $-   Class.switchFloating-      (Decompose decomposeThin)-      (Decompose decomposeThin)-      (Decompose decomposeThin)-      (Decompose decomposeThin)+decomposeTall = liftDecompose Plain.decomposeTall -decomposeThin ::-   (Extent.C horiz, Shape.C height, Shape.C width,-    Class.Floating a, RealOf a ~ ar, Storable ar) =>-   Full horiz Extent.Small height width a ->-   (Full horiz Extent.Small height width a, Vector width ar, Square width a)-decomposeThin (Array (MatrixShape.Full order extent) a) =-   let (height,width) = Extent.dimensions extent-   in (\(u,(s,vt)) -> (u,s,vt)) $-      Array.unsafeCreateWithSizeAndResult (MatrixShape.Full order extent) $-         \ _ uPtr0 ->-      ArrayIO.unsafeCreateWithSizeAndResult width $ \ _ sPtr ->-      ArrayIO.unsafeCreate (MatrixShape.square order width) $ \vtPtr0 ->+liftDecompose ::+   (Array sha a -> (Array shb b, f, Array shc c)) ->+   ArrayMatrix sha a -> (ArrayMatrix shb b, f, ArrayMatrix shc c)+liftDecompose f =+   mapTriple (ArrMatrix.lift0, id, ArrMatrix.lift0) . f . ArrMatrix.toVector -   evalContT $ do-      let ((m,uPtr),(n,vtPtr)) =-            swapOnRowMajor order-               ((Shape.size height, uPtr0), (Shape.size width, vtPtr0))-      let mn = min m n-      let lda = m-      jobuPtr <- Call.char 'S'-      jobvtPtr <- Call.char 'S'-      mPtr <- Call.cint m-      nPtr <- Call.cint n-      aPtr <- copyToTemp (m*n) a-      ldaPtr <- Call.leadingDim lda-      lduPtr <- Call.leadingDim m-      ldvtPtr <- Call.leadingDim mn-      liftIO $-         withInfo "gesvd" $ \infoPtr ->-         gesvd jobuPtr jobvtPtr mPtr nPtr-            aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr mn infoPtr  -type GESVD_ ar a =-   Ptr CChar -> Ptr CChar -> Ptr CInt -> Ptr CInt ->-   Ptr a -> Ptr CInt -> Ptr ar ->-   Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt -> Int -> Ptr CInt -> IO ()--newtype GESVD a = GESVD {getGESVD :: GESVD_ (RealOf a) a}--gesvd :: Class.Floating a => GESVD_ (RealOf a) a-gesvd =-   getGESVD $-   Class.switchFloating-      (GESVD gesvdReal)-      (GESVD gesvdReal)-      (GESVD gesvdComplex)-      (GESVD gesvdComplex)--gesvdReal :: (Class.Real a) => GESVD_ a a-gesvdReal jobuPtr jobvtPtr mPtr nPtr-      aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr _mn infoPtr =-   withAutoWorkspace $ \workPtr lworkPtr ->-   LapackReal.gesvd jobuPtr jobvtPtr-      mPtr nPtr aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr-      workPtr lworkPtr infoPtr--gesvdComplex :: (Class.Real a) => GESVD_ a (Complex a)-gesvdComplex jobuPtr jobvtPtr-      mPtr nPtr aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr mn infoPtr =-   ForeignArray.alloca (5*mn) $ \rworkPtr ->-   withAutoWorkspace $ \workPtr lworkPtr ->-   LapackComplex.gesvd jobuPtr jobvtPtr-      mPtr nPtr aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr-      workPtr lworkPtr rworkPtr infoPtr-- leastSquaresMinimumNormRCond ::    (Extent.C vert, Extent.C horiz,     Shape.C height, Eq height, Shape.C width, Shape.C nrhs, Class.Floating a) =>@@ -287,190 +102,69 @@    Full horiz vert height width a ->    Full vert horiz height nrhs a ->    (Int, Full vert horiz width nrhs a)-leastSquaresMinimumNormRCond rcond-      (Array (MatrixShape.Full orderA extentA) a)-      (Array (MatrixShape.Full orderB extentB) b) =-   case Extent.fuse (Extent.transpose extentA) extentB of-      Nothing -> error "leastSquaresMinimumNorm: height shapes mismatch"-      Just extent ->-         let widthA = Extent.width extentA-             (height,widthB) = Extent.dimensions extentB-             shapeX = MatrixShape.Full ColumnMajor extent-             m = Shape.size height-             n = Shape.size widthA-             nrhs = Shape.size widthB-         in if m == 0-               then (0, Vector.constant shapeX zero)-               else-                  if nrhs == 0-                     then-                        (fst $ unsafePerformIO $-                         case Vector.constant height zero of-                           Array _ b1 ->-                              leastSquaresMinimumNormIO rcond-                                 (MatrixShape.general ColumnMajor widthA ())-                                 orderA a orderB b1 m n 1,-                         Vector.constant shapeX zero)-                     else-                        unsafePerformIO $-                        leastSquaresMinimumNormIO rcond shapeX-                           orderA a orderB b m n nrhs--leastSquaresMinimumNormIO ::-   (Shape.C sh, Class.Floating a) =>-   RealOf a -> sh ->-   Order -> ForeignPtr a ->-   Order -> ForeignPtr a ->-   Int -> Int -> Int -> IO (Int, Array sh a)-leastSquaresMinimumNormIO rcond shapeX orderA a orderB b m n nrhs =-   createHigherArray shapeX m n nrhs $ \(tmpPtr,ldtmp) -> do--   let mn = min m n-   let aSize = m*n-   let lda = m-   evalContT $ do-      mPtr <- Call.cint m-      nPtr <- Call.cint n-      nrhsPtr <- Call.cint nrhs-      aPtr <- Call.allocaArray aSize-      liftIO $ withForeignPtr a $ \asrcPtr ->-         copyToColumnMajor orderA m n asrcPtr aPtr-      ldaPtr <- Call.leadingDim lda-      ldtmpPtr <- Call.leadingDim ldtmp-      liftIO $ withForeignPtr b $ \bPtr ->-         copyToSubColumnMajor orderB m nrhs bPtr ldtmp tmpPtr--      rankPtr <- Call.alloca-      liftIO $-         withInfo "gelss" $ \infoPtr ->-         gelss mPtr nPtr nrhsPtr aPtr ldaPtr tmpPtr ldtmpPtr rcond-            rankPtr mn infoPtr--      liftIO $ peekCInt rankPtr---type GELSS_ ar a =-   Ptr CInt -> Ptr CInt -> Ptr CInt ->-   Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt ->-   ar -> Ptr CInt -> Int -> Ptr CInt -> IO ()--newtype GELSS a = GELSS {getGELSS :: GELSS_ (RealOf a) a}--gelss :: Class.Floating a => GELSS_ (RealOf a) a-gelss =-   getGELSS $-   Class.switchFloating-      (GELSS gelssReal)-      (GELSS gelssReal)-      (GELSS gelssComplex)-      (GELSS gelssComplex)--gelssReal :: (Class.Real a) => GELSS_ a a-gelssReal mPtr nPtr nrhsPtr aPtr ldaPtr bPtr ldbPtr rcond-      rankPtr mn infoPtr =-   Marshal.with rcond $ \rcondPtr ->-   ForeignArray.alloca mn $ \sPtr ->-   withAutoWorkspace $ \workPtr lworkPtr ->-   LapackReal.gelss-      mPtr nPtr nrhsPtr aPtr ldaPtr bPtr ldbPtr sPtr rcondPtr-      rankPtr workPtr lworkPtr infoPtr--gelssComplex :: (Class.Real a) => GELSS_ a (Complex a)-gelssComplex mPtr nPtr nrhsPtr aPtr ldaPtr bPtr ldbPtr rcond-      rankPtr mn infoPtr =-   Marshal.with rcond $ \rcondPtr ->-   ForeignArray.alloca mn $ \sPtr ->-   ForeignArray.alloca (5*mn) $ \rworkPtr ->-   withAutoWorkspace $ \workPtr lworkPtr ->-   LapackComplex.gelss-      mPtr nPtr nrhsPtr aPtr ldaPtr bPtr ldbPtr sPtr rcondPtr-      rankPtr workPtr lworkPtr rworkPtr infoPtr-+leastSquaresMinimumNormRCond rcond a b =+   mapSnd ArrMatrix.lift0 $+   Plain.leastSquaresMinimumNormRCond+      rcond (ArrMatrix.toVector a) (ArrMatrix.toVector b)  pseudoInverseRCond ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>    RealOf a ->    Full vert horiz height width a ->    (Int, Full horiz vert width height a)-pseudoInverseRCond =-   getPseudoInverseRCond $-   Class.switchFloating-      (PseudoInverseRCond pseudoInverseRCondAux)-      (PseudoInverseRCond pseudoInverseRCondAux)-      (PseudoInverseRCond pseudoInverseRCondAux)-      (PseudoInverseRCond pseudoInverseRCondAux)+pseudoInverseRCond rcond =+   mapSnd (ArrMatrix.lift0 . Basic.recheck) .+   Plain.pseudoInverseRCond rcond .+   Basic.uncheck . ArrMatrix.toVector -newtype PseudoInverseRCond f g a =-   PseudoInverseRCond {-      getPseudoInverseRCond :: RealOf a -> f a -> (Int, g a)-   } -pseudoInverseRCondAux ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Eq height, Shape.C width, Eq width,-    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   ar ->++decomposePolar ::+   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,+    Class.Floating a) =>    Full vert horiz height width a ->-   (Int, Full horiz vert width height a)-pseudoInverseRCondAux rcond =-   getPseudoInverseExtent $-   Extent.switchTagPair-      (PseudoInverseExtent $ pseudoInverseRCondWide rcond)-      (PseudoInverseExtent $ pseudoInverseRCondWide rcond)-      (PseudoInverseExtent $ pseudoInverseRCondTall rcond)-      (PseudoInverseExtent $-         either-            (mapSnd Matrix.fromFull . pseudoInverseRCondTall rcond)-            (mapSnd Matrix.fromFull . pseudoInverseRCondWide rcond)-         .-         Matrix.caseTallWide)+   (Full vert horiz height width a, Matrix.Hermitian width a)+decomposePolar =+   mapPair+      (ArrMatrix.lift1 Basic.recheck,+       ArrMatrix.lift1 HermitianBasic.recheck)+   .+   getDecomposePolar+      (Extent.switchTagPair+         (DecomposePolar decomposePolarWide)+         (DecomposePolar decomposePolarWide)+         (DecomposePolar decomposePolarTall)+         (DecomposePolar $+            either+               (mapFst Matrix.fromFull . decomposePolarTall)+               (mapFst Matrix.fromFull . decomposePolarWide)+            .+            Matrix.caseTallWide))+   .+   ArrMatrix.lift1 Basic.uncheck -newtype PseudoInverseExtent height width a vert horiz =-   PseudoInverseExtent {-      getPseudoInverseExtent ::+newtype DecomposePolar height width a vert horiz =+   DecomposePolar {+      getDecomposePolar ::          Full vert horiz height width a ->-         (Int, Full horiz vert width height a)+         (Full vert horiz height width a, Matrix.Hermitian width a)    } -pseudoInverseRCondWide ::-   (Extent.C horiz, Shape.C height, Eq height, Shape.C width, Eq width,-    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   RealOf a ->-   Full Extent.Small horiz height width a ->-   (Int, Full horiz Extent.Small width height a)-pseudoInverseRCondWide rcond a =-   let (u,s,vt) = decomposeWide a-       (rank,recipS) = recipSigma rcond s-   in  (rank,-        Matrix.multiply (Matrix.adjoint vt) $-        scaleRowsReal recipS $ Square.toFull $ Square.adjoint u)--pseudoInverseRCondTall ::-   (Extent.C vert, Shape.C height, Eq height, Shape.C width, Eq width,-    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   RealOf a ->+decomposePolarTall ::+   (Extent.C vert, Shape.C height, Shape.C width, Eq width,+    Class.Floating a) =>    Full vert Extent.Small height width a ->-   (Int, Full Extent.Small vert width height a)-pseudoInverseRCondTall rcond a =+   (Full vert Extent.Small height width a, Matrix.Hermitian width a)+decomposePolarTall a =    let (u,s,vt) = decomposeTall a-       (rank,recipS) = recipSigma rcond s-   in  (rank,-        Matrix.multiply (Square.toFull $ Square.adjoint vt) $-        scaleRowsReal recipS $ Matrix.adjoint u)---recipSigma ::-   (Shape.C sh, Class.Real a) => a -> Array sh a -> (Int, Array sh a)-recipSigma rcond sigmas =-   case Array.toList sigmas of-      [] -> (0, sigmas)-      0:_ -> (0, sigmas)-      xs@(x:_) ->-         let smin = x * rcond-         in (length (takeWhile (>=smin) xs),-             Array.map (\s -> if s>=smin then recip s else 0) sigmas)-+   in (u ##*# vt, Hermitian.congruenceDiagonal s $ Matrix.fromFull vt) -withInfo :: String -> (Ptr CInt -> IO ()) -> IO ()-withInfo = Private.withInfo "%d superdiagonals did not converge"+decomposePolarWide ::+   (Extent.C horiz, Shape.C height, Eq height, Shape.C width, Eq width,+    Class.Floating a) =>+   Full Extent.Small horiz height width a ->+   (Full Extent.Small horiz height width a, Matrix.Hermitian width a)+decomposePolarWide a =+   let (u,s,vt) = decomposeWide a+   in (u #*## vt, Hermitian.congruenceDiagonal s $ Matrix.fromFull vt)
+ src/Numeric/LAPACK/Singular/Plain.hs view
@@ -0,0 +1,475 @@+{-# LANGUAGE TypeFamilies #-}+module Numeric.LAPACK.Singular.Plain (+   values,+   valuesTall,+   valuesWide,+   decompose,+   decomposeTall,+   decomposeWide,+   determinantAbsolute,+   leastSquaresMinimumNormRCond,+   pseudoInverseRCond,+   RealOf,+   ) where++import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape+import qualified Numeric.LAPACK.Matrix.Square.Basic as Square+import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent+import qualified Numeric.LAPACK.Matrix.Private as Matrix+import qualified Numeric.LAPACK.Matrix.Basic as Basic+import qualified Numeric.LAPACK.Vector as Vector+import qualified Numeric.LAPACK.Shape as ExtShape+import qualified Numeric.LAPACK.Private as Private+import Numeric.LAPACK.Matrix.Hermitian.Private+         (TakeDiagonal(..), Determinant(..))+import Numeric.LAPACK.Matrix.Extent.Private (Extent)+import Numeric.LAPACK.Matrix.Square.Basic (Square)+import Numeric.LAPACK.Matrix.Shape.Private (Order(ColumnMajor), swapOnRowMajor)+import Numeric.LAPACK.Matrix.Private (Full, General)+import Numeric.LAPACK.Vector (Vector)+import Numeric.LAPACK.Scalar (RealOf, zero)+import Numeric.LAPACK.Private+         (withAutoWorkspace, peekCInt, createHigherArray,+          copyToTemp, copyToColumnMajor, copyToSubColumnMajor)++import qualified Numeric.LAPACK.FFI.Complex as LapackComplex+import qualified Numeric.LAPACK.FFI.Real as LapackReal+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 System.IO.Unsafe (unsafePerformIO)++import qualified Foreign.Marshal.Array.Guarded as ForeignArray+import qualified Foreign.Marshal.Utils as Marshal+import Foreign.C.Types (CInt, CChar)+import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)+import Foreign.Ptr (Ptr, nullPtr)+import Foreign.Storable (Storable)++import Control.Monad.Trans.Cont (evalContT)+import Control.Monad.IO.Class (liftIO)++import Data.Complex (Complex)+import Data.Tuple.HT (mapSnd)+import Data.Bool.HT (if')+++values ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   General height width a -> Vector (ExtShape.Min height width) (RealOf a)+values = valuesGen $ uncurry ExtShape.Min . Extent.dimensions++valuesTall ::+   (Extent.C vert, Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert Extent.Small height width a -> Vector width (RealOf a)+valuesTall = valuesGen Extent.width++valuesWide ::+   (Extent.C horiz, Shape.C height, Shape.C width, Class.Floating a) =>+   Full Extent.Small horiz height width a -> Vector height (RealOf a)+valuesWide = valuesTall . Basic.transpose++valuesGen ::+   (Extent.C vert, Extent.C horiz, Shape.C width, Shape.C height,+    Shape.C shape, Class.Floating a) =>+   (Extent vert horiz height width -> shape) ->+   Full vert horiz height width a -> Vector shape (RealOf a)+valuesGen resultShape =+   runTakeDiagonal $+   Class.switchFloating+      (TakeDiagonal $ valuesAux resultShape)+      (TakeDiagonal $ valuesAux resultShape)+      (TakeDiagonal $ valuesAux resultShape)+      (TakeDiagonal $ valuesAux resultShape)++valuesAux ::+   (Extent.C vert, Extent.C horiz, Shape.C width, Shape.C height,+    Shape.C shape, Class.Floating a, RealOf a ~ ar, Storable ar) =>+   (Extent vert horiz height width -> shape) ->+   Full vert horiz height width a -> Vector shape ar+valuesAux resultShape (Array shape@(MatrixShape.Full _order extent) a) =+   Array.unsafeCreateWithSize (resultShape extent) $ \mn sPtr -> do+   let (m,n) = MatrixShape.dimensions shape+   let lda = m+   evalContT $ do+      jobuPtr <- Call.char 'N'+      jobvtPtr <- Call.char 'N'+      mPtr <- Call.cint m+      nPtr <- Call.cint n+      aPtr <- copyToTemp (m*n) a+      ldaPtr <- Call.leadingDim lda+      let uPtr = nullPtr+      let vtPtr = nullPtr+      lduPtr <- Call.leadingDim m+      ldvtPtr <- Call.leadingDim n+      liftIO $+         withInfo "gesvd" $ \infoPtr ->+         gesvd jobuPtr jobvtPtr mPtr nPtr+            aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr mn infoPtr+++determinantAbsolute ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   General height width a -> RealOf a+determinantAbsolute =+   getDeterminant $+   Class.switchFloating+      (Determinant determinantAbsoluteAux)+      (Determinant determinantAbsoluteAux)+      (Determinant determinantAbsoluteAux)+      (Determinant determinantAbsoluteAux)++determinantAbsoluteAux ::+   (Shape.C height, Shape.C width,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   General height width a -> ar+determinantAbsoluteAux =+   either (Vector.product . valuesTall) (const zero)+   .+   Basic.caseTallWide+++decompose ::+   (Shape.C height, Shape.C width, Class.Floating a) =>+   General height width a ->+   (Square height a,+    Vector (ExtShape.Min height width) (RealOf a),+    Square width a)+decompose =+   getDecompose $+   Class.switchFloating+      (Decompose decomposeAux)+      (Decompose decomposeAux)+      (Decompose decomposeAux)+      (Decompose decomposeAux)++newtype Decompose m f v g a =+   Decompose {getDecompose :: m a -> (f a, v (RealOf a), g a)}++decomposeAux ::+   (Shape.C height, Shape.C width,+    Class.Floating a, RealOf a ~ ar, Storable ar) =>+   General height width a ->+   (Square height a, Vector (ExtShape.Min height width) ar, Square width a)+decomposeAux arr@(Array shape@(MatrixShape.Full order extent) a) =++   let (height,width) = Extent.dimensions extent+       minShape = ExtShape.Min height width+       mn = Shape.size minShape++   in (if' (mn==0)+         (Square.identityFromHeight arr,+          Vector.fromList minShape [],+          Square.identityFromWidth arr)) $+      (\(u,(s,vt)) -> (u,s,vt)) $+      Array.unsafeCreateWithSizeAndResult (MatrixShape.square order height) $+         \ _ uPtr0 ->+      ArrayIO.unsafeCreateWithSizeAndResult minShape $ \ _ sPtr ->+      ArrayIO.unsafeCreate (MatrixShape.square order width) $ \vtPtr0 ->++   evalContT $ do+      let (m,n) = MatrixShape.dimensions shape+      let (uPtr,vtPtr) = swapOnRowMajor order (uPtr0,vtPtr0)+      let lda = m+      jobuPtr <- Call.char 'A'+      jobvtPtr <- Call.char 'A'+      mPtr <- Call.cint m+      nPtr <- Call.cint n+      aPtr <- copyToTemp (m*n) a+      ldaPtr <- Call.leadingDim lda+      lduPtr <- Call.leadingDim m+      ldvtPtr <- Call.leadingDim n+      liftIO $+         withInfo "gesvd" $ \infoPtr ->+         gesvd jobuPtr jobvtPtr mPtr nPtr+            aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr mn infoPtr+++decomposeWide ::+   (Extent.C horiz, Shape.C height, Shape.C width, Class.Floating a) =>+   Full Extent.Small horiz height width a ->+   (Square height a, Vector height (RealOf a),+      Full Extent.Small horiz height width a)+decomposeWide a =+   let (u,s,vt) = decomposeTall $ Basic.transpose a+   in  (Square.transpose vt, s, Basic.transpose u)++decomposeTall ::+   (Extent.C vert, Shape.C height, Shape.C width, Class.Floating a) =>+   Full vert Extent.Small height width a ->+   (Full vert Extent.Small height width a,+      Vector width (RealOf a), Square width a)+decomposeTall =+   getDecompose $+   Class.switchFloating+      (Decompose decomposeThin)+      (Decompose decomposeThin)+      (Decompose decomposeThin)+      (Decompose decomposeThin)++decomposeThin ::+   (Extent.C vert, Shape.C height, Shape.C width,+    Class.Floating a, RealOf a ~ ar, Storable ar) =>+   Full vert Extent.Small height width a ->+   (Full vert Extent.Small height width a, Vector width ar, Square width a)+decomposeThin (Array (MatrixShape.Full order extent) a) =+   let (height,width) = Extent.dimensions extent+   in (\(u,(s,vt)) -> (u,s,vt)) $+      Array.unsafeCreateWithSizeAndResult (MatrixShape.Full order extent) $+         \ _ uPtr0 ->+      ArrayIO.unsafeCreateWithSizeAndResult width $ \ _ sPtr ->+      ArrayIO.unsafeCreate (MatrixShape.square order width) $ \vtPtr0 ->++   evalContT $ do+      let ((m,uPtr),(n,vtPtr)) =+            swapOnRowMajor order+               ((Shape.size height, uPtr0), (Shape.size width, vtPtr0))+      let mn = min m n+      let lda = m+      jobuPtr <- Call.char 'S'+      jobvtPtr <- Call.char 'S'+      mPtr <- Call.cint m+      nPtr <- Call.cint n+      aPtr <- copyToTemp (m*n) a+      ldaPtr <- Call.leadingDim lda+      lduPtr <- Call.leadingDim m+      ldvtPtr <- Call.leadingDim mn+      liftIO $+         withInfo "gesvd" $ \infoPtr ->+         gesvd jobuPtr jobvtPtr mPtr nPtr+            aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr mn infoPtr+++type GESVD_ ar a =+   Ptr CChar -> Ptr CChar -> Ptr CInt -> Ptr CInt ->+   Ptr a -> Ptr CInt -> Ptr ar ->+   Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt -> Int -> Ptr CInt -> IO ()++newtype GESVD a = GESVD {getGESVD :: GESVD_ (RealOf a) a}++gesvd :: Class.Floating a => GESVD_ (RealOf a) a+gesvd =+   getGESVD $+   Class.switchFloating+      (GESVD gesvdReal)+      (GESVD gesvdReal)+      (GESVD gesvdComplex)+      (GESVD gesvdComplex)++gesvdReal :: (Class.Real a) => GESVD_ a a+gesvdReal jobuPtr jobvtPtr mPtr nPtr+      aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr _mn infoPtr =+   withAutoWorkspace $ \workPtr lworkPtr ->+   LapackReal.gesvd jobuPtr jobvtPtr+      mPtr nPtr aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr+      workPtr lworkPtr infoPtr++gesvdComplex :: (Class.Real a) => GESVD_ a (Complex a)+gesvdComplex jobuPtr jobvtPtr+      mPtr nPtr aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr mn infoPtr =+   ForeignArray.alloca (5*mn) $ \rworkPtr ->+   withAutoWorkspace $ \workPtr lworkPtr ->+   LapackComplex.gesvd jobuPtr jobvtPtr+      mPtr nPtr aPtr ldaPtr sPtr uPtr lduPtr vtPtr ldvtPtr+      workPtr lworkPtr rworkPtr infoPtr+++leastSquaresMinimumNormRCond ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Shape.C nrhs, Class.Floating a) =>+   RealOf a ->+   Full horiz vert height width a ->+   Full vert horiz height nrhs a ->+   (Int, Full vert horiz width nrhs a)+leastSquaresMinimumNormRCond rcond+      (Array (MatrixShape.Full orderA extentA) a)+      (Array (MatrixShape.Full orderB extentB) b) =+   case Extent.fuse (Extent.transpose extentA) extentB of+      Nothing -> error "leastSquaresMinimumNorm: height shapes mismatch"+      Just extent ->+         let widthA = Extent.width extentA+             (height,widthB) = Extent.dimensions extentB+             shapeX = MatrixShape.Full ColumnMajor extent+             m = Shape.size height+             n = Shape.size widthA+             nrhs = Shape.size widthB+         in if m == 0+               then (0, Vector.zero shapeX)+               else+                  if nrhs == 0+                     then+                        (fst $ unsafePerformIO $+                         case Vector.zero height of+                           Array _ b1 ->+                              leastSquaresMinimumNormIO rcond+                                 (MatrixShape.general ColumnMajor widthA ())+                                 orderA a orderB b1 m n 1,+                         Vector.zero shapeX)+                     else+                        unsafePerformIO $+                        leastSquaresMinimumNormIO rcond shapeX+                           orderA a orderB b m n nrhs++leastSquaresMinimumNormIO ::+   (Shape.C sh, Class.Floating a) =>+   RealOf a -> sh ->+   Order -> ForeignPtr a ->+   Order -> ForeignPtr a ->+   Int -> Int -> Int -> IO (Int, Array sh a)+leastSquaresMinimumNormIO rcond shapeX orderA a orderB b m n nrhs =+   createHigherArray shapeX m n nrhs $ \(tmpPtr,ldtmp) -> do++   let mn = min m n+   let aSize = m*n+   let lda = m+   evalContT $ do+      mPtr <- Call.cint m+      nPtr <- Call.cint n+      nrhsPtr <- Call.cint nrhs+      aPtr <- Call.allocaArray aSize+      liftIO $ withForeignPtr a $ \asrcPtr ->+         copyToColumnMajor orderA m n asrcPtr aPtr+      ldaPtr <- Call.leadingDim lda+      ldtmpPtr <- Call.leadingDim ldtmp+      liftIO $ withForeignPtr b $ \bPtr ->+         copyToSubColumnMajor orderB m nrhs bPtr ldtmp tmpPtr++      rankPtr <- Call.alloca+      liftIO $+         withInfo "gelss" $ \infoPtr ->+         gelss mPtr nPtr nrhsPtr aPtr ldaPtr tmpPtr ldtmpPtr rcond+            rankPtr mn infoPtr++      liftIO $ peekCInt rankPtr+++type GELSS_ ar a =+   Ptr CInt -> Ptr CInt -> Ptr CInt ->+   Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt ->+   ar -> Ptr CInt -> Int -> Ptr CInt -> IO ()++newtype GELSS a = GELSS {getGELSS :: GELSS_ (RealOf a) a}++gelss :: Class.Floating a => GELSS_ (RealOf a) a+gelss =+   getGELSS $+   Class.switchFloating+      (GELSS gelssReal)+      (GELSS gelssReal)+      (GELSS gelssComplex)+      (GELSS gelssComplex)++gelssReal :: (Class.Real a) => GELSS_ a a+gelssReal mPtr nPtr nrhsPtr aPtr ldaPtr bPtr ldbPtr rcond+      rankPtr mn infoPtr =+   Marshal.with rcond $ \rcondPtr ->+   ForeignArray.alloca mn $ \sPtr ->+   withAutoWorkspace $ \workPtr lworkPtr ->+   LapackReal.gelss+      mPtr nPtr nrhsPtr aPtr ldaPtr bPtr ldbPtr sPtr rcondPtr+      rankPtr workPtr lworkPtr infoPtr++gelssComplex :: (Class.Real a) => GELSS_ a (Complex a)+gelssComplex mPtr nPtr nrhsPtr aPtr ldaPtr bPtr ldbPtr rcond+      rankPtr mn infoPtr =+   Marshal.with rcond $ \rcondPtr ->+   ForeignArray.alloca mn $ \sPtr ->+   ForeignArray.alloca (5*mn) $ \rworkPtr ->+   withAutoWorkspace $ \workPtr lworkPtr ->+   LapackComplex.gelss+      mPtr nPtr nrhsPtr aPtr ldaPtr bPtr ldbPtr sPtr rcondPtr+      rankPtr workPtr lworkPtr rworkPtr infoPtr+++pseudoInverseRCond ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Eq width, Class.Floating a) =>+   RealOf a ->+   Full vert horiz height width a ->+   (Int, Full horiz vert width height a)+pseudoInverseRCond =+   getPseudoInverseRCond $+   Class.switchFloating+      (PseudoInverseRCond pseudoInverseRCondAux)+      (PseudoInverseRCond pseudoInverseRCondAux)+      (PseudoInverseRCond pseudoInverseRCondAux)+      (PseudoInverseRCond pseudoInverseRCondAux)++newtype PseudoInverseRCond f g a =+   PseudoInverseRCond {+      getPseudoInverseRCond :: RealOf a -> f a -> (Int, g a)+   }++pseudoInverseRCondAux ::+   (Extent.C vert, Extent.C horiz,+    Shape.C height, Eq height, Shape.C width, Eq width,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   ar ->+   Full vert horiz height width a ->+   (Int, Full horiz vert width height a)+pseudoInverseRCondAux rcond =+   getPseudoInverseExtent $+   Extent.switchTagPair+      (PseudoInverseExtent $ pseudoInverseRCondWide rcond)+      (PseudoInverseExtent $ pseudoInverseRCondWide rcond)+      (PseudoInverseExtent $ pseudoInverseRCondTall rcond)+      (PseudoInverseExtent $+         either+            (mapSnd Matrix.fromFull . pseudoInverseRCondTall rcond)+            (mapSnd Matrix.fromFull . pseudoInverseRCondWide rcond)+         .+         Basic.caseTallWide)++newtype PseudoInverseExtent height width a vert horiz =+   PseudoInverseExtent {+      getPseudoInverseExtent ::+         Full vert horiz height width a ->+         (Int, Full horiz vert width height a)+   }++pseudoInverseRCondWide ::+   (Extent.C horiz, Shape.C height, Eq height, Shape.C width, Eq width,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   RealOf a ->+   Full Extent.Small horiz height width a ->+   (Int, Full horiz Extent.Small width height a)+pseudoInverseRCondWide rcond a =+   let (u,s,vt) = decomposeWide a+       (rank,recipS) = recipSigma rcond s+   in  (rank,+        Basic.multiply (Basic.adjoint vt) $+        Basic.scaleRowsReal recipS $ Square.toFull $ Square.adjoint u)++pseudoInverseRCondTall ::+   (Extent.C vert, Shape.C height, Eq height, Shape.C width, Eq width,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   RealOf a ->+   Full vert Extent.Small height width a ->+   (Int, Full Extent.Small vert width height a)+pseudoInverseRCondTall rcond a =+   let (u,s,vt) = decomposeTall a+       (rank,recipS) = recipSigma rcond s+   in  (rank,+        Basic.multiply (Square.toFull $ Square.adjoint vt) $+        Basic.scaleRowsReal recipS $ Basic.adjoint u)+++recipSigma ::+   (Shape.C sh, Class.Real a) => a -> Array sh a -> (Int, Array sh a)+recipSigma rcond sigmas =+   case Array.toList sigmas of+      [] -> (0, sigmas)+      0:_ -> (0, sigmas)+      xs@(x:_) ->+         let smin = x * rcond+         in (length (takeWhile (>=smin) xs),+             Array.map (\s -> if s>=smin then recip s else 0) sigmas)+++withInfo :: String -> (Ptr CInt -> IO ()) -> IO ()+withInfo = Private.withInfo "%d superdiagonals did not converge"
src/Numeric/LAPACK/Split.hs view
@@ -12,9 +12,10 @@          (Order(RowMajor, ColumnMajor), transposeFromOrder,           swapOnRowMajor, sideSwapFromOrder,           Triangle, uploFromOrder, flipOrder)-import Numeric.LAPACK.Matrix.Private-         (Full, Transposition, transposeOrder,+import Numeric.LAPACK.Matrix.Modifier+         (Transposition, transposeOrder,           Conjugation(NonConjugated, Conjugated))+import Numeric.LAPACK.Matrix.Private (Full) import Numeric.LAPACK.Linear.Private (solver, withInfo) import Numeric.LAPACK.Scalar (zero, one) import Numeric.LAPACK.Private (copyBlock, conjugateToTemp)@@ -42,7 +43,9 @@ type Split lower vert horiz height width =       Array (MatrixShape.Split lower vert horiz height width) +type Square lower sh = Split lower Extent.Small Extent.Small sh sh + determinantR ::    (Extent.C vert, Shape.C height, Shape.C width, Class.Floating a) =>    Split lower vert Extent.Small height width a -> a@@ -54,13 +57,6 @@    in unsafePerformIO $       withForeignPtr a $ \aPtr ->       Private.product (min m n) aPtr (k+1)--oddPermutation :: [CInt] -> Bool-oddPermutation = not . null . dropEven . filter id . zipWith (/=) [1..]--dropEven :: [a] -> [a]-dropEven (_:_:xs) = dropEven xs-dropEven xs = xs   extractTriangle ::
src/Numeric/LAPACK/Vector.hs view
@@ -7,45 +7,60 @@    toList,    fromList,    autoFromList,-   append, take, drop,-   takeLeft, takeRight,+   CheckedArray.append, (+++),+   CheckedArray.take, CheckedArray.drop,+   CheckedArray.takeLeft, CheckedArray.takeRight,    swap,-   singleton,+   CheckedArray.singleton,    constant,+   zero,+   one,    unit,-   dot, inner,+   dot, inner, (-*|),    sum,    absSum,    norm1,    norm2,+   norm2Squared,    normInf,    normInf1,    argAbsMaximum,    argAbs1Maximum,    product,-   scale, scaleReal,-   add, sub,+   scale, scaleReal, (.*|),+   add, sub, (|+|), (|-|),+   negate, raise,    mac,    mul,+   divide, recip,+   minimum, argMinimum,+   maximum, argMaximum,+   limits, argLimits,+   CheckedArray.foldl,+   CheckedArray.foldl1,+   CheckedArray.foldMap,     conjugate,    fromReal,    toComplex,    realPart,-   complexFromReal,-   complexToRealPart,-   complexToImaginaryPart,+   imaginaryPart,    zipComplex,    unzipComplex,     random, RandomDistribution(..),    ) where +import qualified Numeric.LAPACK.Matrix.RowMajor as RowMajor+import qualified Numeric.LAPACK.Vector.Private as Vector import qualified Numeric.LAPACK.Scalar as Scalar import qualified Numeric.LAPACK.Private as Private-import Numeric.LAPACK.Matrix.Private (ZeroInt)-import Numeric.LAPACK.Scalar (ComplexOf, RealOf, zero, one, minusOne, absolute)-import Numeric.LAPACK.Private (fill, copyConjugate)+import Numeric.LAPACK.Matrix.Hermitian.Private+         (Determinant(Determinant, getDeterminant))+import Numeric.LAPACK.Linear.Private (withInfo)+import Numeric.LAPACK.Scalar (ComplexOf, RealOf, minusOne, absolute)+import Numeric.LAPACK.Private+         (ComplexPart(RealPart, ImaginaryPart), fill, copyConjugate, realPtr)  import qualified Numeric.LAPACK.FFI.Generic as LapackGen import qualified Numeric.LAPACK.FFI.Complex as LapackComplex@@ -55,10 +70,10 @@ import qualified Numeric.Netlib.Utility as Call import qualified Numeric.Netlib.Class as Class -import Foreign.Marshal.Array (copyArray, advancePtr)-import Foreign.ForeignPtr (withForeignPtr)-import Foreign.Ptr (Ptr, castPtr)-import Foreign.Storable (Storable, peek, poke, peekElemOff, pokeElemOff)+import Foreign.Marshal.Array (advancePtr)+import Foreign.ForeignPtr (withForeignPtr, castForeignPtr)+import Foreign.Ptr (Ptr)+import Foreign.Storable (Storable, peek, peekElemOff, pokeElemOff) import Foreign.C.Types (CInt)  import System.IO.Unsafe (unsafePerformIO)@@ -66,22 +81,29 @@ import Control.Monad.Trans.Cont (ContT(ContT), evalContT) import Control.Monad.IO.Class (liftIO) import Control.Monad.ST (runST)-import Control.Applicative (Const(Const,getConst), liftA3, (<$>))+import Control.Monad (fmap, return, (=<<))+import Control.Applicative (liftA3, (<$>))  import qualified Data.Array.Comfort.Storable.Mutable.Unchecked as UMutArray import qualified Data.Array.Comfort.Storable.Mutable as MutArray import qualified Data.Array.Comfort.Storable.Unchecked as Array import qualified Data.Array.Comfort.Storable as CheckedArray import qualified Data.Array.Comfort.Shape as Shape-import Data.Array.Comfort.Storable.Unchecked (Array(Array))-import Data.Array.Comfort.Shape ((:+:)((:+:)))+import Data.Array.Comfort.Storable.Unchecked (Array(Array), append, (!))+import Data.Array.Comfort.Shape ((:+:)) +import Data.Function (id, flip, ($), (.)) import Data.Complex (Complex)+import Data.Maybe (Maybe(Nothing,Just), maybe) import Data.Tuple.HT (mapFst, uncurry3)+import Data.Tuple (fst, snd) import Data.Word (Word64) import Data.Bits (shiftR, (.&.))+import Data.Ord (Ord, (>=))+import Data.Eq (Eq, (==))+import Data.Bool (Bool(False,True)) -import Prelude hiding (sum, product, take, drop)+import Prelude (Int, fromIntegral, (+), (-), (*), Char, Show, Enum, error, IO)   type Vector = Array@@ -98,67 +120,39 @@   {- |-> singleton = constant ()+> constant () = singleton  However, singleton does not need 'Class.Floating' constraint. -}-singleton :: (Storable a) => a -> Vector () a-singleton a = Array.unsafeCreate () $ flip poke a- constant :: (Shape.C sh, Class.Floating a) => sh -> a -> Vector sh a constant sh a = Array.unsafeCreateWithSize sh $ fill a +zero :: (Shape.C sh, Class.Floating a) => sh -> Vector sh a+zero = flip constant Scalar.zero++one :: (Shape.C sh, Class.Floating a) => sh -> Vector sh a+one = flip constant Scalar.one+ unit ::    (Shape.Indexed sh, Class.Floating a) =>    sh -> Shape.Index sh -> Vector sh a unit sh ix = Array.unsafeCreateWithSize sh $ \n xPtr -> do-   fill zero n xPtr-   pokeElemOff xPtr (Shape.offset sh ix) one+   fill Scalar.zero n xPtr+   pokeElemOff xPtr (Shape.offset sh ix) Scalar.one  -append ::+{- |+Precedence and associativity (right) of (List.++).+This also matches '(Shape.:+:)'.+-}+infixr 5 +++++(+++) ::    (Shape.C shx, Shape.C shy, Storable a) =>    Vector shx a -> Vector shy a -> Vector (shx:+:shy) a-append (Array shX x) (Array shY y) =-   Array.unsafeCreate (shX:+:shY) $ \zPtr ->-   evalContT $ do-      xPtr <- ContT $ withForeignPtr x-      yPtr <- ContT $ withForeignPtr y-      let sizeX = Shape.size shX-      let sizeY = Shape.size shY-      liftIO $ do-         copyArray zPtr xPtr sizeX-         copyArray (advancePtr zPtr sizeX) yPtr sizeY+(+++) = append -take, drop :: (Storable a) => Int -> Vector ZeroInt a -> Vector ZeroInt a-take n = takeLeft . split n-drop n = takeRight . split n -split :: (Storable a) => Int -> Vector ZeroInt a -> Vector (ZeroInt:+:ZeroInt) a-split n =-   Array.mapShape-      (\(Shape.ZeroBased m) ->-         if n<0-            then error "Vector.split: negative number of elements"-            else-               let k = min n m-               in Shape.ZeroBased k :+: Shape.ZeroBased (m-k))--takeLeft ::-   (Shape.C sh0, Shape.C sh1, Storable a) =>-   Vector (sh0:+:sh1) a -> Vector sh0 a-takeLeft (Array (sh0 :+: _sh1) x) =-   Array.unsafeCreateWithSize sh0 $ \k yPtr ->-   withForeignPtr x $ \xPtr -> copyArray yPtr xPtr k--takeRight ::-   (Shape.C sh0, Shape.C sh1, Storable a) =>-   Vector (sh0:+:sh1) a -> Vector sh1 a-takeRight (Array (sh0:+:sh1) x) =-   Array.unsafeCreateWithSize sh1 $ \k yPtr ->-   withForeignPtr x $ \xPtr ->-      copyArray yPtr (advancePtr xPtr (Shape.size sh0)) k- swap ::    (Shape.Indexed sh, Storable a) =>    Shape.Index sh -> Shape.Index sh -> Vector sh a -> Vector sh a@@ -172,14 +166,17 @@       UMutArray.unsafeFreeze y)  -newtype Dot sh a = Dot {runDot :: Vector sh a -> Vector sh a -> a}+infixl 7 -*|, .*| +newtype Dot f a = Dot {runDot :: f a -> f a -> a}+ {- | > dot x y = Matrix.toScalar (singleRow x <#> singleColumn y) -}-dot ::+dot, (-*|) ::    (Shape.C sh, Eq sh, Class.Floating a) =>    Vector sh a -> Vector sh a -> a+(-*|) = dot dot =    runDot $    Class.switchFloating@@ -227,12 +224,12 @@       transPtr <- Call.char trans       mPtr <- Call.cint m       nPtr <- Call.cint 1-      alphaPtr <- Call.number one+      alphaPtr <- Call.number Scalar.one       xPtr <- ContT $ withForeignPtr x       ldxPtr <- Call.leadingDim m       yPtr <- ContT $ withForeignPtr y       incyPtr <- Call.cint 1-      betaPtr <- Call.number zero+      betaPtr <- Call.number Scalar.zero       zPtr <- Call.alloca       inczPtr <- Call.cint 1       liftIO $@@ -293,13 +290,29 @@    Norm {getNorm :: Ptr CInt -> Ptr a -> Ptr CInt -> IO (RealOf a)}  +norm2Squared :: (Shape.C sh, Class.Floating a) => Vector sh a -> RealOf a+norm2Squared =+   getDeterminant $+   Class.switchFloating+      (Determinant norm2SquaredReal)+      (Determinant norm2SquaredReal)+      (Determinant $ norm2SquaredReal . decomplex)+      (Determinant $ norm2SquaredReal . decomplex)++norm2SquaredReal :: (Shape.C sh, Class.Real a) => Vector sh a -> a+norm2SquaredReal arr =+   unsafePerformIO $ evalContT $ do+      (nPtr, sxPtr, incxPtr) <- vectorArgs arr+      liftIO $ BlasReal.dot nPtr sxPtr incxPtr sxPtr incxPtr++ normInf :: (Shape.C sh, Class.Floating a) => Vector sh a -> RealOf a normInf arr = unsafePerformIO $    evalContT $ do       (nPtr, sxPtr, incxPtr) <- vectorArgs arr       liftIO $-         fmap (absolute . maybe zero snd) $-         peekElemOff1 sxPtr =<< absMax nPtr sxPtr incxPtr+         fmap (absolute . maybe Scalar.zero snd) $+         peekElemOff1 sxPtr =<< Vector.absMax nPtr sxPtr incxPtr  {- | Computes (almost) the infinity norm of the vector.@@ -311,7 +324,7 @@    evalContT $ do       (nPtr, sxPtr, incxPtr) <- vectorArgs arr       liftIO $-         fmap (Scalar.norm1 . maybe zero snd) $+         fmap (Scalar.norm1 . maybe Scalar.zero snd) $          peekElemOff1 sxPtr =<< BlasGen.iamax nPtr sxPtr incxPtr  @@ -330,19 +343,7 @@             (maybe                (error "Vector.argAbsMaximum: empty vector")                (mapFst (Shape.uncheckedIndexFromOffset $ Array.shape arr))) $-         peekElemOff1 sxPtr =<< absMax nPtr sxPtr incxPtr--newtype ArgMaximum a =-   ArgMaximum {runArgMaximum :: Ptr CInt -> Ptr a -> Ptr CInt -> IO CInt}--absMax :: Class.Floating a => Ptr CInt -> Ptr a -> Ptr CInt -> IO CInt-absMax =-   runArgMaximum $-   Class.switchFloating-      (ArgMaximum BlasGen.iamax)-      (ArgMaximum BlasGen.iamax)-      (ArgMaximum LapackComplex.imax1)-      (ArgMaximum LapackComplex.imax1)+         peekElemOff1 sxPtr =<< Vector.absMax nPtr sxPtr incxPtr   {- |@@ -386,9 +387,53 @@    withForeignPtr x $ \xPtr -> Private.product (Shape.size sh) xPtr 1  -scale, _scale ::+{- |+For restrictions see 'limits'.+-}+minimum, maximum :: (Shape.C sh, Class.Real a) => Vector sh a -> a+minimum = fst . limits+maximum = snd . limits++{- |+For restrictions see 'limits'.+-}+argMinimum, argMaximum ::+   (Shape.InvIndexed sh, Shape.Index sh ~ ix, Class.Real a) =>+   Vector sh a -> (ix,a)+argMinimum = fst . argLimits+argMaximum = snd . argLimits++{- |+It should hold @limits x = Array.limits x@.+The function is based on fast BLAS functions.+It should be faster than @Array.minimum@ and @Array.maximum@+although it is certainly not as fast as possible.+It is less precise if minimum and maximum differ considerably in magnitude+and there are several minimum or maximum candidates of similar value.+E.g. you cannot rely on the property+that @raise (- minimum x) x@ has only non-negative elements.+-}+limits :: (Shape.C sh, Class.Real a) => Vector sh a -> (a,a)+limits xs0 =+   let xs = Array.mapShape Shape.Deferred xs0+       x0 = snd $ argAbsMaximum xs+       x1 = xs ! fst (argAbsMaximum (raise (-x0) xs))+   in if x0>=0 then (x1,x0) else (x0,x1)++argLimits ::+   (Shape.InvIndexed sh, Shape.Index sh ~ ix, Class.Real a) =>+   Vector sh a -> ((ix,a),(ix,a))+argLimits xs =+   let p0@(_i0,x0) = argAbsMaximum xs+       p1 = (i1,xs!i1); i1 = fst $ argAbsMaximum $ raise (-x0) xs+   in if x0>=0 then (p1,p0) else (p0,p1)+++scale, _scale, (.*|) ::    (Shape.C sh, Class.Floating a) =>    a -> Vector sh a -> Vector sh a+(.*|) = scale+ scale alpha (Array sh x) = Array.unsafeCreateWithSize sh $ \n syPtr -> do    evalContT $ do       alphaPtr <- Call.number alpha@@ -408,12 +453,12 @@       mPtr <- Call.cint m       kPtr <- Call.cint k       nPtr <- Call.cint n-      alphaPtr <- Call.number one+      alphaPtr <- Call.number Scalar.one       aPtr <- Call.number a       ldaPtr <- Call.leadingDim m       bPtr <- ContT $ withForeignPtr b       ldbPtr <- Call.leadingDim k-      betaPtr <- Call.number zero+      betaPtr <- Call.number Scalar.zero       ldcPtr <- Call.leadingDim m       liftIO $          BlasGen.gemm@@ -429,52 +474,68 @@    Class.switchFloating       (ScaleReal scale)       (ScaleReal scale)-      (ScaleReal scaleRealComplex)-      (ScaleReal scaleRealComplex)+      (ScaleReal $ \x -> recomplex . scale x . decomplex)+      (ScaleReal $ \x -> recomplex . scale x . decomplex)  newtype ScaleReal f a = ScaleReal {getScaleReal :: RealOf a -> f a -> f a} -scaleRealComplex ::-   (Shape.C sh, Class.Real a) =>-   a -> Vector sh (Complex a) -> Vector sh (Complex a)-scaleRealComplex alpha (Array sh x) =-      Array.unsafeCreateWithSize sh $ \n cyPtr ->-   evalContT $ do-      alphaPtr <- Call.number alpha-      n2Ptr <- Call.cint (2*n)-      cxPtr <- ContT $ withForeignPtr x-      let sxPtr = castPtr cxPtr-      let syPtr = castPtr cyPtr-      incxPtr <- Call.cint 1-      incyPtr <- Call.cint 1-      liftIO $ do-         BlasReal.copy n2Ptr sxPtr incxPtr syPtr incyPtr-         BlasReal.scal n2Ptr alphaPtr syPtr incyPtr +decomplex ::+   (Class.Real a) =>+   Vector sh (Complex a) -> Vector (sh, Shape.Enumeration ComplexPart) a+decomplex (Array sh a) = Array (sh, Shape.Enumeration) (castForeignPtr a) -add, sub ::+recomplex ::+   (Class.Real a) =>+   Vector (sh, Shape.Enumeration ComplexPart) a -> Vector sh (Complex a)+recomplex (Array (sh, Shape.Enumeration) a) = Array sh (castForeignPtr a)++++infixl 6 |+|, |-|, `add`, `sub`+++add, sub, (|+|), (|-|) ::    (Shape.C sh, Eq sh, Class.Floating a) =>    Vector sh a -> Vector sh a -> Vector sh a-add = mac one+add = mac Scalar.one sub x y = mac minusOne y x +(|+|) = add+(|-|) = sub+ mac ::    (Shape.C sh, Eq sh, Class.Floating a) =>    a -> Vector sh a -> Vector sh a -> Vector sh a-mac alpha (Array shX x) (Array shY y) =-      Array.unsafeCreateWithSize shX $ \n szPtr -> do-   Call.assert "mac: shapes mismatch" (shX == shY)-   evalContT $ do+mac alpha x y =+   if Array.shape x == Array.shape y+      then Vector.mac alpha x y+      else error "mac: shapes mismatch"++negate :: (Shape.C sh, Class.Floating a) => Vector sh a -> Vector sh a+negate =+   getConjugate $+   Class.switchFloating+      (Conjugate $ scaleReal Scalar.minusOne)+      (Conjugate $ scaleReal Scalar.minusOne)+      (Conjugate $ scaleReal Scalar.minusOne)+      (Conjugate $ scaleReal Scalar.minusOne)+++raise :: (Shape.C sh, Class.Floating a) => a -> Array sh a -> Array sh a+raise c (Array shX x) =+   Array.unsafeCreateWithSize shX $ \n yPtr -> evalContT $ do       nPtr <- Call.cint n-      saPtr <- Call.number alpha-      sxPtr <- ContT $ withForeignPtr x-      incxPtr <- Call.cint 1-      syPtr <- ContT $ withForeignPtr y-      incyPtr <- Call.cint 1-      inczPtr <- Call.cint 1-      liftIO $ BlasGen.copy nPtr syPtr incyPtr szPtr inczPtr-      liftIO $ BlasGen.axpy nPtr saPtr sxPtr incxPtr szPtr inczPtr+      cPtr <- Call.number c+      onePtr <- Call.number Scalar.one+      inccPtr <- Call.cint 0+      xPtr <- ContT $ withForeignPtr x+      inc1Ptr <- Call.cint 1+      liftIO $ do+         BlasGen.copy nPtr xPtr inc1Ptr yPtr inc1Ptr+         BlasGen.axpy nPtr onePtr cPtr inccPtr yPtr inc1Ptr + mul ::    (Shape.C sh, Eq sh, Class.Floating a) =>    Vector sh a -> Vector sh a -> Vector sh a@@ -482,25 +543,40 @@       Array.unsafeCreateWithSize shX $ \n yPtr -> do    Call.assert "mul: shapes mismatch" (shA == shX)    evalContT $ do-      transPtr <- Call.char 'N'+      aPtr <- ContT $ withForeignPtr a+      xPtr <- ContT $ withForeignPtr x+      liftIO $ Private.mul n aPtr 1 xPtr 1 yPtr 1++divide ::+   (Shape.C sh, Eq sh, Class.Floating a) =>+   Vector sh a -> Vector sh a -> Vector sh a+divide (Array shB b) (Array shA a) =+      Array.unsafeCreateWithSize shB $ \n xPtr -> do+   Call.assert "divide: shapes mismatch" (shA == shB)+   evalContT $ do       nPtr <- Call.cint n       klPtr <- Call.cint 0       kuPtr <- Call.cint 0-      alphaPtr <- Call.number one-      aPtr <- ContT $ withForeignPtr a-      ldaPtr <- Call.leadingDim 1-      xPtr <- ContT $ withForeignPtr x-      incxPtr <- Call.cint 1-      betaPtr <- Call.number zero-      incyPtr <- Call.cint 1-      liftIO $-         BlasGen.gbmv transPtr-            nPtr nPtr klPtr kuPtr alphaPtr aPtr ldaPtr-            xPtr incxPtr betaPtr yPtr incyPtr+      nrhsPtr <- Call.cint 1+      abPtr <- Private.copyToTemp n a+      ldabPtr <- Call.leadingDim 1+      ipivPtr <- Call.allocaArray n+      bPtr <- ContT $ withForeignPtr b+      ldxPtr <- Call.leadingDim n+      liftIO $ do+         Private.copyBlock n bPtr xPtr+         withInfo "gbsv" $+            LapackGen.gbsv nPtr klPtr kuPtr nrhsPtr+               abPtr ldabPtr ipivPtr xPtr ldxPtr +recip :: (Shape.C sh, Class.Floating a) => Vector sh a -> Vector sh a+recip x =+   Vector.recheck $+   divide (Vector.uncheck $ one $ Array.shape x) (Vector.uncheck x) -newtype Conjugate sh a = Conjugate {getConjugate :: Vector sh a -> Vector sh a} +newtype Conjugate f a = Conjugate {getConjugate :: f a -> f a}+ conjugate ::    (Shape.C sh, Class.Floating a) =>    Vector sh a -> Vector sh a@@ -552,14 +628,14 @@    (Shape.C sh, Class.Real a) => Vector sh a -> Vector sh (Complex a) complexFromReal (Array sh x) =    Array.unsafeCreateWithSize sh $ \n yPtr ->-   case castPtr yPtr of+   case realPtr yPtr of       yrPtr -> evalContT $ do          nPtr <- Call.cint n          xPtr <- ContT $ withForeignPtr x          incxPtr <- Call.cint 1          incyPtr <- Call.cint 2          inczPtr <- Call.cint 0-         zPtr <- Call.number zero+         zPtr <- Call.number Scalar.zero          liftIO $ do             BlasGen.copy nPtr xPtr incxPtr yrPtr incyPtr             BlasGen.copy nPtr zPtr inczPtr (advancePtr yrPtr 1) incyPtr@@ -572,12 +648,16 @@    Class.switchFloating       (ToReal id)       (ToReal id)-      (ToReal complexToRealPart)-      (ToReal complexToRealPart)+      (ToReal $ RowMajor.takeColumn RealPart . decomplex)+      (ToReal $ RowMajor.takeColumn RealPart . decomplex)  newtype ToReal f a = ToReal {getToReal :: f a -> f (RealOf a)} +imaginaryPart ::+   (Shape.C sh, Class.Real a) => Vector sh (Complex a) -> Vector sh a+imaginaryPart = RowMajor.takeColumn ImaginaryPart . decomplex + zipComplex ::    (Shape.C sh, Eq sh, Class.Real a) =>    Vector sh a -> Vector sh a -> Vector sh (Complex a)@@ -587,35 +667,17 @@       nPtr <- Call.cint n       xrPtr <- ContT $ withForeignPtr xr       xiPtr <- ContT $ withForeignPtr xi-      let yrPtr = castPtr yPtr+      let yrPtr = realPtr yPtr       incxPtr <- Call.cint 1       incyPtr <- Call.cint 2       liftIO $ do          BlasGen.copy nPtr xrPtr incxPtr yrPtr incyPtr          BlasGen.copy nPtr xiPtr incxPtr (advancePtr yrPtr 1) incyPtr --complexToRealPart, complexToImaginaryPart ::-   (Shape.C sh, Class.Real a) => Vector sh (Complex a) -> Vector sh a-complexToRealPart = complexToPart 0-complexToImaginaryPart = complexToPart 1--complexToPart ::-   (Shape.C sh, Class.Real a) => Int -> Vector sh (Complex a) -> Vector sh a-complexToPart offset (Array sh x) =-   Array.unsafeCreateWithSize sh $ \n yPtr -> evalContT $ do-      nPtr <- Call.cint n-      xPtr <- ContT $ withForeignPtr x-      incxPtr <- Call.cint 2-      incyPtr <- Call.cint 1-      liftIO $-         BlasGen.copy nPtr-            (advancePtr (castPtr xPtr) offset) incxPtr yPtr incyPtr- unzipComplex ::    (Shape.C sh, Class.Real a) =>    Vector sh (Complex a) -> (Vector sh a, Vector sh a)-unzipComplex x = (complexToRealPart x, complexToImaginaryPart x)+unzipComplex x = (realPart x, imaginaryPart x)   data RandomDistribution =@@ -639,7 +701,7 @@       nPtr <- Call.cint n       distPtr <-          Call.cint $-         case (getConst $ isComplexInFunctor xPtr, dist) of+         case (Private.caseRealComplexFunc xPtr False True, dist) of             (_, UniformBox01) -> 1             (_, UniformBoxPM1) -> 2             (_, Normal) -> 3@@ -656,7 +718,3 @@          pokeElemOff iseedPtr 2 $ fromIntegral ((seed `shiftR` 11) .&. 0xFFF)          pokeElemOff iseedPtr 3 $ fromIntegral ((seed.&.0x7FF)*2+1)          LapackGen.larnv distPtr iseedPtr nPtr xPtr--isComplexInFunctor :: (Class.Floating a) => f a -> Const Bool a-isComplexInFunctor _ =-   Class.switchFloating (Const False) (Const False) (Const True) (Const True)
+ src/Numeric/LAPACK/Vector/Private.hs view
@@ -0,0 +1,55 @@+module Numeric.LAPACK.Vector.Private where++import qualified Numeric.LAPACK.Shape.Private as ShapePriv++import qualified Numeric.LAPACK.FFI.Complex as LapackComplex+import qualified Numeric.BLAS.FFI.Generic as BlasGen+import qualified Numeric.Netlib.Utility as Call+import qualified Numeric.Netlib.Class as Class++import Foreign.ForeignPtr (withForeignPtr)+import Foreign.Ptr (Ptr)+import Foreign.C.Types (CInt)++import Control.Monad.Trans.Cont (ContT(ContT), evalContT)+import Control.Monad.IO.Class (liftIO)++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))+++mac ::+   (Shape.C sh, Class.Floating a) =>+   a -> Array sh a -> Array sh a -> Array sh a+mac alpha (Array shX x) (Array _shY y) =+   Array.unsafeCreateWithSize shX $ \n szPtr -> evalContT $ do+      nPtr <- Call.cint n+      saPtr <- Call.number alpha+      sxPtr <- ContT $ withForeignPtr x+      incxPtr <- Call.cint 1+      syPtr <- ContT $ withForeignPtr y+      incyPtr <- Call.cint 1+      inczPtr <- Call.cint 1+      liftIO $ BlasGen.copy nPtr syPtr incyPtr szPtr inczPtr+      liftIO $ BlasGen.axpy nPtr saPtr sxPtr incxPtr szPtr inczPtr+++newtype ArgMaximum a =+   ArgMaximum {runArgMaximum :: Ptr CInt -> Ptr a -> Ptr CInt -> IO CInt}++absMax :: Class.Floating a => Ptr CInt -> Ptr a -> Ptr CInt -> IO CInt+absMax =+   runArgMaximum $+   Class.switchFloating+      (ArgMaximum BlasGen.iamax)+      (ArgMaximum BlasGen.iamax)+      (ArgMaximum LapackComplex.imax1)+      (ArgMaximum LapackComplex.imax1)+++uncheck :: Array sh a -> Array (ShapePriv.Unchecked sh) a+uncheck = Array.mapShape ShapePriv.Unchecked++recheck :: Array (ShapePriv.Unchecked sh) a -> Array sh a+recheck = Array.mapShape ShapePriv.deconsUnchecked
test/Main.hs view
@@ -8,10 +8,12 @@ import qualified Test.Hermitian as Hermitian import qualified Test.Banded as Banded import qualified Test.BandedHermitian as BandedHermitian+import qualified Test.LowerUpper as LowerUpper import qualified Test.Orthogonal as Orthogonal import qualified Test.Singular as Singular import qualified Test.Shape as Shape import qualified Test.Permutation as Permutation+import qualified Test.Example as Example import Test.Format () import Test.Utility (Tagged(Tagged), prefix) @@ -41,6 +43,7 @@    prefix "Banded" Banded.testsVar ++    prefix "BandedHermitian" BandedHermitian.testsVar ++    prefix "Permutation" Permutation.testsVar +++   prefix "LowerUpper" LowerUpper.testsVar ++    prefix "Orthogonal" Orthogonal.testsVar ++    prefix "Singular" Singular.testsVar ++    []@@ -64,6 +67,7 @@ simpleTests =    prefix "Shape" Shape.tests ++    prefix "Permutation" Permutation.tests +++   prefix "Example" Example.tests ++    []  main :: IO ()
test/Test/Banded.hs view
@@ -4,24 +4,25 @@ {-# LANGUAGE GADTs #-} module Test.Banded (testsVar) where +import qualified Test.Divide as Divide import qualified Test.Indexed as Indexed import qualified Test.Generator as Gen import qualified Test.Utility as Util import Test.Banded.Utility-         (Square(Square), genSquare, genSquareCond,+         (Square(Square), genSquare, shapeBandedFromFull,           offDiagonals, offDiagonalNats)-import Test.Generator ((<.*|>), (<|*.>), (<.*.>), (<|*|>), (<|\|>))+import Test.Generator ((<-*#>), (<#*|>), (<-*|>), (<#*#>), (<#\#>))+import Test.Logic (Dim) import Test.Utility-         (approx, approxArray, approxMatrix,-          genOrder, genArray, Tagged, equalListWith)+         (approx, approxArray, approxMatrix, approxVector,+          genArray, Tagged, equalListWith)  import qualified Numeric.LAPACK.Matrix.Banded as Banded-import qualified Numeric.LAPACK.Matrix.Shape.Box as Box import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape import qualified Numeric.LAPACK.Matrix.Square as Square import qualified Numeric.LAPACK.Matrix as Matrix import qualified Numeric.LAPACK.Vector as Vector-import Numeric.LAPACK.Matrix (ZeroInt, (<#>), (<#), (#>))+import Numeric.LAPACK.Matrix (ShapeInt, (#*##), (-*#), (#*|)) import Numeric.LAPACK.Vector (Vector) import Numeric.LAPACK.Scalar (RealOf, absolute) @@ -32,13 +33,14 @@ import qualified Type.Data.Num.Unary as Unary import Type.Data.Num.Unary (unary, (:+:)) -import qualified Data.Array.Comfort.Storable as Array import qualified Data.Array.Comfort.Shape as Shape  import Foreign.Storable (Storable)  import Control.Applicative ((<$>)) +import Data.Tuple.HT (mapSnd)+ import qualified Test.QuickCheck as QC  @@ -55,20 +57,19 @@   genBanded ::-   (Class.Floating a) => Gen.Matrix a Int Int (Banded ZeroInt ZeroInt a)-genBanded =-      flip Gen.mapGenDim Gen.matrixDims $ \maxElem maxDim (height,width) -> do-   order <- genOrder+   (Dim height, Dim width, Class.Floating a) =>+   Gen.Matrix height width a (Banded height width a)+genBanded = flip Gen.mapGenDim Gen.matrixShape $ \maxElem maxDim shape -> do    kl <- QC.choose (0, toInteger maxDim)    ku <- QC.choose (0, toInteger maxDim)    Unary.reifyNatural kl $ \sub ->       Unary.reifyNatural ku $ \super ->       fmap Banded $ genArray maxElem $-         MatrixShape.bandedGeneral (unary sub, unary super) order height width+      shapeBandedFromFull (unary sub, unary super) shape  multiplyFullIdentity ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Banded ZeroInt ZeroInt a -> Bool+   Banded ShapeInt ShapeInt a -> Bool multiplyFullIdentity (Banded m) =    let a = Banded.toFull m    in approxArray a $@@ -77,18 +78,18 @@  multiplyVectorDot ::    (Class.Floating a, Eq a) =>-   (Vector ZeroInt a,-    Banded ZeroInt ZeroInt a,-    Vector ZeroInt a) ->+   (Vector ShapeInt a,+    Banded ShapeInt ShapeInt a,+    Vector ShapeInt a) ->    Bool multiplyVectorDot (x, Banded m, y) =-   Vector.dot x (m#>y) == Vector.dot (x<#m) y+   Vector.dot x (m#*|y) == Vector.dot (x-*#m) y   multiplyFullAny ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Banded ZeroInt ZeroInt a,-    Matrix.General ZeroInt ZeroInt a) ->+   (Banded ShapeInt ShapeInt a,+    Matrix.General ShapeInt ShapeInt a) ->    Bool multiplyFullAny (Banded a, b) =    approxArray@@ -97,20 +98,20 @@  multiplyFullColumns ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Banded ZeroInt ZeroInt a,-    Matrix.General ZeroInt ZeroInt a) ->+   (Banded ShapeInt ShapeInt a,+    Matrix.General ShapeInt ShapeInt a) ->    Bool multiplyFullColumns (Banded a, b) =-   equalListWith approxArray+   equalListWith approxVector       (Matrix.toColumns (Banded.multiplyFull a b))       (map (Banded.multiplyVector a) (Matrix.toColumns b))   multiplyFullAssoc ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Banded ZeroInt ZeroInt a,-    Matrix.General ZeroInt ZeroInt a,-    Matrix.General ZeroInt ZeroInt a) ->+   (Banded ShapeInt ShapeInt a,+    Matrix.General ShapeInt ShapeInt a,+    Matrix.General ShapeInt ShapeInt a) ->    Bool multiplyFullAssoc (Banded a, b, c) =    approxArray@@ -129,8 +130,8 @@  multiplyBanded ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Banded ZeroInt ZeroInt a,-    Banded ZeroInt ZeroInt a) ->+   (Banded ShapeInt ShapeInt a,+    Banded ShapeInt ShapeInt a) ->    Bool multiplyBanded (Banded a, Banded b) =    case addOffDiagonals a b of@@ -141,21 +142,21 @@  multiplyBandedVectorAssoc ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Banded ZeroInt ZeroInt a,-    Banded ZeroInt ZeroInt a,-    Vector ZeroInt a) ->+   (Banded ShapeInt ShapeInt a,+    Banded ShapeInt ShapeInt a,+    Vector ShapeInt a) ->    Bool multiplyBandedVectorAssoc (Banded a, Banded b, x) =    case addOffDiagonals a b of       (Proof.Nat, Proof.Nat) ->-         approxArray (a #> b #> x) (Banded.multiply a b #> x)+         approxVector (a #*| b #*| x) (Banded.multiply a b #*| x)   multiplyBandedAssoc ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Banded ZeroInt ZeroInt a,-    Banded ZeroInt ZeroInt a,-    Banded ZeroInt ZeroInt a) ->+   (Banded ShapeInt ShapeInt a,+    Banded ShapeInt ShapeInt a,+    Banded ShapeInt ShapeInt a) ->    Bool multiplyBandedAssoc (Banded a, Banded b, Banded c) =    let ab = Banded.multiply a b@@ -181,51 +182,50 @@       Show (Upper size a) where    showsPrec p (Upper a) = showsPrec p a -genUpper :: (Class.Floating a) => Gen.Matrix a Int Int (Upper ZeroInt a)-genUpper = flip Gen.mapGenDim Gen.squareDim $ \maxElem maxDim size -> do-   order <- genOrder+genUpper :: (Class.Floating a) => Gen.MatrixInt a (Upper ShapeInt a)+genUpper = flip Gen.mapGenDim Gen.squareShape $ \maxElem maxDim shape -> do    ku <- QC.choose (0, toInteger maxDim)    Unary.reifyNatural ku $ \super ->       fmap Upper $ genArray maxElem $-      MatrixShape.bandedSquare (unary TypeNum.u0, unary super) order size+      shapeBandedFromFull (unary TypeNum.u0, unary super) shape  multiplyUpperVector ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Upper ZeroInt a, Vector ZeroInt a) -> Bool+   (Upper ShapeInt a, Vector ShapeInt a) -> Bool multiplyUpperVector (Upper m, x) =-   approxArray (m#>x) (Banded.toUpperTriangular m #> x)+   approxVector (m#*|x) (Banded.toUpperTriangular m #*| x)  multiplyLowerVector ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Upper ZeroInt a, Vector ZeroInt a) -> Bool+   (Upper ShapeInt a, Vector ShapeInt a) -> Bool multiplyLowerVector (Upper up, x) =    let lo = Banded.transpose up-   in approxArray (lo#>x) (Banded.toLowerTriangular lo #> x)+   in approxVector (lo#*|x) (Banded.toLowerTriangular lo #*| x)   determinant ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool+   Square ShapeInt a -> Bool determinant (Square a) =    approx 0.5 (Banded.determinant a) (Square.determinant $ Banded.toFull a)   invertible ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool+   Square ShapeInt a -> Bool invertible (Square a) = absolute (Banded.determinant a) > 0.1  multiplySolve ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Square ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Square ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool multiplySolve (Square a, b) =-   approxMatrix 1e-2 (a <#> Banded.solve a b) b+   approxMatrix 1e-2 (a #*## Banded.solve a b) b    checkForAll ::    (Show a, QC.Testable test) =>-   Gen.T tag dim a -> (a -> test) -> Tagged tag QC.Property+   Gen.T dim tag a -> (a -> test) -> Tagged tag QC.Property checkForAll gen = Util.checkForAll (Gen.run gen 10 5)  @@ -236,41 +236,47 @@    ("index",       checkForAll          (Indexed.genMatrixIndexGen-            (\(Banded arr) -> Box.indices $ Array.shape arr)+            (\(Banded arr) -> Matrix.indices arr)             genBanded)          (\(mix, Banded arr) -> Indexed.unitDot (mix, arr))) :     ("multiplyFullIdentity",       checkForAll genBanded multiplyFullIdentity) :    ("multiplyFullAny",-      checkForAll ((,) <$> genBanded <|*|> Gen.matrix) multiplyFullAny) :+      checkForAll ((,) <$> genBanded <#*#> Gen.matrix) multiplyFullAny) :    ("multiplyVectorDot",       checkForAll-         ((,,) <$> Gen.vector <.*|> genBanded <.*.> Gen.vector)+         ((,,) <$> Gen.vector <-*#> genBanded <-*|> Gen.vector)          multiplyVectorDot) :    ("multiplyFullColumns",-      checkForAll ((,) <$> genBanded <|*|> Gen.matrix) multiplyFullColumns) :+      checkForAll ((,) <$> genBanded <#*#> Gen.matrix) multiplyFullColumns) :    ("multiplyFullAssoc",       checkForAll-         ((,,) <$> genBanded <|*|> Gen.matrix <|*|> Gen.matrix)+         ((,,) <$> genBanded <#*#> Gen.matrix <#*#> Gen.matrix)          multiplyFullAssoc) :    ("multiplyBanded",-      checkForAll ((,) <$> genBanded <|*|> genBanded) multiplyBanded) :+      checkForAll ((,) <$> genBanded <#*#> genBanded) multiplyBanded) :    ("multiplyBandedVectorAssoc",       checkForAll-         ((,,) <$> genBanded <|*|> genBanded <|*.> Gen.vector)+         ((,,) <$> genBanded <#*#> genBanded <#*|> Gen.vector)          multiplyBandedVectorAssoc) :    ("multiplyBandedAssoc",       checkForAll-         ((,,) <$> genBanded <|*|> genBanded <|*|> genBanded)+         ((,,) <$> genBanded <#*#> genBanded <#*#> genBanded)          multiplyBandedAssoc) :    ("multiplyUpperVector",-      checkForAll ((,) <$> genUpper <|*.> Gen.vector) multiplyUpperVector) :+      checkForAll ((,) <$> genUpper <#*|> Gen.vector) multiplyUpperVector) :    ("multiplyLowerVector",-      checkForAll ((,) <$> genUpper <|*.> Gen.vector) multiplyLowerVector) :+      checkForAll ((,) <$> genUpper <#*|> Gen.vector) multiplyLowerVector) :    ("determinant",       checkForAll genSquare determinant) :    ("multiplySolve",       checkForAll-         ((,) <$> genSquareCond invertible <|\|> Gen.matrix) multiplySolve) :+         ((,) <$> Gen.condition invertible genSquare <#\#> Gen.matrix)+         multiplySolve) :+   map+      (mapSnd+         ($ ((\(Square m) -> Divide.SquareMatrix m)+               <$> Gen.condition invertible genSquare)))+      Divide.testsVarAny ++    []
test/Test/Banded/Utility.hs view
@@ -2,12 +2,13 @@ module Test.Banded.Utility where  import qualified Test.Generator as Gen-import Test.Utility (genOrder, genArray)+import Test.Utility (genArray)  import qualified Numeric.LAPACK.Matrix.Banded as Banded+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape import Numeric.LAPACK.Matrix.Shape (UnaryProxy)-import Numeric.LAPACK.Matrix (ZeroInt)+import Numeric.LAPACK.Matrix (ShapeInt)  import qualified Numeric.Netlib.Class as Class @@ -16,7 +17,6 @@ import Type.Data.Num.Unary (unary) import Type.Base.Proxy (Proxy(Proxy)) -import qualified Data.Array.Comfort.Storable as Array import qualified Data.Array.Comfort.Shape as Shape  import Foreign.Storable (Storable)@@ -33,7 +33,7 @@ offDiagonals ::    Banded.Banded sub super vert horiz height width a ->    (UnaryProxy sub, UnaryProxy super)-offDiagonals = MatrixShape.bandedOffDiagonals . Array.shape+offDiagonals = MatrixShape.bandedOffDiagonals . ArrMatrix.shape  offDiagonalNats ::    (Unary.Natural sub, Unary.Natural super) =>@@ -42,6 +42,14 @@ offDiagonalNats = mapPair (natFromProxy, natFromProxy) . offDiagonals  +shapeBandedFromFull ::+   (MatrixShape.UnaryProxy sub, MatrixShape.UnaryProxy super) ->+   MatrixShape.Full vert horiz height width ->+   MatrixShape.Banded sub super vert horiz height width+shapeBandedFromFull klu (MatrixShape.Full order extent) =+   MatrixShape.Banded klu order extent++ data Square size a =    forall sub super.    (Unary.Natural sub, Unary.Natural super) =>@@ -52,22 +60,11 @@       Show (Square size a) where    showsPrec p (Square a) = showsPrec p a -genSquare :: (Class.Floating a) => Gen.Matrix a Int Int (Square ZeroInt a)-genSquare = genSquareCond (const True)--genSquareCond ::-   (Class.Floating a) =>-   (Square ZeroInt a -> Bool) ->-   Gen.Matrix a Int Int (Square ZeroInt a)-genSquareCond cond =-      flip Gen.mapGenDim Gen.squareDim $ \maxElem maxDim size -> do-   order <- genOrder+genSquare :: (Class.Floating a) => Gen.MatrixInt a (Square ShapeInt a)+genSquare = flip Gen.mapGenDim Gen.squareShape $ \maxElem maxDim shape -> do    kl <- QC.choose (0, toInteger maxDim)    ku <- QC.choose (0, toInteger maxDim)    Unary.reifyNatural kl $ \sub ->       Unary.reifyNatural ku $ \super ->-      (fmap Square $-         genArray maxElem $-            MatrixShape.bandedSquare (unary sub, unary super) order size)-      `QC.suchThat`-      cond+      fmap Square $+         genArray maxElem $ shapeBandedFromFull (unary sub, unary super) shape
test/Test/BandedHermitian.hs view
@@ -5,28 +5,33 @@ {-# LANGUAGE GADTs #-} module Test.BandedHermitian (testsVar) where +import qualified Test.Divide as Divide import qualified Test.Indexed as Indexed import qualified Test.Generator as Gen import qualified Test.Utility as Util import Test.Banded.Utility-         (Square(Square), genSquare, natFromProxy, offDiagonalNats)-import Test.Generator ((<.*|>), (<|*.>), (<.*.>), (<|*|>), (<|\|>))+         (Square(Square), genSquare, shapeBandedFromFull,+          natFromProxy, offDiagonalNats)+import Test.Generator ((<-*#>), (<#*|>), (<-*|>), (<#*#>), (<#\#>))+import Test.Logic (Dim) import Test.Utility-         (approxReal, approxArray, approxRealArrayTol, approxMatrix,-          genOrder, genArray, Tagged, equalListWith)+         (approxReal, approxArray, approxRealVectorTol, approxMatrix,+          approxVector,+          genOrder, genArray, genVector, Tagged, equalListWith)  import qualified Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite                                                        as BandedHermitianPD import qualified Numeric.LAPACK.Matrix.BandedHermitian as BandedHermitian import qualified Numeric.LAPACK.Matrix.Banded as Banded import qualified Numeric.LAPACK.Matrix.Hermitian as Hermitian-import qualified Numeric.LAPACK.Matrix.Shape.Box as Box import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape+import qualified Numeric.LAPACK.Matrix.Extent as Extent import qualified Numeric.LAPACK.Matrix.Square as Square+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix as Matrix import qualified Numeric.LAPACK.Vector as Vector import qualified Numeric.LAPACK.ShapeStatic as ShapeStatic-import Numeric.LAPACK.Matrix (ZeroInt, zeroInt, (<#>), (<#), (#>))+import Numeric.LAPACK.Matrix (ShapeInt, shapeInt, (#*#), (#*##), (-*#), (#*|)) import Numeric.LAPACK.Vector (Vector) import Numeric.LAPACK.Scalar (RealOf, fromReal, absolute, selectReal) @@ -45,6 +50,7 @@  import qualified Data.List.HT as ListHT import Data.Tuple.HT (mapSnd)+import Data.Semigroup ((<>))  import qualified Test.QuickCheck as QC @@ -60,28 +66,34 @@    showsPrec p (BandedHermitian a) = showsPrec p a  +shapeBandedHermitianFromSquare ::+   (MatrixShape.UnaryProxy off) ->+   MatrixShape.Square size -> MatrixShape.BandedHermitian off size+shapeBandedHermitianFromSquare k (MatrixShape.Full order extent) =+   MatrixShape.BandedHermitian k order $ Extent.height extent++ {- Non-real elements on the diagonal. -} _genBandedHermitian ::-   (Class.Floating a) => Gen.Matrix a Int Int (BandedHermitian ZeroInt a)+   (Class.Floating a) => Gen.MatrixInt a (BandedHermitian ShapeInt a) _genBandedHermitian =-      flip Gen.mapGenDim Gen.squareDim $ \maxElem maxDim size -> do-   order <- genOrder+      flip Gen.mapGenDim Gen.squareShape $ \maxElem maxDim shape -> do    k <- QC.choose (0, toInteger maxDim)    Unary.reifyNatural k $ \numOff ->       fmap BandedHermitian $ genArray maxElem $-         MatrixShape.bandedHermitian (unary numOff) order size+         shapeBandedHermitianFromSquare (unary numOff) shape  genBandedHermitian ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Gen.Matrix a Int Int (BandedHermitian ZeroInt a)+   (Dim sh, Shape.Indexed sh, Shape.Index sh ~ ix, Eq ix,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Gen.Square sh a (BandedHermitian sh a) genBandedHermitian =-      flip Gen.mapGenDim Gen.squareDim $ \maxElem maxDim size -> do-   order <- genOrder+      flip Gen.mapGenDim Gen.squareShape $ \maxElem maxDim sqShape -> do    k <- QC.choose (0, toInteger maxDim)    Unary.reifyNatural k $ \numOff -> do-      let shape = MatrixShape.bandedHermitian (unary numOff) order size+      let shape = shapeBandedHermitianFromSquare (unary numOff) sqShape       BandedHermitian <$>          (Util.genArrayIndexed shape $ \ix ->             let real =@@ -97,7 +109,7 @@  convertToFull ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   BandedHermitian ZeroInt a -> Bool+   BandedHermitian ShapeInt a -> Bool convertToFull (BandedHermitian a) =    approxArray       (Hermitian.toSquare $ BandedHermitian.toHermitian a)@@ -105,22 +117,22 @@  takeDiagonal ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   BandedHermitian ZeroInt a -> Bool+   BandedHermitian ShapeInt a -> Bool takeDiagonal (BandedHermitian a) =-   approxRealArrayTol 1e-5+   approxRealVectorTol 1e-5       (Hermitian.takeDiagonal $ BandedHermitian.toHermitian a)       (BandedHermitian.takeDiagonal a) -covariance ::+gramian ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool-covariance (Square a) =+   Square ShapeInt a -> Bool+gramian (Square a) =    let (sub,super) = offDiagonalNats a    in case (Proof.addNat sub super, Proof.addComm sub super) of          (Proof.Nat, Proof.AddComm) ->             approxArray-               (BandedHermitian.toBanded $ BandedHermitian.covariance a)-               (Banded.adjoint a <#> a)+               (BandedHermitian.toBanded $ BandedHermitian.gramian a)+               (Banded.adjoint a #*# a)   @@ -139,7 +151,7 @@  genScaledVectors ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Gen.Vector a Int (SumRank1 ZeroInt a)+   Gen.VectorInt a (SumRank1 ShapeInt a) genScaledVectors =    flip Gen.mapGen Gen.vectorDim $ \maxElem size@(Shape.ZeroBased n) -> do       k <- QC.choose (0, n-1)@@ -151,12 +163,12 @@                QC.listOf $                   liftA2 (,) (Util.genReal maxElem) $                   liftA2 (,) (QC.choose (0,n-k-1))-                     (Util.genArray maxElem+                     (genVector maxElem                         (ShapeStatic.ZeroBased $ unary $ Unary.succ numOff))  sumRank1 ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   MatrixShape.Order -> SumRank1 ZeroInt a -> Bool+   MatrixShape.Order -> SumRank1 ShapeInt a -> Bool sumRank1 order (SumRank1 sh xs) =    approxArray       (BandedHermitian.toHermitian $ BandedHermitian.sumRank1 order sh xs)@@ -165,19 +177,19 @@  displace ::    (Shape.C sh, Class.Floating a) =>-   ZeroInt -> Int -> Vector sh a -> Vector ZeroInt a+   ShapeInt -> Int -> Vector sh a -> Vector ShapeInt a displace (Shape.ZeroBased n) k a =-   Array.mapShape (zeroInt . Shape.size) $-      Vector.constant (zeroInt k) 0+   Array.mapShape (shapeInt . Shape.size) $+      Vector.zero (shapeInt k)       `Vector.append`       a       `Vector.append`-      Vector.constant (zeroInt $ max 0 $ n - k - Shape.size (Array.shape a)) 0+      Vector.zero (shapeInt $ max 0 $ n - k - Shape.size (Array.shape a))   multiplyIdentity ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Hermitian.Transposition -> Matrix.General ZeroInt ZeroInt a -> Bool+   Hermitian.Transposition -> Matrix.General ShapeInt ShapeInt a -> Bool multiplyIdentity trans m =    approxArray m       (BandedHermitian.multiplyFull trans@@ -186,7 +198,7 @@ multiplyDiagonal ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    Hermitian.Transposition ->-   (Vector ZeroInt ar, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Vector ShapeInt ar, Matrix.General ShapeInt ShapeInt a) -> Bool multiplyDiagonal trans (d,m) =    approxArray       (Matrix.scaleRowsReal d m)@@ -194,7 +206,7 @@  multiplyFullIdentity ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   BandedHermitian ZeroInt a -> Bool+   BandedHermitian ShapeInt a -> Bool multiplyFullIdentity (BandedHermitian m) =    let a = Banded.toFull $ BandedHermitian.toBanded m    in approxArray a $@@ -205,25 +217,25 @@ multiplyHermitianVector ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    Hermitian.Transposition ->-   (BandedHermitian ZeroInt a, Vector ZeroInt a) ->+   (BandedHermitian ShapeInt a, Vector ShapeInt a) ->    Bool multiplyHermitianVector trans (BandedHermitian m, x) =-   approxArray+   approxVector       (BandedHermitian.multiplyVector trans m x)       (Hermitian.multiplyVector trans (BandedHermitian.toHermitian m) x)  multiplyVectorDot ::    (Class.Floating a, Eq a) =>-   (Vector ZeroInt a, BandedHermitian ZeroInt a, Vector ZeroInt a) -> Bool+   (Vector ShapeInt a, BandedHermitian ShapeInt a, Vector ShapeInt a) -> Bool multiplyVectorDot (x, BandedHermitian m, y) =-   Vector.dot x (m#>y) == Vector.dot (x<#m) y+   Vector.dot x (m#*|y) == Vector.dot (x-*#m) y   multiplyFullAny ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    Hermitian.Transposition ->-   (BandedHermitian ZeroInt a,-    Matrix.General ZeroInt ZeroInt a) ->+   (BandedHermitian ShapeInt a,+    Matrix.General ShapeInt ShapeInt a) ->    Bool multiplyFullAny trans (BandedHermitian a, b) =    approxArray@@ -233,9 +245,9 @@ multiplyFullColumns ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    BandedHermitian.Transposition ->-   (BandedHermitian ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (BandedHermitian ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool multiplyFullColumns trans (BandedHermitian a, b) =-   equalListWith approxArray+   equalListWith approxVector       (Matrix.toColumns (BandedHermitian.multiplyFull trans a b))       (map (BandedHermitian.multiplyVector trans a) (Matrix.toColumns b)) @@ -243,9 +255,9 @@ multiplyFullAssoc ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    BandedHermitian.Transposition ->-   (BandedHermitian ZeroInt a,-    Matrix.General ZeroInt ZeroInt a,-    Matrix.General ZeroInt ZeroInt a) ->+   (BandedHermitian ShapeInt a,+    Matrix.General ShapeInt ShapeInt a,+    Matrix.General ShapeInt ShapeInt a) ->    Bool multiplyFullAssoc trans (BandedHermitian a, b, c) =    approxArray@@ -256,9 +268,8 @@  genBandedHPD ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Gen.Matrix a Int Int (BandedHermitian ZeroInt a)-genBandedHPD = flip Gen.mapGenDim Gen.squareDim $ \maxElem maxDim size -> do-   order <- genOrder+   Gen.MatrixInt a (BandedHermitian ShapeInt a)+genBandedHPD = flip Gen.mapGenDim Gen.squareShape $ \maxElem maxDim shape -> do    kl <- QC.choose (0, toInteger maxDim)    ku <- QC.choose (0, toInteger maxDim)    Unary.reifyNatural kl $ \subU ->@@ -267,16 +278,15 @@           super = unary superU; superP = natFromProxy super       in case (Proof.addNat subP superP, Proof.addComm subP superP) of             (Proof.Nat, Proof.AddComm) ->-               fmap (BandedHermitian . BandedHermitian.covariance) $-                  (genArray maxElem $-                     MatrixShape.bandedSquare (sub, super) order size)+               fmap (BandedHermitian . BandedHermitian.gramian) $+                  (genArray maxElem $ shapeBandedFromFull (sub, super) shape)                   `QC.suchThat`                   (\a -> absolute (Banded.determinant a) > 0.1)   determinant ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   BandedHermitian ZeroInt a -> Bool+   BandedHermitian ShapeInt a -> Bool determinant (BandedHermitian a) =    let detB = BandedHermitianPD.determinant a        detS = Hermitian.determinant $ BandedHermitian.toHermitian a@@ -285,13 +295,13 @@  multiplySolve ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (BandedHermitian ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (BandedHermitian ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool multiplySolve (BandedHermitian a, b) =-   approxMatrix (selectReal 10 1e-3) (a <#> BandedHermitianPD.solve a b) b+   approxMatrix (selectReal 10 1e-3) (a #*## BandedHermitianPD.solve a b) b  solveDecomposed ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (BandedHermitian ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (BandedHermitian ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool solveDecomposed (BandedHermitian a, b) =    approxMatrix (selectReal 1e-3 1e-7)       (BandedHermitianPD.solve a b)@@ -301,7 +311,7 @@  eigenvaluesDeterminant ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   BandedHermitian ZeroInt a -> Bool+   BandedHermitian ShapeInt a -> Bool eigenvaluesDeterminant (BandedHermitian a) =    let det = BandedHermitianPD.determinant a        prod = Vector.product $ BandedHermitian.eigenvalues a@@ -309,48 +319,49 @@  eigensystem ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   BandedHermitian ZeroInt a -> Bool+   BandedHermitian ShapeInt a -> Bool eigensystem (BandedHermitian a) =    let (q,d) = BandedHermitian.eigensystem a    in  approxMatrix 1e-4          (Banded.toFull $ BandedHermitian.toBanded a)-         (q <#> Matrix.scaleRowsReal d (Square.adjoint q))+         (q <> Matrix.scaleRowsReal d (Square.adjoint q))  eigenvaluesHermitian ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   BandedHermitian ZeroInt a -> Bool+   BandedHermitian ShapeInt a -> Bool eigenvaluesHermitian (BandedHermitian a) =-   approxRealArrayTol (selectReal 1e-3 1e-5)+   approxRealVectorTol (selectReal 1e-3 1e-5)       (BandedHermitian.eigenvalues a)       (Hermitian.eigenvalues $ BandedHermitian.toHermitian a)  eigensystemHermitian ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   BandedHermitian ZeroInt a -> QC.Property+   BandedHermitian ShapeInt a -> QC.Property eigensystemHermitian (BandedHermitian a) =    let (q0,d0) = BandedHermitian.eigensystem a        (q1,d1) = Hermitian.eigensystem $ BandedHermitian.toHermitian a-       unit = Matrix.adjoint q0 <#> q1+       unit = Matrix.adjoint q0 <> q1        tol = selectReal 1e-4 1e-7    in not (or (ListHT.mapAdjacent (approxReal 0.1) (Array.toList d0)))       QC.==>-      approxRealArrayTol tol d0 d1+      approxRealVectorTol tol d0 d1       &&       and          (zipWith             (\(r,c) x -> approxReal tol (absolute x) $ if r==c then 1 else 0)-            (Shape.indices $ Array.shape unit) (Array.toList unit))+            (Shape.indices $ ArrMatrix.shape unit)+            (Array.toList $ ArrMatrix.toVector unit))    checkForAll ::    (Show a, QC.Testable test) =>-   Gen.T tag dim a -> (a -> test) -> Tagged tag QC.Property+   Gen.T dim tag a -> (a -> test) -> Tagged tag QC.Property checkForAll gen = Util.checkForAll (Gen.run gen 6 5)  checkForAllExtra ::    (Show a, Show b, QC.Testable test) =>-   QC.Gen a -> Gen.T tag dim b ->+   QC.Gen a -> Gen.T dim tag b ->    (a -> b -> test) -> Tagged tag QC.Property checkForAllExtra = Gen.withExtra checkForAll @@ -363,7 +374,7 @@    ("index",       checkForAll          (Indexed.genMatrixIndexGen-            (\(BandedHermitian arr) -> Box.indices $ Array.shape arr)+            (\(BandedHermitian arr) -> Matrix.indices arr)             genBandedHermitian)          (\(mix, BandedHermitian arr) -> Indexed.unitDot (mix, arr))) :    ("convertToFull",@@ -372,40 +383,44 @@       checkForAll genBandedHermitian takeDiagonal) :    ("sumRank1",       checkForAllExtra genOrder genScaledVectors sumRank1) :-   ("covariance",-      checkForAll genSquare covariance) :+   ("gramian",+      checkForAll genSquare gramian) :    ("multiplyIdentity",       checkForAllExtra QC.arbitraryBoundedEnum Gen.matrix multiplyIdentity) :    ("multiplyDiagonal",       checkForAllExtra QC.arbitraryBoundedEnum-         ((,) <$> Gen.vectorReal <.*|> Gen.matrix) multiplyDiagonal) :+         ((,) <$> Gen.vectorReal <-*#> Gen.matrix) multiplyDiagonal) :    ("multiplyFullIdentity",       checkForAll genBandedHermitian multiplyFullIdentity) :    ("multiplyFullAny",       checkForAllExtra QC.arbitraryBoundedEnum-         ((,) <$> genBandedHermitian <|*|> Gen.matrix) multiplyFullAny) :+         ((,) <$> genBandedHermitian <#*#> Gen.matrix) multiplyFullAny) :    ("multiplyHermitianVector",       checkForAllExtra QC.arbitraryBoundedEnum-         ((,) <$> genBandedHermitian <|*.> Gen.vector)+         ((,) <$> genBandedHermitian <#*|> Gen.vector)          multiplyHermitianVector) :    ("multiplyVectorDot",       checkForAll-         ((,,) <$> Gen.vector <.*|> genBandedHermitian <.*.> Gen.vector)+         ((,,) <$> Gen.vector <-*#> genBandedHermitian <-*|> Gen.vector)          multiplyVectorDot) :    ("multiplyFullColumns",       checkForAllExtra QC.arbitraryBoundedEnum-         ((,) <$> genBandedHermitian <|*|> Gen.matrix) multiplyFullColumns) :+         ((,) <$> genBandedHermitian <#*#> Gen.matrix) multiplyFullColumns) :    ("multiplyFullAssoc",       checkForAllExtra QC.arbitraryBoundedEnum-         ((,,) <$> genBandedHermitian <|*|> Gen.matrix <|*|> Gen.matrix)+         ((,,) <$> genBandedHermitian <#*#> Gen.matrix <#*#> Gen.matrix)          multiplyFullAssoc) :     ("determinant",       checkForAll genBandedHPD determinant) :    ("multiplySolve",-      checkForAll ((,) <$> genBandedHPD <|\|> Gen.matrix) multiplySolve) :+      checkForAll ((,) <$> genBandedHPD <#\#> Gen.matrix) multiplySolve) :    ("solveDecomposed",-      checkForAll ((,) <$> genBandedHPD <|\|> Gen.matrix) solveDecomposed) :+      checkForAll ((,) <$> genBandedHPD <#\#> Gen.matrix) solveDecomposed) :+   map+      (mapSnd+         ($ ((\(BandedHermitian m) -> Divide.SquareMatrix m) <$> genBandedHPD)))+      Divide.testsVarAny ++     ("eigenvaluesDeterminant",       checkForAll genBandedHPD eigenvaluesDeterminant) :
+ test/Test/Divide.hs view
@@ -0,0 +1,130 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ExistentialQuantification #-}+module Test.Divide (+   testsVar,+   testsVarAny,+   SquareMatrix(SquareMatrix),+   determinant,+   ) where++import qualified Test.Generator as Gen+import qualified Test.Utility as Util+import Test.Generator ((<#\#>), (<#/#>))+import Test.Utility (Tagged, approxMatrix)++import qualified Numeric.LAPACK.Linear.LowerUpper as LU+import qualified Numeric.LAPACK.Matrix.Square as Square+import qualified Numeric.LAPACK.Matrix.Special as Special+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix.Shape.Box as Box+import qualified Numeric.LAPACK.Matrix as Matrix+import qualified Numeric.LAPACK.Scalar as Scalar+import Numeric.LAPACK.Matrix.Array (ArrayMatrix)+import Numeric.LAPACK.Matrix (Matrix, ShapeInt, (##/#), (##*#), (#*##), (#\##))+import Numeric.LAPACK.Scalar (RealOf)++import qualified Numeric.Netlib.Class as Class++import qualified Data.Array.Comfort.Shape as Shape++import Control.Applicative ((<$>))++import Data.Tuple.HT (mapSnd)++import qualified Test.QuickCheck as QC++++determinant ::+   (ArrMatrix.Determinant shape, ArrMatrix.SquareShape shape,+    Box.HeightOf shape ~ ShapeInt, Box.WidthOf shape ~ ShapeInt,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   ArrayMatrix shape a -> Bool+determinant a =+   Util.approx+      (Scalar.selectReal 1e-1 1e-5)+      (Matrix.determinant a)+      (Square.determinant $ Matrix.toSquare a)+++multiplySolveTrans ::+   (Shape.C size, Eq size, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   LU.Transposition ->+   (SquareMatrix size a, Matrix.General size ShapeInt a) -> Bool+multiplySolveTrans trans (SquareMatrix a, b) =+   approxMatrix 1e-2 b $+      Matrix.multiplySquare trans a $ Matrix.solve trans a b++multiplySolveRight ::+   (Shape.C size, Eq size, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (SquareMatrix size a, Matrix.General size ShapeInt a) -> Bool+multiplySolveRight (SquareMatrix a, b) =+   approxMatrix 1e-2 b (a #*## (a #\## b))++multiplySolveLeft ::+   (Shape.C size, Eq size, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Matrix.General ShapeInt size a, SquareMatrix size a) -> Bool+multiplySolveLeft (b, SquareMatrix a) =+   approxMatrix 1e-2 b ((b ##/# a) ##*# a)++multiplyInverseRight ::+   (Shape.C size, Eq size, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (SquareMatrix size a, Matrix.General size ShapeInt a) -> Bool+multiplyInverseRight (SquareMatrix a, b) =+   approxMatrix 1e-2 b (a #*## (Special.Inverse a #*## b))++multiplyInverseLeft ::+   (Shape.C size, Eq size, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Matrix.General ShapeInt size a, SquareMatrix size a) -> Bool+multiplyInverseLeft (b, SquareMatrix a) =+   approxMatrix 1e-2 b ((b ##*# Special.Inverse a) ##*# a)+++checkForAll ::+   (Show a, QC.Testable test) =>+   Gen.T dim tag a -> (a -> test) -> Tagged tag QC.Property+checkForAll gen = Util.checkForAll (Gen.run gen 3 5)+++data SquareMatrix size a =+   forall typ matrix.+   (Matrix.Solve typ, Matrix.MultiplySquare typ,+    Matrix typ a ~ matrix, Show matrix,+    Matrix.HeightOf typ ~ size, Matrix.WidthOf typ ~ size) =>+   SquareMatrix (Matrix typ a)++instance Show (SquareMatrix size a) where+   show (SquareMatrix m) = show m+++testsVarAny ::+   (Show a, Class.Floating a, Eq a, RealOf a ~ ar, Class.Real ar) =>+   [(String, Gen.MatrixInt a (SquareMatrix ShapeInt a) -> Tagged a QC.Property)]+testsVarAny =+   ("multiplySolveTrans",+      \gen ->+         Gen.withExtra checkForAll QC.arbitraryBoundedEnum+            ((,) <$> gen <#\#> Gen.matrix) multiplySolveTrans) :+   ("multiplySolveRight",+      \gen ->+         checkForAll ((,) <$> gen <#\#> Gen.matrix) multiplySolveRight) :+   ("multiplySolveLeft",+      \gen ->+         checkForAll ((,) <$> Gen.matrix <#/#> gen) multiplySolveLeft) :+   ("multiplyInverseRight",+      \gen ->+         checkForAll ((,) <$> gen <#\#> Gen.matrix) multiplyInverseRight) :+   ("multiplyInverseLeft",+      \gen ->+         checkForAll ((,) <$> Gen.matrix <#/#> gen) multiplyInverseLeft) :+   []++testsVar ::+   (Matrix.Solve typ, Matrix.MultiplySquare typ,+    Matrix typ a ~ matrix, Show matrix,+    Matrix.HeightOf typ ~ ShapeInt, Matrix.WidthOf typ ~ ShapeInt,+    Show a, Class.Floating a, Eq a, RealOf a ~ ar, Class.Real ar) =>+   Gen.MatrixInt a (Matrix typ a) -> [(String, Tagged a QC.Property)]+testsVar gen =+   map (mapSnd ($ (SquareMatrix <$> gen))) testsVarAny
+ test/Test/Example.hs view
@@ -0,0 +1,21 @@+module Test.Example where++import qualified Test.Utility as Util++import qualified Numeric.LAPACK.Example.EconomicAllocation as Eco+import qualified Numeric.LAPACK.Vector as Vector++import qualified Data.Array.Comfort.Storable as Array++import qualified Test.QuickCheck as QC+++tests :: [(String, QC.Property)]+tests =+   ("economicAllocation",+      QC.property $+         let iterated = Eco.iterated Eco.expenses0 Eco.balances0+         in Util.approxVector iterated+               (Vector.append (Eco.compensated Eco.expenses0 Eco.balances0) $+                Vector.zero $ Array.shape $ Vector.takeRight iterated)) :+   []
test/Test/Format.hs view
@@ -1,16 +1,20 @@ {-# LANGUAGE Rank2Types #-} module Test.Format where +import qualified Numeric.LAPACK.Orthogonal.Householder as Hh+import qualified Numeric.LAPACK.Linear.LowerUpper as LU import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape import qualified Numeric.LAPACK.Matrix.BandedHermitian as BandedHermitian import qualified Numeric.LAPACK.Matrix.Banded as Banded import qualified Numeric.LAPACK.Matrix.Hermitian as Hermitian import qualified Numeric.LAPACK.Matrix.Triangular as Triangular+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix as Matrix import qualified Numeric.LAPACK.Vector as Vector import qualified Numeric.LAPACK.Permutation as Perm import Numeric.LAPACK.Matrix.Shape (Order(RowMajor, ColumnMajor), UnaryProxy)-import Numeric.LAPACK.Matrix (ZeroInt, zeroInt)+import Numeric.LAPACK.Matrix.Array (ArrayMatrix)+import Numeric.LAPACK.Matrix (ShapeInt, shapeInt) import Numeric.LAPACK.Format (Format, (##))  import qualified Numeric.Netlib.Class as Class@@ -23,15 +27,20 @@ import Data.Array.Comfort.Storable (Array)  import Data.Complex as Cplx (Complex((:+)))+import Data.Word (Word64)  -vector :: (Class.Floating a) => Vector.Vector ZeroInt a-vector = Vector.random Vector.UniformBoxPM1 (zeroInt 4) 419+randomMatrix ::+   (Shape.C sh, Class.Floating a) => sh -> Word64 -> ArrayMatrix sh a+randomMatrix sh = ArrMatrix.lift0 . Vector.random Vector.UniformBoxPM1 sh -general :: (Class.Floating a) => Order -> Matrix.General ZeroInt ZeroInt a++vector :: (Class.Floating a) => Vector.Vector ShapeInt a+vector = Vector.random Vector.UniformBoxPM1 (shapeInt 4) 419++general :: (Class.Floating a) => Order -> Matrix.General ShapeInt ShapeInt a general order =-   Vector.random Vector.UniformBoxPM1-      (MatrixShape.general order (zeroInt 3) (zeroInt 4)) 420+   randomMatrix (MatrixShape.general order (shapeInt 3) (shapeInt 4)) 420  split ::    (Eq lower, Shape.C height, Shape.C width, Class.Floating a) =>@@ -41,41 +50,35 @@    Vector.random Vector.UniformBoxPM1       (MatrixShape.splitGeneral lowerPart order height width) 420 -hermitian :: (Class.Floating a) => Order -> Hermitian.Hermitian ZeroInt a+hermitian :: (Class.Floating a) => Order -> Hermitian.Hermitian ShapeInt a hermitian order =-   Vector.random Vector.UniformBoxPM1-      (MatrixShape.hermitian order (zeroInt 4)) 421+   randomMatrix (MatrixShape.hermitian order (shapeInt 4)) 421 -diagonal :: (Class.Floating a) => Order -> Triangular.Diagonal ZeroInt a+diagonal :: (Class.Floating a) => Order -> Triangular.Diagonal ShapeInt a diagonal order =-   Vector.random Vector.UniformBoxPM1-      (MatrixShape.diagonal order (zeroInt 4)) 422+   randomMatrix (MatrixShape.diagonal order (shapeInt 4)) 422  lowerTriangular ::-   (Class.Floating a) => Order -> Triangular.Lower ZeroInt a+   (Class.Floating a) => Order -> Triangular.Lower ShapeInt a lowerTriangular order =-   Vector.random Vector.UniformBoxPM1-      (MatrixShape.lowerTriangular order (zeroInt 4)) 423+   randomMatrix (MatrixShape.lowerTriangular order (shapeInt 4)) 423  upperTriangular ::-   (Class.Floating a) => Order -> Triangular.Upper ZeroInt a+   (Class.Floating a) => Order -> Triangular.Upper ShapeInt a upperTriangular order =-   Vector.random Vector.UniformBoxPM1-      (MatrixShape.upperTriangular order (zeroInt 4)) 424+   randomMatrix (MatrixShape.upperTriangular order (shapeInt 4)) 424 -symmetric :: (Class.Floating a) => Order -> Triangular.Symmetric ZeroInt a+symmetric :: (Class.Floating a) => Order -> Triangular.Symmetric ShapeInt a symmetric order =-   Vector.random Vector.UniformBoxPM1-      (MatrixShape.symmetric order (zeroInt 4)) 425+   randomMatrix (MatrixShape.symmetric order (shapeInt 4)) 425   bandedHermitian ::    (Unary.Natural offDiag, Class.Floating a) =>    UnaryProxy offDiag -> Order ->-   BandedHermitian.BandedHermitian offDiag ZeroInt a+   BandedHermitian.BandedHermitian offDiag ShapeInt a bandedHermitian numOff order =-   Vector.random Vector.UniformBoxPM1-      (MatrixShape.bandedHermitian numOff order (zeroInt 4)) 426+   randomMatrix (MatrixShape.bandedHermitian numOff order (shapeInt 4)) 426  banded ::    (Unary.Natural sub, Unary.Natural super,@@ -83,16 +86,26 @@    (UnaryProxy sub, UnaryProxy super) -> height -> width -> Order ->    Banded.General sub super height width a banded offDiag height width order =-   Vector.random Vector.UniformBoxPM1-      (MatrixShape.bandedGeneral offDiag order height width) 427+   randomMatrix (MatrixShape.bandedGeneral offDiag order height width) 427  -permutation :: Perm.Permutation ZeroInt+permutation :: Perm.Permutation ShapeInt permutation =-   Perm.fromPivots Perm.NonInverted (zeroInt 5) $-   Vector.fromList (zeroInt 5) [3,2,4,5,5]+   Perm.fromPivots Perm.NonInverted $+   Vector.fromList (Perm.Shape $ shapeInt 5) $ map Perm.Element [3,2,4,5,5]  +lu :: (Class.Floating a) => Order -> LU.Tall ShapeInt ShapeInt a+lu order =+   LU.fromMatrix $+   randomMatrix (MatrixShape.tall order (shapeInt 4) (shapeInt 3)) 428++qr :: (Class.Floating a) => Order -> Hh.Tall ShapeInt ShapeInt a+qr order =+   Hh.fromMatrix $+   randomMatrix (MatrixShape.tall order (shapeInt 4) (shapeInt 3)) 429++ fmt :: String fmt = "%.4g" @@ -130,9 +143,9 @@    printVectorFloat vector    printVectorComplex vector    printVectorWithOrder general-   printVectorWithOrder $ split MatrixShape.Reflector (zeroInt 4) (zeroInt 3)-   printVectorWithOrder $ split MatrixShape.Reflector (zeroInt 3) (zeroInt 4)-   printVectorWithOrder $ split MatrixShape.Triangle (zeroInt 4) (zeroInt 3)+   printVectorWithOrder $ split MatrixShape.Reflector (shapeInt 4) (shapeInt 3)+   printVectorWithOrder $ split MatrixShape.Reflector (shapeInt 3) (shapeInt 4)+   printVectorWithOrder $ split MatrixShape.Triangle (shapeInt 4) (shapeInt 3)    printVectorWithOrder hermitian    printVectorWithOrder diagonal    printVectorWithOrder lowerTriangular@@ -142,12 +155,14 @@    printVectorWithOrder $ bandedHermitian $ unary TypeNum.u1    printVectorWithOrder $ bandedHermitian $ unary TypeNum.u2    printVectorWithOrder $-      banded (unary TypeNum.u0, unary TypeNum.u0) (zeroInt 4) (zeroInt 3)+      banded (unary TypeNum.u0, unary TypeNum.u0) (shapeInt 4) (shapeInt 3)    printVectorWithOrder $-      banded (unary TypeNum.u0, unary TypeNum.u2) (zeroInt 4) (zeroInt 3)+      banded (unary TypeNum.u0, unary TypeNum.u2) (shapeInt 4) (shapeInt 3)    printVectorWithOrder $-      banded (unary TypeNum.u2, unary TypeNum.u0) (zeroInt 4) (zeroInt 3)+      banded (unary TypeNum.u2, unary TypeNum.u0) (shapeInt 4) (shapeInt 3)    printVectorWithOrder $-      banded (unary TypeNum.u1, unary TypeNum.u2) (zeroInt 4) (zeroInt 3)+      banded (unary TypeNum.u1, unary TypeNum.u2) (shapeInt 4) (shapeInt 3)    printVectorWithOrder $-      banded (unary TypeNum.u1, unary TypeNum.u2) (zeroInt 3) (zeroInt 4)+      banded (unary TypeNum.u1, unary TypeNum.u2) (shapeInt 3) (shapeInt 4)+   printVectorWithOrder lu+   printVectorWithOrder qr
test/Test/Generator.hs view
@@ -6,7 +6,8 @@  import qualified Test.Logic as Logic import qualified Test.Utility as Util-import Test.Logic (Dim, MatchMode(DontForceMatch,ForceMatch), (=!=), (<!=))+import Test.Logic+         (Dim, MatchMode(DontForceMatch,ForceMatch), (=!=), (<!=), (!+!), (!*!)) import Test.Utility (Match)  import qualified UniqueLogic.ST.TF.System.Simple as Sys@@ -17,21 +18,23 @@ import qualified Numeric.LAPACK.Matrix as Matrix import qualified Numeric.LAPACK.Vector as Vector import Numeric.LAPACK.Matrix.Hermitian (Hermitian)-import Numeric.LAPACK.Matrix (ZeroInt, zeroInt)+import Numeric.LAPACK.Matrix (ShapeInt) import Numeric.LAPACK.Scalar (RealOf, fromReal, one)  import qualified Numeric.Netlib.Class as Class  import qualified Data.Array.Comfort.Shape as Shape-import Data.Array.Comfort.Storable (Array) import Data.Array.Comfort.Shape ((:+:))  import qualified Control.Monad.Trans.RWS as MRWS+import qualified Control.Monad.Trans.Writer as MW+import qualified Control.Monad.Trans.Reader as MR import qualified Control.Monad.Trans.Class as MT import qualified Control.Applicative.HT as AppHT-import Control.Monad.Trans.RWS (RWST, evalRWST)-import Control.Applicative (liftA2, (<*>), (<$>))+import qualified Control.Functor.HT as FuncHT+import Control.Applicative (liftA2, liftA3, (<*>), (<$>)) +import qualified Data.NonEmpty.Class as NonEmptyC import qualified Data.Ref as Ref import Data.Semigroup ((<>)) import Data.Monoid (Monoid, mempty)@@ -42,25 +45,43 @@   {- |-@Cons generator@ with @generator maxElem@.-@generator@ constructs an array and maintains relations between the dimensions.+@generator :: Base dim array@+constructs an array shape or an array of type @array@+with dimensions @dim@ and maintains relations between the dimensions. Dimensions will be choosen arbitrarily from the range @(0,maxDim)@.-Elements are choosen from the range @(-maxElem,maxElem)@.+@TaggedVariables s dim@ maintain the 'Logic' variables for the array dimensions.+@Logic.M s array@ contains the query for retrieving the object+that depends on the solved logic system.+@M s@ collects all constraints in a 'MW.WriterT'. -I moved the 's' tag to within the 'Cons' constructor+I moved the 's' tag to within the 'Base' constructor and furthermore defined 'TaggedVariables' to strip the 's' tag from the Variables in 'dim'. This way, we can easily define 'checkForAll' in the test modules. Otherwise there would not be a way to quantify 'dim' while containing 's' tags. That is, we would have to reset 'dim' to () before every call to 'checkForAll'. -}-newtype T tag dim array =-   Cons {-      decons :: forall s.-         RWST Integer (Logic.System s) () (Logic.M s)-            (TaggedVariables s dim, Logic.M s array)-   }+newtype Base dim array = Base {unbase :: forall s. BaseM s dim array} +{- |+'T' adds the capability of array creation to 'Base'.+To this end it employs a 'MR.ReaderT' that provides the 'maxElem' parameter.+Array elements are choosen from the range @(-maxElem,maxElem)@.+The many levels of construction of 'T' look complicated,+but every level represents a major step.+While 'Base' generates matching dimensions for all involved objects,+'T' adds the final 'QC.Gen' that generates+all arrays containing QuickCheck generated random values.+The separation of dimension and array creation allows us+to place constraints like invertibility to the generator, afterwards,+or to extend single generators to list generators.+-}+newtype T dim elem array = Cons (forall s. BaseM s dim (MaxElemQCGen array))+type MaxElemQCGen = MR.ReaderT Integer QC.Gen++type BaseM s dim array = M s (TaggedVariables s dim, Logic.M s array)++type M s = MW.WriterT (Logic.System s) (Logic.M s) data Variable dim  type family TaggedVariables s tuple@@ -69,217 +90,304 @@ type instance TaggedVariables s (a,b) =                   (TaggedVariables s a, TaggedVariables s b) -instance Functor (T tag dim) where-   fmap f (Cons gen) = Cons $ mapSnd (fmap f) <$> gen+instance Functor (Base dim) where+   fmap f (Base gen) = Base $ mapSnd (fmap f) <$> gen -newVariable :: (Ref.C m, Monoid w) => RWST r w () m (Sys.Variable m a)+instance Functor (T dim elem) where+   fmap f = liftBase $ fmap $ fmap f++newVariable :: (Ref.C m, Monoid w) => MW.WriterT w m (Sys.Variable m a) newVariable = MT.lift Sys.globalVariable -run ::-   T tag dim array -> Integer -> Int ->-   Util.TaggedGen tag (array, Match)-run gen maxElem maxDim =+newVariableWith ::+   (Ref.C m, Monoid w) =>+   (Sys.Variable m a -> w) -> MW.WriterT w m (Sys.Variable m a)+newVariableWith constraint = do+   v <- newVariable+   MW.tell $ constraint v+   return v++run :: T dim elem array -> Integer -> Int -> Util.TaggedGen elem (array, Match)+run (Cons gen) maxElem maxDim =    Util.Tagged $-      QC.elements [DontForceMatch, ForceMatch] >>=+      FuncHT.mapFst (flip MR.runReaderT maxElem)+      =<<       Logic.runSTInGen-         (do ((_dim, queries), sys) <- evalRWST (decons gen) maxElem ()+         (do ((_dim, queries), sys) <- MW.runWriterT gen              Logic.solve sys              queries)          maxDim+      =<<+      QC.elements [DontForceMatch, ForceMatch]  withExtra ::-   (T tag dim (a,b) -> ((a,b) -> c) -> io) ->-   QC.Gen a -> T tag dim b -> (a -> b -> c) -> io+   (T dim elem (a,b) -> ((a,b) -> c) -> io) ->+   QC.Gen a -> T dim elem b -> (a -> b -> c) -> io withExtra checkForAll genA genB test =-   checkForAll (mapGen (\_ b -> flip (,) b <$> genA) genB) (uncurry test)+   checkForAll (mapQC (\b -> flip (,) b <$> genA) genB) (uncurry test)  -mapGen ::-   (Integer -> a -> QC.Gen b) ->-   T tag dim a -> T tag dim b-mapGen f (Cons gen) =-   Cons $ do-      maxElem <- MRWS.ask-      mapSnd (Logic.liftGen . f maxElem =<<) <$> gen+fromBase :: Base dim (MaxElemQCGen a) -> T dim elem a+fromBase (Base gen) = Cons gen -mapGenDim ::-   (Integer -> Int -> a -> QC.Gen b) ->-   T tag dim a -> T tag dim b-mapGenDim f (Cons gen) =+liftBase ::+   (Base dimA (MaxElemQCGen a) -> Base dimB (MaxElemQCGen b)) ->+   T dimA elem a -> T dimB elem b+liftBase f (Cons gen) = Cons $ unbase $ f $ Base gen++condition :: (a -> Bool) -> T dim elem a -> T dim elem a+condition = liftBase . fmap . MR.mapReaderT . flip QC.suchThat++mapQC :: (a -> QC.Gen b) -> T dim elem a -> T dim elem b+mapQC f = liftBase $ fmap (MT.lift . f =<<)++mapGen :: (Integer -> a -> QC.Gen b) -> Base dim a -> T dim elem b+mapGen f = fromBase . fmap (MR.ReaderT . flip f)++mapGenDim :: (Integer -> Int -> a -> QC.Gen b) -> Base dim a -> T dim elem b+mapGenDim f (Base gen) =    Cons $ do-      maxElem <- MRWS.ask       (maxDim, _matchMode) <- MT.lift $ Logic.M MRWS.ask-      mapSnd (Logic.liftGen . f maxElem maxDim =<<) <$> gen+      mapSnd (fmap (\a -> MR.ReaderT $ \maxElem -> f maxElem maxDim a))+         <$> gen  +constrain ::+   (forall s. TaggedVariables s dim -> Logic.System s) ->+   Base dim a -> Base dim a+constrain constraint (Base gen) =+   Base $ do+      (dim,a) <- gen+      MW.tell $ constraint dim+      return (dim,a)+ combine ::    (forall s.     TaggedVariables s dimF -> TaggedVariables s dimA ->     (TaggedVariables s dimB, Logic.System s)) ->-   T tag dimF (a -> b) ->-   T tag dimA a ->-   T tag dimB b-combine combineDim (Cons genF) (Cons genA) =+   T dimF elem (a -> b) ->+   T dimA elem a ->+   T dimB elem b+combine combineDim =+   combineM+      (\dimF dimA -> do+         let (dimB, constraint) = combineDim dimF dimA+         MW.tell constraint+         return dimB)++combineM ::+   (forall s.+    TaggedVariables s dimF -> TaggedVariables s dimA ->+    M s (TaggedVariables s dimB)) ->+   T dimF elem (a -> b) ->+   T dimA elem a ->+   T dimB elem b+combineM combineDim (Cons genF) (Cons genA) =    Cons $ do       (dimF,f) <- genF       (dimA,a) <- genA-      let (dimB, constraint) = combineDim dimF dimA-      MRWS.tell constraint-      return (dimB, f <*> a)+      dimB <- combineDim dimF dimA+      return (dimB, liftA2 (<*>) f a) +combine3M ::+   (forall s.+    TaggedVariables s dimF ->+    TaggedVariables s dimA -> TaggedVariables s dimB ->+    M s (TaggedVariables s dimC)) ->+   T dimF elem (a -> b -> c) ->+   T dimA elem a ->+   T dimB elem b ->+   T dimC elem c+combine3M combineDim (Cons genF) (Cons genA) (Cons genB) =+   Cons $ do+      (dimF,f) <- genF+      (dimA,a) <- genA+      (dimB,b) <- genB+      dimC <- combineDim dimF dimA dimB+      return (dimC, liftA3 (\fi ai bi -> fi <*> ai <*> bi) f a b) -type Scalar tag = T tag () +type ScalarBase = Base ()+type Scalar elem = T () elem++scalarGen :: (Class.Floating a) => Scalar b a+scalarGen = Cons $ return ((), return $ MR.ReaderT Util.genElement)+ scalar :: (Class.Floating a) => Scalar a a-scalar =-   Cons $ do-      maxElem <- MRWS.ask-      return ((), Logic.liftGen $ Util.genElement maxElem)+scalar = scalarGen -(<.*.>) ::+scalarReal :: (Class.Floating a, RealOf a ~ ar, Class.Real ar) => Scalar a ar+scalarReal = scalarGen++(<-*|>) ::    (Dim size, Eq size) =>-   Vector tag size (a -> b) ->-   Vector tag size a ->-   Scalar tag b-(<.*.>) = combine (\dimF dimA -> ((), dimF=!=dimA))+   Vector size elem (a -> b) ->+   Vector size elem a ->+   Scalar elem b+(<-*|>) = combine (\dimF dimA -> ((), dimF=!=dimA))  -queryZeroInt :: Logic.Variable s Int -> Logic.M s ZeroInt-queryZeroInt var = zeroInt <$> Logic.query var--type Vector tag size = T tag (Variable size)+type VectorBase size = Base (Variable size)+type Vector size elem = T (Variable size) elem+type VectorInt elem = Vector ShapeInt elem -vectorDim :: Vector a Int ZeroInt+vectorDim :: (Dim size) => VectorBase size size vectorDim =-   Cons $ do+   Base $ do       dim <- newVariable-      return (dim, queryZeroInt dim)+      return (dim, Logic.query dim) -vector :: (Class.Floating a) => Vector a Int (Vector.Vector ZeroInt a)-vector = mapGen Util.genArray vectorDim+vectorGen ::+   (Dim size, Class.Floating a) => Vector size b (Vector.Vector size a)+vectorGen = mapGen Util.genVector vectorDim +vector ::+   (Dim size, Class.Floating a) => Vector size a (Vector.Vector size a)+vector = vectorGen+ vectorReal ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Vector a Int (Vector.Vector ZeroInt ar)-vectorReal = mapGen Util.genArray vectorDim+   VectorInt a (Vector.Vector ShapeInt ar)+vectorReal = vectorGen -(<.*|>) ::+(<-*#>) ::    (Dim height, Eq height) =>-   Vector tag height (a -> b) ->-   Matrix tag height width a ->-   Vector tag width b-(<.*|>) = combine (\dim (height,width) -> (width, dim=!=height))+   Vector height elem (a -> b) ->+   Matrix height width elem a ->+   Vector width elem b+(<-*#>) = combine (\dim (height,width) -> (width, dim=!=height)) -(<|*.>) ::+(<#*|>) ::    (Dim width, Eq width) =>-   Matrix tag height width (a -> b) ->-   Vector tag width a ->-   Vector tag height b-(<|*.>) = combine (\(height,width) dim -> (height, width=!=dim))+   Matrix height width elem (a -> b) ->+   Vector width elem a ->+   Vector height elem b+(<#*|>) = combine (\(height,width) dim -> (height, width=!=dim)) -(<.=.>) ::+(<|=|>) ::    (Dim size, Eq size) =>-   Vector tag size (a -> b) ->-   Vector tag size a ->-   Vector tag size b-(<.=.>) = combine (\sizeF sizeA -> (sizeF, sizeF=!=sizeA))+   Vector size elem (a -> b) ->+   Vector size elem a ->+   Vector size elem b+(<|=|>) = combine (\sizeF sizeA -> (sizeF, sizeF=!=sizeA)) +(<+++>) ::+   Vector sizeA elem (a -> b) ->+   Vector sizeB elem a ->+   Vector (sizeA:+:sizeB) elem b+(<+++>) = combineM (\sizeA sizeB -> newVariableWith $ sizeA!+!sizeB) -type Matrix tag height width = T tag (Variable height, Variable width) -matrixDims :: Matrix a Int Int (ZeroInt, ZeroInt)+type MatrixBase height width = Base (Variable height, Variable width)+type Matrix height width = T (Variable height, Variable width)+type MatrixInt = Matrix ShapeInt ShapeInt++shapeFromDims :: (MatrixShape.Order -> a -> b) -> Base dim a -> Base dim b+shapeFromDims f (Base gen) =+   Base $ mapSnd (liftA2 f (Logic.liftGen Util.genOrder)) <$> gen++matrixDims ::+   (Dim height, Dim width) => MatrixBase height width (height, width) matrixDims =-   Cons $ do+   Base $ do       dims <- liftA2 (,) newVariable newVariable-      return (dims, AppHT.mapPair (queryZeroInt,queryZeroInt) dims)+      return (dims, AppHT.mapPair (Logic.query,Logic.query) dims) +matrixShape ::+   (Dim height, Dim width) =>+   MatrixBase height width (MatrixShape.General height width)+matrixShape = shapeFromDims (uncurry . MatrixShape.general) matrixDims+ matrix ::-   (Class.Floating a) => Matrix a Int Int (Matrix.General ZeroInt ZeroInt a)-matrix =-   flip mapGen matrixDims $ \maxElem dims -> do-      order <- Util.genOrder-      Util.genArray maxElem $ uncurry (MatrixShape.general order) dims+   (Dim height, Dim width, Class.Floating a) =>+   Matrix height width a (Matrix.General height width a)+matrix = mapGen Util.genArray matrixShape +matrixInt ::+   (Class.Floating a) => MatrixInt a (Matrix.General ShapeInt ShapeInt a)+matrixInt = matrix -squareDim :: Matrix a Int Int ZeroInt-squareDim =++listOf ::+   (NonEmptyC.Gen f) =>+   (forall s. TaggedVariables s dim -> Logic.M s size) ->+   T dim elem a -> T dim elem (size, f a)+listOf querySize (Cons gen) =    Cons $ do-      dim <- newVariable-      return ((dim,dim), queryZeroInt dim)+      (dim, query) <- gen+      return (dim, do+         size <- querySize dim+         qc <- query+         return $ (,) size <$> MR.mapReaderT NonEmptyC.genOf qc) -squareShaped ::-   (Shape.C sh, Class.Floating a) =>-   (MatrixShape.Order -> ZeroInt -> sh) -> Matrix a Int Int (Array sh a)-squareShaped shape =-   flip mapGen squareDim $ \maxElem size -> do-      order <- Util.genOrder-      Util.genArray maxElem $ shape order size+listOfVector ::+   (Dim size, NonEmptyC.Gen f) =>+   Vector size elem a -> Vector size elem (size, f a)+listOfVector = listOf Logic.query -square :: (Class.Floating a) => Matrix a Int Int (Square.Square ZeroInt a)-square = squareShaped MatrixShape.square+listOfMatrix ::+   (Dim height, Dim width, NonEmptyC.Gen f) =>+   Matrix height width elem a -> Matrix height width elem ((height,width), f a)+listOfMatrix = listOf (AppHT.mapPair (Logic.query,Logic.query)) -squareCond ::-   (Class.Floating a) =>-   (Square.Square ZeroInt a -> Bool) ->-   Matrix a Int Int (Square.Square ZeroInt a)-squareCond cond =-   flip mapGen squareDim $ \maxElem size -> do-      order <- Util.genOrder-      Util.genArray maxElem (MatrixShape.square order size)-         `QC.suchThat`-         cond +type SquareBase sh = MatrixBase sh sh+type Square sh = Matrix sh sh++squareDim :: (Dim sh) => SquareBase sh sh+squareDim =+   Base $ do+      dim <- newVariable+      return ((dim,dim), Logic.query dim)++squareShape :: (Dim sh) => SquareBase sh (MatrixShape.Square sh)+squareShape = shapeFromDims MatrixShape.square squareDim++square :: (Class.Floating a) => MatrixInt a (Square.Square ShapeInt a)+square = mapGen Util.genArray squareShape+ invertible ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix a Int Int (Square.Square ZeroInt a)-invertible = squareCond Util.invertible+   MatrixInt a (Square.Square ShapeInt a)+invertible = condition Util.invertible square -diagonal ::-   (Class.Floating a) => Matrix a Int Int (Triangular.Diagonal ZeroInt a)-diagonal = squareShaped MatrixShape.diagonal+diagonal :: (Class.Floating a) => MatrixInt a (Triangular.Diagonal ShapeInt a)+diagonal = mapGen Util.genArray $ shapeFromDims MatrixShape.diagonal squareDim  identity ::    (MatrixShape.Content lo, MatrixShape.Content up, Class.Floating a) =>-   Matrix a Int Int (Triangular.Triangular lo MatrixShape.Unit up ZeroInt a)-identity =-   flip mapGen squareDim $ \ _maxElem size -> do-      order <- Util.genOrder-      return $ Triangular.identity order size+   MatrixInt a (Triangular.Triangular lo MatrixShape.Unit up ShapeInt a)+identity = fromBase $ return <$> shapeFromDims Triangular.identity squareDim -triangularCond ::+triangularShape ::    (MatrixShape.Content up, MatrixShape.Content lo, MatrixShape.TriDiag diag,-    Class.Floating a) =>-   (Triangular.Triangular lo diag up ZeroInt a -> Bool) ->-   Matrix a Int Int (Triangular.Triangular lo diag up ZeroInt a)-triangularCond cond =-   flip mapGen squareDim $ \maxElem size -> do-      order <- Util.genOrder-      genTriangularArray maxElem-         (MatrixShape.Triangular-            MatrixShape.autoDiag MatrixShape.autoUplo order size)-         `QC.suchThat`-         cond+    Dim sh) =>+   SquareBase sh (MatrixShape.Triangular lo diag up sh)+triangularShape =+   shapeFromDims+      (MatrixShape.Triangular MatrixShape.autoDiag MatrixShape.autoUplo)+      squareDim  triangular ::    (MatrixShape.Content up, MatrixShape.Content lo, MatrixShape.TriDiag diag,-    Class.Floating a) =>-   Matrix a Int Int (Triangular.Triangular lo diag up ZeroInt a)-triangular = triangularCond (const True)+    Dim sh, Shape.Indexed sh, Shape.Index sh ~ ix, Eq ix, Class.Floating a) =>+   Square sh a (Triangular.Triangular lo diag up sh a)+triangular = mapGen genTriangularArray triangularShape  -newtype GenTriangularDiag lo up a diag =+newtype GenTriangularDiag lo up sh a diag =    GenTriangularDiag {       runGenTriangularDiag ::-         MatrixShape.Triangular lo diag up ZeroInt ->-         QC.Gen (Triangular.Triangular lo diag up ZeroInt a)+         MatrixShape.Triangular lo diag up sh ->+         QC.Gen (Triangular.Triangular lo diag up sh a)    }  genTriangularArray ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,-    Class.Floating a) =>+    Shape.Indexed sh, Shape.Index sh ~ ix, Eq ix, Class.Floating a) =>    Integer ->-   MatrixShape.Triangular lo diag up ZeroInt ->-   QC.Gen (Triangular.Triangular lo diag up ZeroInt a)+   MatrixShape.Triangular lo diag up sh ->+   QC.Gen (Triangular.Triangular lo diag up sh a) genTriangularArray maxElem =    runGenTriangularDiag $    MatrixShape.switchTriDiag@@ -288,150 +396,167 @@       (GenTriangularDiag $ Util.genArray maxElem)  -tallDims :: Matrix a Int Int (ZeroInt, ZeroInt)-tallDims =-   Cons $ do-      height <- newVariable-      width  <- newVariable-      MRWS.tell $  width <!= height-      return ((height,width),-              liftA2 (,) (queryZeroInt height) (queryZeroInt width))+tallShape :: MatrixBase ShapeInt ShapeInt (MatrixShape.Tall ShapeInt ShapeInt)+tallShape =+   shapeFromDims (uncurry . MatrixShape.tall) $+   constrain (uncurry $ flip (<!=)) matrixDims -tall ::-   (Class.Floating a) =>-   Matrix a Int Int (Matrix.Tall ZeroInt ZeroInt a)-tall =-   flip mapGen tallDims $ \maxElem dims -> do-      order <- Util.genOrder-      Util.genArray maxElem $ uncurry (MatrixShape.tall order) dims+tall :: (Class.Floating a) => MatrixInt a (Matrix.Tall ShapeInt ShapeInt a)+tall = mapGen Util.genArray tallShape  fullRankTall ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix a Int Int (Matrix.Tall ZeroInt ZeroInt a)-fullRankTall =-   flip mapGen tallDims $ \maxElem dims -> do-      order <- Util.genOrder-      Util.genArray maxElem (uncurry (MatrixShape.tall order) dims)-         `QC.suchThat` Util.fullRankTall+   MatrixInt a (Matrix.Tall ShapeInt ShapeInt a)+fullRankTall = condition Util.fullRankTall tall  -wide ::-   (Class.Floating a) =>-   Matrix a Int Int (Matrix.Wide ZeroInt ZeroInt a)+wide :: (Class.Floating a) => MatrixInt a (Matrix.Wide ShapeInt ShapeInt a) wide = Matrix.transpose <$> transpose tall  fullRankWide ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix a Int Int (Matrix.Wide ZeroInt ZeroInt a)+   MatrixInt a (Matrix.Wide ShapeInt ShapeInt a) fullRankWide = Matrix.transpose <$> transpose fullRankTall   hermitian ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix a Int Int (Hermitian ZeroInt a)-hermitian = hermitianCond (const True)--hermitianCond ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Hermitian ZeroInt a -> Bool) ->-   Matrix a Int Int (Hermitian ZeroInt a)-hermitianCond cond =-   flip mapGen squareDim $ \maxElem size -> do-      order <- Util.genOrder-      let shape = MatrixShape.hermitian order size-      (Util.genArrayExtraDiag maxElem shape-          (const $ fromReal <$> Util.genReal maxElem))-         `QC.suchThat` cond+   (Dim sh, Shape.Indexed sh, Shape.Index sh ~ ix, Eq ix,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Square sh a (Hermitian sh a)+hermitian =+   flip mapGen (shapeFromDims MatrixShape.hermitian squareDim) $+         \maxElem shape ->+      Util.genArrayExtraDiag maxElem shape+         (const $ fromReal <$> Util.genReal maxElem)   {- There cannot be a pure/point function. -}-(<|*|>) ::+(<#*#>) ::    (Dim fuse, Eq fuse) =>-   Matrix tag height fuse (a -> b) ->-   Matrix tag fuse width a ->-   Matrix tag height width b-(<|*|>) =+   Matrix height fuse elem (a -> b) ->+   Matrix fuse width elem a ->+   Matrix height width elem b+(<#*#>) =    combine (\(height,fuseF) (fuseA,width) -> ((height,width), fuseF=!=fuseA)) +(<.*#>) :: Scalar elem (a -> b) -> T dim elem a -> T dim elem b+(<.*#>) = combine (\() size -> (size, mempty))++mapDims ::+   (forall s.+    (Logic.Variable s heightA, Logic.Variable s widthA) ->+    (Logic.Variable s heightB, Logic.Variable s widthB)) ->+   Matrix heightA widthA elem a ->+   Matrix heightB widthB elem a+mapDims f = liftBase $ \(Base gen) -> Base $ mapFst f <$> gen+ transpose ::-   Matrix tag height width a ->-   Matrix tag width height a-transpose (Cons gen) = Cons $ mapFst swap <$> gen+   Matrix height width elem a ->+   Matrix width height elem a+transpose = mapDims swap -(<|\|>) ::+gramian ::+   Matrix height width elem a ->+   Matrix width width elem a+gramian = mapDims (\(_,w) -> (w,w))++(<#\#>) ::    (Dim height, Eq height) =>-   Matrix tag height width (a -> b) ->-   Matrix tag height nrhs a ->-   Matrix tag width nrhs b-(<|\|>) a b = transpose a <|*|> b+   Matrix height width elem (a -> b) ->+   Matrix height nrhs elem a ->+   Matrix width nrhs elem b+(<#\#>) a b = transpose a <#*#> b -(<***>) ::-   Vector tag height (a -> b) ->-   Vector tag width a ->-   Matrix tag height width b-(<***>) = combine (\height width -> ((height,width), mempty))+(<#/#>) ::+   (Dim width, Eq width) =>+   Matrix nlhs width elem (a -> b) ->+   Matrix height width elem a ->+   Matrix nlhs height elem b+(<#/#>) a b = a <#*#> transpose b +(<|*->) ::+   Vector height elem (a -> b) ->+   Vector width elem a ->+   Matrix height width elem b+(<|*->) = combine (\height width -> ((height,width), mempty)) -(<|=|>) ::++(<><>) ::+   Matrix heightA widthA elem (a -> b) ->+   Matrix heightB widthB elem a ->+   Matrix (heightA,heightB) (widthA,widthB) elem b+(<><>) =+   combineM+      (\(heightA,widthA) (heightB,widthB) ->+         liftA2 (,)+            (newVariableWith $ heightA !*! heightB)+            (newVariableWith $ widthA !*! widthB))+++(<#=#>) ::    (Dim height, Eq height) =>    (Dim width, Eq width) =>-   Matrix tag height width (a -> b) ->-   Matrix tag height width a ->-   Matrix tag height width b-(<|=|>) =+   Matrix height width elem (a -> b) ->+   Matrix height width elem a ->+   Matrix height width elem b+(<#=#>) =    combine $ \(heightF,widthF) (heightA,widthA) ->       ((heightF,widthF), heightF=!=heightA <> widthF=!=widthA)  -(!+!) ::-   Logic.Variable s dimA ->-   Logic.Variable s dimB ->-   RWST r (Logic.System s) () (Logic.M s) (Logic.Variable s (dimA :+: dimB))-a!+!b = do-   c <- newVariable-   MRWS.tell $ (a Logic.!+! b) c-   return c- (<===>) ::    (Dim width, Eq width) =>-   Matrix tag heightA width (a -> b) ->-   Matrix tag heightB width a ->-   Matrix tag (heightA:+:heightB) width b-(<===>) (Cons genF) (Cons genA) =-   Cons $ do-      ((heightF,widthF),f) <- genF-      ((heightA,widthA),a) <- genA-      MRWS.tell $ widthF=!=widthA-      heightB <- heightF!+!heightA-      return ((heightB,widthF), f <*> a)+   Matrix heightA width elem (a -> b) ->+   Matrix heightB width elem a ->+   Matrix (heightA:+:heightB) width elem b+(<===>) =+   combineM+      (\(heightA,widthA) (heightB,widthB) -> do+         MW.tell $ widthA=!=widthB+         heightC <- newVariableWith $ heightA!+!heightB+         return (heightC,widthA))  (<|||>) ::    (Dim height, Eq height) =>-   Matrix tag height widthA (a -> b) ->-   Matrix tag height widthB a ->-   Matrix tag height (widthA:+:widthB) b+   Matrix height widthA elem (a -> b) ->+   Matrix height widthB elem a ->+   Matrix height (widthA:+:widthB) elem b (<|||>) f a = transpose $ transpose f <===> transpose a   +stackDiagonal ::+   (Dim heightA, Eq heightA) =>+   (Dim widthB, Eq widthB) =>+   Matrix heightA widthA elem a ->+   Matrix heightB widthB elem c ->+   Matrix (heightA:+:heightB) (widthA:+:widthB) elem (a,c)+stackDiagonal genA =+   combineM+      (\(heightA,widthA) (heightB,widthB) -> do+         liftA2 (,)+            (newVariableWith $ heightA!+!heightB)+            (newVariableWith $ widthA!+!widthB))+      ((,) <$> genA)+ stack3 ::    (Dim heightA, Eq heightA) =>    (Dim widthB, Eq widthB) =>-   Matrix tag heightA widthA a ->-   Matrix tag heightA widthB b ->-   Matrix tag heightB widthB c ->-   Matrix tag (heightA:+:heightB) (widthA:+:widthB) (a,b,c)-stack3 (Cons genF) (Cons genA) (Cons genB) =-   Cons $ do-      ((heightF,widthF),f) <- genF-      ((heightA,widthA),a) <- genA-      ((heightB,widthB),b) <- genB-      MRWS.tell $  heightF=!=heightA  <>  widthA=!=widthB-      heightC <- heightF!+!heightB-      widthC <- widthF!+!widthB-      return ((heightC,widthC), (,,) <$> f <*> a <*> b)+   Matrix heightA widthA elem a ->+   Matrix heightA widthB elem b ->+   Matrix heightB widthB elem c ->+   Matrix (heightA:+:heightB) (widthA:+:widthB) elem (a,b,c)+stack3 genA =+   combine3M+      (\(heightA,widthA) (heightA0,widthB0) (heightB,widthB) -> do+         MW.tell $  heightA=!=heightA0  <>  widthB=!=widthB0+         liftA2 (,)+            (newVariableWith $ heightA!+!heightB)+            (newVariableWith $ widthA!+!widthB))+      ((,,) <$> genA)  -infixl 4 <.*.>, <.*|>, <|*.>, <|*|>, <|\|>, <***>, <.=.>, <|=|>, <===>, <|||>+infixl 4 <-*|>, <.*#>, <-*#>, <#*|>, <#*#>, <#\#>, <#/#>+infixl 4 <|*->, <><>, <|=|>, <#=#>, <+++>, <===>, <|||>
+ test/Test/Generic.hs view
@@ -0,0 +1,52 @@+{-# LANGUAGE TypeFamilies #-}+module Test.Generic where++import qualified Test.Generator as Gen+import qualified Test.Logic as Logic+import Test.Generator ((<#*|>), (<#=#>))+import Test.Utility (approxVector)++import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix as Matrix+import Numeric.LAPACK.Matrix.Array (ArrayMatrix)+import Numeric.LAPACK.Matrix (ShapeInt, (#*|), (#+#), (#-#))+import Numeric.LAPACK.Vector (Vector, (|+|), (|-|))+import Numeric.LAPACK.Scalar (RealOf)++import qualified Numeric.Netlib.Class as Class++import qualified Data.Array.Comfort.Shape as Shape++import Control.Applicative ((<$>))+++forceOrder ::+   (ArrMatrix.ShapeOrder shape, ArrMatrix.MultiplyVector shape,+    MatrixShape.HeightOf shape ~ height, Shape.C height, Eq height,+    MatrixShape.WidthOf shape ~ width, width ~ ShapeInt,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   MatrixShape.Order ->+   (ArrayMatrix shape a, Vector width a) -> Bool+forceOrder order (a,x) =+   let ao = Matrix.forceOrder order a+   in ArrMatrix.shapeOrder (ArrMatrix.shape ao) == order+      &&+      approxVector (a #*| x) (ao #*| x)+++genDistribution ::+   (Logic.Dim height, Eq height, Logic.Dim width, Eq width, Class.Floating a) =>+   Gen.Matrix height width a matrix ->+   Gen.Vector height a ((matrix, matrix), Vector width a)+genDistribution gen = (,) <$> ((,) <$> gen <#=#> gen) <#*|> Gen.vector++addDistributive, subDistributive ::+   (ArrMatrix.Additive shape, ArrMatrix.MultiplyVector shape,+    MatrixShape.HeightOf shape ~ height, Shape.C height, Eq height,+    MatrixShape.WidthOf shape ~ width, width ~ ShapeInt,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   ((ArrayMatrix shape a, ArrayMatrix shape a), Vector width a) ->+   Bool+addDistributive ((a,b),x) = approxVector ((a#+#b) #*| x) (a#*|x |+| b#*|x)+subDistributive ((a,b),x) = approxVector ((a#-#b) #*| x) (a#*|x |-| b#*|x)
test/Test/Hermitian.hs view
@@ -1,19 +1,24 @@ {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} module Test.Hermitian (testsVar) where +import qualified Test.Divide as Divide+import qualified Test.Multiply as Multiply+import qualified Test.Generic as Generic import qualified Test.Indexed as Indexed import qualified Test.Generator as Gen import qualified Test.Utility as Util-import Test.Generator ((<.*|>), (<|*.>), (<|*|>), (<|\|>))+import Test.Generator ((<-*#>), (<#*|>), (<.*#>), (<#*#>), (<#\#>), (<#=#>)) import Test.Utility-         (approx, approxReal, approxArray, approxArrayTol, approxMatrix,-          equalArray, Tagged, genOrder)+         (approxReal, approxArray, approxArrayTol, approxMatrix,+          approxVector, equalArray, Tagged, genOrder, (!===))  import qualified Numeric.LAPACK.Orthogonal.Householder as HH import qualified Numeric.LAPACK.Matrix.HermitianPositiveDefinite as HermitianPD import qualified Numeric.LAPACK.Matrix.Hermitian as Hermitian import qualified Numeric.LAPACK.Matrix.Triangular as Triangular import qualified Numeric.LAPACK.Matrix.Square as Square+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape import qualified Numeric.LAPACK.Matrix as Matrix import qualified Numeric.LAPACK.Vector as Vector@@ -21,195 +26,257 @@ import Numeric.LAPACK.Matrix.Square (Square) import Numeric.LAPACK.Matrix.Shape (Order) import Numeric.LAPACK.Matrix-         (General, ZeroInt, zeroInt, (<#), (<#>), (#>), (|||), (===))-import Numeric.LAPACK.Vector (Vector)-import Numeric.LAPACK.Scalar (RealOf, fromReal, selectReal)+         (General, ShapeInt, (#+#), (-*#), (##*#), (#*##), (#*|), (|||))+import Numeric.LAPACK.Vector (Vector, (.*|))+import Numeric.LAPACK.Scalar (RealOf, selectReal)  import qualified Numeric.Netlib.Class as Class  import qualified Data.Array.Comfort.Storable as Array import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Shape ((:+:))  import Control.Applicative (liftA2, (<$>))  import qualified Data.NonEmpty.Class as NonEmptyC import qualified Data.NonEmpty as NonEmpty+import Data.Semigroup ((<>))+import Data.Tuple.HT (uncurry3, mapFst)  import qualified Test.QuickCheck as QC  ++generalFromHermitian ::+   (Shape.C sh, Class.Floating a) => Hermitian sh a -> General sh sh a+generalFromHermitian = Matrix.fromFull . Hermitian.toSquare+ stack ::    (Class.Floating a) =>-   (Hermitian ZeroInt a, General ZeroInt ZeroInt a, Hermitian ZeroInt a) ->+   (Hermitian ShapeInt a, General ShapeInt ShapeInt a, Hermitian ShapeInt a) ->    Bool stack (a,b,c) =-   let abc = Matrix.fromFull $ Hermitian.toSquare $ Hermitian.stack a b c-   in equalArray abc $ Matrix.adaptOrder abc $+   let abc = generalFromHermitian $ Hermitian.stack a b c+   in equalArray abc $          (Matrix.fromFull (Hermitian.toSquare a) ||| b-          ===+          !===           Matrix.adjoint b ||| Matrix.fromFull (Hermitian.toSquare c)) -covariance ::+split :: (Class.Floating a) => Hermitian (ShapeInt:+:ShapeInt) a -> Bool+split abc = equalArray abc $ uncurry3 Hermitian.stack $ Hermitian.split abc++gramian ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   General ZeroInt ZeroInt a -> Bool-covariance x =+   General ShapeInt ShapeInt a -> Bool+gramian x =    approxArray-      (Matrix.fromFull $ Hermitian.toSquare $ Hermitian.covariance x)-      (Matrix.adjoint x <#> x)+      (generalFromHermitian $ Hermitian.gramian x)+      (Matrix.adjoint x <> x) +gramianAdjoint ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   General ShapeInt ShapeInt a -> Bool+gramianAdjoint x =+   approxArray+      (generalFromHermitian $ Hermitian.gramianAdjoint x)+      (Matrix.adaptOrder x $ x <> Matrix.adjoint x) +gramianNonAdjoint ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   General ShapeInt ShapeInt a -> Bool+gramianNonAdjoint x =+   approxArray+      (Matrix.forceOrder (ArrMatrix.shapeOrder $ ArrMatrix.shape x) $+       Hermitian.gramian $ Matrix.adjoint x)+      (Hermitian.gramianAdjoint x)++congruenceDiagonal ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Vector ShapeInt ar, General ShapeInt ShapeInt a) -> Bool+congruenceDiagonal (d,a) =+   approxArray+      (generalFromHermitian $ Hermitian.congruenceDiagonal d a)+      (Matrix.adjoint a <> Matrix.scaleRowsReal d a)++congruenceDiagonalAdjoint ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (General ShapeInt ShapeInt a, Vector ShapeInt ar) -> Bool+congruenceDiagonalAdjoint (a,d) =+   approxMatrix 1e-5+      (generalFromHermitian $ Hermitian.congruenceDiagonalAdjoint a d)+      (Matrix.scaleColumnsReal d a <> Matrix.adjoint a)++congruenceDiagonalGramian ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   General ShapeInt ShapeInt a -> Bool+congruenceDiagonalGramian a =+   approxArray+      (Hermitian.congruenceDiagonal (Vector.one $ Matrix.height a) a)+      (Hermitian.gramian a)++congruence ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Hermitian ShapeInt a, General ShapeInt ShapeInt a) -> Bool+congruence (b,a) =+   approxArray+      (Hermitian.toSquare $ Hermitian.congruence b a)+      (Square.congruence (Hermitian.toSquare b) a)++congruenceAdjoint ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (General ShapeInt ShapeInt a, Hermitian ShapeInt a) -> Bool+congruenceAdjoint (a,b) =+   approxMatrix 1e-5+      (Hermitian.toSquare $ Hermitian.congruenceAdjoint a b)+      (Square.congruenceAdjoint a $ Hermitian.toSquare b)++congruenceCongruenceDiagonal ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Order -> (Vector ShapeInt ar, General ShapeInt ShapeInt a) -> Bool+congruenceCongruenceDiagonal order (d,a) =+   approxArray+      (Hermitian.congruenceDiagonal d a)+      (Hermitian.congruence (Hermitian.diagonal order d) a)++anticommutator ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (General ShapeInt ShapeInt a, General ShapeInt ShapeInt a) -> Bool+anticommutator (a,b) =+   approxArray+      (generalFromHermitian $ Hermitian.anticommutator a b)+      ((Matrix.adjoint b <> a) #+# (Matrix.adjoint a <> b))++anticommutatorCommutative ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (General ShapeInt ShapeInt a, General ShapeInt ShapeInt a) -> Bool+anticommutatorCommutative (a,b) =+   approxMatrix 1e-5+      (Hermitian.anticommutator a b)+      (Hermitian.anticommutator b a)++anticommutatorAdjoint ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (General ShapeInt ShapeInt a, General ShapeInt ShapeInt a) -> Bool+anticommutatorAdjoint (a,b) =+   approxArray+      (Matrix.forceOrder (ArrMatrix.shapeOrder $ ArrMatrix.shape b) $+       Hermitian.anticommutator (Matrix.adjoint a) (Matrix.adjoint b))+      (Hermitian.anticommutatorAdjoint a b)++ outer ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Order -> Vector ZeroInt a -> Bool+   Order -> Vector ShapeInt a -> Bool outer order x =    approxArray-      (Matrix.fromFull $ Hermitian.toSquare $ Hermitian.outer order x)+      (generalFromHermitian $ Hermitian.outer order x)       (Matrix.outer order x x)   genScaledVectors ::    (NonEmptyC.Gen f, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Gen.Vector a Int (ZeroInt, f (ar, Vector ZeroInt a))-genScaledVectors =-   flip Gen.mapGen Gen.vectorDim $ \maxElem size ->-      fmap ((,) size) $-      NonEmptyC.genOf $-         liftA2 (,) (Util.genReal maxElem) (Util.genArray maxElem size)+   Gen.VectorInt a (ShapeInt, f (ar, Vector ShapeInt a))+genScaledVectors = Gen.listOfVector ((,) <$> Gen.scalarReal <.*#> Gen.vector)  sumRank1 ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Order -> (ZeroInt, [(ar, Vector ZeroInt a)]) -> Bool+   Order -> (ShapeInt, [(ar, Vector ShapeInt a)]) -> Bool sumRank1 order (sh,xs) =    approxArray-      (Matrix.fromFull $ Hermitian.toSquare $ Hermitian.sumRank1 order sh xs)-      (foldl Vector.add (Vector.constant (MatrixShape.general order sh sh) 0) $+      (generalFromHermitian $ Hermitian.sumRank1 order sh xs)+      (Util.addMatrices (MatrixShape.general order sh sh) $        fmap (rank1 order) xs)  sumRank1NonEmpty ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Order -> NonEmpty.T [] (ar, Vector ZeroInt a) -> Bool+   Order -> NonEmpty.T [] (ar, Vector ShapeInt a) -> Bool sumRank1NonEmpty order xs =    approxArray-      (Matrix.fromFull $ Hermitian.toSquare $-       Hermitian.sumRank1NonEmpty order xs)-      (NonEmpty.foldl1 Vector.add $ fmap (rank1 order) xs)+      (generalFromHermitian $ Hermitian.sumRank1NonEmpty order xs)+      (NonEmpty.foldl1 (ArrMatrix.lift2 Vector.add) $ fmap (rank1 order) xs)  rank1 ::    (Eq size, Shape.C size, Class.Floating a) =>    Order -> (RealOf a, Vector size a) -> Matrix.General size size a-rank1 order (r,x) = Vector.scaleReal r $ Matrix.outer order x x+rank1 order (r,x) = Matrix.scaleReal r $ Matrix.outer order x x   genScaledVectorPairs ::    (NonEmptyC.Gen f, Class.Floating a) =>-   Gen.Vector a Int (ZeroInt, f (a, (Vector ZeroInt a, Vector ZeroInt a)))+   Gen.VectorInt a (ShapeInt, f (a, (Vector ShapeInt a, Vector ShapeInt a))) genScaledVectorPairs =    flip Gen.mapGen Gen.vectorDim $ \maxElem size ->       fmap ((,) size) $       NonEmptyC.genOf $          liftA2 (,) (Util.genElement maxElem) $-         liftA2 (,) (Util.genArray maxElem size) (Util.genArray maxElem size)+         liftA2 (,) (Util.genVector maxElem size) (Util.genVector maxElem size)  sumRank2 ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Order -> (ZeroInt, [(a, (Vector ZeroInt a, Vector ZeroInt a))]) -> Bool+   Order -> (ShapeInt, [(a, (Vector ShapeInt a, Vector ShapeInt a))]) -> Bool sumRank2 order (sh,xys) =    approxArray-      (Matrix.fromFull $ Hermitian.toSquare $ Hermitian.sumRank2 order sh xys)-      (foldl Vector.add (Vector.constant (MatrixShape.general order sh sh) 0) $+      (generalFromHermitian $ Hermitian.sumRank2 order sh xys)+      (Util.addMatrices (MatrixShape.general order sh sh) $        fmap (rank2 order) xys)  sumRank2NonEmpty ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Order -> NonEmpty.T [] (a, (Vector ZeroInt a, Vector ZeroInt a)) -> Bool+   Order -> NonEmpty.T [] (a, (Vector ShapeInt a, Vector ShapeInt a)) -> Bool sumRank2NonEmpty order xys =    approxArray-      (Matrix.fromFull $ Hermitian.toSquare $-       Hermitian.sumRank2NonEmpty order xys)-      (NonEmpty.foldl1 Vector.add $ fmap (rank2 order) xys)+      (generalFromHermitian $ Hermitian.sumRank2NonEmpty order xys)+      (NonEmpty.foldl1 (ArrMatrix.lift2 Vector.add) $ fmap (rank2 order) xys)  rank2 ::    (Eq size, Shape.C size, Class.Floating a) =>    Order -> (a, (Vector size a, Vector size a)) -> Matrix.General size size a rank2 order (a,(x,y)) =-   let ax = Vector.scale a x-   in Vector.add+   let ax = a.*|x+   in ArrMatrix.lift2 Vector.add          (Matrix.outer order ax y)          (Matrix.outer order y ax)   addAdjoint ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool+   Square ShapeInt a -> Bool addAdjoint x =    approxArray       (Hermitian.toSquare $ Hermitian.addAdjoint x)-      (Matrix.add (Matrix.adjoint x) x)+      (Matrix.adjoint x #+# x)  -multiplySquare ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Hermitian ZeroInt a -> Bool-multiplySquare a =-   approxArray (Hermitian.toSquare $ Hermitian.square a) (a <#> a) -squareSquare ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Hermitian ZeroInt a -> Bool-squareSquare a =-   approxArray-      (Hermitian.toSquare $ Hermitian.square a)-      (Square.square $ Hermitian.toSquare a)--{--multiplyPower ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Int, Hermitian ZeroInt a) -> Bool-multiplyPower (n,a) =-   let b = Hermitian.power (fromIntegral n) a-       c = nest n (Hermitian.multiply a) $ Hermitian.identityFrom a-   in approxArrayTol (1e-6 * (Vector.normInf1 b + Vector.normInf1 c)) b c--}-- multiplyVectorLeft ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Vector ZeroInt a, Hermitian ZeroInt a) -> Bool+   (Vector ShapeInt a, Hermitian ShapeInt a) -> Bool multiplyVectorLeft (x,a) =-   approxArray (x <# Hermitian.toSquare a) (x <# a)+   approxVector (x -*# Hermitian.toSquare a) (x -*# a)  multiplyVectorRight ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Hermitian ZeroInt a, Vector ZeroInt a) -> Bool+   (Hermitian ShapeInt a, Vector ShapeInt a) -> Bool multiplyVectorRight (a,x) =-   approxArray (Hermitian.toSquare a #> x) (a #> x)+   approxVector (Hermitian.toSquare a #*| x) (a #*| x)   multiplyLeft ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (General ZeroInt ZeroInt a, Hermitian ZeroInt a) -> Bool+   (General ShapeInt ShapeInt a, Hermitian ShapeInt a) -> Bool multiplyLeft (a,b) =-   approxMatrix 1e-5 (a <#> Hermitian.toSquare b) (a <#> b)+   approxMatrix 1e-5 (a ##*# Hermitian.toSquare b) (a ##*# b)  multiplyRight ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Hermitian ZeroInt a, General ZeroInt ZeroInt a) -> Bool+   (Hermitian ShapeInt a, General ShapeInt ShapeInt a) -> Bool multiplyRight (a,b) =-   approxArray (Hermitian.toSquare a <#> b) (a <#> b)+   approxArray (Hermitian.toSquare a #*## b) (a #*## b)  -determinant ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Hermitian ZeroInt a -> Bool-determinant a =-   approx-      (selectReal 1e-1 1e-5)-      (fromReal $ Hermitian.determinant a)-      (Square.determinant $ Hermitian.toSquare a)- choleskyQR ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix.Tall ZeroInt ZeroInt a -> QC.Property+   Matrix.Tall ShapeInt ShapeInt a -> QC.Property choleskyQR a =    let qr = HH.fromMatrix a        r = HH.tallExtractR qr@@ -219,17 +286,17 @@          (Matrix.scaleRows (Array.map signum $ Triangular.takeDiagonal r) $           Triangular.toSquare r)          (Triangular.toSquare $-          HermitianPD.decompose $ Hermitian.covariance $ Matrix.fromFull a)+          HermitianPD.decompose $ Hermitian.gramian $ Matrix.fromFull a)  -invertible ::-   (Shape.C sh, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Hermitian sh a -> Bool-invertible a = abs (Hermitian.determinant a) > 0.1+genInvertible ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Gen.MatrixInt a (Hermitian ShapeInt a)+genInvertible = Gen.condition Util.invertible Gen.hermitian  inverse ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Hermitian ZeroInt a -> Bool+   Hermitian ShapeInt a -> Bool inverse a =    approxArrayTol       (selectReal 1 1e-5)@@ -239,7 +306,7 @@  solve ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Hermitian ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Hermitian ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool solve (a, b) =    approxMatrix (selectReal 1 1e-5)       (Hermitian.solve a b)@@ -249,19 +316,13 @@  genPositiveDefinite ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Gen.Matrix a Int Int (Hermitian ZeroInt a)+   Gen.MatrixInt a (Hermitian ShapeInt a) genPositiveDefinite =-   flip Gen.mapGenDim Gen.squareDim $-         \maxElem maxDim width@(Shape.ZeroBased w) -> do-      height <- zeroInt <$> QC.choose (w,maxDim)-      order <- Util.genOrder-      Hermitian.covariance . Matrix.fromFull <$>-         Util.genArray maxElem (MatrixShape.tall order height width)-            `QC.suchThat` Util.fullRankTall+   Hermitian.gramian . Matrix.fromFull <$> Gen.gramian Gen.fullRankTall  determinantPD ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Hermitian ZeroInt a -> Bool+   Hermitian ShapeInt a -> Bool determinantPD a =    approxReal (selectReal 100 1e-4)       (Hermitian.determinant a)@@ -269,7 +330,7 @@  inversePD ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Hermitian ZeroInt a -> Bool+   Hermitian ShapeInt a -> Bool inversePD a =    approxArrayTol (selectReal 1000 1e-4)       (Hermitian.inverse a)@@ -277,7 +338,7 @@  solvePD ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Hermitian ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Hermitian ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool solvePD (a,b) =    approxArrayTol (selectReal 1000 1e-4)       (Hermitian.solve a b)@@ -285,7 +346,7 @@  solveDecomposedPD ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Hermitian ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Hermitian ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool solveDecomposedPD (a,b) =    approxArrayTol (selectReal 1e-1 1e-6)       (HermitianPD.solve a b)@@ -295,7 +356,7 @@  eigenvaluesDeterminant ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Hermitian ZeroInt a -> Bool+   Hermitian ShapeInt a -> Bool eigenvaluesDeterminant a =    approxReal       (selectReal 1e-1 1e-5)@@ -304,23 +365,22 @@  eigensystem ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Hermitian ZeroInt a -> Bool+   Hermitian ShapeInt a -> Bool eigensystem a =-   let (q,d) = Hermitian.eigensystem a-   in  approxMatrix 1e-4-         (Hermitian.toSquare a)-         (q <#> Matrix.scaleRowsReal d (Square.adjoint q))+   approxMatrix 1e-4 a $+   uncurry Hermitian.congruenceDiagonalAdjoint $+   mapFst Matrix.fromFull $ Hermitian.eigensystem a    checkForAll ::    (Show a, QC.Testable test) =>-   Gen.T tag dim a -> (a -> test) -> Tagged tag QC.Property+   Gen.T dim tag a -> (a -> test) -> Tagged tag QC.Property checkForAll gen = Util.checkForAll (Gen.run gen 3 5)  checkForAllExtra ::    (Show a, Show b, QC.Testable test) =>-   QC.Gen a -> Gen.T tag dim b ->+   QC.Gen a -> Gen.T dim tag b ->    (a -> b -> test) -> Tagged tag QC.Property checkForAllExtra = Gen.withExtra checkForAll @@ -331,10 +391,50 @@ testsVar =    ("index",       checkForAll (Indexed.genMatrixIndex Gen.hermitian) Indexed.unitDot) :+   ("forceOrder",+      checkForAllExtra genOrder+         ((,) <$> Gen.hermitian <#*|> Gen.vector) Generic.forceOrder) :+   ("addDistributive",+      checkForAll+         (Generic.genDistribution Gen.hermitian)+         Generic.addDistributive) :+   ("subDistributive",+      checkForAll+         (Generic.genDistribution Gen.hermitian)+         Generic.subDistributive) :+    ("stack",       checkForAll (Gen.stack3 Gen.hermitian Gen.matrix Gen.hermitian) stack) :-   ("covariance",-      checkForAll Gen.matrix covariance) :+   ("split",+      checkForAll Gen.hermitian split) :+   ("gramian",+      checkForAll Gen.matrix gramian) :+   ("gramianAdjoint",+      checkForAll Gen.matrix gramianAdjoint) :+   ("gramianNonAdjoint",+      checkForAll Gen.matrix gramianNonAdjoint) :+   ("congruenceDiagonal",+      checkForAll ((,) <$> Gen.vectorReal <-*#> Gen.matrix) congruenceDiagonal) :+   ("congruence",+      checkForAll ((,) <$> Gen.hermitian <#*#> Gen.matrix) congruence) :+   ("congruenceDiagonalAdjoint",+      checkForAll+         ((,) <$> Gen.matrix <#*|> Gen.vectorReal) congruenceDiagonalAdjoint) :+   ("congruenceDiagonalGramian",+      checkForAll Gen.matrix congruenceDiagonalGramian) :+   ("congruenceAdjoint",+      checkForAll ((,) <$> Gen.matrix <#*#> Gen.hermitian) congruenceAdjoint) :+   ("congruenceCongruenceDiagonal",+      checkForAllExtra genOrder+         ((,) <$>+            Gen.vectorReal <-*#> Gen.matrix) congruenceCongruenceDiagonal) :+   ("anticommutator",+      checkForAll ((,) <$> Gen.matrix <#=#> Gen.matrix) anticommutator) :+   ("anticommutatorCommutative",+      checkForAll ((,) <$> Gen.matrix <#=#> Gen.matrix)+         anticommutatorCommutative) :+   ("anticommutatorAdjoint",+      checkForAll ((,) <$> Gen.matrix <#=#> Gen.matrix) anticommutatorAdjoint) :    ("outer",       checkForAllExtra genOrder Gen.vector outer) :    ("sumRank1",@@ -349,39 +449,41 @@    ("addAdjoint",       checkForAll Gen.square addAdjoint) :    ("multiplySquare",-      checkForAll Gen.hermitian multiplySquare) :+      checkForAll Gen.hermitian Multiply.multiplySquare) :    ("squareSquare",-      checkForAll Gen.hermitian squareSquare) :+      checkForAll Gen.hermitian Multiply.squareSquare) :+   ("power",+      checkForAllExtra (QC.choose (0,10)) Gen.hermitian Multiply.power) :     ("multiplyVectorLeft",-      checkForAll ((,) <$> Gen.vector <.*|> Gen.hermitian) multiplyVectorLeft) :+      checkForAll ((,) <$> Gen.vector <-*#> Gen.hermitian) multiplyVectorLeft) :    ("multiplyVectorRight",-      checkForAll ((,) <$> Gen.hermitian <|*.> Gen.vector) multiplyVectorRight) :+      checkForAll ((,) <$> Gen.hermitian <#*|> Gen.vector) multiplyVectorRight) :    ("multiplyLeft",-      checkForAll ((,) <$> Gen.matrix <|*|> Gen.hermitian) multiplyLeft) :+      checkForAll ((,) <$> Gen.matrix <#*#> Gen.hermitian) multiplyLeft) :    ("multiplyRight",-      checkForAll ((,) <$> Gen.hermitian <|*|> Gen.matrix) multiplyRight) :+      checkForAll ((,) <$> Gen.hermitian <#*#> Gen.matrix) multiplyRight) :     ("determinant",-      checkForAll Gen.hermitian determinant) :+      checkForAll Gen.hermitian Divide.determinant) :    ("choleskyQR",       checkForAll Gen.tall choleskyQR) :     ("inverse",-      checkForAll (Gen.hermitianCond invertible) inverse) :+      checkForAll genInvertible inverse) :    ("solve",-      checkForAll-         ((,) <$> Gen.hermitianCond invertible <|\|> Gen.matrix) solve) :+      checkForAll ((,) <$> genInvertible <#\#> Gen.matrix) solve) :+   Divide.testsVar genInvertible ++     ("determinantPD",       checkForAll genPositiveDefinite determinantPD) :    ("inversePD",       checkForAll genPositiveDefinite inversePD) :    ("solvePD",-      checkForAll ((,) <$> genPositiveDefinite <|\|> Gen.matrix) solvePD) :+      checkForAll ((,) <$> genPositiveDefinite <#\#> Gen.matrix) solvePD) :    ("solveDecomposedPD",       checkForAll-         ((,) <$> genPositiveDefinite <|\|> Gen.matrix) solveDecomposedPD) :+         ((,) <$> genPositiveDefinite <#\#> Gen.matrix) solveDecomposedPD) :     ("eigenvaluesDeterminant",       checkForAll Gen.hermitian eigenvaluesDeterminant) :
test/Test/Indexed.hs view
@@ -2,52 +2,48 @@ module Test.Indexed where  import qualified Test.Generator as Gen-import Test.Utility (maybeProperty)+import Test.Utility (NonEmptyInt) -import qualified Numeric.LAPACK.Matrix.Shape.Box as Box import qualified Numeric.LAPACK.Matrix as Matrix import qualified Numeric.LAPACK.Vector as Vector-import Numeric.LAPACK.Matrix ((#!), (#>))+import Numeric.LAPACK.Matrix (Matrix, (#!), (#*|))+import Numeric.LAPACK.Vector ((-*|))  import qualified Numeric.Netlib.Class as Class -import qualified Data.Array.Comfort.Storable as Array import qualified Data.Array.Comfort.Shape as Shape-import Data.Array.Comfort.Storable (Array) -import qualified Data.Traversable as Trav-import Data.Maybe.HT (toMaybe)- import qualified Test.QuickCheck as QC  +type GenMatrixNonEmpty = Gen.Matrix NonEmptyInt NonEmptyInt+ genMatrixIndexGen ::    (Class.Floating a) =>    (array -> [ix]) ->-   Gen.Matrix a Int Int array ->-   Gen.Matrix a Int Int (Maybe ix, array)+   GenMatrixNonEmpty a array ->+   GenMatrixNonEmpty a (ix, array) genMatrixIndexGen indices gen =-   flip Gen.mapGen gen $ \_maxElem m -> do-      let set = indices m-      ij <- Trav.mapM QC.elements $ toMaybe (not $ null set) set+   flip Gen.mapQC gen $ \m -> do+      ij <- QC.elements $ indices m       return (ij,m)  genMatrixIndex ::-   (Shape.Indexed shape, Class.Floating a) =>-   Gen.Matrix a Int Int (Array shape a) ->-   Gen.Matrix a Int Int (Maybe (Shape.Index shape), Array shape a)-genMatrixIndex = genMatrixIndexGen (Shape.indices . Array.shape)+   (Matrix.Indexed typ,+    Matrix.HeightOf typ ~ height, Shape.Indexed height,+    Matrix.WidthOf typ ~ width, Shape.Indexed width,+    Class.Floating a) =>+   GenMatrixNonEmpty a (Matrix typ a) ->+   GenMatrixNonEmpty a (Shape.Index (height,width), Matrix typ a)+genMatrixIndex = genMatrixIndexGen Matrix.indices  unitDot ::-   (Matrix.Indexed shape, Matrix.MultiplyRight shape,-    Box.HeightOf shape ~ height, Shape.Indexed height, Eq height,-    Box.WidthOf shape ~ width, Shape.Indexed width,+   (Matrix.Indexed typ, Matrix.MultiplyVector typ,+    Matrix.HeightOf typ ~ height, Shape.Indexed height, Eq height,+    Matrix.WidthOf typ ~ width, Shape.Indexed width, Eq width,     Class.Floating a, Eq a) =>-   (Maybe (Shape.Index height, Shape.Index width), Array shape a) -> QC.Property-unitDot (mij,m) =-   maybeProperty $-   flip fmap mij $ \(i,j) ->-      m#!(i,j) ==-      Vector.dot-         (Vector.unit (Matrix.height m) i)-         (m #> Vector.unit (Matrix.width m) j)+   (Shape.Index (height,width), Matrix typ a) -> Bool+unitDot ((i,j),m) =+   m#!(i,j) ==+   Vector.unit (Matrix.height m) i  -*|+      (m #*| Vector.unit (Matrix.width m) j)
test/Test/Logic.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE Rank2Types #-}@@ -12,6 +13,7 @@ import qualified Data.Ref as Ref import Data.STRef (newSTRef, writeSTRef, readSTRef) +import qualified Data.Array.Comfort.Shape as Shape import Data.Array.Comfort.Shape ((:+:)((:+:)))  import qualified Control.Monad.Trans.Class as MT@@ -54,7 +56,9 @@ type System s = AppMn.T (Sys.T (M s)) ()  -example :: Int -> MatchMode -> QC.Gen ([Int], Match)+type ShapeInt = Shape.ZeroBased Int++example :: Int -> MatchMode -> QC.Gen ([ShapeInt], Match) example =    runSTInGen (do       a <- Sys.globalVariable@@ -73,14 +77,23 @@ choose :: (Random a) => (Int -> (a,a)) -> M s a choose f = liftGen . QC.choose . f . fst =<< M MRWS.ask -(<!=) :: Variable s Int -> Variable s Int -> System s+liftZeroBased ::+   (Functor f) =>+   (a -> f b) -> Shape.ZeroBased a -> f (Shape.ZeroBased b)+liftZeroBased f (Shape.ZeroBased x) = Shape.ZeroBased <$> f x++(<!=) :: Variable s ShapeInt -> Variable s ShapeInt -> System s va <!= vb  =  AppMn.Cons $ do-   assignmentM (\a -> choose (\ maxk -> (a,maxk))) va vb-   assignmentM (\b -> choose (\_maxk -> (0,b))) vb va+   assignmentM (liftZeroBased $ \a -> choose (\ maxk -> (a,maxk))) va vb+   assignmentM (liftZeroBased $ \b -> choose (\_maxk -> (0,b))) vb va  -class Dim dim where chooseDim :: M s dim-instance Dim Int where chooseDim = choose ((,) 0)+class (Shape.C dim) => Dim dim where chooseDim :: M s dim+instance (i ~ Int) => Dim (Shape.ZeroBased i) where+   chooseDim = fmap Shape.ZeroBased $ choose ((,) 0)+instance Dim () where chooseDim = return ()+instance (Dim dimA, Dim dimB) => Dim (dimA,dimB) where+   chooseDim = liftA2 (,) chooseDim chooseDim instance (Dim dimA, Dim dimB) => Dim (dimA:+:dimB) where    chooseDim = liftA2 (:+:) chooseDim chooseDim @@ -110,6 +123,10 @@    Sys.assignment3 (:+:) va vb vab    Sys.assignment2 (\(a:+:_) -> a) vab va    Sys.assignment2 (\(_:+:b) -> b) vab vb++(!*!) ::+   Variable s dimA -> Variable s dimB -> Variable s (dimA,dimB) -> System s+(!*!) va vb vab = AppMn.Cons $ Rule.pair va vb vab   runSTInGen :: (forall s. M s b) -> Int -> MatchMode -> QC.Gen (b, Match)
+ test/Test/LowerUpper.hs view
@@ -0,0 +1,221 @@+{-# LANGUAGE TypeFamilies #-}+module Test.LowerUpper (testsVar) where++import qualified Test.Divide as Divide+import qualified Test.Generator as Gen+import qualified Test.Utility as Util+import Test.Generator ((<#\#>), (<#*#>))+import Test.Utility (Tagged, approx, approxMatrix, maybeConjugate)++import qualified Numeric.LAPACK.Linear.LowerUpper as LU+import qualified Numeric.LAPACK.Matrix.Permutation as PermMatrix+import qualified Numeric.LAPACK.Matrix.Extent as Extent+import qualified Numeric.LAPACK.Matrix.Square as Square+import qualified Numeric.LAPACK.Matrix as Matrix+import qualified Numeric.LAPACK.Permutation as Perm+import Numeric.LAPACK.Matrix.Square (Square)+import Numeric.LAPACK.Matrix (ShapeInt, (#*#), (#*##))+import Numeric.LAPACK.Scalar (RealOf, selectReal)++import qualified Numeric.Netlib.Class as Class++import Control.Applicative (liftA2, (<$>))++import Data.Semigroup ((<>))++import qualified Test.QuickCheck as QC+++toFromTallMatrix ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Matrix.Tall ShapeInt ShapeInt a -> Bool+toFromTallMatrix a =+   approxMatrix 1e-5 a (LU.toMatrix $ LU.fromMatrix a)++{-+Strictly wide matrices are problematic,+because a full rank wide matrix can have a leading column+consisting entirely of zeros.+To prevent this, the LU decomposition would need column pivoting.+For now we restrict to Square matrices.+-}+toFromSquareMatrix ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Square ShapeInt a -> Bool+toFromSquareMatrix a =+   approxMatrix 1e-5 a (LU.toMatrix $ LU.fromMatrix a)+++multiplyPApply ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (LU.Inversion, LU.Inversion) ->+   (Square ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+multiplyPApply (inv0,inv1) (a,b) =+   let lu = LU.fromMatrix a+   in approxMatrix (selectReal 1e-1 1e-5)+         (LU.multiplyP (inv0<>inv1) lu b)+         (Perm.apply inv0 (PermMatrix.toPermutation $ LU.extractP inv1 lu) b)++multiplyP ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   LU.Inversion -> (Square ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+multiplyP inv (a,b) =+   let lu = LU.fromMatrix a+   in approxMatrix (selectReal 1e-1 1e-5)+         (LU.multiplyP inv lu b)+         (LU.extractP inv lu #*## b)++multiplyL ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   LU.Transposition ->+   (Square ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+multiplyL trans (a,b) =+   let lu = LU.fromMatrix a+   in approxMatrix (selectReal 1e-1 1e-5)+         (LU.wideMultiplyL trans lu b)+         (Matrix.multiplySquare trans (LU.extractL lu) b)++wideMultiplyL ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   LU.Transposition ->+   (Square ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+wideMultiplyL trans (a,b) =+   let lu = LU.fromMatrix a+   in approxMatrix (selectReal 1e-1 1e-5)+         (LU.wideMultiplyL trans lu b)+         (Matrix.multiplySquare trans (LU.wideExtractL lu) b)++multiplyU ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   LU.Transposition ->+   (Square ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+multiplyU trans (a,b) =+   let lu = LU.fromMatrix a+   in approxMatrix (selectReal 1e-1 1e-5)+         (LU.tallMultiplyU trans lu b)+         (Matrix.multiplySquare trans (LU.extractU lu) b)++tallMultiplyU ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   LU.Transposition ->+   (Matrix.Tall ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+tallMultiplyU trans (a,b) =+   let lu = LU.fromMatrix a+   in approxMatrix (selectReal 1e-1 1e-5)+         (LU.tallMultiplyU trans lu b)+         (Matrix.multiplySquare trans (LU.tallExtractU lu) b)++multiplySquareFull ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Square ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+multiplySquareFull (a,b) =+   approxMatrix (selectReal 1e-1 1e-5)+      (a #*## b)+      (LU.multiplyFull (LU.mapExtent Extent.fromSquare $ LU.fromMatrix a) b)++multiplyTallFull ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Matrix.Tall ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+multiplyTallFull (a,b) =+   approxMatrix (selectReal 1e-1 1e-5)+      (a #*# b)+      (LU.multiplyFull (LU.mapExtent Extent.generalizeTall $ LU.fromMatrix a) b)++determinant ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Square ShapeInt a -> Bool+determinant a =+   approx (selectReal 1e-1 1e-5)+      (Square.determinant a)+      (LU.determinant $ LU.fromMatrix a)++wideSolveL ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (LU.Transposition, LU.Conjugation) ->+   (Square ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+wideSolveL (trans,conj) (a,b) =+   let lu = LU.fromMatrix a+       l = maybeConjugate conj $ LU.wideExtractL lu+   in approxMatrix (selectReal 1e-1 1e-5)+         (LU.wideSolveL trans conj lu b)+         (Matrix.solve trans l b)++tallSolveU ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (LU.Transposition, LU.Conjugation) ->+   (Matrix.Tall ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+tallSolveU (trans,conj) (a,b) =+   let lu = LU.fromMatrix a+       u = maybeConjugate conj $ LU.tallExtractU lu+   in approxMatrix (selectReal 1e-1 1e-5)+         (LU.tallSolveU trans conj lu b)+         (Matrix.solve trans u b)++solve ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Square ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+solve (a,b) =+   approxMatrix (selectReal 1e-1 1e-5)+      (Square.solve a b)+      (LU.solve (LU.fromMatrix a) b)+++checkForAll ::+   (Show a, QC.Testable test) =>+   Gen.T dim tag a -> (a -> test) -> Tagged tag QC.Property+checkForAll gen = Util.checkForAll (Gen.run gen 3 5)++checkForAllExtra ::+   (Show a, Show b, QC.Testable test) =>+   QC.Gen a -> Gen.T dim tag b ->+   (a -> b -> test) -> Tagged tag QC.Property+checkForAllExtra = Gen.withExtra checkForAll+++testsVar ::+   (Show a, Class.Floating a, Eq a, RealOf a ~ ar, Class.Real ar) =>+   [(String, Tagged a QC.Property)]+testsVar =+   ("toFromTallMatrix",+      checkForAll Gen.fullRankTall toFromTallMatrix) :+   ("toFromSquareMatrix",+      checkForAll Gen.invertible toFromSquareMatrix) :+   ("multiplyPApply",+      checkForAllExtra+         (liftA2 (,) QC.arbitraryBoundedEnum QC.arbitraryBoundedEnum)+         ((,) <$> Gen.invertible <#*#> Gen.matrix) multiplyPApply) :+   ("multiplyP",+      checkForAllExtra QC.arbitraryBoundedEnum+         ((,) <$> Gen.invertible <#*#> Gen.matrix) multiplyP) :+   ("multiplyL",+      checkForAllExtra QC.arbitraryBoundedEnum+         ((,) <$> Gen.invertible <#*#> Gen.matrix) multiplyL) :+   ("wideMultiplyL",+      checkForAllExtra QC.arbitraryBoundedEnum+         ((,) <$> Gen.invertible <#*#> Gen.matrix) wideMultiplyL) :+   ("multiplyU",+      checkForAllExtra QC.arbitraryBoundedEnum+         ((,) <$> Gen.invertible <#*#> Gen.matrix) multiplyU) :+   ("tallMultiplyU",+      checkForAllExtra QC.arbitraryBoundedEnum+         ((,) <$> Gen.fullRankTall <#*#> Gen.matrix) tallMultiplyU) :+   ("multiplySquareFull",+      checkForAll+         ((,) <$> Gen.invertible <#*#> Gen.matrix) multiplySquareFull) :+   ("multiplyTallFull",+      checkForAll+         ((,) <$> Gen.fullRankTall <#*#> Gen.matrix) multiplyTallFull) :+   ("determinant",+      checkForAll Gen.invertible determinant) :+   ("wideSolveL",+      checkForAllExtra+         (liftA2 (,) QC.arbitraryBoundedEnum QC.arbitraryBoundedEnum)+         ((,) <$> Gen.invertible <#\#> Gen.matrix) wideSolveL) :+   ("tallSolveU",+      checkForAllExtra+         (liftA2 (,) QC.arbitraryBoundedEnum QC.arbitraryBoundedEnum)+         ((,) <$> Gen.fullRankTall <#*#> Gen.matrix) tallSolveU) :+   ("solve",+      checkForAll ((,) <$> Gen.invertible <#\#> Gen.matrix) solve) :+   Divide.testsVar (LU.fromMatrix <$> Gen.invertible) +++   []
test/Test/Matrix.hs view
@@ -2,23 +2,30 @@ {-# LANGUAGE TypeOperators #-} module Test.Matrix (testsVar) where +import qualified Test.Generic as Generic import qualified Test.Indexed as Indexed import qualified Test.Generator as Gen import qualified Test.Utility as Util import Test.Generator-         ((<|*|>), (<|*.>), (<.*.>), (<***>), (<|=|>), (<|||>), (<===>))+         ((<.*#>), (<#*#>), (<#*|>), (<-*|>), (<|*->),+          (<><>), (<|||>), (<===>)) import Test.Utility          (equalArray, approx, approxArray, approxMatrix,-          maybeProperty, genOrder, Tagged(Tagged), TaggedGen)+          approxVector, equalVector, genOrder,+          Tagged(Tagged), TaggedGen, NonEmptyInt, EInt, (!|||), (!===))  import qualified Numeric.LAPACK.Matrix.Triangular as Triangular-import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape import qualified Numeric.LAPACK.Matrix.Square as Square+import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape+import qualified Numeric.LAPACK.Matrix.Extent as Extent+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix as Matrix import qualified Numeric.LAPACK.Vector as Vector+import Numeric.LAPACK.Matrix.Square (Square)+import Numeric.LAPACK.Matrix.Array (ArrayMatrix) import Numeric.LAPACK.Matrix-         (General, ZeroInt, zeroInt, (#>), (<#>), (|||), (===))-import Numeric.LAPACK.Vector (Vector)+         (General, ShapeInt, shapeInt, (##*#), (#*#), (#*##), (#*|), (|||), (===))+import Numeric.LAPACK.Vector (Vector, (.*|)) import Numeric.LAPACK.Scalar (RealOf, conjugate)  import qualified Numeric.Netlib.Class as Class@@ -26,42 +33,41 @@ import qualified Data.Array.Comfort.Boxed as BoxedArray import qualified Data.Array.Comfort.Storable as Array import qualified Data.Array.Comfort.Shape as Shape-import Data.Array.Comfort.Storable (Array) import Data.Array.Comfort.Shape ((:+:)) -import Control.Applicative (liftA2, (<$>))+import qualified Control.Monad.Trans.Reader as MR+import qualified Control.Functor.HT as FuncHT+import Control.Applicative (liftA2, liftA3, pure, (<$>)) -import Data.Traversable (forM)-import Data.Maybe.HT (toMaybe)-import Data.Tuple.HT (mapPair, swap)+import Data.Tuple.HT (mapTriple, mapPair, swap)  import qualified Test.QuickCheck as QC   genArray ::-   (Shape.C shape, Class.Floating a) => shape -> QC.Gen (Array shape a)+   (Shape.C shape, Class.Floating a) => shape -> QC.Gen (ArrayMatrix shape a) genArray = Util.genArray 10   dotProduct ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Vector ZeroInt a, Vector ZeroInt a) -> Bool+   (Vector ShapeInt a, Vector ShapeInt a) -> Bool dotProduct (x,y) =    approx 1e-5       (Vector.dot x y)       (Matrix.toScalar $-       Matrix.singleRow MatrixShape.RowMajor x <#>+       Matrix.singleRow MatrixShape.RowMajor x #*#        Matrix.singleColumn MatrixShape.ColumnMajor y)  innerDot ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Vector ZeroInt a, Vector ZeroInt a) -> Bool+   (Vector ShapeInt a, Vector ShapeInt a) -> Bool innerDot (x,y) =    approx 1e-5 (Vector.inner x y) (Vector.dot (Vector.conjugate x) y)  tensorProductTranspose ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   MatrixShape.Order -> (Vector ZeroInt a, Vector ZeroInt a) -> Bool+   MatrixShape.Order -> (Vector ShapeInt a, Vector ShapeInt a) -> Bool tensorProductTranspose order (x,y) =    approxArray       (Matrix.transpose (Matrix.tensorProduct order x y))@@ -69,7 +75,7 @@  outerTranspose ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   MatrixShape.Order -> (Vector ZeroInt a, Vector ZeroInt a) -> Bool+   MatrixShape.Order -> (Vector ShapeInt a, Vector ShapeInt a) -> Bool outerTranspose order (x,y) =    approxArray       (Matrix.transpose (Matrix.outer order x y))@@ -78,28 +84,28 @@  tensorProduct ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   MatrixShape.Order -> (Vector ZeroInt a, Vector ZeroInt a) -> Bool+   MatrixShape.Order -> (Vector ShapeInt a, Vector ShapeInt a) -> Bool tensorProduct order (x,y) =    approxArray       (Matrix.tensorProduct order x y)-      (Matrix.singleColumn order x <#> Matrix.singleRow order y)+      (Matrix.singleColumn order x #*# Matrix.singleRow order y)  tensorProductMul ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Triangular.Diagonal ZeroInt a,-    Matrix.General ZeroInt ZeroInt a,-    Triangular.Diagonal ZeroInt a) ->+   (Triangular.Diagonal ShapeInt a,+    Matrix.General ShapeInt ShapeInt a,+    Triangular.Diagonal ShapeInt a) ->    Bool tensorProductMul (x,m,y) =-   let xmy = x <#> m <#> y+   let xmy = (x #*## m) ##*# y    in approxArray xmy-         (Vector.mul m-            (Matrix.tensorProduct (MatrixShape.fullOrder $ Array.shape xmy)+         (ArrMatrix.lift2 Vector.mul m+            (Matrix.tensorProduct (MatrixShape.fullOrder $ ArrMatrix.shape xmy)                (Triangular.takeDiagonal x) (Triangular.takeDiagonal y)))  outerTensorProduct ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   MatrixShape.Order -> (Vector ZeroInt a, Vector ZeroInt a) -> Bool+   MatrixShape.Order -> (Vector ShapeInt a, Vector ShapeInt a) -> Bool outerTensorProduct order (x,y) =    approxArray       (Matrix.outer order x y)@@ -107,19 +113,16 @@  genScaledVectorPairs ::    (Class.Floating a) =>-   Gen.Matrix a Int Int-      ((ZeroInt, ZeroInt), [(a, (Vector ZeroInt a, Vector ZeroInt a))])+   Gen.MatrixInt a+      ((ShapeInt, ShapeInt), [(a, (Vector ShapeInt a, Vector ShapeInt a))]) genScaledVectorPairs =-   flip Gen.mapGen Gen.matrixDims $ \maxElem size@(height,width) ->-      fmap ((,) size) $-      QC.listOf $-         liftA2 (,) (Util.genElement maxElem) $-         liftA2 (,) (Util.genArray maxElem height) (Util.genArray maxElem width)+   Gen.listOfMatrix+      ((,) <$> Gen.scalar <.*#> ((,) <$> Gen.vector <|*-> Gen.vector))  sumRank1 ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    MatrixShape.Order ->-   ((ZeroInt,ZeroInt), [(a, (Vector ZeroInt a, Vector ZeroInt a))]) -> Bool+   ((ShapeInt,ShapeInt), [(a, (Vector ShapeInt a, Vector ShapeInt a))]) -> Bool sumRank1 order (size,xys) =    approxArray       (case order of@@ -127,14 +130,13 @@          MatrixShape.RowMajor ->             Matrix.adjoint $             Matrix.sumRank1 (swap size) $ map (mapPair (conjugate, swap)) xys)-      (foldl Vector.add-         (Vector.constant (uncurry (MatrixShape.general order) size) 0)-         (map (\(a,(x,y)) -> Matrix.outer order (Vector.scale a x) y) xys))+      (Util.addMatrices (uncurry (MatrixShape.general order) size)+         (map (\(a,(x,y)) -> Matrix.outer order (a.*|x) y) xys))   outerTrace ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   MatrixShape.Order -> (Vector ZeroInt a, Vector ZeroInt a) -> Bool+   MatrixShape.Order -> (Vector ShapeInt a, Vector ShapeInt a) -> Bool outerTrace order (x,y) =    approx 1e-5       (Vector.inner y x)@@ -143,14 +145,14 @@ outerInner ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    MatrixShape.Order ->-   (Vector ZeroInt a, Vector ZeroInt a, Vector ZeroInt a) -> Bool+   (Vector ShapeInt a, Vector ShapeInt a, Vector ShapeInt a) -> Bool outerInner order (x,y,z) =-   approxArray (Matrix.outer order x y #> z) (Vector.scale (Vector.inner y z) x)+   approxVector (Matrix.outer order x y #*| z) (Vector.inner y z .*| x)   tensorTrace ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   MatrixShape.Order -> (Vector ZeroInt a, Vector ZeroInt a) -> Bool+   MatrixShape.Order -> (Vector ShapeInt a, Vector ShapeInt a) -> Bool tensorTrace order (x,y) =    approx 1e-5 (Vector.dot y x)       (Square.trace $ Square.fromGeneral $ Matrix.tensorProduct order x y)@@ -158,25 +160,61 @@ tensorDot ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    MatrixShape.Order ->-   (Vector ZeroInt a, Vector ZeroInt a, Vector ZeroInt a) -> Bool+   (Vector ShapeInt a, Vector ShapeInt a, Vector ShapeInt a) -> Bool tensorDot order (x,y,z) =+   approxVector (Matrix.tensorProduct order x y #*| z) (Vector.dot y z .*| x)+++kroneckerTranspose ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (General ShapeInt ShapeInt a, General ShapeInt ShapeInt a) -> Bool+kroneckerTranspose (a,b) =    approxArray-      (Matrix.tensorProduct order x y #> z) (Vector.scale (Vector.dot y z) x)+      (Matrix.transpose $ Matrix.kronecker a b)+      (Matrix.kronecker (Matrix.transpose a) (Matrix.transpose b)) +kroneckerTrace ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Square ShapeInt a, Square ShapeInt a) -> Bool+kroneckerTrace (a,b) =+   approx 1e-5+      (Square.trace $ Matrix.kronecker a b)+      (Square.trace a * Square.trace b) +kroneckerProduct ::+   (Shape.C s0, Shape.C s1, Shape.C s2, Eq s0, Eq s1, Eq s2,+    Shape.C t0, Shape.C t1, Shape.C t2, Eq t0, Eq t1, Eq t2,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   ((General s0 s1 a, General t0 t1 a),+    (General s1 s2 a, General t1 t2 a)) -> Bool+kroneckerProduct ((a,b),(c,d)) =+   approxArray+      (Matrix.kronecker a b #*# Matrix.kronecker c d)+      (Matrix.kronecker (a #*# c) (b #*# d))++kronecker3 ::+   (Shape.C s0, Shape.C s1, Shape.C s2, Shape.C s3, Eq s0, Eq s1, Eq s2, Eq s3,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (General s0 s1 a, General s1 s2 a, General s2 s3 a) -> Bool+kronecker3 (a,b,c) =+   approxVector+      (Matrix.kronecker a (Matrix.transpose c) #*| Matrix.toRowMajor b)+      (Matrix.toRowMajor $ a #*# b #*# c)++ genZeroColumns ::-   (Class.Floating a) => TaggedGen a (Matrix.Tall ZeroInt ZeroInt a)+   (Class.Floating a) => TaggedGen a (Matrix.Tall ShapeInt ShapeInt a) genZeroColumns = Tagged $ do-   height <- zeroInt <$> QC.choose (0,5)+   height <- shapeInt <$> QC.choose (0,5)    order <- genOrder-   genArray (MatrixShape.tall order height (zeroInt 0))+   genArray (MatrixShape.tall order height (shapeInt 0))  -reverseNoRows :: (Class.Floating a) => Matrix.Wide ZeroInt ZeroInt a -> Bool+reverseNoRows :: (Class.Floating a) => Matrix.Wide ShapeInt ShapeInt a -> Bool reverseNoRows x =    equalArray x $ Matrix.reverseRows x -reverseNoColumns :: (Class.Floating a) => Matrix.Tall ZeroInt ZeroInt a -> Bool+reverseNoColumns :: (Class.Floating a) => Matrix.Tall ShapeInt ShapeInt a -> Bool reverseNoColumns x =    equalArray x $ Matrix.reverseColumns x @@ -184,21 +222,21 @@  genMatrix2EqHeight ::    (Class.Floating a) =>-   Gen.Matrix a Int (Int:+:Int)-      (General ZeroInt ZeroInt a, General ZeroInt ZeroInt a)+   Gen.Matrix ShapeInt (ShapeInt:+:ShapeInt) a+      (General ShapeInt ShapeInt a, General ShapeInt ShapeInt a) genMatrix2EqHeight = (,) <$> Gen.matrix <|||> Gen.matrix  genMatrix2EqWidth ::    (Class.Floating a) =>-   Gen.Matrix a (Int:+:Int) Int-      (General ZeroInt ZeroInt a, General ZeroInt ZeroInt a)+   Gen.Matrix (ShapeInt:+:ShapeInt) ShapeInt a+      (General ShapeInt ShapeInt a, General ShapeInt ShapeInt a) genMatrix2EqWidth = (,) <$> Gen.matrix <===> Gen.matrix -reverseRows :: (Class.Floating a) => General ZeroInt ZeroInt a -> Bool+reverseRows :: (Class.Floating a) => General ShapeInt ShapeInt a -> Bool reverseRows x =    equalArray x $ Matrix.reverseRows (Matrix.reverseRows x) -reverseColumns :: (Class.Floating a) => General ZeroInt ZeroInt a -> Bool+reverseColumns :: (Class.Floating a) => General ShapeInt ShapeInt a -> Bool reverseColumns x =    equalArray x $ Matrix.reverseColumns (Matrix.reverseColumns x) @@ -206,61 +244,49 @@ -- cf. Vector.genSwapVector genSwapVector ::    (Class.Floating a) =>-   Gen.Vector a Int-      (Maybe (Int,Int), (General ZeroInt ZeroInt a, Vector ZeroInt a))+   Gen.VectorInt a+      ((EInt,EInt), (General ShapeInt NonEmptyInt a, Vector NonEmptyInt a)) genSwapVector =-   flip Gen.mapGen ((,) <$> Gen.matrix <|*.> Gen.vector) $ \_maxElem (m,x) -> do+   flip Gen.mapQC ((,) <$> Gen.matrix <#*|> Gen.vector) $ \(m,x) -> do       let set = Shape.indices $ Array.shape x-      ij <--         forM (toMaybe (not $ null set) set) $ \s ->-            liftA2 (,) (QC.elements s) (QC.elements s)+      ij <- liftA2 (,) (QC.elements set) (QC.elements set)       return (ij,(m,x))  swapColumns ::-   (Class.Floating a) =>-   (Maybe (Int,Int), (General ZeroInt ZeroInt a, Vector ZeroInt a)) ->-   QC.Property-swapColumns (mij,(m,x)) =-   let mx = m#>x-   in seq (Array.shape mx) $-      maybeProperty $-      flip fmap mij $ \(i,j) ->-         equalArray mx (Matrix.swapColumns i j m #> Vector.swap i j x)--_swapColumns ::-   (Class.Floating a) =>-   ((Int,Int), (General ZeroInt ZeroInt a, Vector ZeroInt a)) -> Bool-_swapColumns ((i,j),(m,x)) =-   equalArray-      (m#>x)-      (Matrix.swapColumns i j m #> Vector.swap i j x)+   (Eq sh, Shape.Indexed sh, Shape.Index sh ~ ix, Class.Floating a) =>+   ((ix,ix), (General ShapeInt sh a, Vector sh a)) -> Bool+swapColumns ((i,j),(m,x)) =+   equalVector (m#*|x) (Matrix.swapColumns i j m #*| Vector.swap i j x)   zeroIntHeight ::    (Shape.C height, Shape.C width) =>-   General height width a -> General ZeroInt width a-zeroIntHeight = Matrix.mapHeight (zeroInt . Shape.size)+   General height width a -> General ShapeInt width a+zeroIntHeight = Matrix.mapHeight (shapeInt . Shape.size)  zeroIntWidth ::    (Shape.C height, Shape.C width) =>-   General height width a -> General height ZeroInt a-zeroIntWidth = Matrix.mapWidth (zeroInt . Shape.size)+   General height width a -> General height ShapeInt a+zeroIntWidth = Matrix.mapWidth (shapeInt . Shape.size)  reverseRowsStack ::    (Class.Floating a) =>-   (General ZeroInt ZeroInt a, General ZeroInt ZeroInt a) -> Bool+   (General ShapeInt ShapeInt a, General ShapeInt ShapeInt a) -> Bool reverseRowsStack (x,y) =-   equalArray-      (Matrix.reverseRows $ zeroIntHeight $ x===y)-      (zeroIntHeight $ Matrix.reverseRows y === Matrix.reverseRows x)+   let above = Matrix.above Matrix.contiguousBias Extent.appendRight+   in equalArray+         (Matrix.reverseRows $ zeroIntHeight $ above x y)+         (zeroIntHeight $ above (Matrix.reverseRows y) (Matrix.reverseRows x))  reverseColumnsStack ::    (Class.Floating a) =>-   (General ZeroInt ZeroInt a, General ZeroInt ZeroInt a) -> Bool+   (General ShapeInt ShapeInt a, General ShapeInt ShapeInt a) -> Bool reverseColumnsStack (x,y) =-   equalArray-      (Matrix.reverseColumns $ zeroIntWidth $ x|||y)-      (zeroIntWidth $ Matrix.reverseColumns y ||| Matrix.reverseColumns x)+   let beside = Matrix.beside Matrix.contiguousBias Extent.appendRight+   in equalArray+         (Matrix.reverseColumns $ zeroIntWidth $ beside x y)+         (zeroIntWidth $+          beside (Matrix.reverseColumns y) (Matrix.reverseColumns x))   data Cut = Take | Drop deriving (Show, Eq, Ord, Enum, Bounded)@@ -269,7 +295,7 @@ cut ::    (Class.Floating a) =>    Cut -> Slice -> Int ->-   General ZeroInt ZeroInt a -> General ZeroInt ZeroInt a+   General ShapeInt ShapeInt a -> General ShapeInt ShapeInt a cut Take Row = Matrix.takeRows cut Take Column = Matrix.takeColumns cut Drop Row = Matrix.dropRows@@ -277,7 +303,7 @@  cutCommutative ::    (Class.Floating a) =>-   ((Cut,Slice),(Int,Int)) -> General ZeroInt ZeroInt a -> Bool+   ((Cut,Slice),(Int,Int)) -> General ShapeInt ShapeInt a -> Bool cutCommutative (kind,(k,j)) x =    let cutK = uncurry cut kind k        cutJ = uncurry cut kind j@@ -285,7 +311,7 @@  cutRowColumnCommutative ::    (Class.Floating a) =>-   ((Cut,Int),(Cut,Int)) -> General ZeroInt ZeroInt a -> Bool+   ((Cut,Int),(Cut,Int)) -> General ShapeInt ShapeInt a -> Bool cutRowColumnCommutative ((cutR,k),(cutC,j)) x =    let cutRows = cut cutR Row k        cutColumns = cut cutC Column j@@ -293,14 +319,14 @@   takeEqually ::-   (Class.Floating a) => Int -> General ZeroInt ZeroInt a -> Bool+   (Class.Floating a) => Int -> General ShapeInt ShapeInt a -> Bool takeEqually k x =    equalArray       (Matrix.takeEqually k x)       (Matrix.takeRows k (Matrix.takeColumns k x))  dropEqually ::-   (Class.Floating a) => Int -> General ZeroInt ZeroInt a -> Bool+   (Class.Floating a) => Int -> General ShapeInt ShapeInt a -> Bool dropEqually k x =    equalArray       (Matrix.dropEqually k x)@@ -308,127 +334,138 @@   takeRowArray ::-   (Class.Floating a) => [Int] -> General ZeroInt ZeroInt a -> Bool+   (Class.Floating a) => [Int] -> General ShapeInt ShapeInt a -> Bool takeRowArray ixs x =-   equalArray-      (Matrix.adaptOrder x $-       Matrix.fromRows (Matrix.width x) $ map (Matrix.takeRow x) ixs)+   Util.equalMatrix+      (Matrix.fromRows (Matrix.width x) $ map (Matrix.takeRow x) ixs)       (Matrix.takeRowArray (BoxedArray.vectorFromList ixs) x)   stackSplitRows ::-   (Class.Floating a) => Int -> General ZeroInt ZeroInt a -> Bool-stackSplitRows k x =-   equalArray x-      (zeroIntHeight $ Matrix.takeRows k x === Matrix.dropRows k x)+   (Class.Floating a) => General (ShapeInt:+:ShapeInt) ShapeInt a -> Bool+stackSplitRows x =+   equalArray x $ Matrix.takeTop x === Matrix.takeBottom x  stackSplitColumns ::-   (Class.Floating a) => Int -> General ZeroInt ZeroInt a -> Bool-stackSplitColumns k x =-   equalArray x-      (zeroIntWidth $ Matrix.takeColumns k x ||| Matrix.dropColumns k x)+   (Class.Floating a) => General ShapeInt (ShapeInt:+:ShapeInt) a -> Bool+stackSplitColumns x =+   equalArray x $ Matrix.takeLeft x ||| Matrix.takeRight x   takeStackRows, dropStackRows ::    (Class.Floating a) =>-   (General ZeroInt ZeroInt a, General ZeroInt ZeroInt a) -> Bool-takeStackRows (x,y) =-   equalArray-      (Matrix.toRowMajor x)-      (Matrix.toRowMajor $ Matrix.takeRows (Shape.size $ Matrix.height x) $-       zeroIntHeight $ x===y)-dropStackRows (x,y) =-   equalArray-      (Matrix.toRowMajor y)-      (Matrix.toRowMajor $ Matrix.dropRows (Shape.size $ Matrix.height x) $-       zeroIntHeight $ x===y)+   (General ShapeInt ShapeInt a, General ShapeInt ShapeInt a) -> Bool+takeStackRows (x,y) = equalArray x $ Matrix.takeTop $ x!===y+dropStackRows (x,y) = equalArray y $ Matrix.takeBottom $ x===y  takeStackColumns, dropStackColumns ::    (Class.Floating a) =>-   (General ZeroInt ZeroInt a, General ZeroInt ZeroInt a) -> Bool-takeStackColumns (x,y) =-   equalArray-      (Matrix.toRowMajor x)-      (Matrix.toRowMajor $ Matrix.takeColumns (Shape.size $ Matrix.width x) $-       zeroIntWidth $ x|||y)-dropStackColumns (x,y) =-   equalArray-      (Matrix.toRowMajor y)-      (Matrix.toRowMajor $ Matrix.dropColumns (Shape.size $ Matrix.width x) $-       zeroIntWidth $ x|||y)+   (General ShapeInt ShapeInt a, General ShapeInt ShapeInt a) -> Bool+takeStackColumns (x,y) = equalArray x $ Matrix.takeLeft $ x!|||y+dropStackColumns (x,y) = equalArray y $ Matrix.takeRight $ x|||y ++type BiasMatrix height width a =+   MR.Reader Matrix.OrderBias (Matrix.General height width a)++infixr 3 ?|||?+infixr 2 ?===?++(?|||?) ::+   (Shape.C height, Eq height, Shape.C widthA, Shape.C widthB,+    Class.Floating a) =>+   BiasMatrix height widthA a ->+   BiasMatrix height widthB a ->+   BiasMatrix height (widthA:+:widthB) a+(?|||?) = liftA3 (flip Matrix.beside Extent.appendAny) MR.ask++(?===?) ::+   (Shape.C width, Eq width, Shape.C heightA, Shape.C heightB,+    Class.Floating a) =>+   BiasMatrix heightA width a ->+   BiasMatrix heightB width a ->+   BiasMatrix (heightA:+:heightB) width a+(?===?) = liftA3 (flip Matrix.above Extent.appendAny) MR.ask++runWithOrderBias ::+   (args -> readerArgs) ->+   (readerArgs -> MR.Reader bias prop) -> bias -> args -> prop+runWithOrderBias f prop orderBias args =+   MR.runReader (prop $ f args) orderBias++ stackRowsAssociative, stackColumnsAssociative ::    (Class.Floating a) =>-   (General ZeroInt ZeroInt a,-    General ZeroInt ZeroInt a,-    General ZeroInt ZeroInt a) -> Bool-stackRowsAssociative (x,y,z) =-   equalArray-      (zeroIntHeight ((x===y)===z))-      (zeroIntHeight (x===(y===z)))-stackColumnsAssociative (x,y,z) =-   equalArray-      (zeroIntWidth ((x|||y)|||z))-      (zeroIntWidth (x|||(y|||z)))+   Matrix.OrderBias ->+   (General ShapeInt ShapeInt a,+    General ShapeInt ShapeInt a,+    General ShapeInt ShapeInt a) -> Bool+stackRowsAssociative =+   runWithOrderBias (mapTriple (pure,pure,pure)) $ \(x,y,z) ->+   liftA2 equalArray+      (zeroIntHeight <$> ((x?===?y)?===?z))+      (zeroIntHeight <$> (x?===?(y?===?z)))+stackColumnsAssociative =+   runWithOrderBias (mapTriple (pure,pure,pure)) $ \(x,y,z) ->+   liftA2 equalArray+      (zeroIntWidth <$> ((x?|||?y)?|||?z))+      (zeroIntWidth <$> (x?|||?(y?|||?z)))  stackRowsColumnsCommutative ::    (Class.Floating a) =>-   ((General ZeroInt ZeroInt a, General ZeroInt ZeroInt a),-    (General ZeroInt ZeroInt a, General ZeroInt ZeroInt a)) -> Bool-stackRowsColumnsCommutative ((x,y),(z,w)) =-   equalArray-      (Matrix.toRowMajor $ (x|||y)===(z|||w))-      (Matrix.toRowMajor $ (x===z)|||(y===w))+   Matrix.OrderBias ->+   ((General ShapeInt ShapeInt a, General ShapeInt ShapeInt a),+    (General ShapeInt ShapeInt a, General ShapeInt ShapeInt a)) -> Bool+stackRowsColumnsCommutative =+   runWithOrderBias+      (mapPair (mapPair (pure,pure), mapPair (pure,pure))) $ \((x,y),(z,w)) ->+   liftA2 equalArray+      ((x?|||?y)?===?(z?|||?w))+      ((x?===?z)?|||?(y?===?w)) +genOrderBias :: QC.Gen Matrix.OrderBias+genOrderBias =+   QC.elements [Matrix.leftBias, Matrix.rightBias, Matrix.contiguousBias] -forceOrder ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   MatrixShape.Order ->-   (General ZeroInt ZeroInt a, Vector ZeroInt a) ->-   Bool-forceOrder order (a,x) =-   let ao = Matrix.forceOrder order a-   in MatrixShape.fullOrder (Array.shape ao) == order-      &&-      approxArray (a #> x) (ao #> x)+genLeftRightBias :: QC.Gen Matrix.OrderBias+genLeftRightBias =+   QC.elements [Matrix.leftBias, Matrix.rightBias] -addDistributive ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   ((General ZeroInt ZeroInt a, General ZeroInt ZeroInt a), Vector ZeroInt a) ->-   Bool-addDistributive ((a,b),x) =-   approxArray (Matrix.add a b #> x) (Vector.add (a#>x) (b#>x)) -subDistributive ::+rowArgAbsMaximums ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   ((General ZeroInt ZeroInt a, General ZeroInt ZeroInt a), Vector ZeroInt a) ->-   Bool-subDistributive ((a,b),x) =-   approxArray (Matrix.sub a b #> x) (Vector.sub (a#>x) (b#>x))+   General ShapeInt (():+:ShapeInt) a -> Bool+rowArgAbsMaximums x0 =+   let x = zeroIntWidth x0+       (ixs0,xs0) = Matrix.rowArgAbsMaximums x+       (ixs1,xs1) =+         mapPair (Array.fromBoxed, Array.fromBoxed) $+         FuncHT.unzip $ fmap Vector.argAbsMaximum $ Matrix.toRowArray x+   in ixs0==ixs1 && approxVector xs0 xs1   multiplyDiagonalMatrix ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Triangular.Diagonal ZeroInt a, General ZeroInt ZeroInt a) -> Bool+   (Triangular.Diagonal ShapeInt a, General ShapeInt ShapeInt a) -> Bool multiplyDiagonalMatrix (x,y) =-   approxArray (x <#> y) (Triangular.toSquare x <#> y)+   approxArray (x #*## y) (Triangular.toSquare x #*## y)  multiplyMatrixDiagonal ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (General ZeroInt ZeroInt a, Triangular.Diagonal ZeroInt a) -> Bool+   (General ShapeInt ShapeInt a, Triangular.Diagonal ShapeInt a) -> Bool multiplyMatrixDiagonal (x,y) =-   approxMatrix 1e-5 (x <#> y) (x <#> Triangular.toSquare y)+   approxMatrix 1e-5 (x ##*# y) (x ##*# Triangular.toSquare y)    checkForAll ::    (Show a, QC.Testable test) =>-   Gen.T tag dim a -> (a -> test) -> Tagged tag QC.Property+   Gen.T dim tag a -> (a -> test) -> Tagged tag QC.Property checkForAll gen = Util.checkForAll (Gen.run gen 10 5)  checkForAllExtra ::    (Show a, Show b, QC.Testable test) =>-   QC.Gen a -> Gen.T tag dim b ->+   QC.Gen a -> Gen.T dim tag b ->    (a -> b -> test) -> Tagged tag QC.Property checkForAllExtra = Gen.withExtra checkForAll @@ -440,39 +477,56 @@    ("index",       checkForAll (Indexed.genMatrixIndex Gen.matrix) Indexed.unitDot) :    ("dotProduct",-      checkForAll ((,) <$> Gen.vector <.*.> Gen.vector) dotProduct) :+      checkForAll ((,) <$> Gen.vector <-*|> Gen.vector) dotProduct) :    ("innerDot",-      checkForAll ((,) <$> Gen.vector <.*.> Gen.vector) innerDot) :+      checkForAll ((,) <$> Gen.vector <-*|> Gen.vector) innerDot) :    ("tensorProductTranspose",       checkForAllExtra genOrder-         ((,) <$> Gen.vector <***> Gen.vector) tensorProductTranspose) :+         ((,) <$> Gen.vector <|*-> Gen.vector) tensorProductTranspose) :    ("outerTranspose",       checkForAllExtra genOrder-         ((,) <$> Gen.vector <***> Gen.vector) outerTranspose) :+         ((,) <$> Gen.vector <|*-> Gen.vector) outerTranspose) :    ("tensorProduct",       checkForAllExtra genOrder-         ((,) <$> Gen.vector <***> Gen.vector) tensorProduct) :+         ((,) <$> Gen.vector <|*-> Gen.vector) tensorProduct) :    ("tensorProductMul",-      checkForAll ((,,) <$> Gen.diagonal <|*|> Gen.matrix <|*|> Gen.diagonal)+      checkForAll ((,,) <$> Gen.diagonal <#*#> Gen.matrix <#*#> Gen.diagonal)          tensorProductMul) :    ("outerTensorProduct",       checkForAllExtra genOrder-         ((,) <$> Gen.vector <***> Gen.vector) outerTensorProduct) :+         ((,) <$> Gen.vector <|*-> Gen.vector) outerTensorProduct) :    ("sumRank1",       checkForAllExtra genOrder genScaledVectorPairs sumRank1) :     ("outerTrace",       checkForAllExtra genOrder-         ((,) <$> Gen.vector <.*.> Gen.vector) outerTrace) :+         ((,) <$> Gen.vector <-*|> Gen.vector) outerTrace) :    ("outerInner",       checkForAllExtra genOrder-         ((,,) <$> Gen.vector <***> Gen.vector <|*.> Gen.vector) outerInner) :+         ((,,) <$> Gen.vector <|*-> Gen.vector <#*|> Gen.vector) outerInner) :    ("tensorTrace",       checkForAllExtra genOrder-         ((,) <$> Gen.vector <.*.> Gen.vector) tensorTrace) :+         ((,) <$> Gen.vector <-*|> Gen.vector) tensorTrace) :    ("tensorDot",       checkForAllExtra genOrder-         ((,,) <$> Gen.vector <***> Gen.vector <|*.> Gen.vector) tensorDot) :+         ((,,) <$> Gen.vector <|*-> Gen.vector <#*|> Gen.vector) tensorDot) :+   ("kroneckerTranspose",+      checkForAll+         ((,) <$> Gen.matrix <><> Gen.matrix) kroneckerTranspose) :+   ("kroneckerTrace",+      checkForAll+         ((,) <$> Gen.square <><> Gen.square) kroneckerTrace) :+   ("kroneckerProduct",+      checkForAll+         ((,) <$>+            ((,) <$> Gen.matrixInt <><> Gen.matrixInt)+            <#*#>+            ((,) <$> Gen.matrixInt <><> Gen.matrixInt))+         kroneckerProduct) :+   ("kronecker3",+      checkForAll+         ((,,) <$> Gen.matrixInt <#*#> Gen.matrixInt <#*#> Gen.matrixInt)+         kronecker3) :     ("reverseNoRows",       Util.checkForAllPlain@@ -505,8 +559,8 @@       checkForAllExtra (QC.choose (0,5)) Gen.matrix dropEqually) :    ("takeRowArray",       checkForAll-         (Gen.mapGen-            (\_maxElem x -> do+         (Gen.mapQC+            (\x -> do                let set = Shape.indices $ Matrix.height x                ixs <-                   if null set then return [] else QC.listOf $ QC.elements set@@ -516,9 +570,9 @@    ("swapColumns",       checkForAll genSwapVector swapColumns) :    ("stackSplitRows",-      checkForAllExtra (QC.choose (0,5)) Gen.matrix stackSplitRows) :+      checkForAll Gen.matrix stackSplitRows) :    ("stackSplitColumns",-      checkForAllExtra (QC.choose (0,5)) Gen.matrix stackSplitColumns) :+      checkForAll Gen.matrix stackSplitColumns) :    ("takeStackRows",       checkForAll genMatrix2EqWidth takeStackRows) :    ("dropStackRows",@@ -528,40 +582,36 @@    ("dropStackColumns",       checkForAll genMatrix2EqHeight dropStackColumns) :    ("stackRowsAssociative",-      checkForAll+      checkForAllExtra genOrderBias          ((,,) <$> Gen.matrix <===> Gen.matrix <===> Gen.matrix)          stackRowsAssociative) :    ("stackColumnsAssociative",-      checkForAll+      checkForAllExtra genOrderBias          ((,,) <$> Gen.matrix <|||> Gen.matrix <|||> Gen.matrix)          stackColumnsAssociative) :    ("stackRowsColumnsCommutative",-      checkForAll+      checkForAllExtra genLeftRightBias          ((,) <$> genMatrix2EqHeight <===> genMatrix2EqHeight)          stackRowsColumnsCommutative) :     ("forceOrder",       checkForAllExtra genOrder-         ((,) <$> Gen.matrix <|*.> Gen.vector) forceOrder) :+         ((,) <$> Gen.matrixInt <#*|> Gen.vector) Generic.forceOrder) :    ("addDistributive",       checkForAll-         ((,) <$>-            ((,) <$> Gen.matrix <|=|> Gen.matrix)-            <|*.>-            Gen.vector)-         addDistributive) :+         (Generic.genDistribution Gen.matrixInt)+         Generic.addDistributive) :    ("subDistributive",       checkForAll-         ((,) <$>-            ((,) <$> Gen.matrix <|=|> Gen.matrix)-            <|*.>-            Gen.vector)-         subDistributive) :+         (Generic.genDistribution Gen.matrixInt)+         Generic.subDistributive) :+   ("rowArgAbsMaximums",+      checkForAll Gen.matrix rowArgAbsMaximums) :     ("multiplyDiagonalMatrix",       checkForAll-         ((,) <$> Gen.diagonal <|*|> Gen.matrix) multiplyDiagonalMatrix) :+         ((,) <$> Gen.diagonal <#*#> Gen.matrix) multiplyDiagonalMatrix) :    ("multiplyMatrixDiagonal",       checkForAll-         ((,) <$> Gen.matrix <|*|> Gen.diagonal) multiplyMatrixDiagonal) :+         ((,) <$> Gen.matrix <#*#> Gen.diagonal) multiplyMatrixDiagonal) :    []
+ test/Test/Multiply.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE TypeFamilies #-}+module Test.Multiply (+   multiplySquare,+   squareSquare,+   power,+   ) where++import qualified Test.Utility as Util++import qualified Numeric.LAPACK.Matrix.Square as Square+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix+import qualified Numeric.LAPACK.Matrix as Matrix+import qualified Numeric.LAPACK.Vector as Vector+import Numeric.LAPACK.Matrix (Matrix, ShapeInt, (#*##))+import Numeric.LAPACK.Scalar (RealOf)++import qualified Numeric.Netlib.Class as Class++++multiplySquare ::+   (Matrix.Power typ, Matrix.MultiplySquare typ,+    Matrix.SquareShape typ, Matrix.HeightOf typ ~ ShapeInt,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Matrix typ a -> Bool+multiplySquare a =+   Util.approxArray -- (Scalar.selectReal 1e-1 1e-5)+      (Matrix.toSquare $ Matrix.square a)+      (a #*## Matrix.toSquare a)++squareSquare ::+   (Matrix.Power typ, Matrix.MultiplySquare typ,+    Matrix.SquareShape typ, Matrix.HeightOf typ ~ ShapeInt,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Matrix typ a -> Bool+squareSquare a =+   Util.approxArray -- (Scalar.selectReal 1e-1 1e-5)+      (Matrix.toSquare $ Matrix.square a)+      (Square.square $ Matrix.toSquare a)++power ::+   (Matrix.Power typ, Matrix.MultiplySquare typ,+    Matrix.SquareShape typ, Matrix.HeightOf typ ~ ShapeInt,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Int -> Matrix typ a -> Bool+power n a =+   let b = Matrix.toSquare (Matrix.power (n+1) a)+       c = a #*## Matrix.toSquare (Matrix.power n a)+       normInf1 = Vector.normInf1 . ArrMatrix.toVector+   in Util.approxArrayTol (1e-6 * (normInf1 b + normInf1 c)) b c
test/Test/Orthogonal.hs view
@@ -2,11 +2,13 @@ {-# LANGUAGE FlexibleContexts #-} module Test.Orthogonal (testsVar) where +import qualified Test.Divide as Divide import qualified Test.Generator as Gen import qualified Test.Utility as Util-import Test.Generator ((<|*|>), (<|\|>))+import Test.Generator ((<#*#>), (<#\#>)) import Test.Utility-         (approx, approxReal, approxArrayTol, approxMatrix, isIdentity, Tagged)+         (approx, approxReal, approxArrayTol, approxMatrix,+          Tagged, isIdentity, isUnitary, maybeConjugate)  import qualified Numeric.LAPACK.Orthogonal.Householder as HH import qualified Numeric.LAPACK.Orthogonal as Ortho@@ -14,55 +16,56 @@ import qualified Numeric.LAPACK.Matrix.Triangular as Triangular import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape import qualified Numeric.LAPACK.Matrix.Square as Square+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix as Matrix import qualified Numeric.LAPACK.Vector as Vector import Numeric.LAPACK.Matrix.Square (Square)-import Numeric.LAPACK.Matrix (General, ZeroInt, (<#>))+import Numeric.LAPACK.Matrix (General, ShapeInt, (#*#), (##*#), (#*##), (#\##)) import Numeric.LAPACK.Scalar (RealOf, absolute, selectReal)  import qualified Numeric.Netlib.Class as Class  import qualified Data.Array.Comfort.Storable as Array import qualified Data.Array.Comfort.Shape as Shape-import Data.Array.Comfort.Storable (Array)  import Control.Applicative (liftA2, (<$>))+import Data.Semigroup ((<>))  import qualified Test.QuickCheck as QC   pseudoInverseProjection ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   General ZeroInt ZeroInt a -> Bool+   General ShapeInt ShapeInt a -> Bool pseudoInverseProjection a =    let ainv = snd $ Ortho.pseudoInverseRCond 1e-5 a        tol = selectReal 1e-1 1e-5-   in approxArrayTol tol a (a <#> ainv <#> a) &&-      approxArrayTol tol ainv (ainv <#> a <#> ainv)+   in approxArrayTol tol a (a <> ainv <> a) &&+      approxArrayTol tol ainv (ainv <> a <> ainv)  pseudoInverseHermitian ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   General ZeroInt ZeroInt a -> Bool+   General ShapeInt ShapeInt a -> Bool pseudoInverseHermitian a =    let ainv = snd $ Ortho.pseudoInverseRCond 1e-5 a        tol = selectReal 1e-2 1e-5-       aainv = a <#> ainv-       ainva = ainv <#> a+       aainv = a <> ainv+       ainva = ainv <> a    in approxMatrix tol aainv (Matrix.adjoint aainv) &&       approxMatrix tol ainva (Matrix.adjoint ainva)  pseudoInverseFactored ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Matrix.Tall ZeroInt ZeroInt a,-    Matrix.Wide ZeroInt ZeroInt a) -> Bool+   (Matrix.Tall ShapeInt ShapeInt a,+    Matrix.Wide ShapeInt ShapeInt a) -> Bool pseudoInverseFactored (a,b) =    let pinv x = snd $ Ortho.pseudoInverseRCond 1e-5 x    in approxMatrix (selectReal 1e-1 1e-5)-         (pinv (a <#> b)) (pinv b <#> pinv a)+         (pinv (a #*# b)) (pinv b #*# pinv a)  pseudoInverseInverse ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool+   Square ShapeInt a -> Bool pseudoInverseInverse a =    approxMatrix (selectReal 1e-1 1e-5)       (Matrix.inverse a)@@ -71,7 +74,7 @@  determinant ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool+   Square ShapeInt a -> Bool determinant a =    let detSquare = Square.determinant a        detOrtho = Ortho.determinant a@@ -81,7 +84,7 @@  determinantAbsolute ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool+   Square ShapeInt a -> Bool determinantAbsolute a =    let det = absolute $ Ortho.determinant a        detAbs = Ortho.determinantAbsolute a@@ -89,60 +92,60 @@  gramianDeterminant ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   General ZeroInt ZeroInt a -> Bool+   General ShapeInt ShapeInt a -> Bool gramianDeterminant a =-   let cov = Herm.covariance a+   let gram = Herm.gramian a        Shape.ZeroBased n = Matrix.width a-       estimate = (Vector.sum (Herm.takeDiagonal cov) / fromIntegral n) ^ n+       estimate = (Vector.sum (Herm.takeDiagonal gram) / fromIntegral n) ^ n    in approxReal (1e-5 * max 1 estimate)-         (Herm.determinant cov)+         (Herm.determinant gram)          (Ortho.determinantAbsolute a ^ (2::Int))   multiplyDeterminantRight ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (General ZeroInt ZeroInt a, Square ZeroInt a) -> Bool+   (General ShapeInt ShapeInt a, Square ShapeInt a) -> Bool multiplyDeterminantRight (a,b) =    let detA = Ortho.determinantAbsolute a        detB = absolute $ Ortho.determinant b    in approxReal          (selectReal 1e-1 1e-5 * max 1 detA * max 1 detB)-         (Ortho.determinantAbsolute (a<#>b))+         (Ortho.determinantAbsolute (a##*#b))          (detA * detB)  multiplyDeterminantLeft ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Square ZeroInt a, General ZeroInt ZeroInt a) -> Bool+   (Square ShapeInt a, General ShapeInt ShapeInt a) -> Bool multiplyDeterminantLeft (a,b) =    let detA = absolute $ Ortho.determinant a        detB = Ortho.determinantAbsolute b    in approxReal          (selectReal 1e-1 1e-5 * max 1 detA * max 1 detB)-         (Ortho.determinantAbsolute (a<#>b))+         (Ortho.determinantAbsolute (a#*##b))          (detA * detB)   genFullRankTallRHS ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Gen.Matrix a Int Int-      (Matrix.Tall ZeroInt ZeroInt a,-       Matrix.General ZeroInt ZeroInt a)-genFullRankTallRHS = (,) <$> Gen.fullRankTall <|\|> Gen.matrix+   Gen.MatrixInt a+      (Matrix.Tall ShapeInt ShapeInt a,+       Matrix.General ShapeInt ShapeInt a)+genFullRankTallRHS = (,) <$> Gen.fullRankTall <#\#> Gen.matrix   normalEquationLeastSquares ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Matrix.Tall ZeroInt ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Matrix.Tall ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool normalEquationLeastSquares (a, b) =    approxArrayTol       (selectReal 10 1e-3)       (Ortho.leastSquares a b)-      (Herm.solve (Herm.covariance $ Matrix.fromFull a) $-       Matrix.adjoint a <#> b)+      (Herm.solve (Herm.gramian $ Matrix.fromFull a) $+       Matrix.adjoint a #*# b)  specializedLeastSquares ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Matrix.Tall ZeroInt ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Matrix.Tall ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool specializedLeastSquares (a, b) =    approxArrayTol       (selectReal 1e-1 1e-5)@@ -151,36 +154,46 @@  householderLeastSquares ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Matrix.Tall ZeroInt ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Matrix.Tall ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool householderLeastSquares (a, b) =    approxArrayTol       (selectReal 1e-1 1e-5)       (Ortho.leastSquares a b)       (HH.leastSquares (HH.fromMatrix a) b) +triangularLeastSquares ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Matrix.Tall ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+triangularLeastSquares (a, b) =+   approxArrayTol+      (selectReal 1e-1 1e-5)+      (Ortho.leastSquares a b)+      (let (q,r) = Ortho.householderTall a+       in r #\## (Matrix.adjoint q #*# b))  + genFullRankWideRHS ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Gen.Matrix a Int Int-      (Matrix.Wide ZeroInt ZeroInt a,-       Matrix.General ZeroInt ZeroInt a)-genFullRankWideRHS = (,) <$> Gen.fullRankWide <|\|> Gen.matrix+   Gen.MatrixInt a+      (Matrix.Wide ShapeInt ShapeInt a,+       Matrix.General ShapeInt ShapeInt a)+genFullRankWideRHS = (,) <$> Gen.fullRankWide <#\#> Gen.matrix   normalEquationMinimumNorm ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Matrix.Wide ZeroInt ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Matrix.Wide ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool normalEquationMinimumNorm (a, b) =    approxArrayTol       (selectReal 10 1e-3)       (Ortho.minimumNorm a b)-      (Matrix.adjoint a <#>-       Herm.solve (Herm.covariance $ Matrix.fromFull $ Matrix.adjoint a) b)+      (Matrix.adjoint a #*#+       Herm.solve (Herm.gramian $ Matrix.fromFull $ Matrix.adjoint a) b)  specializedMinimumNorm ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Matrix.Wide ZeroInt ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Matrix.Wide ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool specializedMinimumNorm (a, b) =    approxArrayTol       (selectReal 1e-1 1e-5)@@ -189,87 +202,83 @@  householderMinimumNorm ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Matrix.Wide ZeroInt ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Matrix.Wide ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool householderMinimumNorm (a, b) =    approxArrayTol       (selectReal 1e-1 1e-5)       (Ortho.minimumNorm a b)       (HH.minimumNorm (HH.fromMatrix $ Matrix.adjoint a) b) +triangularMinimumNorm ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Matrix.Wide ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+triangularMinimumNorm (a, b) =+   approxArrayTol+      (selectReal 1e-1 1e-5)+      (Ortho.minimumNorm a b)+      (let (q,r) = Ortho.householderTall $ Matrix.adjoint a+       in q #*# (Triangular.adjoint r #\## b)) + complementDimension ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix.Tall ZeroInt ZeroInt a -> Bool+   Matrix.Tall ShapeInt ShapeInt a -> Bool complementDimension a =    let b = Matrix.fromFull a Matrix.||| Matrix.fromFull (Ortho.complement a)    in Shape.size (Matrix.height b) == Shape.size (Matrix.width b)  complementBiorthogonal ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix.Tall ZeroInt ZeroInt a -> Bool+   Matrix.Tall ShapeInt ShapeInt a -> Bool complementBiorthogonal a =-   all (approx 1e-3 0) $-   Array.toList $ Matrix.adjoint a <#> Ortho.complement a+   all (approx 1e-3 0) $ Array.toList $ ArrMatrix.toVector $+   Matrix.adjoint a #*# Ortho.complement a  complementOrthogonal ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix.Tall ZeroInt ZeroInt a -> Bool-complementOrthogonal =-   isIdentity (selectReal 1e-3 1e-7) .-   Herm.toSquare . Herm.covariance . Matrix.fromFull . Ortho.complement+   Matrix.Tall ShapeInt ShapeInt a -> Bool+complementOrthogonal = isUnitary (selectReal 1e-3 1e-7) . Ortho.complement   householderReconstruction ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix.General ZeroInt ZeroInt a -> Bool+   Matrix.General ShapeInt ShapeInt a -> Bool householderReconstruction a =    approxArrayTol (selectReal 1e-3 1e-7)-      a (uncurry (<#>) (Ortho.householder a))+      a (uncurry (#*##) (Ortho.householder a))  householderDeterminant ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool+   Square ShapeInt a -> Bool householderDeterminant a =    let detOrtho = Ortho.determinant a        detHH = HH.determinant $ HH.fromMatrix a    in approx 1e-5 detOrtho detHH  -maybeConjugate ::-   (Shape.C sh, Class.Floating a) =>-   HH.Conjugation -> Array sh a -> Array sh a-maybeConjugate HH.NonConjugated = id-maybeConjugate HH.Conjugated = Vector.conjugate--maybeTranspose ::+maybeTriTranspose ::    (Shape.C size, Class.Floating a, MatrixShape.TriDiag diag,     MatrixShape.Content lo, MatrixShape.Content up) =>-   Herm.Transposition ->+   HH.Transposition ->    Triangular.Triangular up diag lo size a -> Square size a-maybeTranspose HH.NonTransposed = Triangular.toSquare-maybeTranspose HH.Transposed = Triangular.toSquare . Triangular.transpose--maybeAdjoint ::-   (Shape.C size, Class.Floating a) =>-   HH.Inversion -> Square size a -> Square size a-maybeAdjoint HH.NonInverted = id-maybeAdjoint HH.Inverted = Matrix.adjoint+maybeTriTranspose HH.NonTransposed = Triangular.toSquare+maybeTriTranspose HH.Transposed = Triangular.toSquare . Triangular.transpose  householderSolveRR ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    (HH.Transposition, HH.Conjugation) ->-   Matrix.Tall ZeroInt ZeroInt a -> Bool+   Matrix.Tall ShapeInt ShapeInt a -> Bool householderSolveRR (trans,conj) a =    let qr = HH.fromMatrix a    in  isIdentity (selectReal 1e-3 1e-7) $          HH.tallSolveR trans conj qr $-         maybeTranspose trans $ maybeConjugate conj $ HH.tallExtractR qr+         maybeTriTranspose trans $ maybeConjugate conj $ HH.tallExtractR qr   householderMultiplyR ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    HH.Transposition ->-   (Matrix.Tall ZeroInt ZeroInt a, Matrix.General ZeroInt ZeroInt a) ->+   (Matrix.Tall ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) ->    Bool householderMultiplyR trans (a,b) =    let qr = HH.fromMatrix a@@ -277,68 +286,69 @@    in approxArrayTol          (selectReal 1e-3 1e-7)          (HH.tallMultiplyR trans qr b)-         (case trans of-            HH.NonTransposed -> r <#> b-            HH.Transposed -> Triangular.transpose r <#> b)+         (Matrix.multiplySquare trans r b)   householderQOrthogonal ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix.General ZeroInt ZeroInt a -> Bool-householderQOrthogonal a =-   let q = HH.extractQ $ HH.fromMatrix a-   in isIdentity (selectReal 1e-3 1e-7) $ Matrix.adjoint q <#> q+   Matrix.General ShapeInt ShapeInt a -> Bool+householderQOrthogonal =+   isUnitary (selectReal 1e-3 1e-7) . HH.extractQ . HH.fromMatrix   householderMultiplyQ ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   HH.Inversion ->-   (Matrix.General ZeroInt ZeroInt a, Matrix.General ZeroInt ZeroInt a) ->+   (HH.Transposition, HH.Conjugation) ->+   (Matrix.General ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) ->    Bool-householderMultiplyQ inv (a,b) =+householderMultiplyQ (trans,conj) (a,b) =    let qr = HH.fromMatrix a    in approxArrayTol          (selectReal 1e-3 1e-7)-         (maybeAdjoint inv (HH.extractQ qr) <#> b)-         (HH.multiplyQ inv qr b)+         (Matrix.multiplySquare trans (maybeConjugate conj $ HH.extractQ qr) b)+         (HH.multiplyQ trans conj qr b)   householderTallQOrthogonal ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix.Tall ZeroInt ZeroInt a -> Bool+   Matrix.Tall ShapeInt ShapeInt a -> Bool householderTallQOrthogonal =-   isIdentity (selectReal 1e-3 1e-7) .-   Herm.toSquare . Herm.covariance . Matrix.fromFull .-   HH.tallExtractQ . HH.fromMatrix+   isUnitary (selectReal 1e-3 1e-7) . HH.tallExtractQ . HH.fromMatrix  householderTallMultiplyQ ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Matrix.Tall ZeroInt ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Matrix.Tall ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool householderTallMultiplyQ (a,b) =    let qr = HH.fromMatrix a    in approxArrayTol          (selectReal 1e-3 1e-7)-         (HH.tallExtractQ qr <#> b)+         (HH.tallExtractQ qr #*# b)          (HH.tallMultiplyQ qr b)  householderTallMultiplyQAdjoint ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Matrix.Tall ZeroInt ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Matrix.Tall ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool householderTallMultiplyQAdjoint (a,b) =    let qr = HH.fromMatrix a    in approxArrayTol          (selectReal 1e-3 1e-7)-         (Matrix.adjoint (HH.tallExtractQ qr) <#> b)+         (Matrix.adjoint (HH.tallExtractQ qr) #*# b)          (HH.tallMultiplyQAdjoint qr b)    checkForAll ::    (Show a, QC.Testable test) =>-   Gen.T tag dim a -> (a -> test) -> Tagged tag QC.Property+   Gen.T dim tag a -> (a -> test) -> Tagged tag QC.Property checkForAll gen = Util.checkForAll (Gen.run gen 3 5) +checkForAllExtra ::+   (Show a, Show b, QC.Testable test) =>+   QC.Gen a -> Gen.T dim tag b ->+   (a -> b -> test) -> Tagged tag QC.Property+checkForAllExtra = Gen.withExtra checkForAll + testsVar ::    (Show a, Class.Floating a, Eq a, RealOf a ~ ar, Class.Real ar) =>    [(String, Tagged a QC.Property)]@@ -349,7 +359,7 @@       checkForAll Gen.matrix pseudoInverseHermitian) :    ("pseudoInverseFactored",       checkForAll-         ((,) <$> Gen.fullRankTall <|*|> Gen.fullRankWide)+         ((,) <$> Gen.fullRankTall <#*#> Gen.fullRankWide)          pseudoInverseFactored) :    ("pseudoInverseInverse",       checkForAll Gen.invertible pseudoInverseInverse) :@@ -362,10 +372,10 @@       checkForAll Gen.matrix gramianDeterminant) :    ("multiplyDeterminantRight",       checkForAll-         ((,) <$> Gen.matrix <|*|> Gen.square) multiplyDeterminantRight) :+         ((,) <$> Gen.matrix <#*#> Gen.square) multiplyDeterminantRight) :    ("multiplyDeterminantLeft",       checkForAll-         ((,) <$> (fst . Ortho.householder <$> Gen.square) <|*|> Gen.matrix)+         ((,) <$> (fst . Ortho.householder <$> Gen.square) <#*#> Gen.matrix)          multiplyDeterminantLeft) :    ("normalEquationLeastSquares",       checkForAll genFullRankTallRHS normalEquationLeastSquares) :@@ -383,6 +393,11 @@    ("complementOrthogonal",       checkForAll Gen.tall complementOrthogonal) : +   ("triangularLeastSquares",+      checkForAll genFullRankTallRHS triangularLeastSquares) :+   ("triangularMinimumNorm",+      checkForAll genFullRankWideRHS triangularMinimumNorm) :+    ("householderReconstruction",       checkForAll Gen.matrix householderReconstruction) :    ("householderDeterminant",@@ -392,24 +407,26 @@    ("householderMinimumNorm",       checkForAll genFullRankWideRHS householderMinimumNorm) :    ("householderSolveRR",-      Gen.withExtra checkForAll+      checkForAllExtra          (liftA2 (,) QC.arbitraryBoundedEnum QC.arbitraryBoundedEnum)          Gen.fullRankTall householderSolveRR) :    ("householderMultiplyR",-      Gen.withExtra checkForAll-         QC.arbitraryBoundedEnum ((,) <$> Gen.tall <|*|> Gen.matrix)+      checkForAllExtra QC.arbitraryBoundedEnum+         ((,) <$> Gen.tall <#*#> Gen.matrix)          householderMultiplyR) :    ("householderQOrthogonal",       checkForAll Gen.matrix householderQOrthogonal) :    ("householderMultiplyQ",-      Gen.withExtra checkForAll-         QC.arbitraryBoundedEnum ((,) <$> Gen.matrix <|\|> Gen.matrix)+      checkForAllExtra+         (liftA2 (,) QC.arbitraryBoundedEnum QC.arbitraryBoundedEnum)+         ((,) <$> Gen.matrix <#\#> Gen.matrix)          householderMultiplyQ) :    ("householderTallQOrthogonal",       checkForAll Gen.tall householderTallQOrthogonal) :    ("householderTallMultiplyQ",-      checkForAll ((,) <$> Gen.tall <|*|> Gen.matrix) householderTallMultiplyQ) :+      checkForAll ((,) <$> Gen.tall <#*#> Gen.matrix) householderTallMultiplyQ) :    ("householderTallMultiplyQAdjoint",       checkForAll-         ((,) <$> Gen.tall <|\|> Gen.matrix) householderTallMultiplyQAdjoint) :+         ((,) <$> Gen.tall <#\#> Gen.matrix) householderTallMultiplyQAdjoint) :+   Divide.testsVar (HH.fromMatrix <$> Gen.invertible) ++    []
test/Test/Permutation.hs view
@@ -1,18 +1,21 @@ module Test.Permutation where +import qualified Test.Indexed as Indexed import qualified Test.Generator as Gen import qualified Test.Utility as Util-import Test.Generator ((<|*|>))-import Test.Utility (equalArray, Tagged(Tagged))+import Test.Generator ((<#*#>))+import Test.Logic (Dim)+import Test.Utility (Tagged, equalArray)  import qualified Numeric.LAPACK.Permutation as Perm+import qualified Numeric.LAPACK.Matrix.Permutation as PermMatrix import qualified Numeric.LAPACK.Matrix.Square as Square import qualified Numeric.LAPACK.Matrix as Matrix import qualified Numeric.LAPACK.Vector as Vector import Numeric.LAPACK.Permutation          (Permutation, Inversion(Inverted, NonInverted)) import Numeric.LAPACK.Matrix.Square (Square)-import Numeric.LAPACK.Matrix (ZeroInt, zeroInt, (<#>))+import Numeric.LAPACK.Matrix (Matrix, ShapeInt, shapeInt, (#*##)) import Numeric.LAPACK.Vector (Vector)  import qualified Numeric.Netlib.Class as Class@@ -20,40 +23,40 @@ import qualified Data.Array.Comfort.Storable as Array import qualified Data.Array.Comfort.Shape as Shape -import Foreign.C.Types (CInt)- import Control.Monad (forM) import Control.Applicative (liftA2, (<$>)) -import Data.Monoid ((<>))+import Data.Semigroup ((<>))  import qualified Test.QuickCheck as QC  -genPivots :: [()] -> QC.Gen (Vector ZeroInt CInt)+type Pivots = Vector (Perm.Shape ShapeInt) (Perm.Element ShapeInt)++genPivots :: [()] -> QC.Gen Pivots genPivots nat = do    let n = length nat    let nc = fromIntegral n-   fmap (Vector.fromList (zeroInt n)) $-      forM (zip [1..] nat) $ \(i,()) -> QC.choose (i,nc)+   fmap (Vector.fromList (Perm.Shape $ shapeInt n)) $+      forM (zip [1..] nat) $ \(i,()) -> Perm.Element <$> QC.choose (i,nc) -genPerm :: [()] -> QC.Gen (Permutation ZeroInt)-genPerm = fmap (\p -> Perm.fromPivots NonInverted (Array.shape p) p) . genPivots+genPerm :: [()] -> QC.Gen (Permutation ShapeInt)+genPerm = fmap (Perm.fromPivots NonInverted) . genPivots  -permutationPivots :: Inversion -> Vector ZeroInt CInt -> Bool+permutationPivots :: Inversion -> Pivots -> Bool permutationPivots inv xs =-   Array.toList (Perm.toPivots inv (Perm.fromPivots inv (Array.shape xs) xs))+   Array.toList (Perm.toPivots inv (Perm.fromPivots inv xs))    ==    Array.toList xs -determinantMultiply :: (Permutation ZeroInt, Permutation ZeroInt) -> Bool+determinantMultiply :: (Permutation ShapeInt, Permutation ShapeInt) -> Bool determinantMultiply (p0,p1) =    Perm.determinant (Perm.multiply p0 p1)    ==    Perm.determinant p0 <> Perm.determinant p1 -transposeMultiply :: (Permutation ZeroInt, Permutation ZeroInt) -> Bool+transposeMultiply :: (Permutation ShapeInt, Permutation ShapeInt) -> Bool transposeMultiply (p0,p1) =    (Array.toList $ Perm.toPivots NonInverted $     Perm.transpose (Perm.multiply p0 p1))@@ -62,21 +65,14 @@     Perm.multiply (Perm.transpose p1) (Perm.transpose p0))  -genPermutation :: Gen.Matrix a Int Int (Permutation ZeroInt)+genPermutation :: (Dim sh) => Gen.Matrix sh sh a (Permutation sh) genPermutation =-   flip Gen.mapGen Gen.squareDim $ \_ sh@(Shape.ZeroBased n) ->-   let nc = fromIntegral n-   in fmap (Perm.fromPivots NonInverted sh . Vector.fromList sh) $-         forM [1..] $ \i -> QC.choose (i,nc)+   flip Gen.mapGen Gen.squareDim $ \_maxElem sh ->+   let nc = fromIntegral $ Shape.size sh+   in fmap (Perm.fromPivots NonInverted . Vector.fromList (Perm.Shape sh)) $+         forM [1..] $ \i -> Perm.Element <$> QC.choose (i,nc)  -permApply ::-   (Shape.C height, Eq height, Shape.C width, Class.Floating a) =>-   Inversion -> Permutation height ->-   Matrix.General height width a ->-   Matrix.General height width a-permApply inv = Perm.apply (inv==Inverted)- permToMatrix ::    (Shape.C sh, Class.Floating a) =>    Inversion -> Permutation sh -> Square sh a@@ -87,46 +83,40 @@  applyToMatrix ::    (Class.Floating a) =>-   Inversion -> (Permutation ZeroInt, Matrix.General ZeroInt ZeroInt a) -> Bool+   Inversion -> (Permutation ShapeInt, Matrix.General ShapeInt ShapeInt a) -> Bool applyToMatrix inv (p,m) =    equalArray-      (permApply inv p m)-      (permToMatrix inv p <#> m)+      (Perm.apply inv p m)+      (permToMatrix inv p #*## m)  applyMultiply ::    (Class.Floating a) =>    Inversion ->-   (Permutation ZeroInt, Permutation ZeroInt,-    Matrix.General ZeroInt ZeroInt a) -> Bool+   (Permutation ShapeInt, Permutation ShapeInt,+    Matrix.General ShapeInt ShapeInt a) -> Bool applyMultiply inv (p0,p1,m) =    equalArray       (case inv of-         NonInverted -> permApply inv p0 $ permApply inv p1 m-         Inverted -> permApply inv p1 $ permApply inv p0 m)-      (permApply inv (Perm.multiply p0 p1) m)+         NonInverted -> Perm.apply inv p0 $ Perm.apply inv p1 m+         Inverted -> Perm.apply inv p1 $ Perm.apply inv p0 m)+      (Perm.apply inv (Perm.multiply p0 p1) m)  applyTranspose ::    (Class.Floating a) =>-   Inversion -> (Permutation ZeroInt, Matrix.General ZeroInt ZeroInt a) -> Bool+   Inversion -> (Permutation ShapeInt, Matrix.General ShapeInt ShapeInt a) -> Bool applyTranspose inv (p,m) =    equalArray-      (permApply inv (Perm.transpose p) m)-      (Matrix.transpose (permToMatrix inv p) <#> m)+      (Perm.apply inv (Perm.transpose p) m)+      (Matrix.transpose (permToMatrix inv p) #*## m)  -addTag :: Gen.T a dim array -> Gen.T a dim (Tagged a array)-addTag = fmap Tagged--taggedToMatrix ::-   (Class.Floating a) => Tagged a (Permutation ZeroInt) -> Square ZeroInt a-taggedToMatrix (Tagged p) = Perm.toMatrix p+genPermMatrix :: (Dim sh) => Gen.Matrix sh sh a (Matrix (Permutation sh) a)+genPermMatrix = PermMatrix.fromPermutation <$> genPermutation  determinantNumber ::-   (Class.Floating a, Eq a) => Tagged a (Permutation ZeroInt) -> Bool-determinantNumber tp@(Tagged p) =-   Perm.numberFromSign (Perm.determinant p)-   ==-   Square.determinant (taggedToMatrix tp)+   (Class.Floating a, Eq a) => Matrix (Permutation ShapeInt) a -> Bool+determinantNumber p =+   PermMatrix.determinant p == Square.determinant (PermMatrix.toMatrix p)   tests :: [(String, QC.Property)]@@ -154,12 +144,12 @@  checkForAll ::    (Show a, QC.Testable test) =>-   Gen.T tag dim a -> (a -> test) -> Tagged tag QC.Property+   Gen.T dim tag a -> (a -> test) -> Tagged tag QC.Property checkForAll gen = Util.checkForAll (Gen.run gen 10 5)  checkForAllExtra ::    (Show a, Show b, QC.Testable test) =>-   QC.Gen a -> Gen.T tag dim b ->+   QC.Gen a -> Gen.T dim tag b ->    (a -> b -> test) -> Tagged tag QC.Property checkForAllExtra = Gen.withExtra checkForAll @@ -167,16 +157,18 @@    (Show a, Class.Floating a, Eq a) =>    [(String, Tagged a QC.Property)] testsVar =+   ("index",+      checkForAll (Indexed.genMatrixIndex genPermMatrix) Indexed.unitDot) :    ("applyToMatrix",       checkForAllExtra QC.arbitraryBoundedEnum-         ((,) <$> genPermutation <|*|> Gen.matrix) applyToMatrix) :+         ((,) <$> genPermutation <#*#> Gen.matrix) applyToMatrix) :    ("applyMultiply",       checkForAllExtra QC.arbitraryBoundedEnum-         ((,,) <$> genPermutation <|*|> genPermutation <|*|> Gen.matrix)+         ((,,) <$> genPermutation <#*#> genPermutation <#*#> Gen.matrix)          applyMultiply) :    ("applyTranspose",       checkForAllExtra QC.arbitraryBoundedEnum-         ((,) <$> genPermutation <|*|> Gen.matrix) applyTranspose) :+         ((,) <$> genPermutation <#*#> Gen.matrix) applyTranspose) :    ("determinantNumber",-      checkForAll (addTag genPermutation) determinantNumber) :+      checkForAll genPermMatrix determinantNumber) :    []
test/Test/Shape.hs view
@@ -9,7 +9,9 @@  import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape import qualified Numeric.LAPACK.Matrix.Extent as Extent-import Numeric.LAPACK.Matrix (ZeroInt, zeroInt)+import qualified Numeric.LAPACK.Permutation as Perm+import qualified Numeric.LAPACK.Shape as ExtShape+import Numeric.LAPACK.Matrix (ShapeInt, shapeInt)  import qualified Type.Data.Num.Unary as Unary import Type.Data.Num.Unary (unary)@@ -19,65 +21,76 @@ import qualified Test.QuickCheck as QC  -genGeneral :: QC.Gen (MatrixShape.General ZeroInt ZeroInt)+genMin :: QC.Gen (ExtShape.Min ShapeInt (Shape.Shifted Int))+genMin = do+   m <- QC.choose (0,10)+   start <- QC.choose (-10,10)+   n <- QC.choose (0,10)+   return $ ExtShape.Min (shapeInt m) (Shape.Shifted start n)++genPermutation :: QC.Gen (Perm.Shape ShapeInt)+genPermutation = Perm.Shape . Shape.ZeroBased <$> QC.choose (0,10)+++genGeneral :: QC.Gen (MatrixShape.General ShapeInt ShapeInt) genGeneral = do    order <- genOrder    m <- QC.choose (0,10)    n <- QC.choose (0,10)-   return $ MatrixShape.general order (zeroInt m) (zeroInt n)+   return $ MatrixShape.general order (shapeInt m) (shapeInt n) -genTall :: QC.Gen (MatrixShape.Tall ZeroInt ZeroInt)+genTall :: QC.Gen (MatrixShape.Tall ShapeInt ShapeInt) genTall = do    order <- genOrder    m <- QC.choose (0,10)    n <- QC.choose (0,m)-   return $ MatrixShape.tall order (zeroInt m) (zeroInt n)+   return $ MatrixShape.tall order (shapeInt m) (shapeInt n) -genWide :: QC.Gen (MatrixShape.Wide ZeroInt ZeroInt)+genWide :: QC.Gen (MatrixShape.Wide ShapeInt ShapeInt) genWide = do    order <- genOrder    m <- QC.choose (0,10)    n <- QC.choose (m,10)-   return $ MatrixShape.wide order (zeroInt m) (zeroInt n)+   return $ MatrixShape.wide order (shapeInt m) (shapeInt n) -genSquare :: QC.Gen (MatrixShape.Square ZeroInt)+genSquare :: QC.Gen (MatrixShape.Square ShapeInt) genSquare = do    order <- genOrder    n <- QC.choose (0,10)-   return $ MatrixShape.square order (zeroInt n)+   return $ MatrixShape.square order (shapeInt n)  -genHermitian :: QC.Gen (MatrixShape.Hermitian ZeroInt)+genHermitian :: QC.Gen (MatrixShape.Hermitian ShapeInt) genHermitian = do    order <- genOrder    n <- QC.choose (0,10)-   return $ MatrixShape.hermitian order (zeroInt n)+   return $ MatrixShape.hermitian order (shapeInt n) -genDiagonal :: QC.Gen (MatrixShape.Diagonal ZeroInt)+genDiagonal :: QC.Gen (MatrixShape.Diagonal ShapeInt) genDiagonal = do    order <- genOrder    n <- QC.choose (0,10)-   return $ MatrixShape.diagonal order (zeroInt n)+   return $ MatrixShape.diagonal order (shapeInt n)  genLowerTriangular ::-   QC.Gen (MatrixShape.LowerTriangular MatrixShape.NonUnit ZeroInt)+   QC.Gen (MatrixShape.LowerTriangular MatrixShape.NonUnit ShapeInt) genLowerTriangular = do    order <- genOrder    n <- QC.choose (0,10)-   return $ MatrixShape.lowerTriangular order (zeroInt n)+   return $ MatrixShape.lowerTriangular order (shapeInt n)  genUpperTriangular ::-   QC.Gen (MatrixShape.UpperTriangular MatrixShape.NonUnit ZeroInt)+   QC.Gen (MatrixShape.UpperTriangular MatrixShape.NonUnit ShapeInt) genUpperTriangular = do    order <- genOrder    n <- QC.choose (0,10)-   return $ MatrixShape.upperTriangular order (zeroInt n)+   return $ MatrixShape.upperTriangular order (shapeInt n) -genSymmetric :: QC.Gen (MatrixShape.Symmetric ZeroInt)+genSymmetric :: QC.Gen (MatrixShape.Symmetric ShapeInt) genSymmetric = do    order <- genOrder    n <- QC.choose (0,10)-   return $ MatrixShape.symmetric order (zeroInt n)+   return $ MatrixShape.symmetric order (shapeInt n)   data Banded vert horiz height width =@@ -163,18 +176,21 @@       Shape.uncheckedIndexFromOffset sh  -genBandedHermitian :: QC.Gen (BandedHermitian ZeroInt)+genBandedHermitian :: QC.Gen (BandedHermitian ShapeInt) genBandedHermitian = do    order <- genOrder    n <- QC.choose (0,10)    k <- QC.choose (0,10)    Unary.reifyNatural k $ \numOff ->       return $ BandedHermitian $-         MatrixShape.bandedHermitian (unary numOff) order (zeroInt n)+         MatrixShape.bandedHermitian (unary numOff) order (shapeInt n)   tests :: [(String, QC.Property)] tests =+   prefix "Min" (ShapeTest.tests genMin) +++   prefix "Permutation" (ShapeTest.tests genPermutation) +++    prefix "General" (ShapeTest.tests genGeneral) ++    prefix "Tall" (ShapeTest.tests genTall) ++    prefix "Wide" (ShapeTest.tests genWide) ++
test/Test/Singular.hs view
@@ -3,15 +3,15 @@  import qualified Test.Generator as Gen import qualified Test.Utility as Util-import Test.Generator ((<|\|>))+import Test.Generator ((<#\#>)) import Test.Utility-         (approxReal, approxArrayTol, approxMatrix, isIdentity, Tagged)+         (approxReal, approxArrayTol, approxMatrix, isUnitary, Tagged)  import qualified Numeric.LAPACK.Singular as Singular import qualified Numeric.LAPACK.Orthogonal as Ortho-import qualified Numeric.LAPACK.Matrix.Hermitian as Herm import qualified Numeric.LAPACK.Matrix as Matrix-import Numeric.LAPACK.Matrix (General, ZeroInt, (<#>))+import Numeric.LAPACK.Matrix+         (General, ShapeInt, shapeInt, (##*#), (#*#), (#*##)) import Numeric.LAPACK.Scalar (RealOf, selectReal)  import qualified Numeric.Netlib.Class as Class@@ -20,13 +20,14 @@ import qualified Data.Array.Comfort.Shape as Shape  import Control.Applicative ((<$>))+import Data.Semigroup ((<>))  import qualified Test.QuickCheck as QC   pseudoInverseOrtho ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   General ZeroInt ZeroInt a -> Bool+   General ShapeInt ShapeInt a -> Bool pseudoInverseOrtho a =    let (no,invo) = Ortho.pseudoInverseRCond 1e-5 a        (ns,invs) = Singular.pseudoInverseRCond 1e-5 a@@ -35,28 +36,28 @@  pseudoInverseProjection ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   General ZeroInt ZeroInt a -> Bool+   General ShapeInt ShapeInt a -> Bool pseudoInverseProjection a =    let ainv = snd $ Singular.pseudoInverseRCond 1e-5 a        tol = selectReal 1e-1 1e-5-   in approxArrayTol tol a (a <#> ainv <#> a) &&-      approxArrayTol tol ainv (ainv <#> a <#> ainv)+   in approxArrayTol tol a (a <> ainv <> a) &&+      approxArrayTol tol ainv (ainv <> a <> ainv)  pseudoInverseHermitian ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   General ZeroInt ZeroInt a -> Bool+   General ShapeInt ShapeInt a -> Bool pseudoInverseHermitian a =    let ainv = snd $ Singular.pseudoInverseRCond 1e-5 a        tol = selectReal 1e-2 1e-5-       aainv = a <#> ainv-       ainva = ainv <#> a+       aainv = a <> ainv+       ainva = ainv <> a    in approxMatrix tol aainv (Matrix.adjoint aainv) &&       approxMatrix tol ainva (Matrix.adjoint ainva)   determinantAbsolute ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   General ZeroInt ZeroInt a -> Bool+   General ShapeInt ShapeInt a -> Bool determinantAbsolute a =    let detOrtho = Ortho.determinantAbsolute a        detSing = Singular.determinantAbsolute a@@ -67,7 +68,7 @@  leastSquaresMinimumNorm ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Matrix.General ZeroInt ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Matrix.General ShapeInt ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool leastSquaresMinimumNorm (a,b) =    let (no,xo) = Ortho.leastSquaresMinimumNormRCond 1e-5 a b        (ns,xs) = Singular.leastSquaresMinimumNormRCond 1e-5 a b@@ -77,47 +78,56 @@  decompose ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix.General ZeroInt ZeroInt a -> Bool+   Matrix.General ShapeInt ShapeInt a -> Bool decompose a =    let (u,s,vt) = Singular.decompose a        mn = Shape.size $ Array.shape s    in approxArrayTol 1e-3 a-        (Matrix.takeColumns mn (Matrix.generalizeWide u) <#>-         Matrix.scaleRowsReal s (Matrix.takeRows mn (Matrix.generalizeTall vt)))+        (Matrix.takeColumns mn (Matrix.generalizeWide u) #*#+         Matrix.scaleRowsReal+            (Array.mapShape (shapeInt . Shape.size) s)+            (Matrix.takeRows mn (Matrix.generalizeTall vt)))       &&-      isIdentity 1e-3 (Matrix.adjoint u <#> u)+      isUnitary 1e-3 u       &&-      isIdentity 1e-3 (Matrix.adjoint vt <#> vt)+      isUnitary 1e-3 vt  decomposeTall ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix.Tall ZeroInt ZeroInt a -> Bool+   Matrix.Tall ShapeInt ShapeInt a -> Bool decomposeTall a =    let (u,s,vt) = Singular.decomposeTall a-   in approxArrayTol 1e-3 a (u <#> Matrix.scaleRowsReal s vt)+   in approxArrayTol 1e-3 a (u ##*# Matrix.scaleRowsReal s vt)       &&-      isIdentity 1e-3 (Herm.toSquare $ Herm.covariance $ Matrix.fromFull u)+      isUnitary 1e-3 u       &&-      isIdentity 1e-3 (Matrix.adjoint vt <#> vt)+      isUnitary 1e-3 vt  decomposeWide ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Matrix.Wide ZeroInt ZeroInt a -> Bool+   Matrix.Wide ShapeInt ShapeInt a -> Bool decomposeWide a =    let (u,s,vt) = Singular.decomposeWide a-   in approxArrayTol 1e-3 a (u <#> Matrix.scaleRowsReal s vt)+   in approxArrayTol 1e-3 a (u #*## Matrix.scaleRowsReal s vt)       &&-      isIdentity 1e-3 (Matrix.adjoint u <#> u)+      isUnitary 1e-3 u       &&-      isIdentity 1e-3-         (Herm.toSquare $ Herm.covariance $-          Matrix.fromFull $ Matrix.transpose vt)+      isUnitary 1e-3 (Matrix.transpose vt) +decomposePolar ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Matrix.Tall ShapeInt ShapeInt a -> Bool+decomposePolar a =+   let (u,h) = Singular.decomposePolar a+   in approxArrayTol 1e-3 a (u ##*# h)+      &&+      isUnitary 1e-3 u  + checkForAll ::    (Show a, QC.Testable test) =>-   Gen.T tag dim a -> (a -> test) -> Tagged tag QC.Property+   Gen.T dim tag a -> (a -> test) -> Tagged tag QC.Property checkForAll gen = Util.checkForAll (Gen.run gen 3 5)  testsVar ::@@ -133,11 +143,13 @@    ("determinantAbsolute",       checkForAll Gen.matrix determinantAbsolute) :    ("leastSquaresMinimumNorm",-      checkForAll ((,) <$> Gen.matrix <|\|> Gen.matrix) leastSquaresMinimumNorm) :+      checkForAll ((,) <$> Gen.matrix <#\#> Gen.matrix) leastSquaresMinimumNorm) :    ("decompose",       checkForAll Gen.matrix decompose) :    ("decomposeTall",       checkForAll Gen.tall decomposeTall) :    ("decomposeWide",       checkForAll Gen.wide decomposeWide) :+   ("decomposePolar",+      checkForAll Gen.tall decomposePolar) :    []
test/Test/Square.hs view
@@ -1,45 +1,63 @@ {-# LANGUAGE TypeFamilies #-} module Test.Square (testsVar) where +import qualified Test.Divide as Divide+import qualified Test.Multiply as Multiply import qualified Test.Generator as Gen import qualified Test.Utility as Util-import Test.Generator ((<|*|>), (<|\|>))+import Test.Generator ((<#*#>), (<#\#>)) import Test.Utility (approx, approxArray, approxArrayTol, approxMatrix, Tagged) -import qualified Numeric.LAPACK.Matrix.Triangular as Tri-import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape import qualified Numeric.LAPACK.Matrix.Square as Square+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix as Matrix import qualified Numeric.LAPACK.Vector as Vector import Numeric.LAPACK.Matrix.Square (Square)-import Numeric.LAPACK.Matrix (ZeroInt, (<#>))-import Numeric.LAPACK.Vector (Vector)+import Numeric.LAPACK.Matrix+         (ShapeInt, (##*#), (#*##), (##/#), (#\##), (#*\), (\*#)) import Numeric.LAPACK.Scalar (RealOf, absolute, selectReal)  import qualified Numeric.Netlib.Class as Class -import qualified Data.Array.Comfort.Storable as Array- import Control.Applicative ((<$>))  import Data.Function.HT (nest)+import Data.Semigroup ((<>))+import Data.Complex (Complex)  import qualified Test.QuickCheck as QC  +congruence ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Square ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool+congruence (b,a) =+   approxArray+      (Square.toFull $ Square.congruence b a)+      (Matrix.adjoint a <> (b #*## a))++congruenceAdjoint ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Matrix.General ShapeInt ShapeInt a, Square ShapeInt a) -> Bool+congruenceAdjoint (a,b) =+   approxArray+      (Square.toFull $ Square.congruenceAdjoint a b)+      (a <> b #*## Matrix.adjoint a)+ multiplySquare ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool+   Square ShapeInt a -> Bool multiplySquare a =    approxArray (Square.square a) (Square.multiply a a)  multiplyPower ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Int -> Square ZeroInt a -> Bool+   Int -> Square ShapeInt a -> Bool multiplyPower n a =    let b = Square.power (fromIntegral n) a        c = nest n (Square.multiply a) $ Square.identityFrom a-   in approxArrayTol (1e-6 * (Vector.normInf1 b + Vector.normInf1 c)) b c+       normInf1 = Vector.normInf1 . ArrMatrix.toVector+   in approxArrayTol (1e-6 * (normInf1 b + normInf1 c)) b c   determinantSingleton ::@@ -50,7 +68,7 @@  determinantTranspose ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool+   Square ShapeInt a -> Bool determinantTranspose a =    approx 1e-5       (Square.determinant a) (Square.determinant $ Square.transpose a)@@ -58,93 +76,100 @@  multiplyDeterminant ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Square ZeroInt a, Square ZeroInt a) -> Bool+   (Square ShapeInt a, Square ShapeInt a) -> Bool multiplyDeterminant (a,b) =    let detA = Square.determinant a        detB = Square.determinant b    in approx          (1e-2 * max 1 (absolute detA) * max 1 (absolute detB))-         (Square.determinant (a<#>b))+         (Square.determinant (a<>b))          (detA * detB)  multiplyInverse ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool-multiplyInverse a =-   let eye = Square.inverse a <#> a-   in approxArrayTol 1e-4 eye (Square.identityFrom eye)+   Square ShapeInt a -> Bool+multiplyInverse a = Util.isIdentity 1e-4 $ Square.inverse a <> a   multiplySolve ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Square ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Square ShapeInt a, Matrix.General ShapeInt ShapeInt a) -> Bool multiplySolve (a, b) =-   approxMatrix 1e-2 (a <#> Square.solve a b) b+   approxMatrix 1e-2 (a #*## a #\## b) b  schur ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool+   Square ShapeInt a -> Bool schur a =    let (q,r) = Square.schur a-   in  approxMatrix 1e-4 a (q <#> r <#> Square.adjoint q)+   in approxMatrix 1e-4 a $ Square.congruenceAdjoint (Matrix.fromFull q) r +schurComplex :: (Class.Real a) => Square ShapeInt (Complex a) -> Bool+schurComplex a =+   let (q,r) = Square.schurComplex a+   in approxMatrix 1e-4 a $ q #*## r #*## Square.adjoint q -diagonal :: (Class.Floating a) => Vector ZeroInt a -> Tri.Diagonal ZeroInt a-diagonal = Tri.diagonal MatrixShape.ColumnMajor  genDiagonalizable ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Gen.Matrix a Int Int (Square ZeroInt a)-genDiagonalizable = flip Gen.mapGen Gen.invertible $ \ _maxElem a -> do+   Gen.MatrixInt a (Square ShapeInt a)+genDiagonalizable = flip Gen.mapQC Gen.invertible $ \a -> do    d <- Util.genDistinct 3 10 (Square.size a)-   return $ Square.solve a $ diagonal d <#> a+   return $ a #\## d \*# a   eigensystem ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool+   Square ShapeInt a -> Bool eigensystem a =-   let (vr,d,vl) = Square.eigensystem a-       scal = Array.map recip $ Square.takeDiagonal $ Square.adjoint vl <#> vr+   let (vr,d,vlAdj) = Square.eigensystem a+       scal = Square.takeDiagonal $ vlAdj <> vr    in  approxMatrix (selectReal 1e-1 1e-5)-         (Vector.toComplex a)-         (vr <#> diagonal d <#> diagonal scal <#> Square.adjoint vl)+         (Matrix.toComplex a)+         (vr #*\ Vector.divide d scal ##*# vlAdj)  eigensystemLeft ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool+   Square ShapeInt a -> Bool eigensystemLeft a =-   let (_vr,d,vl) = Square.eigensystem a-       vlAdj = Square.adjoint vl+   let (_vr,d,vlAdj) = Square.eigensystem a    in  approxMatrix (selectReal 1e-1 1e-5)-         (Vector.toComplex a)-         (Square.solve vlAdj $ diagonal d <#> vlAdj)+         (Matrix.toComplex a)+         (vlAdj #\## d \*# vlAdj)  eigensystemRight ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square ZeroInt a -> Bool+   Square ShapeInt a -> Bool eigensystemRight a =-   let (vr,d,_vl) = Square.eigensystem a-       solveLeft b m =-         Matrix.transpose $-         Square.solve (Matrix.transpose m) (Matrix.transpose b)+   let (vr,d,_vlAdj) = Square.eigensystem a    in  approxMatrix (selectReal 1e-1 1e-5)-         (Vector.toComplex a)-         (solveLeft (vr <#> diagonal d) vr)+         (Matrix.toComplex a)+         (vr #*\ d ##/# vr)    checkForAll ::    (Show a, QC.Testable test) =>-   Gen.T tag dim a -> (a -> test) -> Tagged tag QC.Property+   Gen.T dim tag a -> (a -> test) -> Tagged tag QC.Property checkForAll gen = Util.checkForAll (Gen.run gen 3 5)   testsVar ::-   (Show a, Class.Floating a, Eq a, RealOf a ~ ar, Class.Real ar) =>+   (Show a, Class.Floating a, Eq a, RealOf a ~ ar, Show ar, Class.Real ar) =>    [(String, Tagged a QC.Property)] testsVar =    ("multiplySquare",+      checkForAll Gen.square Multiply.multiplySquare) :+   ("squareSquare",+      checkForAll Gen.square Multiply.squareSquare) :+   ("power",+      Gen.withExtra checkForAll+         (QC.choose (0,10)) Gen.square Multiply.power) :+   ("congruence",+      checkForAll ((,) <$> Gen.square <#*#> Gen.matrix) congruence) :+   ("congruenceAdjoint",+      checkForAll ((,) <$> Gen.matrix <#*#> Gen.square) congruenceAdjoint) :+   ("multiplySquare",       checkForAll Gen.square multiplySquare) :    ("multiplyPower",       Gen.withExtra checkForAll (QC.choose (0,10)) Gen.square multiplyPower) :@@ -155,12 +180,15 @@    ("determinantTranspose",       checkForAll Gen.square determinantTranspose) :    ("multiplyDeterminant",-      checkForAll ((,) <$> Gen.square <|*|> Gen.square) multiplyDeterminant) :+      checkForAll ((,) <$> Gen.square <#*#> Gen.square) multiplyDeterminant) :    ("multiplySolve",-      checkForAll ((,) <$> Gen.invertible <|\|> Gen.matrix) multiplySolve) :+      checkForAll ((,) <$> Gen.invertible <#\#> Gen.matrix) multiplySolve) :+   Divide.testsVar Gen.invertible ++     ("schur",       checkForAll Gen.square schur) :+   ("schurComplex",+      checkForAll (Matrix.toComplex <$> Gen.square) schurComplex) :    ("eigensystem",       checkForAll genDiagonalizable eigensystem) :    ("eigensystemLeft",
test/Test/Triangular.hs view
@@ -1,76 +1,73 @@ {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE Rank2Types #-} module Test.Triangular (testsVar) where +import qualified Test.Divide as Divide+import qualified Test.Multiply as Multiply+import qualified Test.Generic as Generic import qualified Test.Indexed as Indexed import qualified Test.Generator as Gen import qualified Test.Utility as Util-import Test.Generator ((<.*|>), (<|*.>), (<|*|>), (<|\|>), (<|=|>))+import Test.Generator ((<-*#>), (<#*|>), (<#*#>), (<#\#>)) import Test.Utility-         (approx, approxArray, approxArrayTol, approxMatrix, equalArray, Tagged)+         (approx, approxArray, approxArrayTol, approxMatrix,+          approxVector, equalArray, Tagged, (!|||), (!===))  import qualified Numeric.LAPACK.Matrix.Triangular as Triangular import qualified Numeric.LAPACK.Matrix.Square as Square import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix as Matrix import qualified Numeric.LAPACK.Vector as Vector import Numeric.LAPACK.Matrix.Triangular (Triangular)-import Numeric.LAPACK.Matrix (General, ZeroInt, (<#), (<#>), (#>), (|||), (===))-import Numeric.LAPACK.Vector (Vector)-import Numeric.LAPACK.Scalar (RealOf, selectReal, absolute)+import Numeric.LAPACK.Matrix+         (General, ShapeInt, (#+#), (#-#),+          (-*#), (##*#), (#*##), (#*|), (|||), (===))+import Numeric.LAPACK.Vector (Vector, (|+|), (|-|))+import Numeric.LAPACK.Scalar (RealOf, selectReal)  import qualified Numeric.Netlib.Class as Class -import qualified Data.Array.Comfort.Storable as Array import qualified Data.Array.Comfort.Shape as Shape import Data.Array.Comfort.Storable ((!))+import Data.Array.Comfort.Shape ((:+:))  import Control.Applicative ((<$>)) -import Data.Tuple.HT (mapFst)+import Data.Tuple.HT (mapFst, uncurry3)+import Data.Semigroup ((<>))  import qualified Test.QuickCheck as QC  -forceOrder ::-   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,-    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   MatrixShape.Order ->-   (Triangular lo diag up ZeroInt a, Vector ZeroInt a) -> Bool-forceOrder order (a,x) =-   let ao = Triangular.forceOrder order a-   in MatrixShape.triangularOrder (Array.shape ao) == order-      &&-      approxArray (a #> x) (ao #> x)-+-- cf. Test.Generic.addDistributive addDistributive ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Eq lo, Eq up, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   ((Triangular lo diag up ZeroInt a,-     Triangular lo diag up ZeroInt a),-    Vector ZeroInt a) ->+   ((Triangular lo diag up ShapeInt a,+     Triangular lo diag up ShapeInt a),+    Vector ShapeInt a) ->    Bool addDistributive ((a,b),x) =-   approxArray-      (Triangular.add-         (Triangular.strictNonUnitDiagonal a)-         (Triangular.strictNonUnitDiagonal b) #> x)-      (Vector.add (a#>x) (b#>x))+   approxVector+      ((Triangular.strictNonUnitDiagonal a #+#+        Triangular.strictNonUnitDiagonal b)    #*| x)+      (a#*|x |+| b#*|x)  subDistributive ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Eq lo, Eq up, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   ((Triangular lo diag up ZeroInt a,-     Triangular lo diag up ZeroInt a),-    Vector ZeroInt a) ->+   ((Triangular lo diag up ShapeInt a,+     Triangular lo diag up ShapeInt a),+    Vector ShapeInt a) ->    Bool subDistributive ((a,b),x) =-   approxArray-      (Triangular.sub-         (Triangular.strictNonUnitDiagonal a)-         (Triangular.strictNonUnitDiagonal b) #> x)-      (Vector.sub (a#>x) (b#>x))+   approxVector+      ((Triangular.strictNonUnitDiagonal a #-#+        Triangular.strictNonUnitDiagonal b)    #*| x)+      (a#*|x |-| b#*|x)   expandTriangle ::@@ -82,60 +79,104 @@ transposedZero ::    (Class.Floating a, Shape.C width, Shape.C height) =>    General height width a -> General width height a-transposedZero a = Vector.constant (Array.shape (Matrix.transpose a)) 0+transposedZero = ArrMatrix.zero . ArrMatrix.shape . Matrix.transpose +stackDiagonal ::+   (MatrixShape.TriDiag diag, Class.Floating a) =>+   (Triangular.FlexDiagonal diag ShapeInt a,+    Triangular.FlexDiagonal diag ShapeInt a) ->+   Bool+stackDiagonal (a,c) =+   let ac = expandTriangle $ Triangular.stackDiagonal a c+       b = Matrix.zero $+           MatrixShape.general MatrixShape.RowMajor+              (Matrix.height a) (Matrix.height c)+   in equalArray ac $+         (expandTriangle a ||| b+          ===+          Matrix.transpose b ||| expandTriangle c)+ stackLower ::    (MatrixShape.TriDiag diag, Class.Floating a) =>-   (Triangular.FlexLower diag ZeroInt a,-    General ZeroInt ZeroInt a,-    Triangular.FlexLower diag ZeroInt a) ->+   (Triangular.FlexLower diag ShapeInt a,+    General ShapeInt ShapeInt a,+    Triangular.FlexLower diag ShapeInt a) ->    Bool stackLower (a,b,c) =    let abc = expandTriangle $ Triangular.stackLower a b c-   in equalArray abc $ Matrix.adaptOrder abc $-         (expandTriangle a ||| transposedZero b+   in equalArray abc $+         (expandTriangle a !||| transposedZero b           ===-          b ||| expandTriangle c)+          b !||| expandTriangle c)  stackUpper ::    (MatrixShape.TriDiag diag, Class.Floating a) =>-   (Triangular.FlexUpper diag ZeroInt a,-    General ZeroInt ZeroInt a,-    Triangular.FlexUpper diag ZeroInt a) ->+   (Triangular.FlexUpper diag ShapeInt a,+    General ShapeInt ShapeInt a,+    Triangular.FlexUpper diag ShapeInt a) ->    Bool stackUpper (a,b,c) =    let abc = Matrix.fromFull $          Triangular.toSquare $ Triangular.stackUpper a b c-   in equalArray abc $ Matrix.adaptOrder abc $+   in equalArray abc $          (expandTriangle a ||| b-          ===+          !===           transposedZero b ||| expandTriangle c)  stackSymmetric ::    (MatrixShape.TriDiag diag, Class.Floating a) =>-   (Triangular.FlexSymmetric diag ZeroInt a,-    General ZeroInt ZeroInt a,-    Triangular.FlexSymmetric diag ZeroInt a) ->+   (Triangular.FlexSymmetric diag ShapeInt a,+    General ShapeInt ShapeInt a,+    Triangular.FlexSymmetric diag ShapeInt a) ->    Bool stackSymmetric (a,b,c) =    let abc = expandTriangle $ Triangular.stackSymmetric a b c-   in equalArray abc $ Matrix.adaptOrder abc $+   in equalArray abc $          (expandTriangle a ||| b-          ===+          !===           Matrix.transpose b ||| expandTriangle c)  +splitDiagonal ::+   (MatrixShape.TriDiag diag, Eq diag, Class.Floating a) =>+   Triangular.FlexDiagonal diag (ShapeInt:+:ShapeInt) a -> Bool+splitDiagonal abc =+   equalArray abc $+      uncurry Triangular.stackDiagonal $ Triangular.splitDiagonal abc++splitLower ::+   (MatrixShape.TriDiag diag, Eq diag, Class.Floating a) =>+   Triangular.FlexLower diag (ShapeInt:+:ShapeInt) a -> Bool+splitLower abc =+   equalArray abc $+      uncurry3 Triangular.stackLower $ Triangular.splitLower abc++splitUpper ::+   (MatrixShape.TriDiag diag, Eq diag, Class.Floating a) =>+   Triangular.FlexUpper diag (ShapeInt:+:ShapeInt) a -> Bool+splitUpper abc =+   equalArray abc $+      uncurry3 Triangular.stackUpper $ Triangular.splitUpper abc++splitSymmetric ::+   (MatrixShape.TriDiag diag, Eq diag, Class.Floating a) =>+   Triangular.FlexSymmetric diag (ShapeInt:+:ShapeInt) a -> Bool+splitSymmetric abc =+   equalArray abc $+      uncurry3 Triangular.stackSymmetric $ Triangular.splitSymmetric abc++ multiplyIdentityVector ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Triangular lo diag up ZeroInt a, Vector ZeroInt a) -> Bool+   (Triangular lo diag up ShapeInt a, Vector ShapeInt a) -> Bool multiplyIdentityVector (eye,a) =-   approxArray a (Triangular.multiplyVector eye a)+   approxVector a (Triangular.multiplyVector eye a)  multiplyIdentityFull ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Triangular lo diag up ZeroInt a, General ZeroInt ZeroInt a) ->+   (Triangular lo diag up ShapeInt a, General ShapeInt ShapeInt a) ->    Bool multiplyIdentityFull (eye,a) =    approxArray a (Triangular.multiplyFull eye a)@@ -144,138 +185,93 @@    (MatrixShape.DiagUpLo lo up, MatrixShape.TriDiag diag,     Eq lo, Eq diag, Eq up,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Triangular lo diag up ZeroInt a, Triangular lo diag up ZeroInt a) ->+   (Triangular lo diag up ShapeInt a, Triangular lo diag up ShapeInt a) ->    Bool-multiplyIdentity (eye,a) =-   approxArray a (Triangular.multiply eye a)+multiplyIdentity (eye,a) = approxArray a (eye <> a)  multiplyVector ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Triangular lo diag up ZeroInt a, Vector ZeroInt a) -> Bool+   (Triangular lo diag up ShapeInt a, Vector ShapeInt a) -> Bool multiplyVector (a,x) =-   approxArray-      (Triangular.toSquare a #> x)+   approxVector+      (Triangular.toSquare a #*| x)       (Triangular.multiplyVector a x)  multiply ::    (MatrixShape.DiagUpLo lo up, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Triangular lo diag up ZeroInt a, Triangular lo diag up ZeroInt a) ->+   (Triangular lo diag up ShapeInt a, Triangular lo diag up ShapeInt a) ->    Bool multiply (a,b) =    approxArray-      (Triangular.toSquare a <#> Triangular.toSquare b)-      (Triangular.toSquare $ Triangular.multiply a b)+      (Triangular.toSquare a <> Triangular.toSquare b)+      (Triangular.toSquare $ a <> b)  multiplyFull ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Triangular lo diag up ZeroInt a, General ZeroInt ZeroInt a) ->+   (Triangular lo diag up ShapeInt a, General ShapeInt ShapeInt a) ->    Bool multiplyFull (a,b) =    approxArray-      (Triangular.toSquare a <#> b)+      (Triangular.toSquare a #*## b)       (Triangular.multiplyFull a b) -multiplySquare ::-   (MatrixShape.DiagUpLo lo up, MatrixShape.TriDiag diag,-    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Triangular lo diag up ZeroInt a -> Bool-multiplySquare a =-   approxArray-      (Triangular.toSquare $ Triangular.square a)-      (Triangular.multiplyFull a $ Triangular.toSquare a) -squareSquare ::-   (MatrixShape.DiagUpLo lo up, MatrixShape.TriDiag diag,-    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Triangular lo diag up ZeroInt a -> Bool-squareSquare a =-   approxArray-      (Triangular.toSquare $ Triangular.square a)-      (Square.square $ Triangular.toSquare a)-- multiplyVectorLeft ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Vector ZeroInt a, Triangular lo diag up ZeroInt a) -> Bool+   (Vector ShapeInt a, Triangular lo diag up ShapeInt a) -> Bool multiplyVectorLeft (x,a) =-   approxArray (x <# Triangular.toSquare a) (x <# a)+   approxVector (x -*# Triangular.toSquare a) (x -*# a)  multiplyVectorRight ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Triangular lo diag up ZeroInt a, Vector ZeroInt a) -> Bool+   (Triangular lo diag up ShapeInt a, Vector ShapeInt a) -> Bool multiplyVectorRight (a,x) =-   approxArray (Triangular.toSquare a #> x) (a #> x)+   approxVector (Triangular.toSquare a #*| x) (a #*| x)   multiplyLeft ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (General ZeroInt ZeroInt a, Triangular lo diag up ZeroInt a) -> Bool+   (General ShapeInt ShapeInt a, Triangular lo diag up ShapeInt a) -> Bool multiplyLeft (a,b) =-   approxMatrix 1e-5 (a <#> Triangular.toSquare b) (a <#> b)+   approxMatrix 1e-5 (a ##*# Triangular.toSquare b) (a ##*# b)  multiplyRight ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Triangular lo diag up ZeroInt a, General ZeroInt ZeroInt a) -> Bool+   (Triangular lo diag up ShapeInt a, General ShapeInt ShapeInt a) -> Bool multiplyRight (a,b) =-   approxArray (Triangular.toSquare a <#> b) (a <#> b)+   approxArray (Triangular.toSquare a #*## b) (a #*## b)   -determinant ::-   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,-    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Triangular lo diag up ZeroInt a -> Bool-determinant a =-   approx-      (selectReal 1e-1 1e-5)-      (Triangular.determinant a)-      (Square.determinant $ Triangular.toSquare a)---invertible ::-   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,-    Shape.C sh, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Triangular lo diag up sh a -> Bool-invertible a = absolute (Triangular.determinant a) > 0.1- genInvertible ::    (MatrixShape.Content up, MatrixShape.Content lo, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   GenTriangular lo diag up a-genInvertible = Gen.triangularCond invertible+   GenTriangular lo diag up ShapeInt a+genInvertible = Gen.condition Util.invertible Gen.triangular  inverse ::-   (MatrixShape.DiagUpLo lo up, MatrixShape.TriDiag diag,+   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Triangular lo diag up ZeroInt a -> Bool+   Triangular lo diag up ShapeInt a -> Bool inverse a =    approxArrayTol       (selectReal 1 1e-5)       (Triangular.toSquare $ Triangular.inverse a)       (Square.inverse $ Triangular.toSquare a) -inverseGeneric ::-   (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,-    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Triangular lo diag up ZeroInt a -> Bool-inverseGeneric a =-   approxArrayTol-      (selectReal 1 1e-5)-      (Triangular.toSquare $ Triangular.inverseGeneric a)-      (Square.inverse $ Triangular.toSquare a) - solve ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Triangular lo diag up ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Triangular lo diag up ShapeInt a, Matrix.General ShapeInt ShapeInt a) ->+   Bool solve (a, b) =    approxMatrix (selectReal 1 1e-5)       (Triangular.solve a b)@@ -284,17 +280,17 @@ solveIdentity ::    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Triangular lo diag up ZeroInt a, Matrix.General ZeroInt ZeroInt a) -> Bool+   (Triangular lo diag up ShapeInt a, Matrix.General ShapeInt ShapeInt a) ->+   Bool solveIdentity (eye, a) =-   approxMatrix (selectReal 1e-3 1e-5)-      a (Triangular.solve eye a)+   approxMatrix (selectReal 1e-3 1e-5) a (Triangular.solve eye a)    eigenvaluesDeterminant ::    (MatrixShape.DiagUpLo lo up, MatrixShape.TriDiag diag,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Triangular lo diag up ZeroInt a -> Bool+   Triangular lo diag up ShapeInt a -> Bool eigenvaluesDeterminant a =    approx       (selectReal 1e-1 1e-5)@@ -305,48 +301,41 @@ genDiagonalizable ::    (MatrixShape.Content lo, MatrixShape.Content up,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   GenTriangular lo MatrixShape.NonUnit up a+   GenTriangular lo MatrixShape.NonUnit up ShapeInt a genDiagonalizable =-   flip Gen.mapGen Gen.squareDim $ \maxElem size -> do-      order <- Util.genOrder-      d <- Util.genDistinct 3 10 size-      let shape =-            MatrixShape.Triangular-               MatrixShape.NonUnit MatrixShape.autoUplo order size+   flip Gen.mapGen Gen.triangularShape $ \maxElem shape -> do+      d <- Util.genDistinct 3 10 $ MatrixShape.triangularSize shape       Util.genArrayExtraDiag maxElem shape (\r -> return (d!r))  eigensystem ::    (MatrixShape.DiagUpLo lo up, Eq lo, Eq up,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   MatrixShape.Order -> Triangular lo MatrixShape.NonUnit up ZeroInt a -> Bool+   MatrixShape.Order -> Triangular lo MatrixShape.NonUnit up ShapeInt a -> Bool eigensystem order a =    let (vr,d,vl) = Triangular.eigensystem a-       scal = Triangular.takeDiagonal $ Triangular.multiply vl vr-   in approxMatrix-         (selectReal 1e-3 1e-5)-         (Triangular.toSquare a)-         (Triangular.toSquare $-          vr-          `Triangular.multiply`-          Triangular.diagonal order (Vector.mul d $ Array.map recip scal)-          `Triangular.multiply`+       scal = Triangular.takeDiagonal $ vl <> vr+   in approxMatrix (selectReal 1e-3 1e-5) a+         (vr+          <>+          Triangular.diagonal order (Vector.divide d scal)+          <>           vl)   checkForAll ::    (Show a, QC.Testable test) =>-   Gen.T tag dim a -> (a -> test) -> Tagged tag QC.Property+   Gen.T dim tag a -> (a -> test) -> Tagged tag QC.Property checkForAll gen = Util.checkForAll (Gen.run gen 3 5)  checkForAllExtra ::    (Show a, Show b, QC.Testable test) =>-   QC.Gen a -> Gen.T tag dim b ->+   QC.Gen a -> Gen.T dim tag b ->    (a -> b -> test) -> Tagged tag QC.Property checkForAllExtra = Gen.withExtra checkForAll  -type GenTriangular lo diag up a =-      Gen.Matrix a Int Int (Triangular lo diag up ZeroInt a)+type GenTriangular lo diag up sh a =+      Gen.Square sh a (Triangular lo diag up sh a)   addSuperName :: String -> [(String, a)] -> [(String, a)]@@ -358,12 +347,12 @@    (forall lo up.     (MatrixShape.Content lo, MatrixShape.Content up,      Eq lo, Eq up, Show lo, Show up) =>-    GenTriangular lo diag up a ->+    GenTriangular lo diag up sh a ->     Tagged a QC.Property) ->    (forall lo up.     (MatrixShape.Content lo, MatrixShape.Content up,      Eq lo, Eq up, Show lo, Show up) =>-    GenTriangular lo diag up a) ->+    GenTriangular lo diag up sh a) ->    [(String, Tagged a QC.Property)] checkAnyFlexDiag name checker gen =    (checkDiagUpLoFlexDiag name checker gen ++) $@@ -376,18 +365,18 @@    (forall lo up diag.     (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,      Eq lo, Eq up, Show lo, Show up, Show diag) =>-    GenTriangular lo diag up a ->+    GenTriangular lo diag up sh a ->     Tagged a QC.Property) ->    (forall lo up diag.     (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,      Eq lo, Eq up, Show lo, Show up, Show diag) =>-    GenTriangular lo diag up a) ->+    GenTriangular lo diag up sh a) ->    [(String, Tagged a QC.Property)] checkAny name checker gen =    checkAnyFlexDiag (name++".Unit") checker-      (Triangular.forceUnitDiagonal <$> gen) +++      (Triangular.requireUnitDiagonal <$> gen) ++    checkAnyFlexDiag (name++".NonUnit") checker-      (Triangular.forceNonUnitDiagonal <$> gen)+      (Triangular.requireNonUnitDiagonal <$> gen)   checkDiagUpLoFlexDiag ::@@ -395,11 +384,11 @@    String ->    (forall lo up.     (MatrixShape.DiagUpLo lo up, Eq lo, Eq up, Show lo, Show up) =>-    GenTriangular lo diag up a ->+    GenTriangular lo diag up sh a ->     Tagged a QC.Property) ->    (forall lo up.     (MatrixShape.DiagUpLo lo up, Eq lo, Eq up, Show lo, Show up) =>-    GenTriangular lo diag up a) ->+    GenTriangular lo diag up sh a) ->    [(String, Tagged a QC.Property)] checkDiagUpLoFlexDiag name checker gen =    addSuperName name $@@ -413,31 +402,63 @@    (forall lo up diag.     (MatrixShape.DiagUpLo lo up, MatrixShape.TriDiag diag,      Eq lo, Eq diag, Eq up, Show lo, Show diag, Show up) =>-    GenTriangular lo diag up a -> Tagged a QC.Property) ->+    GenTriangular lo diag up sh a -> Tagged a QC.Property) ->    (forall lo up diag.     (MatrixShape.DiagUpLo lo up, MatrixShape.TriDiag diag,      Eq lo, Eq diag, Eq up, Show lo, Show diag, Show up) =>-    GenTriangular lo diag up a) ->+    GenTriangular lo diag up sh a) ->    [(String, Tagged a QC.Property)] checkDiagUpLo name checker gen =    checkDiagUpLoFlexDiag (name++".Unit") checker-      (Triangular.forceUnitDiagonal <$> gen) +++      (Triangular.requireUnitDiagonal <$> gen) ++    checkDiagUpLoFlexDiag (name++".NonUnit") checker-      (Triangular.forceNonUnitDiagonal <$> gen)+      (Triangular.requireNonUnitDiagonal <$> gen)  +newtype Power diag sh a lo up =+   Power {getPower :: GenTriangular lo diag up sh a -> Tagged a QC.Property}++restrictDiagUpLo ::+   (MatrixShape.DiagUpLo lo0 up0, MatrixShape.TriDiag diag0,+    Eq lo0, Eq diag0, Eq up0, Show lo0, Show diag0, Show up0) =>+   (forall lo up diag.+    (Triangular.PowerContentDiag lo diag up,+     Eq lo, Eq diag, Eq up, Show lo, Show diag, Show up) =>+    GenTriangular lo diag up sh a -> Tagged a QC.Property) ->+   GenTriangular lo0 diag0 up0 sh a -> Tagged a QC.Property+restrictDiagUpLo f =+   getPower $ MatrixShape.switchDiagUpLo (Power f) (Power f) (Power f)++checkDiagUpLoSym ::+   String ->+   (forall lo up diag.+    (Triangular.PowerContentDiag lo diag up,+     Eq lo, Eq diag, Eq up, Show lo, Show diag, Show up) =>+    GenTriangular lo diag up ShapeInt a -> Tagged a QC.Property) ->+   (forall lo up diag.+    (MatrixShape.Content lo, MatrixShape.Content up, MatrixShape.TriDiag diag,+     Eq lo, Eq diag, Eq up, Show lo, Show diag, Show up) =>+    GenTriangular lo diag up ShapeInt a) ->+   [(String, Tagged a QC.Property)]+checkDiagUpLoSym name checker gen =+   (checkDiagUpLo name (restrictDiagUpLo checker) gen ++) $+   addSuperName name $+   ("Symmetric", checker (Triangular.asSymmetric <$> gen)) :+   []++ checkFlexDiag ::    String ->    (forall diag.     (MatrixShape.TriDiag diag, Eq diag, Show diag) =>-    GenTriangular lo diag up a -> Tagged a QC.Property) ->+    GenTriangular lo diag up sh a -> Tagged a QC.Property) ->    (forall diag.     (MatrixShape.TriDiag diag, Eq diag, Show diag) =>-    GenTriangular lo diag up a) ->+    GenTriangular lo diag up sh a) ->    [(String, Tagged a QC.Property)] checkFlexDiag name checker gen =-   (name++".Unit", checker (Triangular.forceUnitDiagonal <$> gen)) :-   (name++".NonUnit", checker (Triangular.forceNonUnitDiagonal <$> gen)) :+   (name++".Unit", checker (Triangular.requireUnitDiagonal <$> gen)) :+   (name++".NonUnit", checker (Triangular.requireNonUnitDiagonal <$> gen)) :    []  @@ -449,6 +470,9 @@       (\gen -> checkForAll (Indexed.genMatrixIndex gen) Indexed.unitDot)       Gen.triangular ++ +   checkFlexDiag "stackDiagonal"+      (\gen -> checkForAll (Gen.stackDiagonal gen gen) stackDiagonal)+      Gen.triangular ++    checkFlexDiag "stackLower"       (\gen ->          checkForAll (Gen.stack3 gen (Matrix.transpose <$> Gen.matrix) gen)@@ -461,77 +485,89 @@       (\gen -> checkForAll (Gen.stack3 gen Gen.matrix gen) stackSymmetric)       Gen.triangular ++ +   checkFlexDiag "splitDiagonal"+      (\gen -> checkForAll gen splitDiagonal)+      Gen.triangular +++   checkFlexDiag "splitLower"+      (\gen -> checkForAll gen splitLower)+      Gen.triangular +++   checkFlexDiag "splitUpper"+      (\gen -> checkForAll gen splitUpper)+      Gen.triangular +++   checkFlexDiag "splitSymmetric"+      (\gen -> checkForAll gen splitSymmetric)+      Gen.triangular +++    checkAny "forceOrder"       (\gen ->          checkForAllExtra Util.genOrder-            ((,) <$> gen <|*.> Gen.vector) forceOrder)+            ((,) <$> gen <#*|> Gen.vector) Generic.forceOrder)       Gen.triangular ++    checkAny "addDistributive"-      (\gen ->-         checkForAll-            ((,) <$> ((,) <$> gen <|=|> gen) <|*.> Gen.vector)-            addDistributive)+      (\gen -> checkForAll (Generic.genDistribution gen) addDistributive)       Gen.triangular ++    checkAny "subDistributive"-      (\gen ->-         checkForAll-            ((,) <$> ((,) <$> gen <|=|> gen) <|*.> Gen.vector)-            subDistributive)+      (\gen -> checkForAll (Generic.genDistribution gen) subDistributive)       Gen.triangular ++     checkAny "multiplyIdentityVector"-      (\gen -> checkForAll ((,) <$> gen <|*.> Gen.vector) multiplyIdentityVector)+      (\gen -> checkForAll ((,) <$> gen <#*|> Gen.vector)+         multiplyIdentityVector)       (Triangular.relaxUnitDiagonal <$> Gen.identity) ++    checkAny "multiplyIdentityFull"-      (\gen -> checkForAll ((,) <$> gen <|*|> Gen.matrix) multiplyIdentityFull)+      (\gen -> checkForAll ((,) <$> gen <#*#> Gen.matrix) multiplyIdentityFull)       (Triangular.relaxUnitDiagonal <$> Gen.identity) ++    checkDiagUpLo "multiplyIdentity"-      (\gen -> checkForAll ((,) <$> gen <|*|> Gen.triangular) multiplyIdentity)+      (\gen -> checkForAll ((,) <$> gen <#*#> Gen.triangular) multiplyIdentity)       (Triangular.relaxUnitDiagonal <$> Gen.identity) ++    checkAny "multiplyVector"-      (\gen -> checkForAll ((,) <$> gen <|*.> Gen.vector) multiplyVector)+      (\gen -> checkForAll ((,) <$> gen <#*|> Gen.vector) multiplyVector)       Gen.triangular ++    checkAny "multiplyFull"-      (\gen -> checkForAll ((,) <$> gen <|*|> Gen.matrix) multiplyFull)+      (\gen -> checkForAll ((,) <$> gen <#*#> Gen.matrix) multiplyFull)       Gen.triangular ++    checkAny "multiplyVectorLeft"-      (\gen -> checkForAll ((,) <$> Gen.vector <.*|> gen) multiplyVectorLeft)+      (\gen -> checkForAll ((,) <$> Gen.vector <-*#> gen) multiplyVectorLeft)       Gen.triangular ++    checkAny "multiplyVectorRight"-      (\gen -> checkForAll ((,) <$> gen <|*.> Gen.vector) multiplyVectorRight)+      (\gen -> checkForAll ((,) <$> gen <#*|> Gen.vector) multiplyVectorRight)       Gen.triangular ++    checkAny "multiplyLeft"-      (\gen -> checkForAll ((,) <$> Gen.matrix <|*|> gen) multiplyLeft)+      (\gen -> checkForAll ((,) <$> Gen.matrix <#*#> gen) multiplyLeft)       Gen.triangular ++    checkAny "multiplyRight"-      (\gen -> checkForAll ((,) <$> gen <|*|> Gen.matrix) multiplyRight)+      (\gen -> checkForAll ((,) <$> gen <#*#> Gen.matrix) multiplyRight)       Gen.triangular ++     checkDiagUpLo "multiply"-      (\gen -> checkForAll ((,) <$> gen <|*|> gen) multiply)+      (\gen -> checkForAll ((,) <$> gen <#*#> gen) multiply)       Gen.triangular ++-   checkDiagUpLo "multiplySquare"-      (\gen -> checkForAll gen multiplySquare)+   checkDiagUpLoSym "multiplySquare"+      (\gen -> checkForAll gen Multiply.multiplySquare)       Gen.triangular ++-   checkDiagUpLo "squareSquare"-      (\gen -> checkForAll gen squareSquare)+   checkDiagUpLoSym "squareSquare"+      (\gen -> checkForAll gen Multiply.squareSquare)       Gen.triangular +++   checkDiagUpLoSym "power"+      (\gen -> checkForAllExtra (QC.choose (0,10::Int)) gen Multiply.power)+      Gen.triangular ++     checkAny "determinant"-      (\gen -> checkForAll gen determinant)+      (\gen -> checkForAll gen Divide.determinant)       Gen.triangular ++    checkAny "solve"-      (\gen -> checkForAll ((,) <$> gen <|\|> Gen.matrix) solve)+      (\gen -> checkForAll ((,) <$> gen <#\#> Gen.matrix) solve)       genInvertible ++    checkAny "solveIdentity"-      (\gen -> checkForAll ((,) <$> gen <|\|> Gen.matrix) solveIdentity)+      (\gen -> checkForAll ((,) <$> gen <#\#> Gen.matrix) solveIdentity)       (Triangular.relaxUnitDiagonal <$> Gen.identity) ++-   checkDiagUpLo "inverse"+   checkAny "inverse"       (\gen -> checkForAll gen inverse)       genInvertible ++-   checkAny "inverseGeneric"-      (\gen -> checkForAll gen inverseGeneric)-      genInvertible +++   concatMap+      (\(name,test) ->+         checkAny name (test . fmap Divide.SquareMatrix) genInvertible)+      Divide.testsVarAny ++     checkDiagUpLo "eigenvaluesDeterminant"       (\gen -> checkForAll gen eigenvaluesDeterminant)
test/Test/Utility.hs view
@@ -1,14 +1,17 @@ {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} module Test.Utility where -import qualified Numeric.LAPACK.Matrix.Square as Square+import qualified Numeric.LAPACK.Matrix.Hermitian as Herm+import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix.Extent as Extent import qualified Numeric.LAPACK.Matrix as Matrix import qualified Numeric.LAPACK.Vector as Vector+import qualified Numeric.LAPACK.Orthogonal.Householder as HH import qualified Numeric.LAPACK.Orthogonal as Ortho-import Numeric.LAPACK.Matrix.Square (Square)+import Numeric.LAPACK.Matrix.Array (ArrayMatrix) import Numeric.LAPACK.Matrix.Shape (Order(RowMajor,ColumnMajor))-import Numeric.LAPACK.Matrix (ZeroInt)+import Numeric.LAPACK.Matrix (Matrix, ShapeInt) import Numeric.LAPACK.Vector (Vector) import Numeric.LAPACK.Scalar (RealOf, absolute) @@ -17,6 +20,7 @@ import qualified Data.Array.Comfort.Storable as Array import qualified Data.Array.Comfort.Shape as Shape import Data.Array.Comfort.Storable (Array)+import Data.Array.Comfort.Shape ((:+:))  import qualified Control.Monad.Trans.State as MS import Control.Monad (replicateM)@@ -47,18 +51,10 @@       (map Just ys ++ repeat Nothing)  -equalArray ::-   (Shape.C shape, Eq shape, Class.Floating a) =>-   Array shape a -> Array shape a -> Bool-equalArray x y =-   if Array.shape x == Array.shape y-     then equalArrayBody x y-     else error "equalArray: shapes mismatch"--equalArrayBody ::+equalVectorBody ::    (Shape.C shape, Class.Floating a) =>    Array shape a -> Array shape a -> Bool-equalArrayBody =+equalVectorBody =    getEqualArray $    Class.switchFloating       (EqualArray $ equating Array.toList)@@ -68,7 +64,25 @@  newtype EqualArray f a = EqualArray {getEqualArray :: f a -> f a -> Bool} +equalVector ::+   (Shape.C shape, Eq shape, Class.Floating a) =>+   Array shape a -> Array shape a -> Bool+equalVector x y =+   if Array.shape x == Array.shape y+     then equalVectorBody x y+     else error "equalArray: shapes mismatch" +equalArray ::+   (Shape.C shape, Eq shape, Class.Floating a) =>+   ArrayMatrix shape a -> ArrayMatrix shape a -> Bool+equalArray x y = equalVector (ArrMatrix.toVector x) (ArrMatrix.toVector y)++equalMatrix ::+   (ArrMatrix.ShapeOrder shape, Eq shape, Class.Floating a) =>+   ArrayMatrix shape a -> ArrayMatrix shape a -> Bool+equalMatrix x y = equalArray (Matrix.adaptOrder y x) y++ approx ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) => ar -> a -> a -> Bool approx tol x y = absolute (x-y) <= tol@@ -77,44 +91,59 @@ approxReal tol x y = abs (x-y) <= tol  -approxArrayTol ::+approxVectorTol ::    (Shape.C shape, Eq shape, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    ar -> Array shape a -> Array shape a -> Bool-approxArrayTol tol x y =+approxVectorTol tol x y =    if Array.shape x == Array.shape y      then and $ zipWith (approx tol) (Array.toList x) (Array.toList y)      else error "approxArray: shapes mismatch" -approxArray ::+approxVector ::    (Shape.C shape, Eq shape, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>    Array shape a -> Array shape a -> Bool-approxArray = approxArrayTol 1e-5+approxVector = approxVectorTol 1e-5 -approxRealArrayTol ::+approxRealVectorTol ::    (Shape.C shape, Eq shape, Class.Real a) =>    a -> Array shape a -> Array shape a -> Bool-approxRealArrayTol tol x y =+approxRealVectorTol tol x y =    if Array.shape x == Array.shape y      then and $ zipWith (approxReal tol) (Array.toList x) (Array.toList y)      else error "approxRealArray: shapes mismatch" ++approxArrayTol ::+   (Shape.C shape, Eq shape, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   ar -> ArrayMatrix shape a -> ArrayMatrix shape a -> Bool+approxArrayTol tol x y =+   approxVectorTol tol (ArrMatrix.toVector x) (ArrMatrix.toVector y)++approxArray ::+   (Shape.C shape, Eq shape, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   ArrayMatrix shape a -> ArrayMatrix shape a -> Bool+approxArray x y = approxVector (ArrMatrix.toVector x) (ArrMatrix.toVector y)++ approxMatrix ::-   (Extent.C vert, Extent.C horiz,-    Shape.C height, Eq height, Shape.C width, Eq width,+   (ArrMatrix.ShapeOrder shape, Eq shape,     Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   ar ->-   Matrix.Full vert horiz height width a ->-   Matrix.Full vert horiz height width a -> Bool+   ar -> ArrayMatrix shape a -> ArrayMatrix shape a -> Bool approxMatrix tol x y =-   approxArrayTol tol-      (Matrix.toRowMajor $ Matrix.fromFull x)-      (Matrix.toRowMajor $ Matrix.fromFull y)+   approxArrayTol tol x $ Matrix.adaptOrder x y  -maybeProperty :: (QC.Testable a) => Maybe a -> QC.Property-maybeProperty = maybe (QC.property QC.Discard) QC.property+maybeConjugate ::+   (Matrix.Complex typ, Class.Floating a) =>+   HH.Conjugation -> Matrix typ a -> Matrix typ a+maybeConjugate HH.NonConjugated = id+maybeConjugate HH.Conjugated = Matrix.conjugate  +type NonEmptyInt = ():+:ShapeInt+type EInt = Either () Int++ genReal :: (Class.Real a) => Integer -> QC.Gen a genReal n = fromInteger <$> QC.choose (-n,n) @@ -125,21 +154,26 @@ genElement n =    Class.switchFloating (genReal n) (genReal n) (genComplex n) (genComplex n) -genArray ::+genVector ::    (Shape.C shape, Class.Floating a) =>    Integer -> shape -> QC.Gen (Array shape a)-genArray maxElem shape =+genVector maxElem shape =    Array.fromList shape <$> replicateM (Shape.size shape) (genElement maxElem) +genArray ::+   (Shape.C shape, Class.Floating a) =>+   Integer -> shape -> QC.Gen (ArrayMatrix shape a)+genArray maxElem shape = fmap ArrMatrix.lift0 $ genVector maxElem shape+ genArrayIndexed ::    (Shape.Indexed shape, Class.Floating a) =>-   shape -> (Shape.Index shape -> QC.Gen a) -> QC.Gen (Array shape a)+   shape -> (Shape.Index shape -> QC.Gen a) -> QC.Gen (ArrayMatrix shape a) genArrayIndexed shape f =-   Array.fromList shape <$> traverse f (Shape.indices shape)+   ArrMatrix.lift0 . Array.fromList shape <$> traverse f (Shape.indices shape)  genArrayExtraDiag ::    (Shape.Indexed shape, Shape.Index shape ~ (i,i), Eq i, Class.Floating a) =>-   Integer -> shape -> (i -> QC.Gen a) -> QC.Gen (Array shape a)+   Integer -> shape -> (i -> QC.Gen a) -> QC.Gen (ArrayMatrix shape a) genArrayExtraDiag maxElem shape diag =    genArrayIndexed shape $       \(r,c) -> if r==c then diag r else genElement maxElem@@ -150,17 +184,16 @@  genDistinct ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Integer -> Integer -> ZeroInt -> QC.Gen (Vector ZeroInt a)+   Integer -> Integer -> ShapeInt -> QC.Gen (Vector ShapeInt a) genDistinct maxElemS maxElemD size@(Shape.ZeroBased n) = do    let range k = map fromInteger [(-k)..k]-   xs <-+   fmap (Vector.fromList size) $       MS.evalStateT (replicateM n $ MS.StateT select) $       Class.switchFloating          (range maxElemS)          (range maxElemD)          (liftA2 (:+) (range maxElemS) (range maxElemS))          (liftA2 (:+) (range maxElemD) (range maxElemD))-   return $ Vector.fromList size xs   genOrder :: QC.Gen Order@@ -169,9 +202,9 @@   invertible ::-   (Shape.C sh, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Square sh a -> Bool-invertible a = absolute (Square.determinant a) > 0.1+   (Matrix.Determinant typ, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Matrix typ a -> Bool+invertible a = absolute (Matrix.determinant a) > 0.1  fullRankTall ::    (Shape.C height, Shape.C width,@@ -181,10 +214,43 @@   isIdentity ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   ar -> Square ZeroInt a -> Bool+   (ArrMatrix.SquareShape shape, ArrMatrix.ShapeOrder shape, Eq shape,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   ar -> ArrayMatrix shape a -> Bool isIdentity tol eye =-   approxArrayTol tol eye (Square.identityFrom eye)+   approxArrayTol tol eye (Matrix.identityFrom eye)++isUnitary ::+   (Extent.C vert, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   ar -> Matrix.Full vert Extent.Small ShapeInt ShapeInt a -> Bool+isUnitary tol = isIdentity tol . Herm.gramian . Matrix.fromFull+++addMatrices ::+   (ArrMatrix.Homogeneous sh, Eq sh, Class.Floating a) =>+   sh -> [ArrayMatrix sh a] -> ArrayMatrix sh a+addMatrices sh = foldl (ArrMatrix.lift2 Vector.add) (ArrMatrix.zero sh)++++infixl 3 !|||+infixl 2 !===++(!|||) ::+   (Shape.C height, Eq height, Shape.C widthA, Shape.C widthB,+    Class.Floating a) =>+   Matrix.General height widthA a ->+   Matrix.General height widthB a ->+   Matrix.General height (widthA:+:widthB) a+(!|||) = Matrix.beside Matrix.leftBias Extent.appendAny++(!===) ::+   (Shape.C width, Eq width, Shape.C heightA, Shape.C heightB,+    Class.Floating a) =>+   Matrix.General heightA width a ->+   Matrix.General heightB width a ->+   Matrix.General (heightA:+:heightB) width a+(!===) = Matrix.above Matrix.leftBias Extent.appendAny   
test/Test/Vector.hs view
@@ -3,17 +3,19 @@  import qualified Test.Generator as Gen import qualified Test.Utility as Util-import Test.Utility (Tagged(Tagged), TaggedGen)+import Test.Generator ((<+++>), (<.*#>), (<#*|>), (<|=|>))+import Test.Utility (Tagged, NonEmptyInt, EInt) +import qualified Numeric.LAPACK.Matrix.Triangular as Triangular import qualified Numeric.LAPACK.Vector as Vector import qualified Numeric.LAPACK.Scalar as Scalar-import Numeric.LAPACK.Matrix (ZeroInt, zeroInt)-import Numeric.LAPACK.Vector (Vector)+import Numeric.LAPACK.Matrix (ShapeInt, shapeInt, (-/#))+import Numeric.LAPACK.Vector (Vector, (|+|), (|-|), (.*|)) import Numeric.LAPACK.Scalar (RealOf)  import qualified Numeric.Netlib.Class as Class -import Control.Applicative (liftA2, (<$>))+import Control.Applicative ((<$>))  import qualified Data.Array.Comfort.Storable as Array import qualified Data.Array.Comfort.Shape as Shape@@ -27,51 +29,52 @@   singleton :: (Class.Floating a) => a -> Bool-singleton x = Util.equalArray (Vector.singleton x) (Vector.constant () x)--appendTakeDrop ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Int -> Vector ZeroInt a -> Bool-appendTakeDrop n x =-   Util.equalArray x $-   Array.mapShape (zeroInt . Shape.size)-      (Vector.append (Vector.take n x) (Vector.drop n x))--takeLeftRightAppend ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   (Vector ZeroInt a, Vector ZeroInt a) -> Bool-takeLeftRightAppend (x,y) =-   let xy = Vector.append x y-   in Util.equalArray x (Vector.takeLeft xy)-      &&-      Util.equalArray y (Vector.takeRight xy)+singleton x = Util.equalVector (Vector.singleton x) (Vector.constant () x)  -genSwapVector :: (Class.Floating a) => TaggedGen a ((Int,Int), Vector ZeroInt a)+genSwapVector ::+   (Class.Floating a) =>+   Gen.Vector NonEmptyInt a ((EInt, EInt), Vector NonEmptyInt a) genSwapVector =-   flip fmap genVector $ \gen -> do-      x <- gen `QC.suchThat` (not . null . Vector.toList)+   flip Gen.mapQC Gen.vector $ \x -> do       let set = Shape.indices $ Array.shape x       i <- QC.elements set       j <- QC.elements set       return ((i,j),x)  swapInverse ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   ((Int,Int), Vector ZeroInt a) -> Bool+   (Eq sh, Shape.Indexed sh, Shape.Index sh ~ ix,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   ((ix,ix), Vector sh a) -> Bool swapInverse ((i,j),x) =-   Util.equalArray x $ Vector.swap i j $ Vector.swap i j x+   Util.equalVector x $ Vector.swap i j $ Vector.swap i j x  swapCommutative ::-   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   ((Int,Int), Vector ZeroInt a) -> Bool+   (Eq sh, Shape.Indexed sh, Shape.Index sh ~ ix,+    Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   ((ix,ix), Vector sh a) -> Bool swapCommutative ((i,j),x) =-   Util.equalArray (Vector.swap i j x) (Vector.swap j i x)+   Util.equalVector (Vector.swap i j x) (Vector.swap j i x)  +norm2Squared ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Vector ShapeInt a -> Bool+norm2Squared x =+   Util.approxReal+      (Scalar.selectReal 1e-3 1e-10)+      (Vector.norm2Squared x) (Vector.norm2 x ^ (2::Int))++norm2Inner ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   Vector ShapeInt a -> Bool+norm2Inner x =+   Scalar.equal (Vector.inner x x) (Scalar.fromReal (Vector.norm2Squared x))++ normInf ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Vector ZeroInt a -> Bool+   Vector ShapeInt a -> Bool normInf x =    Vector.normInf x    ==@@ -79,19 +82,16 @@  normInf1 ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Vector ZeroInt a -> Bool+   Vector ShapeInt a -> Bool normInf1 x =    Vector.normInf1 x    ==    (NonEmpty.maximum $ 0 !: map Scalar.norm1 (Array.toList x))  -genVector :: (Class.Floating a) => TaggedGen a (Vector ZeroInt a)-genVector = Tagged $ Util.genArray 10 . zeroInt =<< QC.choose (0,5)- normInfAppend ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar, RealOf ar ~ ar) =>-   (Vector ZeroInt a, Vector ZeroInt a) -> Bool+   (Vector ShapeInt a, Vector ShapeInt a) -> Bool normInfAppend (x,y) =    Vector.normInf (Vector.append x y)    ==@@ -99,35 +99,101 @@  normInf1Append ::    (Class.Floating a, RealOf a ~ ar, Class.Real ar, RealOf ar ~ ar) =>-   (Vector ZeroInt a, Vector ZeroInt a) -> Bool+   (Vector ShapeInt a, Vector ShapeInt a) -> Bool normInf1Append (x,y) =    Vector.normInf1 (Vector.append x y)    ==    Vector.normInf1 (Vector.autoFromList [Vector.normInf1 x, Vector.normInf1 y])  +sumList :: (Eq a, Class.Floating a) => Vector ShapeInt a -> Bool+sumList xs  =  Vector.sum xs == sum (Vector.toList xs)++productList :: (Eq a, Class.Floating a) => Vector ShapeInt a -> Bool+productList xs  =  Vector.product xs == product (Vector.toList xs)+++withNonEmpty ::+   (Vector ShapeInt a -> b) ->+   (b -> Vector ShapeInt a -> Bool) ->+   Vector ShapeInt a -> Bool+withNonEmpty f law xs =+   let x = f xs+   in if Array.shape xs == shapeInt 0+         then isBottom x+         else law x xs++minimumList :: (Class.Real a) => Vector ShapeInt a -> Bool+minimumList =+   withNonEmpty Vector.minimum $ \x xs -> x == minimum (Vector.toList xs)++maximumList :: (Class.Real a) => Vector ShapeInt a -> Bool+maximumList =+   withNonEmpty Vector.maximum $ \x xs -> x == maximum (Vector.toList xs)++limitsMinimumMaximum :: (Class.Real a) => Vector ShapeInt a -> Bool+limitsMinimumMaximum =+   withNonEmpty Vector.limits $+      \xe xs -> xe == (Vector.minimum xs, Vector.maximum xs)++limits :: (Class.Real a) => Vector ShapeInt a -> Bool+limits =+   withNonEmpty Vector.limits $ \xe xs -> xe == Array.limits xs++argLimits :: (Class.Real a) => Vector ShapeInt a -> Bool+argLimits =+   withNonEmpty Vector.argLimits $+      \xe xs -> xe == (Vector.argMinimum xs, Vector.argMaximum xs)++ argAbsMaximum ::    (Eq a, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Vector ZeroInt a -> Bool-argAbsMaximum xs =-   let kx@(k,x) = Vector.argAbsMaximum xs-   in if Array.shape xs == zeroInt 0-         then isBottom kx-         else xs!k == x && Scalar.absolute x == Vector.normInf xs+   Vector ShapeInt a -> Bool+argAbsMaximum =+   withNonEmpty Vector.argAbsMaximum $+      \(k,x) xs -> xs!k == x && Scalar.absolute x == Vector.normInf xs  argAbs1Maximum ::    (Eq a, Class.Floating a, RealOf a ~ ar, Class.Real ar) =>-   Vector ZeroInt a -> Bool-argAbs1Maximum xs =-   let kx@(k,x) = Vector.argAbs1Maximum xs-   in if Array.shape xs == zeroInt 0-         then isBottom kx-         else xs!k == x && Scalar.norm1 x == Vector.normInf1 xs+   Vector ShapeInt a -> Bool+argAbs1Maximum =+   withNonEmpty Vector.argAbs1Maximum $+      \(k,x) xs -> xs!k == x && Scalar.norm1 x == Vector.normInf1 xs  +raiseZero :: (Eq a, Class.Floating a) => Vector ShapeInt a -> Bool+raiseZero xs =  Util.equalVector xs $ Vector.raise Scalar.zero xs++addRaise :: (Eq a, Class.Floating a) => (a, Vector ShapeInt a) -> Bool+addRaise (x,ys) =+   Util.equalVector+      (Vector.raise x ys)+      (ys |+| Vector.constant (Array.shape ys) x)++subRaise :: (Eq a, Class.Floating a) => (a, Vector ShapeInt a) -> Bool+subRaise (x,ys) =+   Util.equalVector+      (Vector.raise (-x) ys)+      (ys |-| Vector.constant (Array.shape ys) x)++addScaleMac ::+   (Eq a, Class.Floating a) => (a, Vector ShapeInt a, Vector ShapeInt a) -> Bool+addScaleMac (a,xs,ys) =+   Util.equalVector (Vector.mac a xs ys) (a.*|xs |+| ys)+++divide ::+   (Class.Floating a, RealOf a ~ ar, Class.Real ar) =>+   (Triangular.Diagonal ShapeInt a, Vector ShapeInt a) -> Bool+divide (a,b) =+   Util.approxVector+      (b -/# a)+      (Vector.divide b $ Triangular.takeDiagonal a)++ checkForAll ::    (Show a, QC.Testable test) =>-   Gen.T tag dim a -> (a -> test) -> Tagged tag QC.Property+   Gen.T dim tag a -> (a -> test) -> Tagged tag QC.Property checkForAll gen = Util.checkForAll (Gen.run gen 10 5)  @@ -138,28 +204,52 @@ testsVar =    ("singleton",       checkForAll Gen.scalar singleton) :-   ("appendTakeDrop",-      Gen.withExtra checkForAll-         (QC.getNonNegative <$> QC.arbitrary) Gen.vector appendTakeDrop) :-   ("takeLeftRightAppend",-      Util.checkForAllPlain-         (liftA2 (liftA2 (,)) genVector genVector) takeLeftRightAppend) :    ("swapInverse",-      Util.checkForAllPlain genSwapVector swapInverse) :+      checkForAll genSwapVector swapInverse) :    ("swapCommutative",-      Util.checkForAllPlain genSwapVector swapCommutative) :+      checkForAll genSwapVector swapCommutative) :+   ("norm2Squared",+      checkForAll Gen.vector norm2Squared) :+   ("norm2Inner",+      checkForAll Gen.vector norm2Inner) :    ("normInf",       checkForAll Gen.vector normInf) :    ("normInf1",       checkForAll Gen.vector normInf1) :    ("normInfAppend",-      Util.checkForAllPlain-         (liftA2 (liftA2 (,)) genVector genVector) normInfAppend) :+      checkForAll ((,) <$> Gen.vector <+++> Gen.vector) normInfAppend) :    ("normInf1Append",-      Util.checkForAllPlain-         (liftA2 (liftA2 (,)) genVector genVector) normInf1Append) :+      checkForAll ((,) <$> Gen.vector <+++> Gen.vector) normInf1Append) :+   ("sum",+      checkForAll Gen.vector sumList) :+   ("product",+      checkForAll Gen.vector productList) :+   ("minimum",+      checkForAll Gen.vector (minimumList . Vector.realPart)) :+   ("maximum",+      checkForAll Gen.vector (maximumList . Vector.realPart)) :+   ("limitsMinimumMaximum",+      checkForAll Gen.vector (limitsMinimumMaximum . Vector.realPart)) :+   ("limits",+      checkForAll Gen.vector (limits . Vector.realPart)) :+   ("argLimits",+      checkForAll Gen.vector (argLimits . Vector.realPart)) :    ("argAbsMaximum",       checkForAll Gen.vector argAbsMaximum) :    ("argAbs1Maximum",       checkForAll Gen.vector argAbs1Maximum) :+   ("raiseZero",+      checkForAll Gen.vector raiseZero) :+   ("addRaise",+      checkForAll ((,) <$> Gen.scalar <.*#> Gen.vector) addRaise) :+   ("subRaise",+      checkForAll ((,) <$> Gen.scalar <.*#> Gen.vector) subRaise) :+   ("addScaleMac",+      checkForAll+         ((,,) <$> Gen.scalar <.*#> Gen.vector <|=|> Gen.vector)+         addScaleMac) :+   ("divide",+      checkForAll+         ((,) <$> Gen.condition Util.invertible Gen.diagonal <#*|> Gen.vector)+         divide) :    []