circuits-mat
Safe HaskellNone
LanguageGHC2024

Circuit.Mat.Affine

Description

Affine indexing morphisms between harpie-style shapes.

An Affine p q is an affine map q = Λ·p + v where Λ is a len q × len p matrix of natural numbers and v is a len q offset vector. In-bounds is checked at construction time.

These are the change-of-basis joints that let Mat constructions flow between carriers: flatten, shapen, axis swap, and arbitrary permutations are all affine maps, and harpie consumes them as stride/index maps.

Synopsis

Type

data Affine (p :: [Nat]) (q :: [Nat]) Source #

An affine map from shape p to shape q.

The phantom types carry the shape; the fields carry the concrete matrix and offset. Use affine to construct a validated value.

Constructors

Affine 

Fields

Instances

Instances details
Eq (Affine p q) Source # 
Instance details

Defined in Circuit.Mat.Affine

Methods

(==) :: Affine p q -> Affine p q -> Bool #

(/=) :: Affine p q -> Affine p q -> Bool #

Show (Affine p q) Source # 
Instance details

Defined in Circuit.Mat.Affine

Methods

showsPrec :: Int -> Affine p q -> ShowS #

show :: Affine p q -> String #

showList :: [Affine p q] -> ShowS #

Smart constructor

affine :: forall (p :: [Nat]) (q :: [Nat]). (KnownNats p, KnownNats q) => [[Int]] -> [Int] -> Maybe (Affine p q) Source #

Smart constructor. Returns Nothing if the dimensions do not match the shape, if entries are negative, or if offsets are out of bounds.

Category structure

identityAffine :: forall (p :: [Nat]). KnownNats p => Affine p p Source #

Identity affine map.

composeAffine :: forall (p :: [Nat]) (q :: [Nat]) (r :: [Nat]). (KnownNats p, KnownNats q, KnownNats r) => Affine q r -> Affine p q -> Affine p r Source #

Composition of affine maps.

>>> let Just f = affine @'[2,3] @'[6] [[3,1]] [0]
>>> let Just g = affine @'[6] @'[2,3] [[1],[2]] [0,0]
>>> applyAffine (composeAffine g f) [1,2]
[5,10]

applyAffine :: forall (p :: [Nat]) (q :: [Nat]). Affine p q -> [Int] -> [Int] Source #

Apply an affine map to an index vector. Assumes the input is in bounds.

Canonical maps

flattenAffine :: forall (p :: [Nat]). KnownNats p => Affine p '[SizeOf p] Source #

Flatten a shape to its total size.

swapAxesAffine :: forall (m :: Nat) (n :: Nat). Affine '[m, n] '[n, m] Source #

Swap the two axes of a rank-2 shape.

permuteAxes :: forall (p :: [Nat]) (q :: [Nat]). (KnownNats p, KnownNats q) => [Int] -> Maybe (Affine p q) Source #

Permute axes by a value-level permutation list.

The permutation must be a reordering of [0 .. length p - 1]. No type-level tracking of the output shape is attempted; the caller supplies the desired shape phantom.

Harpie seam

toIndexMap :: forall (p :: [Nat]) (q :: [Nat]). Affine p q -> Fins p -> Fins q Source #

Apply the affine map to harpie Fins.

toHarpieBackpermute :: forall (p :: [Nat]) (q :: [Nat]) s. (KnownNats p, KnownNats q) => Affine p q -> Array p s -> Array q s Source #

Build a harpie backpermute from an affine map.

This is the code generator: an affine reindexing becomes a harpie backpermute with an index-map derived from the affine inverse. The map is precomputed, so the result fuses with surrounding harpie operations.

Precondition: the affine map must be a bijection between the index sets (true for flatten, permutation, and axis-swap). If it is not, the lookup will fail at runtime.