abelian package

Submodules

abelian.functions module

This module consists of a class for functions on LCAs, called LCAFunc. Such a function represents a function from a LCA G to the complex numbers C.

class LCAFunc(representation, domain)

Bases: collections.abc.Callable

A function from an LCA to a complex number.

__init__(representation, domain)

Initialize a function G -> C.

Parameters:
  • representation (function or n-dimensional list of domain allows it) – A function which takes in a list as a first argument, representing the group element. Alternatively a list of lists if the domain is discrete and of finite order.
  • domain (LCA) – An elementary locally compact abelian group, which is the domain of the function.

Examples

If a function representation is used, functions on domains are relatively straightforward.

>>> def power(list_arg, exponent = 2):
...     return sum(x**exponent for x in list_arg)
>>> from abelian import LCAFunc, LCA
>>> # A function on R/Z = T
>>> f = LCAFunc(power, LCA([1], [False]))
>>> f([0.5])
0.25
>>> f([1.5], exponent = 3) == 0.5**3
True
>>> # A function on Z_p
>>> f = LCAFunc(power, LCA([5, 10]))
>>> f([1,1]) == f([6, 11])
True
>>> f([2, 2], exponent = 1)
4

If a table representation is used, the function can be defined on direct sums of Z_n.

>>> # Define a table: a list of lists
>>> table = [[1, 2],
...          [3, 4],
...          [5, 6]]
>>> f = LCAFunc(table, LCA([3, 2]))
>>> f([1, 1])
4
>>> f([3, 1])
2
>>> import numpy as np
>>> f = LCAFunc(np.array(table), LCA([3, 2]))
>>> f([1, 1])
4
copy()

Return a copy of the instance.

Returns:function – A copy of self.
Return type:LCAFunc

Examples

>>> from abelian import LCA, LCAFunc
>>> f = LCAFunc(lambda x:sum(x), LCA([0]))
>>> g = f.copy()
>>> f([1]) == g([1])
True
dft(func_type=None)

If the domain allows it, compute DFT.

This method uses the n-dimensional Fast Fourier Transform (FFT) to compute the n-dimensional Discrete Fourier Transform. The data is converted to a ndarray object for efficient numerical computation, then the fftn() function is used to compute the fast fourier transform.

This implementation is different from the implementation in fftn() by a factor. While the fftn() function divides by m*n on the inverse transform, this implementation does it on the forward transform, and vice verca.

Parameters:func_type (str) – If None, compute the function values using pure python. If ‘ogrid’, use a numpy.ogrid (open mesh-grid) to compute the functino values. If ‘mgrid’, use a numpy.mgrid (dense mesh-grid) to compute the function values.
Returns:function – The discrete Fourier transformation of the original function.
Return type:LCAFunc

Examples

>>> from abelian import LCA, LCAFunc
>>> # Create a simple linear function on Z_5 + Z_4 + Z_3
>>> domain = LCA([5, 4, 3])
>>> def linear(list_arg):
...     return sum(list_arg)
>>> func = LCAFunc(linear, domain)
>>> func([1, 2, 1])
4
>>> # Take the discrete fourier transform and evaluate
>>> func_dft = func.dft()
>>> func_dft([0, 0, 0]) / (5*4*3) # Divide by number of points
(4.5+0j)
>>> # Take the inverse discrete fourier transform
>>> func_dft_idft = func_dft.idft()
>>> # Numerics might not make this equal, but mathematically it is
>>> abs(func_dft_idft([1, 2, 1]) - func([1, 2, 1])) < 10e-10
True
evaluate(list_arg, *args, **kwargs)

Evaluate function on a group element.

Parameters:
  • list_arg (list) – The first argument, which must be a list (interpreted as vector).
  • *args (tuple) – An unpacked tuple of arguments.
  • **kwargs (dict) – An unpacked dictionary of arguments.
Returns:

value – A complex number (could be real or integer).

Return type:

complex, float or int

Examples

>>> from abelian import LCA, LCAFunc
>>> R = LCA([0], [False])
>>> function = LCAFunc(lambda x: 1, domain = R**2)
>>> function([1, 2])
1

Some subtle concepts are shown below.

>>> function(1)
Traceback (most recent call last):
...
ValueError: Argument to function must be list.
>>> function([1])
Traceback (most recent call last):
...
ValueError: LCAFunc argument does not match domain length.
>>> type(function([1, 1])) in (int, float, complex)
True
idft(func_type=None)

If the domain allows it, compute inv DFT.

This is a wrapper around np.fft.ifftn.

Parameters:func_type (str) – If None, compute the function values using pure python. If ‘ogrid’, use a numpy.ogrid (open mesh-grid) to compute the functino values. If ‘mgrid’, use a numpy.mgrid (dense mesh-grid) to compute the function values.
Returns:function – The inverse discrete Fourier transformation of the original function.
Return type:LCAFunc

Examples

