{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
module Numeric.LAPACK.Matrix.Multiply where

import qualified Numeric.LAPACK.Matrix.Array.Multiply as Multiply
import qualified Numeric.LAPACK.Matrix.Array.Unpacked as Unpacked
import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix
import qualified Numeric.LAPACK.Matrix.Permutation as PermMatrix
import qualified Numeric.LAPACK.Matrix.Class as MatrixClass
import qualified Numeric.LAPACK.Matrix.Type as Matrix
import qualified Numeric.LAPACK.Matrix.Basic as FullBasic
import qualified Numeric.LAPACK.Matrix.Modifier as Mod
import qualified Numeric.LAPACK.Matrix.Shape.Omni as Omni
import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape
import qualified Numeric.LAPACK.Matrix.Layout.Private as Layout
import qualified Numeric.LAPACK.Matrix.Extent.Private as ExtentPriv
import qualified Numeric.LAPACK.Matrix.Extent as Extent
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 qualified Numeric.Netlib.Class as Class

import qualified Data.Array.Comfort.Storable as Array
import qualified Data.Array.Comfort.Shape as Shape

import qualified Data.Stream as Stream
import Data.Stream (Stream)
import Data.Maybe (fromMaybe)



infixl 7 -*#
infixr 7 #*|

(#*|) ::
   (MultiplyVector typ xl xu, Omni.Strip lower, Omni.Strip upper) =>
   (Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.C height, Shape.C width, Eq width, Class.Floating a) =>
   Matrix typ xl xu lower upper meas vert horiz height width a ->
   Vector width a -> Vector height a
#*| :: Matrix typ xl xu lower upper meas vert horiz height width a
-> Vector width a -> Vector height a
(#*|) = Matrix typ xl xu lower upper meas vert horiz height width a
-> Vector width a -> Vector height a
forall typ xl xu lower upper meas vert horiz height width a.
(MultiplyVector typ xl xu, Strip lower, Strip upper, Measure meas,
 C vert, C horiz, C height, C width, Eq width, Floating a) =>
Matrix typ xl xu lower upper meas vert horiz height width a
-> Vector width a -> Vector height a
matrixVector

(-*#) ::
   (MultiplyVector typ xl xu, Omni.Strip lower, Omni.Strip upper) =>
   (Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.C height, Shape.C width, Eq height, Class.Floating a) =>
   Vector height a ->
   Matrix typ xl xu lower upper meas vert horiz height width a ->
   Vector width a
-*# :: Vector height a
-> Matrix typ xl xu lower upper meas vert horiz height width a
-> Vector width a
(-*#) = Vector height a
-> Matrix typ xl xu lower upper meas vert horiz height width a
-> Vector width a
forall typ xl xu lower upper meas vert horiz height width a.
(MultiplyVector typ xl xu, Strip lower, Strip upper, Measure meas,
 C vert, C horiz, C height, C width, Eq height, Floating a) =>
Vector height a
-> Matrix typ xl xu lower upper meas vert horiz height width a
-> Vector width a
vectorMatrix


class (Matrix.Box typ) => MultiplyVector typ xl xu where
   matrixVector ::
      (Omni.Strip lower, Omni.Strip upper) =>
      (Extent.Measure meas, Extent.C vert, Extent.C horiz,
       Shape.C height, Shape.C width) =>
      (Eq width, Class.Floating a) =>
      Matrix typ xl xu lower upper meas vert horiz height width a ->
      Vector width a -> Vector height a
   vectorMatrix ::
      (Omni.Strip lower, Omni.Strip upper) =>
      (Extent.Measure meas, Extent.C vert, Extent.C horiz,
       Shape.C height, Shape.C width) =>
      (Eq height, Class.Floating a) =>
      Vector height a ->
      Matrix typ xl xu lower upper meas vert horiz height width a ->
      Vector width a

instance (xl ~ (), xu ~ ()) => MultiplyVector Matrix.Scale xl xu where
   matrixVector :: Matrix Scale xl xu lower upper meas vert horiz height width a
-> Vector width a -> Vector height a
matrixVector a :: Matrix Scale xl xu lower upper meas vert horiz height width a
a@(Matrix.Scale _ _) =
      String
-> (Vector height a -> height)
-> (a -> Vector height a -> Vector height a)
-> Matrix Scale xl xu lower upper meas vert horiz height height a
-> Vector height a
-> Vector height a
forall shape b a c xl xu lower upper meas vert horiz.
Eq shape =>
String
-> (b -> shape)
-> (a -> b -> c)
-> Matrix Scale xl xu lower upper meas vert horiz shape shape a
-> b
-> c
scaleWithCheck String
"Matrix.Multiply.matrixVector Scale"
         Vector height a -> height
forall sh a. Array sh a -> sh
Array.shape a -> Vector height a -> Vector height a
forall sh a. (C sh, Floating a) => a -> Vector sh a -> Vector sh a
Vector.scale Matrix Scale xl xu lower upper meas vert horiz height height a
Matrix Scale xl xu lower upper meas vert horiz height width a
a
   vectorMatrix :: Vector height a
-> Matrix Scale xl xu lower upper meas vert horiz height width a
-> Vector width a
vectorMatrix Vector height a
v a :: Matrix Scale xl xu lower upper meas vert horiz height width a
a@(Matrix.Scale _ _) =
      String
-> (Vector height a -> height)
-> (a -> Vector height a -> Vector height a)
-> Matrix Scale xl xu lower upper meas vert horiz height height a
-> Vector height a
-> Vector height a
forall shape b a c xl xu lower upper meas vert horiz.
Eq shape =>
String
-> (b -> shape)
-> (a -> b -> c)
-> Matrix Scale xl xu lower upper meas vert horiz shape shape a
-> b
-> c
scaleWithCheck String
"Matrix.Multiply.vectorMatrix Scale"
         Vector height a -> height
forall sh a. Array sh a -> sh
Array.shape a -> Vector height a -> Vector height a
forall sh a. (C sh, Floating a) => a -> Vector sh a -> Vector sh a
Vector.scale Matrix Scale xl xu lower upper meas vert horiz height height a
Matrix Scale xl xu lower upper meas vert horiz height width a
a Vector height a
v

instance (xl ~ (), xu ~ ()) => MultiplyVector Matrix.Permutation xl xu where
   matrixVector :: Matrix Permutation xl xu lower upper meas vert horiz height width a
-> Vector width a -> Vector height a
matrixVector a :: Matrix Permutation xl xu lower upper meas vert horiz height width a
a@(Matrix.Permutation _) =
      Inversion
-> FlexPermutation lower upper height a
-> Vector height a
-> Vector height a
forall size a lower upper.
(C size, Eq size, Floating a) =>
Inversion
-> FlexPermutation lower upper size a
-> Vector size a
-> Vector size a
PermMatrix.multiplyVector Inversion
Mod.NonInverted Matrix Permutation xl xu lower upper meas vert horiz height width a
FlexPermutation lower upper height a
a
   vectorMatrix :: Vector height a
-> Matrix
     Permutation xl xu lower upper meas vert horiz height width a
-> Vector width a
vectorMatrix Vector height a
v a :: Matrix Permutation xl xu lower upper meas vert horiz height width a
a@(Matrix.Permutation _) =
      Inversion
-> FlexPermutation lower upper height a
-> Vector height a
-> Vector height a
forall size a lower upper.
(C size, Eq size, Floating a) =>
Inversion
-> FlexPermutation lower upper size a
-> Vector size a
-> Vector size a
PermMatrix.multiplyVector Inversion
Mod.Inverted Matrix Permutation xl xu lower upper meas vert horiz height width a
FlexPermutation lower upper height a
a Vector height a
v

instance
   (Layout.Packing pack, Omni.Property property, xl ~ (), xu ~ ()) =>
      MultiplyVector (ArrMatrix.Array pack property) xl xu where
   matrixVector :: Matrix
  (Array pack property)
  xl
  xu
  lower
  upper
  meas
  vert
  horiz
  height
  width
  a
-> Vector width a -> Vector height a
matrixVector = Matrix
  (Array pack property)
  xl
  xu
  lower
  upper
  meas
  vert
  horiz
  height
  width
  a
-> Vector width a -> Vector height a
forall pack property lower upper meas vert horiz height width a.
(Packing pack, Property property, Strip lower, Strip upper,
 Measure meas, C vert, C horiz, C height, C width, Eq width,
 Floating a) =>
ArrayMatrix
  pack property lower upper meas vert horiz height width a
-> Vector width a -> Vector height a
Multiply.matrixVector
   vectorMatrix :: Vector height a
-> Matrix
     (Array pack property)
     xl
     xu
     lower
     upper
     meas
     vert
     horiz
     height
     width
     a
-> Vector width a
vectorMatrix = Vector height a
-> Matrix
     (Array pack property)
     xl
     xu
     lower
     upper
     meas
     vert
     horiz
     height
     width
     a
-> Vector width a
forall pack property lower upper meas vert horiz height width a.
(Packing pack, Property property, Strip lower, Strip upper,
 Measure meas, C vert, C horiz, C height, Eq height, C width,
 Floating a) =>
Vector height a
-> ArrayMatrix
     pack property lower upper meas vert horiz height width a
-> Vector width a
Multiply.vectorMatrix



class (Matrix.Box typ) => MultiplySquare typ xl xu where
   {-# MINIMAL transposableSquare | fullSquare,squareFull #-}
   transposableSquare ::
      (Omni.Strip lower, Omni.Strip upper) =>
      (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
      (Shape.C height, Eq height, Shape.C width, Class.Floating a) =>
      Transposition ->
      Matrix.Quadratic typ xl xu lower upper height a ->
      Full meas vert horiz height width a ->
      Full meas vert horiz height width a
   transposableSquare Transposition
NonTransposed Quadratic typ xl xu lower upper height a
a Full meas vert horiz height width a
b = Quadratic typ xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
forall typ xl xu lower upper meas vert horiz height width a.
(MultiplySquare typ xl xu, Strip lower, Strip upper, Measure meas,
 C vert, C horiz, C height, Eq height, C width, Floating a) =>
Quadratic typ xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
squareFull Quadratic typ xl xu lower upper height a
a Full meas vert horiz height width a
b
   transposableSquare Transposition
Transposed Quadratic typ xl xu lower upper height a
a Full meas vert horiz height width a
b =
      Unpacked Arbitrary Filled Filled meas horiz vert width height a
-> Full meas vert horiz height width a
forall property lower upper meas vert horiz height width a.
(Property property, Strip lower, Strip upper, Measure meas, C vert,
 C horiz) =>
Unpacked property lower upper meas vert horiz height width a
-> Unpacked property upper lower meas horiz vert width height a
Unpacked.transpose (Unpacked Arbitrary Filled Filled meas horiz vert width height a
 -> Full meas vert horiz height width a)
-> Unpacked Arbitrary Filled Filled meas horiz vert width height a
-> Full meas vert horiz height width a
forall a b. (a -> b) -> a -> b
$ Unpacked Arbitrary Filled Filled meas horiz vert width height a
-> Quadratic typ xl xu lower upper height a
-> Unpacked Arbitrary Filled Filled meas horiz vert width height a
forall typ xl xu lower upper meas vert horiz height width a.
(MultiplySquare typ xl xu, Strip lower, Strip upper, Measure meas,
 C vert, C horiz, C height, C width, Eq width, Floating a) =>
Full meas vert horiz height width a
-> Quadratic typ xl xu lower upper width a
-> Full meas vert horiz height width a
fullSquare (Full meas vert horiz height width a
-> Unpacked Arbitrary Filled Filled meas horiz vert width height a
forall property lower upper meas vert horiz height width a.
(Property property, Strip lower, Strip upper, Measure meas, C vert,
 C horiz) =>
Unpacked property lower upper meas vert horiz height width a
-> Unpacked property upper lower meas horiz vert width height a
Unpacked.transpose Full meas vert horiz height width a
b) Quadratic typ xl xu lower upper height a
a

   squareFull ::
      (Omni.Strip lower, Omni.Strip upper) =>
      (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
      (Shape.C height, Eq height, Shape.C width, Class.Floating a) =>
      Matrix.Quadratic typ xl xu lower upper height a ->
      Full meas vert horiz height width a ->
      Full meas vert horiz height width a
   squareFull = Transposition
-> Quadratic typ xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
forall typ xl xu lower upper meas vert horiz height width a.
(MultiplySquare typ xl xu, Strip lower, Strip upper, Measure meas,
 C vert, C horiz, C height, Eq height, C width, Floating a) =>
Transposition
-> Quadratic typ xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
transposableSquare Transposition
NonTransposed

   fullSquare ::
      (Omni.Strip lower, Omni.Strip upper) =>
      (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
      (Shape.C height, Shape.C width, Eq width, Class.Floating a) =>
      Full meas vert horiz height width a ->
      Matrix.Quadratic typ xl xu lower upper width a ->
      Full meas vert horiz height width a
   fullSquare Full meas vert horiz height width a
b Quadratic typ xl xu lower upper width a
a =
      Unpacked Arbitrary Filled Filled meas horiz vert width height a
-> Full meas vert horiz height width a
forall property lower upper meas vert horiz height width a.
(Property property, Strip lower, Strip upper, Measure meas, C vert,
 C horiz) =>
Unpacked property lower upper meas vert horiz height width a
-> Unpacked property upper lower meas horiz vert width height a
Unpacked.transpose (Unpacked Arbitrary Filled Filled meas horiz vert width height a
 -> Full meas vert horiz height width a)
-> Unpacked Arbitrary Filled Filled meas horiz vert width height a
-> Full meas vert horiz height width a
forall a b. (a -> b) -> a -> b
$
      Transposition
-> Quadratic typ xl xu lower upper width a
-> Unpacked Arbitrary Filled Filled meas horiz vert width height a
-> Unpacked Arbitrary Filled Filled meas horiz vert width height a
forall typ xl xu lower upper meas vert horiz height width a.
(MultiplySquare typ xl xu, Strip lower, Strip upper, Measure meas,
 C vert, C horiz, C height, Eq height, C width, Floating a) =>
Transposition
-> Quadratic typ xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
transposableSquare Transposition
Transposed Quadratic typ xl xu lower upper width a
a (Unpacked Arbitrary Filled Filled meas horiz vert width height a
 -> Unpacked Arbitrary Filled Filled meas horiz vert width height a)
-> Unpacked Arbitrary Filled Filled meas horiz vert width height a
-> Unpacked Arbitrary Filled Filled meas horiz vert width height a
forall a b. (a -> b) -> a -> b
$ Full meas vert horiz height width a
-> Unpacked Arbitrary Filled Filled meas horiz vert width height a
forall property lower upper meas vert horiz height width a.
(Property property, Strip lower, Strip upper, Measure meas, C vert,
 C horiz) =>
Unpacked property lower upper meas vert horiz height width a
-> Unpacked property upper lower meas horiz vert width height a
Unpacked.transpose Full meas vert horiz height width a
b


type Unpacked lower upper meas vert horiz height width =
         Unpacked.Unpacked MatrixShape.Arbitrary
            lower upper meas vert horiz height width

infixl 7 ##*#, #*#
infixr 7 #*##

(#*##) ::
   (MultiplySquare typ xl xu, Matrix.ToQuadratic typ) =>
   (Omni.Strip lowerA, Omni.Strip upperA) =>
   (Omni.Strip lowerB, Omni.Strip upperB) =>
   (Omni.Strip lowerC, Omni.Strip upperC) =>
   (Omni.MultipliedBands lowerA lowerB ~ lowerC) =>
   (Omni.MultipliedBands lowerB lowerA ~ lowerC) =>
   (Omni.MultipliedBands upperA upperB ~ upperC) =>
   (Omni.MultipliedBands upperB upperA ~ upperC) =>
   (Extent.Measure measA, Extent.Measure measB, Extent.Measure measC,
    Extent.MultiplyMeasure measA measB ~ measC) =>
   (Extent.C vert, Extent.C horiz) =>
   (Shape.C height, Shape.C fuse, Eq fuse, Shape.C width, Class.Floating a) =>
   Matrix.QuadraticMeas typ xl xu lowerA upperA measA height fuse a ->
   Unpacked lowerB upperB measB vert horiz fuse width a ->
   Unpacked lowerC upperC measC vert horiz height width a
QuadraticMeas typ xl xu lowerA upperA measA height fuse a
a#*## :: QuadraticMeas typ xl xu lowerA upperA measA height fuse a
-> Unpacked lowerB upperB measB vert horiz fuse width a
-> Unpacked lowerC upperC measC vert horiz height width a
#*##Unpacked lowerB upperB measB vert horiz fuse width a
b =
   case QuadraticMeas typ xl xu lowerA upperA measA height fuse a
-> (IdentityMaes measA height fuse a,
    Quadratic typ xl xu lowerA upperA fuse a)
forall typ meas xl xu lower upper height width a.
(ToQuadratic typ, Measure meas) =>
QuadraticMeas typ xl xu lower upper meas height width a
-> (IdentityMaes meas height width a,
    Quadratic typ xl xu lower upper width a)
factorIdentityLeft QuadraticMeas typ xl xu lowerA upperA measA height fuse a
a of
      (IdentityMaes measA height fuse a
ident, Quadratic typ xl xu lowerA upperA fuse a
q) ->
         (FullArray measC vert horiz height width a
 -> FullArray measC vert horiz height width a)
-> UnpackedMatrix
     Arbitrary Filled Filled measC vert horiz height width a
-> Unpacked lowerC upperC measC vert horiz height width a
forall propertyA lowerA upperA propertyB lowerB upperB measA vertA
       horizA heightA widthA a measB vertB horizB heightB widthB b.
(Property propertyA, Strip lowerA, Strip upperA,
 Property propertyB, Strip lowerB, Strip upperB) =>
(FullArray measA vertA horizA heightA widthA a
 -> FullArray measB vertB horizB heightB widthB b)
-> UnpackedMatrix
     propertyA lowerA upperA measA vertA horizA heightA widthA a
-> UnpackedMatrix
     propertyB lowerB upperB measB vertB horizB heightB widthB b
ArrMatrix.liftUnpacked1 FullArray measC vert horiz height width a
-> FullArray measC vert horiz height width a
forall a. a -> a
id (UnpackedMatrix
   Arbitrary Filled Filled measC vert horiz height width a
 -> Unpacked lowerC upperC measC vert horiz height width a)
-> UnpackedMatrix
     Arbitrary Filled Filled measC vert horiz height width a
-> Unpacked lowerC upperC measC vert horiz height width a
forall a b. (a -> b) -> a -> b
$
         IdentityMaes measA height fuse a
-> Full measB vert horiz fuse width a
-> UnpackedMatrix
     Arbitrary Filled Filled measC vert horiz height width a
forall measA measB measC vert horiz fuse height a width.
(Measure measA, Measure measB, Measure measC,
 MultiplyMeasure measA measB ~ measC, C vert, C horiz, Eq fuse) =>
IdentityMaes measA height fuse a
-> Full measB vert horiz fuse width a
-> Full measC vert horiz height width a
reshapeHeight IdentityMaes measA height fuse a
ident (Quadratic typ xl xu lowerA upperA fuse a
-> Full measB vert horiz fuse width a
-> Full measB vert horiz fuse width a
forall typ xl xu lower upper meas vert horiz height width a.
(MultiplySquare typ xl xu, Strip lower, Strip upper, Measure meas,
 C vert, C horiz, C height, Eq height, C width, Floating a) =>
Quadratic typ xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
squareFull Quadratic typ xl xu lowerA upperA fuse a
q ((FullArray measB vert horiz fuse width a
 -> FullArray measB vert horiz fuse width a)
-> Unpacked lowerB upperB measB vert horiz fuse width a
-> Full measB vert horiz fuse width a
forall propertyA lowerA upperA propertyB lowerB upperB measA vertA
       horizA heightA widthA a measB vertB horizB heightB widthB b.
(Property propertyA, Strip lowerA, Strip upperA,
 Property propertyB, Strip lowerB, Strip upperB) =>
(FullArray measA vertA horizA heightA widthA a
 -> FullArray measB vertB horizB heightB widthB b)
-> UnpackedMatrix
     propertyA lowerA upperA measA vertA horizA heightA widthA a
-> UnpackedMatrix
     propertyB lowerB upperB measB vertB horizB heightB widthB b
ArrMatrix.liftUnpacked1 FullArray measB vert horiz fuse width a
-> FullArray measB vert horiz fuse width a
forall a. a -> a
id Unpacked lowerB upperB measB vert horiz fuse width a
b))

(##*#) ::
   (MultiplySquare typ xl xu, Matrix.ToQuadratic typ) =>
   (Omni.Strip lowerA, Omni.Strip upperA) =>
   (Omni.Strip lowerB, Omni.Strip upperB) =>
   (Omni.Strip lowerC, Omni.Strip upperC) =>
   (Omni.MultipliedBands lowerA lowerB ~ lowerC) =>
   (Omni.MultipliedBands lowerB lowerA ~ lowerC) =>
   (Omni.MultipliedBands upperA upperB ~ upperC) =>
   (Omni.MultipliedBands upperB upperA ~ upperC) =>
   (Extent.Measure measA, Extent.Measure measB, Extent.Measure measC,
    Extent.MultiplyMeasure measA measB ~ measC) =>
   (Extent.C vert, Extent.C horiz) =>
   (Shape.C height, Shape.C fuse, Eq fuse, Shape.C width, Class.Floating a) =>
   Unpacked lowerB upperB measB vert horiz height fuse a ->
   Matrix.QuadraticMeas typ xl xu lowerA upperA measA fuse width a ->
   Unpacked lowerC upperC measC vert horiz height width a
Unpacked lowerB upperB measB vert horiz height fuse a
b##*# :: Unpacked lowerB upperB measB vert horiz height fuse a
-> QuadraticMeas typ xl xu lowerA upperA measA fuse width a
-> Unpacked lowerC upperC measC vert horiz height width a
##*#QuadraticMeas typ xl xu lowerA upperA measA fuse width a
a =
   case QuadraticMeas typ xl xu lowerA upperA measA fuse width a
-> (Quadratic typ xl xu lowerA upperA fuse a,
    IdentityMaes measA fuse width a)
forall typ meas xl xu lower upper height width a.
(ToQuadratic typ, Measure meas) =>
QuadraticMeas typ xl xu lower upper meas height width a
-> (Quadratic typ xl xu lower upper height a,
    IdentityMaes meas height width a)
factorIdentityRight QuadraticMeas typ xl xu lowerA upperA measA fuse width a
a of
      (Quadratic typ xl xu lowerA upperA fuse a
q, IdentityMaes measA fuse width a
ident) ->
         (FullArray measC vert horiz height width a
 -> FullArray measC vert horiz height width a)
-> UnpackedMatrix
     Arbitrary Filled Filled measC vert horiz height width a
-> Unpacked lowerC upperC measC vert horiz height width a
forall propertyA lowerA upperA propertyB lowerB upperB measA vertA
       horizA heightA widthA a measB vertB horizB heightB widthB b.
(Property propertyA, Strip lowerA, Strip upperA,
 Property propertyB, Strip lowerB, Strip upperB) =>
(FullArray measA vertA horizA heightA widthA a
 -> FullArray measB vertB horizB heightB widthB b)
-> UnpackedMatrix
     propertyA lowerA upperA measA vertA horizA heightA widthA a
-> UnpackedMatrix
     propertyB lowerB upperB measB vertB horizB heightB widthB b
ArrMatrix.liftUnpacked1 FullArray measC vert horiz height width a
-> FullArray measC vert horiz height width a
forall a. a -> a
id (UnpackedMatrix
   Arbitrary Filled Filled measC vert horiz height width a
 -> Unpacked lowerC upperC measC vert horiz height width a)
-> UnpackedMatrix
     Arbitrary Filled Filled measC vert horiz height width a
-> Unpacked lowerC upperC measC vert horiz height width a
forall a b. (a -> b) -> a -> b
$
         Full measB vert horiz height fuse a
-> IdentityMaes measA fuse width a
-> UnpackedMatrix
     Arbitrary Filled Filled measC vert horiz height width a
forall measA measB measC vert horiz fuse height a width.
(Measure measA, Measure measB, Measure measC,
 MultiplyMeasure measA measB ~ measC, C vert, C horiz, Eq fuse) =>
Full measB vert horiz height fuse a
-> IdentityMaes measA fuse width a
-> Full measC vert horiz height width a
reshapeWidth (Full measB vert horiz height fuse a
-> Quadratic typ xl xu lowerA upperA fuse a
-> Full measB vert horiz height fuse a
forall typ xl xu lower upper meas vert horiz height width a.
(MultiplySquare typ xl xu, Strip lower, Strip upper, Measure meas,
 C vert, C horiz, C height, C width, Eq width, Floating a) =>
Full meas vert horiz height width a
-> Quadratic typ xl xu lower upper width a
-> Full meas vert horiz height width a
fullSquare ((FullArray measB vert horiz height fuse a
 -> FullArray measB vert horiz height fuse a)
-> Unpacked lowerB upperB measB vert horiz height fuse a
-> Full measB vert horiz height fuse a
forall propertyA lowerA upperA propertyB lowerB upperB measA vertA
       horizA heightA widthA a measB vertB horizB heightB widthB b.
(Property propertyA, Strip lowerA, Strip upperA,
 Property propertyB, Strip lowerB, Strip upperB) =>
(FullArray measA vertA horizA heightA widthA a
 -> FullArray measB vertB horizB heightB widthB b)
-> UnpackedMatrix
     propertyA lowerA upperA measA vertA horizA heightA widthA a
-> UnpackedMatrix
     propertyB lowerB upperB measB vertB horizB heightB widthB b
ArrMatrix.liftUnpacked1 FullArray measB vert horiz height fuse a
-> FullArray measB vert horiz height fuse a
forall a. a -> a
id Unpacked lowerB upperB measB vert horiz height fuse a
b) Quadratic typ xl xu lowerA upperA fuse a
q) IdentityMaes measA fuse width a
ident


type IdentityMaes meas =
         Matrix.QuadraticMeas Matrix.Identity () ()
            MatrixShape.Empty MatrixShape.Empty meas

factorIdentityLeft ::
   (Matrix.ToQuadratic typ, Extent.Measure meas) =>
   Matrix.QuadraticMeas typ xl xu lower upper meas height width a ->
   (IdentityMaes meas height width a,
    Matrix.Quadratic typ xl xu lower upper width a)
factorIdentityLeft :: QuadraticMeas typ xl xu lower upper meas height width a
-> (IdentityMaes meas height width a,
    Quadratic typ xl xu lower upper width a)
factorIdentityLeft QuadraticMeas typ xl xu lower upper meas height width a
a =
   (Extent meas Small Small height width
-> IdentityMaes meas height width a
forall meas height width a.
Measure meas =>
Extent meas Small Small height width
-> QuadraticMeas Identity () () Empty Empty meas height width a
Matrix.Identity (Extent meas Small Small height width
 -> IdentityMaes meas height width a)
-> Extent meas Small Small height width
-> IdentityMaes meas height width a
forall a b. (a -> b) -> a -> b
$ QuadraticMeas typ xl xu lower upper meas height width a
-> Extent meas Small Small height width
forall typ meas vert horiz xl xu lower upper height width a.
(Box typ, Measure meas, C vert, C horiz) =>
Matrix typ xl xu lower upper meas vert horiz height width a
-> Extent meas vert horiz height width
Matrix.extent QuadraticMeas typ xl xu lower upper meas height width a
a, QuadraticMeas typ xl xu lower upper meas height width a
-> Quadratic typ xl xu lower upper width a
forall typ meas xl xu lower upper height width a.
(ToQuadratic typ, Measure meas) =>
QuadraticMeas typ xl xu lower upper meas height width a
-> Quadratic typ xl xu lower upper width a
Matrix.widthToQuadratic QuadraticMeas typ xl xu lower upper meas height width a
a)

factorIdentityRight ::
   (Matrix.ToQuadratic typ, Extent.Measure meas) =>
   Matrix.QuadraticMeas typ xl xu lower upper meas height width a ->
   (Matrix.Quadratic typ xl xu lower upper height a,
    IdentityMaes meas height width a)
factorIdentityRight :: QuadraticMeas typ xl xu lower upper meas height width a
-> (Quadratic typ xl xu lower upper height a,
    IdentityMaes meas height width a)
factorIdentityRight QuadraticMeas typ xl xu lower upper meas height width a
a =
   (QuadraticMeas typ xl xu lower upper meas height width a
-> Quadratic typ xl xu lower upper height a
forall typ meas xl xu lower upper height width a.
(ToQuadratic typ, Measure meas) =>
QuadraticMeas typ xl xu lower upper meas height width a
-> Quadratic typ xl xu lower upper height a
Matrix.heightToQuadratic QuadraticMeas typ xl xu lower upper meas height width a
a, Extent meas Small Small height width
-> IdentityMaes meas height width a
forall meas height width a.
Measure meas =>
Extent meas Small Small height width
-> QuadraticMeas Identity () () Empty Empty meas height width a
Matrix.Identity (Extent meas Small Small height width
 -> IdentityMaes meas height width a)
-> Extent meas Small Small height width
-> IdentityMaes meas height width a
forall a b. (a -> b) -> a -> b
$ QuadraticMeas typ xl xu lower upper meas height width a
-> Extent meas Small Small height width
forall typ meas vert horiz xl xu lower upper height width a.
(Box typ, Measure meas, C vert, C horiz) =>
Matrix typ xl xu lower upper meas vert horiz height width a
-> Extent meas vert horiz height width
Matrix.extent QuadraticMeas typ xl xu lower upper meas height width a
a)

reshapeHeight ::
   (Extent.Measure measA, Extent.Measure measB, Extent.Measure measC,
    Extent.MultiplyMeasure measA measB ~ measC,
    Extent.C vert, Extent.C horiz, Eq fuse) =>
   IdentityMaes measA height fuse a ->
   Full measB vert horiz fuse width a ->
   Full measC vert horiz height width a
reshapeHeight :: IdentityMaes measA height fuse a
-> Full measB vert horiz fuse width a
-> Full measC vert horiz height width a
reshapeHeight (Matrix.Identity extentA) =
   (PlainArray
   Unpacked Arbitrary Filled Filled measB vert horiz fuse width a
 -> PlainArray
      Unpacked Arbitrary Filled Filled measC vert horiz height width a)
-> Full measB vert horiz fuse width a
-> Full measC vert horiz height width a
forall packA propA lowerA upperA measA vertA horizA heightA widthA
       packB propB lowerB upperB measB vertB horizB heightB widthB a b.
(ToPlain
   packA propA lowerA upperA measA vertA horizA heightA widthA,
 FromPlain
   packB propB lowerB upperB measB vertB horizB heightB widthB) =>
(PlainArray
   packA propA lowerA upperA measA vertA horizA heightA widthA a
 -> PlainArray
      packB propB lowerB upperB measB vertB horizB heightB widthB b)
-> ArrayMatrix
     packA propA lowerA upperA measA vertA horizA heightA widthA a
-> ArrayMatrix
     packB propB lowerB upperB measB vertB horizB heightB widthB b
ArrMatrix.lift1 ((PlainArray
    Unpacked Arbitrary Filled Filled measB vert horiz fuse width a
  -> PlainArray
       Unpacked Arbitrary Filled Filled measC vert horiz height width a)
 -> Full measB vert horiz fuse width a
 -> Full measC vert horiz height width a)
-> (PlainArray
      Unpacked Arbitrary Filled Filled measB vert horiz fuse width a
    -> PlainArray
         Unpacked Arbitrary Filled Filled measC vert horiz height width a)
-> Full measB vert horiz fuse width a
-> Full measC vert horiz height width a
forall a b. (a -> b) -> a -> b
$ (Extent measB vert horiz fuse width
 -> Extent measC vert horiz height width)
-> Full measB vert horiz fuse width a
-> Full measC vert horiz height width a
forall measA vertA horizA heightA widthA measB vertB horizB heightB
       widthB a.
(Extent measA vertA horizA heightA widthA
 -> Extent measB vertB horizB heightB widthB)
-> Full measA vertA horizA heightA widthA a
-> Full measB vertB horizB heightB widthB a
FullBasic.mapExtent ((Extent measB vert horiz fuse width
  -> Extent measC vert horiz height width)
 -> Full measB vert horiz fuse width a
 -> Full measC vert horiz height width a)
-> (Extent measB vert horiz fuse width
    -> Extent measC vert horiz height width)
-> Full measB vert horiz fuse width a
-> Full measC vert horiz height width a
forall a b. (a -> b) -> a -> b
$ \Extent measB vert horiz fuse width
extentB ->
      Extent measC vert horiz height width
-> Maybe (Extent measC vert horiz height width)
-> Extent measC vert horiz height width
forall a. a -> Maybe a -> a
fromMaybe (String -> Extent measC vert horiz height width
forall a. HasCallStack => String -> a
error String
"Multiply.reshapeHeight: shapes mismatch") (Maybe (Extent measC vert horiz height width)
 -> Extent measC vert horiz height width)
-> Maybe (Extent measC vert horiz height width)
-> Extent measC vert horiz height width
forall a b. (a -> b) -> a -> b
$
      Extent measC vert horiz height fuse
-> Extent measC vert horiz fuse width
-> Maybe (Extent measC vert horiz height width)
forall meas vert horiz fuse height width.
(Measure meas, C vert, C horiz, Eq fuse) =>
Extent meas vert horiz height fuse
-> Extent meas vert horiz fuse width
-> Maybe (Extent meas vert horiz height width)
Extent.fuse
         (Extent measA Small Small height fuse
-> Extent measB vert horiz fuse width
-> Extent
     (MultiplyMeasure measA measB)
     (Multiply Small vert)
     (Multiply Small horiz)
     height
     fuse
forall measA measB vertA horizA vertB horizB height fuse width.
(Measure measA, Measure measB, C vertA, C horizA, C vertB,
 C horizB) =>
Extent measA vertA horizA height fuse
-> Extent measB vertB horizB fuse width
-> Extent
     (MultiplyMeasure measA measB)
     (Multiply vertA vertB)
     (Multiply horizA horizB)
     height
     fuse
ExtentPriv.unifyLeft Extent measA Small Small height fuse
extentA Extent measB vert horiz fuse width
extentB)
         (Extent measA Small Small height fuse
-> Extent measB vert horiz fuse width
-> Extent measC vert horiz fuse width
forall measA measB measC vert horiz vertA horizA heightA widthA
       height width.
(Measure measA, Measure measB, MultiplyMeasure measA measB ~ measC,
 C vert, C horiz) =>
Extent measA vertA horizA heightA widthA
-> Extent measB vert horiz height width
-> Extent measC vert horiz height width
ExtentPriv.relaxMeasureWith Extent measA Small Small height fuse
extentA Extent measB vert horiz fuse width
extentB)

reshapeWidth ::
   (Extent.Measure measA, Extent.Measure measB, Extent.Measure measC,
    Extent.MultiplyMeasure measA measB ~ measC,
    Extent.C vert, Extent.C horiz, Eq fuse) =>
   Full measB vert horiz height fuse a ->
   IdentityMaes measA fuse width a ->
   Full measC vert horiz height width a
reshapeWidth :: Full measB vert horiz height fuse a
-> IdentityMaes measA fuse width a
-> Full measC vert horiz height width a
reshapeWidth = (IdentityMaes measA fuse width a
 -> Full measB vert horiz height fuse a
 -> Full measC vert horiz height width a)
-> Full measB vert horiz height fuse a
-> IdentityMaes measA fuse width a
-> Full measC vert horiz height width a
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((IdentityMaes measA fuse width a
  -> Full measB vert horiz height fuse a
  -> Full measC vert horiz height width a)
 -> Full measB vert horiz height fuse a
 -> IdentityMaes measA fuse width a
 -> Full measC vert horiz height width a)
-> (IdentityMaes measA fuse width a
    -> Full measB vert horiz height fuse a
    -> Full measC vert horiz height width a)
-> Full measB vert horiz height fuse a
-> IdentityMaes measA fuse width a
-> Full measC vert horiz height width a
forall a b. (a -> b) -> a -> b
$ \(Matrix.Identity extentA) ->
   (PlainArray
   Unpacked Arbitrary Filled Filled measB vert horiz height fuse a
 -> PlainArray
      Unpacked Arbitrary Filled Filled measC vert horiz height width a)
-> Full measB vert horiz height fuse a
-> Full measC vert horiz height width a
forall packA propA lowerA upperA measA vertA horizA heightA widthA
       packB propB lowerB upperB measB vertB horizB heightB widthB a b.
(ToPlain
   packA propA lowerA upperA measA vertA horizA heightA widthA,
 FromPlain
   packB propB lowerB upperB measB vertB horizB heightB widthB) =>
(PlainArray
   packA propA lowerA upperA measA vertA horizA heightA widthA a
 -> PlainArray
      packB propB lowerB upperB measB vertB horizB heightB widthB b)
-> ArrayMatrix
     packA propA lowerA upperA measA vertA horizA heightA widthA a
-> ArrayMatrix
     packB propB lowerB upperB measB vertB horizB heightB widthB b
ArrMatrix.lift1 ((PlainArray
    Unpacked Arbitrary Filled Filled measB vert horiz height fuse a
  -> PlainArray
       Unpacked Arbitrary Filled Filled measC vert horiz height width a)
 -> Full measB vert horiz height fuse a
 -> Full measC vert horiz height width a)
-> (PlainArray
      Unpacked Arbitrary Filled Filled measB vert horiz height fuse a
    -> PlainArray
         Unpacked Arbitrary Filled Filled measC vert horiz height width a)
-> Full measB vert horiz height fuse a
-> Full measC vert horiz height width a
forall a b. (a -> b) -> a -> b
$ (Extent measB vert horiz height fuse
 -> Extent measC vert horiz height width)
-> Full measB vert horiz height fuse a
-> Full measC vert horiz height width a
forall measA vertA horizA heightA widthA measB vertB horizB heightB
       widthB a.
(Extent measA vertA horizA heightA widthA
 -> Extent measB vertB horizB heightB widthB)
-> Full measA vertA horizA heightA widthA a
-> Full measB vertB horizB heightB widthB a
FullBasic.mapExtent ((Extent measB vert horiz height fuse
  -> Extent measC vert horiz height width)
 -> Full measB vert horiz height fuse a
 -> Full measC vert horiz height width a)
-> (Extent measB vert horiz height fuse
    -> Extent measC vert horiz height width)
-> Full measB vert horiz height fuse a
-> Full measC vert horiz height width a
forall a b. (a -> b) -> a -> b
$ \Extent measB vert horiz height fuse
extentB ->
      Extent measC vert horiz height width
-> Maybe (Extent measC vert horiz height width)
-> Extent measC vert horiz height width
forall a. a -> Maybe a -> a
fromMaybe (String -> Extent measC vert horiz height width
forall a. HasCallStack => String -> a
error String
"Multiply.reshapeWidth: shapes mismatch") (Maybe (Extent measC vert horiz height width)
 -> Extent measC vert horiz height width)
-> Maybe (Extent measC vert horiz height width)
-> Extent measC vert horiz height width
forall a b. (a -> b) -> a -> b
$
      Extent measC vert horiz height fuse
-> Extent measC vert horiz fuse width
-> Maybe (Extent measC vert horiz height width)
forall meas vert horiz fuse height width.
(Measure meas, C vert, C horiz, Eq fuse) =>
Extent meas vert horiz height fuse
-> Extent meas vert horiz fuse width
-> Maybe (Extent meas vert horiz height width)
Extent.fuse
         (Extent measA Small Small fuse width
-> Extent measB vert horiz height fuse
-> Extent measC vert horiz height fuse
forall measA measB measC vert horiz vertA horizA heightA widthA
       height width.
(Measure measA, Measure measB, MultiplyMeasure measA measB ~ measC,
 C vert, C horiz) =>
Extent measA vertA horizA heightA widthA
-> Extent measB vert horiz height width
-> Extent measC vert horiz height width
ExtentPriv.relaxMeasureWith Extent measA Small Small fuse width
extentA Extent measB vert horiz height fuse
extentB)
         (Extent measC horiz vert width fuse
-> Extent measC vert horiz fuse width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width
-> Extent meas horiz vert width height
Extent.transpose (Extent measC horiz vert width fuse
 -> Extent measC vert horiz fuse width)
-> Extent measC horiz vert width fuse
-> Extent measC vert horiz fuse width
forall a b. (a -> b) -> a -> b
$
          Extent measA Small Small width fuse
-> Extent measB horiz vert fuse height
-> Extent
     (MultiplyMeasure measA measB)
     (Multiply Small horiz)
     (Multiply Small vert)
     width
     fuse
forall measA measB vertA horizA vertB horizB height fuse width.
(Measure measA, Measure measB, C vertA, C horizA, C vertB,
 C horizB) =>
Extent measA vertA horizA height fuse
-> Extent measB vertB horizB fuse width
-> Extent
     (MultiplyMeasure measA measB)
     (Multiply vertA vertB)
     (Multiply horizA horizB)
     height
     fuse
ExtentPriv.unifyLeft
            (Extent measA Small Small fuse width
-> Extent measA Small Small width fuse
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width
-> Extent meas horiz vert width height
Extent.transpose Extent measA Small Small fuse width
extentA) (Extent measB vert horiz height fuse
-> Extent measB horiz vert fuse height
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width
-> Extent meas horiz vert width height
Extent.transpose Extent measB vert horiz height fuse
extentB))


instance (xl ~ (), xu ~ ()) => MultiplySquare Matrix.Scale xl xu where
   transposableSquare :: Transposition
-> Quadratic Scale xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
transposableSquare Transposition
_trans =
      String
-> (Full meas vert horiz height width a -> height)
-> (a
    -> Full meas vert horiz height width a
    -> Full meas vert horiz height width a)
-> Quadratic Scale xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
forall shape b a c xl xu lower upper meas vert horiz.
Eq shape =>
String
-> (b -> shape)
-> (a -> b -> c)
-> Matrix Scale xl xu lower upper meas vert horiz shape shape a
-> b
-> c
scaleWithCheck String
"Matrix.Multiply.transposableSquare" Full meas vert horiz height width a -> height
forall typ meas vert horiz xl xu lower upper height width a.
(Box typ, Measure meas, C vert, C horiz) =>
Matrix typ xl xu lower upper meas vert horiz height width a
-> height
Matrix.height ((a
  -> Full meas vert horiz height width a
  -> Full meas vert horiz height width a)
 -> Quadratic Scale xl xu lower upper height a
 -> Full meas vert horiz height width a
 -> Full meas vert horiz height width a)
-> (a
    -> Full meas vert horiz height width a
    -> Full meas vert horiz height width a)
-> Quadratic Scale xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
forall a b. (a -> b) -> a -> b
$
         (Array (Full meas vert horiz height width) a
 -> Array (Full meas vert horiz height width) a)
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
forall packA propA lowerA upperA measA vertA horizA heightA widthA
       packB propB lowerB upperB measB vertB horizB heightB widthB a b.
(ToPlain
   packA propA lowerA upperA measA vertA horizA heightA widthA,
 FromPlain
   packB propB lowerB upperB measB vertB horizB heightB widthB) =>
(PlainArray
   packA propA lowerA upperA measA vertA horizA heightA widthA a
 -> PlainArray
      packB propB lowerB upperB measB vertB horizB heightB widthB b)
-> ArrayMatrix
     packA propA lowerA upperA measA vertA horizA heightA widthA a
-> ArrayMatrix
     packB propB lowerB upperB measB vertB horizB heightB widthB b
ArrMatrix.lift1 ((Array (Full meas vert horiz height width) a
  -> Array (Full meas vert horiz height width) a)
 -> Full meas vert horiz height width a
 -> Full meas vert horiz height width a)
-> (a
    -> Array (Full meas vert horiz height width) a
    -> Array (Full meas vert horiz height width) a)
-> a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a
-> Array (Full meas vert horiz height width) a
-> Array (Full meas vert horiz height width) a
forall sh a. (C sh, Floating a) => a -> Vector sh a -> Vector sh a
Vector.scale

instance (xl ~ (), xu ~ ()) => MultiplySquare Matrix.Permutation xl xu where
   transposableSquare :: Transposition
-> Quadratic Permutation xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
transposableSquare =
      Inversion
-> FlexPermutation lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
forall meas vert horiz height width a lower upper.
(Measure meas, C vert, C horiz, C height, Eq height, C width,
 Floating a) =>
Inversion
-> FlexPermutation lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
PermMatrix.multiplyFull (Inversion
 -> FlexPermutation lower upper height a
 -> Full meas vert horiz height width a
 -> Full meas vert horiz height width a)
-> (Transposition -> Inversion)
-> Transposition
-> FlexPermutation lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transposition -> Inversion
Perm.inversionFromTransposition

instance
   (Layout.Packing pack, Omni.Property property, xl ~ (), xu ~ ()) =>
      MultiplySquare (ArrMatrix.Array pack property) xl xu where
   transposableSquare :: Transposition
-> Quadratic (Array pack property) xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
transposableSquare = Transposition
-> Quadratic (Array pack property) xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
forall pack property lower upper meas vert horiz height width a.
(Packing pack, Property property, Strip lower, Strip upper,
 Measure meas, C vert, C horiz, C height, Eq height, C width,
 Floating a) =>
Transposition
-> Quadratic pack property lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
Multiply.transposableSquare
   fullSquare :: Full meas vert horiz height width a
-> Quadratic (Array pack property) xl xu lower upper width a
-> Full meas vert horiz height width a
fullSquare = Full meas vert horiz height width a
-> Quadratic (Array pack property) xl xu lower upper width a
-> Full meas vert horiz height width a
forall pack property lower upper meas vert horiz height width a.
(Packing pack, Property property, Strip lower, Strip upper,
 Measure meas, C vert, C horiz, C height, C width, Eq width,
 Floating a) =>
Full meas vert horiz height width a
-> Quadratic pack property lower upper width a
-> Full meas vert horiz height width a
Multiply.fullSquare
   squareFull :: Quadratic (Array pack property) xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
squareFull = Quadratic (Array pack property) xl xu lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
forall pack property lower upper meas vert horiz height width a.
(Packing pack, Property property, Strip lower, Strip upper,
 Measure meas, C vert, C horiz, C height, Eq height, C width,
 Floating a) =>
Quadratic pack property lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
Multiply.squareFull


class (Matrix.Box typ) => Power typ xl xu where
   square ::
      (MatrixShape.PowerStrip lower, MatrixShape.PowerStrip upper) =>
      (Shape.C sh, Class.Floating a) =>
      Matrix.Quadratic typ xl xu lower upper sh a ->
      Matrix.Quadratic typ xl xu lower upper sh a
   power ::
      (MatrixShape.PowerStrip lower, MatrixShape.PowerStrip upper) =>
      (Shape.C sh, Class.Floating a) =>
      Integer ->
      Matrix.Quadratic typ xl xu lower upper sh a ->
      Matrix.Quadratic typ xl xu lower upper sh a
   powers1 ::
      (MatrixShape.PowerStrip lower, MatrixShape.PowerStrip upper) =>
      (Shape.C sh, Class.Floating a) =>
      Matrix.Quadratic typ xl xu lower upper sh a ->
      Stream (Matrix.Quadratic typ xl xu lower upper sh a)

instance (xl ~ (), xu ~ ()) => Power Matrix.Scale xl xu where
   square :: Quadratic Scale xl xu lower upper sh a
-> Quadratic Scale xl xu lower upper sh a
square (Matrix.Scale sh a) = sh -> a -> Quadratic Scale () () Empty Empty sh a
forall sh a. sh -> a -> Quadratic Scale () () Empty Empty sh a
Matrix.Scale sh
sh (a
aa -> a -> a
forall a. Num a => a -> a -> a
*a
a)
   power :: Integer
-> Quadratic Scale xl xu lower upper sh a
-> Quadratic Scale xl xu lower upper sh a
power Integer
n (Matrix.Scale sh a) = sh -> a -> Quadratic Scale () () Empty Empty sh a
forall sh a. sh -> a -> Quadratic Scale () () Empty Empty sh a
Matrix.Scale sh
sh (a
aa -> Integer -> a
forall a b. (Num a, Integral b) => a -> b -> a
^Integer
n)
   powers1 :: Quadratic Scale xl xu lower upper sh a
-> Stream (Quadratic Scale xl xu lower upper sh a)
powers1 (Matrix.Scale sh a) =
      (a -> Quadratic Scale () () Empty Empty sh a)
-> Stream a -> Stream (Quadratic Scale () () Empty Empty sh a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (sh -> a -> Quadratic Scale () () Empty Empty sh a
forall sh a. sh -> a -> Quadratic Scale () () Empty Empty sh a
Matrix.Scale sh
sh) (Stream a -> Stream (Quadratic Scale () () Empty Empty sh a))
-> Stream a -> Stream (Quadratic Scale () () Empty Empty sh a)
forall a b. (a -> b) -> a -> b
$ (a -> a) -> a -> Stream a
forall a. (a -> a) -> a -> Stream a
Stream.iterate (a -> a -> a
forall a. Num a => a -> a -> a
*a
a) a
a

instance (xl ~ (), xu ~ ()) => Power Matrix.Permutation xl xu where
   square :: Quadratic Permutation xl xu lower upper sh a
-> Quadratic Permutation xl xu lower upper sh a
square (Matrix.Permutation p) = Permutation sh -> Quadratic Permutation () () lower upper sh a
forall sh lower upper a.
Permutation sh -> Quadratic Permutation () () lower upper sh a
Matrix.Permutation (Permutation sh -> Quadratic Permutation () () lower upper sh a)
-> Permutation sh -> Quadratic Permutation () () lower upper sh a
forall a b. (a -> b) -> a -> b
$ Permutation sh -> Permutation sh
forall sh. C sh => Permutation sh -> Permutation sh
Perm.square Permutation sh
p
   power :: Integer
-> Quadratic Permutation xl xu lower upper sh a
-> Quadratic Permutation xl xu lower upper sh a
power Integer
n (Matrix.Permutation p) = Permutation sh -> Quadratic Permutation () () lower upper sh a
forall sh lower upper a.
Permutation sh -> Quadratic Permutation () () lower upper sh a
Matrix.Permutation (Permutation sh -> Quadratic Permutation () () lower upper sh a)
-> Permutation sh -> Quadratic Permutation () () lower upper sh a
forall a b. (a -> b) -> a -> b
$ Integer -> Permutation sh -> Permutation sh
forall sh. C sh => Integer -> Permutation sh -> Permutation sh
Perm.power Integer
n Permutation sh
p
   powers1 :: Quadratic Permutation xl xu lower upper sh a
-> Stream (Quadratic Permutation xl xu lower upper sh a)
powers1 (Matrix.Permutation p) =
      (Permutation sh -> Quadratic Permutation () () lower upper sh a)
-> Stream (Permutation sh)
-> Stream (Quadratic Permutation () () lower upper sh a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Permutation sh -> Quadratic Permutation () () lower upper sh a
forall sh lower upper a.
Permutation sh -> Quadratic Permutation () () lower upper sh a
Matrix.Permutation (Stream (Permutation sh)
 -> Stream (Quadratic Permutation () () lower upper sh a))
-> Stream (Permutation sh)
-> Stream (Quadratic Permutation () () lower upper sh a)
forall a b. (a -> b) -> a -> b
$ (Permutation sh -> Permutation sh)
-> Permutation sh -> Stream (Permutation sh)
forall a. (a -> a) -> a -> Stream a
Stream.iterate ((Permutation sh -> Permutation sh -> Permutation sh)
-> Permutation sh -> Permutation sh -> Permutation sh
forall a b c. (a -> b -> c) -> b -> a -> c
flip Permutation sh -> Permutation sh -> Permutation sh
forall sh.
C sh =>
Permutation sh -> Permutation sh -> Permutation sh
Perm.multiplyUnchecked Permutation sh
p) Permutation sh
p

instance
   (Layout.Packing pack, Omni.Property property, xl ~ (), xu ~ ()) =>
      Power (ArrMatrix.Array pack property) xl xu where
   square :: Quadratic (Array pack property) xl xu lower upper sh a
-> Quadratic (Array pack property) xl xu lower upper sh a
square = Quadratic (Array pack property) xl xu lower upper sh a
-> Quadratic (Array pack property) xl xu lower upper sh a
forall pack property lower upper sh a.
(Packing pack, Property property, PowerStrip lower,
 PowerStrip upper, C sh, Floating a) =>
Quadratic pack property lower upper sh a
-> Quadratic pack property lower upper sh a
Multiply.square
   power :: Integer
-> Quadratic (Array pack property) xl xu lower upper sh a
-> Quadratic (Array pack property) xl xu lower upper sh a
power = Integer
-> Quadratic (Array pack property) xl xu lower upper sh a
-> Quadratic (Array pack property) xl xu lower upper sh a
forall pack property lower upper sh a.
(Packing pack, Property property, PowerStrip lower,
 PowerStrip upper, C sh, Floating a) =>
Integer
-> Quadratic pack property lower upper sh a
-> Quadratic pack property lower upper sh a
Multiply.power
   powers1 :: Quadratic (Array pack property) xl xu lower upper sh a
-> Stream (Quadratic (Array pack property) xl xu lower upper sh a)
powers1 = Quadratic (Array pack property) xl xu lower upper sh a
-> Stream (Quadratic (Array pack property) xl xu lower upper sh a)
forall pack property lower upper sh a.
(Packing pack, Property property, PowerStrip lower,
 PowerStrip upper, C sh, Floating a) =>
Quadratic pack property lower upper sh a
-> Stream (Quadratic pack property lower upper sh a)
Multiply.powers1

powers ::
   (Power typ xl xu, MatrixClass.SquareShape typ) =>
   (MatrixShape.PowerStrip lower, MatrixShape.PowerStrip upper) =>
   (Shape.C sh, Class.Floating a) =>
   Matrix.Quadratic typ xl xu lower upper sh a ->
   Stream (Matrix.Quadratic typ xl xu lower upper sh a)
powers :: Quadratic typ xl xu lower upper sh a
-> Stream (Quadratic typ xl xu lower upper sh a)
powers Quadratic typ xl xu lower upper sh a
a = Quadratic typ xl xu lower upper sh a
-> Stream (Quadratic typ xl xu lower upper sh a)
-> Stream (Quadratic typ xl xu lower upper sh a)
forall a. a -> Stream a -> Stream a
Stream.Cons (Quadratic typ xl xu lower upper sh a
-> Quadratic typ xl xu lower upper sh a
forall typ sh a xl xu lower upper.
(SquareShape typ, C sh, Floating a) =>
Quadratic typ xl xu lower upper sh a
-> Quadratic typ xl xu lower upper sh a
MatrixClass.identityFrom Quadratic typ xl xu lower upper sh a
a) (Quadratic typ xl xu lower upper sh a
-> Stream (Quadratic typ xl xu lower upper sh a)
forall typ xl xu lower upper sh a.
(Power typ xl xu, PowerStrip lower, PowerStrip upper, C sh,
 Floating a) =>
Quadratic typ xl xu lower upper sh a
-> Stream (Quadratic typ xl xu lower upper sh a)
powers1 Quadratic typ xl xu lower upper sh a
a)


(#*#) ::
   (Matrix.Box typA, Omni.Strip lowerA, Omni.Strip upperA) =>
   (Matrix.Box typB, Omni.Strip lowerB, Omni.Strip upperB) =>
   (Matrix.Box typC, Omni.Strip lowerC, Omni.Strip upperC) =>
   (Multiply typA xlA xuA typB xlB xuB lowerC upperC measC) =>
   (Multiplied typA xlA xuA typB xlB xuB lowerC upperC measC ~ typC) =>
   (MultipliedExtra typA xlA xuA typB xlB xuB ~ xlC) =>
   (MultipliedExtra typA xuA xlA typB xuB xlB ~ xuC) =>
   (Omni.MultipliedStrip lowerA lowerB ~ lowerC) =>
   (Omni.MultipliedStrip lowerB lowerA ~ lowerC) =>
   (Omni.MultipliedStrip upperA upperB ~ upperC) =>
   (Omni.MultipliedStrip upperB upperA ~ upperC) =>
   (Omni.MultipliedBands lowerA lowerB ~ lowerC) =>
   (Omni.MultipliedBands lowerB lowerA ~ lowerC) =>
   (Omni.MultipliedBands upperA upperB ~ upperC) =>
   (Omni.MultipliedBands upperB upperA ~ upperC) =>
   (Extent.Measure measA, Extent.C vertA, Extent.C horizA) =>
   (Extent.Measure measB, Extent.C vertB, Extent.C horizB) =>
   (ExtentPriv.MultiplyMeasure measA measB ~ measC) =>
   (ExtentPriv.MultiplyMeasure measB measA ~ measC) =>
   (ExtentPriv.Multiply vertA  vertB  ~ vertC)  =>
   (ExtentPriv.Multiply vertB  vertA  ~ vertC)  =>
   (ExtentPriv.Multiply horizA horizB ~ horizC) =>
   (ExtentPriv.Multiply horizB horizA ~ horizC) =>
   (Shape.C height, Shape.C fuse, Eq fuse, Shape.C width) =>
   (Class.Floating a) =>
   Matrix typA xlA xuA lowerA upperA measA vertA horizA height fuse a ->
   Matrix typB xlB xuB lowerB upperB measB vertB horizB fuse width a ->
   Matrix typC xlC xuC lowerC upperC measC vertC horizC height width a
#*# :: Matrix typA xlA xuA lowerA upperA measA vertA horizA height fuse a
-> Matrix
     typB xlB xuB lowerB upperB measB vertB horizB fuse width a
-> Matrix
     typC xlC xuC lowerC upperC measC vertC horizC height width a
(#*#) = Matrix typA xlA xuA lowerA upperA measA vertA horizA height fuse a
-> Matrix
     typB xlB xuB lowerB upperB measB vertB horizB fuse width a
-> Matrix
     typC xlC xuC lowerC upperC measC vertC horizC height width a
forall typA xlA xuA typB xlB xuB lowerC upperC measC lowerA upperA
       lowerB upperB typC xlC xuC measA vertA horizA measB vertB horizB
       vertC horizC height fuse width a.
(Multiply typA xlA xuA typB xlB xuB lowerC upperC measC, Box typA,
 Strip lowerA, Strip upperA, Box typB, Strip lowerB, Strip upperB,
 Box typC, Strip lowerC, Strip upperC,
 Multiplied typA xlA xuA typB xlB xuB lowerC upperC measC ~ typC,
 MultipliedExtra typA xlA xuA typB xlB xuB ~ xlC,
 MultipliedExtra typA xuA xlA typB xuB xlB ~ xuC,
 MultipliedStrip lowerA lowerB ~ lowerC,
 MultipliedStrip lowerB lowerA ~ lowerC,
 MultipliedStrip upperA upperB ~ upperC,
 MultipliedStrip upperB upperA ~ upperC,
 MultipliedBands lowerA lowerB ~ lowerC,
 MultipliedBands lowerB lowerA ~ lowerC,
 MultipliedBands upperA upperB ~ upperC,
 MultipliedBands upperB upperA ~ upperC, Measure measA, C vertA,
 C horizA, Measure measB, C vertB, C horizB,
 MultiplyMeasure measA measB ~ measC,
 MultiplyMeasure measB measA ~ measC, Multiply vertA vertB ~ vertC,
 Multiply vertB vertA ~ vertC, Multiply horizA horizB ~ horizC,
 Multiply horizB horizA ~ horizC, C height, C fuse, Eq fuse,
 C width, Floating a) =>
Matrix typA xlA xuA lowerA upperA measA vertA horizA height fuse a
-> Matrix
     typB xlB xuB lowerB upperB measB vertB horizB fuse width a
-> Matrix
     typC xlC xuC lowerC upperC measC vertC horizC height width a
matrixMatrix

class
   (Matrix.Box typA, Matrix.Box typB) =>
      Multiply typA xlA xuA typB xlB xuB lowerC upperC measC where
   type Multiplied typA xlA xuA typB xlB xuB lowerC upperC measC
   type MultipliedExtra typA xlA xuA typB xlB xuB
   matrixMatrix ::
      (Matrix.Box typA, Omni.Strip lowerA, Omni.Strip upperA) =>
      (Matrix.Box typB, Omni.Strip lowerB, Omni.Strip upperB) =>
      (Matrix.Box typC, Omni.Strip lowerC, Omni.Strip upperC) =>
      (Multiplied typA xlA xuA typB xlB xuB lowerC upperC measC ~ typC) =>
      (MultipliedExtra typA xlA xuA typB xlB xuB ~ xlC) =>
      (MultipliedExtra typA xuA xlA typB xuB xlB ~ xuC) =>
      (Omni.MultipliedStrip lowerA lowerB ~ lowerC) =>
      (Omni.MultipliedStrip lowerB lowerA ~ lowerC) =>
      (Omni.MultipliedStrip upperA upperB ~ upperC) =>
      (Omni.MultipliedStrip upperB upperA ~ upperC) =>
      (Omni.MultipliedBands lowerA lowerB ~ lowerC) =>
      (Omni.MultipliedBands lowerB lowerA ~ lowerC) =>
      (Omni.MultipliedBands upperA upperB ~ upperC) =>
      (Omni.MultipliedBands upperB upperA ~ upperC) =>
      (Extent.Measure measA, Extent.C vertA, Extent.C horizA) =>
      (Extent.Measure measB, Extent.C vertB, Extent.C horizB) =>
      (ExtentPriv.MultiplyMeasure measA measB ~ measC) =>
      (ExtentPriv.MultiplyMeasure measB measA ~ measC) =>
      (ExtentPriv.Multiply vertA  vertB  ~ vertC)  =>
      (ExtentPriv.Multiply vertB  vertA  ~ vertC)  =>
      (ExtentPriv.Multiply horizA horizB ~ horizC) =>
      (ExtentPriv.Multiply horizB horizA ~ horizC) =>
      (Shape.C height, Shape.C fuse, Eq fuse, Shape.C width) =>
      (Class.Floating a) =>
      Matrix typA xlA xuA lowerA upperA measA vertA horizA height fuse a ->
      Matrix typB xlB xuB lowerB upperB measB vertB horizB fuse width a ->
      Matrix typC xlC xuC lowerC upperC measC vertC horizC height width a

instance
   (Layout.Packing packA, Omni.Property propertyA, xlA ~ (), xuA ~ (),
    Layout.Packing packB, Omni.Property propertyB, xlB ~ (), xuB ~ (),
    Layout.Packing packC, Omni.Property propertyC,
    Multiply.MultipliedPacking packA packB ~ pack,
    Multiply.MultipliedPacking packB packA ~ pack,
    Omni.MultipliedProperty propertyA propertyB ~ propertyAB,
    Omni.MultipliedProperty propertyB propertyA ~ propertyAB,
    Omni.UnitIfTriangular lowerC upperC ~ diag,
    Omni.UnitIfTriangular upperC lowerC ~ diag,
    Multiply.PackingByStrip lowerC upperC measC pack ~ packC,
    Multiply.PackingByStrip upperC lowerC measC pack ~ packC,
    Omni.MergeUnit propertyAB diag ~ propertyC,
    Omni.MergeUnit diag propertyAB ~ propertyC) =>
      Multiply
         (ArrMatrix.Array packA propertyA) xlA xuA
         (ArrMatrix.Array packB propertyB) xlB xuB
         lowerC upperC measC where
   type Multiplied
            (ArrMatrix.Array packA propertyA) xlA xuA
            (ArrMatrix.Array packB propertyB) xlB xuB
            lowerC upperC measC =
         ArrMatrix.Array
            (Multiply.PackingByStrip lowerC upperC measC
               (Multiply.MultipliedPacking packA packB))
            (Omni.MergeUnit
               (Omni.MultipliedProperty propertyA propertyB)
               (Omni.UnitIfTriangular lowerC upperC))
   type MultipliedExtra
            (ArrMatrix.Array packA propertyA) xlA xuA
            (ArrMatrix.Array packB propertyB) xlB xuB = ()
   matrixMatrix :: Matrix
  (Array packA propertyA)
  xlA
  xuA
  lowerA
  upperA
  measA
  vertA
  horizA
  height
  fuse
  a
-> Matrix
     (Array packB propertyB)
     xlB
     xuB
     lowerB
     upperB
     measB
     vertB
     horizB
     fuse
     width
     a
-> Matrix
     typC xlC xuC lowerC upperC measC vertC horizC height width a
matrixMatrix = Matrix
  (Array packA propertyA)
  xlA
  xuA
  lowerA
  upperA
  measA
  vertA
  horizA
  height
  fuse
  a
-> Matrix
     (Array packB propertyB)
     xlB
     xuB
     lowerB
     upperB
     measB
     vertB
     horizB
     fuse
     width
     a
-> Matrix
     typC xlC xuC lowerC upperC measC vertC horizC height width a
forall packA propertyA packB propertyB packC propertyC lowerA
       upperA lowerB upperB lowerC upperC pack propertyAB diag measC measA
       vertA horizA measB vertB horizB vertC horizC height fuse width a.
(Packing packA, Property propertyA, Packing packB,
 Property propertyB, Packing packC, Property propertyC,
 Strip lowerA, Strip upperA, Strip lowerB, Strip upperB,
 Strip lowerC, Strip upperC, MultipliedPacking packA packB ~ pack,
 MultipliedPacking packB packA ~ pack,
 MultipliedStrip lowerA lowerB ~ lowerC,
 MultipliedStrip lowerB lowerA ~ lowerC,
 MultipliedStrip upperA upperB ~ upperC,
 MultipliedStrip upperB upperA ~ upperC,
 MultipliedBands lowerA lowerB ~ lowerC,
 MultipliedBands lowerB lowerA ~ lowerC,
 MultipliedBands upperA upperB ~ upperC,
 MultipliedBands upperB upperA ~ upperC,
 MultipliedProperty propertyA propertyB ~ propertyAB,
 MultipliedProperty propertyB propertyA ~ propertyAB,
 UnitIfTriangular lowerC upperC ~ diag,
 UnitIfTriangular upperC lowerC ~ diag,
 MergeUnit propertyAB diag ~ propertyC,
 MergeUnit diag propertyAB ~ propertyC,
 PackingByStrip lowerC upperC measC pack ~ packC,
 PackingByStrip upperC lowerC measC pack ~ packC, Measure measA,
 C vertA, C horizA, Measure measB, C vertB, C horizB,
 MultiplyMeasure measA measB ~ measC,
 MultiplyMeasure measB measA ~ measC, Multiply vertA vertB ~ vertC,
 Multiply vertB vertA ~ vertC, Multiply horizA horizB ~ horizC,
 Multiply horizB horizA ~ horizC, C height, C fuse, Eq fuse,
 C width, Floating a) =>
ArrayMatrix
  packA propertyA lowerA upperA measA vertA horizA height fuse a
-> ArrayMatrix
     packB propertyB lowerB upperB measB vertB horizB fuse width a
-> ArrayMatrix
     packC propertyC lowerC upperC measC vertC horizC height width a
Multiply.matrixMatrix


instance
   (xlA ~ (), xuA ~ (), xlB ~ (), xuB ~ (),
    lowerC ~ MatrixShape.Empty, upperC ~ MatrixShape.Empty) =>
      Multiply Matrix.Scale xlA xuA Matrix.Scale xlB xuB lowerC upperC measC
         where
   type Multiplied
            Matrix.Scale xlA xuA Matrix.Scale xlB xuB lowerC upperC measC =
               Matrix.Scale
   type MultipliedExtra Matrix.Scale xlA xuA Matrix.Scale xlB xuB = ()
   matrixMatrix :: Matrix Scale xlA xuA lowerA upperA measA vertA horizA height fuse a
-> Matrix
     Scale xlB xuB lowerB upperB measB vertB horizB fuse width a
-> Matrix
     typC xlC xuC lowerC upperC measC vertC horizC height width a
matrixMatrix a :: Matrix Scale xlA xuA lowerA upperA measA vertA horizA height fuse a
a@(Matrix.Scale _ _) b :: Matrix Scale xlB xuB lowerB upperB measB vertB horizB fuse width a
b@(Matrix.Scale _ _) =
      Matrix Scale xlA xuA lowerA upperA measA vertA horizA height fuse a
-> Matrix
     Scale xlA xuA lowerA upperA measA vertA horizA height fuse a
-> Matrix
     Scale xlA xuA lowerA upperA measA vertA horizA height fuse a
forall typ xl xu matrix lower upper meas vert horiz sh a.
(MultiplySame typ xl xu,
 matrix ~ Matrix typ xl xu lower upper meas vert horiz sh sh a,
 PowerStrip lower, PowerStrip upper, Measure meas, C vert, C horiz,
 C sh, Eq sh, Floating a) =>
matrix -> matrix -> matrix
Matrix.multiplySame Matrix Scale xlA xuA lowerA upperA measA vertA horizA height fuse a
a Matrix Scale xlA xuA lowerA upperA measA vertA horizA height fuse a
Matrix Scale xlB xuB lowerB upperB measB vertB horizB fuse width a
b

instance
   (ArrMatrix.Scale property, xlA ~ (), xuA ~ (), xlB ~ (), xuB ~ ()) =>
      Multiply Matrix.Scale xlA xuA (ArrMatrix.Array pack property) xlB xuB
            lowerC upperC measC
         where
   type Multiplied Matrix.Scale xlA xuA (ArrMatrix.Array pack property) xlB xuB
            lowerC upperC measC
         = ArrMatrix.Array pack property
   type MultipliedExtra
            Matrix.Scale xlA xuA (ArrMatrix.Array pack property) xlB xuB = ()
   matrixMatrix :: Matrix Scale xlA xuA lowerA upperA measA vertA horizA height fuse a
-> Matrix
     (Array pack property)
     xlB
     xuB
     lowerB
     upperB
     measB
     vertB
     horizB
     fuse
     width
     a
-> Matrix
     typC xlC xuC lowerC upperC measC vertC horizC height width a
matrixMatrix a :: Matrix Scale xlA xuA lowerA upperA measA vertA horizA height fuse a
a@(Matrix.Scale _ _) =
      String
-> (Matrix
      (Array pack property)
      ()
      ()
      lowerC
      upperC
      measC
      vertC
      horizC
      height
      width
      a
    -> height)
-> (a
    -> Matrix
         (Array pack property)
         ()
         ()
         lowerC
         upperC
         measC
         vertC
         horizC
         height
         width
         a
    -> Matrix
         (Array pack property)
         ()
         ()
         lowerC
         upperC
         measC
         vertC
         horizC
         height
         width
         a)
-> Matrix
     Scale xlA xuA lowerA upperA measA vertA horizA height height a
-> Matrix
     (Array pack property)
     ()
     ()
     lowerC
     upperC
     measC
     vertC
     horizC
     height
     width
     a
-> Matrix
     (Array pack property)
     ()
     ()
     lowerC
     upperC
     measC
     vertC
     horizC
     height
     width
     a
forall shape b a c xl xu lower upper meas vert horiz.
Eq shape =>
String
-> (b -> shape)
-> (a -> b -> c)
-> Matrix Scale xl xu lower upper meas vert horiz shape shape a
-> b
-> c
scaleWithCheck String
"Matrix.Multiply.multiply Scale" Matrix
  (Array pack property)
  ()
  ()
  lowerC
  upperC
  measC
  vertC
  horizC
  height
  width
  a
-> height
forall typ meas vert horiz xl xu lower upper height width a.
(Box typ, Measure meas, C vert, C horiz) =>
Matrix typ xl xu lower upper meas vert horiz height width a
-> height
Matrix.height
         a
-> Matrix
     (Array pack property)
     ()
     ()
     lowerC
     upperC
     measC
     vertC
     horizC
     height
     width
     a
-> Matrix
     (Array pack property)
     ()
     ()
     lowerC
     upperC
     measC
     vertC
     horizC
     height
     width
     a
forall meas vert horiz property height width a pack lower upper.
(Measure meas, C vert, C horiz, Scale property, C height, C width,
 Floating a) =>
a
-> ArrayMatrix
     pack property lower upper meas vert horiz height width a
-> ArrayMatrix
     pack property lower upper meas vert horiz height width a
ArrMatrix.scale Matrix
  Scale xlA xuA lowerA upperA measA vertA horizA height height a
Matrix Scale xlA xuA lowerA upperA measA vertA horizA height fuse a
a

instance
   (ArrMatrix.Scale property, xlA ~ (), xuA ~ (), xlB ~ (), xuB ~ ()) =>
      Multiply (ArrMatrix.Array pack property) xlA xuA Matrix.Scale xlB xuB
            lowerC upperC measC
         where
   type Multiplied (ArrMatrix.Array pack property) xlA xuA Matrix.Scale xlB xuB
            lowerC upperC measC
         = ArrMatrix.Array pack property
   type MultipliedExtra
            (ArrMatrix.Array pack property) xlA xuA Matrix.Scale xlB xuB = ()
   matrixMatrix :: Matrix
  (Array pack property)
  xlA
  xuA
  lowerA
  upperA
  measA
  vertA
  horizA
  height
  fuse
  a
-> Matrix
     Scale xlB xuB lowerB upperB measB vertB horizB fuse width a
-> Matrix
     typC xlC xuC lowerC upperC measC vertC horizC height width a
matrixMatrix = (Matrix Scale xlB xuB lowerB upperB measB vertB horizB fuse width a
 -> Matrix
      (Array pack property)
      xlA
      xuA
      lowerA
      upperA
      measA
      vertA
      horizA
      height
      fuse
      a
 -> Matrix
      typC xlC xuC lowerC upperC measC vertC horizC height width a)
-> Matrix
     (Array pack property)
     xlA
     xuA
     lowerA
     upperA
     measA
     vertA
     horizA
     height
     fuse
     a
-> Matrix
     Scale xlB xuB lowerB upperB measB vertB horizB fuse width a
-> Matrix
     typC xlC xuC lowerC upperC measC vertC horizC height width a
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Matrix
    Scale xlB xuB lowerB upperB measB vertB horizB fuse width a
  -> Matrix
       (Array pack property)
       xlA
       xuA
       lowerA
       upperA
       measA
       vertA
       horizA
       height
       fuse
       a
  -> Matrix
       typC xlC xuC lowerC upperC measC vertC horizC height width a)
 -> Matrix
      (Array pack property)
      xlA
      xuA
      lowerA
      upperA
      measA
      vertA
      horizA
      height
      fuse
      a
 -> Matrix
      Scale xlB xuB lowerB upperB measB vertB horizB fuse width a
 -> Matrix
      typC xlC xuC lowerC upperC measC vertC horizC height width a)
-> (Matrix
      Scale xlB xuB lowerB upperB measB vertB horizB fuse width a
    -> Matrix
         (Array pack property)
         xlA
         xuA
         lowerA
         upperA
         measA
         vertA
         horizA
         height
         fuse
         a
    -> Matrix
         typC xlC xuC lowerC upperC measC vertC horizC height width a)
-> Matrix
     (Array pack property)
     xlA
     xuA
     lowerA
     upperA
     measA
     vertA
     horizA
     height
     fuse
     a
-> Matrix
     Scale xlB xuB lowerB upperB measB vertB horizB fuse width a
-> Matrix
     typC xlC xuC lowerC upperC measC vertC horizC height width a
forall a b. (a -> b) -> a -> b
$ \b :: Matrix Scale xlB xuB lowerB upperB measB vertB horizB fuse width a
b@(Matrix.Scale _ _) a :: Matrix
  (Array pack property)
  xlA
  xuA
  lowerA
  upperA
  measA
  vertA
  horizA
  height
  fuse
  a
a@(ArrMatrix.Array _) ->
      String
-> (Matrix
      (Array pack property)
      ()
      ()
      lowerC
      upperC
      measC
      vertA
      horizA
      height
      fuse
      a
    -> fuse)
-> (a
    -> Matrix
         (Array pack property)
         ()
         ()
         lowerC
         upperC
         measC
         vertA
         horizA
         height
         fuse
         a
    -> Matrix
         (Array pack property)
         ()
         ()
         lowerC
         upperC
         measC
         vertA
         horizA
         height
         fuse
         a)
-> Matrix
     Scale xlB xuB lowerB upperB measB vertB horizB fuse fuse a
-> Matrix
     (Array pack property)
     ()
     ()
     lowerC
     upperC
     measC
     vertA
     horizA
     height
     fuse
     a
-> Matrix
     (Array pack property)
     ()
     ()
     lowerC
     upperC
     measC
     vertA
     horizA
     height
     fuse
     a
forall shape b a c xl xu lower upper meas vert horiz.
Eq shape =>
String
-> (b -> shape)
-> (a -> b -> c)
-> Matrix Scale xl xu lower upper meas vert horiz shape shape a
-> b
-> c
scaleWithCheck String
"Matrix.Multiply.multiply Scale" Matrix
  (Array pack property)
  ()
  ()
  lowerC
  upperC
  measC
  vertA
  horizA
  height
  fuse
  a
-> fuse
forall typ meas vert horiz xl xu lower upper height width a.
(Box typ, Measure meas, C vert, C horiz) =>
Matrix typ xl xu lower upper meas vert horiz height width a
-> width
Matrix.width
         a
-> Matrix
     (Array pack property)
     ()
     ()
     lowerC
     upperC
     measC
     vertA
     horizA
     height
     fuse
     a
-> Matrix
     (Array pack property)
     ()
     ()
     lowerC
     upperC
     measC
     vertA
     horizA
     height
     fuse
     a
forall meas vert horiz property height width a pack lower upper.
(Measure meas, C vert, C horiz, Scale property, C height, C width,
 Floating a) =>
a
-> ArrayMatrix
     pack property lower upper meas vert horiz height width a
-> ArrayMatrix
     pack property lower upper meas vert horiz height width a
ArrMatrix.scale Matrix Scale xlB xuB lowerB upperB measB vertB horizB fuse fuse a
Matrix Scale xlB xuB lowerB upperB measB vertB horizB fuse width a
b Matrix
  (Array pack property)
  xlA
  xuA
  lowerA
  upperA
  measA
  vertA
  horizA
  height
  fuse
  a
Matrix
  (Array pack property)
  ()
  ()
  lowerC
  upperC
  measC
  vertA
  horizA
  height
  fuse
  a
a


instance
   (xlA ~ (), xuA ~ (), xlB ~ (), xuB ~ ()) =>
      Multiply Matrix.Permutation xlA xuA Matrix.Permutation xlB xuB
         lowerC upperC measC where
   type Multiplied Matrix.Permutation xlA xuA Matrix.Permutation xlB xuB
            lowerC upperC measC  =  Matrix.Permutation
   type MultipliedExtra
            Matrix.Permutation xlA xuA Matrix.Permutation xlB xuB = ()
   matrixMatrix :: Matrix
  Permutation xlA xuA lowerA upperA measA vertA horizA height fuse a
-> Matrix
     Permutation xlB xuB lowerB upperB measB vertB horizB fuse width a
-> Matrix
     typC xlC xuC lowerC upperC measC vertC horizC height width a
matrixMatrix (Matrix.Permutation a) (Matrix.Permutation b) =
      Permutation fuse
-> Quadratic Permutation () () lowerC upperC fuse a
forall sh lower upper a.
Permutation sh -> Quadratic Permutation () () lower upper sh a
Matrix.Permutation (Permutation fuse
 -> Quadratic Permutation () () lowerC upperC fuse a)
-> Permutation fuse
-> Quadratic Permutation () () lowerC upperC fuse a
forall a b. (a -> b) -> a -> b
$ Permutation fuse -> Permutation fuse -> Permutation fuse
forall sh.
(C sh, Eq sh) =>
Permutation sh -> Permutation sh -> Permutation sh
Perm.multiply Permutation fuse
b Permutation height
Permutation fuse
a