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

import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent
import Numeric.LAPACK.Matrix.Extent.Private (Extent)

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')


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

instance NFData Order where
   rnf :: Order -> ()
rnf Order
RowMajor = ()
   rnf Order
ColumnMajor = ()

flipOrder :: Order -> Order
flipOrder :: Order -> Order
flipOrder Order
RowMajor = Order
ColumnMajor
flipOrder Order
ColumnMajor = Order
RowMajor

transposeFromOrder :: Order -> Char
transposeFromOrder :: Order -> Char
transposeFromOrder Order
RowMajor = Char
'T'
transposeFromOrder Order
ColumnMajor = Char
'N'

swapOnRowMajor :: Order -> (a,a) -> (a,a)
swapOnRowMajor :: 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 :: 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 :: 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 -> ShowS
forall a. [a] -> [a] -> [a]
++ String
": sizes mismatch"


data Full meas vert horiz height width =
   Full {
      Full meas vert horiz height width -> Order
fullOrder :: Order,
      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
/= :: 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
Eq, Int -> Full meas vert horiz height width -> ShowS
[Full meas vert horiz height width] -> ShowS
Full meas vert horiz height width -> String
(Int -> Full meas vert horiz height width -> ShowS)
-> (Full meas vert horiz height width -> String)
-> ([Full meas vert horiz height width] -> ShowS)
-> Show (Full meas vert horiz height width)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> 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 -> ShowS
forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
[Full meas vert horiz height width] -> ShowS
forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
Full meas vert horiz height width -> String
showList :: [Full meas vert horiz height width] -> ShowS
$cshowList :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
[Full meas vert horiz height width] -> ShowS
show :: Full meas vert horiz height width -> 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
showsPrec :: Int -> Full meas vert horiz height width -> ShowS
$cshowsPrec :: forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
Int -> Full meas vert horiz height width -> ShowS
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 :: 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
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
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 :: 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)
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 height, Index width) -> Result check Int)
-> (Int, (Index width, Index height) -> Result check Int)
-> (Int, (Index height, Index width) -> Result check Int)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd (((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) ((Int, (Index width, Index height) -> Result check Int)
 -> (Int, (Index height, Index width) -> Result check Int))
-> (Int, (Index width, Index height) -> Result check Int)
-> (Int, (Index height, Index 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)
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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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)
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 (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)
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 :: 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 :: Order -> height -> width -> General height width
general Order
order height
height width
width = Order -> Extent Size Big Big height width -> General 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 -> General height width)
-> Extent Size Big Big height width -> General 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 :: 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 -> 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 (Extent Size Big Small height width -> Tall height width)
-> Extent Size Big Small height width -> Tall 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 -> Tall 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 :: 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 -> 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 (Extent Size Small Big height width -> Wide height width)
-> Extent Size Small Big height width -> Wide 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 -> Wide 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 :: 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
-> LiberalSquare 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
 -> LiberalSquare height width)
-> Extent Size Small Small height width
-> LiberalSquare 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 -> LiberalSquare height width
forall a. HasCallStack => String -> a
error String
"Layout.liberalSquare: height and width sizes differ"

square :: Order -> sh -> Square sh
square :: Order -> sh -> Square sh
square Order
order sh
sh = Order -> Extent Shape Small Small sh sh -> Square 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 -> Square sh)
-> Extent Shape Small Small sh sh -> Square 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 :: 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 {
      Split lower meas vert horiz height width -> lower
splitLower :: lower,
      Split lower meas vert horiz height width -> Order
splitOrder :: Order,
      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
/= :: 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
Eq, Int -> Split lower meas vert horiz height width -> ShowS
[Split lower meas vert horiz height width] -> ShowS
Split lower meas vert horiz height width -> String
(Int -> Split lower meas vert horiz height width -> ShowS)
-> (Split lower meas vert horiz height width -> String)
-> ([Split lower meas vert horiz height width] -> ShowS)
-> Show (Split lower meas vert horiz height width)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> 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 -> ShowS
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] -> ShowS
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
showList :: [Split lower meas vert horiz height width] -> ShowS
$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] -> ShowS
show :: Split lower meas vert horiz height width -> 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
showsPrec :: Int -> Split lower meas vert horiz height width -> ShowS
$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 -> ShowS
Show)

splitHeight ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz) =>
   Split lower meas vert horiz height width -> height