>>> from abelian import LCA, LCAFunc
>>> # Create a simple linear function on Z_5 + Z_4 + Z_3
>>> domain = LCA([5, 4, 3])
>>> def linear(list_arg):
...     x, y, z = list_arg
...     return complex(x + y, z - x)
>>> func = LCAFunc(linear, domain)
>>> func([1, 2, 1])
(3+0j)
>>> func_idft = func.idft()
>>> func_idft([0, 0, 0]) * (5*4*3)
(210-60j)
pointwise(other, operator)

Apply pointwise binary operator.

Parameters:
  • other (LCAFunc) – Another Functin on the same domain.
  • operator (function) – A binary operator.
Returns:

function – The resulting function, new = operator(self, other).

Return type:

LCAFunc

Examples

>>> from abelian import LCA
>>> domain = LCA([5])
>>> function1 = LCAFunc(lambda arg: sum(arg), domain)
>>> function2 = LCAFunc(lambda arg: sum(arg)*2, domain)
>>> from operator import add
>>> pointwise_add = function1.pointwise(function2, add)
>>> function1([2]) + function2([2]) == pointwise_add([2])
True
>>> from operator import mul
>>> sample_points = [0, 1, 2, 3, 4]
>>> pointwise_mul = function1.pointwise(function2, mul)
>>> pointwise_mul.sample(sample_points) # i * 2*i = 2*i*i
[0, 2, 8, 18, 32]
pullback(morphism)

Return the pullback along morphism.

The pullback is the composition morphism, then self. The domain of self must match the target of the morphism.

Parameters:morphism (HomLCA) – A homomorphism between LCAs
Returns:pullback – The pullback of self along morphism.
Return type:LCAFunc

Examples

Using a simple function and homomorphism.

>>> from abelian import HomLCA, LCA
>>> # Create a function on Z
>>> f = LCAFunc(lambda list_arg:list_arg[0]**2, LCA([0]))
>>> # Create a homomorphism from Z to Z
>>> phi = HomLCA([2])
>>> # Pull f back along phi
>>> f_pullback = f.pullback(phi)
>>> f_pullback([4]) == 64 # (2*4)**2 == 64
True

Using a simple function and homomorphism represented as matrix.

>>> from abelian import HomLCA, LCA
>>> def func(list_arg):
...     x, y = tuple(list_arg)
...     return x ** 2 + y ** 2
>>> domain = LCA([5, 3])
>>> f = LCAFunc(func, domain)
>>> phi = HomLCA([1, 1], target=domain)
>>> f_pullback = f.pullback(phi)
>>>
>>> f_pullback([8]) == 13
True
pushforward(morphism, terms_in_sum=50)

Return the pushforward along morphism.

The pushforward is computed by solving an equation, finding the kernel, and iterating through the kernel. The pushfoward approximates a possibly infinite sum by terms_in_sum terms.

Parameters:
  • morphism (HomLCA) – A homomorphism between LCAs.
  • terms_in_sum (int) – The number of terms in the sum to use, i.e. the number of solutions to the equation to iterate over.
  • norm_condition (function) – If not None, a function can be used to terminate the sum. The norm_condition must be a function of a group element, and when the function is false for every v in the kernel such that maxnorm(v) = C for a given C, then the sum terminates.
Returns:

pushforward – The pushforward of self along morphism.

Return type:

LCAFunc

Examples

The first example is a homomorphism R -> T.

>>> from abelian import LCA, LCAFunc, HomLCA
>>> R = LCA([0], [False])
>>> T = LCA([1], [False])
>>> epimorphism = HomLCA([1], source = R, target = T)
>>> func_expr = lambda x: 2**-sum(x_j**2 for x_j in x)
>>> func = LCAFunc(func_expr, domain = R)
>>> func.pushforward(epimorphism, 1)([0]) # 1 term in the sum
1.0
>>> func.pushforward(epimorphism, 3)([0]) # 1 + 0.5*2
2.0
>>> func.pushforward(epimorphism, 5)([0]) # 1 + 0.5*2 + 0.0625*2
2.125

The first example is a homomorphism Z -> Z_2.

>>> from abelian import LCA, LCAFunc, HomLCA
>>> Z = LCA([0], [True])
>>> Z_2 = LCA([2], [True])
>>> epimorphism = HomLCA([1], source = Z, target = Z_2)
>>> func_expr = lambda x: 2**-sum(x_j**2 for x_j in x)
>>> func = LCAFunc(func_expr, domain = Z)
>>> func.pushforward(epimorphism, 1)([0]) # 1 term in the sum
1.0
>>> func.pushforward(epimorphism, 3)([0]) # 1 + 0.5*2 + 0.0625*2
1.125

The third example is a homomorphism R -> R.

