{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE GADTs #-}
module Numeric.LAPACK.Matrix.Layout.Private (
   module Numeric.LAPACK.Matrix.Layout.Private,
   module Numeric.BLAS.Matrix.Layout,
   ) where

import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent
import Numeric.LAPACK.Matrix.Extent.Private (Extent)
import Numeric.BLAS.Matrix.Layout (Order(..), flipOrder, transposeFromOrder)

import qualified Type.Data.Num.Unary.Literal as TypeNum
import qualified Type.Data.Num.Unary.Proof as Proof
import qualified Type.Data.Num.Unary as Unary
import Type.Data.Num.Unary (unary, (:+:))
import Type.Data.Num (integralFromProxy)
import Type.Base.Proxy (Proxy(Proxy))

import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Shape (triangleSize, triangleRoot)

import Control.DeepSeq (NFData, rnf)
import Control.Applicative ((<$>))

import Data.List (tails)
import Data.Tuple.HT (mapSnd, swap)
import Data.Bool.HT (if')


swapOnRowMajor :: Order -> (a,a) -> (a,a)
swapOnRowMajor :: forall a. Order -> (a, a) -> (a, a)
swapOnRowMajor Order
order =
   case Order
order of
      Order
RowMajor -> (a, a) -> (a, a)
forall a b. (a, b) -> (b, a)
swap
      Order
ColumnMajor -> (a, a) -> (a, a)
forall a. a -> a
id

sideSwapFromOrder :: Order -> (a,a) -> (Char, (a,a))
sideSwapFromOrder :: forall a. Order -> (a, a) -> (Char, (a, a))
sideSwapFromOrder Order
order (a
m0,a
n0) =
   let ((Char
side,a
m), (Char
_,a
n)) = Order -> ((Char, a), (Char, a)) -> ((Char, a), (Char, a))
forall a. Order -> (a, a) -> (a, a)
swapOnRowMajor Order
order ((Char
'L', a
m0), (Char
'R', a
n0))
   in (Char
side,(a
m,a
n))


mapChecked ::
   (Shape.C sha, Shape.C shb) =>
   String -> (sha -> shb) -> sha -> shb
mapChecked :: forall sha shb.
(C sha, C shb) =>
String -> (sha -> shb) -> sha -> shb
mapChecked String
name sha -> shb
f sha
sizeA =
   let sizeB :: shb
sizeB = sha -> shb
f sha
sizeA
   in if sha -> Int
forall sh. C sh => sh -> Int
Shape.size sha
sizeA Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== shb -> Int
forall sh. C sh => sh -> Int
Shape.size shb
sizeB
         then shb
sizeB
         else String -> shb
forall a. HasCallStack => String -> a
error (String -> shb) -> String -> shb
forall a b. (a -> b) -> a -> b
$ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": sizes mismatch"


data Full meas vert horiz height width =
   Full {
      forall meas vert horiz height width.
Full meas vert horiz height width -> Order
fullOrder :: Order,
      forall meas vert horiz height width.
Full meas vert horiz height width
-> Extent meas vert horiz height width
fullExtent :: Extent meas vert horiz height width
   } deriving (Full meas vert horiz height width
-> Full meas vert horiz height width -> Bool
(Full meas vert horiz height width
 -> Full meas vert horiz height width -> Bool)
-> (Full meas vert horiz height width
    -> Full meas vert horiz height width -> Bool)
-> Eq (Full meas vert horiz height width)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Eq height, Eq width) =>
Full meas vert horiz height width
-> Full meas vert horiz height width -> Bool
$c== :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Eq height, Eq width) =>
Full meas vert horiz height width
-> Full meas vert horiz height width -> Bool
== :: Full meas vert horiz height width
-> Full meas vert horiz height width -> Bool
$c/= :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Eq height, Eq width) =>
Full meas vert horiz height width
-> Full meas vert horiz height width -> Bool
/= :: Full meas vert horiz height width
-> Full meas vert horiz height width -> Bool
Eq, Int -> Full meas vert horiz height width -> String -> String
[Full meas vert horiz height width] -> String -> String
Full meas vert horiz height width -> String
(Int -> Full meas vert horiz height width -> String -> String)
-> (Full meas vert horiz height width -> String)
-> ([Full meas vert horiz height width] -> String -> String)
-> Show (Full meas vert horiz height width)
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
Int -> Full meas vert horiz height width -> String -> String
forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
[Full meas vert horiz height width] -> String -> String
forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
Full meas vert horiz height width -> String
$cshowsPrec :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
Int -> Full meas vert horiz height width -> String -> String
showsPrec :: Int -> Full meas vert horiz height width -> String -> String
$cshow :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
Full meas vert horiz height width -> String
show :: Full meas vert horiz height width -> String
$cshowList :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
[Full meas vert horiz height width] -> String -> String
showList :: [Full meas vert horiz height width] -> String -> String
Show)

instance
   (Extent.Measure meas, Extent.C vert, Extent.C horiz,
    NFData height, NFData width) =>
      NFData (Full meas vert horiz height width) where
   rnf :: Full meas vert horiz height width -> ()
rnf (Full Order
order Extent meas vert horiz height width
extent) = (Order, Extent meas vert horiz height width) -> ()
forall a. NFData a => a -> ()
rnf (Order
order, Extent meas vert horiz height width
extent)

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

   size :: Full meas vert horiz height width -> Int
size (Full Order
_ Extent meas vert horiz height width
extent) = (height, width) -> Int
forall sh. C sh => sh -> Int
Shape.size (Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent)

instance
   (Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.Indexed height, Shape.Indexed width) =>
      Shape.Indexed (Full meas vert horiz height width) where

   type Index (Full meas vert horiz height width) =
            (Shape.Index height, Shape.Index width)
   indices :: Full meas vert horiz height width
-> [Index (Full meas vert horiz height width)]
indices (Full Order
order Extent meas vert horiz height width
extent) = Order
-> Extent meas vert horiz height width
-> [(Index height, Index width)]
forall meas vert horiz a b.
(Measure meas, C vert, C horiz, Indexed a, Indexed b) =>
Order -> Extent meas vert horiz a b -> [(Index a, Index b)]
fullIndices Order
order Extent meas vert horiz height width
extent

   unifiedOffset :: forall check.
Checking check =>
Full meas vert horiz height width
-> Index (Full meas vert horiz height width) -> Result check Int
unifiedOffset (Full Order
RowMajor Extent meas vert horiz height width
extent) =
      (height, width) -> Index (height, width) -> Result check Int
forall sh check.
(Indexed sh, Checking check) =>
sh -> Index sh -> Result check Int
forall check.
Checking check =>
(height, width) -> Index (height, width) -> Result check Int
Shape.unifiedOffset (Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent)
   unifiedOffset (Full Order
ColumnMajor Extent meas vert horiz height width
extent) =
      (width, height) -> Index (width, height) -> Result check Int
forall sh check.
(Indexed sh, Checking check) =>
sh -> Index sh -> Result check Int
forall check.
Checking check =>
(width, height) -> Index (width, height) -> Result check Int
Shape.unifiedOffset ((height, width) -> (width, height)
forall a b. (a, b) -> (b, a)
swap ((height, width) -> (width, height))
-> (height, width) -> (width, height)
forall a b. (a -> b) -> a -> b
$ Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent) ((Index width, Index height) -> Result check Int)
-> ((Index height, Index width) -> (Index width, Index height))
-> (Index height, Index width)
-> Result check Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Index height, Index width) -> (Index width, Index height)
forall a b. (a, b) -> (b, a)
swap

   unifiedSizeOffset :: forall check.
Checking check =>
Full meas vert horiz height width
-> (Int,
    Index (Full meas vert horiz height width) -> Result check Int)
unifiedSizeOffset (Full Order
RowMajor Extent meas vert horiz height width
extent) =
      (height, width) -> (Int, Index (height, width) -> Result check Int)
forall sh check.
(Indexed sh, Checking check) =>
sh -> (Int, Index sh -> Result check Int)
forall check.
Checking check =>
(height, width) -> (Int, Index (height, width) -> Result check Int)
Shape.unifiedSizeOffset (Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent)
   unifiedSizeOffset (Full Order
ColumnMajor Extent meas vert horiz height width
extent) =
      (((Index width, Index height) -> Result check Int)
 -> Index (Full meas vert horiz height width) -> Result check Int)
-> (Int, (Index width, Index height) -> Result check Int)
-> (Int,
    Index (Full meas vert horiz height width) -> Result check Int)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd (((Index width, Index height) -> Result check Int)
-> (Index (Full meas vert horiz height width)
    -> (Index width, Index height))
-> Index (Full meas vert horiz height width)
-> Result check Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Index height, Index width) -> (Index width, Index height)
Index (Full meas vert horiz height width)
-> (Index width, Index height)
forall a b. (a, b) -> (b, a)
swap) ((Int, (Index width, Index height) -> Result check Int)
 -> (Int,
     Index (Full meas vert horiz height width) -> Result check Int))
-> (Int, (Index width, Index height) -> Result check Int)
-> (Int,
    Index (Full meas vert horiz height width) -> Result check Int)
forall a b. (a -> b) -> a -> b
$
      (width, height) -> (Int, Index (width, height) -> Result check Int)
forall sh check.
(Indexed sh, Checking check) =>
sh -> (Int, Index sh -> Result check Int)
forall check.
Checking check =>
(width, height) -> (Int, Index (width, height) -> Result check Int)
Shape.unifiedSizeOffset ((height, width) -> (width, height)
forall a b. (a, b) -> (b, a)
swap ((height, width) -> (width, height))
-> (height, width) -> (width, height)
forall a b. (a -> b) -> a -> b
$ Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent)

   inBounds :: Full meas vert horiz height width
-> Index (Full meas vert horiz height width) -> Bool
inBounds (Full Order
_ Extent meas vert horiz height width
extent) = (height, width) -> Index (height, width) -> Bool
forall sh. Indexed sh => sh -> Index sh -> Bool
Shape.inBounds (Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent)

instance
   (Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.InvIndexed height, Shape.InvIndexed width) =>
      Shape.InvIndexed (Full meas vert horiz height width) where

   unifiedIndexFromOffset :: forall check.
Checking check =>
Full meas vert horiz height width
-> Int -> Result check (Index (Full meas vert horiz height width))
unifiedIndexFromOffset (Full Order
order Extent meas vert horiz height width
extent) =
      Order
-> Extent meas vert horiz height width
-> Int
-> Result check (Index height, Index width)
forall check meas vert horiz a b.
(Checking check, Measure meas, C vert, C horiz, InvIndexed a,
 InvIndexed b) =>
Order
-> Extent meas vert horiz a b
-> Int
-> Result check (Index a, Index b)
fullIndexFromOffset Order
order Extent meas vert horiz height width
extent


transpose ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
   Full meas vert horiz height width -> Full meas horiz vert width height
transpose :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Full meas vert horiz height width
-> Full meas horiz vert width height
transpose (Full Order
order Extent meas vert horiz height width
extent) = Order
-> Extent meas horiz vert width height
-> Full meas horiz vert width height
forall meas vert horiz height width.
Order
-> Extent meas vert horiz height width
-> Full meas vert horiz height width
Full (Order -> Order
flipOrder Order
order) (Extent meas vert horiz height width
-> Extent meas horiz vert width 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 meas vert horiz height width
extent)

inverse ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
   Full meas vert horiz height width -> Full meas horiz vert width height
inverse :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Full meas vert horiz height width
-> Full meas horiz vert width height
inverse (Full Order
order Extent meas vert horiz height width
extent) = Order
-> Extent meas horiz vert width height
-> Full meas horiz vert width height
forall meas vert horiz height width.
Order
-> Extent meas vert horiz height width
-> Full meas vert horiz height width
Full Order
order (Extent meas vert horiz height width
-> Extent meas horiz vert width 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 meas vert horiz height width
extent)

dimensions ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.C height, Shape.C width) =>
   Full meas vert horiz height width -> (Int, Int)
dimensions :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz, C height, C width) =>
Full meas vert horiz height width -> (Int, Int)
dimensions (Full Order
order Extent meas vert horiz height width
extent) =
   Order -> (Int, Int) -> (Int, Int)
forall a. Order -> (a, a) -> (a, a)
swapOnRowMajor Order
order
      (height -> Int
forall sh. C sh => sh -> Int
Shape.size (height -> Int) -> height -> Int
forall a b. (a -> b) -> a -> b
$ Extent meas vert horiz height width -> height
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> height
Extent.height Extent meas vert horiz height width
extent,
       width -> Int
forall sh. C sh => sh -> Int
Shape.size (width -> Int) -> width -> Int
forall a b. (a -> b) -> a -> b
$ Extent meas vert horiz height width -> width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
Extent.width Extent meas vert horiz height width
extent)

fullHeight ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
   Full meas vert horiz height width -> height
fullHeight :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Full meas vert horiz height width -> height
fullHeight = Extent meas vert horiz height width -> height
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> height
Extent.height (Extent meas vert horiz height width -> height)
-> (Full meas vert horiz height width
    -> Extent meas vert horiz height width)
-> Full meas vert horiz height width
-> height
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Full meas vert horiz height width
-> Extent meas vert horiz height width
forall meas vert horiz height width.
Full meas vert horiz height width
-> Extent meas vert horiz height width
fullExtent

fullWidth ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
   Full meas vert horiz height width -> width
fullWidth :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Full meas vert horiz height width -> width
fullWidth = Extent meas vert horiz height width -> width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
Extent.width (Extent meas vert horiz height width -> width)
-> (Full meas vert horiz height width
    -> Extent meas vert horiz height width)
-> Full meas vert horiz height width
-> width
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Full meas vert horiz height width
-> Extent meas vert horiz height width
forall meas vert horiz height width.
Full meas vert horiz height width
-> Extent meas vert horiz height width
fullExtent


fullIndices ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.Indexed a, Shape.Indexed b) =>
   Order -> Extent meas vert horiz a b -> [(Shape.Index a, Shape.Index b)]
fullIndices :: forall meas vert horiz a b.
(Measure meas, C vert, C horiz, Indexed a, Indexed b) =>
Order -> Extent meas vert horiz a b -> [(Index a, Index b)]
fullIndices Order
order Extent meas vert horiz a b
extent =
   case Order
order of
      Order
RowMajor -> (a, b) -> [Index (a, b)]
forall sh. Indexed sh => sh -> [Index sh]
Shape.indices ((a, b) -> [Index (a, b)]) -> (a, b) -> [Index (a, b)]
forall a b. (a -> b) -> a -> b
$ Extent meas vert horiz a b -> (a, b)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz a b
extent
      Order
ColumnMajor -> ((Index b, Index a) -> (Index a, Index b))
-> [(Index b, Index a)] -> [(Index a, Index b)]
forall a b. (a -> b) -> [a] -> [b]
map (Index b, Index a) -> (Index a, Index b)
forall a b. (a, b) -> (b, a)
swap ([(Index b, Index a)] -> [(Index a, Index b)])
-> [(Index b, Index a)] -> [(Index a, Index b)]
forall a b. (a -> b) -> a -> b
$ (b, a) -> [Index (b, a)]
forall sh. Indexed sh => sh -> [Index sh]
Shape.indices ((b, a) -> [Index (b, a)]) -> (b, a) -> [Index (b, a)]
forall a b. (a -> b) -> a -> b
$ (a, b) -> (b, a)
forall a b. (a, b) -> (b, a)
swap ((a, b) -> (b, a)) -> (a, b) -> (b, a)
forall a b. (a -> b) -> a -> b
$ Extent meas vert horiz a b -> (a, b)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz a b
extent

fullIndexFromOffset ::
   (Shape.Checking check,
    Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.InvIndexed a, Shape.InvIndexed b) =>
   Order -> Extent meas vert horiz a b -> Int ->
   Shape.Result check (Shape.Index a, Shape.Index b)
fullIndexFromOffset :: forall check meas vert horiz a b.
(Checking check, Measure meas, C vert, C horiz, InvIndexed a,
 InvIndexed b) =>
Order
-> Extent meas vert horiz a b
-> Int
-> Result check (Index a, Index b)
fullIndexFromOffset Order
order Extent meas vert horiz a b
extent =
   case Order
order of
      Order
RowMajor ->
         (a, b) -> Int -> Result check (Index (a, b))
forall sh check.
(InvIndexed sh, Checking check) =>
sh -> Int -> Result check (Index sh)
forall check.
Checking check =>
(a, b) -> Int -> Result check (Index (a, b))
Shape.unifiedIndexFromOffset (Extent meas vert horiz a b -> (a, b)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz a b
extent)
      Order
ColumnMajor ->
         ((Index b, Index a) -> (Index a, Index b))
-> Result check (Index b, Index a)
-> Result check (Index a, Index b)
forall a b. (a -> b) -> Result check a -> Result check b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Index b, Index a) -> (Index a, Index b)
forall a b. (a, b) -> (b, a)
swap (Result check (Index b, Index a)
 -> Result check (Index a, Index b))