splitHeight :: 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 :: 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 :: 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 :: 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
/= :: Reflector -> Reflector -> Bool
$c/= :: Reflector -> Reflector -> Bool
== :: Reflector -> Reflector -> Bool
$c== :: Reflector -> Reflector -> Bool
Eq, Int -> Reflector -> ShowS
[Reflector] -> ShowS
Reflector -> String
(Int -> Reflector -> ShowS)
-> (Reflector -> String)
-> ([Reflector] -> ShowS)
-> Show Reflector
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Reflector] -> ShowS
$cshowList :: [Reflector] -> ShowS
show :: Reflector -> String
$cshow :: Reflector -> String
showsPrec :: Int -> Reflector -> ShowS
$cshowsPrec :: Int -> Reflector -> ShowS
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
/= :: Triangle -> Triangle -> Bool
$c/= :: Triangle -> Triangle -> Bool
== :: Triangle -> Triangle -> Bool
$c== :: Triangle -> Triangle -> Bool
Eq, Int -> Triangle -> ShowS
[Triangle] -> ShowS
Triangle -> String
(Int -> Triangle -> ShowS)
-> (Triangle -> String) -> ([Triangle] -> ShowS) -> Show Triangle
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Triangle] -> ShowS
$cshowList :: [Triangle] -> ShowS
show :: Triangle -> String
$cshow :: Triangle -> String
showsPrec :: Int -> Triangle -> ShowS
$cshowsPrec :: Int -> Triangle -> ShowS
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 :: 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)
 -> (Either lower Triangle, (Index height, Index width)))
-> [(Index height, Index width)]
-> [(Either lower Triangle, (Index height, Index 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)]
 -> [(Either lower Triangle, (Index height, Index width))])