>>> from abelian import LCA, LCAFunc, HomLCA
>>> R = LCA([0], [False])
>>> epimorphism = HomLCA([1], source = R, target = R)
>>> func_expr = lambda x: 2**-sum(x_j**2 for x_j in x)
>>> func = LCAFunc(func_expr, domain = R)
>>> func.pushforward(epimorphism, 3)([0]) # 1 term in the sum
1.0
sample(list_of_elements, *args, **kwargs)

Sample on a list of group elements.

Parameters:list_of_elements (list) – A list of groups elements, where each element is also a list.
Returns:sampled_vals – A list of sampled values at the elements.
Return type:list

Examples

>>> from abelian import LCAFunc, LCA
>>> func = LCAFunc(lambda x : sum(x), LCA([0, 0]))
>>> sample_points = [[0, 0], [1, 2], [2, 1], [3, 3]]
>>> func.sample(sample_points)
[0, 3, 3, 6]
shift(list_shift)

Shift the function.

Parameters:list_shift (list) – A list of shifts.
Returns:function – A new function which is shifted.
Return type:LCAFunc

Examples

>>> from abelian import LCAFunc, LCA
>>> func = LCAFunc(lambda x: sum(x), LCA([0]))
>>> func.sample([0, 1, 2, 3])
[0, 1, 2, 3]
>>> func.shift([2]).sample([0, 1, 2, 3])
[-2, -1, 0, 1]
to_latex()

Return as a \(\LaTeX\) string.

Returns:latex_str – The object as a latex string.
Return type:str
to_table(*args, **kwargs)

Return a n-dimensional table.

Returns:table – The table representation.
Return type:n-dimensional list

Examples

>>> from abelian import LCA, LCAFunc
>>> domain = LCA([5, 5])
>>> f = LCAFunc(lambda x: sum(x), domain)
>>> table = f.to_table()
>>> table[1][1]
(2+0j)

Using a table from the start.

>>> from abelian import LCA, LCAFunc
>>> import numpy as np
>>> domain = LCA([5, 5])
>>> f = LCAFunc(np.eye(5), domain)
>>> table = f.to_table()
>>> table[1][1]
1.0
>>> type(table)
<class 'numpy.ndarray'>
>>> f = LCAFunc([[1, 2], [2, 4]], LCA([2, 2]))
>>> f.to_table()
[[1, 2], [2, 4]]
transversal(epimorphism, transversal_rule=None, default_value=0)

Pushforward using transversal rule.

If (transversal * epimorphism)(x) = x, then x is pushed forward using the transversal rule. If not, then the default_value value is returned.

Parameters:
  • epimorphism (HomLCA) – An epimorphism.
  • transversal_rule (function) – A function with signature func(list_arg, *args, **kwargs).
Returns:

function – The pushforward of self along the transversal of the epimorphism.

Return type:

LCAFunc

Examples

>>> from abelian import LCA, LCAFunc, HomLCA
>>> n = 5 # Sice of the domain, Z_n
>>> f_on_Zn = LCAFunc(lambda x: sum(x)**2, LCA([n]))
>>> # To move this function to Z, create an epimorphism and a
>>> # transversal rule
>>> epimorphism = HomLCA([1], source = [0], target = [n])
>>> def transversal_rule(x):
...     if sum(x) < n/2:
...         return [sum(x)]
...     elif sum(x) >= n/2:
...         return [sum(x) - n]
...     else:
...         return None
>>> # Do the pushforward with the transversal rule
>>> f_on_Z = f_on_Zn.transversal(epimorphism, transversal_rule)
>>> f_on_Z.sample(list(range(-n, n+1)))
[0, 0, 0, 9.0, 16.0, 0.0, 1.0, 4.0, 0, 0, 0]
voronoi(epimorphism, norm_p=2)

Return the Voronoi transversal function.

This higher-order function returns a quotient transversal which maps x to the y which is cloest to the low-frequency fourier mode.

Parameters:
  • epimorphism_kernel (HomLCA) – The kernel of the epimorphism that we want to find a section for.
  • norm (function or None) – A norm function, if None, the max-norm is used.
Returns:

sigma – A function x -> y.

Return type:

function

Examples

>>> # An orthogonal example
>>> from abelian import LCAFunc, HomLCA, LCA
>>> Z_10 = LCA([10])
>>> epimorphism = HomLCA([1], target = Z_10)

abelian.groups module

This module consists of a class for elementary locally compact abelian groups, the LCA class.

class LCA(orders, discrete=None)

Bases: collections.abc.Sequence, collections.abc.Callable

An elementary locally compact abelian group (LCA).

__init__(orders, discrete=None)

Initialize a new LCA.

This class represents locally compact abelian groups, defined by their orders and whether or not they are discrete. An order of 0 means infinite order. The possible groups are:

  • \(\mathbb{Z}_n\) : order = n, discrete = True
  • \(\mathbb{Z}\) : order = 0, discrete = True
  • \(T\) : order = 1, discrete = False
  • \(\mathbb{R}\) : order = 0, discrete = False