-> (Int -> Result check (Index b, Index a))
-> Int
-> Result check (Index a, Index b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
         (b, a) -> Int -> Result check (Index (b, a))
forall sh check.
(InvIndexed sh, Checking check) =>
sh -> Int -> Result check (Index sh)
forall check.
Checking check =>
(b, a) -> Int -> Result check (Index (b, a))
Shape.unifiedIndexFromOffset ((a, b) -> (b, a)
forall a b. (a, b) -> (b, a)
swap ((a, b) -> (b, a)) -> (a, b) -> (b, a)
forall a b. (a -> b) -> a -> b
$ Extent meas vert horiz a b -> (a, b)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz a b
extent)


type General height width = Full Extent.Size Extent.Big Extent.Big height width
type Tall height width = Full Extent.Size Extent.Big Extent.Small height width
type Wide height width = Full Extent.Size Extent.Small Extent.Big height width
type LiberalSquare height width = SquareMeas Extent.Size height width
type Square size = SquareMeas Extent.Shape size size
type SquareMeas meas height width =
         Full meas Extent.Small Extent.Small height width


fullMapExtent ::
   Extent.Map measA vertA horizA measB vertB horizB height width ->
   Full measA vertA horizA height width ->
   Full measB vertB horizB height width
fullMapExtent :: forall measA vertA horizA measB vertB horizB height width.
Map measA vertA horizA measB vertB horizB height width
-> Full measA vertA horizA height width
-> Full measB vertB horizB height width
fullMapExtent Map measA vertA horizA measB vertB horizB height width
f (Full Order
order Extent measA vertA horizA height width
extent) = Order
-> Extent measB vertB horizB height width
-> Full measB vertB horizB height width
forall meas vert horiz height width.
Order
-> Extent meas vert horiz height width
-> Full meas vert horiz height width
Full Order
order (Extent measB vertB horizB height width
 -> Full measB vertB horizB height width)
-> Extent measB vertB horizB height width
-> Full measB vertB horizB height width
forall a b. (a -> b) -> a -> b
$ Map measA vertA horizA measB vertB horizB height width
f Extent measA vertA horizA height width
extent

general :: Order -> height -> width -> General height width
general :: forall height width.
Order -> height -> width -> General height width
general Order
order height
height width
width = Order
-> Extent Size Big Big height width
-> Full Size Big Big height width
forall meas vert horiz height width.
Order
-> Extent meas vert horiz height width
-> Full meas vert horiz height width
Full Order
order (Extent Size Big Big height width
 -> Full Size Big Big height width)
-> Extent Size Big Big height width
-> Full Size Big Big height width
forall a b. (a -> b) -> a -> b
$ height -> width -> Extent Size Big Big height width
forall height width. height -> width -> General height width
Extent.general height
height width
width

tall ::
   (Shape.C height, Shape.C width) =>
   Order -> height -> width -> Tall height width
tall :: forall height width.
(C height, C width) =>
Order -> height -> width -> Tall height width
tall Order
order height
height width
width =
   if height -> Int
forall sh. C sh => sh -> Int
Shape.size height
height Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= width -> Int
forall sh. C sh => sh -> Int
Shape.size width
width
      then Order
-> Extent Size Big Small height width
-> Full Size Big Small height width
forall meas vert horiz height width.
Order
-> Extent meas vert horiz height width
-> Full meas vert horiz height width
Full Order
order (Extent Size Big Small height width
 -> Full Size Big Small height width)
-> Extent Size Big Small height width
-> Full Size Big Small height width
forall a b. (a -> b) -> a -> b
$ height -> width -> Extent Size Big Small height width
forall height width. height -> width -> Tall height width
Extent.tall height
height width
width
      else String -> Full Size Big Small height width
forall a. HasCallStack => String -> a
error String
"Layout.tall: height smaller than width"

wide ::
   (Shape.C height, Shape.C width) =>
   Order -> height -> width -> Wide height width
wide :: forall height width.
(C height, C width) =>
Order -> height -> width -> Wide height width
wide Order
order height
height width
width =
   if height -> Int
forall sh. C sh => sh -> Int
Shape.size height
height Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= width -> Int
forall sh. C sh => sh -> Int
Shape.size width
width
      then Order
-> Extent Size Small Big height width
-> Full Size Small Big height width
forall meas vert horiz height width.
Order
-> Extent meas vert horiz height width
-> Full meas vert horiz height width
Full Order
order (Extent Size Small Big height width
 -> Full Size Small Big height width)
-> Extent Size Small Big height width
-> Full Size Small Big height width
forall a b. (a -> b) -> a -> b
$ height -> width -> Extent Size Small Big height width
forall height width. height -> width -> Wide height width
Extent.wide height
height width
width
      else String -> Full Size Small Big height width
forall a. HasCallStack => String -> a
error String
"Layout.wide: width smaller than height"

liberalSquare ::
   (Shape.C height, Shape.C width) =>
   Order -> height -> width -> LiberalSquare height width
liberalSquare :: forall height width.
(C height, C width) =>
Order -> height -> width -> LiberalSquare height width
liberalSquare Order
order height
height width
width =
   if height -> Int
forall sh. C sh => sh -> Int
Shape.size height
height Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== width -> Int
forall sh. C sh => sh -> Int
Shape.size width
width
      then Order
-> Extent Size Small Small height width
-> Full Size Small Small height width
forall meas vert horiz height width.
Order
-> Extent meas vert horiz height width
-> Full meas vert horiz height width
Full Order
order (Extent Size Small Small height width
 -> Full Size Small Small height width)
-> Extent Size Small Small height width
-> Full Size Small Small height width
forall a b. (a -> b) -> a -> b
$ height -> width -> Extent Size Small Small height width
forall height width. height -> width -> LiberalSquare height width
Extent.liberalSquare height
height width
width
      else String -> Full Size Small Small height width
forall a. HasCallStack => String -> a
error String
"Layout.liberalSquare: height and width sizes differ"

square :: Order -> sh -> Square sh
square :: forall sh. Order -> sh -> Square sh
square Order
order sh
sh = Order
-> Extent Shape Small Small sh sh -> Full Shape Small Small sh sh
forall meas vert horiz height width.
Order
-> Extent meas vert horiz height width
-> Full meas vert horiz height width
Full Order
order (Extent Shape Small Small sh sh -> Full Shape Small Small sh sh)
-> Extent Shape Small Small sh sh -> Full Shape Small Small sh sh
forall a b. (a -> b) -> a -> b
$ sh -> Extent Shape Small Small sh sh
forall sh. sh -> Square sh
Extent.square sh
sh


caseTallWide ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.C height, Shape.C width) =>
   Full meas vert horiz height width ->
   Either (Tall height width) (Wide height width)
caseTallWide :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz, C height, C width) =>
Full meas vert horiz height width
-> Either (Tall height width) (Wide height width)
caseTallWide (Full Order
order Extent meas vert horiz height width
extent) =
   (Extent Size Big Small height width
 -> Either (Tall height width) (Wide height width))
-> (Extent Size Small Big height width
    -> Either (Tall height width) (Wide height width))
-> Either
     (Extent Size Big Small height width)
     (Extent Size Small Big height width)
-> Either (Tall height width) (Wide height width)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Tall height width -> Either (Tall height width) (Wide height width)
forall a b. a -> Either a b
Left (Tall height width
 -> Either (Tall height width) (Wide height width))
-> (Extent Size Big Small height width -> Tall height width)
-> Extent Size Big Small height width
-> Either (Tall height width) (Wide height width)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Order -> Extent Size Big Small height width -> Tall height width
forall meas vert horiz height width.
Order
-> Extent meas vert horiz height width
-> Full meas vert horiz height width
Full Order
order) (Wide height width -> Either (Tall height width) (Wide height width)
forall a b. b -> Either a b
Right (Wide height width
 -> Either (Tall height width) (Wide height width))
-> (Extent Size Small Big height width -> Wide height width)
-> Extent Size Small Big height width
-> Either (Tall height width) (Wide height width)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Order -> Extent Size Small Big height width -> Wide height width
forall meas vert horiz height width.
Order
-> Extent meas vert horiz height width
-> Full meas vert horiz height width
Full Order
order) (Either
   (Extent Size Big Small height width)
   (Extent Size Small Big height width)
 -> Either (Tall height width) (Wide height width))
-> Either
     (Extent Size Big Small height width)
     (Extent Size Small Big height width)
-> Either (Tall height width) (Wide height width)
forall a b. (a -> b) -> a -> b
$
   (height -> width -> Bool)
-> Extent meas vert horiz height width
-> Either
     (Extent Size Big Small height width)
     (Extent Size Small Big height width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
(height -> width -> Bool)
-> Extent meas vert horiz height width
-> Either (Tall height width) (Wide height width)
Extent.caseTallWide (\height
h width
w -> height -> Int
forall sh. C sh => sh -> Int
Shape.size height
h Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= width -> Int
forall sh. C sh => sh -> Int
Shape.size width
w) Extent meas vert horiz height width
extent


data Split lower meas vert horiz height width =
   Split {
      forall lower meas vert horiz height width.
Split lower meas vert horiz height width -> lower
splitLower :: lower,
      forall lower meas vert horiz height width.
Split lower meas vert horiz height width -> Order
splitOrder :: Order,
      forall lower meas vert horiz height width.
Split lower meas vert horiz height width
-> Extent meas vert horiz height width
splitExtent :: Extent meas vert horiz height width
   } deriving (Split lower meas vert horiz height width
-> Split lower meas vert horiz height width -> Bool
(Split lower meas vert horiz height width
 -> Split lower meas vert horiz height width -> Bool)
-> (Split lower meas vert horiz height width
    -> Split lower meas vert horiz height width -> Bool)
-> Eq (Split lower meas vert horiz height width)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall lower meas vert horiz height width.
(Measure meas, C vert, C horiz, Eq lower, Eq height, Eq width) =>
Split lower meas vert horiz height width
-> Split lower meas vert horiz height width -> Bool
$c== :: forall lower meas vert horiz height width.
(Measure meas, C vert, C horiz, Eq lower, Eq height, Eq width) =>
Split lower meas vert horiz height width
-> Split lower meas vert horiz height width -> Bool
== :: Split lower meas vert horiz height width
-> Split lower meas vert horiz height width -> Bool
$c/= :: forall lower meas vert horiz height width.
(Measure meas, C vert, C horiz, Eq lower, Eq height, Eq width) =>
Split lower meas vert horiz height width
-> Split lower meas vert horiz height width -> Bool
/= :: Split lower meas vert horiz height width
-> Split lower meas vert horiz height width -> Bool
Eq, Int -> Split lower meas vert horiz height width -> String -> String
[Split lower meas vert horiz height width] -> String -> String
Split lower meas vert horiz height width -> String
(Int
 -> Split lower meas vert horiz height width -> String -> String)
-> (Split lower meas vert horiz height width -> String)
-> ([Split lower meas vert horiz height width] -> String -> String)
-> Show (Split lower meas vert horiz height width)
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
forall lower meas vert horiz height width.
(Measure meas, C vert, C horiz, Show lower, Show height,
 Show width) =>
Int -> Split lower meas vert horiz height width -> String -> String
forall lower meas vert horiz height width.
(Measure meas, C vert, C horiz, Show lower, Show height,
 Show width) =>
[Split lower meas vert horiz height width] -> String -> String
forall lower meas vert horiz height width.
(Measure meas, C vert, C horiz, Show lower, Show height,
 Show width) =>
Split lower meas vert horiz height width -> String
$cshowsPrec :: forall lower meas vert horiz height width.
(Measure meas, C vert, C horiz, Show lower, Show height,
 Show width) =>
Int -> Split lower meas vert horiz height width -> String -> String
showsPrec :: Int -> Split lower meas vert horiz height width -> String -> String
$cshow :: forall lower meas vert horiz height width.
(Measure meas, C vert, C horiz, Show lower, Show height,
 Show width) =>
Split lower meas vert horiz height width -> String
show :: Split lower meas vert horiz height width -> String
$cshowList :: forall lower meas vert horiz height width.
(Measure meas, C vert, C horiz, Show lower, Show height,
 Show width) =>
[Split lower meas vert horiz height width] -> String -> String
showList :: [Split lower meas vert horiz height width] -> String -> String
Show)

splitHeight ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
   Split lower meas vert horiz height width -> height
splitHeight :: forall meas vert horiz lower height width.
(Measure meas, C vert, C horiz) =>
Split lower meas vert horiz height width -> height
splitHeight = Extent meas vert horiz height width -> height
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> height
Extent.height (Extent meas vert horiz height width -> height)
-> (Split lower meas vert horiz height width
    -> Extent meas vert horiz height width)
-> Split lower meas vert horiz height width
-> height
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Split lower meas vert horiz height width
-> Extent meas vert horiz height width
forall lower meas vert horiz height width.
Split lower meas vert horiz height width
-> Extent meas vert horiz height width
splitExtent

splitWidth ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
   Split lower meas vert horiz height width -> width
splitWidth :: forall meas vert horiz lower height width.
(Measure meas, C vert, C horiz) =>
Split lower meas vert horiz height width -> width
splitWidth = Extent meas vert horiz height width -> width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
Extent.width (Extent meas vert horiz height width -> width)
-> (Split lower meas vert horiz height width
    -> Extent meas vert horiz height width)
-> Split lower meas vert horiz height width
-> width
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Split lower meas vert horiz height width
-> Extent meas vert horiz height width
forall lower meas vert horiz height width.
Split lower meas vert horiz height width
-> Extent meas vert horiz height width
splitExtent

splitMapExtent ::
   Extent.Map measA vertA horizA measB vertB horizB height width ->
   Split lower measA vertA horizA height width ->
   Split lower measB vertB horizB height width
splitMapExtent :: forall measA vertA horizA measB vertB horizB height width lower.
Map measA vertA horizA measB vertB horizB height width
-> Split lower measA vertA horizA height width
-> Split lower measB vertB horizB height width
splitMapExtent Map measA vertA horizA measB vertB horizB height width
f (Split lower
lowerPart Order
order Extent measA vertA horizA height width
extent) =
   lower
-> Order
-> Extent measB vertB horizB height width
-> Split lower measB vertB horizB height width
forall lower meas vert horiz height width.
lower
-> Order
-> Extent meas vert horiz height width
-> Split lower meas vert horiz height width
Split lower
lowerPart Order
order (Extent measB vertB horizB height width
 -> Split lower measB vertB horizB height width)
-> Extent measB vertB horizB height width
-> Split lower measB vertB horizB height width
forall a b. (a -> b) -> a -> b
$ Map measA vertA horizA measB vertB horizB height width
f Extent measA vertA horizA height width
extent


caseTallWideSplit ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.C height, Shape.C width) =>
   Split lower meas vert horiz height width ->
   Either
      (Split lower Extent.Size Extent.Big Extent.Small height width)
      (Split lower Extent.Size Extent.Small Extent.Big height width)
caseTallWideSplit :: forall meas vert horiz height width lower.
(Measure meas, C vert, C horiz, C height, C width) =>
Split lower meas vert horiz height width
-> Either
     (Split lower Size Big Small height width)
     (Split lower Size Small Big height width)
caseTallWideSplit (Split lower
lowerPart Order
order Extent meas vert horiz height width
extent) =
   (Extent Size Big Small height width
 -> Either
      (Split lower Size Big Small height width)
      (Split lower Size Small Big height width))
-> (Extent Size Small Big height width
    -> Either
         (Split lower Size Big Small height width)
         (Split lower Size Small Big height width))
-> Either
     (Extent Size Big Small height width)
     (Extent Size Small Big height width)
-> Either
     (Split lower Size Big Small height width)
     (Split lower Size Small Big height width)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Split lower Size Big Small height width
-> Either
     (Split lower Size Big Small height width)
     (Split lower Size Small Big height width)
forall a b. a -> Either a b
Left (Split lower Size Big Small height width
 -> Either
      (Split lower Size Big Small height width)
      (Split lower Size Small Big height width))
-> (Extent Size Big Small height width
    -> Split lower Size Big Small height width)
-> Extent Size Big Small height width
-> Either
     (Split lower Size Big Small height width)
     (Split lower Size Small Big height width)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. lower
-> Order
-> Extent Size Big Small height width
-> Split lower Size Big Small height width
forall lower meas vert horiz height width.
lower
-> Order
-> Extent meas vert horiz height width
-> Split lower meas vert horiz height width
Split lower
lowerPart Order
order) (Split lower Size Small Big height width
-> Either
     (Split lower Size Big Small height width)
     (Split lower Size Small Big height width)
forall a b. b -> Either a b
Right (Split lower Size Small Big height width
 -> Either
      (Split lower Size Big Small height width)
      (Split lower Size Small Big height width))
-> (Extent Size Small Big height width
    -> Split lower Size Small Big height width)
-> Extent Size Small Big height width
-> Either
     (Split lower Size Big Small height width)
     (Split lower Size Small Big height width)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. lower
-> Order
-> Extent Size Small Big height width
-> Split lower Size Small Big height width
forall lower meas vert horiz height width.
lower
-> Order
-> Extent meas vert horiz height width
-> Split lower meas vert horiz height width
Split lower
lowerPart Order
order) (Either
   (Extent Size Big Small height width)
   (Extent Size Small Big height width)
 -> Either
      (Split lower Size Big Small height width)
      (Split lower Size Small Big height width))
-> Either
     (Extent Size Big Small height width)
     (Extent Size Small Big height width)
-> Either
     (Split lower Size Big Small height width)
     (Split lower Size Small Big height width)
forall a b. (a -> b) -> a -> b
$
   (height -> width -> Bool)
-> Extent meas vert horiz height width
-> Either
     (Extent Size Big Small height width)
     (Extent Size Small Big height width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
(height -> width -> Bool)
-> Extent meas vert horiz height width
-> Either (Tall height width) (Wide height width)
Extent.caseTallWide (\height
h width
w -> height -> Int
forall sh. C sh => sh -> Int
Shape.size height
h Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= width -> Int
forall sh. C sh => sh -> Int
Shape.size width
w) Extent meas vert horiz height width
extent

data Reflector = Reflector deriving (Reflector -> Reflector -> Bool
(Reflector -> Reflector -> Bool)
-> (Reflector -> Reflector -> Bool) -> Eq Reflector
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Reflector -> Reflector -> Bool
== :: Reflector -> Reflector -> Bool
$c/= :: Reflector -> Reflector -> Bool
/= :: Reflector -> Reflector -> Bool
Eq, Int -> Reflector -> String -> String
[Reflector] -> String -> String
Reflector -> String
(Int -> Reflector -> String -> String)
-> (Reflector -> String)
-> ([Reflector] -> String -> String)
-> Show Reflector
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> Reflector -> String -> String
showsPrec :: Int -> Reflector -> String -> String
$cshow :: Reflector -> String
show :: Reflector -> String
$cshowList :: [Reflector] -> String -> String
showList :: [Reflector] -> String -> String
Show)
data Triangle = Triangle deriving (Triangle -> Triangle -> Bool
(Triangle -> Triangle -> Bool)
-> (Triangle -> Triangle -> Bool) -> Eq Triangle
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Triangle -> Triangle -> Bool
== :: Triangle -> Triangle -> Bool
$c/= :: Triangle -> Triangle -> Bool
/= :: Triangle -> Triangle -> Bool
Eq, Int -> Triangle -> String -> String
[Triangle] -> String -> String
Triangle -> String
(Int -> Triangle -> String -> String)
-> (Triangle -> String)
-> ([Triangle] -> String -> String)
-> Show Triangle
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> Triangle -> String -> String
showsPrec :: Int -> Triangle -> String -> String
$cshow :: Triangle -> String
show :: Triangle -> String
$cshowList :: [Triangle] -> String -> String
showList :: [Triangle] -> String -> String
Show)

instance NFData Reflector where rnf :: Reflector -> ()
rnf Reflector
Reflector = ()
instance NFData Triangle where rnf :: Triangle -> ()
rnf Triangle
Triangle = ()

splitPart ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.Indexed height, Shape.Indexed width) =>
   Split lower meas vert horiz height width ->
   (Shape.Index height, Shape.Index width) -> Either lower Triangle