-> [(Index height, Index width)]
-> [(Either lower Triangle, (Index height, Index 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 :: 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) (part,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
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
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 :: 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 (m :: * -> *) a. Monad m => a -> m a
return Int
a
      in case Order
order of
            Order
RowMajor ->
               (((Index height, Index width) -> Result check Int)
 -> (Either lower Triangle, (Index height, Index width))
 -> Result check Int)
-> (Int, (Index height, Index width) -> Result check Int)
-> (Int,
    (Either lower Triangle, (Index height, Index 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,
     (Either lower Triangle, (Index height, Index width))
     -> Result check Int))
-> (Int, (Index height, Index width) -> Result check Int)
-> (Int,
    (Either lower Triangle, (Index height, Index 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)
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)
 -> (Either lower Triangle, (Index height, Index width))
 -> Result check Int)
-> (Int, (Index width, Index height) -> Result check Int)
-> (Int,
    (Either lower Triangle, (Index height, Index 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,
     (Either lower Triangle, (Index height, Index width))
     -> Result check Int))
-> (Int, (Index width, Index height) -> Result check Int)
-> (Int,
    (Either lower Triangle, (Index height, Index 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)
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) (part,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 :: 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 (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 {
      Mosaic pack mirror uplo size -> PackingSingleton pack
mosaicPack :: PackingSingleton pack,
      Mosaic pack mirror uplo size -> MirrorSingleton mirror
mosaicMirror :: MirrorSingleton mirror,
      Mosaic pack mirror uplo size -> UpLoSingleton uplo
mosaicUplo :: UpLoSingleton uplo,
      Mosaic pack mirror uplo size -> Order
mosaicOrder :: Order,
      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
/= :: 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
Eq, Int -> Mosaic pack mirror uplo size -> ShowS
[Mosaic pack mirror uplo size] -> ShowS
Mosaic pack mirror uplo size -> String
(Int -> Mosaic pack mirror uplo size -> ShowS)
-> (Mosaic pack mirror uplo size -> String)
-> ([Mosaic pack mirror uplo size] -> ShowS)
-> Show (Mosaic pack mirror uplo size)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall pack mirror uplo size.
Show size =>
Int -> Mosaic pack mirror uplo size -> ShowS
forall pack mirror uplo size.
Show size =>
[Mosaic pack mirror uplo size] -> ShowS
forall pack mirror uplo size.
Show size =>
Mosaic pack mirror uplo size -> String
showList :: [Mosaic pack mirror uplo size] -> ShowS
$cshowList :: forall pack mirror uplo size.
Show size =>
[Mosaic pack mirror uplo size] -> ShowS
show :: Mosaic pack mirror uplo size -> String
$cshow :: forall pack mirror uplo size.
Show size =>
Mosaic pack mirror uplo size -> String
showsPrec :: Int -> Mosaic pack mirror uplo size -> ShowS
$cshowsPrec :: forall pack mirror uplo size.
Show size =>
Int -> Mosaic pack mirror uplo size -> ShowS
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 :: 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 :: 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 :: forall pack mirror uplo size.
PackingSingleton pack
-> MirrorSingleton mirror
-> UpLoSingleton uplo
-> Order
-> size
-> Mosaic pack mirror uplo size
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 :: UpLoSingleton uplo -> Order -> size -> Triangular uplo size
triangular = PackingSingleton Packed
-> MirrorSingleton NoMirror
-> UpLoSingleton uplo
-> Order
-> size
-> Triangular 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 :: Order -> size -> UpperTriangular size
upperTriangular = UpLoSingleton Upper -> Order -> size -> UpperTriangular size
forall uplo size.
UpLoSingleton uplo -> Order -> size -> Triangular uplo size
triangular UpLoSingleton Upper
Upper

lowerTriangular :: Order -> size -> LowerTriangular size
lowerTriangular :: Order -> size -> LowerTriangular size
lowerTriangular = UpLoSingleton Lower -> Order -> size -> LowerTriangular 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 :: PackingSingleton pack
-> UpLoSingleton uplo
-> Order
-> size
-> TriangularP pack uplo size
triangularP PackingSingleton pack
pack = PackingSingleton pack
-> MirrorSingleton NoMirror
-> UpLoSingleton uplo
-> Order
-> size
-> TriangularP pack 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 :: PackingSingleton pack
-> Order -> size -> UpperTriangularP pack size
upperTriangularP PackingSingleton pack
pack = PackingSingleton pack
-> UpLoSingleton Upper
-> Order
-> size
-> UpperTriangularP pack 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 :: PackingSingleton pack
-> Order -> size -> LowerTriangularP pack size
lowerTriangularP PackingSingleton pack
pack = PackingSingleton pack
-> UpLoSingleton Lower
-> Order
-> size
-> LowerTriangularP pack 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 :: Order -> size -> Symmetric size
symmetric = PackingSingleton Packed -> Order -> size -> Symmetric size
forall pack size.
PackingSingleton pack -> Order -> size -> SymmetricP pack size
symmetricP PackingSingleton Packed
Packed

symmetricP :: PackingSingleton pack -> Order -> size -> SymmetricP pack size
symmetricP :: PackingSingleton pack -> Order -> size -> SymmetricP pack size
symmetricP PackingSingleton pack
pack = PackingSingleton pack
-> MirrorSingleton SimpleMirror
-> UpLoSingleton Upper
-> Order
-> size
-> SymmetricP pack 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 :: 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
-> SymmetricP pack 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 :: Order -> size -> Hermitian size
hermitian = PackingSingleton Packed -> Order -> size -> Hermitian size
forall pack size.
PackingSingleton pack -> Order -> size -> HermitianP pack size
hermitianP PackingSingleton Packed
Packed

hermitianP :: PackingSingleton pack -> Order -> size -> HermitianP pack size
hermitianP :: PackingSingleton pack -> Order -> size -> HermitianP pack size
hermitianP PackingSingleton pack
pack = PackingSingleton pack
-> MirrorSingleton ConjugateMirror
-> UpLoSingleton Upper
-> Order
-> size
-> HermitianP pack 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 :: 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
-> HermitianP pack 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
/= :: Bands offDiag -> Bands offDiag -> Bool
$c/= :: forall offDiag. Bands offDiag -> Bands offDiag -> Bool
== :: Bands offDiag -> Bands offDiag -> Bool
$c== :: forall offDiag. Bands offDiag -> Bands offDiag -> Bool
Eq, Int -> Bands offDiag -> ShowS
[Bands offDiag] -> ShowS
Bands offDiag -> String
(Int -> Bands offDiag -> ShowS)
-> (Bands offDiag -> String)
-> ([Bands offDiag] -> ShowS)
-> Show (Bands offDiag)
forall offDiag. Natural offDiag => Int -> Bands offDiag -> ShowS
forall offDiag. Natural offDiag => [Bands offDiag] -> ShowS
forall offDiag. Natural offDiag => Bands offDiag -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Bands offDiag] -> ShowS
$cshowList :: forall offDiag. Natural offDiag => [Bands offDiag] -> ShowS
show :: Bands offDiag -> String
$cshow :: forall offDiag. Natural offDiag => Bands offDiag -> String
showsPrec :: Int -> Bands offDiag -> ShowS
$cshowsPrec :: forall offDiag. Natural offDiag => Int -> Bands offDiag -> ShowS
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
/= :: Filled -> Filled -> Bool
$c/= :: Filled -> Filled -> Bool
== :: Filled -> Filled -> Bool
$c== :: Filled -> Filled -> Bool
Eq, Int -> Filled -> ShowS
[Filled] -> ShowS
Filled -> String
(Int -> Filled -> ShowS)
-> (Filled -> String) -> ([Filled] -> ShowS) -> Show Filled
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Filled] -> ShowS
$cshowList :: [Filled] -> ShowS
show :: Filled -> String
$cshow :: Filled -> String
showsPrec :: Int -> Filled -> ShowS
$cshowsPrec :: Int -> Filled -> ShowS
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 :: 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 :: UpLoSingleton uplo
autoUplo = UpLoSingleton Upper -> UpLoSingleton Lower -> UpLoSingleton uplo
forall uplo (f :: * -> *).
UpLo uplo =>
f Upper -> f Lower -> f uplo
switchUpLo UpLoSingleton Upper
Upper UpLoSingleton Lower
Lower

uploOrder :: UpLoSingleton uplo -> Order -> Order
uploOrder :: 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 :: f Upper -> f Lower -> f Upper
switchUpLo f Upper
f f Lower
_ = f Upper
f

instance UpLo Shape.Lower where
   switchUpLo :: 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 :: 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 size, Index size))
-> [(Index size, Index size)] -> [(Index size, Index size)]
forall a b. (a -> b) -> [a] -> [b]
map (Index size, Index size) -> (Index size, Index size)
forall a b. (a, b) -> (b, a)
swap ([(Index size, Index size)] -> [(Index size, Index size)])
-> [(Index size, Index size)] -> [(Index size, Index 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 :: 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
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 :: 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)
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 size, Index size) -> Result check Int)
-> (Int, (Index size, Index size) -> Result check Int)
-> (Int, (Index size, Index size) -> Result check Int)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd (((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) ((Int, (Index size, Index size) -> Result check Int)
 -> (Int, (Index size, Index size) -> Result check Int))
-> (Int, (Index size, Index size) -> Result check Int)
-> (Int, (Index size, Index 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@(r,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 :: 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)
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 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 -> ShowS
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 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 -> ShowS
forall a. [a] -> [a] -> [a]
++ String
": no triangular number of elements")

triangleIndices ::
   (Shape.Indexed sh) => Order -> sh -> [(Shape.Index sh, Shape.Index sh)]
triangleIndices :: Order -> sh -> [(Index sh, Index sh)]
triangleIndices Order
RowMajor = UpperTriangular sh -> [(Index sh, Index 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)]
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 :: 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
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
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 :: 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)
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)
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 :: 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)
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 (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)
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 {
      Banded sub super meas vert horiz height width
-> (UnaryProxy sub, UnaryProxy super)
bandedOffDiagonals :: (UnaryProxy sub, UnaryProxy super),
      Banded sub super meas vert horiz height width -> Order
bandedOrder :: Order,
      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
/= :: 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
Eq, Int -> Banded sub super meas vert horiz height width -> ShowS
[Banded sub super meas vert horiz height width] -> ShowS
Banded sub super meas vert horiz height width -> String
(Int -> Banded sub super meas vert horiz height width -> ShowS)
-> (Banded sub super meas vert horiz height width -> String)
-> ([Banded sub super meas vert horiz height width] -> ShowS)
-> Show (Banded sub super meas vert horiz height width)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> 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 -> ShowS
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] -> ShowS
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
showList :: [Banded sub super meas vert horiz height width] -> ShowS
$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] -> ShowS
show :: Banded sub super meas vert horiz height width -> 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
showsPrec :: Int -> Banded sub super meas vert horiz height width -> ShowS
$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 -> ShowS
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 :: 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 :: 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 :: 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 :: (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 :: 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 :: UnaryProxy n -> Nat n
natFromProxy UnaryProxy 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 :: (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)),
    (UnaryProxy subC
forall a. Proxy a
Proxy,UnaryProxy 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 :: 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 :: 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
-> BandedSquareMeas U0 U0 meas 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 :: (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
-> BandedGeneral sub super 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 :: (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
-> BandedSquare sub super 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 -> BandedSquare sub super size)
-> (size -> Extent Shape Small Small size size)
-> size
-> BandedSquare sub super 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 :: 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
-> RectangularDiagonal 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 row, Eq column) =>
BandedIndex row column -> BandedIndex row column -> Bool
/= :: BandedIndex row column -> BandedIndex row column -> Bool
$c/= :: forall row column.
(Eq row, Eq column) =>
BandedIndex row column -> BandedIndex row column -> Bool
== :: BandedIndex row column -> BandedIndex row column -> Bool
$c== :: forall row column.
(Eq row, Eq column) =>
BandedIndex row column -> BandedIndex row column -> Bool
Eq, Int -> BandedIndex row column -> ShowS
[BandedIndex row column] -> ShowS
BandedIndex row column -> String
(Int -> BandedIndex row column -> ShowS)
-> (BandedIndex row column -> String)
-> ([BandedIndex row column] -> ShowS)
-> Show (BandedIndex row column)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall row column.
(Show row, Show column) =>
Int -> BandedIndex row column -> ShowS
forall row column.
(Show row, Show column) =>
[BandedIndex row column] -> ShowS
forall row column.
(Show row, Show column) =>
BandedIndex row column -> String
showList :: [BandedIndex row column] -> ShowS
$cshowList :: forall row column.
(Show row, Show column) =>
[BandedIndex row column] -> ShowS
show :: BandedIndex row column -> String
$cshow :: forall row column.
(Show row, Show column) =>
BandedIndex row column -> String
showsPrec :: Int -> BandedIndex row column -> ShowS
$cshowsPrec :: forall row column.
(Show row, Show column) =>
Int -> BandedIndex row column -> ShowS
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))
 -> BandedIndex (Index height) (Index width))
-> [(Index height, Either Int (Index width))]
-> [BandedIndex (Index height) (Index 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))]
 -> [BandedIndex (Index height) (Index width)])