Every locally compact abelian group is isomorphic to a direct sum or one or several of the groups above.

Parameters:
  • orders (list) – A list of orders, e.g. [6, 8, 11].
  • discrete (list) – A list of booleans such as [True, False, …] or alternatively a list of letters such as [‘d’, ‘c’, …], where ‘d’ stands for discrete and ‘c’ stands for continuous. If None, it defaults to discrete.

Examples

>>> # Create G = Z_5 + Z_6 + Z_7 in three ways
>>> G1 = LCA([5, 6, 7])
>>> G2 = LCA([5, 6, 7], [True, True, True])
>>> G3 = LCA([5, 6, 7], ['d']*3)
>>> (G1 == G2 == G3)
True
>>> # Create G = R + Z
>>> G = LCA(orders = [0, 0], discrete = [False, True])
>>> G = LCA([], [])
>>> G
[]
canonical()

Return the LCA in canonical form using SNF.

The canonical form decomposition will:

  1. Put the torsion (discrete with order >= 1) subgroup in a canonical form using invariant factor decomposition from the Smith Normal Form decomposition.
  2. Sort the non-torsion subgroup.
Returns:group – The LCA in canonical form.
Return type:LCA

Examples

>>> G = LCA([4, 3])
>>> G.canonical() == LCA([12])
True
>>> G = LCA([1, 1, 8, 2, 4], ['c', 'd', 'd', 'd', 'd'])
>>> G.canonical() == LCA([1], ['c']) + LCA([2, 4, 8])
True
compose_self(power)

Repeated direct summation.

Returns:group – A new group.
Return type:LCA

Examples

>>> R = LCA([0], [False])
>>> (R + R) == R**2
True
>>> R**0 == LCA.trivial()
True
>>> Z = LCA([0])
>>> (Z + R)**2 == Z + R + Z + R
True
contained_in(other)

Whether the LCA is contained in other.

A LCA G is contained in another LCA H iff there exists an injection from the elements of G to H such that every source/target of the mapping is isomorphic. In other words, every group in G must be found in H, and no two groups in G can be identified with the same isomorphic group is H.

Parameters:other (LCA) – A locally compact abelian group.
Returns:is_subgroup – Whether or not self is contained in other.
Return type:bool

Examples

>>> # Simple example
>>> G = LCA([2, 2, 3])
>>> H = LCA([2, 2, 3, 3])
>>> G.contained_in(H)
True
>>> # Order does not matter
>>> G = LCA([2, 3, 2])
>>> H = LCA([2, 2, 3, 3])
>>> G.contained_in(H)
True
>>> # Trivial groups are not removed
>>> G = LCA([2, 3, 2, 1])
>>> H = LCA([2, 2, 3, 3])
>>> G in H
False
copy()

Return a copy of the LCA.

Returns:group – A copy of the LCA.
Return type:LCA

Examples

>>> G = LCA([1, 5, 7], [False, True, True])
>>> H = G.copy()
>>> G == H
True
dual()

Return the Pontryagin dual of the LCA.

Returns a group isomorphic to the Pontryagin dual.

Returns:group – The Pontryagin dual of the LCA.
Return type:LCA

Examples

>>> G = LCA([5, 1], [True, False])
>>> H = LCA([5, 0], [True, True])
>>> G.dual() == H
True
>>> G.dual().dual() == G
True
>>> self_dual = LCA([5])
>>> self_dual.dual() == self_dual
True
elements_by_maxnorm(norm_values=None)

Yield elements corresponding to max norm value.

If the group is discrete, elements can be generated by maxnorm.

Parameters:norm_values (iterable) – An iterable containing integer norm values.
Yields:group_element (list) – Group elements with max norm specified by the input iterable.

Examples

>>> G = LCA([0, 0])
>>> for element in G.elements_by_maxnorm([0, 1]):
...     print(element)
[0, 0]
[1, -1]
[-1, -1]
[1, 0]
[-1, 0]
[1, 1]
[-1, 1]
[0, 1]
[0, -1]
>>> G = LCA([5, 8])
>>> for element in G.elements_by_maxnorm([4, 5]):
...     print(element)
[3, 4]
[4, 4]
[0, 4]
[1, 4]
[2, 4]
equal(other)

Whether or not two LCAs are equal.

Two LCAs are equal iff the list of orders and the list of discrete are both equal.

Parameters:other (LCA) – The LCA to compare equality with.
Returns:equal – Whether or not the LCAs are equal.
Return type:bool

Examples

>>> G = LCA([1, 5, 7], [False, True, True])
>>> H = G.copy()
>>> G == H  # The `==` operator is overloaded
True
>>> G.equal(H)  # Equality using the method
True
getitem(key)

Return a slice of the LCA.

Parameters:key (slice) – A slice object, or an integer.
Returns:group – A slice of the FGA as specified by the slice object.
Return type:LCA

Examples

