open_hypergraphs.finite_function
An implementation of finite functions as arrays. All datastructures are ultimately built from finite functions. For an overview, see Wilson and Zanasi [WZ23], Section 2.2.2.
Finite functions can be thought of as a thin wrapper around integer arrays whose elements are within a specified range. Here’s an example of contructing a finite function:
>>> print(FiniteFunction(3, [0, 1, 2, 0]))
[0 1 2 0] : 4 → 3
Mathematically, this represents a function from the set of 4 elements to the set
of 3 elements, and so its “type” is 4 → 3.
There are several constructors for finite functions corresponding to useful
morphisms in category theory.
For example, the identity map is like numpy’s arange:
>>> print(FiniteFunction.identity(5))
[0 1 2 3 4] : 5 → 5
and the terminal map is an array of zeroes:
>>> print(FiniteFunction.terminal(5))
[0 0 0 0 0] : 5 → 1
Finite functions form a symmetric monoidal category. They can be composed sequentially:
>>> print(FiniteFunction.identity(5) >> FiniteFunction.terminal(5))
[0 0 0 0 0] : 5 → 5
And in parallel:
>>> FiniteFunction.identity(5) @ FiniteFunction.terminal(5)
FiniteFunction(6, [0 1 2 3 4 5 5 5 5 5])
- class open_hypergraphs.finite_function.FiniteFunction(target, table)
Finite functions parametrised over the underlying array type (the “backend”). This implementation assumes there is a cls.Array member implementing various primitives. For example, cls.Array.sum() should compute the sum of an array.
- Dtype: Any
- Array: Type[ArrayBackend]
- target: None | int
- property dtype: Any
- property source: int
The source (aka “domain”) of this finite function
- property type
Get the source and target of this finite function.
- Returns:
(f.source, f.target)
- Return type:
tuple
- classmethod identity(n: int) FiniteFunction
Return the identity finite function of type n → n. :param n: The object of which to return the identity map :type n: int
- Returns:
Identity map at n
- Return type:
- compose(g: FiniteFunction) FiniteFunction
Compose this finite function with another
- Parameters:
g – A FiniteFunction for which self.target == g.source
- Returns:
The composition f ; g.
- Raises:
ValueError – if self.target != g.source
- classmethod initial(b: None | int, dtype=None) FiniteFunction
Compute the initial map
? : 0 → b
- to_initial() FiniteFunction
Turn a finite function
f : A → Binto the initial map? : 0 → B.>>> f.to_initial() == FiniteFunction.initial(f.target) >> f
- classmethod inj0(a: int, b: int) FiniteFunction
Compute the injection
ι₀ : a → a + b
- classmethod inj1(a: int, b: int) FiniteFunction
Compute the injection
ι₁ : b → a + b
- inject0(b: int) FiniteFunction
Directly compute (f ; ι₀) instead of by composition.
>>> f.inject0(b) == f >> ι₀
- inject1(a: int) FiniteFunction
Directly compute (f ; ι₁) instead of by composition.
>>> f.inject1(a) == f >> ι₁
- coproduct(g: FiniteFunction) FiniteFunction
Given maps
f : A₀ → Bandg : A₁ → Bcompute the coproductf.coproduct(g) : A₀ + A₁ → B
- static unit() int
return the unit object of the category
- tensor(g: FiniteFunction) FiniteFunction
Given maps
f : A₀ → B₀andg : A₁ → B₁compute the tensor productf.tensor(g) : A₀ + A₁ → B₀ + B₁
- classmethod twist(a: int, b: int) FiniteFunction
- coequalizer(g: FiniteFunction) FiniteFunction
Given finite functions
f, g : A → B, return the coequalizerq : B → Qwhich is the unique arrow such thatf >> q = g >> qhaving a unique arrow to any other such map.
- coequalizer_universal(f: FiniteFunction) FiniteFunction
Given a coequalizer q : B → Q of morphisms a, b : A → B and some f : B → B’ such that f(a) = f(b), Compute the universal map u : Q → B’ such that q ; u = f.
- classmethod terminal(a: int) FiniteFunction
Compute the terminal map
! : a → 1.
- classmethod singleton(x: int, b: int | None, dtype=None) FiniteFunction
return the singleton array
[x]whose domain isb.
- classmethod constant(x: int, a: int, b: int | None, dtype=None) FiniteFunction
constant(x, a, b)is the constant function of typea → bmapping all inputs to the valuex.
- argsort() Self
Given a finite function
f : A → BReturn the stable sorting permutationp : A → Asuch thatp >> fis monotonic.
- classmethod transpose(a: int, b: int, dtype=None) FiniteFunction
transpose(a, b)is the “transposition permutation” for ana → bmatrix.Given an
b*a-dimensional input thought of as a matrix in row-major order withbrows andacolumns,transpose(a, b)computes the “target indices” in the transpose. So if we have a matrixM : A → Band a matrixN : B → A, then setting indexesN[transpose(a, b)] = Mis the same as writingN = M.T
- classmethod coproduct_list(fs: List[FiniteFunction], target=None, dtype=None)
Compute the coproduct of a list of finite functions. O(n) in size of the result.
Warning
Does not speed up to O(log n) in the parallel case.
- classmethod tensor_list(fs: List[FiniteFunction])
Compute the tensor product of a list of finite functions. O(n) in size of the result.
Warning
Does not speed up to O(log n) in the parallel case.
- injections(a: FiniteFunction)
Given a finite function
s : N → Krepresenting the objects of the coproductΣ_{n ∈ N} s(n)whose injections have the typeι_x : s(x) → Σ_{n ∈ N} s(n), and given a finite mapa : A → N, compute the coproduct of injectionsinjections(s, a) : Σ_{x ∈ A} s(x) → Σ_{n ∈ N} s(n) injections(s, a) = Σ_{x ∈ A} ι_a(x)So that
injections(s, id) == idNote that when a is a permutation, injections(s, a) is a “blockwise” version of that permutation with block sizes equal to s.
- class open_hypergraphs.finite_function.HasFiniteFunction(*args, **kwargs)
Classes which have a chosen finite function implementation
- classmethod FiniteFunction() Type[FiniteFunction]
- class open_hypergraphs.finite_function.IndexedCoproduct(sources: FiniteFunction, values: FiniteFunction)
A finite coproduct of finite functions. You can think of it simply as a segmented array. Categorically, it represents a finite coproduct:
Σ_{i ∈ N} f_i : s(f_i) → Yas a pair of maps:
sources: N → Nat (target is natural numbers) values : sum(sources) → Σ₀
- sources: FiniteFunction
- values: FiniteFunction
- property dtype
Return the dtype of the underlying table
- classmethod initial(target: None | int, dtype=None) IndexedCoproduct
- classmethod singleton(values: FiniteFunction, dtype=None) IndexedCoproduct
Turn a
FiniteFunctionf : A → Binto anIndexedCoproduct`` Σ_{x ∈ 1} f : A → B
- classmethod elements(values: FiniteFunction, dtype=None) IndexedCoproduct
Turn a
FiniteFunctionf : A → Binto anIndexedCoproduct`` Σ_{a ∈ A} f_a : A → B
- property target: None | int
- classmethod from_list(target, fs: List[FiniteFunction], dtype=None) IndexedCoproduct
Create an IndexedCoproduct from a list of
FiniteFunction
- coproduct(y: IndexedCoproduct) IndexedCoproduct
- tensor(y: IndexedCoproduct) IndexedCoproduct
- classmethod tensor_list(xs: List[IndexedCoproduct])
Concatenate a nonempty sequence of IndexedCoproduct
- indexed_values(x: FiniteFunction) FiniteFunction
Like
map_indexesbut only computes thevaluesarray of an IndexedCoproduct
- map_values(x: FiniteFunction) IndexedCoproduct
Given an
IndexedCoproductof finite functions:Σ_{i ∈ X} f_i : Σ_{i ∈ X} A_i → Band a finite function:
b : B → C
return a new
IndexedCoproductrepresenting:Σ_{i ∈ X} f_i : Σ_{i ∈ W} A_i → C
- map_indexes(x: FiniteFunction) IndexedCoproduct
Given an
IndexedCoproductof finite functions:Σ_{i ∈ X} f_i : Σ_{i ∈ X} A_i → Band a finite function:
x : W → X
return a new
IndexedCoproductrepresenting:Σ_{i ∈ X} f_{x(i)} : Σ_{i ∈ W} A_{x(i)} → B
- flatmap(y: IndexedCoproduct) IndexedCoproduct
Compose two IndexedCoproducts.
- class open_hypergraphs.finite_function.HasIndexedCoproduct(*args, **kwargs)
Classes which have a chosen indexed coproduct implementation
- abstract classmethod IndexedCoproduct() Type[IndexedCoproduct]