Source code for permaviss.spectral_sequence.local_chains_class

"""
This module takes care of chains stored on first page of the spectral sequence.

The format will be, for a certain position (n_deg, deg):
References on each open cover of intersection degree `n_deg`
Local chain coordinates as rows for each reference.
"""

import numpy as np


[docs]class local_chains(object): """Chains in local forms, references and local coordinates. Attributes ---------- p : int or None Prime number to be used for computations. """ p = None def __init__(self, *args): """Initialize local_chains. Parameters ---------- *args : int or two `:obj:list` If one parameter is given, it has to be an `int` indicating the number of local entries to save. If two parameters are given, these have to be two `:obj:list`. The first stores references while the second, `:obj:Numpy Array` with local coordinates. Attributes ---------- ref : `:obj:list` List of lists containing local references. coord : `:obj:list` List of `:obj:Numpy Array` indicating local coordinates. The rows correspond to the number of indices in references. This is what we mean by `local_chains` standard format. Raises ------ ValueError Whenever more than two arguments are given in *args. If `len(args[0])` does not match `len(args[1])` If the number of elements on the `k` entry in `args[0]` does not match the number of rows on the `k` entry in `args[0]`. """ if len(args) == 2: if len(args[0]) != len(args[1]): raise ValueError self.ref, self.coord = [], [] for idx, ref in enumerate(args[0]): if len(ref) != np.size(args[1][idx], 0): raise ValueError self.ref.append(np.copy(ref)) self.coord.append(np.copy(args[1][idx])) elif isinstance(args[0], int): # initialize empty references and coordinates self.ref, self.coord = [], [] for i in range(args[0]): self.ref.append([]) self.coord.append([]) else: raise ValueError ########################################################################### # add_entry
[docs] def add_entry(self, index, ref, coord): """ Add a references and coordinates at some index. Checks that the input is correct. Parameters ---------- index : int Position in local_chains object. ref : :obj:`list` Reference list for current index. coord : :obj:`Numpy Array` or :obj:`list` Local coordinates where expressions are indexed by rows. If it is a list it is the empty list []. Raises ------ ValueError If the given pair of ref and coord do not respect the format rules. """ # include trivial case of adding [] and [] at index if isinstance(coord, list): if len(coord) == len(ref) == 0: return else: print(coord) print(ref) raise ValueError # check that number of expressions match references elif len(ref) == np.size(coord, 0): self.ref[index] = ref self.coord[index] = coord else: raise ValueError
########################################################################### # __add__
[docs] def __add__(self, B): """Given two local chains, adds then and returns the result. Assumes that references are the same Parameters ---------- B : `:class:local_chains` object """ new_ref, new_chains = [], [] A = self for idx, A_ref in enumerate(A.ref): A_coord, B_ref, B_coord = A.coord[idx], B.ref[idx], B.coord[idx] C_ref = np.unique(np.append(A_ref, B_ref)) new_ref.append(C_ref.astype(int)) if min(len(A_ref), len(B_ref)) > 0: C_coord = np.zeros((len(C_ref), np.size(A_coord, 1))) C_coord[np.isin(C_ref, A_ref)] += A_coord C_coord[np.isin(C_ref, B_ref)] += B_coord elif len(A_ref) > 0: C_coord = A_coord elif len(B_coord) > 0: C_coord = B_coord else: C_coord = [] new_chains.append(C_coord) # end if # end for return local_chains(new_ref, new_chains)
########################################################################### # minus
[docs] def minus(self): """ Minus all local coordinates of self. """ for idx, coordinates in enumerate(self.coord): if len(coordinates) > 0: self.coord[idx] = -coordinates % self.p
########################################################################### # local_sums
[docs] def sums(chains, coord_sums): """Sum chains as indicated by "coord_sums" Parameters ---------- chains : :class:`local_chains` object Chains in local_chains format to be added. coord_sums : :obj:`Numpy Array` Each sum is given by rows in coord_sums. These store the coefficients that the chain entries need to be added. """ no_sums = np.size(coord_sums, axis=0) new_ref = [] new_coord = [] for local_idx, ref in enumerate(chains.ref): if len(ref) > 0: new_ref.append(np.array(range(no_sums)).astype(int)) new_coord.append(np.matmul( chains.coord[local_idx].T, (coord_sums.T)[ref]).T) else: new_ref.append([]) new_coord.append([]) # end for return local_chains(new_ref, new_coord)
########################################################################### # copy_seq_local
[docs] def copy_seq(seq_chains): """ Given a sequence of local chains, makes a copy and returns it. """ copy_seq = [] for chains in seq_chains: copy_seq.append(local_chains(chains.ref, chains.coord)) return copy_seq
# end local_chains class