>>> G = LCA([5, 6, 1])
>>> G[0:2] == LCA([5, 6])
True
>>> G[0] == LCA([5])
True
is_FGA()

Whether or not the LCA is a FGA.

A locally compact abelian group (LCA) is a finitely generated abelian group (FGA) iff all the groups in the direct sum are discrete.

Returns:is_FGA – True if the object is an FGA, False if not.
Return type:bool

Examples

>>> G = LCA([5, 1], [True, False])
>>> G.is_FGA()
False
>>> G = LCA([1, 7], [False, True])
>>> G.dual().is_FGA()
True
isomorphic(other)

Whether or not two LCAs are isomorphic.

Two LCAs are isomorphic iff they can be put into the same canonical form.

Parameters:other (LCA) – The LCA to compare with.
Returns:isomorphic – Whether or not the LCAs are isomorphic.
Return type:bool

Examples

>>> G = LCA([3, 4])
>>> H = LCA([12])
>>> G.isomorphic(H)
True
>>> G.equal(H)
False
>>> LCA([2, 6]).isomorphic(LCA([12]))
False
>>> G = LCA([0, 0, 1, 3, 4], [False, True, True, True, True])
>>> H = LCA([0, 0, 3, 4], [True, False, True, True])
>>> G.isomorphic(H)
True
>>> LCA([]).isomorphic(LCA.trivial())
True
iterate()

Yields the groups in the direct sum one by one.

Iterate through the groups and yield the individual groups in the direct sum, one by one.

Yields:group (LCA) – A single group in the direct sum.

Examples

>>> G = LCA([5, 1], [True, False])
>>> groups = [LCA([5], [True]), LCA([1], [False])]
>>> for i, group in enumerate(G):
...     group == groups[i]
True
True
length()

The number of groups in the direct sum.

Returns:length – The number of groups in the direct sum.
Return type:int

Examples

>>> G = LCA([])
>>> G.length()
0
>>> G = LCA([0, 1, 1, 5])
>>> G.length()
4
project_element(element)

Project an element onto the group.

Parameters:element (MutableDenseMatrix or list) – The group element to project to the LCA.
Returns:element – The group element projected to the LCA.
Return type:MutableDenseMatrix or list

Examples

>>> from sympy import Matrix
>>> G = LCA([5, 9])
>>> g = [6, 22]
>>> G.project_element(g)
[1, 4]
>>> g = Matrix([13, 13])
>>> G.project_element(g) == Matrix([3, 4])
True
rank()

Return the rank of the LCA.

Returns:rank – An integer greater than or equal to 0.
Return type:int

Examples

>>> G = LCA([5, 6, 1])
>>> G.rank()
2
>>> LCA([1]).rank()
0
>>> G = LCA([5, 6, 1])
>>> H = LCA([1])
>>> G.rank() + H.rank() == (G + H).rank()
True
remove_indices(indices)

Return a LCA with some groups removed.

Parameters:indices (list) – A list of indices corresponding to LCAs to remove.
Returns:group – The LCA with some groups removed.
Return type:LCA

Examples

>>> G = LCA([5, 8, 9])
>>> G.remove_indices([0, 2]) == LCA([8])
True
remove_trivial()

Remove trivial groups from the object.

Returns:group – The group with trivial groups removed.
Return type:LCA

Examples

>>> G = LCA([5, 1, 1])
>>> G.remove_trivial() == LCA([5])
True
sum(other)

Return the direct sum of two LCAs.

Parameters:other (LCA) – The LCA to take direct sum with.
Returns:group – The direct sum of self and other.
Return type:LCA

Examples

>>> G = LCA([5])
>>> H = LCA([7])
>>> G + H == LCA([5, 7])  # The `+` operator is overloaded
True
>>> G + H == G.sum(H)  # Directs sums two ways
True
to_latex()

Return the LCA as a \(\LaTeX\) string.

Returns:latex_str – A string with LaTeX code for the object.
Return type:str

Examples

>>> G = LCA([5, 0], [True, False])
>>> G.to_latex()
'\\mathbb{Z}_{5} \\oplus \\mathbb{R}'
classmethod trivial()

Return a trivial LCA.

Returns:group – A trivial LCA.
Return type:LCA

Examples

>>> trivial = LCA.trivial()
>>> Z = LCA([0])
>>> (Z + trivial).isomorphic(Z)
True

abelian.morphisms module

This module consists of classes representing homomorphisms between elementary LCAs, the HomLCA class.

class HomLCA(A, target=None, source=None)

Bases: collections.abc.Callable

A homomorphism between elementary LCAs.

__init__(A, target=None, source=None)

Initialize a homomorphism.

Parameters:
  • A (MutableDenseMatrix or list) – A sympy matrix representing the homomorphism. The user may also use a list of lists in the form [row1, row2, …] as input.
  • target (LCA or list) – The target of the homomorphism. If None, a discrete target of infinite order is used as the default.
  • source (LCA or list) – The source of the homomorphism. If None, a discrete source of infinite order is used as the default.

