Module ateams.complexes

Classes

class Cubical
Expand source code
class Cubical:
        def __init__(self): pass

        def fromCorners(self, corners, periodic=True):
                """
                Creates a cell complex with the given corners made of cells of the
                provided dimension.

                Args:
                        corners (list): Corners of the complex; determines the maximal
                                cell dimension.
                        periodic (bool): Do we use periodic boundary
                                conditions (i.e. are we making a torus)?
                """
                self._construct(corners, periodic)
                return self
        

        @staticmethod
        def _fullBoundaryMatrix(flattened, coefficients):
                return np.array(fullBoundaryMatrix(flattened, coefficients))
        

        def _construct(
                        self, corners, periodic, data=None
                ):
                self.dimension = len(corners)
                self.periodic = periodic
                self.corners = corners
                self.matrices = Matrices()

                # Specify sparse "boundary matrices," which we'll convert to *actual*
                # matrices for the purposes of our stuff.
                if not data:
                        vertexMap, Complex, flatBoundary, flatCoboundary = cubicalComplex(self.corners, self.dimension, self.periodic)
                        self.vertexMap, self.Boundary = vertexMap, Complex
                else:
                        self.vertexMap = data.get("vertexMap", None)
                        self.Boundary = {
                                int(t): data["Complex"][t].astype(int) for t in data["Complex"].files
                        }
                        data["Complex"].close()
                        flatBoundary, flatCoboundary = boundaryMatrix(self.Boundary, self.dimension)
                
                # Construct the finite field and boundary matrices.
                self.reindexer, self.reindexed, self.flattened = flatten(self.Boundary, self.dimension)
                self.matrices.boundary = flatBoundary
                self.matrices.coboundary = flatCoboundary

                self.orientations = coefficients = { d: np.tile([-1,1], d*2).astype(MINT) for d in range(1, self.dimension+1) }
                self.matrices.full = np.array(fullBoundaryMatrix(self.flattened, coefficients), dtype=MINT)

                # Get index ranges. (This may turn out to be vestigial; who knows?)
                self.tranches = np.zeros((self.dimension+1, 2), dtype=int)
                self.tranches[0][1] = len(self.Boundary[0])

                for d in range(1, self.dimension+1):
                        self.tranches[d] = [self.tranches[d-1][1], self.tranches[d-1][1] + len(self.Boundary[d])]

                # Breaks. (For percolation computation.)
                self.breaks = np.array(self.tranches[:,0])

                return self
        

        def recomputeBoundaryMatrices(self, dimension):
                """
                Recomputes the boundary matrices up to the provided dimension.

                Args:
                        dimension (int): New dimention.

                Returns:
                        A triple of matrices --- the new flat boundary/coboundary, and the
                        new full boundary.
                """
                boundary, coboundary = boundaryMatrix(self.Boundary, dimension)
                
                return boundary, coboundary


        
        def toFile(self, fp, vertexMap=False):
                """
                JSON-serializes this object and writes it to file so we can reconstruct
                it later.

                Args:
                        fp (str): Filepath.
                        vertexMap (bool): Do we save the vertex map? Not doing so saves
                                a lot of space.
                """
                # Write compressed boundary matrix and vertex maps to file.
                absolute = Path(fp).resolve()
                root = absolute.parent
                stem = absolute.stem
                ComplexFile = root/f".{stem}.complex.npz"
                np.savez(ComplexFile, **{str(t): v for t, v in self.Boundary.items()})

                with open(fp, "w") as write:
                        json.dump(
                                {
                                        "dimension": self.dimension,
                                        "periodic": int(self.periodic),
                                        "corners": self.corners,
                                        "Complex": str(ComplexFile),
                                        "vertexMap": { str(k): int(v) for k, v in self.vertexMap.items() } if vertexMap else { }
                                }, write
                        )

        
        def fromFile(self, fp:str, vertexMap=False, field=None):
                """
                Reconstructs a serialized Complex.

                Args:
                        fp (str): Filepath.
                        vertexMap (bool): Is there a vertexmap to load?
                        field (int): Reconstructs this lattice with a different field;
                                good for portability.
                """
                with open(fp, "r") as read:
                        # Read file into memory.
                        serialized = json.load(read)

                        # Set field and dimension.
                        periodic = bool(serialized["periodic"])
                        corners = serialized["corners"]
                        data = { "Complex": np.load(serialized["Complex"], allow_pickle=True) }
                        if vertexMap: data["vertexMap"] = { le(k): int(v) for k, v in serialized["vertexMap"].items() }

                        # Construct indices, boundary matrix, and graph.
                        return self._construct(
                                corners, periodic, data
                        )

Methods

def fromCorners(self, corners, periodic=True)

Creates a cell complex with the given corners made of cells of the provided dimension.

Args

corners : list
Corners of the complex; determines the maximal cell dimension.
periodic : bool
Do we use periodic boundary conditions (i.e. are we making a torus)?
def fromFile(self, fp: str, vertexMap=False, field=None)

Reconstructs a serialized Complex.

Args

fp : str
Filepath.
vertexMap : bool
Is there a vertexmap to load?
field : int
Reconstructs this lattice with a different field; good for portability.
def recomputeBoundaryMatrices(self, dimension)

Recomputes the boundary matrices up to the provided dimension.

Args

dimension : int
New dimention.

Returns

A triple of matrices — the new flat boundary/coboundary, and the new full boundary.

def toFile(self, fp, vertexMap=False)

JSON-serializes this object and writes it to file so we can reconstruct it later.

Args

fp : str
Filepath.
vertexMap : bool
Do we save the vertex map? Not doing so saves a lot of space.