splitPart :: forall meas vert horiz height width lower.
(Measure meas, C vert, C horiz, Indexed height, Indexed width) =>
Split lower meas vert horiz height width
-> (Index height, Index width) -> Either lower Triangle
splitPart (Split lower
lowerPart Order
_ Extent meas vert horiz height width
extent) (Index height
r,Index width
c) =
   if height -> Index height -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset (Extent meas vert horiz height width -> height
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> height
Extent.height Extent meas vert horiz height width
extent) Index height
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>
         width -> Index width -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset (Extent meas vert horiz height width -> width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
Extent.width Extent meas vert horiz height width
extent) Index width
c
     then lower -> Either lower Triangle
forall a b. a -> Either a b
Left lower
lowerPart
     else Triangle -> Either lower Triangle
forall a b. b -> Either a b
Right Triangle
Triangle

instance
   (NFData lower, Extent.Measure meas, Extent.C vert, Extent.C horiz,
    NFData height, NFData width) =>
      NFData (Split lower meas vert horiz height width) where
   rnf :: Split lower meas vert horiz height width -> ()
rnf (Split lower
lowerPart Order
order Extent meas vert horiz height width
extent) = (lower, Order, Extent meas vert horiz height width) -> ()
forall a. NFData a => a -> ()
rnf (lower
lowerPart, Order
order, Extent meas vert horiz height width
extent)

instance
   (Eq lower, Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.C height, Shape.C width) =>
      Shape.C (Split lower meas vert horiz height width) where

   size :: Split lower meas vert horiz height width -> Int
size (Split lower
_ Order
_ Extent meas vert horiz height width
extent) = (height, width) -> Int
forall sh. C sh => sh -> Int
Shape.size (Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent)

instance
   (Eq lower, Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.Indexed height, Shape.Indexed width) =>
      Shape.Indexed (Split lower meas vert horiz height width) where

   type Index (Split lower meas vert horiz height width) =
            (Either lower Triangle,
             (Shape.Index height, Shape.Index width))

   indices :: Split lower meas vert horiz height width
-> [Index (Split lower meas vert horiz height width)]
indices sh :: Split lower meas vert horiz height width
sh@(Split lower
_ Order
order Extent meas vert horiz height width
extent) =
      ((Index height, Index width)
 -> Index (Split lower meas vert horiz height width))
-> [(Index height, Index width)]
-> [Index (Split lower meas vert horiz height width)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Index height, Index width)
ix -> (Split lower meas vert horiz height width
-> (Index height, Index width) -> Either lower Triangle
forall meas vert horiz height width lower.
(Measure meas, C vert, C horiz, Indexed height, Indexed width) =>
Split lower meas vert horiz height width
-> (Index height, Index width) -> Either lower Triangle
splitPart Split lower meas vert horiz height width
sh (Index height, Index width)
ix, (Index height, Index width)
ix)) ([(Index height, Index width)]
 -> [Index (Split lower meas vert horiz height width)])
-> [(Index height, Index width)]
-> [Index (Split lower meas vert horiz height width)]
forall a b. (a -> b) -> a -> b
$ Order
-> Extent meas vert horiz height width
-> [(Index height, Index width)]
forall meas vert horiz a b.
(Measure meas, C vert, C horiz, Indexed a, Indexed b) =>
Order -> Extent meas vert horiz a b -> [(Index a, Index b)]
fullIndices Order
order Extent meas vert horiz height width
extent

   unifiedOffset :: forall check.
Checking check =>
Split lower meas vert horiz height width
-> Index (Split lower meas vert horiz height width)
-> Result check Int
unifiedOffset sh :: Split lower meas vert horiz height width
sh@(Split lower
_ Order
order Extent meas vert horiz height width
extent) (Either lower Triangle
part,(Index height, Index width)
ix) = do
      String -> Bool -> Result check ()
forall check. Checking check => String -> Bool -> Result check ()
Shape.assert String
"Shape.Split.offset: wrong matrix part" (Bool -> Result check ()) -> Bool -> Result check ()
forall a b. (a -> b) -> a -> b
$
         Either lower Triangle
part Either lower Triangle -> Either lower Triangle -> Bool
forall a. Eq a => a -> a -> Bool
== Split lower meas vert horiz height width
-> (Index height, Index width) -> Either lower Triangle
forall meas vert horiz height width lower.
(Measure meas, C vert, C horiz, Indexed height, Indexed width) =>
Split lower meas vert horiz height width
-> (Index height, Index width) -> Either lower Triangle
splitPart Split lower meas vert horiz height width
sh (Index height, Index width)
ix
      case Order
order of
         Order
RowMajor -> (height, width) -> Index (height, width) -> Result check Int
forall sh check.
(Indexed sh, Checking check) =>
sh -> Index sh -> Result check Int
forall check.
Checking check =>
(height, width) -> Index (height, width) -> Result check Int
Shape.unifiedOffset (Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent) (Index height, Index width)
Index (height, width)
ix
         Order
ColumnMajor ->
            (width, height) -> Index (width, height) -> Result check Int
forall sh check.
(Indexed sh, Checking check) =>
sh -> Index sh -> Result check Int
forall check.
Checking check =>
(width, height) -> Index (width, height) -> Result check Int
Shape.unifiedOffset ((height, width) -> (width, height)
forall a b. (a, b) -> (b, a)
swap ((height, width) -> (width, height))
-> (height, width) -> (width, height)
forall a b. (a -> b) -> a -> b
$ Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent) ((Index height, Index width) -> (Index width, Index height)
forall a b. (a, b) -> (b, a)
swap (Index height, Index width)
ix)

   unifiedSizeOffset :: forall check.
Checking check =>
Split lower meas vert horiz height width
-> (Int,
    Index (Split lower meas vert horiz height width)
    -> Result check Int)
unifiedSizeOffset sh :: Split lower meas vert horiz height width
sh@(Split lower
_ Order
order Extent meas vert horiz height width
extent) =
      let check :: (Either lower Triangle, (Index height, Index width))
-> Int -> Result check Int
check (Either lower Triangle
part,(Index height, Index width)
ix) Int
a = do
            String -> Bool -> Result check ()
forall check. Checking check => String -> Bool -> Result check ()
Shape.assert String
"Shape.Split.sizeOffset: wrong matrix part" (Bool -> Result check ()) -> Bool -> Result check ()
forall a b. (a -> b) -> a -> b
$
               Either lower Triangle
part Either lower Triangle -> Either lower Triangle -> Bool
forall a. Eq a => a -> a -> Bool
== Split lower meas vert horiz height width
-> (Index height, Index width) -> Either lower Triangle
forall meas vert horiz height width lower.
(Measure meas, C vert, C horiz, Indexed height, Indexed width) =>
Split lower meas vert horiz height width
-> (Index height, Index width) -> Either lower Triangle
splitPart Split lower meas vert horiz height width
sh (Index height, Index width)
ix
            Int -> Result check Int
forall a. a -> Result check a
forall (m :: * -> *) a. Monad m => a -> m a
return Int
a
      in case Order
order of
            Order
RowMajor ->
               (((Index height, Index width) -> Result check Int)
 -> Index (Split lower meas vert horiz height width)
 -> Result check Int)
-> (Int, (Index height, Index width) -> Result check Int)
-> (Int,
    Index (Split lower meas vert horiz height width)
    -> Result check Int)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd
                  (\(Index height, Index width) -> Result check Int
getOffset (Either lower Triangle
part,(Index height, Index width)
ix) -> (Either lower Triangle, (Index height, Index width))
-> Int -> Result check Int
check (Either lower Triangle
part,(Index height, Index width)
ix) (Int -> Result check Int) -> Result check Int -> Result check Int
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Index height, Index width) -> Result check Int
getOffset (Index height, Index width)
ix) ((Int, (Index height, Index width) -> Result check Int)
 -> (Int,
     Index (Split lower meas vert horiz height width)
     -> Result check Int))
-> (Int, (Index height, Index width) -> Result check Int)
-> (Int,
    Index (Split lower meas vert horiz height width)
    -> Result check Int)
forall a b. (a -> b) -> a -> b
$
               (height, width) -> (Int, Index (height, width) -> Result check Int)
forall sh check.
(Indexed sh, Checking check) =>
sh -> (Int, Index sh -> Result check Int)
forall check.
Checking check =>
(height, width) -> (Int, Index (height, width) -> Result check Int)
Shape.unifiedSizeOffset (Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent)
            Order
ColumnMajor ->
               (((Index width, Index height) -> Result check Int)
 -> Index (Split lower meas vert horiz height width)
 -> Result check Int)
-> (Int, (Index width, Index height) -> Result check Int)
-> (Int,
    Index (Split lower meas vert horiz height width)
    -> Result check Int)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd
                  (\(Index width, Index height) -> Result check Int
getOffset (Either lower Triangle
part,(Index height, Index width)
ix) ->
                     (Either lower Triangle, (Index height, Index width))
-> Int -> Result check Int
check (Either lower Triangle
part,(Index height, Index width)
ix) (Int -> Result check Int) -> Result check Int -> Result check Int
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Index width, Index height) -> Result check Int
getOffset ((Index height, Index width) -> (Index width, Index height)
forall a b. (a, b) -> (b, a)
swap (Index height, Index width)
ix)) ((Int, (Index width, Index height) -> Result check Int)
 -> (Int,
     Index (Split lower meas vert horiz height width)
     -> Result check Int))
-> (Int, (Index width, Index height) -> Result check Int)
-> (Int,
    Index (Split lower meas vert horiz height width)
    -> Result check Int)
forall a b. (a -> b) -> a -> b
$
               (width, height) -> (Int, Index (width, height) -> Result check Int)
forall sh check.
(Indexed sh, Checking check) =>
sh -> (Int, Index sh -> Result check Int)
forall check.
Checking check =>
(width, height) -> (Int, Index (width, height) -> Result check Int)
Shape.unifiedSizeOffset ((height, width) -> (width, height)
forall a b. (a, b) -> (b, a)
swap ((height, width) -> (width, height))
-> (height, width) -> (width, height)
forall a b. (a -> b) -> a -> b
$ Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent)

   inBounds :: Split lower meas vert horiz height width
-> Index (Split lower meas vert horiz height width) -> Bool
inBounds sh :: Split lower meas vert horiz height width
sh@(Split lower
_ Order
_ Extent meas vert horiz height width
extent) (Either lower Triangle
part,(Index height, Index width)
ix) =
      (height, width) -> Index (height, width) -> Bool
forall sh. Indexed sh => sh -> Index sh -> Bool
Shape.inBounds (Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent) (Index height, Index width)
Index (height, width)
ix
      Bool -> Bool -> Bool
&&
      Either lower Triangle
part Either lower Triangle -> Either lower Triangle -> Bool
forall a. Eq a => a -> a -> Bool
== Split lower meas vert horiz height width
-> (Index height, Index width) -> Either lower Triangle
forall meas vert horiz height width lower.
(Measure meas, C vert, C horiz, Indexed height, Indexed width) =>
Split lower meas vert horiz height width
-> (Index height, Index width) -> Either lower Triangle
splitPart Split lower meas vert horiz height width
sh (Index height, Index width)
ix

instance
   (Eq lower, Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.InvIndexed height, Shape.InvIndexed width) =>
      Shape.InvIndexed (Split lower meas vert horiz height width) where

   unifiedIndexFromOffset :: forall check.
Checking check =>
Split lower meas vert horiz height width
-> Int
-> Result check (Index (Split lower meas vert horiz height width))
unifiedIndexFromOffset sh :: Split lower meas vert horiz height width
sh@(Split lower
_ Order
order Extent meas vert horiz height width
extent) Int
k = do
      (Index height, Index width)
ix <- Order
-> Extent meas vert horiz height width
-> Int
-> Result check (Index height, Index width)
forall check meas vert horiz a b.
(Checking check, Measure meas, C vert, C horiz, InvIndexed a,
 InvIndexed b) =>
Order
-> Extent meas vert horiz a b
-> Int
-> Result check (Index a, Index b)
fullIndexFromOffset Order
order Extent meas vert horiz height width
extent Int
k
      (Either lower Triangle, (Index height, Index width))
-> Result
     check (Either lower Triangle, (Index height, Index width))
forall a. a -> Result check a
forall (m :: * -> *) a. Monad m => a -> m a
return (Split lower meas vert horiz height width
-> (Index height, Index width) -> Either lower Triangle
forall meas vert horiz height width lower.
(Measure meas, C vert, C horiz, Indexed height, Indexed width) =>
Split lower meas vert horiz height width
-> (Index height, Index width) -> Either lower Triangle
splitPart Split lower meas vert horiz height width
sh (Index height, Index width)
ix, (Index height, Index width)
ix)



data Mosaic pack mirror uplo size =
   Mosaic {
      forall pack mirror uplo size.
Mosaic pack mirror uplo size -> PackingSingleton pack
mosaicPack :: PackingSingleton pack,
      forall pack mirror uplo size.
Mosaic pack mirror uplo size -> MirrorSingleton mirror
mosaicMirror :: MirrorSingleton mirror,
      forall pack mirror uplo size.
Mosaic pack mirror uplo size -> UpLoSingleton uplo
mosaicUplo :: UpLoSingleton uplo,
      forall pack mirror uplo size. Mosaic pack mirror uplo size -> Order
mosaicOrder :: Order,
      forall pack mirror uplo size. Mosaic pack mirror uplo size -> size
mosaicSize :: size
   } deriving (Mosaic pack mirror uplo size
-> Mosaic pack mirror uplo size -> Bool
(Mosaic pack mirror uplo size
 -> Mosaic pack mirror uplo size -> Bool)
-> (Mosaic pack mirror uplo size
    -> Mosaic pack mirror uplo size -> Bool)
-> Eq (Mosaic pack mirror uplo size)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall pack mirror uplo size.
Eq size =>
Mosaic pack mirror uplo size
-> Mosaic pack mirror uplo size -> Bool
$c== :: forall pack mirror uplo size.
Eq size =>
Mosaic pack mirror uplo size
-> Mosaic pack mirror uplo size -> Bool
== :: Mosaic pack mirror uplo size
-> Mosaic pack mirror uplo size -> Bool
$c/= :: forall pack mirror uplo size.
Eq size =>
Mosaic pack mirror uplo size
-> Mosaic pack mirror uplo size -> Bool
/= :: Mosaic pack mirror uplo size
-> Mosaic pack mirror uplo size -> Bool
Eq, Int -> Mosaic pack mirror uplo size -> String -> String
[Mosaic pack mirror uplo size] -> String -> String
Mosaic pack mirror uplo size -> String
(Int -> Mosaic pack mirror uplo size -> String -> String)
-> (Mosaic pack mirror uplo size -> String)
-> ([Mosaic pack mirror uplo size] -> String -> String)
-> Show (Mosaic pack mirror uplo size)
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
forall pack mirror uplo size.
Show size =>
Int -> Mosaic pack mirror uplo size -> String -> String
forall pack mirror uplo size.
Show size =>
[Mosaic pack mirror uplo size] -> String -> String
forall pack mirror uplo size.
Show size =>
Mosaic pack mirror uplo size -> String
$cshowsPrec :: forall pack mirror uplo size.
Show size =>
Int -> Mosaic pack mirror uplo size -> String -> String
showsPrec :: Int -> Mosaic pack mirror uplo size -> String -> String
$cshow :: forall pack mirror uplo size.
Show size =>
Mosaic pack mirror uplo size -> String
show :: Mosaic pack mirror uplo size -> String
$cshowList :: forall pack mirror uplo size.
Show size =>
[Mosaic pack mirror uplo size] -> String -> String
showList :: [Mosaic pack mirror uplo size] -> String -> String
Show)

data Packed
data Unpacked

data PackingSingleton pack where
   Packed :: PackingSingleton Packed
   Unpacked :: PackingSingleton Unpacked

deriving instance Eq (PackingSingleton pack)
deriving instance Show (PackingSingleton pack)

instance NFData (PackingSingleton pack) where
   rnf :: PackingSingleton pack -> ()
rnf PackingSingleton pack
Packed = ()
   rnf PackingSingleton pack
Unpacked = ()

class Packing pack where autoPacking :: PackingSingleton pack
instance Packing Unpacked where autoPacking :: PackingSingleton Unpacked
autoPacking = PackingSingleton Unpacked
Unpacked
instance Packing Packed where autoPacking :: PackingSingleton Packed
autoPacking = PackingSingleton Packed
Packed

squareFromMosaic :: Mosaic Unpacked mirror uplo size -> Square size
squareFromMosaic :: forall mirror uplo size.
Mosaic Unpacked mirror uplo size -> Square size
squareFromMosaic (Mosaic {mosaicOrder :: forall pack mirror uplo size. Mosaic pack mirror uplo size -> Order
mosaicOrder = Order
order, mosaicSize :: forall pack mirror uplo size. Mosaic pack mirror uplo size -> size
mosaicSize = size
size}) =
   Order -> size -> Square size
forall sh. Order -> sh -> Square sh
square Order
order size
size

mosaicFromSquare ::
   (Mirror mirror, UpLo uplo) => Square size -> Mosaic Unpacked mirror uplo size
mosaicFromSquare :: forall mirror uplo size.
(Mirror mirror, UpLo uplo) =>
Square size -> Mosaic Unpacked mirror uplo size
mosaicFromSquare (Full {fullOrder :: forall meas vert horiz height width.
Full meas vert horiz height width -> Order
fullOrder = Order
order, fullExtent :: forall meas vert horiz height width.
Full meas vert horiz height width
-> Extent meas vert horiz height width
fullExtent = Extent Shape Small Small size size
extent}) =
   Mosaic {
      mosaicPack :: PackingSingleton Unpacked
mosaicPack = PackingSingleton Unpacked
Unpacked,
      mosaicMirror :: MirrorSingleton mirror
mosaicMirror = MirrorSingleton mirror
forall mirror. Mirror mirror => MirrorSingleton mirror
autoMirror,
      mosaicUplo :: UpLoSingleton uplo
mosaicUplo = UpLoSingleton uplo
forall uplo. UpLo uplo => UpLoSingleton uplo
autoUplo,
      mosaicOrder :: Order
mosaicOrder = Order
order,
      mosaicSize :: size
mosaicSize = Extent Shape Small Small size size -> size
forall shape. Square shape -> shape
Extent.squareSize Extent Shape Small Small size size
extent
   }


data NoMirror
data SimpleMirror
data ConjugateMirror

data MirrorSingleton mirror where
   NoMirror :: MirrorSingleton NoMirror
   SimpleMirror :: MirrorSingleton SimpleMirror
   ConjugateMirror :: MirrorSingleton ConjugateMirror

deriving instance Eq (MirrorSingleton mirror)
deriving instance Show (MirrorSingleton mirror)