-> [(Index height, Either Int (Index width))]
-> [BandedIndex (Index height) (Index 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))
 -> BandedIndex (Index height) (Index width))
-> [(Index width, Either Int (Index height))]
-> [BandedIndex (Index height) (Index 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))]
 -> [BandedIndex (Index height) (Index width)])
-> [(Index width, Either Int (Index height))]
-> [BandedIndex (Index height) (Index 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 :: 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 (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 :: 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 :: 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 :: (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 :: (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 :: (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)
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 (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 (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)
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)
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 (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 (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)
Shape.unifiedIndexFromOffset height
height Int
ri)


data BandedHermitian off size =
   BandedHermitian {
      BandedHermitian off size -> UnaryProxy off
bandedHermitianOffDiagonals :: UnaryProxy off,
      BandedHermitian off size -> Order
bandedHermitianOrder :: Order,
      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
/= :: 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
Eq, Int -> BandedHermitian off size -> ShowS
[BandedHermitian off size] -> ShowS
BandedHermitian off size -> String
(Int -> BandedHermitian off size -> ShowS)
-> (BandedHermitian off size -> String)
-> ([BandedHermitian off size] -> ShowS)
-> Show (BandedHermitian off size)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall off size.
(Natural off, Show size) =>
Int -> BandedHermitian off size -> ShowS
forall off size.
(Natural off, Show size) =>
[BandedHermitian off size] -> ShowS
forall off size.
(Natural off, Show size) =>
BandedHermitian off size -> String
showList :: [BandedHermitian off size] -> ShowS
$cshowList :: forall off size.
(Natural off, Show size) =>
[BandedHermitian off size] -> ShowS
show :: BandedHermitian off size -> String
$cshow :: forall off size.
(Natural off, Show size) =>
BandedHermitian off size -> String
showsPrec :: Int -> BandedHermitian off size -> ShowS
$cshowsPrec :: forall off size.
(Natural off, Show size) =>
Int -> BandedHermitian off size -> ShowS
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))
 -> BandedIndex (Index size) (Index size))
-> [(Index size, Either Int (Index size))]
-> [BandedIndex (Index size) (Index 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))]
 -> [BandedIndex (Index size) (Index size)])
-> [(Index size, Either Int (Index size))]
-> [BandedIndex (Index size) (Index 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))
 -> BandedIndex (Index size) (Index size))
-> [(Index size, Either Int (Index size))]
-> [BandedIndex (Index size) (Index 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))]
 -> [BandedIndex (Index size) (Index size)])
-> [(Index size, Either Int (Index size))]
-> [BandedIndex (Index size) (Index 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 :: 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 (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 :: 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 :: 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)
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)
Shape.unifiedIndexFromOffset sh
size Int
ci
            else BandedIndex ix ix -> Result check (BandedIndex ix ix)
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)
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)
Shape.unifiedIndexFromOffset sh
size Int
ri
            else BandedIndex ix ix -> Result check (BandedIndex ix ix)
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