Examples

>>> # If no source/target is given, a free discrete group is assumed
>>> phi = HomLCA([[1,2],
...               [3,4]])
>>> phi.source.is_FGA() and phi.target.is_FGA()
True
>>> # If no source is given, a free discrete group is assumed
>>> phi = HomLCA([[1,2],
...               [3,4]], target = [5, 5])
>>> phi.source.is_FGA()
True
>>> # The homomorphism must be valid
>>> from abelian import LCA, HomLCA
>>> T = LCA(orders = [1], discrete = [False])
>>> R = LCA(orders = [0], discrete = [False])
>>> phi = HomLCA([1], target = R, source = T)
Traceback (most recent call last):
    ...
ValueError: 1: [T] -> [R] is not homomorphism
add(other)

Elementwise addition.

Elementwise addition of the underlying matrix.

Parameters:other (HomLCA or numeric) – A homomorphism to add to the current one, or a number.
Returns:homomorphism – A new homomorphism with the argument added.
Return type:HomLCA
annihilator()

Compute the annihilator monomorphism.

coimage()

Compute the coimage epimorphism.

Returns:homomorphism – The coimage homomorphism.
Return type:HomLCA

Examples

>>> phi = HomLCA([[4, 4],
...               [2, 8]], target = [16, 16])
>>> im = phi.image().remove_trivial_groups()
>>> coim = phi.coimage().remove_trivial_groups()
>>> phi == (im * coim).project_to_target()
True
cokernel()

Compute the cokernel epimorphism.

Returns:homomorphism – The cokernel homomorphism.
Return type:HomLCA

Examples

>>> phi = HomLCA([[1, 0], [0, 1], [1, 1]])
>>> coker = phi.cokernel()
>>> coker.target.isomorphic(LCA([1, 1, 0]))
True
compose(other)

Compose two homomorphisms.

The composition of self and other is first other, then self.

Parameters:other (HomLCA) – The homomorphism to compose with.
Returns:homomorphism – The composition of self and other, i.e. self ( other (x)).
Return type:HomLCA

Examples

>>> phi = HomLCA([[1, 0, 1],
...               [0, 1, 1]])
>>> ker_phi = HomLCA([1, 1, -1])
>>> (phi * ker_phi) == HomLCA([0, 0])
True
>>> phi.compose(ker_phi) == HomLCA([0, 0])
True
compose_self(power)

Repeated composition of an endomorphism.

Parameters:power (int) – The number of times to compose with self.
Returns:homomorphism – The endomorphism composed with itself power times.
Return type:HomLCA

Examples

>>> from sympy import diag
>>> phi = HomLCA(diag(2, 3))
>>> phi**3 == HomLCA(diag(2**3, 3**3))
True
copy()

Return a copy of the homomorphism.

Returns:homomorphism – A copy of the homomorphism.
Return type:HomLCA

Examples

>>> phi = HomLCA([1, 2, 3])
>>> phi.copy() == phi
True
det()

Determinant of the matrix representing the HomLCA.

Returns:determinant – Determinant of the matrix, if possible.
Return type:float

Examples

>>> from abelian import LCA, HomLCA
>>> phi = HomLCA([[2, 0], [0, 3]])
>>> phi.det()
6
>>> R = LCA([0], [False])
>>> phi = HomLCA([[2.5, 0], [0, 2.5]], R**2, R**2)
>>> phi.det() == 6.25
True
>>> HomLCA([[3, 1]]).det()
Traceback (most recent call last):
...
sympy.matrices.common.NonSquareMatrixError
dual()

Compute the dual homomorphism.

TODO: Write detailed description.

Returns:dual – The dual homomorphism.
Return type:HomLCA

Examples

>>> phi = HomLCA([2])
>>> phi_dual = phi.dual()
>>> phi_dual.source == phi_dual.target
True

Computing duals by first calculating orders

>>> # Project, then find dual
>>> phi = HomLCA([2], target = [10])
>>> phi_proj = phi.project_to_source()
>>> phi_project_dual = phi_proj.dual()
>>> phi_project_dual == HomLCA([1], [5], [10])
True
>>> # Do not project
>>> phi_dual = phi.dual()
>>> phi_dual == HomLCA([1/5], LCA([1], [False]), [10])
True
equal(other)

Whether or not two homomorphisms are equal.

Two HomLCAs are equal iff (1) the sources are equal, (2) the targets are equal and (3) the matrices representing the homomorphisms are equal.

Parameters:other (HomLCA) – A HomLCA to compare equality with.
Returns:equal – Whether or not the HomLCAs are equal.
Return type:bool

Examples

>>> phi = HomLCA([1], target=[0], source = [0]) # Explicit
>>> psi = HomLCA([1])   # Shorter, defaults to the above
>>> phi == psi
True
evaluate(source_element)