instance NFData (MirrorSingleton mirror) where
   rnf :: MirrorSingleton mirror -> ()
rnf MirrorSingleton mirror
NoMirror = ()
   rnf MirrorSingleton mirror
SimpleMirror = ()
   rnf MirrorSingleton mirror
ConjugateMirror = ()

class Mirror mirror where autoMirror :: MirrorSingleton mirror
instance Mirror NoMirror where autoMirror :: MirrorSingleton NoMirror
autoMirror = MirrorSingleton NoMirror
NoMirror
instance Mirror SimpleMirror where autoMirror :: MirrorSingleton SimpleMirror
autoMirror = MirrorSingleton SimpleMirror
SimpleMirror
instance Mirror ConjugateMirror where autoMirror :: MirrorSingleton ConjugateMirror
autoMirror = MirrorSingleton ConjugateMirror
ConjugateMirror


type TriangularP pack = Mosaic pack NoMirror
type Triangular = TriangularP Packed

type LowerTriangularP pack = TriangularP pack Shape.Lower
type LowerTriangular = Triangular Shape.Lower

type UpperTriangularP pack = TriangularP pack Shape.Upper
type UpperTriangular = Triangular Shape.Upper

triangular :: UpLoSingleton uplo -> Order -> size -> Triangular uplo size
triangular :: forall uplo size.
UpLoSingleton uplo -> Order -> size -> Triangular uplo size
triangular = PackingSingleton Packed
-> MirrorSingleton NoMirror
-> UpLoSingleton uplo
-> Order
-> size
-> Mosaic Packed NoMirror uplo size
forall pack mirror uplo size.
PackingSingleton pack
-> MirrorSingleton mirror
-> UpLoSingleton uplo
-> Order
-> size
-> Mosaic pack mirror uplo size
Mosaic PackingSingleton Packed
Packed MirrorSingleton NoMirror
NoMirror

upperTriangular :: Order -> size -> UpperTriangular size
upperTriangular :: forall size. Order -> size -> UpperTriangular size
upperTriangular = UpLoSingleton Upper -> Order -> size -> Triangular Upper size
forall uplo size.
UpLoSingleton uplo -> Order -> size -> Triangular uplo size
triangular UpLoSingleton Upper
Upper

lowerTriangular :: Order -> size -> LowerTriangular size
lowerTriangular :: forall size. Order -> size -> LowerTriangular size
lowerTriangular = UpLoSingleton Lower -> Order -> size -> Triangular Lower size
forall uplo size.
UpLoSingleton uplo -> Order -> size -> Triangular uplo size
triangular UpLoSingleton Lower
Lower


triangularP ::
   PackingSingleton pack ->
   UpLoSingleton uplo -> Order -> size -> TriangularP pack uplo size
triangularP :: forall pack uplo size.
PackingSingleton pack
-> UpLoSingleton uplo
-> Order
-> size
-> TriangularP pack uplo size
triangularP PackingSingleton pack
pack = PackingSingleton pack
-> MirrorSingleton NoMirror
-> UpLoSingleton uplo
-> Order
-> size
-> Mosaic pack NoMirror uplo size
forall pack mirror uplo size.
PackingSingleton pack
-> MirrorSingleton mirror
-> UpLoSingleton uplo
-> Order
-> size
-> Mosaic pack mirror uplo size
Mosaic PackingSingleton pack
pack MirrorSingleton NoMirror
NoMirror

upperTriangularP ::
   PackingSingleton pack -> Order -> size -> UpperTriangularP pack size
upperTriangularP :: forall pack size.
PackingSingleton pack
-> Order -> size -> UpperTriangularP pack size
upperTriangularP PackingSingleton pack
pack = PackingSingleton pack
-> UpLoSingleton Upper
-> Order
-> size
-> TriangularP pack Upper size
forall pack uplo size.
PackingSingleton pack
-> UpLoSingleton uplo
-> Order
-> size
-> TriangularP pack uplo size
triangularP PackingSingleton pack
pack UpLoSingleton Upper
Upper

lowerTriangularP ::
   PackingSingleton pack -> Order -> size -> LowerTriangularP pack size
lowerTriangularP :: forall pack size.
PackingSingleton pack
-> Order -> size -> LowerTriangularP pack size
lowerTriangularP PackingSingleton pack
pack = PackingSingleton pack
-> UpLoSingleton Lower
-> Order
-> size
-> TriangularP pack Lower size
forall pack uplo size.
PackingSingleton pack
-> UpLoSingleton uplo
-> Order
-> size
-> TriangularP pack uplo size
triangularP PackingSingleton pack
pack UpLoSingleton Lower
Lower


type SymmetricP pack = Mosaic pack SimpleMirror Shape.Upper
type Symmetric = SymmetricP Packed

symmetric :: Order -> size -> Symmetric size
symmetric :: forall size. Order -> size -> Symmetric size
symmetric = PackingSingleton Packed -> Order -> size -> SymmetricP Packed size
forall pack size.
PackingSingleton pack -> Order -> size -> SymmetricP pack size
symmetricP PackingSingleton Packed
Packed

symmetricP :: PackingSingleton pack -> Order -> size -> SymmetricP pack size
symmetricP :: forall pack size.
PackingSingleton pack -> Order -> size -> SymmetricP pack size
symmetricP PackingSingleton pack
pack = PackingSingleton pack
-> MirrorSingleton SimpleMirror
-> UpLoSingleton Upper
-> Order
-> size
-> Mosaic pack SimpleMirror Upper size
forall pack mirror uplo size.
PackingSingleton pack
-> MirrorSingleton mirror
-> UpLoSingleton uplo
-> Order
-> size
-> Mosaic pack mirror uplo size
Mosaic PackingSingleton pack
pack MirrorSingleton SimpleMirror
SimpleMirror UpLoSingleton Upper
Upper

symmetricFromHermitian :: HermitianP pack size -> SymmetricP pack size
symmetricFromHermitian :: forall pack size. HermitianP pack size -> SymmetricP pack size
symmetricFromHermitian (Mosaic PackingSingleton pack
pack MirrorSingleton ConjugateMirror
ConjugateMirror UpLoSingleton Upper
upper Order
order size
size) =
   PackingSingleton pack
-> MirrorSingleton SimpleMirror
-> UpLoSingleton Upper
-> Order
-> size
-> Mosaic pack SimpleMirror Upper size
forall pack mirror uplo size.
PackingSingleton pack
-> MirrorSingleton mirror
-> UpLoSingleton uplo
-> Order
-> size
-> Mosaic pack mirror uplo size
Mosaic PackingSingleton pack
pack MirrorSingleton SimpleMirror
SimpleMirror UpLoSingleton Upper
upper Order
order size
size


type HermitianP pack = Mosaic pack ConjugateMirror Shape.Upper
type Hermitian = HermitianP Packed

hermitian :: Order -> size -> Hermitian size
hermitian :: forall size. Order -> size -> Hermitian size
hermitian = PackingSingleton Packed -> Order -> size -> HermitianP Packed size
forall pack size.
PackingSingleton pack -> Order -> size -> HermitianP pack size
hermitianP PackingSingleton Packed
Packed

hermitianP :: PackingSingleton pack -> Order -> size -> HermitianP pack size
hermitianP :: forall pack size.
PackingSingleton pack -> Order -> size -> HermitianP pack size
hermitianP PackingSingleton pack
pack = PackingSingleton pack
-> MirrorSingleton ConjugateMirror
-> UpLoSingleton Upper
-> Order
-> size
-> Mosaic pack ConjugateMirror Upper size
forall pack mirror uplo size.
PackingSingleton pack
-> MirrorSingleton mirror
-> UpLoSingleton uplo
-> Order
-> size
-> Mosaic pack mirror uplo size
Mosaic PackingSingleton pack
pack MirrorSingleton ConjugateMirror
ConjugateMirror UpLoSingleton Upper
Upper

hermitianFromSymmetric :: SymmetricP pack size -> HermitianP pack size
hermitianFromSymmetric :: forall pack size. SymmetricP pack size -> HermitianP pack size
hermitianFromSymmetric (Mosaic PackingSingleton pack
pack MirrorSingleton SimpleMirror
SimpleMirror UpLoSingleton Upper
upper Order
order size
size) =
   PackingSingleton pack
-> MirrorSingleton ConjugateMirror
-> UpLoSingleton Upper
-> Order
-> size
-> Mosaic pack ConjugateMirror Upper size
forall pack mirror uplo size.
PackingSingleton pack
-> MirrorSingleton mirror
-> UpLoSingleton uplo
-> Order
-> size
-> Mosaic pack mirror uplo size
Mosaic PackingSingleton pack
pack MirrorSingleton ConjugateMirror
ConjugateMirror UpLoSingleton Upper
upper Order
order size
size

uploFromOrder :: Order -> Char
uploFromOrder :: Order -> Char
uploFromOrder Order
RowMajor = Char
'L'
uploFromOrder Order
ColumnMajor = Char
'U'



newtype Bands offDiag = Bands (UnaryProxy offDiag) deriving (Bands offDiag -> Bands offDiag -> Bool
(Bands offDiag -> Bands offDiag -> Bool)
-> (Bands offDiag -> Bands offDiag -> Bool) -> Eq (Bands offDiag)
forall offDiag. Bands offDiag -> Bands offDiag -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall offDiag. Bands offDiag -> Bands offDiag -> Bool
== :: Bands offDiag -> Bands offDiag -> Bool
$c/= :: forall offDiag. Bands offDiag -> Bands offDiag -> Bool
/= :: Bands offDiag -> Bands offDiag -> Bool
Eq, Int -> Bands offDiag -> String -> String
[Bands offDiag] -> String -> String
Bands offDiag -> String
(Int -> Bands offDiag -> String -> String)
-> (Bands offDiag -> String)
-> ([Bands offDiag] -> String -> String)
-> Show (Bands offDiag)
forall offDiag.
Natural offDiag =>
Int -> Bands offDiag -> String -> String
forall offDiag.
Natural offDiag =>
[Bands offDiag] -> String -> String
forall offDiag. Natural offDiag => Bands offDiag -> String
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: forall offDiag.
Natural offDiag =>
Int -> Bands offDiag -> String -> String
showsPrec :: Int -> Bands offDiag -> String -> String
$cshow :: forall offDiag. Natural offDiag => Bands offDiag -> String
show :: Bands offDiag -> String
$cshowList :: forall offDiag.
Natural offDiag =>
[Bands offDiag] -> String -> String
showList :: [Bands offDiag] -> String -> String
Show)

type family GetBands strip
type instance GetBands (Bands offDiag) = offDiag

type Empty = Bands TypeNum.U0
data Filled = Filled deriving (Filled -> Filled -> Bool
(Filled -> Filled -> Bool)
-> (Filled -> Filled -> Bool) -> Eq Filled
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Filled -> Filled -> Bool
== :: Filled -> Filled -> Bool
$c/= :: Filled -> Filled -> Bool
/= :: Filled -> Filled -> Bool
Eq, Int -> Filled -> String -> String
[Filled] -> String -> String
Filled -> String
(Int -> Filled -> String -> String)
-> (Filled -> String)
-> ([Filled] -> String -> String)
-> Show Filled
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> Filled -> String -> String
showsPrec :: Int -> Filled -> String -> String
$cshow :: Filled -> String
show :: Filled -> String
$cshowList :: [Filled] -> String -> String
showList :: [Filled] -> String -> String
Show)

u0 :: UnaryProxy TypeNum.U0
u0 :: UnaryProxy U0
u0 = Proxy U0 -> UnaryProxy U0
forall n. Proxy n -> Proxy (Un n)
unary Proxy U0
TypeNum.u0

empty :: Empty
empty :: Empty
empty = UnaryProxy U0 -> Empty
forall offDiag. UnaryProxy offDiag -> Bands offDiag
Bands UnaryProxy U0
u0

type family TriTransposed uplo
type instance TriTransposed Shape.Lower = Shape.Upper
type instance TriTransposed Shape.Upper = Shape.Lower

triangularTranspose ::
   (UpLo uplo) =>
   Mosaic pack mirror uplo sh ->
   Mosaic pack mirror (TriTransposed uplo) sh
triangularTranspose :: forall uplo pack mirror sh.
UpLo uplo =>
Mosaic pack mirror uplo sh
-> Mosaic pack mirror (TriTransposed uplo) sh
triangularTranspose (Mosaic PackingSingleton pack
pack MirrorSingleton mirror
mirror UpLoSingleton uplo
uplo Order
order sh
size) =
   PackingSingleton pack
-> MirrorSingleton mirror
-> UpLoSingleton (TriTransposed uplo)
-> Order
-> sh
-> Mosaic pack mirror (TriTransposed uplo) sh
forall pack mirror uplo size.
PackingSingleton pack
-> MirrorSingleton mirror
-> UpLoSingleton uplo
-> Order
-> size
-> Mosaic pack mirror uplo size
Mosaic PackingSingleton pack
pack MirrorSingleton mirror
mirror
      (case UpLoSingleton uplo
uplo of
         UpLoSingleton uplo
Lower -> UpLoSingleton Upper
UpLoSingleton (TriTransposed uplo)
Upper
         UpLoSingleton uplo
Upper -> UpLoSingleton Lower
UpLoSingleton (TriTransposed uplo)
Lower)
      (Order -> Order
flipOrder Order
order)
      sh
size


autoUplo :: (UpLo uplo) => UpLoSingleton uplo
autoUplo :: forall uplo. UpLo uplo => UpLoSingleton uplo
autoUplo = UpLoSingleton Upper -> UpLoSingleton Lower -> UpLoSingleton uplo
forall uplo (f :: * -> *).
UpLo uplo =>
f Upper -> f Lower -> f uplo
forall (f :: * -> *). f Upper -> f Lower -> f uplo
switchUpLo UpLoSingleton Upper
Upper UpLoSingleton Lower
Lower

uploOrder :: UpLoSingleton uplo -> Order -> Order
uploOrder :: forall uplo. UpLoSingleton uplo -> Order -> Order
uploOrder UpLoSingleton uplo
uplo = case UpLoSingleton uplo
uplo of UpLoSingleton uplo
Lower -> Order -> Order
flipOrder; UpLoSingleton uplo
Upper -> Order -> Order
forall a. a -> a
id


class UpLo uplo where
   switchUpLo :: f Shape.Upper -> f Shape.Lower -> f uplo

instance UpLo Shape.Upper where
   switchUpLo :: forall (f :: * -> *). f Upper -> f Lower -> f Upper
switchUpLo f Upper
f f Lower
_ = f Upper
f

instance UpLo Shape.Lower where
   switchUpLo :: forall (f :: * -> *). f Upper -> f Lower -> f Lower
switchUpLo f Upper
_ f Lower
f = f Lower
f

data UpLoSingleton uplo where
   Lower :: UpLoSingleton Shape.Lower
   Upper :: UpLoSingleton Shape.Upper

instance Eq (UpLoSingleton uplo) where
   UpLoSingleton uplo
Lower == :: UpLoSingleton uplo -> UpLoSingleton uplo -> Bool
== UpLoSingleton uplo
Lower  =  Bool
True
   UpLoSingleton uplo
Upper == UpLoSingleton uplo
Upper  =  Bool
True

instance Show (UpLoSingleton uplo) where
   show :: UpLoSingleton uplo -> String
show UpLoSingleton uplo
Lower = String
"Lower"
   show UpLoSingleton uplo
Upper = String
"Upper"

instance NFData (UpLoSingleton uplo) where
   rnf :: UpLoSingleton uplo -> ()
rnf UpLoSingleton uplo
Lower = ()
   rnf UpLoSingleton uplo
Upper = ()

uploChar :: UpLoSingleton uplo -> Char
uploChar :: forall uplo. UpLoSingleton uplo -> Char
uploChar UpLoSingleton uplo
Lower = Char
'L'
uploChar UpLoSingleton uplo
Upper = Char
'U'


instance
   (UpLo uplo, NFData size) =>
      NFData (Mosaic pack mirror uplo size) where
   rnf :: Mosaic pack mirror uplo size -> ()
rnf (Mosaic PackingSingleton pack
pack MirrorSingleton mirror
mirror UpLoSingleton uplo
uplo Order
order size
size) =
      (PackingSingleton pack, MirrorSingleton mirror, UpLoSingleton uplo,
 Order, size)
-> ()
forall a. NFData a => a -> ()
rnf (PackingSingleton pack
pack, MirrorSingleton mirror
mirror, UpLoSingleton uplo
uplo, Order
order, size
size)

instance
   (UpLo uplo, Shape.C size) =>
      Shape.C (Mosaic pack mirror uplo size) where

   size :: Mosaic pack mirror uplo size -> Int
size (Mosaic PackingSingleton pack
pack MirrorSingleton mirror
_mirror UpLoSingleton uplo
_uplo Order
order size
size) =
      case PackingSingleton pack
pack of
         PackingSingleton pack
