Make sure computing half is an integer, and caching method
In some cases taking half of an integer results in a fractional type (even if it represents an integer number). This causes problems with indices, so this change uses division with quotient and remainder instead. Also, it caches the degeneration morphism, which is expensive to create.
This commit is contained in:
parent
2c2d2aeac0
commit
71cb7aef68
319
aplK.py
319
aplK.py
@ -8,7 +8,7 @@ import copy
|
||||
class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
||||
"""
|
||||
A differential multi-graded commutative algebra
|
||||
|
||||
|
||||
This class extends the DifferentialGCAlgebra_multigraded class
|
||||
to create the algebra of polynomial differential forms with coefficients in QQ
|
||||
|
||||
@ -29,7 +29,7 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
||||
- ``differential`` -- a differential
|
||||
"""
|
||||
|
||||
self.n = len(A._names)//2-1
|
||||
self.n = len(A._names) // 2 - 1
|
||||
DifferentialGCAlgebra_multigraded.__init__(self, A, differential)
|
||||
self.t_relation = sum(self.gens()[:self.n+1])-1
|
||||
self.y_relation = sum(self.gens()[self.n+1:])
|
||||
@ -44,7 +44,7 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
||||
new = '{}'.format([i[0] for i in self._degrees_multi])
|
||||
return s.replace(old, new)
|
||||
|
||||
def integrand(self, value):
|
||||
def integrand(self, value):
|
||||
"""
|
||||
Returns a polynomial whose definite integral is equal to 'value'
|
||||
|
||||
@ -55,28 +55,28 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
||||
return value*factorial(self.n)*prod(self.gens()[self.n+2:])
|
||||
else:
|
||||
raise ValueError("only field elements can be integrated.")
|
||||
|
||||
|
||||
class Element(GCAlgebra_multigraded.Element, DifferentialGCAlgebra.Element):
|
||||
"""
|
||||
Element class of the commutative differential multi-graded algebra (Apl)n.
|
||||
"""
|
||||
|
||||
|
||||
def is_homogeneous(self):
|
||||
"""
|
||||
Return "True" if "self" is homogeneous and "False" otherwise.
|
||||
"""
|
||||
|
||||
|
||||
degrees = set([k[0] for k in self.homogeneous_parts()])
|
||||
return len(degrees) == 1
|
||||
|
||||
|
||||
def total_degree(self):
|
||||
"""
|
||||
Return the total degree of this element.
|
||||
"""
|
||||
|
||||
"""
|
||||
|
||||
degrees = set([k[0] for k in self.homogeneous_parts()])
|
||||
return max(degrees)
|
||||
|
||||
|
||||
def homogeneous_part(self,degree):
|
||||
"""
|
||||
Returns the homogeneous part of the element for a given degree.
|
||||
@ -86,54 +86,54 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
||||
raise ValueError('`degree` must be a non-negative integer')
|
||||
parts = [self.homogeneous_parts()[k] for k in self.homogeneous_parts() if list(k)[0]==degree]
|
||||
return self.parent()(sum(parts))
|
||||
|
||||
|
||||
def reduce(self, relations=[]):
|
||||
""""
|
||||
""""
|
||||
The method reduces the polynomial by the Ideal <sum(t_i)-1, sum(y_j)>
|
||||
|
||||
|
||||
INPUT::
|
||||
- p: polynomial in variables t_0,..t_n,y_0,...,y_n
|
||||
- relations (optional): if relations are given, the polynomial is reduced following
|
||||
this rules. If no relations are given, the polynomial is reduced taking into
|
||||
account the relations of the parent algebra.
|
||||
|
||||
|
||||
OUTPUT::
|
||||
- The polynomial after applying the corresponding relations
|
||||
- The polynomial after applying the corresponding relations
|
||||
"""
|
||||
apl = self.parent()
|
||||
if relations:
|
||||
return DifferentialGCAlgebra.Element.reduce(self, relations)
|
||||
else:
|
||||
return DifferentialGCAlgebra.Element.reduce(self, [apl.t_relation, apl.y_relation])
|
||||
|
||||
|
||||
def _integrable_part(self):
|
||||
|
||||
|
||||
"""
|
||||
The method returns the coefficient in Q[t_1,...,t_n] of the term
|
||||
of degree `n`
|
||||
|
||||
OUTPUT:
|
||||
- A polynomial in the ring Q<t_1,..t_n>.
|
||||
(After reducing the variables t_{0},y_{0} by the corresponding relations,
|
||||
the algorithm removes the variables y_{1},..,y_{n}).
|
||||
(After reducing the variables t_{0},y_{0} by the corresponding relations,
|
||||
the algorithm removes the variables y_{1},..,y_{n}).
|
||||
"""
|
||||
|
||||
|
||||
apl = self.parent()
|
||||
pol = apl(self.reduce()) #needed in case reduce() returns an integer
|
||||
relations = []
|
||||
for i in range(apl.n+1):
|
||||
for i in range(apl.n+1):
|
||||
relations.append(apl.gens()[apl.n+1+i]-1)
|
||||
pol = apl(pol.homogeneous_part(degree=apl.n))
|
||||
pol = apl(pol.homogeneous_part(degree=apl.n))
|
||||
return apl(pol.reduce(relations=relations))
|
||||
|
||||
def integral(self):
|
||||
"""
|
||||
Returns the definite integral of the term of degree `n`
|
||||
|
||||
|
||||
OUTPUT:
|
||||
- The rational number obtained by the definite integral
|
||||
- The rational number obtained by the definite integral
|
||||
of the term of degree `n`
|
||||
|
||||
|
||||
"""
|
||||
|
||||
apl = self.parent()
|
||||
@ -147,32 +147,32 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
||||
denominator += e
|
||||
coef = pol.dict()[k]
|
||||
result += coef*numerator/factorial(denominator)
|
||||
#return ((-1)**(apl.n*(apl.n-1)/2))*result
|
||||
#return ((-1) ** ((apl.n*(apl.n-1)) // 2)) * result
|
||||
return result
|
||||
|
||||
|
||||
def _get_term(self, coef, exp, gens):
|
||||
""""
|
||||
|
||||
""""
|
||||
|
||||
Returns the term specified by its coefficient, exponents and generators
|
||||
|
||||
|
||||
INPUT::
|
||||
- coef: The coefficient of the term
|
||||
- exp: A tuple with the exponents of each variable
|
||||
- gens: The generators
|
||||
|
||||
|
||||
OUTPUT::
|
||||
- A polynomial
|
||||
"""
|
||||
return coef*prod(list(map(lambda exp, gen: gen**exp, exp, gens)))
|
||||
|
||||
def _get_terms(self):
|
||||
""""
|
||||
|
||||
""""
|
||||
|
||||
Returns self seen as a collection of terms in the variables y_j with coefficients in QQ<t_1,..,t_n>
|
||||
|
||||
|
||||
OUTPUT::
|
||||
- A dictionary with all terms
|
||||
|
||||
|
||||
"""
|
||||
a = self.parent()
|
||||
n = len(a.gens())//2
|
||||
@ -186,14 +186,14 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
||||
if key not in terms.keys():
|
||||
terms[key] = coef
|
||||
else:
|
||||
terms[key] += coef
|
||||
terms[key] += coef
|
||||
return terms
|
||||
|
||||
def _get_leading_pol(self):
|
||||
""""
|
||||
|
||||
""""
|
||||
|
||||
Returns the leading polynomial
|
||||
|
||||
|
||||
OUTPUT::
|
||||
- A polynomial
|
||||
"""
|
||||
@ -203,13 +203,13 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
||||
return terms[keys[0]]*keys[0]
|
||||
|
||||
def _get_idx(self, exp):
|
||||
""""
|
||||
|
||||
""""
|
||||
|
||||
Returns the idx 'i' of the first generator 'y_i' that appears in exp
|
||||
|
||||
|
||||
INPUT::
|
||||
- exp: A tuple with the exponents
|
||||
|
||||
|
||||
OUTPUT::
|
||||
- A non-negative number lower or equal to 'n'
|
||||
"""
|
||||
@ -219,14 +219,14 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
||||
return next((i for i, x in enumerate(list(diff_forms)) if x), None)-n
|
||||
|
||||
def _monomial_primitive(self, monomial, idx):
|
||||
""""
|
||||
|
||||
""""
|
||||
|
||||
Returns the primitive of the given monomial
|
||||
|
||||
|
||||
INPUT::
|
||||
- monomial: A monomial
|
||||
- idx: the index of the variable y_j that will be used to calculate the pseudo-primitive
|
||||
|
||||
|
||||
OUTPUT::
|
||||
- A polynomial
|
||||
"""
|
||||
@ -243,9 +243,9 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
||||
return self._get_term(new_coef, primitive, a.gens())
|
||||
|
||||
def _leading_primitive(self):
|
||||
""""
|
||||
""""
|
||||
Returns the primitive of the leading term of self
|
||||
|
||||
|
||||
OUTPUT::
|
||||
- A polynomial
|
||||
"""
|
||||
@ -264,9 +264,9 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
||||
return result
|
||||
|
||||
def primitive(self):
|
||||
""""
|
||||
""""
|
||||
Retuns a polynomial whose differential is self
|
||||
|
||||
|
||||
OUTPUT::
|
||||
- A polynomial
|
||||
"""
|
||||
@ -277,8 +277,8 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
||||
if (theta == 0):
|
||||
return w
|
||||
else:
|
||||
return w+theta.primitive()
|
||||
|
||||
return w+theta.primitive()
|
||||
|
||||
def AlgebraPL(n):
|
||||
"""
|
||||
The graded commutative differential cochain algebra Apl of dimension ``n``
|
||||
@ -308,9 +308,9 @@ def AlgebraPL(n):
|
||||
|
||||
class SimplicialAplN(AplN, UniqueRepresentation):
|
||||
"""
|
||||
|
||||
|
||||
The simplicial commutative cochain algebra Apl
|
||||
|
||||
|
||||
"""
|
||||
|
||||
def _base_repr(self):
|
||||
@ -327,18 +327,18 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
||||
"""
|
||||
Element class of the simplicial commutative differential algebra (Apl)n.
|
||||
"""
|
||||
|
||||
|
||||
def face_morphism(self,i):
|
||||
""""
|
||||
|
||||
""""
|
||||
|
||||
Returns the morphism face 'i' of self
|
||||
|
||||
|
||||
INPUT::
|
||||
|
||||
|
||||
- i: A non-negative integer lower or equal to 'n'. Represents the face index
|
||||
|
||||
|
||||
OUTPUT::
|
||||
|
||||
|
||||
- A morphism of cochain algebras
|
||||
"""
|
||||
n = self.parent().n
|
||||
@ -361,35 +361,36 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
||||
yImages.append(codomain.gens()[n+k-2])
|
||||
images = tImages+yImages
|
||||
return domain.hom(codomain=codomain,im_gens=images)
|
||||
|
||||
|
||||
def face(self,i):
|
||||
""""
|
||||
|
||||
""""
|
||||
|
||||
Returns the face 'i' of self
|
||||
|
||||
|
||||
INPUT::
|
||||
|
||||
|
||||
- i: A non-negative integer lower or equal to 'n'. Represents the face index
|
||||
|
||||
|
||||
OUTPUT::
|
||||
|
||||
|
||||
- A polynomial that is the face 'i' of self
|
||||
"""
|
||||
|
||||
|
||||
return self.face_morphism(i)(self)
|
||||
|
||||
|
||||
@cached_method
|
||||
def degeneration_morphism(self,j):
|
||||
""""
|
||||
|
||||
""""
|
||||
|
||||
Returns the morphism degeneration 'j' of self
|
||||
|
||||
|
||||
INPUT::
|
||||
- j: A non-negative integer lower or equal to 'n'. Represents the degeneration index
|
||||
|
||||
|
||||
OUTPUT::
|
||||
- A morphism of cochain algebras
|
||||
"""
|
||||
|
||||
|
||||
n = self.parent().n
|
||||
domain = self.parent()
|
||||
codomain = SimplicialAlgebraplN(n+1)
|
||||
@ -415,23 +416,23 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
||||
yImages.append(codomain.gens()[n+1+k+1])
|
||||
images = tImages+yImages
|
||||
return domain.hom(codomain=codomain,im_gens=images)
|
||||
|
||||
|
||||
def degeneration(self,j):
|
||||
""""
|
||||
|
||||
""""
|
||||
|
||||
Returns the degeneration 'j' of self
|
||||
|
||||
|
||||
INPUT::
|
||||
- j: A non-negative integer lower or equal to 'n'. Represents the degeneration index
|
||||
|
||||
|
||||
OUTPUT::
|
||||
- A polynomial that is the degeneration 'j' of self
|
||||
"""
|
||||
return self.degeneration_morphism(j)(self)
|
||||
|
||||
|
||||
def propagate(self, face_list, dest_dim):
|
||||
"""
|
||||
Returns a polynomial in dimension 'dest_dim' that has 'self' as a face
|
||||
Returns a polynomial in dimension 'dest_dim' that has 'self' as a face
|
||||
|
||||
INPUT:
|
||||
- face_list: indexes of the elements that form the face of the simplex we want to propagate
|
||||
@ -441,7 +442,7 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
||||
p = (t1^2+t2^2)*y1*y2
|
||||
p.propagate2([0,1,2],3)
|
||||
t1^2*t2*y0*y1 + t2^3*y0*y1 - t1^3*y0*y2 - t1*t2^2*y0*y2 + t0*t1^2*y1*y2 + t0*t2^2*y1*y2
|
||||
|
||||
|
||||
"""
|
||||
if not (self.is_homogeneous() and self.total_degree()==self.parent().n):
|
||||
raise ValueError("The polynomial is not homogeneous of maximum degree.")
|
||||
@ -464,15 +465,15 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
||||
ts_exp = exp[:self_dim+1]
|
||||
coeff_in_t += coef*prod(list(map(lambda t, e: t**e, t_gens, ts_exp)))
|
||||
return coeff_in_t*graded_part
|
||||
|
||||
def _get_primitive_basis_of_a_monomial(self, monomial):
|
||||
|
||||
def _get_primitive_basis_of_a_monomial(self, monomial):
|
||||
"""
|
||||
Returns a basis of the primitive of a given monomial
|
||||
|
||||
Example:
|
||||
Example:
|
||||
|
||||
"""
|
||||
n_vars = len(monomial)/2
|
||||
n_vars = len(monomial) // 2
|
||||
combinations = []
|
||||
for i in range(n_vars):
|
||||
mono = list(copy.deepcopy(monomial))
|
||||
@ -482,15 +483,15 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
||||
combinations.append(tuple(mono))
|
||||
return list(set(combinations))
|
||||
|
||||
def _add_kernel_terms_to_primitive_basis(self, basis):
|
||||
def _add_kernel_terms_to_primitive_basis(self, basis):
|
||||
new_elements = []
|
||||
for e in basis:
|
||||
monomial = list(copy.deepcopy(e))
|
||||
n = len(e)/2
|
||||
n = len(e) // 2
|
||||
monomial[:n] = n*[0]
|
||||
new_elements.append(tuple(monomial))
|
||||
return new_elements
|
||||
|
||||
|
||||
def _get_primitive_basis(self):
|
||||
"""
|
||||
Returns a basis of the primitive of 'self'
|
||||
@ -505,7 +506,7 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
||||
terms = []
|
||||
apl = self.parent()
|
||||
for b in basis:
|
||||
dim = len(monomial)/2-1
|
||||
dim = len(monomial)//2 - 1
|
||||
terms.append(self._get_term(1, b, apl.gens()))
|
||||
terms.sort(reverse=False)
|
||||
return terms
|
||||
@ -528,7 +529,7 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
||||
|
||||
def _get_coordinate_vector_differential(self, diff_basis):
|
||||
"""
|
||||
Returns the coordinates of 'self'
|
||||
Returns the coordinates of 'self'
|
||||
in terms of the differential basis
|
||||
"""
|
||||
p_reduced = self.reduce()
|
||||
@ -561,7 +562,7 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
||||
diff_basis_element = differential_basis[i]
|
||||
term = list(diff_basis_element.dict().keys())[0] # there is only one monomial
|
||||
if term in monomials:
|
||||
M[i,j] = diff_primitive.dict()[term]
|
||||
M[i,j] = diff_primitive.dict()[term]
|
||||
return M
|
||||
|
||||
def solve_primitive(self):
|
||||
@ -572,7 +573,7 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
||||
Mdif = p._differential_matrix(primitive_basis, diff_basis)
|
||||
sol = Mdif.solve_right(v)
|
||||
return sum(map(lambda x,y: x*y, sol, primitive_basis))
|
||||
|
||||
|
||||
def SimplicialAlgebraplN(n):
|
||||
"""
|
||||
Returns the graded commutative differential cochain algebra (Apl)_n as part of
|
||||
@ -590,9 +591,9 @@ def SimplicialAlgebraplN(n):
|
||||
degrees = tuple((n+1)*[(0,2)])+tuple((n+1)*[(1,2)])
|
||||
gca = GradedCommutativeAlgebra(QQ, names=ts+ys, degrees=degrees)
|
||||
differentials = {gca.gens_dict()[ts[i]]:gca.gens_dict()[ys[i]] for i in range(n+1)}
|
||||
return SimplicialAplN(gca,differentials)
|
||||
|
||||
|
||||
return SimplicialAplN(gca,differentials)
|
||||
|
||||
|
||||
#############################################
|
||||
# TEST
|
||||
#print("TEST SimplicialAlgebraN")
|
||||
@ -617,11 +618,11 @@ def SimplicialAlgebraplN(n):
|
||||
|
||||
class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
"""
|
||||
|
||||
|
||||
The graded commutative differential cochain algebra Apl(K)
|
||||
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self,simplicial_complex, category=None):
|
||||
"""
|
||||
The constructor of Apl(K)
|
||||
@ -635,43 +636,43 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
Parent.__init__(self,category=category)
|
||||
f = MorphismFromQQToAplK(self)
|
||||
self.register_coercion(f)
|
||||
|
||||
|
||||
def _repr_(self):
|
||||
"""
|
||||
Return the base string representation of ``self``.
|
||||
"""
|
||||
return "The graded commutative differential cochain algebra Apl(K) of %s" % self.K
|
||||
|
||||
|
||||
def _element_constructor_(self,values):
|
||||
"""
|
||||
The constructor of an element of this class
|
||||
"""
|
||||
return self.element_class(self,values)
|
||||
|
||||
|
||||
def dimension(self):
|
||||
"""
|
||||
The dimension of the algebra. It is equivalent to the maximum degree possible that a non-null element of this algebra can take.
|
||||
"""
|
||||
return self.n
|
||||
|
||||
|
||||
def simplicialComplex(self):
|
||||
"""
|
||||
The simplicial complex of this algebra.
|
||||
"""
|
||||
return self.K
|
||||
|
||||
|
||||
def _n_cells_sorted(self,n):
|
||||
"""
|
||||
Returns all simplices of dimension 'n', as a sorted list.
|
||||
"""
|
||||
return self.K._n_cells_sorted(n)
|
||||
|
||||
|
||||
def _faces_of_length(self, simplex, length):
|
||||
"""
|
||||
Returns all faces of dimension 'length' for a given simplex
|
||||
"""
|
||||
return [tuple(e) for e in Set(simplex).subsets(length)]
|
||||
|
||||
|
||||
def null_element(self):
|
||||
"""
|
||||
Returns the null element of the algebra respect to the addition operation
|
||||
@ -696,19 +697,19 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
max_dim = dim
|
||||
apl = SimplicialAlgebraplN(dim)
|
||||
if dim>0:
|
||||
values[k] = ((-1)**(dim*(dim-1)/2))*apl.integrand(cochain[k])
|
||||
values[k] = ((-1) ** ((dim * (dim-1)) // 2)) * apl.integrand(cochain[k])
|
||||
else:
|
||||
values[k]= apl(cochain[k])
|
||||
|
||||
|
||||
# second, we propagate the simplicial information
|
||||
simplicial_structure = {}
|
||||
for n in reversed(range(max_dim+1)):
|
||||
keys = [k for k in values.keys() if len(k) == n+1] # keys of the n-simplices
|
||||
for k in keys:
|
||||
simplicial_structure[k] = values[k] + self._propagate(cochain, k)
|
||||
simplicial_structure[k] = values[k] + self._propagate(cochain, k)
|
||||
#print(simplicial_structure)
|
||||
return AlgebraAplK.Element(self,simplicial_structure)
|
||||
|
||||
|
||||
def _propagate(self, cochain, simplex):
|
||||
"""
|
||||
Returns the part of the polynomial assigned to 'simplex' related to the
|
||||
@ -726,9 +727,9 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
value = cochain[f]
|
||||
face_indexes = [simplex.index(i) for i in f]
|
||||
#print("dim: ",n," pol: ",pol," face_idx: ",face_indexes," dim: ", n)
|
||||
propagation += value*((-1)**(n*(n-1)/2))*factorial(n)*pol.propagate(face_indexes, dim)
|
||||
propagation += value*((-1) ** ((n * (n-1)) // 2)) * factorial(n) * pol.propagate(face_indexes, dim)
|
||||
return propagation
|
||||
|
||||
|
||||
def cohomology_gens(self,degree):
|
||||
"""
|
||||
Returns the cohomolosy generators of a given degree
|
||||
@ -739,7 +740,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
if k[0] == degree:
|
||||
gens[k] = basis[k]
|
||||
return gens
|
||||
|
||||
|
||||
def cohomology_group(self, n):
|
||||
chainComplex = self.K.chain_complex(base_ring=QQ)
|
||||
cochainComplex = chainComplex.dual()
|
||||
@ -774,12 +775,12 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
cochain[tuple(simplex)] = v[i]
|
||||
i = i+1
|
||||
return cochain
|
||||
|
||||
|
||||
def lift_cochain_complex(self, cochain, dim):
|
||||
"""
|
||||
(REVISAR)
|
||||
Returns an element of the preimage by the differential of a given cochain
|
||||
|
||||
|
||||
INPUT:
|
||||
- cochain: a cochain as a vector
|
||||
- dim: dimension of the cochain
|
||||
@ -807,7 +808,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
#print(type(i[0].tuple()))
|
||||
cochain[i[0].tuple()] = i[1]
|
||||
return cochain
|
||||
|
||||
|
||||
def get_cohomology_aplk(self,degree):
|
||||
"""
|
||||
Returns a set of representative elements of Apl(K), one for each cohomology generator of a given degree
|
||||
@ -819,10 +820,10 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
cochain = self.lift_cohomology_generator(gen)
|
||||
representative_aplk_elements[key] = self.lift_cochain(cochain)
|
||||
return representative_aplk_elements
|
||||
|
||||
|
||||
def first_cohomology_group(self):
|
||||
"""
|
||||
Returns the degree >= 1 of the first non-null cohomology generator.
|
||||
Returns the degree >= 1 of the first non-null cohomology generator.
|
||||
"""
|
||||
basis = self.K.cohomology_ring(base_ring=QQ).basis()
|
||||
indexes = list(basis.keys())
|
||||
@ -832,29 +833,29 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
if indexes[n][0] > 0:
|
||||
return indexes[n][0]
|
||||
return -1
|
||||
|
||||
|
||||
class Element(Element):
|
||||
"""
|
||||
Element class of the simplicial commutative differential algebra (Apl)n.
|
||||
"""
|
||||
def __init__(self, parent, values):
|
||||
Element.__init__(self,parent)
|
||||
self.elements = self._reduce(values)
|
||||
self.check()
|
||||
|
||||
self.elements = self._reduce(values)
|
||||
self.check()
|
||||
|
||||
def _repr_(self):
|
||||
"""
|
||||
Return the base string representation of ``self``.
|
||||
"""
|
||||
return str(self.elements)
|
||||
|
||||
|
||||
def dimension(self):
|
||||
"""
|
||||
Returns the dimension where 'self' lives
|
||||
"""
|
||||
return self.parent().dimension()
|
||||
|
||||
|
||||
|
||||
|
||||
def _add_(self,other):
|
||||
"""
|
||||
Addition operation
|
||||
@ -878,7 +879,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
for k in self.elements.keys():
|
||||
newValues[k] = self.elements[k]-other.elements[k]
|
||||
return C(self.parent(),newValues)
|
||||
|
||||
|
||||
def _mul_(self,other):
|
||||
"""
|
||||
Multiplication operation
|
||||
@ -890,7 +891,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
for k in self.elements.keys():
|
||||
newValues[k] = self.elements[k]*other.elements[k]
|
||||
return C(self.parent(),newValues)
|
||||
|
||||
|
||||
def __pow__(self, n):
|
||||
"""
|
||||
Return ``self`` raised to the power ``n``.
|
||||
@ -900,7 +901,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
for k in self.elements.keys():
|
||||
newValues[k] = self.elements[k]**n
|
||||
return C(self.parent(),newValues)
|
||||
|
||||
|
||||
|
||||
def _richcmp_(self, other, op):
|
||||
"""
|
||||
@ -920,9 +921,9 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
|
||||
def _reduce(self, values):
|
||||
"""
|
||||
Returns the polynomials given as input, after applying the corresponding relations
|
||||
Returns the polynomials given as input, after applying the corresponding relations
|
||||
of the algebra where each polynomial belongs.
|
||||
|
||||
|
||||
INPUT:
|
||||
- values: a dictionary where the values are polynomials in (Apl)n
|
||||
"""
|
||||
@ -931,10 +932,10 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
n = len(k)-1
|
||||
reduced_values[k] = values[k].reduce()
|
||||
return reduced_values
|
||||
|
||||
|
||||
def check(self):
|
||||
"""
|
||||
Checks if the initial assignation respects the simplicial structure. For every simplex S, the algorithm checks
|
||||
Checks if the initial assignation respects the simplicial structure. For every simplex S, the algorithm checks
|
||||
if the polynomial assigned to each face of S is equal to the same face of the polynomial assigned to S.
|
||||
"""
|
||||
S = self.parent().simplicialComplex()
|
||||
@ -948,7 +949,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
#print("face: " + str(f),"simplex: " + str(simplex),"sFace: " + str(self.elements[sFace]), "aFace: " + str(aFace))
|
||||
if(self.elements[sFace] != aFace):
|
||||
raise ValueError("the assignation is not valid")
|
||||
|
||||
|
||||
def differential(self):
|
||||
"""
|
||||
Returns the differential of 'self'
|
||||
@ -958,7 +959,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
for k in self.elements.keys():
|
||||
newValues[k] = self.elements[k].differential()
|
||||
return C(self.parent(),newValues)
|
||||
|
||||
|
||||
def is_closed(self):
|
||||
"""
|
||||
Returns 'True' if 'self' is closed, i.e., its differential is zero.
|
||||
@ -968,7 +969,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def homogeneous_part(self,degree):
|
||||
"""
|
||||
Returns the homogeneous component of grade 'degree' of 'self'
|
||||
@ -1008,7 +1009,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
if not isHomogeneous:
|
||||
break
|
||||
return isHomogeneous
|
||||
|
||||
|
||||
def degree(self):
|
||||
if not self.is_homogeneous():
|
||||
return -1
|
||||
@ -1019,7 +1020,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
degree = e.degree()[0]
|
||||
break
|
||||
return degree
|
||||
|
||||
|
||||
def integral(self):
|
||||
"""
|
||||
Returns the cochain obtained as integration of 'self'
|
||||
@ -1029,9 +1030,9 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
for k in self.elements.keys():
|
||||
dim = len(k)-1
|
||||
# the sign is due to stoke's theorem
|
||||
cochain[k] = ((-1)**(dim*(dim-1)/2))*self.elements[k].integral()
|
||||
cochain[k] = ((-1) ** ((dim * (dim-1)) // 2)) * self.elements[k].integral()
|
||||
return cochain
|
||||
|
||||
|
||||
def _face_basis(self, basis, face_idx):
|
||||
face_basis = []
|
||||
for b in basis:
|
||||
@ -1044,9 +1045,9 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
face_basis = list(set(face_basis))
|
||||
face_basis.sort(reverse=False)
|
||||
return face_basis
|
||||
|
||||
|
||||
def _get_primitive_basis(self):
|
||||
|
||||
|
||||
primitive_basis = {}
|
||||
S = self.parent().simplicialComplex()
|
||||
dim = S.dimension()
|
||||
@ -1069,7 +1070,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
primitive_basis[simplex_face] = list(set(primitive_basis[simplex_face]))
|
||||
primitive_basis[simplex_face].sort(reverse=False)
|
||||
return primitive_basis
|
||||
|
||||
|
||||
def _diff_basis(self, basis):
|
||||
diff_basis = []
|
||||
for b in basis:
|
||||
@ -1082,7 +1083,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
diff_basis = list(set(diff_basis))
|
||||
diff_basis.sort(reverse=False)
|
||||
return diff_basis
|
||||
|
||||
|
||||
def _get_differential_basis(self, primitive_basis):
|
||||
differential_basis = {}
|
||||
S = self.parent().simplicialComplex()
|
||||
@ -1093,7 +1094,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
prim_diff_basis = primitive_basis[simplex.tuple()]
|
||||
differential_basis[simplex.tuple()] = self._diff_basis(prim_diff_basis)
|
||||
return differential_basis
|
||||
|
||||
|
||||
def _get_differential_matrix(self, p_basis, d_basis):
|
||||
S = self.parent().simplicialComplex()
|
||||
dim = S.dimension()
|
||||
@ -1125,9 +1126,9 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
col_index += len(primitives)
|
||||
elif primitives:
|
||||
col_index += len(primitives)
|
||||
|
||||
|
||||
return M
|
||||
|
||||
|
||||
def _get_vector_diff_coordinates(self, d_basis):
|
||||
len_v = sum([len(l) for l in d_basis.values()])
|
||||
v = zero_vector(QQ, len_v)
|
||||
@ -1150,7 +1151,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
v[offset + v_index] = dic[monomial]
|
||||
offset += len(differentials)
|
||||
return v
|
||||
|
||||
|
||||
def _get_offsets_matrix(self, p_basis):
|
||||
offsets = {}
|
||||
S = self.parent().simplicialComplex()
|
||||
@ -1169,11 +1170,11 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
offsets[simplex.tuple()] = offset
|
||||
offset += len(primitives)
|
||||
return offsets
|
||||
|
||||
|
||||
def _get_row_face_matrix(self, primitives, face_idx, face_basis,
|
||||
offset_simplex, offset_face, len_row):
|
||||
M = zero_matrix(QQ,1, len_row)
|
||||
for fb in face_basis:
|
||||
for fb in face_basis:
|
||||
fb_idx = face_basis.index(fb)
|
||||
row = zero_matrix(QQ,1, len_row)
|
||||
row[0,offset_face+fb_idx] = -1
|
||||
@ -1188,10 +1189,10 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
row[0,offset_simplex+i] = coef
|
||||
M = M.stack(row)
|
||||
return M[1:]
|
||||
|
||||
|
||||
|
||||
|
||||
def _get_face_matrix(self, p_basis):
|
||||
|
||||
|
||||
offsets = self._get_offsets_matrix(p_basis)
|
||||
len_row = sum([len(l) for l in p_basis.values()])
|
||||
M = zero_matrix(QQ,1, len_row)
|
||||
@ -1209,7 +1210,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
len_row)
|
||||
M = M.stack(rows)
|
||||
return M[1:]
|
||||
|
||||
|
||||
def _get_solution(self, sol, p_basis):
|
||||
S = self.parent().simplicialComplex()
|
||||
dim = S.dimension()
|
||||
@ -1229,11 +1230,11 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
coef = sol[offset+i]
|
||||
pol += coef*p
|
||||
offset += len(primitives)
|
||||
values[simplex] = pol
|
||||
values[simplex] = pol
|
||||
A = self.parent()
|
||||
# return values
|
||||
return A._element_constructor_(values)
|
||||
|
||||
|
||||
def solve_primitive(self):
|
||||
p_basis = self._get_primitive_basis()
|
||||
d_basis = self._get_differential_basis(p_basis)
|
||||
@ -1245,7 +1246,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
||||
M = diff_matrix.stack(face_matrix)
|
||||
sol = M.solve_right(v)
|
||||
return self._get_solution(sol, p_basis)
|
||||
|
||||
|
||||
|
||||
class MorphismFromQQToAplK(Morphism):
|
||||
|
||||
@ -1261,7 +1262,7 @@ class MorphismFromQQToAplK(Morphism):
|
||||
for c in S._n_cells_sorted(d):
|
||||
params[tuple(c)]=s(x)
|
||||
A = AlgebraAplK(S)
|
||||
return AlgebraAplK.Element(A, params)
|
||||
return AlgebraAplK.Element(A, params)
|
||||
|
||||
#############################################
|
||||
# TEST
|
||||
|
||||
Loading…
Reference in New Issue
Block a user