Apply the homomorphism to an element.

Parameters:source_element

Examples

>>> from sympy import diag
>>> phi = HomLCA(diag(3, 4), target = [5, 6])
>>> phi.evaluate([2, 3])
[1, 0]
>>> phi.evaluate(Matrix([2, 3]))
Matrix([
[1],
[0]])
getitem(args)

Return a slice of the homomorphism.

Slices the object with the common matrix slice notation, e.g. A[rows, cols], where the rows and cols objects can be either integers or slice objects. If the homomorphism is represented by a column or row matrix, then the notation A[key] will also work. The underlying matrix and the source and target LCAs are all sliced.

Parameters:args (slice) – A slice or a tuple with (slice_row, slice_col).
Returns:homomorphism – A sliced homomorphism.
Return type:HomLCA

Examples

The homomorphism is sliced using two input arguments.

>>> from sympy import diag
>>> phi = HomLCA(diag(4,5,6))
>>> phi[0,:] == HomLCA([[4, 0, 0]])
True
>>> phi[:,1] == HomLCA([0, 5, 0])
True

If the homomorphism is represented by a row or column, one arg will do.

>>> phi = HomLCA([1,2,3])
>>> phi[0:2] == HomLCA([1,2])
True
classmethod identity(group)

Return the identity morphism.

Examples

>>> from abelian import LCA, HomLCA
>>> H = LCA([5, 6, 7])
>>> G = LCA([0, 0])
>>> phi = HomLCA([[1,2], [3,4], [5,6]], source = G, target = H)
>>> Id_H = HomLCA.identity(H)
>>> Id_G = HomLCA.identity(G)
>>> # Verify the properties of the identity morphism
>>> Id_H * phi == phi
True
>>> phi * Id_G == phi
True
image()

Compute the image monomorphism.

Returns:homomorphism – The image homomorphism.
Return type:HomLCA

Examples

>>> phi = HomLCA([[4, 4],
...               [2, 8]], target = [64, 32])
>>> im = phi.image().remove_trivial_groups()
>>> coim = phi.coimage().remove_trivial_groups()
>>> phi == (im * coim).project_to_target()
True
>>> # Image computations are also allowed when target is R
>>> R = LCA(orders = [0], discrete = [False])
>>> sample_matrix = [[1, 2, 3], [2, 3, 5]]
>>> phi_sample = HomLCA(sample_matrix, target = R + R)
>>> phi_sample_im = phi_sample.image().remove_trivial_groups()
>>> phi_sample_im == phi_sample[:, 1:]
True
kernel()

Compute the kernel monomorphism.

Returns:homomorphism – The kernel homomorphism.
Return type:HomLCA

Examples

>>> phi = HomLCA([[1, 0, 1], [0, 1, 1]])
>>> phi.kernel() == HomLCA([-1, -1, 1])
True
project_to_source()

Project columns to source group (orders).

Returns:homomorphism – A homomorphism with orders in the source FGA.
Return type:HomLCA

Examples

>>> target = [3, 6]
>>> phi = HomLCA([[1, 0],
...               [3, 3]], target = target)
>>> phi = phi.project_to_source()
>>> phi.source.orders == [6, 2]
True
project_to_target()

Project columns to target group.

Returns:homomorphism – A homomorphism with columns projected to the target FGA.
Return type:HomLCA

Examples

>>> target = [7, 12]
>>> phi = HomLCA([[15, 12],
...               [9,  17]], target = target)
>>> phi_proj = HomLCA([[1, 5],
...                    [9, 5]], target = target)
>>> phi.project_to_target() == phi_proj
True
remove_trivial_groups()

Remove trivial groups.

A group is trivial if it is discrete with order 1, i.e. Z_1. Removing trivial groups from the target group means removing the Z_1 groups from the target, along with the corresponding rows of the matrix representing the homomorphism. Removing trivial groups from the source group means removing the groups Z_1 from the source, i.e. removing every column (generator) with order 1.

Returns:homomorphism – A homomorphism where the trivial groups have been removed from the source and the target. The corresponding rows and columns of the matrix representing the homomorphism are also removed.
Return type:HomLCA

Examples

>>> target = [1, 7]
>>> phi = HomLCA([[2, 1], [7, 2]], target=target)
>>> projected = HomLCA([[2]], target=[7], source = [7])
>>> phi.project_to_source().remove_trivial_groups() == projected
True
shape

The shape (rows, cols).

Returns:shape – A tuple with the shape of the underlying matrix A, i.e. (rows, cols).
Return type:tuple
stack_diag(other)

Stack diagonally.

Parameters:other (HomLCA) – A homomorphism to stack with the current one.
Returns:stacked_vert – The result of stacking the homomorphisms on diagonally.
Return type:HomLCA

Examples

>>> phi = HomLCA([1])
>>> psi = HomLCA([2])
>>> phi.stack_diag(psi) == HomLCA([[1, 0], [0, 2]])
True
stack_horiz(other)