Packed -> Int -> Int
triangleSize (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ size -> Int
forall sh. C sh => sh -> Int
Shape.size size
size
         PackingSingleton pack
Unpacked -> Square size -> Int
forall sh. C sh => sh -> Int
Shape.size (Square size -> Int) -> Square size -> Int
forall a b. (a -> b) -> a -> b
$ Order -> size -> Square size
forall sh. Order -> sh -> Square sh
square Order
order size
size

instance
   (UpLo uplo, Shape.Indexed size) =>
      Shape.Indexed (Mosaic pack mirror uplo size) where
   type Index (Mosaic pack mirror uplo size) =
         (Shape.Index size, Shape.Index size)

   indices :: Mosaic pack mirror uplo size
-> [Index (Mosaic pack mirror uplo size)]
indices (Mosaic PackingSingleton pack
pack MirrorSingleton mirror
_mirror UpLoSingleton uplo
uplo Order
order size
size) =
      case (PackingSingleton pack
pack,UpLoSingleton uplo
uplo) of
         (PackingSingleton pack
Unpacked,UpLoSingleton uplo
_) -> Square size -> [Index (Square size)]
forall sh. Indexed sh => sh -> [Index sh]
Shape.indices (Square size -> [Index (Square size)])
-> Square size -> [Index (Square size)]
forall a b. (a -> b) -> a -> b
$ Order -> size -> Square size
forall sh. Order -> sh -> Square sh
square Order
order size
size
         (PackingSingleton pack
Packed,UpLoSingleton uplo
Upper) -> Order -> size -> [(Index size, Index size)]
forall sh. Indexed sh => Order -> sh -> [(Index sh, Index sh)]
triangleIndices Order
order size
size
         (PackingSingleton pack
Packed,UpLoSingleton uplo
Lower) -> ((Index size, Index size) -> Index (Mosaic pack mirror uplo size))
-> [(Index size, Index size)]
-> [Index (Mosaic pack mirror uplo size)]
forall a b. (a -> b) -> [a] -> [b]
map (Index size, Index size) -> (Index size, Index size)
(Index size, Index size) -> Index (Mosaic pack mirror uplo size)
forall a b. (a, b) -> (b, a)
swap ([(Index size, Index size)]
 -> [Index (Mosaic pack mirror uplo size)])
-> [(Index size, Index size)]
-> [Index (Mosaic pack mirror uplo size)]
forall a b. (a -> b) -> a -> b
$ Order -> size -> [(Index size, Index size)]
forall sh. Indexed sh => Order -> sh -> [(Index sh, Index sh)]
triangleIndices (Order -> Order
flipOrder Order
order) size
size

   unifiedOffset :: forall check.
Checking check =>
Mosaic pack mirror uplo size
-> Index (Mosaic pack mirror uplo size) -> Result check Int
unifiedOffset (Mosaic PackingSingleton pack
pack MirrorSingleton mirror
_mirror UpLoSingleton uplo
uplo Order
order size
size) =
      case (PackingSingleton pack
pack,UpLoSingleton uplo
uplo) of
         (PackingSingleton pack
Unpacked,UpLoSingleton uplo
_) -> Square size -> Index (Square size) -> Result check Int
forall sh check.
(Indexed sh, Checking check) =>
sh -> Index sh -> Result check Int
forall check.
Checking check =>
Square size -> Index (Square size) -> Result check Int
Shape.unifiedOffset (Square size -> Index (Square size) -> Result check Int)
-> Square size -> Index (Square size) -> Result check Int
forall a b. (a -> b) -> a -> b
$ Order -> size -> Square size
forall sh. Order -> sh -> Square sh
square Order
order size
size
         (PackingSingleton pack
Packed,UpLoSingleton uplo
Upper) -> Order -> size -> (Index size, Index size) -> Result check Int
forall check sh.
(Checking check, Indexed sh) =>
Order -> sh -> (Index sh, Index sh) -> Result check Int
triangleOffset Order
order size
size
         (PackingSingleton pack
Packed,UpLoSingleton uplo
Lower) -> Order -> size -> (Index size, Index size) -> Result check Int
forall check sh.
(Checking check, Indexed sh) =>
Order -> sh -> (Index sh, Index sh) -> Result check Int
triangleOffset (Order -> Order
flipOrder Order
order) size
size ((Index size, Index size) -> Result check Int)
-> ((Index size, Index size) -> (Index size, Index size))
-> (Index size, Index size)
-> Result check Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Index size, Index size) -> (Index size, Index size)
forall a b. (a, b) -> (b, a)
swap

   unifiedSizeOffset :: forall check.
Checking check =>
Mosaic pack mirror uplo size
-> (Int, Index (Mosaic pack mirror uplo size) -> Result check Int)
unifiedSizeOffset (Mosaic PackingSingleton pack
pack MirrorSingleton mirror
_mirror UpLoSingleton uplo
uplo Order
order size
size) =
      case (PackingSingleton pack
pack,UpLoSingleton uplo
uplo) of
         (PackingSingleton pack
Unpacked,UpLoSingleton uplo
_) -> Square size -> (Int, Index (Square size) -> Result check Int)
forall sh check.
(Indexed sh, Checking check) =>
sh -> (Int, Index sh -> Result check Int)
forall check.
Checking check =>
Square size -> (Int, Index (Square size) -> Result check Int)
Shape.unifiedSizeOffset (Square size -> (Int, Index (Square size) -> Result check Int))
-> Square size -> (Int, Index (Square size) -> Result check Int)
forall a b. (a -> b) -> a -> b
$ Order -> size -> Square size
forall sh. Order -> sh -> Square sh
square Order
order size
size
         (PackingSingleton pack
Packed,UpLoSingleton uplo
Upper) -> Order
-> size -> (Int, (Index size, Index size) -> Result check Int)
forall check sh.
(Checking check, Indexed sh) =>
Order -> sh -> (Int, (Index sh, Index sh) -> Result check Int)
triangleSizeOffset Order
order size
size
         (PackingSingleton pack
Packed,UpLoSingleton uplo
Lower) ->
            (((Index size, Index size) -> Result check Int)
 -> Index (Mosaic pack mirror uplo size) -> Result check Int)
-> (Int, (Index size, Index size) -> Result check Int)
-> (Int, Index (Mosaic pack mirror uplo size) -> Result check Int)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd (((Index size, Index size) -> Result check Int)
-> (Index (Mosaic pack mirror uplo size)
    -> (Index size, Index size))
-> Index (Mosaic pack mirror uplo size)
-> Result check Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Index size, Index size) -> (Index size, Index size)
Index (Mosaic pack mirror uplo size) -> (Index size, Index size)
forall a b. (a, b) -> (b, a)
swap) ((Int, (Index size, Index size) -> Result check Int)
 -> (Int, Index (Mosaic pack mirror uplo size) -> Result check Int))
-> (Int, (Index size, Index size) -> Result check Int)
-> (Int, Index (Mosaic pack mirror uplo size) -> Result check Int)
forall a b. (a -> b) -> a -> b
$ Order
-> size -> (Int, (Index size, Index size) -> Result check Int)
forall check sh.
(Checking check, Indexed sh) =>
Order -> sh -> (Int, (Index sh, Index sh) -> Result check Int)
triangleSizeOffset (Order -> Order
flipOrder Order
order) size
size

   inBounds :: Mosaic pack mirror uplo size
-> Index (Mosaic pack mirror uplo size) -> Bool
inBounds (Mosaic PackingSingleton pack
pack MirrorSingleton mirror
_mirror UpLoSingleton uplo
uplo Order
_ size
size) ix :: Index (Mosaic pack mirror uplo size)
ix@(Index size
r,Index size
c) =
      (size, size) -> Index (size, size) -> Bool
forall sh. Indexed sh => sh -> Index sh -> Bool
Shape.inBounds (size
size,size
size) Index (size, size)
Index (Mosaic pack mirror uplo size)
ix
      Bool -> Bool -> Bool
&&
      case (PackingSingleton pack
pack,UpLoSingleton uplo
uplo) of
         (PackingSingleton pack
Unpacked,UpLoSingleton uplo
_) -> Bool
True
         (PackingSingleton pack
Packed,UpLoSingleton uplo
Upper) -> size -> Index size -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset size
size Index size
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= size -> Index size -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset size
size Index size
c
         (PackingSingleton pack
Packed,UpLoSingleton uplo
Lower) -> size -> Index size -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset size
size Index size
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= size -> Index size -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset size
size Index size
c

instance
   (UpLo uplo, Shape.InvIndexed size) =>
      Shape.InvIndexed (Mosaic pack mirror uplo size) where

   unifiedIndexFromOffset :: forall check.
Checking check =>
Mosaic pack mirror uplo size
-> Int -> Result check (Index (Mosaic pack mirror uplo size))
unifiedIndexFromOffset (Mosaic PackingSingleton pack
pack MirrorSingleton mirror
_mirror UpLoSingleton uplo
uplo Order
order size
size) Int
k =
      case (PackingSingleton pack
pack,UpLoSingleton uplo
uplo) of
         (PackingSingleton pack
Unpacked,UpLoSingleton uplo
_) ->
            Square size -> Int -> Result check (Index (Square size))
forall sh check.
(InvIndexed sh, Checking check) =>
sh -> Int -> Result check (Index sh)
forall check.
Checking check =>
Square size -> Int -> Result check (Index (Square size))
Shape.unifiedIndexFromOffset (Order -> size -> Square size
forall sh. Order -> sh -> Square sh
square Order
order size
size) Int
k
         (PackingSingleton pack
Packed,UpLoSingleton uplo
Upper) -> Order -> size -> Int -> Result check (Index size, Index size)
forall check sh.
(Checking check, InvIndexed sh) =>
Order -> sh -> Int -> Result check (Index sh, Index sh)
triangleIndexFromOffset Order
order size
size Int
k
         (PackingSingleton pack
Packed,UpLoSingleton uplo
Lower) ->
            (Index size, Index size) -> (Index size, Index size)
forall a b. (a, b) -> (b, a)
swap ((Index size, Index size) -> (Index size, Index size))
-> Result check (Index size, Index size)
-> Result check (Index size, Index size)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Order -> size -> Int -> Result check (Index size, Index size)
forall check sh.
(Checking check, InvIndexed sh) =>
Order -> sh -> Int -> Result check (Index sh, Index sh)
triangleIndexFromOffset (Order -> Order
flipOrder Order
order) size
size Int
k


squareRootDouble :: Int -> Double
squareRootDouble :: Int -> Double
squareRootDouble = Double -> Double
forall a. Floating a => a -> a
sqrt (Double -> Double) -> (Int -> Double) -> Int -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral

squareExtent :: String -> Int -> Int
squareExtent :: String -> Int -> Int
squareExtent String
name Int
size =
   let n :: Int
n = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
round (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Double
squareRootDouble Int
size
   in if Int
size Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
n
        then Int
n
        else String -> Int
forall a. HasCallStack => String -> a
error (String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": no square number of elements")


triangleRootDouble :: Int -> Double
triangleRootDouble :: Int -> Double
triangleRootDouble = Double -> Double
forall a. Floating a => a -> a
triangleRoot (Double -> Double) -> (Int -> Double) -> Int -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral

triangleExtent :: String -> Int -> Int
triangleExtent :: String -> Int -> Int
triangleExtent String
name Int
size =
   let n :: Int
n = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
round (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Double
triangleRootDouble Int
size
   in if Int
size Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Int
triangleSize Int
n
        then Int
n
        else String -> Int
forall a. HasCallStack => String -> a
error (String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": no triangular number of elements")

triangleIndices ::
   (Shape.Indexed sh) => Order -> sh -> [(Shape.Index sh, Shape.Index sh)]
triangleIndices :: forall sh. Indexed sh => Order -> sh -> [(Index sh, Index sh)]
triangleIndices Order
RowMajor = UpperTriangular sh -> [(Index sh, Index sh)]
UpperTriangular sh -> [Index (UpperTriangular sh)]
forall sh. Indexed sh => sh -> [Index sh]
Shape.indices (UpperTriangular sh -> [(Index sh, Index sh)])
-> (sh -> UpperTriangular sh) -> sh -> [(Index sh, Index sh)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. sh -> UpperTriangular sh
forall size. size -> UpperTriangular size
Shape.upperTriangular
triangleIndices Order
ColumnMajor = ((Index sh, Index sh) -> (Index sh, Index sh))
-> [(Index sh, Index sh)] -> [(Index sh, Index sh)]
forall a b. (a -> b) -> [a] -> [b]
map (Index sh, Index sh) -> (Index sh, Index sh)
forall a b. (a, b) -> (b, a)
swap ([(Index sh, Index sh)] -> [(Index sh, Index sh)])
-> (sh -> [(Index sh, Index sh)]) -> sh -> [(Index sh, Index sh)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LowerTriangular sh -> [(Index sh, Index sh)]
LowerTriangular sh -> [Index (LowerTriangular sh)]
forall sh. Indexed sh => sh -> [Index sh]
Shape.indices (LowerTriangular sh -> [(Index sh, Index sh)])
-> (sh -> LowerTriangular sh) -> sh -> [(Index sh, Index sh)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. sh -> LowerTriangular sh
forall size. size -> LowerTriangular size
Shape.lowerTriangular

triangleOffset ::
   (Shape.Checking check, Shape.Indexed sh) =>
   Order -> sh -> (Shape.Index sh, Shape.Index sh) -> Shape.Result check Int
triangleOffset :: forall check sh.
(Checking check, Indexed sh) =>
Order -> sh -> (Index sh, Index sh) -> Result check Int
triangleOffset Order
order sh
size =
   case Order
order of
      Order
RowMajor    -> UpperTriangular sh
-> Index (UpperTriangular sh) -> Result check Int
forall sh check.
(Indexed sh, Checking check) =>
sh -> Index sh -> Result check Int
forall check.
Checking check =>
UpperTriangular sh
-> Index (UpperTriangular sh) -> Result check Int
Shape.unifiedOffset (sh -> UpperTriangular sh
forall size. size -> UpperTriangular size
Shape.upperTriangular sh
size)
      Order
ColumnMajor -> LowerTriangular sh
-> Index (LowerTriangular sh) -> Result check Int
forall sh check.
(Indexed sh, Checking check) =>
sh -> Index sh -> Result check Int
forall check.
Checking check =>
LowerTriangular sh
-> Index (LowerTriangular sh) -> Result check Int
Shape.unifiedOffset (sh -> LowerTriangular sh
forall size. size -> LowerTriangular size
Shape.lowerTriangular sh
size) ((Index sh, Index sh) -> Result check Int)
-> ((Index sh, Index sh) -> (Index sh, Index sh))
-> (Index sh, Index sh)
-> Result check Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Index sh, Index sh) -> (Index sh, Index sh)
forall a b. (a, b) -> (b, a)
swap

triangleSizeOffset ::
   (Shape.Checking check, Shape.Indexed sh) =>
   Order -> sh ->
   (Int, (Shape.Index sh, Shape.Index sh) -> Shape.Result check Int)
triangleSizeOffset :: forall check sh.
(Checking check, Indexed sh) =>
Order -> sh -> (Int, (Index sh, Index sh) -> Result check Int)
triangleSizeOffset Order
order sh
size =
   case Order
order of
      Order
RowMajor -> UpperTriangular sh
-> (Int, Index (UpperTriangular sh) -> Result check Int)
forall sh check.
(Indexed sh, Checking check) =>
sh -> (Int, Index sh -> Result check Int)
forall check.
Checking check =>
UpperTriangular sh
-> (Int, Index (UpperTriangular sh) -> Result check Int)
Shape.unifiedSizeOffset (sh -> UpperTriangular sh
forall size. size -> UpperTriangular size
Shape.upperTriangular sh
size)
      Order
ColumnMajor ->
         (((Index sh, Index sh) -> Result check Int)
 -> (Index sh, Index sh) -> Result check Int)
-> (Int, (Index sh, Index sh) -> Result check Int)
-> (Int, (Index sh, Index sh) -> Result check Int)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd (((Index sh, Index sh) -> Result check Int)
-> ((Index sh, Index sh) -> (Index sh, Index sh))
-> (Index sh, Index sh)
-> Result check Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Index sh, Index sh) -> (Index sh, Index sh)
forall a b. (a, b) -> (b, a)
swap) ((Int, (Index sh, Index sh) -> Result check Int)
 -> (Int, (Index sh, Index sh) -> Result check Int))
-> (Int, (Index sh, Index sh) -> Result check Int)
-> (Int, (Index sh, Index sh) -> Result check Int)
forall a b. (a -> b) -> a -> b
$ LowerTriangular sh
-> (Int, Index (LowerTriangular sh) -> Result check Int)
forall sh check.
(Indexed sh, Checking check) =>
sh -> (Int, Index sh -> Result check Int)
forall check.
Checking check =>
LowerTriangular sh
-> (Int, Index (LowerTriangular sh) -> Result check Int)
Shape.unifiedSizeOffset (sh -> LowerTriangular sh
forall size. size -> LowerTriangular size
Shape.lowerTriangular sh
size)

triangleIndexFromOffset ::
   (Shape.Checking check, Shape.InvIndexed sh) =>
   Order -> sh -> Int -> Shape.Result check (Shape.Index sh, Shape.Index sh)
triangleIndexFromOffset :: forall check sh.
(Checking check, InvIndexed sh) =>
Order -> sh -> Int -> Result check (Index sh, Index sh)
triangleIndexFromOffset Order
order sh
size =
   case Order
order of
      Order
RowMajor -> UpperTriangular sh
-> Int -> Result check (Index (UpperTriangular sh))
forall sh check.
(InvIndexed sh, Checking check) =>
sh -> Int -> Result check (Index sh)
forall check.
Checking check =>
UpperTriangular sh
-> Int -> Result check (Index (UpperTriangular sh))
Shape.unifiedIndexFromOffset (sh -> UpperTriangular sh
forall size. size -> UpperTriangular size
Shape.upperTriangular sh
size)
      Order
ColumnMajor ->
         ((Index sh, Index sh) -> (Index sh, Index sh))
-> Result check (Index sh, Index sh)
-> Result check (Index sh, Index sh)
forall a b. (a -> b) -> Result check a -> Result check b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Index sh, Index sh) -> (Index sh, Index sh)
forall a b. (a, b) -> (b, a)
swap (Result check (Index sh, Index sh)
 -> Result check (Index sh, Index sh))
-> (Int -> Result check (Index sh, Index sh))
-> Int
-> Result check (Index sh, Index sh)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LowerTriangular sh
-> Int -> Result check (Index (LowerTriangular sh))
forall sh check.
(InvIndexed sh, Checking check) =>
sh -> Int -> Result check (Index sh)
forall check.
Checking check =>
LowerTriangular sh
-> Int -> Result check (Index (LowerTriangular sh))
Shape.unifiedIndexFromOffset (sh -> LowerTriangular sh
forall size. size -> LowerTriangular size
Shape.lowerTriangular sh
size)


type UnaryProxy a = Proxy (Unary.Un a)

data Banded sub super meas vert horiz height width =
   Banded {
      forall sub super meas vert horiz height width.
Banded sub super meas vert horiz height width
-> (UnaryProxy sub, UnaryProxy super)
bandedOffDiagonals :: (UnaryProxy sub, UnaryProxy super),
      forall sub super meas vert horiz height width.
Banded sub super meas vert horiz height width -> Order
bandedOrder :: Order,
      forall sub super meas vert horiz height width.
Banded sub super meas vert horiz height width
-> Extent meas vert horiz height width
bandedExtent :: Extent meas vert horiz height width
   } deriving (Banded sub super meas vert horiz height width
-> Banded sub super meas vert horiz height width -> Bool
(Banded sub super meas vert horiz height width
 -> Banded sub super meas vert horiz height width -> Bool)
-> (Banded sub super meas vert horiz height width
    -> Banded sub super meas vert horiz height width -> Bool)
-> Eq (Banded sub super meas vert horiz height width)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall sub super meas vert horiz height width.
(Measure meas, C vert, C horiz, Eq height, Eq width) =>
Banded sub super meas vert horiz height width
-> Banded sub super meas vert horiz height width -> Bool
$c== :: forall sub super meas vert horiz height width.
(Measure meas, C vert, C horiz, Eq height, Eq width) =>
Banded sub super meas vert horiz height width
-> Banded sub super meas vert horiz height width -> Bool
== :: Banded sub super meas vert horiz height width
-> Banded sub super meas vert horiz height width -> Bool
$c/= :: forall sub super meas vert horiz height width.
(Measure meas, C vert, C horiz, Eq height, Eq width) =>
Banded sub super meas vert horiz height width
-> Banded sub super meas vert horiz height width -> Bool
/= :: Banded sub super meas vert horiz height width
-> Banded sub super meas vert horiz height width -> Bool
Eq, Int
-> Banded sub super meas vert horiz height width
-> String
-> String
[Banded sub super meas vert horiz height width] -> String -> String
Banded sub super meas vert horiz height width -> String
(Int
 -> Banded sub super meas vert horiz height width
 -> String
 -> String)
-> (Banded sub super meas vert horiz height width -> String)
-> ([Banded sub super meas vert horiz height width]
    -> String -> String)
-> Show (Banded sub super meas vert horiz height width)
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
forall sub super meas vert horiz height width.
(Natural sub, Natural super, Measure meas, C vert, C horiz,
 Show height, Show width) =>
Int
-> Banded sub super meas vert horiz height width
-> String
-> String
forall sub super meas vert horiz height width.
(Natural sub, Natural super, Measure meas, C vert, C horiz,
 Show height, Show width) =>
[Banded sub super meas vert horiz height width] -> String -> String
forall sub super meas vert horiz height width.
(Natural sub, Natural super, Measure meas, C vert, C horiz,
 Show height, Show width) =>
Banded sub super meas vert horiz height width -> String
$cshowsPrec :: forall sub super meas vert horiz height width.
(Natural sub, Natural super, Measure meas, C vert, C horiz,
 Show height, Show width) =>
Int
-> Banded sub super meas vert horiz height width
-> String
-> String
showsPrec :: Int
-> Banded sub super meas vert horiz height width
-> String
-> String
$cshow :: forall sub super meas vert horiz height width.
(Natural sub, Natural super, Measure meas, C vert, C horiz,
 Show height, Show width) =>
Banded sub super meas vert horiz height width -> String
show :: Banded sub super meas vert horiz height width -> String
$cshowList :: forall sub super meas vert horiz height width.
(Natural sub, Natural super, Measure meas, C vert, C horiz,
 Show height, Show width) =>
[Banded sub super meas vert horiz height width] -> String -> String
showList :: [Banded sub super meas vert horiz height width] -> String -> String
Show)

type BandedGeneral sub super =
      Banded sub super Extent.Size Extent.Big Extent.Big
type BandedSquareMeas sub super meas height width =
      Banded sub super meas Extent.Small Extent.Small height width
type BandedSquare sub super size =
      BandedSquareMeas sub super Extent.Shape size size

type BandedLowerTriangular sub size = BandedSquare sub TypeNum.U0 size
type BandedUpperTriangular super size = BandedSquare TypeNum.U0 super size

type Diagonal size = BandedSquare TypeNum.U0 TypeNum.U0 size
type RectangularDiagonal = Banded TypeNum.U0 TypeNum.U0


bandedHeight ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
   Banded sub super meas vert horiz height width -> height
bandedHeight :: forall meas vert horiz sub super height width.
(Measure meas, C vert, C horiz) =>
Banded sub super meas vert horiz height width -> height
bandedHeight = Extent meas vert horiz height width -> height
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> height
Extent.height (Extent meas vert horiz height width -> height)
-> (Banded sub super meas vert horiz height width
    -> Extent meas vert horiz height width)
-> Banded sub super meas vert horiz height width
-> height
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Banded sub super meas vert horiz height width
-> Extent meas vert horiz height width
forall sub super meas vert horiz height width.
Banded sub super meas vert horiz height width
-> Extent meas vert horiz height width
bandedExtent

bandedWidth ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
   Banded sub super meas vert horiz height width -> width
bandedWidth :: forall meas vert horiz sub super height width.
(Measure meas, C vert, C horiz) =>
Banded sub super meas vert horiz height width -> width
bandedWidth = Extent meas vert horiz height width -> width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
Extent.width (Extent meas vert horiz height width -> width)
-> (Banded sub super meas vert horiz height width
    -> Extent meas vert horiz height width)
-> Banded sub super meas vert horiz height width
-> width
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Banded sub super meas vert horiz height width
-> Extent meas vert horiz height width
forall sub super meas vert horiz height width.
Banded sub super meas vert horiz height width
-> Extent meas vert horiz height width
bandedExtent

bandedMapExtent ::
   Extent.Map measA vertA horizA measB vertB horizB height width ->
   Banded sub super measA vertA horizA height width ->
   Banded sub super measB vertB horizB height width
bandedMapExtent :: forall measA vertA horizA measB vertB horizB height width sub
       super.
Map measA vertA horizA measB vertB horizB height width
-> Banded sub super measA vertA horizA height width
-> Banded sub super measB vertB horizB height width
bandedMapExtent Map measA vertA horizA measB vertB horizB height width
f (Banded (UnaryProxy sub, UnaryProxy super)
offDiag Order
order Extent measA vertA horizA height width
extent) =
   (UnaryProxy sub, UnaryProxy super)
-> Order
-> Extent measB vertB horizB height width
-> Banded sub super measB vertB horizB height width
forall sub super meas vert horiz height width.
(UnaryProxy sub, UnaryProxy super)
-> Order
-> Extent meas vert horiz height width
-> Banded sub super meas vert horiz height width
Banded (UnaryProxy sub, UnaryProxy super)
offDiag Order
order (Extent measB vertB horizB height width
 -> Banded sub super measB vertB horizB height width)
-> Extent measB vertB horizB height width
-> Banded sub super measB vertB horizB height width
forall a b. (a -> b) -> a -> b
$ Map measA vertA horizA measB vertB horizB height width
f Extent measA vertA horizA height width
extent

bandedBreadth ::
   (Unary.Natural sub, Unary.Natural super) =>
   (UnaryProxy sub, UnaryProxy super) -> Int
bandedBreadth :: forall sub super.
(Natural sub, Natural super) =>
(UnaryProxy sub, UnaryProxy super) -> Int
bandedBreadth (UnaryProxy sub
sub,UnaryProxy super
super) =
   UnaryProxy sub -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy sub
sub Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ UnaryProxy super -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy super
super

numOffDiagonals ::
   (Unary.Natural sub, Unary.Natural super) =>
   Order -> (UnaryProxy sub, UnaryProxy super) -> (Int,Int)
numOffDiagonals :: forall sub super.
(Natural sub, Natural super) =>
Order -> (UnaryProxy sub, UnaryProxy super) -> (Int, Int)
numOffDiagonals Order
order (UnaryProxy sub
sub,UnaryProxy super
super) =
   Order -> (Int, Int) -> (Int, Int)
forall a. Order -> (a, a) -> (a, a)
swapOnRowMajor Order
order (UnaryProxy sub -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy sub
sub, UnaryProxy super -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy super
super)

natFromProxy :: (Unary.Natural n) => UnaryProxy n -> Proof.Nat n
natFromProxy :: forall n. Natural n => UnaryProxy n -> Nat n
natFromProxy Proxy (Un n)
Proxy = Nat n
forall x. Natural x => Nat x
Proof.Nat

addOffDiagonals ::
   (Unary.Natural subA, Unary.Natural superA,
    Unary.Natural subB, Unary.Natural superB,
    (subA :+: subB) ~ subC,
    (superA :+: superB) ~ superC) =>
   (UnaryProxy subA, UnaryProxy superA) ->
   (UnaryProxy subB, UnaryProxy superB) ->
   ((Proof.Nat subC, Proof.Nat superC),
    (UnaryProxy subC, UnaryProxy superC))
addOffDiagonals :: forall subA superA subB superB subC superC.
(Natural subA, Natural superA, Natural subB, Natural superB,
 (subA :+: subB) ~ subC, (superA :+: superB) ~ superC) =>
(UnaryProxy subA, UnaryProxy superA)
-> (UnaryProxy subB, UnaryProxy superB)
-> ((Nat subC, Nat superC), (UnaryProxy subC, UnaryProxy superC))
addOffDiagonals (UnaryProxy subA
subA,UnaryProxy superA
superA) (UnaryProxy subB
subB,UnaryProxy superB
superB) =
   ((Nat subA -> Nat subB -> Nat (subA :+: subB)
forall x y. Nat x -> Nat y -> Nat (x :+: y)
Proof.addNat (UnaryProxy subA -> Nat subA
forall n. Natural n => UnaryProxy n -> Nat n
natFromProxy UnaryProxy subA
subA) (UnaryProxy subB -> Nat subB
forall n. Natural n => UnaryProxy n -> Nat n
natFromProxy UnaryProxy subB
subB),
     Nat superA -> Nat superB -> Nat (superA :+: superB)
forall x y. Nat x -> Nat y -> Nat (x :+: y)
Proof.addNat (UnaryProxy superA -> Nat superA
forall n. Natural n => UnaryProxy n -> Nat n
natFromProxy UnaryProxy superA
superA) (UnaryProxy superB -> Nat superB
forall n. Natural n => UnaryProxy n -> Nat n
natFromProxy UnaryProxy superB
superB)),
    (Proxy (Un subC)
forall a. Proxy a
Proxy,Proxy (Un superC)
forall a. Proxy a
Proxy))

bandedTranspose ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
   Banded sub super meas vert horiz height width ->
   Banded super sub meas horiz vert width height
bandedTranspose :: forall meas vert horiz sub super height width.
(Measure meas, C vert, C horiz) =>
Banded sub super meas vert horiz height width
-> Banded super sub meas horiz vert width height
bandedTranspose (Banded (UnaryProxy sub
sub,UnaryProxy super
super) Order
order Extent meas vert horiz height width
extent) =
   (UnaryProxy super, UnaryProxy sub)
-> Order
-> Extent meas horiz vert width height
-> Banded super sub meas horiz vert width height
forall sub super meas vert horiz height width.
(UnaryProxy sub, UnaryProxy super)
-> Order
-> Extent meas vert horiz height width
-> Banded sub super meas vert horiz height width
Banded (UnaryProxy super
super,UnaryProxy sub
sub) (Order -> Order
flipOrder Order
order) (Extent meas vert horiz height width
-> Extent meas horiz vert width 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 meas vert horiz height width
extent)

diagonalInverse ::
   (Extent.Measure meas) =>
   BandedSquareMeas TypeNum.U0 TypeNum.U0 meas height width ->
   BandedSquareMeas TypeNum.U0 TypeNum.U0 meas width height
diagonalInverse :: forall meas height width.
Measure meas =>
BandedSquareMeas U0 U0 meas height width
-> BandedSquareMeas U0 U0 meas width height
diagonalInverse (Banded (UnaryProxy U0
sub,UnaryProxy U0
super) Order
order Extent meas Small Small height width
extent) =
   (UnaryProxy U0, UnaryProxy U0)
-> Order
-> Extent meas Small Small width height
-> Banded U0 U0 meas Small Small width height
forall sub super meas vert horiz height width.
(UnaryProxy sub, UnaryProxy super)
-> Order
-> Extent meas vert horiz height width
-> Banded sub super meas vert horiz height width
Banded (UnaryProxy U0
super,UnaryProxy U0
sub) Order
order (Extent meas Small Small height width
-> Extent meas Small Small width 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 meas Small Small height width
extent)


bandedGeneral ::
   (UnaryProxy sub, UnaryProxy super) -> Order -> height -> width ->
   BandedGeneral sub super height width
bandedGeneral :: forall sub super height width.
(UnaryProxy sub, UnaryProxy super)
-> Order -> height -> width -> BandedGeneral sub super height width
bandedGeneral (UnaryProxy sub, UnaryProxy super)
offDiag Order
order height
height width
width =
   (UnaryProxy sub, UnaryProxy super)
-> Order
-> Extent Size Big Big height width
-> Banded sub super Size Big Big height width
forall sub super meas vert horiz height width.
(UnaryProxy sub, UnaryProxy super)
-> Order
-> Extent meas vert horiz height width
-> Banded sub super meas vert horiz height width
Banded (UnaryProxy sub, UnaryProxy super)
offDiag Order
order (height -> width -> Extent Size Big Big height width
forall height width. height -> width -> General height width
Extent.general height
height width
width)

bandedSquare ::
   (UnaryProxy sub, UnaryProxy super) -> Order -> size ->
   BandedSquare sub super size
bandedSquare :: forall sub super size.
(UnaryProxy sub, UnaryProxy super)
-> Order -> size -> BandedSquare sub super size
bandedSquare (UnaryProxy sub, UnaryProxy super)
offDiag Order
order = (UnaryProxy sub, UnaryProxy super)
-> Order
-> Extent Shape Small Small size size
-> Banded sub super Shape Small Small size size
forall sub super meas vert horiz height width.
(UnaryProxy sub, UnaryProxy super)
-> Order
-> Extent meas vert horiz height width
-> Banded sub super meas vert horiz height width
Banded (UnaryProxy sub, UnaryProxy super)
offDiag Order
order (Extent Shape Small Small size size
 -> Banded sub super Shape Small Small size size)
-> (size -> Extent Shape Small Small size size)
-> size
-> Banded sub super Shape Small Small size size
forall b c a. (b -> c) -> (a -> b) -> a -> c
. size -> Extent Shape Small Small size size
forall sh. sh -> Square sh
Extent.square

rectangularDiagonal ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
   (Shape.C height, Shape.C width) =>
   Extent meas vert horiz height width ->
   (Int, RectangularDiagonal meas vert horiz height width)
rectangularDiagonal :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz, C height, C width) =>
Extent meas vert horiz height width
-> (Int, RectangularDiagonal meas vert horiz height width)
rectangularDiagonal Extent meas vert horiz height width
extent =
   let m :: Int
m = height -> Int
forall sh. C sh => sh -> Int
Shape.size (height -> Int) -> height -> Int
forall a b. (a -> b) -> a -> b
$ Extent meas vert horiz height width -> height
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> height
Extent.height Extent meas vert horiz height width
extent
       n :: Int
n = width -> Int
forall sh. C sh => sh -> Int
Shape.size (width -> Int) -> width -> Int
forall a b. (a -> b) -> a -> b
$ Extent meas vert horiz height width -> width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
Extent.width Extent meas vert horiz height width
extent
       order :: Order
order = if Int
m Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
n then Order
RowMajor else Order
ColumnMajor
   in (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
m Int
n, (UnaryProxy U0, UnaryProxy U0)
-> Order
-> Extent meas vert horiz height width
-> Banded U0 U0 meas vert horiz height width
forall sub super meas vert horiz height width.
(UnaryProxy sub, UnaryProxy super)
-> Order
-> Extent meas vert horiz height width
-> Banded sub super meas vert horiz height width
Banded (UnaryProxy U0
u0,UnaryProxy U0
u0) Order
order Extent meas vert horiz height width
extent)


data BandedIndex row column =
     InsideBox row column
   | VertOutsideBox Int column
   | HorizOutsideBox row Int
   deriving (BandedIndex row column -> BandedIndex row column -> Bool
(BandedIndex row column -> BandedIndex row column -> Bool)
-> (BandedIndex row column -> BandedIndex row column -> Bool)
-> Eq (BandedIndex row column)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall row column.
(Eq column, Eq row) =>
BandedIndex row column -> BandedIndex row column -> Bool
$c== :: forall row column.
(Eq column, Eq row) =>
BandedIndex row column -> BandedIndex row column -> Bool
== :: BandedIndex row column -> BandedIndex row column -> Bool
$c/= :: forall row column.
(Eq column, Eq row) =>
BandedIndex row column -> BandedIndex row column -> Bool
/= :: BandedIndex row column -> BandedIndex row column -> Bool
Eq, Int -> BandedIndex row column -> String -> String
[BandedIndex row column] -> String -> String
BandedIndex row column -> String
(Int -> BandedIndex row column -> String -> String)
-> (BandedIndex row column -> String)
-> ([BandedIndex row column] -> String -> String)
-> Show (BandedIndex row column)
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
forall row column.
(Show column, Show row) =>
Int -> BandedIndex row column -> String -> String
forall row column.
(Show column, Show row) =>
[BandedIndex row column] -> String -> String
forall row column.
(Show column, Show row) =>
BandedIndex row column -> String
$cshowsPrec :: forall row column.
(Show column, Show row) =>
Int -> BandedIndex row column -> String -> String
showsPrec :: Int -> BandedIndex row column -> String -> String
$cshow :: forall row column.
(Show column, Show row) =>
BandedIndex row column -> String
show :: BandedIndex row column -> String
$cshowList :: forall row column.
(Show column, Show row) =>
[BandedIndex row column] -> String -> String
showList :: [BandedIndex row column] -> String -> String
Show)

instance
   (Unary.Natural sub, Unary.Natural super,
    Extent.Measure meas, Extent.C vert, Extent.C horiz,
    NFData height, NFData width) =>
      NFData (Banded sub super meas vert horiz height width) where
   rnf :: Banded sub super meas vert horiz height width -> ()
rnf (Banded (UnaryProxy sub
Proxy,UnaryProxy super
Proxy) Order
order Extent meas vert horiz height width
extent) = (Order, Extent meas vert horiz height width) -> ()
forall a. NFData a => a -> ()
rnf (Order
order, Extent meas vert horiz height width
extent)

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

   size :: Banded sub super meas vert horiz height width -> Int
size (Banded (UnaryProxy sub, UnaryProxy super)
offDiag Order
order Extent meas vert horiz height width
extent) =
      (UnaryProxy sub, UnaryProxy super) -> Int
forall sub super.
(Natural sub, Natural super) =>
(UnaryProxy sub, UnaryProxy super) -> Int
bandedBreadth (UnaryProxy sub, UnaryProxy super)
offDiag Int -> Int -> Int
forall a. Num a => a -> a -> a
*
      case Order
order of
         Order
RowMajor -> height -> Int
forall sh. C sh => sh -> Int
Shape.size (Extent meas vert horiz height width -> height
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> height
Extent.height Extent meas vert horiz height width
extent)
         Order
ColumnMajor -> width -> Int
forall sh. C sh => sh -> Int
Shape.size (Extent meas vert horiz height width -> width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
Extent.width Extent meas vert horiz height width
extent)

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

   type Index (Banded sub super meas vert horiz height width) =
            BandedIndex (Shape.Index height) (Shape.Index width)
   indices :: Banded sub super meas vert horiz height width
-> [Index (Banded sub super meas vert horiz height width)]
indices (Banded (UnaryProxy sub
sub,UnaryProxy super
super) Order
order Extent meas vert horiz height width
extent) =
      let (height
height,width
width) = Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent
      in case Order
order of
            Order
RowMajor ->
               ((Index height, Either Int (Index width))
 -> Index (Banded sub super meas vert horiz height width))
-> [(Index height, Either Int (Index width))]
-> [Index (Banded sub super meas vert horiz height width)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Index height
r,Either Int (Index width)
c) -> (Int -> BandedIndex (Index height) (Index width))
-> (Index width -> BandedIndex (Index height) (Index width))
-> Either Int (Index width)
-> BandedIndex (Index height) (Index width)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Index height -> Int -> BandedIndex (Index height) (Index width)
forall row column. row -> Int -> BandedIndex row column
HorizOutsideBox Index height
r) (Index height
-> Index width -> BandedIndex (Index height) (Index width)
forall row column. row -> column -> BandedIndex row column
InsideBox Index height
r) Either Int (Index width)
c) ([(Index height, Either Int (Index width))]
 -> [Index (Banded sub super meas vert horiz height width)])
