{-# 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, copyToColumnMajorTemp)

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 {
      Matrix (LU vert horiz height width) a
-> Vector (Min width (Shape height)) (Element height)
_pivot ::
         Vector (ExtShape.Min width (Perm.Shape height)) (Perm.Element height),
      Matrix (LU vert horiz height width) a
-> Array (Split Triangle vert horiz height width) a
split_ ::
         Array
            (MatrixShape.Split MatrixShape.Triangle vert horiz height width) a
   } deriving (Int -> Matrix (LU vert horiz height width) a -> ShowS
[Matrix (LU vert horiz height width) a] -> ShowS
Matrix (LU vert horiz height width) a -> String
(Int -> Matrix (LU vert horiz height width) a -> ShowS)
-> (Matrix (LU vert horiz height width) a -> String)
-> ([Matrix (LU vert horiz height width) a] -> ShowS)
-> Show (Matrix (LU vert horiz height width) a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall vert horiz height width a.
(C width, C height, C vert, C horiz, Storable a, Show width,
 Show height, Show a) =>
Int -> Matrix (LU vert horiz height width) a -> ShowS
forall vert horiz height width a.
(C width, C height, C vert, C horiz, Storable a, Show width,
 Show height, Show a) =>
[Matrix (LU vert horiz height width) a] -> ShowS
forall vert horiz height width a.
(C width, C height, C vert, C horiz, Storable a, Show width,
 Show height, Show a) =>
Matrix (LU vert horiz height width) a -> String
showList :: [Matrix (LU vert horiz height width) a] -> ShowS
$cshowList :: forall vert horiz height width a.
(C width, C height, C vert, C horiz, Storable a, Show width,
 Show height, Show a) =>
[Matrix (LU vert horiz height width) a] -> ShowS
show :: Matrix (LU vert horiz height width) a -> String
$cshow :: forall vert horiz height width a.
(C width, C height, C vert, C horiz, Storable a, Show width,
 Show height, Show a) =>
Matrix (LU vert horiz height width) a -> String
showsPrec :: Int -> Matrix (LU vert horiz height width) a -> ShowS
$cshowsPrec :: forall vert horiz height width a.
(C width, C height, C vert, C horiz, Storable a, Show width,
 Show height, Show a) =>
Int -> Matrix (LU vert horiz height width) a -> ShowS
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 :: String -> Matrix (LU vert horiz height width) a -> out
formatMatrix String
fmt lu :: Matrix (LU vert horiz height width) a
lu@(LowerUpper _ipiv m) =
      Permutation height -> out
forall sh out. (C sh, Output out) => Permutation sh -> out
Perm.format (Inversion
-> Matrix (LU vert horiz height width) a -> Permutation height
forall vert horiz height width a.
(C vert, C horiz, C height, C width) =>
Inversion
-> LowerUpper vert horiz height width a -> Permutation height
extractP Inversion
NonInverted Matrix (LU vert horiz height width) a
lu)
      out -> out -> out
forall out. Output out => out -> out -> out
/+/
      String -> Array (Split Triangle vert horiz height width) a -> out
forall sh a out.
(FormatArray sh, Floating a, Output out) =>
String -> Array sh a -> out
formatArray String
fmt Array (Split Triangle vert horiz height width) a
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 :: Map vertA horizA vertB horizB height width
-> LowerUpper vertA horizA height width a
-> LowerUpper vertB horizB height width a
mapExtent Map vertA horizA vertB horizB height width
f (LowerUpper pivot split) =
   Vector (Min width (Shape height)) (Element height)
-> Array (Split Triangle vertB horizB height width) a
-> LowerUpper vertB horizB height width a
forall vert horiz height width a.
Vector (Min width (Shape height)) (Element height)
-> Array (Split Triangle vert horiz height width) a
-> Matrix (LU vert horiz height width) a
LowerUpper Vector (Min width (Shape height)) (Element height)
pivot (Array (Split Triangle vertB horizB height width) a
 -> LowerUpper vertB horizB height width a)
-> Array (Split Triangle vertB horizB height width) a
-> LowerUpper vertB horizB height width a
forall a b. (a -> b) -> a -> b
$ (Split Triangle vertA horizA height width
 -> Split Triangle vertB horizB height width)
-> Array (Split Triangle vertA horizA height width) a
-> Array (Split Triangle vertB horizB height width) a
forall sh0 sh1 a. (sh0 -> sh1) -> Array sh0 a -> Array sh1 a
Array.mapShape (Map vertA horizA vertB horizB height width
-> Split Triangle vertA horizA height width
-> Split Triangle vertB horizB height width
forall vertA horizA vertB horizB height width lower.
Map vertA horizA vertB horizB height width
-> Split lower vertA horizA height width
-> Split lower vertB horizB height width
MatrixShape.splitMapExtent Map vertA horizA vertB horizB height width
f) Array (Split Triangle vertA horizA height width) a
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 :: Full vert horiz height width a
-> LowerUpper vert horiz height width a
fromMatrix (Array (MatrixShape.Full Order
order Extent vert horiz height width
extent) ForeignPtr a
a) =
   let (height
height,width
width) = Extent vert horiz height width -> (height, width)
forall vert horiz height width.
(C vert, C horiz) =>
Extent vert horiz height width -> (height, width)
Extent.dimensions Extent vert horiz height width
extent
   in (Vector (Min width (Shape height)) (Element height)
 -> Array (Split Triangle vert horiz height width) a
 -> LowerUpper vert horiz height width a)
-> (Vector (Min width (Shape height)) (Element height),
    Array (Split Triangle vert horiz height width) a)
-> LowerUpper vert horiz height width a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Vector (Min width (Shape height)) (Element height)
-> Array (Split Triangle vert horiz height width) a
-> LowerUpper vert horiz height width a
forall vert horiz height width a.
Vector (Min width (Shape height)) (Element height)
-> Array (Split Triangle vert horiz height width) a
-> Matrix (LU vert horiz height width) a
LowerUpper ((Vector (Min width (Shape height)) (Element height),
  Array (Split Triangle vert horiz height width) a)
 -> LowerUpper vert horiz height width a)
-> (Vector (Min width (Shape height)) (Element height),
    Array (Split Triangle vert horiz height width) a)
-> LowerUpper vert horiz height width a
forall a b. (a -> b) -> a -> b
$
      Min width (Shape height)
-> (Int
    -> Ptr (Element height)
    -> IO (Array (Split Triangle vert horiz height width) a))
-> (Vector (Min width (Shape height)) (Element height),
    Array (Split Triangle vert horiz height width) a)
forall sh a b.
(C sh, Storable a) =>
sh -> (Int -> Ptr a -> IO b) -> (Array sh a, b)
Array.unsafeCreateWithSizeAndResult
         (width -> Shape height -> Min width (Shape height)
forall sh0 sh1. sh0 -> sh1 -> Min sh0 sh1
ExtShape.Min width
width (Shape height -> Min width (Shape height))
-> Shape height -> Min width (Shape height)
forall a b. (a -> b) -> a -> b
$ height -> Shape height
forall sh. sh -> Shape sh
Perm.Shape height
height) ((Int
  -> Ptr (Element height)
  -> IO (Array (Split Triangle vert horiz height width) a))
 -> (Vector (Min width (Shape height)) (Element height),
     Array (Split Triangle vert horiz height width) a))
-> (Int
    -> Ptr (Element height)
    -> IO (Array (Split Triangle vert horiz height width) a))
-> (Vector (Min width (Shape height)) (Element height),
    Array (Split Triangle vert horiz height width) a)
forall a b. (a -> b) -> a -> b
$ \Int
_ Ptr (Element height)
ipivPtr ->
      Split Triangle vert horiz height width
-> (Ptr a -> IO ())
-> IO (Array (Split Triangle vert horiz height width) a)
forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
sh -> (Ptr a -> IO ()) -> m (Array sh a)
ArrayIO.unsafeCreate
         (Triangle
-> Order
-> Extent vert horiz height width
-> Split Triangle vert horiz height width
forall lower vert horiz height width.
lower
-> Order
-> Extent vert horiz height width
-> Split lower vert horiz height width
MatrixShape.Split Triangle
MatrixShape.Triangle Order
ColumnMajor Extent vert horiz height width
extent) ((Ptr a -> IO ())
 -> IO (Array (Split Triangle vert horiz height width) a))
-> (Ptr a -> IO ())
-> IO (Array (Split Triangle vert horiz height width) a)
forall a b. (a -> b) -> a -> b
$ \Ptr a
luPtr ->

   ContT () IO () -> IO ()
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT () IO () -> IO ()) -> ContT () IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
      let m :: Int
m = height -> Int
forall sh. C sh => sh -> Int
Shape.size height
height
      let n :: Int
n = width -> Int
forall sh. C sh => sh -> Int
Shape.size width
width
      Ptr CInt
mPtr <- Int -> FortranIO () (Ptr CInt)
forall r. Int -> FortranIO r (Ptr CInt)
Call.cint Int
m
      Ptr CInt
nPtr <- Int -> FortranIO () (Ptr CInt)
forall r. Int -> FortranIO r (Ptr CInt)
Call.cint Int
n
      Ptr a
aPtr <- ((Ptr a -> IO ()) -> IO ()) -> ContT () IO (Ptr a)
forall k (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (((Ptr a -> IO ()) -> IO ()) -> ContT () IO (Ptr a))
-> ((Ptr a -> IO ()) -> IO ()) -> ContT () IO (Ptr a)
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
a
      Ptr CInt
ldaPtr <- Int -> FortranIO () (Ptr CInt)
forall r. Int -> FortranIO r (Ptr CInt)
Call.leadingDim Int
m
      IO () -> ContT () IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ContT () IO ()) -> IO () -> ContT () IO ()
forall a b. (a -> b) -> a -> b
$ do
         Order -> Int -> Int -> Ptr a -> Ptr a -> IO ()
forall a.
Floating a =>
Order -> Int -> Int -> Ptr a -> Ptr a -> IO ()
copyToColumnMajor Order
order Int
m Int
n Ptr a
aPtr Ptr a
luPtr
         String -> (Ptr CInt -> IO ()) -> IO ()
withInfo String
"getrf" ((Ptr CInt -> IO ()) -> IO ()) -> (Ptr CInt -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$
            Ptr CInt
-> Ptr CInt -> Ptr a -> Ptr CInt -> Ptr CInt -> Ptr CInt -> IO ()
forall a.
Floating a =>
Ptr CInt
-> Ptr CInt -> Ptr a -> Ptr CInt -> Ptr CInt -> Ptr CInt -> IO ()
LapackGen.getrf Ptr CInt
mPtr Ptr CInt
nPtr Ptr a
luPtr Ptr CInt
ldaPtr
               (Ptr (Element height) -> Ptr CInt
forall sh. Ptr (Element sh) -> Ptr CInt
Perm.deconsElementPtr Ptr (Element height)
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 :: Square height a
-> Full vert horiz height width a -> Full vert horiz height width a
solve = Transposition
-> Square height a
-> Full vert horiz height width a
-> Full vert horiz height width a
forall vert horiz height width a.
(C vert, C horiz, Eq height, C height, C width, Floating a) =>
Transposition
-> Square height a
-> Full vert horiz height width a
-> Full vert horiz height width a
solveTrans Transposition
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 :: Transposition
-> Square height a
-> Full vert horiz height width a
-> Full vert horiz height width a
solveTrans Transposition
trans
   (LowerUpper
      (Array _ ipiv)
      (Array (MatrixShape.Split MatrixShape.Triangle orderLU extentLU) lu)) =

   String
-> height
-> (Int
    -> Ptr CInt -> Ptr CInt -> Ptr a -> Ptr CInt -> ContT () IO ())
-> Full vert horiz height width a
-> Full vert horiz height width a
forall vert horiz height width a.
(C vert, C horiz, C height, C width, Eq height, Floating a) =>
String
-> height
-> (Int
    -> Ptr CInt -> Ptr CInt -> Ptr a -> Ptr CInt -> ContT () IO ())
-> Full vert horiz height width a
-> Full vert horiz height width a
solver String
"LowerUpper.solve" (Extent Small Small height height -> height
forall height width. Extent Small Small height width -> height
Extent.squareSize Extent Small Small height height
extentLU) ((Int
  -> Ptr CInt -> Ptr CInt -> Ptr a -> Ptr CInt -> ContT () IO ())
 -> Full vert horiz height width a
 -> Full vert horiz height width a)
-> (Int
    -> Ptr CInt -> Ptr CInt -> Ptr a -> Ptr CInt -> ContT () IO ())
-> Full vert horiz height width a
-> Full vert horiz height width a
forall a b. (a -> b) -> a -> b
$
         \Int
n Ptr CInt
nPtr Ptr CInt
nrhsPtr Ptr a
xPtr Ptr CInt
ldxPtr -> do
      let lda :: Int
lda = Int
n
      Ptr CChar
transPtr <- Char -> FortranIO () (Ptr CChar)
forall r. Char -> FortranIO r (Ptr CChar)
Call.char (Char -> FortranIO () (Ptr CChar))
-> Char -> FortranIO () (Ptr CChar)
forall a b. (a -> b) -> a -> b
$
         case Transposition
trans of
            Transposition
NonTransposed -> Char
'N'
            Transposition
Transposed -> Char
'T'
      Ptr a
aPtr <-
         case Order
orderLU of
            Order
RowMajor -> Order -> Int -> Int -> ForeignPtr a -> ContT () IO (Ptr a)
forall a r.
Floating a =>
Order -> Int -> Int -> ForeignPtr a -> ContT r IO (Ptr a)
copyToColumnMajorTemp Order
orderLU Int
n Int
n ForeignPtr a
lu
            Order
ColumnMajor -> ((Ptr a -> IO ()) -> IO ()) -> ContT () IO (Ptr a)
forall k (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (((Ptr a -> IO ()) -> IO ()) -> ContT () IO (Ptr a))
-> ((Ptr a -> IO ()) -> IO ()) -> ContT () IO (Ptr a)
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
lu
      Ptr CInt
ldaPtr <- Int -> FortranIO () (Ptr CInt)
forall r. Int -> FortranIO r (Ptr CInt)
Call.leadingDim Int
lda
      Ptr CInt
ipivPtr <- (Ptr (Element height) -> Ptr CInt)
-> ContT () IO (Ptr (Element height)) -> FortranIO () (Ptr CInt)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Ptr (Element height) -> Ptr CInt
forall sh. Ptr (Element sh) -> Ptr CInt
Perm.deconsElementPtr (ContT () IO (Ptr (Element height)) -> FortranIO () (Ptr CInt))
-> ContT () IO (Ptr (Element height)) -> FortranIO () (Ptr CInt)
forall a b. (a -> b) -> a -> b
$ ((Ptr (Element height) -> IO ()) -> IO ())
-> ContT () IO (Ptr (Element height))
forall k (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (((Ptr (Element height) -> IO ()) -> IO ())
 -> ContT () IO (Ptr (Element height)))
-> ((Ptr (Element height) -> IO ()) -> IO ())
-> ContT () IO (Ptr (Element height))
forall a b. (a -> b) -> a -> b
$ ForeignPtr (Element height)
-> (Ptr (Element height) -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr (Element height)
ipiv
      IO () -> ContT () IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ContT () IO ()) -> IO () -> ContT () IO ()
forall a b. (a -> b) -> a -> b
$
         String -> (Ptr CInt -> IO ()) -> IO ()
withInfo String
"getrs" ((Ptr CInt -> IO ()) -> IO ()) -> (Ptr CInt -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$
            Ptr CChar
-> Ptr CInt
-> Ptr CInt
-> Ptr a
-> Ptr CInt
-> Ptr CInt
-> Ptr a
-> Ptr CInt
-> Ptr CInt
-> IO ()
forall a.
Floating a =>
Ptr CChar
-> Ptr CInt
-> Ptr CInt
-> Ptr a
-> Ptr CInt
-> Ptr CInt
-> Ptr a
-> Ptr CInt
-> Ptr CInt
-> IO ()
LapackGen.getrs Ptr CChar
transPtr
               Ptr CInt
nPtr Ptr CInt
nrhsPtr Ptr a
aPtr Ptr CInt
ldaPtr Ptr CInt
ipivPtr Ptr a
xPtr Ptr CInt
ldxPtr

{- |
Caution:
@LU.determinant . LU.fromMatrix@ will fail for singular matrices.
-}
determinant :: (Shape.C sh, Class.Floating a) => Square sh a -> a
determinant :: Square sh a -> a
determinant (LowerUpper ipiv split) =
   [CInt] -> a -> a
forall a. Floating a => [CInt] -> a -> a
Perm.condNegate ((Element sh -> CInt) -> [Element sh] -> [CInt]
forall a b. (a -> b) -> [a] -> [b]
map Element sh -> CInt
forall sh. Element sh -> CInt
Perm.deconsElement ([Element sh] -> [CInt]) -> [Element sh] -> [CInt]
forall a b. (a -> b) -> a -> b
$ Array (Min sh (Shape sh)) (Element sh) -> [Element sh]
forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array (Min sh (Shape sh)) (Element sh)
ipiv) (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$
   Split Triangle Small Small sh sh a -> a
forall vert height width a lower.
(C vert, C height, C width, Floating a) =>
Split lower vert Small height width a -> a
Split.determinantR Split Triangle Small Small sh sh a
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 :: Inversion
-> LowerUpper vert horiz height width a -> Permutation height
extractP Inversion
inverted (LowerUpper ipiv _) =
   Inversion
-> Vector (Min width (Shape height)) (Element height)
-> Permutation height
forall sh sh1.
(C sh, C sh1) =>
Inversion
-> Vector (Min sh1 (Shape sh)) (Element sh) -> Permutation sh
Perm.fromTruncatedPivots (Inversion
Inverted Inversion -> Inversion -> Inversion
forall a. Semigroup a => a -> a -> a
<> Inversion
inverted) Vector (Min width (Shape height)) (Element height)
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 :: Inversion
-> LowerUpper vertA horizA height widthA a
-> Full vertB horizB height widthB a
-> Full vertB horizB height widthB a
multiplyP Inversion
inverted
      (LowerUpper ipiv@(Array shapeIPiv ipivFPtr)
         (Array (MatrixShape.Split _ _ extentLU) _lu))
      (Array shape :: Full vertB horizB height widthB
shape@(MatrixShape.Full Order
order Extent vertB horizB height widthB
extent) ForeignPtr a
a) =
   Full vertB horizB height widthB
-> (Ptr a -> IO ()) -> Full vertB horizB height widthB a
forall sh a.
(C sh, Storable a) =>
sh -> (Ptr a -> IO ()) -> Array sh a
Array.unsafeCreate Full vertB horizB height widthB
shape ((Ptr a -> IO ()) -> Full vertB horizB height widthB a)
-> (Ptr a -> IO ()) -> Full vertB horizB height widthB a
forall a b. (a -> b) -> a -> b
$ \Ptr a
bPtr -> do

   String -> Bool -> IO ()
Call.assert String
"multiplyP: heights mismatch"
      (Extent vertA horizA height widthA -> height
forall vert horiz height width.
(C vert, C horiz) =>
Extent vert horiz height width -> height
Extent.height Extent vertA horizA height widthA
extentLU height -> height -> Bool
forall a. Eq a => a -> a -> Bool
== Extent vertB horizB height widthB -> height
forall vert horiz height width.
(C vert, C horiz) =>
Extent vert horiz height width -> height
Extent.height Extent vertB horizB height widthB
extent)

   let (height
height,widthB
width) = Extent vertB horizB height widthB -> (height, widthB)
forall vert horiz height width.
(C vert, C horiz) =>
Extent vert horiz height width -> (height, width)
Extent.dimensions Extent vertB horizB height widthB
extent
   let m :: Int
m = height -> Int
forall sh. C sh => sh -> Int
Shape.size height
height
   let n :: Int
n = widthB -> Int
forall sh. C sh => sh -> Int
Shape.size widthB
width
   let k :: Int
k = Min widthA (Shape height) -> Int
forall sh. C sh => sh -> Int
Shape.size Min widthA (Shape height)
shapeIPiv

   ContT () IO () -> IO ()
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT () IO () -> IO ()) -> ContT () IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
      Ptr a
aPtr <- ((Ptr a -> IO ()) -> IO ()) -> ContT () IO (Ptr a)
forall k (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (((Ptr a -> IO ()) -> IO ()) -> ContT () IO (Ptr a))
-> ((Ptr a -> IO ()) -> IO ()) -> ContT () IO (Ptr a)
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
a
      Ptr (Element height)
ipivPtr <- ((Ptr (Element height) -> IO ()) -> IO ())
-> ContT () IO (Ptr (Element height))
forall k (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (((Ptr (Element height) -> IO ()) -> IO ())
 -> ContT () IO (Ptr (Element height)))
-> ((Ptr (Element height) -> IO ()) -> IO ())
-> ContT () IO (Ptr (Element height))
forall a b. (a -> b) -> a -> b
$ ForeignPtr (Element height)
-> (Ptr (Element height) -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr (Element height)
ipivFPtr
      IO () -> ContT () IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ContT () IO ()) -> IO () -> ContT () IO ()
forall a b. (a -> b) -> a -> b
$ Int -> Ptr a -> Ptr a -> IO ()
forall a. Floating a => Int -> Ptr a -> Ptr a -> IO ()
copyBlock (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
m) Ptr a
aPtr Ptr a
bPtr
      case Order
order of
         Order
ColumnMajor -> do
            Ptr CInt
nPtr <- Int -> FortranIO () (Ptr CInt)
forall r. Int -> FortranIO r (Ptr CInt)
Call.cint Int
n
            Ptr CInt
ldaPtr <- Int -> FortranIO () (Ptr CInt)
forall r. Int -> FortranIO r (Ptr CInt)
Call.leadingDim Int
m
            Ptr CInt
k1Ptr <- Int -> FortranIO () (Ptr CInt)
forall r. Int -> FortranIO r (Ptr CInt)
Call.cint Int
1
            Ptr CInt
k2Ptr <- Int -> FortranIO () (Ptr CInt)
forall r. Int -> FortranIO r (Ptr CInt)
Call.cint Int
k
            Ptr CInt
incxPtr <-
               Int -> FortranIO () (Ptr CInt)
forall r. Int -> FortranIO r (Ptr CInt)
Call.cint (Int -> FortranIO () (Ptr CInt)) -> Int -> FortranIO () (Ptr CInt)
forall a b. (a -> b) -> a -> b
$
               case Inversion
inverted of
                  Inversion
Inverted -> Int
1
                  Inversion
NonInverted -> -Int
1
            IO () -> ContT () IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ContT () IO ()) -> IO () -> ContT () IO ()
forall a b. (a -> b) -> a -> b
$
               Ptr CInt
-> Ptr a
-> Ptr CInt
-> Ptr CInt
-> Ptr CInt
-> Ptr CInt
-> Ptr CInt
-> IO ()
forall a.
Floating a =>
Ptr CInt
-> Ptr a
-> Ptr CInt
-> Ptr CInt
-> Ptr CInt
-> Ptr CInt
-> Ptr CInt
-> IO ()
LapackGen.laswp Ptr CInt
nPtr Ptr a
bPtr Ptr CInt
ldaPtr Ptr CInt
k1Ptr Ptr CInt
k2Ptr
                  (Ptr (Element height) -> Ptr CInt
forall sh. Ptr (Element sh) -> Ptr CInt
Perm.deconsElementPtr Ptr (Element height)
ipivPtr) Ptr CInt
incxPtr
         Order
RowMajor ->
            IO () -> ContT () IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ContT () IO ()) -> IO () -> ContT () IO ()
forall a b. (a -> b) -> a -> b
$ height
-> Int
-> Ptr a
-> Array (Min widthA (Shape height)) (Element height)
-> [Element height]
-> IO ()
forall sh width a.
(C sh, C width, Floating a) =>
sh
-> Int
-> Ptr a
-> Array (Min width (Shape sh)) (Element sh)
-> [Element sh]
-> IO ()
swapColumns height
height Int
n Ptr a
bPtr Array (Min widthA (Shape height)) (Element height)
ipiv ([Element height] -> IO ()) -> [Element height] -> IO ()
forall a b. (a -> b) -> a -> b
$
            Inversion -> Min widthA (Shape height) -> [Element height]
forall sh small.
(C sh, Indexed small, Index small ~ Element sh) =>
Inversion -> small -> [Element sh]
Perm.indices (Inversion
Inverted Inversion -> Inversion -> Inversion
forall a. Semigroup a => a -> a -> a
<> Inversion
inverted) Min widthA (Shape height)
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
-> Int
-> Ptr a
-> Array (Min width (Shape sh)) (Element sh)
-> [Element sh]
-> IO ()
swapColumns sh
sh Int
n Ptr a
xPtr Array (Min width (Shape sh)) (Element sh)
ipiv [Element sh]
is = ContT () IO () -> IO ()
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT () IO () -> IO ()) -> ContT () IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
   Ptr CInt
nPtr <- Int -> FortranIO () (Ptr CInt)
forall r. Int -> FortranIO r (Ptr CInt)
Call.cint Int
n
   Ptr CInt
incPtr <- Int -> FortranIO () (Ptr CInt)
forall r. Int -> FortranIO r (Ptr CInt)
Call.cint Int
1
   let columnPtr :: Element sh -> Ptr a
columnPtr Element sh
ix =
         Ptr a -> Int -> Ptr a
forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Ptr a
xPtr (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
* Shape sh -> Index (Shape sh) -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.uncheckedOffset (sh -> Shape sh
forall sh. sh -> Shape sh
Perm.Shape sh
sh) Index (Shape sh)
Element sh
ix)
   IO () -> ContT () IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ContT () IO ()) -> IO () -> ContT () IO ()
forall a b. (a -> b) -> a -> b
$ [Element sh] -> (Element sh -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Element sh]
is ((Element sh -> IO ()) -> IO ()) -> (Element sh -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Element sh
i ->
      Ptr CInt -> Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt -> IO ()
forall a.
Floating a =>
Ptr CInt -> Ptr a -> Ptr CInt -> Ptr a -> Ptr CInt -> IO ()
BlasGen.swap Ptr CInt
nPtr (Element sh -> Ptr a
columnPtr Element sh
i) Ptr CInt
incPtr (Element sh -> Ptr a
columnPtr (Array (Min width (Shape sh)) (Element sh)
ipivArray (Min width (Shape sh)) (Element sh)
-> Index (Min width (Shape sh)) -> Element sh
forall sh a.
(Indexed sh, Storable a) =>
Array sh a -> Index sh -> a
!Index (Min width (Shape sh))
Element sh
i)) Ptr CInt
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 :: LowerUpper vert horiz height width a
-> Full vert horiz height width a
extractL = Either Triangle Triangle
-> Split Triangle vert horiz height width a
-> Full vert horiz height width a
forall vert horiz height width a lower.
(C vert, C horiz, C height, C width, Floating a) =>
Either lower Triangle
-> Split lower vert horiz height width a
-> Full vert horiz height width a
Split.extractTriangle (Triangle -> Either Triangle Triangle
forall a b. a -> Either a b
Left Triangle
Triangle) (Split Triangle vert horiz height width a
 -> Full vert horiz height width a)
-> (LowerUpper vert horiz height width a
    -> Split Triangle vert horiz height width a)
-> LowerUpper vert horiz height width a
-> Full vert horiz height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LowerUpper vert horiz height width a
-> Split Triangle vert horiz height width a
forall vert horiz height width a.
Matrix (LU vert horiz height width) a
-> Array (Split Triangle vert horiz height width) a
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 :: LowerUpper Small horiz height width a -> UnitLower height a
wideExtractL = Split Triangle Small horiz height width a -> UnitLower height a
forall horiz height width a lower.
(C horiz, C height, C width, Floating a) =>
Split lower Small horiz height width a -> UnitLower height a
Split.wideExtractL (Split Triangle Small horiz height width a -> UnitLower height a)
-> (LowerUpper Small horiz height width a
    -> Split Triangle Small horiz height width a)
-> LowerUpper Small horiz height width a
-> UnitLower height a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LowerUpper Small horiz height width a
-> Split Triangle Small horiz height width a
forall vert horiz height width a.
Matrix (LU vert horiz height width) a
-> Array (Split Triangle vert horiz height width) a
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 :: Transposition
-> LowerUpper Small horizA height widthA a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
wideMultiplyL Transposition
transposed = Transposition
-> Split Triangle Small horizA height widthA a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
forall horizA vert horiz height widthA widthB a.
(C horizA, C vert, C horiz, C height, Eq height, C widthA,
 C widthB, Floating a) =>
Transposition
-> Split Triangle Small horizA height widthA a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
Split.wideMultiplyL Transposition
transposed (Split Triangle Small horizA height widthA a
 -> Full vert horiz height widthB a
 -> Full vert horiz height widthB a)
-> (LowerUpper Small horizA height widthA a
    -> Split Triangle Small horizA height widthA a)
-> LowerUpper Small horizA height widthA a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LowerUpper Small horizA height widthA a
-> Split Triangle Small horizA height widthA a
forall vert horiz height width a.
Matrix (LU vert horiz height width) a
-> Array (Split Triangle vert horiz height width) a
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 :: Transposition
-> Conjugation
-> LowerUpper Small horizA height width a
-> Full vert horiz height nrhs a
-> Full vert horiz height nrhs a
wideSolveL Transposition
transposed Conjugation
conjugated =
   Transposition
-> Conjugation
-> Split Triangle Small horizA height width a
-> Full vert horiz height nrhs a
-> Full vert horiz height nrhs a
forall horizA vert horiz height width nrhs a.
(C horizA, C vert, C horiz, C height, Eq height, C width, C nrhs,
 Floating a) =>
Transposition
-> Conjugation
-> Split Triangle Small horizA height width a
-> Full vert horiz height nrhs a
-> Full vert horiz height nrhs a
Split.wideSolveL Transposition
transposed Conjugation
conjugated (Split Triangle Small horizA height width a
 -> Full vert horiz height nrhs a -> Full vert horiz height nrhs a)
-> (LowerUpper Small horizA height width a
    -> Split Triangle Small horizA height width a)
-> LowerUpper Small horizA height width a
-> Full vert horiz height nrhs a
-> Full vert horiz height nrhs a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LowerUpper Small horizA height width a
-> Split Triangle Small horizA height width a
forall vert horiz height width a.
Matrix (LU vert horiz height width) a
-> Array (Split Triangle vert horiz height width) a
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 :: LowerUpper vert horiz height width a
-> Full vert horiz height width a
extractU = Either Triangle Triangle
-> Split Triangle vert horiz height width a
-> Full vert horiz height width a
forall vert horiz height width a lower.
(C vert, C horiz, C height, C width, Floating a) =>
Either lower Triangle
-> Split lower vert horiz height width a
-> Full vert horiz height width a
Split.extractTriangle (Triangle -> Either Triangle Triangle
forall a b. b -> Either a b
Right Triangle
Triangle) (Split Triangle vert horiz height width a
 -> Full vert horiz height width a)
-> (LowerUpper vert horiz height width a
    -> Split Triangle vert horiz height width a)
-> LowerUpper vert horiz height width a
-> Full vert horiz height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LowerUpper vert horiz height width a
-> Split Triangle vert horiz height width a
forall vert horiz height width a.
Matrix (LU vert horiz height width) a
-> Array (Split Triangle vert horiz height width) a
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 :: LowerUpper vert Small height width a -> Upper width a
tallExtractU = Split Triangle vert Small height width a -> Upper width a
forall vert height width a lower.
(C vert, C height, C width, Floating a) =>
Split lower vert Small height width a -> Upper width a
Split.tallExtractR (Split Triangle vert Small height width a -> Upper width a)
-> (LowerUpper vert Small height width a
    -> Split Triangle vert Small height width a)
-> LowerUpper vert Small height width a
-> Upper width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LowerUpper vert Small height width a
-> Split Triangle vert Small height width a
forall vert horiz height width a.
Matrix (LU vert horiz height width) a
-> Array (Split Triangle vert horiz height width) a
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 :: Transposition
-> LowerUpper vertA Small heightA height a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
tallMultiplyU Transposition
transposed = Transposition
-> Split Triangle vertA Small heightA height a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
forall vertA vert horiz height heightA widthB a lower.
(C vertA, C vert, C horiz, C height, Eq height, C heightA,
 C widthB, Floating a) =>
Transposition
-> Split lower vertA Small heightA height a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
Split.tallMultiplyR Transposition
transposed (Split Triangle vertA Small heightA height a
 -> Full vert horiz height widthB a
 -> Full vert horiz height widthB a)
-> (LowerUpper vertA Small heightA height a
    -> Split Triangle vertA Small heightA height a)
-> LowerUpper vertA Small heightA height a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LowerUpper vertA Small heightA height a
-> Split Triangle vertA Small heightA height a
forall vert horiz height width a.
Matrix (LU vert horiz height width) a
-> Array (Split Triangle vert horiz height width) a
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 :: Transposition
-> Conjugation
-> LowerUpper vertA Small height width a
-> Full vert horiz width nrhs a
-> Full vert horiz width nrhs a
tallSolveU Transposition
transposed Conjugation
conjugated =
   Transposition
-> Conjugation
-> Split Triangle vertA Small height width a
-> Full vert horiz width nrhs a
-> Full vert horiz width nrhs a
forall vertA vert horiz height width nrhs a lower.
(C vertA, C vert, C horiz, C height, C width, Eq width, C nrhs,
 Floating a) =>
Transposition
-> Conjugation
-> Split lower vertA Small height width a
-> Full vert horiz width nrhs a
-> Full vert horiz width nrhs a
Split.tallSolveR Transposition
transposed Conjugation
conjugated (Split Triangle vertA Small height width a
 -> Full vert horiz width nrhs a -> Full vert horiz width nrhs a)
-> (LowerUpper vertA Small height width a
    -> Split Triangle vertA Small height width a)
-> LowerUpper vertA Small height width a
-> Full vert horiz width nrhs a
-> Full vert horiz width nrhs a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LowerUpper vertA Small height width a
-> Split Triangle vertA Small height width a
forall vert horiz height width a.
Matrix (LU vert horiz height width) a
-> Array (Split Triangle vert horiz height width) a
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 :: LowerUpper vert horiz height width a
-> Full vert horiz height width a
toMatrix =
   ToMatrix height width a vert horiz
-> LowerUpper vert horiz height width a
-> Full vert horiz height width a
forall height width a vert horiz.
ToMatrix height width a vert horiz
-> LowerUpper vert horiz height width a
-> Full vert horiz height width a
getToMatrix (ToMatrix height width a vert horiz
 -> LowerUpper vert horiz height width a
 -> Full vert horiz height width a)
-> ToMatrix height width a vert horiz
-> LowerUpper vert horiz height width a
-> Full vert horiz height width a
forall a b. (a -> b) -> a -> b
$
   ToMatrix height width a Small Small
-> ToMatrix height width a Small Big
-> ToMatrix height width a Big Small
-> ToMatrix height width a Big Big
-> ToMatrix height width a vert horiz
forall vert horiz (f :: * -> * -> *).
(C vert, C horiz) =>
f Small Small
-> f Small Big -> f Big Small -> f Big Big -> f vert horiz
Extent.switchTagPair
      ((LowerUpper Small Small height width a
 -> Full Small Small height width a)
-> ToMatrix height width a Small Small
forall height width a vert horiz.
(LowerUpper vert horiz height width a
 -> Full vert horiz height width a)
-> ToMatrix height width a vert horiz
ToMatrix LowerUpper Small Small height width a
-> Full Small Small height width a
forall horiz height width a.
(C horiz, C height, C width, Eq height, Eq width, Floating a) =>
LowerUpper Small horiz height width a
-> Full Small horiz height width a
wideToMatrix)
      ((LowerUpper Small Big height width a
 -> Full Small Big height width a)
-> ToMatrix height width a Small Big
forall height width a vert horiz.
(LowerUpper vert horiz height width a
 -> Full vert horiz height width a)
-> ToMatrix height width a vert horiz
ToMatrix LowerUpper Small Big height width a
-> Full Small Big height width a
forall horiz height width a.
(C horiz, C height, C width, Eq height, Eq width, Floating a) =>
LowerUpper Small horiz height width a
-> Full Small horiz height width a
wideToMatrix)
      ((LowerUpper Big Small height width a
 -> Full Big Small height width a)
-> ToMatrix height width a Big Small
forall height width a vert horiz.
(LowerUpper vert horiz height width a
 -> Full vert horiz height width a)
-> ToMatrix height width a vert horiz
ToMatrix LowerUpper Big Small height width a
-> Full Big Small height width a
forall vert height width a.
(C vert, C height, C width, Eq height, Eq width, Floating a) =>
LowerUpper vert Small height width a
-> Full vert Small height width a
tallToMatrix)
      ((LowerUpper Big Big height width a -> Full Big Big height width a)
-> ToMatrix height width a Big Big
forall height width a vert horiz.
(LowerUpper vert horiz height width a
 -> Full vert horiz height width a)
-> ToMatrix height width a vert horiz
ToMatrix ((LowerUpper Big Big height width a -> Full Big Big height width a)
 -> ToMatrix height width a Big Big)
-> (LowerUpper Big Big height width a
    -> Full Big Big height width a)
-> ToMatrix height width a Big Big
forall a b. (a -> b) -> a -> b
$
         (LowerUpper Big Small height width a
 -> Full Big Big height width a)
-> (LowerUpper Small Big height width a
    -> Full Big Big height width a)
-> Either
     (LowerUpper Big Small height width a)
     (LowerUpper Small Big height width a)
-> Full Big Big height width a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
            (Full Big Small height width a -> Full Big Big height width a
forall vert horiz height width a.
(C vert, C horiz) =>
Full vert horiz height width a -> General height width a
Matrix.fromFull (Full Big Small height width a -> Full Big Big height width a)
-> (LowerUpper Big Small height width a
    -> Full Big Small height width a)
-> LowerUpper Big Small height width a
-> Full Big Big height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LowerUpper Big Small height width a
-> Full Big Small height width a
forall vert height width a.
(C vert, C height, C width, Eq height, Eq width, Floating a) =>
LowerUpper vert Small height width a
-> Full vert Small height width a
tallToMatrix)
            (Full Small Big height width a -> Full Big Big height width a
forall vert horiz height width a.
(C vert, C horiz) =>
Full vert horiz height width a -> General height width a
Matrix.fromFull (Full Small Big height width a -> Full Big Big height width a)
-> (LowerUpper Small Big height width a
    -> Full Small Big height width a)
-> LowerUpper Small Big height width a
-> Full Big Big height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LowerUpper Small Big height width a
-> Full Small Big height width a
forall horiz height width a.
(C horiz, C height, C width, Eq height, Eq width, Floating a) =>
LowerUpper Small horiz height width a
-> Full Small horiz height width a
wideToMatrix) (Either
   (LowerUpper Big Small height width a)
   (LowerUpper Small Big height width a)
 -> Full Big Big height width a)
-> (LowerUpper Big Big height width a
    -> Either
         (LowerUpper Big Small height width a)
         (LowerUpper Small Big height width a))
-> LowerUpper Big Big height width a
-> Full Big Big height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
         LowerUpper Big Big height width a
-> Either
     (LowerUpper Big Small height width a)
     (LowerUpper Small Big height width a)
forall vert horiz height width a.
(C vert, C horiz, C height, C width) =>
LowerUpper vert horiz height width a
-> Either (Tall height width a) (Wide height width a)
caseTallWide)

newtype ToMatrix height width a vert horiz =
   ToMatrix {
      ToMatrix height width a vert horiz
-> LowerUpper vert horiz height width a
-> Full vert horiz height width a
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 :: LowerUpper vert Small height width a
-> Full vert Small height width a
tallToMatrix LowerUpper vert Small height width a
a =
   Inversion
-> LowerUpper vert Small height width a
-> Full vert Small height width a
-> Full vert Small height width a
forall vertA horizA vertB horizB height widthA widthB a.
(C vertA, C horizA, C vertB, C horizB, Eq height, C height,
 C widthA, C widthB, Floating a) =>
Inversion
-> LowerUpper vertA horizA height widthA a
-> Full vertB horizB height widthB a
-> Full vertB horizB height widthB a
multiplyP Inversion
NonInverted LowerUpper vert Small height width a
a (Full vert Small height width a -> Full vert Small height width a)
-> Full vert Small height width a -> Full vert Small height width a
forall a b. (a -> b) -> a -> b
$ Full Small vert width height a -> Full vert Small height width a
forall vert horiz height width a.
(C vert, C horiz) =>
Full vert horiz height width a -> Full horiz vert width height a
Basic.transpose (Full Small vert width height a -> Full vert Small height width a)
-> Full Small vert width height a -> Full vert Small height width a
forall a b. (a -> b) -> a -> b
$
   Transposition
-> LowerUpper vert Small height width a
-> Full Small vert width height a
-> Full Small vert width height a
forall vertA vert horiz height heightA widthB a.
(C vertA, C vert, C horiz, C height, Eq height, C heightA,
 C widthB, Floating a) =>
Transposition
-> LowerUpper vertA Small heightA height a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
tallMultiplyU Transposition
Transposed LowerUpper vert Small height width a
a (Full Small vert width height a -> Full Small vert width height a)
-> Full Small vert width height a -> Full Small vert width height a
forall a b. (a -> b) -> a -> b
$ Full vert Small height width a -> Full Small vert width height a
forall vert horiz height width a.
(C vert, C horiz) =>
Full vert horiz height width a -> Full horiz vert width height a
Basic.transpose (Full vert Small height width a -> Full Small vert width height a)
-> Full vert Small height width a -> Full Small vert width height a
forall a b. (a -> b) -> a -> b
$ LowerUpper vert Small height width a
-> Full vert Small height width a
forall vert horiz height width a.
(C vert, C horiz, C height, C width, Floating a) =>
LowerUpper vert horiz height width a
-> Full vert horiz height width a
extractL LowerUpper vert Small height width a
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 :: LowerUpper Small horiz height width a
-> Full Small horiz height width a
wideToMatrix LowerUpper Small horiz height width a
a =
   Inversion
-> LowerUpper Small horiz height width a
-> Full Small horiz height width a
-> Full Small horiz height width a
forall vertA horizA vertB horizB height widthA widthB a.
(C vertA, C horizA, C vertB, C horizB, Eq height, C height,
 C widthA, C widthB, Floating a) =>
Inversion
-> LowerUpper vertA horizA height widthA a
-> Full vertB horizB height widthB a
-> Full vertB horizB height widthB a
multiplyP Inversion
NonInverted LowerUpper Small horiz height width a
a (Full Small horiz height width a
 -> Full Small horiz height width a)
-> Full Small horiz height width a
-> Full Small horiz height width a
forall a b. (a -> b) -> a -> b
$ Transposition
-> LowerUpper Small horiz height width a
-> Full Small horiz height width a
-> Full Small horiz height width a
forall horizA vert horiz height widthA widthB a.
(C horizA, C vert, C horiz, C height, Eq height, C widthA,
 C widthB, Floating a) =>
Transposition
-> LowerUpper Small horizA height widthA a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
wideMultiplyL Transposition
NonTransposed LowerUpper Small horiz height width a
a (Full Small horiz height width a
 -> Full Small horiz height width a)
-> Full Small horiz height width a
-> Full Small horiz height width a
forall a b. (a -> b) -> a -> b
$ LowerUpper Small horiz height width a
-> Full Small horiz height width a
forall vert horiz height width a.
(C vert, C horiz, C height, C width, Floating a) =>
LowerUpper vert horiz height width a
-> Full vert horiz height width a
extractU LowerUpper Small horiz height width a
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 :: LowerUpper vert horiz height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
multiplyFull =
   MultiplyFullRight height fuse width a vert horiz
-> LowerUpper vert horiz height fuse a
-> Full vert horiz fuse width a
-> Full vert horiz height width a
forall height fuse width a vert horiz.
MultiplyFullRight height fuse width a vert horiz
-> LowerUpper vert horiz height fuse a
-> Full vert horiz fuse width a
-> Full vert horiz height width a
getMultiplyFullRight (MultiplyFullRight height fuse width a vert horiz
 -> LowerUpper vert horiz height fuse a
 -> Full vert horiz fuse width a
 -> Full vert horiz height width a)
-> MultiplyFullRight height fuse width a vert horiz
-> LowerUpper vert horiz height fuse a
-> Full vert horiz fuse width a
-> Full vert horiz height width a
forall a b. (a -> b) -> a -> b
$
   MultiplyFullRight height fuse width a Small Small
-> MultiplyFullRight height fuse width a Small Big
-> MultiplyFullRight height fuse width a Big Small
-> MultiplyFullRight height fuse width a Big Big
-> MultiplyFullRight height fuse width a vert horiz
forall vert horiz (f :: * -> * -> *).
(C vert, C horiz) =>
f Small Small
-> f Small Big -> f Big Small -> f Big Big -> f vert horiz
Extent.switchTagPair
      {-
      We cannot simply use squareFull here,
      because this requires height~width.
      -}
      ((LowerUpper Small Small height fuse a
 -> Full Small Small fuse width a
 -> Full Small Small height width a)
-> MultiplyFullRight height fuse width a Small Small
forall height fuse width a vert horiz.
(LowerUpper vert horiz height fuse a
 -> Full vert horiz fuse width a -> Full vert horiz height width a)
-> MultiplyFullRight height fuse width a vert horiz
MultiplyFullRight LowerUpper Small Small height fuse a
-> Full Small Small fuse width a -> Full Small Small height width a
forall vert horiz height width fuse a.
(C vert, C horiz, C height, C width, C fuse, Eq height, Eq fuse,
 Floating a) =>
LowerUpper Small horiz height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
wideMultiplyFullRight)
      ((LowerUpper Small Big height fuse a
 -> Full Small Big fuse width a -> Full Small Big height width a)
-> MultiplyFullRight height fuse width a Small Big
forall height fuse width a vert horiz.
(LowerUpper vert horiz height fuse a
 -> Full vert horiz fuse width a -> Full vert horiz height width a)
-> MultiplyFullRight height fuse width a vert horiz
MultiplyFullRight LowerUpper Small Big height fuse a
-> Full Small Big fuse width a -> Full Small Big height width a
forall vert horiz height width fuse a.
(C vert, C horiz, C height, C width, C fuse, Eq height, Eq fuse,
 Floating a) =>
LowerUpper Small horiz height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
wideMultiplyFullRight)
      ((LowerUpper Big Small height fuse a
 -> Full Big Small fuse width a -> Full Big Small height width a)
-> MultiplyFullRight height fuse width a Big Small
forall height fuse width a vert horiz.
(LowerUpper vert horiz height fuse a
 -> Full vert horiz fuse width a -> Full vert horiz height width a)
-> MultiplyFullRight height fuse width a vert horiz
MultiplyFullRight LowerUpper Big Small height fuse a
-> Full Big Small fuse width a -> Full Big Small height width a
forall vert horiz height width fuse a.
(C vert, C horiz, C height, C width, C fuse, Eq height, Eq fuse,
 Floating a) =>
LowerUpper vert Small height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
tallMultiplyFullRight)
      ((LowerUpper Big Big height fuse a
 -> Full Big Big fuse width a -> Full Big Big height width a)
-> MultiplyFullRight height fuse width a Big Big
forall height fuse width a vert horiz.
(LowerUpper vert horiz height fuse a
 -> Full vert horiz fuse width a -> Full vert horiz height width a)
-> MultiplyFullRight height fuse width a vert horiz
MultiplyFullRight ((LowerUpper Big Big height fuse a
  -> Full Big Big fuse width a -> Full Big Big height width a)
 -> MultiplyFullRight height fuse width a Big Big)
-> (LowerUpper Big Big height fuse a
    -> Full Big Big fuse width a -> Full Big Big height width a)
-> MultiplyFullRight height fuse width a Big Big
forall a b. (a -> b) -> a -> b
$
         (LowerUpper Big Small height fuse a
 -> Full Big Big fuse width a -> Full Big Big height width a)
-> (LowerUpper Small Big height fuse a
    -> Full Big Big fuse width a -> Full Big Big height width a)
-> Either
     (LowerUpper Big Small height fuse a)
     (LowerUpper Small Big height fuse a)
-> Full Big Big fuse width a
-> Full Big Big height width a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either LowerUpper Big Small height fuse a
-> Full Big Big fuse width a -> Full Big Big height width a
forall vert horiz height width fuse a.
(C vert, C horiz, C height, C width, C fuse, Eq height, Eq fuse,
 Floating a) =>
LowerUpper vert Small height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
tallMultiplyFullRight LowerUpper Small Big height fuse a
-> Full Big Big fuse width a -> Full Big Big height width a
forall vert horiz height width fuse a.
(C vert, C horiz, C height, C width, C fuse, Eq height, Eq fuse,
 Floating a) =>
LowerUpper Small horiz height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
wideMultiplyFullRight (Either
   (LowerUpper Big Small height fuse a)
   (LowerUpper Small Big height fuse a)
 -> Full Big Big fuse width a -> Full Big Big height width a)
-> (LowerUpper Big Big height fuse a
    -> Either
         (LowerUpper Big Small height fuse a)
         (LowerUpper Small Big height fuse a))
-> LowerUpper Big Big height fuse a
-> Full Big Big fuse width a
-> Full Big Big height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LowerUpper Big Big height fuse a
-> Either
     (LowerUpper Big Small height fuse a)
     (LowerUpper Small Big height fuse a)
forall vert horiz height width a.
(C vert, C horiz, C height, C width) =>
LowerUpper vert horiz height width a
-> Either (Tall height width a) (Wide height width a)
caseTallWide)

newtype MultiplyFullRight height fuse width a vert horiz =
   MultiplyFullRight {
      MultiplyFullRight height fuse width a vert horiz
-> LowerUpper vert horiz height fuse a
-> Full vert horiz fuse width a
-> Full vert horiz height width a
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 :: LowerUpper vert Small height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
tallMultiplyFullRight LowerUpper vert Small height fuse a
a =
   Inversion
-> LowerUpper vert Small height fuse a
-> Full vert horiz height width a
-> Full vert horiz height width a
forall vertA horizA vertB horizB height widthA widthB a.
(C vertA, C horizA, C vertB, C horizB, Eq height, C height,
 C widthA, C widthB, Floating a) =>
Inversion
-> LowerUpper vertA horizA height widthA a
-> Full vertB horizB height widthB a
-> Full vertB horizB height widthB a
multiplyP Inversion
NonInverted LowerUpper vert Small height fuse a
a (Full vert horiz height width a -> Full vert horiz height width a)
-> (Full vert horiz fuse width a -> Full vert horiz height width a)
-> Full vert horiz fuse width a
-> Full vert horiz height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   Full vert horiz height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
forall vert horiz height fuse width a.
(C vert, C horiz, C height, C fuse, Eq fuse, C width,
 Floating a) =>
Full vert horiz height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
Basic.multiply (Full vert Small height fuse a -> Full vert horiz height fuse a
forall vert horiz height width a.
(C vert, C horiz) =>
Full vert Small height width a -> Full vert horiz height width a
Matrix.generalizeTall (LowerUpper vert Small height fuse a
-> Full vert Small height fuse a
forall vert horiz height width a.
(C vert, C horiz, C height, C width, Floating a) =>
LowerUpper vert horiz height width a
-> Full vert horiz height width a
extractL LowerUpper vert Small height fuse a
a)) (Full vert horiz fuse width a -> Full vert horiz height width a)
-> (Full vert horiz fuse width a -> Full vert horiz fuse width a)
-> Full vert horiz fuse width a
-> Full vert horiz height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   Transposition
-> LowerUpper vert Small height fuse a
-> Full vert horiz fuse width a
-> Full vert horiz fuse width a
forall vertA vert horiz height heightA widthB a.
(C vertA, C vert, C horiz, C height, Eq height, C heightA,
 C widthB, Floating a) =>
Transposition
-> LowerUpper vertA Small heightA height a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
tallMultiplyU Transposition
NonTransposed LowerUpper vert Small height fuse a
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 :: LowerUpper Small horiz height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
wideMultiplyFullRight LowerUpper Small horiz height fuse a
a =
   Inversion
-> LowerUpper Small horiz height fuse a
-> Full vert horiz height width a
-> Full vert horiz height width a
forall vertA horizA vertB horizB height widthA widthB a.
(C vertA, C horizA, C vertB, C horizB, Eq height, C height,
 C widthA, C widthB, Floating a) =>
Inversion
-> LowerUpper vertA horizA height widthA a
-> Full vertB horizB height widthB a
-> Full vertB horizB height widthB a
multiplyP Inversion
NonInverted LowerUpper Small horiz height fuse a
a (Full vert horiz height width a -> Full vert horiz height width a)
-> (Full vert horiz fuse width a -> Full vert horiz height width a)
-> Full vert horiz fuse width a
-> Full vert horiz height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transposition
-> LowerUpper Small horiz height fuse a
-> Full vert horiz height width a
-> Full vert horiz height width a
forall horizA vert horiz height widthA widthB a.
(C horizA, C vert, C horiz, C height, Eq height, C widthA,
 C widthB, Floating a) =>
Transposition
-> LowerUpper Small horizA height widthA a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
wideMultiplyL Transposition
NonTransposed LowerUpper Small horiz height fuse a
a (Full vert horiz height width a -> Full vert horiz height width a)
-> (Full vert horiz fuse width a -> Full vert horiz height width a)
-> Full vert horiz fuse width a
-> Full vert horiz height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   Full vert horiz height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
forall vert horiz height fuse width a.
(C vert, C horiz, C height, C fuse, Eq fuse, C width,
 Floating a) =>
Full vert horiz height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
Basic.multiply (Full Small horiz height fuse a -> Full vert horiz height fuse a
forall vert horiz height width a.
(C vert, C horiz) =>
Full Small horiz height width a -> Full vert horiz height width a
Matrix.generalizeWide (LowerUpper Small horiz height fuse a
-> Full Small horiz height fuse a
forall vert horiz height width a.
(C vert, C horiz, C height, C width, Floating a) =>
LowerUpper vert horiz height width a
-> Full vert horiz height width a
extractU LowerUpper Small horiz height fuse a
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 :: LowerUpper horiz Small fuse height a
-> Full vert horiz fuse width a -> Full vert horiz height width a
tallTransMultiplyFullRight LowerUpper horiz Small fuse height a
a =
   Transposition
-> LowerUpper horiz Small fuse height a
-> Full vert horiz height width a
-> Full vert horiz height width a
forall vertA vert horiz height heightA widthB a.
(C vertA, C vert, C horiz, C height, Eq height, C heightA,
 C widthB, Floating a) =>
Transposition
-> LowerUpper vertA Small heightA height a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
tallMultiplyU Transposition
Transposed LowerUpper horiz Small fuse height a
a (Full vert horiz height width a -> Full vert horiz height width a)
-> (Full vert horiz fuse width a -> Full vert horiz height width a)
-> Full vert horiz fuse width a
-> Full vert horiz height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   Full vert horiz height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
forall vert horiz height fuse width a.
(C vert, C horiz, C height, C fuse, Eq fuse, C width,
 Floating a) =>
Full vert horiz height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
Basic.multiply (Full horiz vert fuse height a -> Full vert horiz height fuse a
forall vert horiz height width a.
(C vert, C horiz) =>
Full vert horiz height width a -> Full horiz vert width height a
Basic.transpose (Full horiz vert fuse height a -> Full vert horiz height fuse a)
-> Full horiz vert fuse height a -> Full vert horiz height fuse a
forall a b. (a -> b) -> a -> b
$ Full horiz Small fuse height a -> Full horiz vert fuse height a
forall vert horiz height width a.
(C vert, C horiz) =>
Full vert Small height width a -> Full vert horiz height width a
Matrix.generalizeTall (Full horiz Small fuse height a -> Full horiz vert fuse height a)
-> Full horiz Small fuse height a -> Full horiz vert fuse height a
forall a b. (a -> b) -> a -> b
$ LowerUpper horiz Small fuse height a
-> Full horiz Small fuse height a
forall vert horiz height width a.
(C vert, C horiz, C height, C width, Floating a) =>
LowerUpper vert horiz height width a
-> Full vert horiz height width a
extractL LowerUpper horiz Small fuse height a
a) (Full vert horiz fuse width a -> Full vert horiz height width a)
-> (Full vert horiz fuse width a -> Full vert horiz fuse width a)
-> Full vert horiz fuse width a
-> Full vert horiz height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   Inversion
-> LowerUpper horiz Small fuse height a
-> Full vert horiz fuse width a
-> Full vert horiz fuse width a
forall vertA horizA vertB horizB height widthA widthB a.
(C vertA, C horizA, C vertB, C horizB, Eq height, C height,
 C widthA, C widthB, Floating a) =>
Inversion
-> LowerUpper vertA horizA height widthA a
-> Full vertB horizB height widthB a
-> Full vertB horizB height widthB a
multiplyP Inversion
Inverted LowerUpper horiz Small fuse height a
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 :: LowerUpper Small vert fuse height a
-> Full vert horiz fuse width a -> Full vert horiz height width a
wideTransMultiplyFullRight LowerUpper Small vert fuse height a
a =
   Full vert horiz height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
forall vert horiz height fuse width a.
(C vert, C horiz, C height, C fuse, Eq fuse, C width,
 Floating a) =>
Full vert horiz height fuse a
-> Full vert horiz fuse width a -> Full vert horiz height width a
Basic.multiply (Full horiz vert fuse height a -> Full vert horiz height fuse a
forall vert horiz height width a.
(C vert, C horiz) =>
Full vert horiz height width a -> Full horiz vert width height a
Basic.transpose (Full horiz vert fuse height a -> Full vert horiz height fuse a)
-> Full horiz vert fuse height a -> Full vert horiz height fuse a
forall a b. (a -> b) -> a -> b
$ Full Small vert fuse height a -> Full horiz vert fuse height a
forall vert horiz height width a.
(C vert, C horiz) =>
Full Small horiz height width a -> Full vert horiz height width a
Matrix.generalizeWide (Full Small vert fuse height a -> Full horiz vert fuse height a)
-> Full Small vert fuse height a -> Full horiz vert fuse height a
forall a b. (a -> b) -> a -> b
$ LowerUpper Small vert fuse height a
-> Full Small vert fuse height a
forall vert horiz height width a.
(C vert, C horiz, C height, C width, Floating a) =>
LowerUpper vert horiz height width a
-> Full vert horiz height width a
extractU LowerUpper Small vert fuse height a
a) (Full vert horiz fuse width a -> Full vert horiz height width a)
-> (Full vert horiz fuse width a -> Full vert horiz fuse width a)
-> Full vert horiz fuse width a
-> Full vert horiz height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   Transposition
-> LowerUpper Small vert fuse height a
-> Full vert horiz fuse width a
-> Full vert horiz fuse width a
forall horizA vert horiz height widthA widthB a.
(C horizA, C vert, C horiz, C height, Eq height, C widthA,
 C widthB, Floating a) =>
Transposition
-> LowerUpper Small horizA height widthA a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
wideMultiplyL Transposition
Transposed LowerUpper Small vert fuse height a
a (Full vert horiz fuse width a -> Full vert horiz fuse width a)
-> (Full vert horiz fuse width a -> Full vert horiz fuse width a)
-> Full vert horiz fuse width a
-> Full vert horiz fuse width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   Inversion
-> LowerUpper Small vert fuse height a
-> Full vert horiz fuse width a
-> Full vert horiz fuse width a
forall vertA horizA vertB horizB height widthA widthB a.
(C vertA, C horizA, C vertB, C horizB, Eq height, C height,
 C widthA, C widthB, Floating a) =>
Inversion
-> LowerUpper vertA horizA height widthA a
-> Full vertB horizB height widthB a
-> Full vertB horizB height widthB a
multiplyP Inversion
Inverted LowerUpper Small vert fuse height a
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 vert horiz height width a
-> Either (Tall height width a) (Wide height width a)
caseTallWide (LowerUpper ipiv (Array shape a)) =
   (Split Triangle Big Small height width
 -> Either (Tall height width a) (Wide height width a))
-> (Split Triangle Small Big height width
    -> Either (Tall height width a) (Wide height width a))
-> Either
     (Split Triangle Big Small height width)
     (Split Triangle Small Big height width)
-> Either (Tall height width a) (Wide height width a)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
      (Tall height width a
-> Either (Tall height width a) (Wide height width a)
forall a b. a -> Either a b
Left (Tall height width a
 -> Either (Tall height width a) (Wide height width a))
-> (Split Triangle Big Small height width -> Tall height width a)
-> Split Triangle Big Small height width
-> Either (Tall height width a) (Wide height width a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector (Min width (Shape height)) (Element height)
-> Array (Split Triangle Big Small height width) a
-> Tall height width a
forall vert horiz height width a.
Vector (Min width (Shape height)) (Element height)
-> Array (Split Triangle vert horiz height width) a
-> Matrix (LU vert horiz height width) a
LowerUpper Vector (Min width (Shape height)) (Element height)
ipiv (Array (Split Triangle Big Small height width) a
 -> Tall height width a)
-> (Split Triangle Big Small height width
    -> Array (Split Triangle Big Small height width) a)
-> Split Triangle Big Small height width
-> Tall height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Split Triangle Big Small height width
 -> ForeignPtr a -> Array (Split Triangle Big Small height width) a)
-> ForeignPtr a
-> Split Triangle Big Small height width
-> Array (Split Triangle Big Small height width) a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Split Triangle Big Small height width
-> ForeignPtr a -> Array (Split Triangle Big Small height width) a
forall sh a. sh -> ForeignPtr a -> Array sh a
Array ForeignPtr a
a)
      (Wide height width a
-> Either (Tall height width a) (Wide height width a)
forall a b. b -> Either a b
Right (Wide height width a
 -> Either (Tall height width a) (Wide height width a))
-> (Split Triangle Small Big height width -> Wide height width a)
-> Split Triangle Small Big height width
-> Either (Tall height width a) (Wide height width a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector (Min width (Shape height)) (Element height)
-> Array (Split Triangle Small Big height width) a
-> Wide height width a
forall vert horiz height width a.
Vector (Min width (Shape height)) (Element height)
-> Array (Split Triangle vert horiz height width) a
-> Matrix (LU vert horiz height width) a
LowerUpper Vector (Min width (Shape height)) (Element height)
ipiv (Array (Split Triangle Small Big height width) a
 -> Wide height width a)
-> (Split Triangle Small Big height width
    -> Array (Split Triangle Small Big height width) a)
-> Split Triangle Small Big height width
-> Wide height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Split Triangle Small Big height width
 -> ForeignPtr a -> Array (Split Triangle Small Big height width) a)
-> ForeignPtr a
-> Split Triangle Small Big height width
-> Array (Split Triangle Small Big height width) a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Split Triangle Small Big height width
-> ForeignPtr a -> Array (Split Triangle Small Big height width) a
forall sh a. sh -> ForeignPtr a -> Array sh a
Array ForeignPtr a
a) (Either
   (Split Triangle Big Small height width)
   (Split Triangle Small Big height width)
 -> Either (Tall height width a) (Wide height width a))
-> Either
     (Split Triangle Big Small height width)
     (Split Triangle Small Big height width)
-> Either (Tall height width a) (Wide height width a)
forall a b. (a -> b) -> a -> b
$
   Split Triangle vert horiz height width
-> Either
     (Split Triangle Big Small height width)
     (Split Triangle Small Big height width)
forall vert horiz height width lower.
(C vert, C horiz, C height, C width) =>
Split lower vert horiz height width
-> Either
     (Split lower Big Small height width)
     (Split lower Small Big height width)
MatrixShape.caseTallWideSplit Split Triangle vert horiz height width
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 vert horiz height width a
-> LowerUpper vert horiz height width a
_toRowMajor
   (LowerUpper ipiv
      arr@(Array (MatrixShape.Split MatrixShape.Triangle order extent) a)) =
   Vector (Min width (Shape height)) (Element height)
-> Array (Split Triangle vert horiz height width) a
-> LowerUpper vert horiz height width a
forall vert horiz height width a.
Vector (Min width (Shape height)) (Element height)
-> Array (Split Triangle vert horiz height width) a
-> Matrix (LU vert horiz height width) a
LowerUpper Vector (Min width (Shape height)) (Element height)
ipiv (Array (Split Triangle vert horiz height width) a
 -> LowerUpper vert horiz height width a)
-> Array (Split Triangle vert horiz height width) a
-> LowerUpper vert horiz height width a
forall a b. (a -> b) -> a -> b
$
   case Order
order of
      Order
RowMajor -> Array (Split Triangle vert horiz height width) a
arr
      Order
ColumnMajor ->
         Split Triangle vert horiz height width
-> (Ptr a -> IO ())
-> Array (Split Triangle vert horiz height width) a
forall sh a.
(C sh, Storable a) =>
sh -> (Ptr a -> IO ()) -> Array sh a
Array.unsafeCreate
            (Triangle
-> Order
-> Extent vert horiz height width
-> Split Triangle vert horiz height width
forall lower vert horiz height width.
lower
-> Order
-> Extent vert horiz height width
-> Split lower vert horiz height width
MatrixShape.Split Triangle
MatrixShape.Triangle Order
RowMajor Extent vert horiz height width
extent) ((Ptr a -> IO ())
 -> Array (Split Triangle vert horiz height width) a)
-> (Ptr a -> IO ())
-> Array (Split Triangle vert horiz height width) a
forall a b. (a -> b) -> a -> b
$ \Ptr a
bPtr ->
         ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
a ((Ptr a -> IO ()) -> IO ()) -> (Ptr a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr a
aPtr -> do
            let (height
height, width
width) = Extent vert horiz height width -> (height, width)
forall vert horiz height width.
(C vert, C horiz) =>
Extent vert horiz height width -> (height, width)
Extent.dimensions Extent vert horiz height width
extent
            let n :: Int
n = width -> Int
forall sh. C sh => sh -> Int
Shape.size width
width
            let m :: Int
m = height -> Int
forall sh. C sh => sh -> Int
Shape.size height
height
            Int -> Int -> Ptr a -> Int -> Ptr a -> IO ()
forall a.
Floating a =>
Int -> Int -> Ptr a -> Int -> Ptr a -> IO ()
copyTransposed Int
n Int
m Ptr a
aPtr Int
n Ptr a
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 :: Matrix (LU vert horiz height width) a
-> HeightOf (LU vert horiz height width)
height = Split Triangle vert horiz height width -> height
forall vert horiz lower height width.
(C vert, C horiz) =>
Split lower vert horiz height width -> height
MatrixShape.splitHeight (Split Triangle vert horiz height width -> height)
-> (Matrix (LU vert horiz height width) a
    -> Split Triangle vert horiz height width)
-> Matrix (LU vert horiz height width) a
-> height
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array (Split Triangle vert horiz height width) a
-> Split Triangle vert horiz height width
forall sh a. Array sh a -> sh
Array.shape (Array (Split Triangle vert horiz height width) a
 -> Split Triangle vert horiz height width)
-> (Matrix (LU vert horiz height width) a
    -> Array (Split Triangle vert horiz height width) a)
-> Matrix (LU vert horiz height width) a
-> Split Triangle vert horiz height width
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix (LU vert horiz height width) a
-> Array (Split Triangle vert horiz height width) a
forall vert horiz height width a.
Matrix (LU vert horiz height width) a
-> Array (Split Triangle vert horiz height width) a
split_
   width :: Matrix (LU vert horiz height width) a
-> WidthOf (LU vert horiz height width)
width = Split Triangle vert horiz height width -> width
forall vert horiz lower height width.
(C vert, C horiz) =>
Split lower vert horiz height width -> width
MatrixShape.splitWidth (Split Triangle vert horiz height width -> width)
-> (Matrix (LU vert horiz height width) a
    -> Split Triangle vert horiz height width)
-> Matrix (LU vert horiz height width) a
-> width
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array (Split Triangle vert horiz height width) a
-> Split Triangle vert horiz height width
forall sh a. Array sh a -> sh
Array.shape (Array (Split Triangle vert horiz height width) a
 -> Split Triangle vert horiz height width)
-> (Matrix (LU vert horiz height width) a
    -> Array (Split Triangle vert horiz height width) a)
-> Matrix (LU vert horiz height width) a
-> Split Triangle vert horiz height width
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix (LU vert horiz height width) a
-> Array (Split Triangle vert horiz height width) a
forall vert horiz height width a.
Matrix (LU vert horiz height width) a
-> Array (Split Triangle vert horiz height width) a
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 :: Matrix (LU vert horiz height width) a
-> Vector width a
-> Vector (HeightOf (LU vert horiz height width)) a
matrixVector Matrix (LU vert horiz height width) a
lu Vector width a
x =
      Order
-> (General width () a -> General height () a)
-> Vector width a
-> Vector height a
forall height0 a height1 b.
Order
-> (General height0 () a -> General height1 () b)
-> Vector height0 a
-> Vector height1 b
Basic.unliftColumn Order
MatrixShape.ColumnMajor
         (LowerUpper Big Big height width a
-> General width () a -> General height () a
forall vert horiz height width fuse a.
(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
multiplyFull (Map vert horiz Big Big height width
-> Matrix (LU vert horiz height width) a
-> LowerUpper Big Big height width a
forall vertA horizA vertB horizB height width a.
(C vertA, C horizA, C vertB, C horizB) =>
Map vertA horizA vertB horizB height width
-> LowerUpper vertA horizA height width a
-> LowerUpper vertB horizB height width a
mapExtent Map vert horiz Big Big height width
forall vert horiz height width.
(C vert, C horiz) =>
Map vert horiz Big Big height width
ExtentMap.toGeneral Matrix (LU vert horiz height width) a
lu)) Vector width a
Vector width a
x
   vectorMatrix :: Vector height a
-> Matrix (LU vert horiz height width) a
-> Vector (WidthOf (LU vert horiz height width)) a
vectorMatrix Vector height a
x Matrix (LU vert horiz height width) a
lu =
      Order
-> (General height () a -> General width () a)
-> Vector height a
-> Vector width a
forall height0 a height1 b.
Order
-> (General height0 () a -> General height1 () b)
-> Vector height0 a
-> Vector height1 b
Basic.unliftColumn Order
MatrixShape.ColumnMajor
         ((LowerUpper Big Small height width a
 -> General height () a -> General width () a)
-> (LowerUpper Small Big height width a
    -> General height () a -> General width () a)
-> Either
     (LowerUpper Big Small height width a)
     (LowerUpper Small Big height width a)
-> General height () a
-> General width () a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either LowerUpper Big Small height width a
-> General height () a -> General width () a
forall vert horiz height width fuse a.
(C vert, C horiz, C height, C width, C fuse, Eq height, Eq fuse,
 Floating a) =>
LowerUpper horiz Small fuse height a
-> Full vert horiz fuse width a -> Full vert horiz height width a
tallTransMultiplyFullRight LowerUpper Small Big height width a
-> General height () a -> General width () a
forall vert horiz height width fuse a.
(C vert, C horiz, C height, C width, C fuse, Eq height, Eq fuse,
 Floating a) =>
LowerUpper Small vert fuse height a
-> Full vert horiz fuse width a -> Full vert horiz height width a
wideTransMultiplyFullRight (Either
   (LowerUpper Big Small height width a)
   (LowerUpper Small Big height width a)
 -> General height () a -> General width () a)
-> Either
     (LowerUpper Big Small height width a)
     (LowerUpper Small Big height width a)
-> General height () a
-> General width () a
forall a b. (a -> b) -> a -> b
$
          Matrix (LU vert horiz height width) a
-> Either
     (LowerUpper Big Small height width a)
     (LowerUpper Small Big height width a)
forall vert horiz height width a.
(C vert, C horiz, C height, C width) =>
LowerUpper vert horiz height width a
-> Either (Tall height width a) (Wide height width a)
caseTallWide Matrix (LU vert horiz height width) a
lu)
         Vector height a
Vector height a
x

instance
   (vert ~ Extent.Small, horiz ~ Extent.Small,
    Shape.C height, height ~ width) =>
      Multiply.MultiplySquare (LU vert horiz height width) where

   squareFull :: Matrix (LU vert horiz height width) a
-> Full vert horiz height width a -> Full vert horiz height width a
squareFull Matrix (LU vert horiz height width) a
lu =
      (Array (Full vert horiz width width) a
 -> Array (Full vert horiz height width) a)
-> ArrayMatrix (Full vert horiz width width) a
-> ArrayMatrix (Full vert horiz height width) a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 ((Array (Full vert horiz width width) a
  -> Array (Full vert horiz height width) a)
 -> ArrayMatrix (Full vert horiz width width) a
 -> ArrayMatrix (Full vert horiz height width) a)
-> (Array (Full vert horiz width width) a
    -> Array (Full vert horiz height width) a)
-> ArrayMatrix (Full vert horiz width width) a
-> ArrayMatrix (Full vert horiz height width) a
forall a b. (a -> b) -> a -> b
$
         Inversion
-> Matrix (LU vert horiz height width) a
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
forall vertA horizA vertB horizB height widthA widthB a.
(C vertA, C horizA, C vertB, C horizB, Eq height, C height,
 C widthA, C widthB, Floating a) =>
Inversion
-> LowerUpper vertA horizA height widthA a
-> Full vertB horizB height widthB a
-> Full vertB horizB height widthB a
multiplyP Inversion
NonInverted Matrix (LU vert horiz height width) a
lu (Array (Full vert horiz height width) a
 -> Array (Full vert horiz height width) a)
-> (Array (Full vert horiz width width) a
    -> Array (Full vert horiz height width) a)
-> Array (Full vert horiz width width) a
-> Array (Full vert horiz height width) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
         Transposition
-> LowerUpper Small horiz height width a
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
forall horizA vert horiz height widthA widthB a.
(C horizA, C vert, C horiz, C height, Eq height, C widthA,
 C widthB, Floating a) =>
Transposition
-> LowerUpper Small horizA height widthA a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
wideMultiplyL Transposition
NonTransposed Matrix (LU vert horiz height width) a
LowerUpper Small horiz height width a
lu (Array (Full vert horiz height width) a
 -> Array (Full vert horiz height width) a)
-> (Array (Full vert horiz width width) a
    -> Array (Full vert horiz height width) a)
-> Array (Full vert horiz width width) a
-> Array (Full vert horiz height width) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
         Transposition
-> LowerUpper vert Small height width a
-> Array (Full vert horiz width width) a
-> Array (Full vert horiz width width) a
forall vertA vert horiz height heightA widthB a.
(C vertA, C vert, C horiz, C height, Eq height, C heightA,
 C widthB, Floating a) =>
Transposition
-> LowerUpper vertA Small heightA height a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
tallMultiplyU Transposition
NonTransposed Matrix (LU vert horiz height width) a
LowerUpper vert Small height width a
lu

   fullSquare :: Full vert horiz height width a
-> Matrix (LU vert horiz height width) a
-> Full vert horiz height width a
fullSquare = (LowerUpper Small Small width width a
 -> Full vert horiz height width a
 -> Full vert horiz height width a)
-> Full vert horiz height width a
-> LowerUpper Small Small width width a
-> Full vert horiz height width a
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((LowerUpper Small Small width width a
  -> Full vert horiz height width a
  -> Full vert horiz height width a)
 -> Full vert horiz height width a
 -> LowerUpper Small Small width width a
 -> Full vert horiz height width a)
-> (LowerUpper Small Small width width a
    -> Full vert horiz height width a
    -> Full vert horiz height width a)
-> Full vert horiz height width a
-> LowerUpper Small Small width width a
-> Full vert horiz height width a
forall a b. (a -> b) -> a -> b
$ \LowerUpper Small Small width width a
lu ->
      (Array (Full vert horiz height width) a
 -> Array (Full vert horiz height width) a)
-> Full vert horiz height width a -> Full vert horiz height width a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 ((Array (Full vert horiz height width) a
  -> Array (Full vert horiz height width) a)
 -> Full vert horiz height width a
 -> Full vert horiz height width a)
-> (Array (Full vert horiz height width) a
    -> Array (Full vert horiz height width) a)
-> Full vert horiz height width a
-> Full vert horiz height width a
forall a b. (a -> b) -> a -> b
$
         Full horiz vert width height a
-> Array (Full vert horiz height width) a
forall vert horiz height width a.
(C vert, C horiz) =>
Full vert horiz height width a -> Full horiz vert width height a
Basic.transpose (Full horiz vert width height a
 -> Array (Full vert horiz height width) a)
-> (Array (Full vert horiz height width) a
    -> Full horiz vert width height a)
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
         Transposition
-> LowerUpper Small Small width width a
-> Full horiz vert width height a
-> Full horiz vert width height a
forall vertA vert horiz height heightA widthB a.
(C vertA, C vert, C horiz, C height, Eq height, C heightA,
 C widthB, Floating a) =>
Transposition
-> LowerUpper vertA Small heightA height a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
tallMultiplyU Transposition
Transposed LowerUpper Small Small width width a
lu (Full horiz vert width height a -> Full horiz vert width height a)
-> (Array (Full vert horiz height width) a
    -> Full horiz vert width height a)
-> Array (Full vert horiz height width) a
-> Full horiz vert width height a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
         Transposition
-> LowerUpper Small Small width width a
-> Full horiz vert width height a
-> Full horiz vert width height a
forall horizA vert horiz height widthA widthB a.
(C horizA, C vert, C horiz, C height, Eq height, C widthA,
 C widthB, Floating a) =>
Transposition
-> LowerUpper Small horizA height widthA a
-> Full vert horiz height widthB a
-> Full vert horiz height widthB a
wideMultiplyL Transposition
Transposed LowerUpper Small Small width width a
lu (Full horiz vert width height a -> Full horiz vert width height a)
-> (Array (Full vert horiz height width) a
    -> Full horiz vert width height a)
-> Array (Full vert horiz height width) a
-> Full horiz vert width height a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
         Inversion
-> LowerUpper Small Small width width a
-> Full horiz vert width height a
-> Full horiz vert width height a
forall vertA horizA vertB horizB height widthA widthB a.
(C vertA, C horizA, C vertB, C horizB, Eq height, C height,
 C widthA, C widthB, Floating a) =>
Inversion
-> LowerUpper vertA horizA height widthA a
-> Full vertB horizB height widthB a
-> Full vertB horizB height widthB a
multiplyP Inversion
Inverted LowerUpper Small Small width width a
lu (Full horiz vert width height a -> Full horiz vert width height a)
-> (Array (Full vert horiz height width) a
    -> Full horiz vert width height a)
-> Array (Full vert horiz height width) a
-> Full horiz vert width height a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
         Array (Full vert horiz height width) a
-> Full horiz vert width height a
forall vert horiz height width a.
(C vert, C horiz) =>
Full vert horiz height width a -> Full horiz vert width height a
Basic.transpose

instance
   (vert ~ Extent.Small, horiz ~ Extent.Small,
    Shape.C height, height ~ width) =>
      Divide.Determinant (LU vert horiz height width) where
   determinant :: Matrix (LU vert horiz height width) a -> a
determinant = Matrix (LU vert horiz height width) a -> a
forall sh a. (C sh, Floating a) => Square sh a -> a
determinant

instance
   (vert ~ Extent.Small, horiz ~ Extent.Small,
    Shape.C height, height ~ width) =>
      Divide.Solve (LU vert horiz height width) where
   solve :: Transposition
-> Matrix (LU vert horiz height width) a
-> Full vert horiz height width a
-> Full vert horiz height width a
solve Transposition
trans = (Array (Full vert horiz height width) a
 -> Array (Full vert horiz height width) a)
-> Full vert horiz height width a -> Full vert horiz height width a
forall shA a shB b.
(Array shA a -> Array shB b)
-> ArrayMatrix shA a -> ArrayMatrix shB b
ArrMatrix.lift1 ((Array (Full vert horiz height width) a
  -> Array (Full vert horiz height width) a)
 -> Full vert horiz height width a
 -> Full vert horiz height width a)
-> (Square height a
    -> Array (Full vert horiz height width) a
    -> Array (Full vert horiz height width) a)
-> Square height a
-> Full vert horiz height width a
-> Full vert horiz height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transposition
-> Square height a
-> Array (Full vert horiz height width) a
-> Array (Full vert horiz height width) a
forall vert horiz height width a.
(C vert, C horiz, Eq height, C height, C width, Floating a) =>
Transposition
-> Square height a
-> Full vert horiz height width a
-> Full vert horiz height width a
solveTrans Transposition
trans