Stack horizontally (column wise).

The targets must be the same, the sources will be concatenated. The stacking is done to create a matrix with structure [self, other], i.e. “Putting self to the left of other.”

Parameters:other (HomLCA) – A homomorphism to stack with the current one.
Returns:stacked_vert – The result of stacking the homomorphisms side by side.
Return type:HomLCA

Examples

>>> phi = HomLCA([1])
>>> psi = HomLCA([2])
>>> phi.stack_horiz(psi) == HomLCA([[1, 2]])
True
stack_vert(other)

Stack vertically (row wise).

The sources must be the same, the targets will be concatenated. The stacking is done to create a matrix with structure [[self], [other]], i.e. “Putting self on top of of other.”

Parameters:other (HomLCA) – A homomorphism to stack with the current one.
Returns:stacked_vert – The result of stacking the homomorphisms on top of each other.
Return type:HomLCA

Examples

>>> phi = HomLCA([1])
>>> psi = HomLCA([2])
>>> phi.stack_vert(psi) == HomLCA([1, 2])
True
to_latex()

Return the homomorphism as a \(\LaTeX\) string.

Returns:latex – The HomLCA formatted as a LaTeX string.
Return type:str

Examples

>>> phi = HomLCA([1])
>>> phi.to_latex()
'\\begin{pmatrix}1\\end{pmatrix}:\\mathbb{Z} \\to \\mathbb{Z}'
update(new_A=None, new_target=None, new_source=None)

Return a new homomorphism with updated properties.

classmethod zero(target, source)

Initialize the zero morphism.

Parameters:
  • target (LCA or list) – The target of the homomorphism. If None, a discrete target of infinite order is used as the default.
  • source (LCA or list) – The source of the homomorphism. If None, a discrete source of infinite order is used as the default.

Examples

>>> zero = HomLCA.zero([0]*3, [0]*3)
>>> zero([1, 5, 7]) == [0, 0, 0]
True

abelian.utils module

arg(min_or_max, iterable, function_of_element)

Call a nested list like a function.

Parameters:
  • list_of_lists (list) – A nested list of lists.
  • arg (list) – The argument [dim1, dim2, …].
Returns:

value – The object in the list of lists.

Return type:

object

Examples

>>> iterable = [-8, -4, -2, 3, 5]
>>> arg(min, iterable, abs)
-2
>>> iterable = range(-10, 10)
>>> arg(max, iterable, lambda x: -(x - 3)**2)
3
call_nested_list(list_of_lists, arg)

Call a nested list like a function.

Parameters:
  • list_of_lists (list) – A nested list of lists.
  • arg (list) – The argument [dim1, dim2, …].
Returns:

value – The object in the list of lists.

Return type:

object

Examples

>>> table = [1 ,2 ,3]
>>> call_nested_list(table, [0])
1
>>> table = [[1, 2], [1, 2], [1, 2]]
>>> call_nested_list(table, [0, 0])
1
>>> table = [[[1, 2, 3, 4], [1, 2, 3, 4]],
...          [[1, 2, 3, 4], [1, 2, 3, 4]],
...          [[1, 2, 3, 4], [1, 2, 3, 4]]]
>>> call_nested_list(table, [0, 0])
[1, 2, 3, 4]
>>> call_nested_list(table, [0, 0, 0])
1
copy_func(f)

Based on http://stackoverflow.com/a/6528148/190597 (Glenn Maynard)

function_to_table(function, dims, *args, **kwargs)
Parameters:
  • function (function) – A function with signature (list_arg, *args, **kwargs).
  • dims (list) – A list of dimensions such as [8, 6, 3].
mod(a, b)

Returns a % b, with a % 0 = a.

Parameters:
  • a (int) – The first argument in a % b.
  • b (int) – The second argument in a % b.
Returns:

a modulus b.

Return type:

int

Examples

>>> mod(5, 2)
1
>>> mod(5, 0)
5
verify_dims_list(list_of_lists, dims)

Verify the dimensions of a list of lists.

Parameters:
  • list_of_lists (list) – A nested list of lists.
  • dims (list) – A list of dimensions.
Returns:

verified – Whether or not the dimensions match the dims parameter.

Return type:

bool

Examples

>>> table = [1 ,2 ,3]
>>> dims = [3]
>>> verify_dims_list(table, dims)
True
>>> table = [[1, 2], [1, 2], [1, 2]]
>>> dims = [3, 2]
>>> verify_dims_list(table, dims)
True
>>> table = [[[1, 2, 3, 4], [1, 2, 3, 4]],
...          [[1, 2, 3, 4], [1, 2, 4]],
...          [[1, 2, 3, 4], [1, 2, 3, 4]]]
>>> dims = [3, 2, 4] # Not correct, notice the missing value above
>>> verify_dims_list(table, dims)
False

Module contents