-> [(Index height, Either Int (Index width))]
-> [Index (Banded sub super meas vert horiz height width)]
forall a b. (a -> b) -> a -> b
$
               (UnaryProxy sub, UnaryProxy super)
-> (height, width) -> [(Index height, Either Int (Index width))]
forall sub super height width.
(Natural sub, Natural super, Indexed height, Indexed width) =>
(UnaryProxy sub, UnaryProxy super)
-> (height, width) -> [(Index height, Either Int (Index width))]
bandedIndicesRowMajor (UnaryProxy sub
sub,UnaryProxy super
super) (height
height,width
width)
            Order
ColumnMajor ->
               ((Index width, Either Int (Index height))
 -> Index (Banded sub super meas vert horiz height width))
-> [(Index width, Either Int (Index height))]
-> [Index (Banded sub super meas vert horiz height width)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Index width
c,Either Int (Index height)
r) ->
                     (Int -> BandedIndex (Index height) (Index width))
-> (Index height -> BandedIndex (Index height) (Index width))
-> Either Int (Index height)
-> BandedIndex (Index height) (Index width)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((Int -> Index width -> BandedIndex (Index height) (Index width))
-> Index width -> Int -> BandedIndex (Index height) (Index width)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> Index width -> BandedIndex (Index height) (Index width)
forall row column. Int -> column -> BandedIndex row column
VertOutsideBox Index width
c) ((Index height
 -> Index width -> BandedIndex (Index height) (Index width))
-> Index width
-> Index height
-> BandedIndex (Index height) (Index width)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Index height
-> Index width -> BandedIndex (Index height) (Index width)
forall row column. row -> column -> BandedIndex row column
InsideBox Index width
c) Either Int (Index height)
r) ([(Index width, Either Int (Index height))]
 -> [Index (Banded sub super meas vert horiz height width)])
-> [(Index width, Either Int (Index height))]
-> [Index (Banded sub super meas vert horiz height width)]
forall a b. (a -> b) -> a -> b
$
               (UnaryProxy super, UnaryProxy sub)
-> (width, height) -> [(Index width, Either Int (Index height))]
forall sub super height width.
(Natural sub, Natural super, Indexed height, Indexed width) =>
(UnaryProxy sub, UnaryProxy super)
-> (height, width) -> [(Index height, Either Int (Index width))]
bandedIndicesRowMajor (UnaryProxy super
super,UnaryProxy sub
sub) (width
width,height
height)

   unifiedOffset :: forall check.
Checking check =>
Banded sub super meas vert horiz height width
-> Index (Banded sub super meas vert horiz height width)
-> Result check Int
unifiedOffset shape :: Banded sub super meas vert horiz height width
shape@(Banded (UnaryProxy sub
sub,UnaryProxy super
super) Order
order Extent meas vert horiz height width
extent) Index (Banded sub super meas vert horiz height width)
ix = do
      String -> Bool -> Result check ()
forall check. Checking check => String -> Bool -> Result check ()
Shape.assert String
"Banded.offset: index outside band" (Bool -> Result check ()) -> Bool -> Result check ()
forall a b. (a -> b) -> a -> b
$
         Banded sub super meas vert horiz height width
-> Index (Banded sub super meas vert horiz height width) -> Bool
forall sh. Indexed sh => sh -> Index sh -> Bool
Shape.inBounds Banded sub super meas vert horiz height width
shape Index (Banded sub super meas vert horiz height width)
ix
      let (height
height,width
width) = Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent
          kl :: Int
kl = UnaryProxy sub -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy sub
sub
          ku :: Int
ku = UnaryProxy super -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy super
super
      Int -> Result check Int
forall a. a -> Result check a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Result check Int) -> Int -> Result check Int
forall a b. (a -> b) -> a -> b
$ (Int, Int)
-> Order
-> (height, width)
-> BandedIndex (Index height) (Index width)
-> Int
forall height width.
(Indexed height, Indexed width) =>
(Int, Int)
-> Order
-> (height, width)
-> BandedIndex (Index height) (Index width)
-> Int
bandedOffset (Int
kl,Int
ku) Order
order (height
height,width
width) Index (Banded sub super meas vert horiz height width)
BandedIndex (Index height) (Index width)
ix

   inBounds :: Banded sub super meas vert horiz height width
-> Index (Banded sub super meas vert horiz height width) -> Bool
inBounds (Banded (UnaryProxy sub
sub,UnaryProxy super
super) Order
order Extent meas vert horiz height width
extent) Index (Banded sub super meas vert horiz height width)
ix =
      let (height
height,width
width) = Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent
          kl :: Int
kl = UnaryProxy sub -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy sub
sub
          ku :: Int
ku = UnaryProxy super -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy super
super
          insideBand :: Int -> Int -> Bool
insideBand Int
r Int
c = Range Int -> Index (Range Int) -> Bool
forall sh. Indexed sh => sh -> Index sh -> Bool
Shape.inBounds (Int -> Int -> Range Int
forall n. n -> n -> Range n
Shape.Range (-Int
kl) Int
ku) (Int
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
r)
      in case (Order
order,Index (Banded sub super meas vert horiz height width)
BandedIndex (Index height) (Index width)
ix) of
            (Order
_, InsideBox Index height
r Index width
c) ->
               (height, width) -> Index (height, width) -> Bool
forall sh. Indexed sh => sh -> Index sh -> Bool
Shape.inBounds (height
height,width
width) (Index height
r,Index width
c)
               Bool -> Bool -> Bool
&&
               Int -> Int -> Bool
insideBand (height -> Index height -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset height
height Index height
r) (width -> Index width -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset width
width Index width
c)
            (Order
RowMajor, HorizOutsideBox Index height
r Int
c) ->
               height -> Index height -> Bool
forall sh. Indexed sh => sh -> Index sh -> Bool
Shape.inBounds height
height Index height
r
               Bool -> Bool -> Bool
&&
               Int -> Int -> Bool
insideBand (height -> Index height -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset height
height Index height
r) (width -> Int -> Int
forall sh. C sh => sh -> Int -> Int
outsideOffset width
width Int
c)
            (Order
ColumnMajor, VertOutsideBox Int
r Index width
c) ->
               width -> Index width -> Bool
forall sh. Indexed sh => sh -> Index sh -> Bool
Shape.inBounds width
width Index width
c
               Bool -> Bool -> Bool
&&
               Int -> Int -> Bool
insideBand (height -> Int -> Int
forall sh. C sh => sh -> Int -> Int
outsideOffset height
height Int
r) (width -> Index width -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset width
width Index width
c)
            (Order, BandedIndex (Index height) (Index width))
_ -> Bool
False

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

   unifiedIndexFromOffset :: forall check.
Checking check =>
Banded sub super meas vert horiz height width
-> Int
-> Result
     check (Index (Banded sub super meas vert horiz height width))
unifiedIndexFromOffset (Banded (UnaryProxy sub
sub,UnaryProxy super
super) Order
order Extent meas vert horiz height width
extent) Int
j =
      (Int, Int)
-> Order
-> (height, width)
-> Int
-> Result check (BandedIndex (Index height) (Index width))
forall check height width.
(Checking check, InvIndexed height, InvIndexed width) =>
(Int, Int)
-> Order
-> (height, width)
-> Int
-> Result check (BandedIndex (Index height) (Index width))
bandedIndexFromOffset
         (UnaryProxy sub -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy sub
sub, UnaryProxy super -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy super
super) Order
order
         (Extent meas vert horiz height width -> (height, width)
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> (height, width)
Extent.dimensions Extent meas vert horiz height width
extent) Int
j

outsideOffset :: Shape.C sh => sh -> Int -> Int
outsideOffset :: forall sh. C sh => sh -> Int -> Int
outsideOffset sh
size Int
k = if Int
kInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<Int
0 then Int
k else sh -> Int
forall sh. C sh => sh -> Int
Shape.size sh
size Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k

bandedOffset ::
   (Shape.Indexed height, Shape.Indexed width) =>
   (Int, Int) -> Order -> (height, width) ->
   BandedIndex (Shape.Index height) (Shape.Index width) -> Int
bandedOffset :: forall height width.
(Indexed height, Indexed width) =>
(Int, Int)
-> Order
-> (height, width)
-> BandedIndex (Index height) (Index width)
-> Int
bandedOffset (Int
kl,Int
ku) Order
order (height
height,width
width) BandedIndex (Index height) (Index width)
ix =
   let k :: Int
k = Int
klInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
ku
   in case BandedIndex (Index height) (Index width)
ix of
         InsideBox Index height
r Index width
c ->
            let i :: Int
i = height -> Index height -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.uncheckedOffset height
height Index height
r
                j :: Int
j = width -> Index width -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.uncheckedOffset width
width Index width
c
            in case Order
order of
                  Order
RowMajor -> Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
klInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
j
                  Order
ColumnMajor -> Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
kuInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i
         VertOutsideBox Int
r Index width
c ->
            let i :: Int
i = height -> Int -> Int
forall sh. C sh => sh -> Int -> Int
outsideOffset height
height Int
r
                j :: Int
j = width -> Index width -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.uncheckedOffset width
width Index width
c
            in  Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
kuInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i
         HorizOutsideBox Index height
r Int
c ->
            let i :: Int
i = height -> Index height -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.uncheckedOffset height
height Index height
r
                j :: Int
j = width -> Int -> Int
forall sh. C sh => sh -> Int -> Int
outsideOffset width
width Int
c
            in  Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
klInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
j

bandedIndicesRowMajor ::
   (Unary.Natural sub, Unary.Natural super,
    Shape.Indexed height, Shape.Indexed width) =>
   (UnaryProxy sub, UnaryProxy super) ->
   (height, width) ->
   [(Shape.Index height, Either Int (Shape.Index width))]
bandedIndicesRowMajor :: forall sub super height width.
(Natural sub, Natural super, Indexed height, Indexed width) =>
(UnaryProxy sub, UnaryProxy super)
-> (height, width) -> [(Index height, Either Int (Index width))]
bandedIndicesRowMajor (UnaryProxy sub
sub,UnaryProxy super
super) (height
height,width
width) =
   let kl :: Int
kl = UnaryProxy sub -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy sub
sub
       ku :: Int
ku = UnaryProxy super -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy super
super
   in [[(Index height, Either Int (Index width))]]
-> [(Index height, Either Int (Index width))]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[(Index height, Either Int (Index width))]]
 -> [(Index height, Either Int (Index width))])
-> [[(Index height, Either Int (Index width))]]
-> [(Index height, Either Int (Index width))]
forall a b. (a -> b) -> a -> b
$
      (Index height
 -> [Either Int (Index width)]
 -> [(Index height, Either Int (Index width))])
-> [Index height]
-> [[Either Int (Index width)]]
-> [[(Index height, Either Int (Index width))]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Index height
r -> (Either Int (Index width)
 -> (Index height, Either Int (Index width)))
-> [Either Int (Index width)]
-> [(Index height, Either Int (Index width))]
forall a b. (a -> b) -> [a] -> [b]
map ((,) Index height
r)) (height -> [Index height]
forall sh. Indexed sh => sh -> [Index sh]
Shape.indices height
height) ([[Either Int (Index width)]]
 -> [[(Index height, Either Int (Index width))]])
-> [[Either Int (Index width)]]
-> [[(Index height, Either Int (Index width))]]
forall a b. (a -> b) -> a -> b
$
      ([Either Int (Index width)] -> [Either Int (Index width)])
-> [[Either Int (Index width)]] -> [[Either Int (Index width)]]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> [Either Int (Index width)] -> [Either Int (Index width)]
forall a. Int -> [a] -> [a]
take (Int
klInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
ku)) ([[Either Int (Index width)]] -> [[Either Int (Index width)]])
-> [[Either Int (Index width)]] -> [[Either Int (Index width)]]
forall a b. (a -> b) -> a -> b
$ [Either Int (Index width)] -> [[Either Int (Index width)]]
forall a. [a] -> [[a]]
tails ([Either Int (Index width)] -> [[Either Int (Index width)]])
-> [Either Int (Index width)] -> [[Either Int (Index width)]]
forall a b. (a -> b) -> a -> b
$
         ((Int -> Either Int (Index width))
-> [Int] -> [Either Int (Index width)]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Either Int (Index width)
forall a b. a -> Either a b
Left ([Int] -> [Either Int (Index width)])
-> [Int] -> [Either Int (Index width)]
forall a b. (a -> b) -> a -> b
$ Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
kl ([Int] -> [Int]) -> [Int] -> [Int]
forall a b. (a -> b) -> a -> b
$ (Int -> Int) -> Int -> [Int]
forall a. (a -> a) -> a -> [a]
iterate (Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+) (-Int
kl)) [Either Int (Index width)]
-> [Either Int (Index width)] -> [Either Int (Index width)]
forall a. [a] -> [a] -> [a]
++
         ((Index width -> Either Int (Index width))
-> [Index width] -> [Either Int (Index width)]
forall a b. (a -> b) -> [a] -> [b]
map Index width -> Either Int (Index width)
forall a b. b -> Either a b
Right ([Index width] -> [Either Int (Index width)])
-> [Index width] -> [Either Int (Index width)]
forall a b. (a -> b) -> a -> b
$ width -> [Index width]
forall sh. Indexed sh => sh -> [Index sh]
Shape.indices width
width) [Either Int (Index width)]
-> [Either Int (Index width)] -> [Either Int (Index width)]
forall a. [a] -> [a] -> [a]
++
         ((Int -> Either Int (Index width))
-> [Int] -> [Either Int (Index width)]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Either Int (Index width)
forall a b. a -> Either a b
Left ([Int] -> [Either Int (Index width)])
-> [Int] -> [Either Int (Index width)]
forall a b. (a -> b) -> a -> b
$ (Int -> Int) -> Int -> [Int]
forall a. (a -> a) -> a -> [a]
iterate (Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+) Int
0)

bandedIndexFromOffset ::
   (Shape.Checking check, Shape.InvIndexed height, Shape.InvIndexed width) =>
   (Int,Int) -> Order -> (height,width) -> Int ->
   Shape.Result check (BandedIndex (Shape.Index height) (Shape.Index width))
bandedIndexFromOffset :: forall check height width.
(Checking check, InvIndexed height, InvIndexed width) =>
(Int, Int)
-> Order
-> (height, width)
-> Int
-> Result check (BandedIndex (Index height) (Index width))
bandedIndexFromOffset (Int
kl,Int
ku) Order
order (height
height,width
width) =
   case Order
order of
      Order
RowMajor -> let n :: Int
n = width -> Int
forall sh. C sh => sh -> Int
Shape.size width
width in \Int
j -> do
         let (Int
rb,Int
cb) = Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
divMod Int
j (Int
klInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
ku)
         Index height
r <- height -> Int -> Result check (Index height)
forall sh check.
(InvIndexed sh, Checking check) =>
sh -> Int -> Result check (Index sh)
forall check.
Checking check =>
height -> Int -> Result check (Index height)
Shape.unifiedIndexFromOffset height
height Int
rb
         let ci :: Int
ci = Int
rbInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
cbInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
kl
         Bool
-> Result check (BandedIndex (Index height) (Index width))
-> Result check (BandedIndex (Index height) (Index width))
-> Result check (BandedIndex (Index height) (Index width))
forall a. Bool -> a -> a -> a
if' (Int
ciInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<Int
0) (BandedIndex (Index height) (Index width)
-> Result check (BandedIndex (Index height) (Index width))
forall a. a -> Result check a
forall (m :: * -> *) a. Monad m => a -> m a
return (BandedIndex (Index height) (Index width)
 -> Result check (BandedIndex (Index height) (Index width)))
-> BandedIndex (Index height) (Index width)
-> Result check (BandedIndex (Index height) (Index width))
forall a b. (a -> b) -> a -> b
$ Index height -> Int -> BandedIndex (Index height) (Index width)
forall row column. row -> Int -> BandedIndex row column
HorizOutsideBox Index height
r Int
ci) (Result check (BandedIndex (Index height) (Index width))
 -> Result check (BandedIndex (Index height) (Index width)))
-> Result check (BandedIndex (Index height) (Index width))
-> Result check (BandedIndex (Index height) (Index width))
forall a b. (a -> b) -> a -> b
$
            Bool
-> Result check (BandedIndex (Index height) (Index width))
-> Result check (BandedIndex (Index height) (Index width))
-> Result check (BandedIndex (Index height) (Index width))
forall a. Bool -> a -> a -> a
if' (Int
ciInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>=Int
n) (BandedIndex (Index height) (Index width)
-> Result check (BandedIndex (Index height) (Index width))
forall a. a -> Result check a
forall (m :: * -> *) a. Monad m => a -> m a
return (BandedIndex (Index height) (Index width)
 -> Result check (BandedIndex (Index height) (Index width)))
-> BandedIndex (Index height) (Index width)
-> Result check (BandedIndex (Index height) (Index width))
forall a b. (a -> b) -> a -> b
$ Index height -> Int -> BandedIndex (Index height) (Index width)
forall row column. row -> Int -> BandedIndex row column
HorizOutsideBox Index height
r (Int
ciInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
n)) (Result check (BandedIndex (Index height) (Index width))
 -> Result check (BandedIndex (Index height) (Index width)))
-> Result check (BandedIndex (Index height) (Index width))
-> Result check (BandedIndex (Index height) (Index width))
forall a b. (a -> b) -> a -> b
$
            (Index height
-> Index width -> BandedIndex (Index height) (Index width)
forall row column. row -> column -> BandedIndex row column
InsideBox Index height
r (Index width -> BandedIndex (Index height) (Index width))
-> Result check (Index width)
-> Result check (BandedIndex (Index height) (Index width))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> width -> Int -> Result check (Index width)
forall sh check.
(InvIndexed sh, Checking check) =>
sh -> Int -> Result check (Index sh)
forall check.
Checking check =>
width -> Int -> Result check (Index width)
Shape.unifiedIndexFromOffset width
width Int
ci)
      Order
ColumnMajor -> \Int
j -> do
         let m :: Int
m = height -> Int
forall sh. C sh => sh -> Int
Shape.size height
height
         let (Int
cb,Int
rb) = Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
divMod Int
j (Int
klInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
ku)
         Index width
c <- width -> Int -> Result check (Index width)
forall sh check.
(InvIndexed sh, Checking check) =>
sh -> Int -> Result check (Index sh)
forall check.
Checking check =>
width -> Int -> Result check (Index width)
Shape.unifiedIndexFromOffset width
width Int
cb
         let ri :: Int
ri = Int
rbInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
cbInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
ku
         Bool
-> Result check (BandedIndex (Index height) (Index width))
-> Result check (BandedIndex (Index height) (Index width))
-> Result check (BandedIndex (Index height) (Index width))
forall a. Bool -> a -> a -> a
if' (Int
riInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<Int
0) (BandedIndex (Index height) (Index width)
-> Result check (BandedIndex (Index height) (Index width))
forall a. a -> Result check a
forall (m :: * -> *) a. Monad m => a -> m a
return (BandedIndex (Index height) (Index width)
 -> Result check (BandedIndex (Index height) (Index width)))
-> BandedIndex (Index height) (Index width)
-> Result check (BandedIndex (Index height) (Index width))
forall a b. (a -> b) -> a -> b
$ Int -> Index width -> BandedIndex (Index height) (Index width)
forall row column. Int -> column -> BandedIndex row column
VertOutsideBox Int
ri Index width
c) (Result check (BandedIndex (Index height) (Index width))
 -> Result check (BandedIndex (Index height) (Index width)))
-> Result check (BandedIndex (Index height) (Index width))
-> Result check (BandedIndex (Index height) (Index width))
forall a b. (a -> b) -> a -> b
$
            Bool
-> Result check (BandedIndex (Index height) (Index width))
-> Result check (BandedIndex (Index height) (Index width))
-> Result check (BandedIndex (Index height) (Index width))
forall a. Bool -> a -> a -> a
if' (Int
riInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>=Int
m) (BandedIndex (Index height) (Index width)
-> Result check (BandedIndex (Index height) (Index width))
forall a. a -> Result check a
forall (m :: * -> *) a. Monad m => a -> m a
return (BandedIndex (Index height) (Index width)
 -> Result check (BandedIndex (Index height) (Index width)))
-> BandedIndex (Index height) (Index width)
-> Result check (BandedIndex (Index height) (Index width))
forall a b. (a -> b) -> a -> b
$ Int -> Index width -> BandedIndex (Index height) (Index width)
forall row column. Int -> column -> BandedIndex row column
VertOutsideBox (Int
riInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
m) Index width
c) (Result check (BandedIndex (Index height) (Index width))
 -> Result check (BandedIndex (Index height) (Index width)))
-> Result check (BandedIndex (Index height) (Index width))
-> Result check (BandedIndex (Index height) (Index width))
forall a b. (a -> b) -> a -> b
$
            ((Index height
 -> Index width -> BandedIndex (Index height) (Index width))
-> Index width
-> Index height
-> BandedIndex (Index height) (Index width)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Index height
-> Index width -> BandedIndex (Index height) (Index width)
forall row column. row -> column -> BandedIndex row column
InsideBox Index width
c (Index height -> BandedIndex (Index height) (Index width))
-> Result check (Index height)
-> Result check (BandedIndex (Index height) (Index width))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> height -> Int -> Result check (Index height)
forall sh check.
(InvIndexed sh, Checking check) =>
sh -> Int -> Result check (Index sh)
forall check.
Checking check =>
height -> Int -> Result check (Index height)
Shape.unifiedIndexFromOffset height
height Int
ri)


data BandedHermitian off size =
   BandedHermitian {
      forall off size. BandedHermitian off size -> UnaryProxy off
bandedHermitianOffDiagonals :: UnaryProxy off,
      forall off size. BandedHermitian off size -> Order
bandedHermitianOrder :: Order,
      forall off size. BandedHermitian off size -> size
bandedHermitianSize :: size
   } deriving (BandedHermitian off size -> BandedHermitian off size -> Bool
(BandedHermitian off size -> BandedHermitian off size -> Bool)
-> (BandedHermitian off size -> BandedHermitian off size -> Bool)
-> Eq (BandedHermitian off size)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall off size.
Eq size =>
BandedHermitian off size -> BandedHermitian off size -> Bool
$c== :: forall off size.
Eq size =>
BandedHermitian off size -> BandedHermitian off size -> Bool
== :: BandedHermitian off size -> BandedHermitian off size -> Bool
$c/= :: forall off size.
Eq size =>
BandedHermitian off size -> BandedHermitian off size -> Bool
/= :: BandedHermitian off size -> BandedHermitian off size -> Bool
Eq, Int -> BandedHermitian off size -> String -> String
[BandedHermitian off size] -> String -> String
BandedHermitian off size -> String
(Int -> BandedHermitian off size -> String -> String)
-> (BandedHermitian off size -> String)
-> ([BandedHermitian off size] -> String -> String)
-> Show (BandedHermitian off size)
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
forall off size.
(Natural off, Show size) =>
Int -> BandedHermitian off size -> String -> String
forall off size.
(Natural off, Show size) =>
[BandedHermitian off size] -> String -> String
forall off size.
(Natural off, Show size) =>
BandedHermitian off size -> String
$cshowsPrec :: forall off size.
(Natural off, Show size) =>
Int -> BandedHermitian off size -> String -> String
showsPrec :: Int -> BandedHermitian off size -> String -> String
$cshow :: forall off size.
(Natural off, Show size) =>
BandedHermitian off size -> String
show :: BandedHermitian off size -> String
$cshowList :: forall off size.
(Natural off, Show size) =>
[BandedHermitian off size] -> String -> String
showList :: [BandedHermitian off size] -> String -> String
Show)

instance (Unary.Natural off, NFData size) =>
      NFData (BandedHermitian off size) where
   rnf :: BandedHermitian off size -> ()
rnf (BandedHermitian Proxy (Un off)
Proxy Order
order size
size) = (Order, size) -> ()
forall a. NFData a => a -> ()
rnf (Order
order, size
size)

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

   size :: BandedHermitian off size -> Int
size (BandedHermitian UnaryProxy off
offDiag Order
_order size
size) =
      (Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ UnaryProxy off -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy off
offDiag) Int -> Int -> Int
forall a. Num a => a -> a -> a
* size -> Int
forall sh. C sh => sh -> Int
Shape.size size
size

instance (Unary.Natural off, Shape.Indexed size) =>
      Shape.Indexed (BandedHermitian off size) where
   type Index (BandedHermitian off size) =
            BandedIndex (Shape.Index size) (Shape.Index size)
   indices :: BandedHermitian off size -> [Index (BandedHermitian off size)]
indices (BandedHermitian UnaryProxy off
offDiag Order
order size
size) =
      case Order
order of
         Order
RowMajor ->
            ((Index size, Either Int (Index size))
 -> Index (BandedHermitian off size))
-> [(Index size, Either Int (Index size))]
-> [Index (BandedHermitian off size)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Index size
r,Either Int (Index size)
c) -> (Int -> BandedIndex (Index size) (Index size))
-> (Index size -> BandedIndex (Index size) (Index size))
-> Either Int (Index size)
-> BandedIndex (Index size) (Index size)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Index size -> Int -> BandedIndex (Index size) (Index size)
forall row column. row -> Int -> BandedIndex row column
HorizOutsideBox Index size
r) (Index size -> Index size -> BandedIndex (Index size) (Index size)
forall row column. row -> column -> BandedIndex row column
InsideBox Index size
r) Either Int (Index size)
c) ([(Index size, Either Int (Index size))]
 -> [Index (BandedHermitian off size)])
-> [(Index size, Either Int (Index size))]
-> [Index (BandedHermitian off size)]
forall a b. (a -> b) -> a -> b
$
            (UnaryProxy U0, UnaryProxy off)
-> (size, size) -> [(Index size, Either Int (Index size))]
forall sub super height width.
(Natural sub, Natural super, Indexed height, Indexed width) =>
(UnaryProxy sub, UnaryProxy super)
-> (height, width) -> [(Index height, Either Int (Index width))]
bandedIndicesRowMajor (UnaryProxy U0
u0, UnaryProxy off
offDiag) (size
size,size
size)
         Order
ColumnMajor ->
            ((Index size, Either Int (Index size))
 -> Index (BandedHermitian off size))
-> [(Index size, Either Int (Index size))]
-> [Index (BandedHermitian off size)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Index size
c,Either Int (Index size)
r) ->
                  (Int -> BandedIndex (Index size) (Index size))
-> (Index size -> BandedIndex (Index size) (Index size))
-> Either Int (Index size)
-> BandedIndex (Index size) (Index size)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((Int -> Index size -> BandedIndex (Index size) (Index size))
-> Index size -> Int -> BandedIndex (Index size) (Index size)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> Index size -> BandedIndex (Index size) (Index size)
forall row column. Int -> column -> BandedIndex row column
VertOutsideBox Index size
c) ((Index size -> Index size -> BandedIndex (Index size) (Index size))
-> Index size
-> Index size
-> BandedIndex (Index size) (Index size)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Index size -> Index size -> BandedIndex (Index size) (Index size)
forall row column. row -> column -> BandedIndex row column
InsideBox Index size
c) Either Int (Index size)
r) ([(Index size, Either Int (Index size))]
 -> [Index (BandedHermitian off size)])
-> [(Index size, Either Int (Index size))]
-> [Index (BandedHermitian off size)]
forall a b. (a -> b) -> a -> b
$
            (UnaryProxy off, UnaryProxy U0)
-> (size, size) -> [(Index size, Either Int (Index size))]
forall sub super height width.
(Natural sub, Natural super, Indexed height, Indexed width) =>
(UnaryProxy sub, UnaryProxy super)
-> (height, width) -> [(Index height, Either Int (Index width))]
bandedIndicesRowMajor (UnaryProxy off
offDiag, UnaryProxy U0
u0) (size
size,size
size)

   unifiedOffset :: forall check.
Checking check =>
BandedHermitian off size
-> Index (BandedHermitian off size) -> Result check Int
unifiedOffset shape :: BandedHermitian off size
shape@(BandedHermitian UnaryProxy off
offDiag Order
order size
size) Index (BandedHermitian off size)
ix = do
      String -> Bool -> Result check ()
forall check. Checking check => String -> Bool -> Result check ()
Shape.assert String
"BandedHermitian.offset: index outside band" (Bool -> Result check ()) -> Bool -> Result check ()
forall a b. (a -> b) -> a -> b
$
         BandedHermitian off size
-> Index (BandedHermitian off size) -> Bool
forall sh. Indexed sh => sh -> Index sh -> Bool
Shape.inBounds BandedHermitian off size
shape Index (BandedHermitian off size)
ix
      let k :: Int
k = UnaryProxy off -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy off
offDiag
      Int -> Result check Int
forall a. a -> Result check a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Result check Int) -> Int -> Result check Int
forall a b. (a -> b) -> a -> b
$ (Int, Int)
-> Order
-> (size, size)
-> BandedIndex (Index size) (Index size)
-> Int
forall height width.
(Indexed height, Indexed width) =>
(Int, Int)
-> Order
-> (height, width)
-> BandedIndex (Index height) (Index width)
-> Int
bandedOffset (Int
0,Int
k) Order
order (size
size,size
size) Index (BandedHermitian off size)
BandedIndex (Index size) (Index size)
ix

   inBounds :: BandedHermitian off size
-> Index (BandedHermitian off size) -> Bool
inBounds (BandedHermitian UnaryProxy off
offDiag Order
order size
size) Index (BandedHermitian off size)
ix =
      let ku :: Int
ku = UnaryProxy off -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy off
offDiag
          insideBand :: Int -> Int -> Bool
insideBand Int
r Int
c = Range Int -> Index (Range Int) -> Bool
forall sh. Indexed sh => sh -> Index sh -> Bool
Shape.inBounds (Int -> Int -> Range Int
forall n. n -> n -> Range n
Shape.Range Int
0 Int
ku) (Int
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
r)
      in case (Order
order,Index (BandedHermitian off size)
BandedIndex (Index size) (Index size)
ix) of
            (Order
_, InsideBox Index size
r Index size
c) ->
               (size, size) -> Index (size, size) -> Bool
forall sh. Indexed sh => sh -> Index sh -> Bool
Shape.inBounds (size
size,size
size) (Index size
r,Index size
c)
               Bool -> Bool -> Bool
&&
               Int -> Int -> Bool
insideBand (size -> Index size -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset size
size Index size
r) (size -> Index size -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset size
size Index size
c)
            (Order
RowMajor, HorizOutsideBox Index size
r Int
c) ->
               size -> Index size -> Bool
forall sh. Indexed sh => sh -> Index sh -> Bool
Shape.inBounds size
size Index size
r
               Bool -> Bool -> Bool
&&
               Int -> Int -> Bool
insideBand (size -> Index size -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset size
size Index size
r) (size -> Int -> Int
forall sh. C sh => sh -> Int -> Int
outsideOffset size
size Int
c)
            (Order
ColumnMajor, VertOutsideBox Int
r Index size
c) ->
               size -> Index size -> Bool
forall sh. Indexed sh => sh -> Index sh -> Bool
Shape.inBounds size
size Index size
c
               Bool -> Bool -> Bool
&&
               Int -> Int -> Bool
insideBand (size -> Int -> Int
forall sh. C sh => sh -> Int -> Int
outsideOffset size
size Int
r) (size -> Index size -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset size
size Index size
c)
            (Order, BandedIndex (Index size) (Index size))
_ -> Bool
False

instance (Unary.Natural off, Shape.InvIndexed size) =>
      Shape.InvIndexed (BandedHermitian off size) where

   unifiedIndexFromOffset :: forall check.
Checking check =>
BandedHermitian off size
-> Int -> Result check (Index (BandedHermitian off size))
unifiedIndexFromOffset (BandedHermitian UnaryProxy off
offDiag Order
order size
size) Int
j =
      Int
-> Order
-> size
-> Int
-> Result check (BandedIndex (Index size) (Index size))
forall check sh ix.
(Checking check, InvIndexed sh, Index sh ~ ix) =>
Int -> Order -> sh -> Int -> Result check (BandedIndex ix ix)
bandedHermitianIndexFromOffset
         (UnaryProxy off -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy off
offDiag) Order
order size
size Int
j

bandedHermitianIndexFromOffset ::
   (Shape.Checking check, Shape.InvIndexed sh, Shape.Index sh ~ ix) =>
   Int -> Order -> sh -> Int -> Shape.Result check (BandedIndex ix ix)
bandedHermitianIndexFromOffset :: forall check sh ix.
(Checking check, InvIndexed sh, Index sh ~ ix) =>
Int -> Order -> sh -> Int -> Result check (BandedIndex ix ix)
bandedHermitianIndexFromOffset Int
k Order
order sh
size =
   case Order
order of
      Order
RowMajor -> let n :: Int
n = sh -> Int
forall sh. C sh => sh -> Int
Shape.size sh
size in \Int
j -> do
         let (Int
rb,Int
cb) = Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
divMod Int
j (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
         ix
r <- sh -> Int -> Result check (Index sh)
forall sh check.
(InvIndexed sh, Checking check) =>
sh -> Int -> Result check (Index sh)
forall check.
Checking check =>
sh -> Int -> Result check (Index sh)
Shape.unifiedIndexFromOffset sh
size Int
rb
         let ci :: Int
ci = Int
rbInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
cb
         if Int
ciInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<Int
n
            then ix -> ix -> BandedIndex ix ix
forall row column. row -> column -> BandedIndex row column
InsideBox ix
r (ix -> BandedIndex ix ix)
-> Result check ix -> Result check (BandedIndex ix ix)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> sh -> Int -> Result check (Index sh)
forall sh check.
(InvIndexed sh, Checking check) =>
sh -> Int -> Result check (Index sh)
forall check.
Checking check =>
sh -> Int -> Result check (Index sh)
Shape.unifiedIndexFromOffset sh
size Int
ci
            else BandedIndex ix ix -> Result check (BandedIndex ix ix)
forall a. a -> Result check a
forall (m :: * -> *) a. Monad m => a -> m a
return (BandedIndex ix ix -> Result check (BandedIndex ix ix))
-> BandedIndex ix ix -> Result check (BandedIndex ix ix)
forall a b. (a -> b) -> a -> b
$ ix -> Int -> BandedIndex ix ix
forall row column. row -> Int -> BandedIndex row column
HorizOutsideBox ix
r (Int
ciInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
n)
      Order
ColumnMajor -> \Int
j -> do
         let (Int
cb,Int
rb) = Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
divMod Int
j (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
         ix
c <- sh -> Int -> Result check (Index sh)
forall sh check.
(InvIndexed sh, Checking check) =>
sh -> Int -> Result check (Index sh)
forall check.
Checking check =>
sh -> Int -> Result check (Index sh)
Shape.unifiedIndexFromOffset sh
size Int
cb
         let ri :: Int
ri = Int
rbInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
cbInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
k
         if Int
riInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>=Int
0
            then (ix -> ix -> BandedIndex ix ix) -> ix -> ix -> BandedIndex ix ix
forall a b c. (a -> b -> c) -> b -> a -> c
flip ix -> ix -> BandedIndex ix ix
forall row column. row -> column -> BandedIndex row column
InsideBox ix
c (ix -> BandedIndex ix ix)
-> Result check ix -> Result check (BandedIndex ix ix)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> sh -> Int -> Result check (Index sh)
forall sh check.
(InvIndexed sh, Checking check) =>
sh -> Int -> Result check (Index sh)
forall check.
Checking check =>
sh -> Int -> Result check (Index sh)
Shape.unifiedIndexFromOffset sh
size Int
ri
            else BandedIndex ix ix -> Result check (BandedIndex ix ix)
forall a. a -> Result check a
forall (m :: * -> *) a. Monad m => a -> m a
return (BandedIndex ix ix -> Result check (BandedIndex ix ix))
-> BandedIndex ix ix -> Result check (BandedIndex ix ix)
forall a b. (a -> b) -> a -> b
$ Int -> ix -> BandedIndex ix ix
forall row column. Int -> column -> BandedIndex row column
VertOutsideBox Int
ri ix
c