5519 lines
179 KiB
Plaintext
5519 lines
179 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# About the organization of the notebook\n",
|
|
"\n",
|
|
"In this document, the implementation of different mathematical objects is explained. For each one, the information is structured in the following way:\n",
|
|
"\n",
|
|
"1) First section: Definition. The object is defined using mathematical language.\n",
|
|
"2) Second section: Implementation.\n",
|
|
" 1) Ideas and decisions made\n",
|
|
" 2) Initial declaration of the main class\n",
|
|
" 3) Implementation of a new method and examples\n",
|
|
"\n",
|
|
"Each class is declared iteratively, i.e., each method is added in a different cell in order to explain it properly and to show examples. This is done in that way for a didactic purpose. For that reason, the subsection 2.c) is repeated for each new method that is added to the main class.\n",
|
|
"\n",
|
|
"***"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# The cochain algebra $(A_{PL})_{n}$\n",
|
|
"In this section it is implemented the graded commutative differential cochain algebra $(A_{PL})_{n}$. For more information, see [Rational homotopy theory, Felix, Halperin, Thomas, chapter 10.c)].\n",
|
|
"\n",
|
|
"## Definition\n",
|
|
"First, consider the free graded commutative algebra $\\Lambda(t_0,\\dots,t_n,y_0,\\dots,y_n)$, where the generators $t_i$ have degree $0$, and the generators $y_j$ have degree $1$. The differential, $d$, is given by \n",
|
|
"\n",
|
|
"* $d(t_i)=y_i$\n",
|
|
"* $d(y_j)=0$\n",
|
|
"\n",
|
|
"The cochain algebra $(A_{PL})_n$ is defined as the quotient of the previous algebra by the relations:\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"$$(A_{PL})_n=\\frac{\\Lambda(t_0,\\dots,t_n,y_0,\\dots,y_n)}{<\\sum {t_i}-1,\\sum{y_j}>}$$\n",
|
|
"\n",
|
|
"\n",
|
|
"## Implementation\n",
|
|
"\n",
|
|
"$(A_{PL})_{n}$ is a graded commutatite differential algebra, GCDA. In order to work with GCDA's that are finitely generated by elements of $degree \\geq 1$, there is defined in SAGE a class called \"DifferentialGCAlgebra\". Our first problem is that our GCDA has generators of $degree=0$ (the generators $t_i$) and this class doesn't allow us to create such object. \n",
|
|
"\n",
|
|
"As a first approximation, in order to solve this problem, we will define a new class of GCDA's that internally will work with multigraded generators, but this feature will be transparent for the user. For that reason, we will extend the class \"DifferentialGCAlgebra_multigraded\" in order to add new methods that will be useful later."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Initial declaration of the main class"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from sage.algebras.commutative_dga import *\n",
|
|
"import copy\n",
|
|
"\n",
|
|
"class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):\n",
|
|
" \"\"\"\n",
|
|
" A differential multi-graded commutative algebra\n",
|
|
" \n",
|
|
" This class extends the DifferentialGCAlgebra_multigraded class\n",
|
|
" to create the algebra of polynomial differential forms with coefficients in QQ\n",
|
|
"\n",
|
|
" INPUT:\n",
|
|
"\n",
|
|
" - ``A`` -- a multi-graded commutative algebra\n",
|
|
" - ``differential`` -- the differential rules\n",
|
|
"\n",
|
|
" \"\"\"\n",
|
|
"\n",
|
|
" def __init__(self, A, differential):\n",
|
|
" \"\"\"\n",
|
|
" Initialize ``self``.\n",
|
|
"\n",
|
|
" INPUT:\n",
|
|
"\n",
|
|
" - ``A`` -- a multi-graded commutative algebra\n",
|
|
" - ``differential`` -- a differential\n",
|
|
" \"\"\"\n",
|
|
"\n",
|
|
" self.n = len(A._names)/2-1\n",
|
|
" DifferentialGCAlgebra_multigraded.__init__(self, A, differential)\n",
|
|
" self.t_relation = sum(self.gens()[:self.n+1])-1\n",
|
|
" self.y_relation = sum(self.gens()[self.n+1:])\n",
|
|
"\n",
|
|
" def _base_repr(self):\n",
|
|
" \"\"\"\n",
|
|
" Return the base string representation of ``self``.\n",
|
|
" \"\"\"\n",
|
|
"\n",
|
|
" s = DifferentialGCAlgebra._base_repr(self)\n",
|
|
" old = '{}'.format(self._degrees)\n",
|
|
" new = '{}'.format([i[0] for i in self._degrees_multi])\n",
|
|
" return s.replace(old, new)\n",
|
|
"\n",
|
|
" class Element(GCAlgebra_multigraded.Element, DifferentialGCAlgebra.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the commutative differential multi-graded algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
" pass\n",
|
|
" \n",
|
|
"def AlgebraPL(n):\n",
|
|
" \"\"\"\n",
|
|
" The graded commutative differential cochain algebra Apl of dimension ``n``\n",
|
|
"\n",
|
|
" INPUT:\n",
|
|
"\n",
|
|
" - ``n`` -- A non-negative integer corresponding to the number of generators of degree 0.\n",
|
|
" \"\"\"\n",
|
|
"\n",
|
|
" if (n<0):\n",
|
|
" raise ValueError('`n` must be a non-negative integer')\n",
|
|
" ts = ['t'+str(t) for t in range(n+1)]\n",
|
|
" ys = ['y'+str(t) for t in range(n+1)]\n",
|
|
" degrees = tuple((n+1)*[(0,2)])+tuple((n+1)*[(1,2)])\n",
|
|
" gca = GradedCommutativeAlgebra(QQ, names=ts+ys, degrees=degrees)\n",
|
|
" differentials = {gca.gens_dict()[ts[i]]:gca.gens_dict()[ys[i]] for i in range(n+1)}\n",
|
|
" return AplN(gca,differentials)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Example: creating an element of $(Apl)_{n}$"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Commutative Differential Graded Algebra with generators ('t0', 't1', 'y0', 'y1') in degrees [0, 0, 1, 1] over Rational Field with differential:\n",
|
|
" t0 --> y0\n",
|
|
" t1 --> y1\n",
|
|
" y0 --> 0\n",
|
|
" y1 --> 0\n",
|
|
"Defining t0, t1, y0, y1\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"apl = AlgebraPL(1)\n",
|
|
"print(apl)\n",
|
|
"apl.inject_variables()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"y0 + y1 + t0"
|
|
]
|
|
},
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"p = t0 + y0 + y1\n",
|
|
"p"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Adding new methods: homogeneity and total degree of a polynomial\n",
|
|
"\n",
|
|
"As we mentioned before, we use a multigraded algebra internally. Specifically, we use a bigraded algebra, where the generators have either degree $(0,2)$ or degree $(1,2)$ The first component of the bigrade represents the actual degree we want to use, and the second component is ignored (it is only needed to be an even number $>0$). In particular, the generators $t_i$ have internally a degree $(0,2)$ and the generators $y_j$ have degree $(1,2)$. In order to make it transparent for the user, we implement a several methods to get, for example, the homogeneous part of a polynomial, ignoring the mentioned bigrade, and taking into account only the first compoment of the multigrade."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AplN(AplN,UniqueRepresentation):\n",
|
|
" class Element(AplN.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the commutative differential multi-graded algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" def is_homogeneous(self):\n",
|
|
" \"\"\"\n",
|
|
" Return \"True\" if \"self\" is homogeneous and \"False\" otherwise.\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" degrees = set([k[0] for k in self.homogeneous_parts()])\n",
|
|
" return len(degrees) == 1\n",
|
|
" \n",
|
|
" def total_degree(self):\n",
|
|
" \"\"\"\n",
|
|
" Return the total degree of this element.\n",
|
|
" \"\"\" \n",
|
|
" \n",
|
|
" degrees = set([k[0] for k in self.homogeneous_parts()])\n",
|
|
" return max(degrees)\n",
|
|
" \n",
|
|
" def homogeneous_part(self,degree):\n",
|
|
" \"\"\"\n",
|
|
" Returns the homogeneous part of the element for a given degree.\n",
|
|
" \"\"\"\n",
|
|
"\n",
|
|
" if (degree<0):\n",
|
|
" raise ValueError('`degree` must be a non-negative integer')\n",
|
|
" parts = [self.homogeneous_parts()[k] for k in self.homogeneous_parts() if list(k)[0]==degree]\n",
|
|
" return sum(parts)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Example: checking the homogeneity of a given polynomial"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, y0, y1\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"apl = AlgebraPL(1)\n",
|
|
"apl.inject_variables()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"False"
|
|
]
|
|
},
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"p = t0 + y0 + y1\n",
|
|
"p.is_homogeneous()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Example: getting the homogeneous part of a polynomial for a given degree"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Original polynomial: y0 + y1 + t0\n",
|
|
"Homogeneous part of degree 1 of p: y0 + y1\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"p = t0 + y0 + y1\n",
|
|
"deg = 1\n",
|
|
"print(\"Original polynomial:\", p)\n",
|
|
"print(\"Homogeneous part of degree\", deg, \"of p: \", p.homogeneous_part(degree=deg))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Example: getting the total degree of a polynomial"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"2"
|
|
]
|
|
},
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"q = y0*y1 + t0*y1 + 1\n",
|
|
"q.total_degree()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Adding new method: reduce a polynomial by relations\n",
|
|
"\n",
|
|
"As seen in the definition, the algebra $(A_{PL})_{n}$ is the quiotient algebra\n",
|
|
"\n",
|
|
"$$(A_{PL})_n=\\frac{\\Lambda(t_0,\\dots,t_n,y_0,\\dots,y_n)}{<\\sum {t_i}-1,\\sum{y_j}>}$$\n",
|
|
"\n",
|
|
"Notice that there is an isomorphism between this algebra and the free algebra:\n",
|
|
"\n",
|
|
"$$ (A_{PL})_n \\cong \\Lambda(t_1,\\dots,t_n,y_1,\\dots,y_n) $$\n",
|
|
"\n",
|
|
"\n",
|
|
"In order to obtain a representative of a particular element on the free algebra, a method called \"reduce\" is added to the elements of our class. This method reduces the variables $t_0,y_0$ applying the following rules:\n",
|
|
"\n",
|
|
"$$t_0 = 1 - \\sum_{i=1}^{n} t_i$$\n",
|
|
"$$y_0 = -\\sum_{j=1}^{n} y_j$$\n",
|
|
"\n",
|
|
"Thus, after applying this method, an element of $(A_{PL})_{n}$ will be represented as an element of the algebra $\\Lambda(t_1,\\dots,t_n,y_1,\\dots,y_n)$.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AplN(AplN,UniqueRepresentation):\n",
|
|
" class Element(AplN.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the commutative differential multi-graded algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
" def reduce(self, relations=[]):\n",
|
|
" \"\"\"\" \n",
|
|
" The method reduces the polynomial by the Ideal <sum(t_i)-1, sum(y_j)>\n",
|
|
" \n",
|
|
" INPUT::\n",
|
|
" - p: polynomial in variables t_0,..t_n,y_0,...,y_n\n",
|
|
" - relations (optional): if relations are given, the polynomial is reduced following\n",
|
|
" this rules. If no relations are given, the polynomial is reduced taking into\n",
|
|
" account the relations of the parent algebra.\n",
|
|
" \n",
|
|
" OUTPUT::\n",
|
|
" - The polynomial after applying the corresponding relations \n",
|
|
" \"\"\"\n",
|
|
" apl = self.parent()\n",
|
|
" dim = len(apl.gens())//2-1\n",
|
|
" if relations:\n",
|
|
" return DifferentialGCAlgebra.Element.reduce(self, relations)\n",
|
|
" else:\n",
|
|
" return DifferentialGCAlgebra.Element.reduce(self, [apl.t_relation, apl.y_relation])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Example: getting the reduced polynomial of a given element"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, y0, y1\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"apl = AlgebraPL(1)\n",
|
|
"apl.inject_variables()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"unreduced polynomial: y0 + y1 + t0\n",
|
|
"reduced polynomial: -t1 + 1\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"p=t0+y0+y1\n",
|
|
"print(\"unreduced polynomial: \", p)\n",
|
|
"print(\"reduced polynomial: \", p.reduce())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Adding new methods: The definite integral map\n",
|
|
"\n",
|
|
"We define a linear map:\n",
|
|
"\n",
|
|
"$$ \\int_{n}: (A_{PL})_{n}^{n} \\rightarrow \\mathbb{Q} $$\n",
|
|
"\n",
|
|
"by setting\n",
|
|
"\n",
|
|
"$$ \\int_{n}t_1^{k_1}t_2^{k_2}\\dots t_n^{k_n}dt_1\\wedge \\dots \\wedge dt_n = \\int_{0}^{1} dt_1 \\int_{0}^{1-t_1}dt_2 \\dots \\int_{0}^{1-\\sum_{1}^{n-1}t_i}t_1^{k_1}t_2^{k_2}\\dots t_n^{k_n}dt_n = \\frac{k_1!k_2! \\dots k_n!}{(k_1+ \\dots +k_n+n)!} $$"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AplN(AplN,UniqueRepresentation):\n",
|
|
" class Element(AplN.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the commutative differential multi-graded algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
" def _integrable_part(self):\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" The method returns the coefficient in Q[t_1,...,t_n] of the term\n",
|
|
" of degree `n`\n",
|
|
"\n",
|
|
" OUTPUT:\n",
|
|
" - A polynomial in the ring Q<t_1,..t_n>.\n",
|
|
" (After reducing the variables t_{0},y_{0} by the corresponding relations, \n",
|
|
" the algorithm removes the variables y_{1},..,y_{n}). \n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" apl = self.parent()\n",
|
|
" pol = apl(self.reduce()) #needed in case reduce() returns an integer\n",
|
|
" relations = []\n",
|
|
" for i in range(apl.n+1): \n",
|
|
" relations.append(apl.gens()[apl.n+1+i]-1)\n",
|
|
" pol = apl(pol.homogeneous_part(degree=apl.n)) \n",
|
|
" return apl(pol.reduce(relations=relations))\n",
|
|
"\n",
|
|
" def integral(self):\n",
|
|
" \"\"\"\n",
|
|
" Returns the definite integral of the term of degree `n`\n",
|
|
" \n",
|
|
" OUTPUT:\n",
|
|
" - The rational number obtained by the definite integral \n",
|
|
" of the term of degree `n`\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
"\n",
|
|
" apl = self.parent()\n",
|
|
" pol = self._integrable_part()\n",
|
|
" result = 0\n",
|
|
" for k in pol.dict().keys(): # k is a monomial\n",
|
|
" numerator = 1\n",
|
|
" denominator = apl.n\n",
|
|
" for e in k: # e is an exponents\n",
|
|
" numerator *= factorial(e)\n",
|
|
" denominator += e\n",
|
|
" coef = pol.dict()[k]\n",
|
|
" result += coef*numerator/factorial(denominator)\n",
|
|
" #return ((-1)**(apl.n*(apl.n-1)/2))*result\n",
|
|
" return result"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Example"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, y0, y1\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"apl = AlgebraPL(1)\n",
|
|
"apl.inject_variables()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Integrable part: -t1 + 2\n",
|
|
"Definite integral: 3/2\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"p=t0+y1*(t0+1)\n",
|
|
"print(\"Integrable part: \",p._integrable_part())\n",
|
|
"print(\"Definite integral: \", p.integral())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Adding new method: find an integrand for a given definite integral\n",
|
|
"\n",
|
|
"The linear map we have defined above is not injective, but we can consider one way to find a polynomial whose image by the definite integral map is given. We call \"integrand\" to this particular element of the preimage set of the given element by the linear map.\n",
|
|
"\n",
|
|
"$$ \\int_{n}^{-1} c = c (n!) dt_1 \\wedge \\dots \\wedge dt_n$$\n",
|
|
"$$ c \\in \\mathbb{Q} $$\n",
|
|
"\n",
|
|
"It is easy to see that $ \\int_{n}\\int_{n}^{-1} c = c $ although the inverse is not always true. \n",
|
|
"\n",
|
|
"We define a class method, called \"integrand\", that returns a polynomial whose definite integral image is equal to a rational number given as input."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AplN(AplN,UniqueRepresentation):\n",
|
|
" def integrand(self, value): \n",
|
|
" \"\"\"\n",
|
|
" Returns a polynomial whose definite integral is equal to 'value'\n",
|
|
"\n",
|
|
" OUTPUT:\n",
|
|
" - A polynomial\n",
|
|
" \"\"\"\n",
|
|
" return value*factorial(self.n)*prod(self.gens()[self.n+2:])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Example: getting a polynomial for whose definite integral is given"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, y0, y1\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"apl = AlgebraPL(1)\n",
|
|
"apl.inject_variables()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"5*y1"
|
|
]
|
|
},
|
|
"execution_count": 17,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"value = 5\n",
|
|
"apl.integrand(value)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"True"
|
|
]
|
|
},
|
|
"execution_count": 18,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"#checking that the composition of the integral and the lift is the identity map\n",
|
|
"p = apl.integrand(value)\n",
|
|
"p.integral()==value"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Adding new methods: find a primitive of the coboundary operator\n",
|
|
"\n",
|
|
"As we have mentioned before, there is an isomorphism between the cochain algebra $(A_{PL})_n$ and the algebra $\\Lambda (t_1, \\dots, t_n,y_1, \\dots, y_n)$, where the variables $t_i$ have degree $0$, and the variables $y_j$ have degree $1$. This algebra is the tensor product of the polynomial ring in the variables $t_i$ with the exterior algebra in the variables $y_j$:\n",
|
|
"\n",
|
|
"$$(A_{PL})_n \\cong \\mathbb{Q}[t_1, \\dots, t_n]\\otimes_{\\mathbb{Q}} \\Lambda ^{\\mathbb{Q}}(y_1, \\dots, y_n)$$\n",
|
|
"\n",
|
|
"In this algebra, we define the lexicographic monomial order in the variables $y_i$ as \n",
|
|
"\n",
|
|
"$$y_i > y_j, \\: if \\: i<j$$\n",
|
|
"\n",
|
|
"A polynomial $p \\in \\Lambda (t_1, \\dots, t_n,y_1, \\dots, y_n)$ has the form:\n",
|
|
"\n",
|
|
"$$ p = p^0 y_{1}^{k_{1}^{0}} \\dots y_{n}^{k_{n}^{0}} + p^1 y_{1}^{k_{1}^{1}} \\dots y_{n}^{k_{n}^{1}} + \\dots $$ \n",
|
|
"\n",
|
|
"where \n",
|
|
"\n",
|
|
"- $k_{j}^{i} \\in \\mathbb{Z}_2$\n",
|
|
"- $p^i \\in \\mathbb{Q}[t_1, \\dots, t_n]$\n",
|
|
"- $(k_{1}^{i}, \\dots , k_{n}^{i}) \\neq (k_{1}^{j}, \\dots, k_{n}^{j})$ if $i \\neq j$\n",
|
|
"\n",
|
|
"It is easy to see that $p$ will have at most $2^n-1$ non-null terms in the variables $y_j$.\n",
|
|
"\n",
|
|
"As we have set the lexicographic monomial ordering, for every two consecutive non-null terms in a polynomial $p$\n",
|
|
"\n",
|
|
"$$ p = \\dots + p^i y_{1}^{k_{1}^{i}} \\dots y_{n}^{k_{n}^{i}} + p^{i+1} y_{1}^{k_{1}^{i+1}} \\dots y_{n}^{k_{n}^{i+1}} + \\dots$$\n",
|
|
"\n",
|
|
"occurs one of the following situations:\n",
|
|
"\n",
|
|
"- $k_{1}^{i} > k_{1}^{i+1}$\n",
|
|
"- $\\exists m \\in \\mathbb{N}, 1 < m \\leq n $ so that $k_{l}^{i} = k_{l}^{i+1}$ for $1 \\leq l < m$, and $k_{l}^{i} > k_{l}^{i+1}$ for $l= m$.\n",
|
|
"\n",
|
|
"\n",
|
|
"Our algebra $(A_{PL})_n$, as a cochain algebra, has a coboundary operator, $d$, and by definition, we know that $d^2=0$. Also, we know that $H^p((A_{PL})_n)=0$ for $p \\geq 1$, meaning that, for every element $\\theta \\in (A_{PL})_n$ so that $d\\theta=0$ (i.e., $\\theta$ is closed), there exists an element $\\omega \\in (A_{PL})_n$ so that $\\theta = d\\omega$.\n",
|
|
"\n",
|
|
"Our problem here is to find a primitive $\\omega$ whose differential $\\theta$ is known, $\\theta = d\\omega$. As we know that $\\theta$ is the differential of some element, for now on we will consider polynomials where all terms have at least one exponent $k_{j}^{i} \\neq 0$ (i.e., our polynomial $\\theta$ has no terms of degree $0$)."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"**Definition**. (pseudo-primitive of a monomial) Let $\\theta \\in (A_{PL})_n$ be a polynomial formed by only one term of degree $p$ of the form:\n",
|
|
"\n",
|
|
"$$\\theta = ct_{1}^{l_{1}^{0}} \\dots t_{n}^{l_{n}^{0}} y_{1}^{k_{1}^{0}} \\dots y_{n}^{k_{n}^{0}}$$\n",
|
|
"\n",
|
|
"satisfying:\n",
|
|
"\n",
|
|
"- $c \\in \\mathbb{Q}$\n",
|
|
"- $k_{j}^{i} \\in \\mathbb{Z}_2$\n",
|
|
"- $\\sum k_{j}^{i} = p$\n",
|
|
"- $l_{j}^{i} \\in \\mathbb{N} \\cup \\{0\\}$\n",
|
|
"\n",
|
|
"We define the *pseudo-primitive of $\\theta$* (in relation to the coboundary operator) as the homogeneous polynomial $\\omega$, of degree $p-1$, whose differential is the polynomial $\\theta$ plus some homogeneous polynomial $\\epsilon$ of degree $p$:\n",
|
|
"\n",
|
|
"$$d\\omega = \\theta+\\epsilon$$\n",
|
|
"\n",
|
|
"This polynomial is calculated in the following way:\n",
|
|
"\n",
|
|
"**Step 1:** Choose the lowest $i$ for which $k_{i}^{0}=1$\n",
|
|
"\n",
|
|
"**Step 2:** Set $k_{i}^{0}=0$ and increase $l_{i}^{0}$ by 1\n",
|
|
"\n",
|
|
"$$ \\omega = ct_{1}^{l_{1}^{0}} \\dots t_{i}^{l_{i}^{0}+1} \\dots t_{n}^{l_{n}^{0}} y_{1}^{0} \\dots y_{i}^{0} \\dots y_{n}^{k_{n}^{0}}$$\n",
|
|
"\n",
|
|
"**Step 3:** Divide the coefficient $c$ by $l_{i}^{0}+1$\n",
|
|
"\n",
|
|
"$$ \\omega = \\frac{c}{l_{i}^{0}+1}t_{1}^{l_{1}^{0}} \\dots t_{i}^{l_{i}^{0}+1} \\dots t_{n}^{l_{n}^{0}} y_{1}^{0} \\dots y_{i}^{0} \\dots y_{n}^{k_{n}^{0}}$$\n",
|
|
"\n",
|
|
"\n",
|
|
"**Lemma**: $d\\omega= \\theta + \\epsilon$\n",
|
|
"\n",
|
|
"**Proof**: TODO\n",
|
|
"***\n",
|
|
"\n",
|
|
"\n",
|
|
"#### **The algorithm**\n",
|
|
"\n",
|
|
"The input of our algorithm is a polynomial $\\theta \\in (A_{PL})_n$ that has the form:\n",
|
|
"\n",
|
|
"$$ \\theta = p^0 y_{1}^{k_{1}^{0}} \\dots y_{n}^{k_{n}^{0}} + p^1 y_{1}^{k_{1}^{1}} \\dots y_{n}^{k_{n}^{1}} + \\dots $$\n",
|
|
"\n",
|
|
"$$p^i \\in \\mathbb{Q}[t_1, \\dots, t_n]$$\n",
|
|
"\n",
|
|
"**Step 1**: Find a pseudo-primitive of the leading term of $\\theta$.\n",
|
|
"\n",
|
|
"First, we define the variables $\\omega, \\theta_0$, and we initialize them as \n",
|
|
"\n",
|
|
"$$\\omega=0$$\n",
|
|
"$$\\theta_0=\\theta$$\n",
|
|
"\n",
|
|
"The leading term of $\\theta_0$, $LT(\\theta_0)$, has the form:\n",
|
|
"\n",
|
|
"$$LT(\\theta_0) = c_0t_{1}^{l_{1}^{0}} \\dots t_{n}^{l_{n}^{0}} y_{1}^{k_{1}^{0}} \\dots y_{n}^{k_{n}^{0}}$$\n",
|
|
"$$ c_0\\in \\mathbb{Q}$$\n",
|
|
"$$ l_{i}^{0} \\geq 0$$\n",
|
|
"\n",
|
|
"What we want to do in this step is to find a polynomial $\\omega_0$ whose differential contains the leading term of the element $\\theta_0$ plus some extra terms $\\epsilon_0$:\n",
|
|
"\n",
|
|
"$$d\\omega_0 = LT(\\theta_0)+\\epsilon_0$$\n",
|
|
"\n",
|
|
"Knowing that the coboundary operator increases the degree in 1 unit, and the degree of every term comes from the variables $y_j$, one approach is the following:\n",
|
|
"\n",
|
|
"1) Assign to $\\omega_0$ the leading term of $\\theta_0$, \n",
|
|
"2) Choose the lowest $i$ for which $k_{i}^{0}=1$\n",
|
|
"3) Set $k_{i}^{0}=0$ and increase $l_{i}^{0}$ by 1\n",
|
|
"4) Divide the coefficient $c_0$ by $l_{i}^{0}+1$\n",
|
|
"\n",
|
|
"$$ \\omega_0 = \\frac{c_0}{l_{i}^{0}+1}t_{1}^{l_{1}^{0}} \\dots t_{i}^{l_{i}^{0}+1} \\dots t_{n}^{l_{n}^{0}} y_{1}^{0} \\dots y_{i}^{0} \\dots y_{n}^{k_{n}^{0}}$$\n",
|
|
"\n",
|
|
"TODO: Prueba de que esto funciona:\n",
|
|
"\n",
|
|
"$$\\omega_0 = c_0a(t)*b(y)$$\n",
|
|
"$$d\\omega_0 = d(c_0a(t))*b(y)) = c_0d(a(t))b(y)$$\n",
|
|
"\n",
|
|
"**Step 2**: Calculate the new $\\theta_i$:\n",
|
|
"\n",
|
|
"Once we have found the element $\\omega_0$, we update the variable $\\omega$ as:\n",
|
|
"\n",
|
|
"$$ \\omega = \\omega + \\omega_0$$\n",
|
|
"\n",
|
|
"and we define the new variable $\\theta_{1}$ as:\n",
|
|
"\n",
|
|
"$$ \\theta_{1} = \\theta-d\\omega $$\n",
|
|
"\n",
|
|
"If $\\theta_{1}=0$ we have finished and $\\omega$ is the element we were looking for. If $\\theta_{1} \\neq 0$, continue with the following steps.\n",
|
|
"\n",
|
|
"\n",
|
|
"**Step 3**:\n",
|
|
"\n",
|
|
"Get the leading term of $\\theta_{1}$, and obtain its pseudo-primitive $\\omega_1$.\n",
|
|
"\n",
|
|
"**Step 4:**\n",
|
|
"\n",
|
|
"Update the variable $\\omega$ as:\n",
|
|
"\n",
|
|
"$$ \\omega = \\omega + \\omega_1$$\n",
|
|
"\n",
|
|
"and define the new variable $\\theta_{2}$ as:\n",
|
|
"\n",
|
|
"$$ \\theta_{2} = \\theta-d\\omega $$\n",
|
|
"\n",
|
|
"**Step 5:**\n",
|
|
"If $\\theta_{2}=0$ we have finished and $\\omega$ is the element we were looking for. If $\\theta_{2} \\neq 0$, go back to step 3 and repeat the steps 3 and 4 several times until we get that $\\theta_{i+1}=0$.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AplN(AplN,UniqueRepresentation):\n",
|
|
" class Element(AplN.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the commutative differential multi-graded algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" def _get_term(self, coef, exp, gens):\n",
|
|
" \"\"\"\" \n",
|
|
" \n",
|
|
" Returns the term specified by its coefficient, exponents and generators\n",
|
|
" \n",
|
|
" INPUT::\n",
|
|
" - coef: The coefficient of the term\n",
|
|
" - exp: A tuple with the exponents of each variable\n",
|
|
" - gens: The generators\n",
|
|
" \n",
|
|
" OUTPUT::\n",
|
|
" - A polynomial\n",
|
|
" \"\"\"\n",
|
|
" return coef*prod(list(map(lambda exp, gen: gen^exp, exp, gens)))\n",
|
|
"\n",
|
|
" def _get_terms(self):\n",
|
|
" \"\"\"\" \n",
|
|
" \n",
|
|
" Returns self seen as a collection of terms in the variables y_j with coefficients in QQ<t_1,..,t_n>\n",
|
|
" \n",
|
|
" OUTPUT::\n",
|
|
" - A dictionary with all terms\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" a = self.parent()\n",
|
|
" n = len(a.gens())/2\n",
|
|
" ts_only_gens = a.gens()[:n]+tuple(n*[1])\n",
|
|
" ys_only_gens = tuple(n*[1])+a.gens()[n:]\n",
|
|
" terms = {}\n",
|
|
" pol = self.dict()\n",
|
|
" for exp in pol.keys():\n",
|
|
" key = self._get_term(1, exp,ys_only_gens)\n",
|
|
" coef = self._get_term(pol[exp],exp,ts_only_gens)\n",
|
|
" if key not in terms.keys():\n",
|
|
" terms[key] = coef\n",
|
|
" else:\n",
|
|
" terms[key] += coef \n",
|
|
" return terms\n",
|
|
"\n",
|
|
" def _get_leading_pol(self):\n",
|
|
" \"\"\"\" \n",
|
|
" \n",
|
|
" Returns the leading polynomial\n",
|
|
" \n",
|
|
" OUTPUT::\n",
|
|
" - A polynomial\n",
|
|
" \"\"\"\n",
|
|
" terms = self._get_terms()\n",
|
|
" keys = list(terms.keys())\n",
|
|
" keys.sort(reverse=True)\n",
|
|
" return terms[keys[0]]*keys[0]\n",
|
|
"\n",
|
|
" def _get_idx(self, exp):\n",
|
|
" \"\"\"\" \n",
|
|
" \n",
|
|
" Returns the idx 'i' of the first generator 'y_i' that appears in exp\n",
|
|
" \n",
|
|
" INPUT::\n",
|
|
" - exp: A tuple with the exponents\n",
|
|
" \n",
|
|
" OUTPUT::\n",
|
|
" - A non-negative number lower or equal to 'n'\n",
|
|
" \"\"\"\n",
|
|
" n = len(exp)/2\n",
|
|
" filter_ts = n*[0]+n*[1]\n",
|
|
" diff_forms = list(map(lambda v, f: v*f, exp, filter_ts))\n",
|
|
" return next((i for i, x in enumerate(list(diff_forms)) if x), None)-n\n",
|
|
"\n",
|
|
" def _monomial_primitive(self, monomial, idx):\n",
|
|
" \"\"\"\" \n",
|
|
" \n",
|
|
" Returns the primitive of the given monomial\n",
|
|
" \n",
|
|
" INPUT::\n",
|
|
" - monomial: A monomial\n",
|
|
" - idx: the index of the variable y_j that will be used to calculate the pseudo-primitive\n",
|
|
" \n",
|
|
" OUTPUT::\n",
|
|
" - A polynomial\n",
|
|
" \"\"\"\n",
|
|
" exp = list(monomial.dict().keys())[0]\n",
|
|
" coef = monomial.dict()[exp]\n",
|
|
" n = len(exp)/2\n",
|
|
" if (exp[n+idx]==0):\n",
|
|
" raise IndexError(\"It is not possible to get a primitive using the given idx.\")\n",
|
|
" primitive = list(copy.deepcopy(exp))\n",
|
|
" primitive[n+idx] = 0\n",
|
|
" primitive[idx] += 1\n",
|
|
" new_coef = coef/primitive[idx]\n",
|
|
" a = monomial.parent()\n",
|
|
" return self._get_term(new_coef, primitive, a.gens())\n",
|
|
"\n",
|
|
" def _leading_primitive(self):\n",
|
|
" \"\"\"\" \n",
|
|
" Returns the primitive of the leading term of self\n",
|
|
" \n",
|
|
" OUTPUT::\n",
|
|
" - A polynomial\n",
|
|
" \"\"\"\n",
|
|
" polynomial = self._get_leading_pol()\n",
|
|
" # necessary condition: all monomials have apl.gens[n+idx] factor\n",
|
|
" exp = list(polynomial.dict().keys())[0]\n",
|
|
" idx = self._get_idx(exp)\n",
|
|
" aGens = polynomial.parent().gens()\n",
|
|
" primitive = 0\n",
|
|
" for exp in polynomial.dict().keys():\n",
|
|
" coef = polynomial.dict()[exp]\n",
|
|
" monomial = self._get_term(coef, exp, aGens)\n",
|
|
" primitive += self._monomial_primitive(monomial, idx)\n",
|
|
" terms = primitive._get_terms()\n",
|
|
" result = sum([terms[key]*key for key in terms.keys()])\n",
|
|
" return result\n",
|
|
"\n",
|
|
" def primitive(self):\n",
|
|
" \"\"\"\" \n",
|
|
" Retuns a polynomial whose differential is self\n",
|
|
" \n",
|
|
" OUTPUT::\n",
|
|
" - A polynomial\n",
|
|
" \"\"\"\n",
|
|
" if self.differential()!=0 :\n",
|
|
" raise ValueError(\"This polynomial is not closed.\")\n",
|
|
" w = self._leading_primitive()\n",
|
|
" theta = self - w.differential()\n",
|
|
" if (theta == 0):\n",
|
|
" return w\n",
|
|
" else:\n",
|
|
" return w+theta.primitive()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Example"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, t2, t3, t4, t5, y0, y1, y2, y3, y4, y5\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"apl = AlgebraPL(5)\n",
|
|
"apl.inject_variables()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"True\n",
|
|
"False\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"omega_orig = t0+5*y1*y2+y3*y4*t1*y5\n",
|
|
"theta = omega_orig.differential()\n",
|
|
"print(theta.primitive().differential()==theta)\n",
|
|
"print(theta.primitive()==omega_orig)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"0\n",
|
|
"True\n",
|
|
"t0*t1^2*y1*y3 + 1/2*t0^2*y1*y3 + t0*y1*y3\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"theta = (t0+t1^2+1)*y0*y1*y3\n",
|
|
"print(theta.differential())\n",
|
|
"print(theta.primitive().differential()==theta)\n",
|
|
"print(theta.primitive())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# The simplicial cochain algebra $A_{PL}$\n",
|
|
"This class implements the simplicial cochain algebra $A_{PL} = \\{(A_{PL})_{n}\\}_{n\\geq0}$. For more information, see [Rational homotopy theory, Felix, Halperin, Thomas, chapter 10.c)].\n",
|
|
"\n",
|
|
"## Definition\n",
|
|
"\n",
|
|
"A simplicial object $K$ with values in a category $\\mathfrak{C}$ is a sequence $\\{K_n\\}_{n \\geq 0}$ of objects in $\\mathfrak{C}$, together with $\\mathfrak{C}$-morphisms:\n",
|
|
"\n",
|
|
"$$\\delta_i: K_{n} \\rightarrow K_{n-1}, \\; 0 \\leq i \\leq n $$ \n",
|
|
"\n",
|
|
"$$s_j: K_{n} \\rightarrow K_{n+1}, \\; 0 \\leq j \\leq n$$\n",
|
|
"\n",
|
|
"that satisfy the identities:\n",
|
|
"\n",
|
|
"$$\\delta_i \\delta_j = \\delta_{j-1} \\delta_i,\\; i<j$$\n",
|
|
"$$s_i s_j = s_{j+1} s_i,\\; i \\leq j$$\n",
|
|
"$$\\delta_i s_j = \\left\\{\\begin{matrix}\n",
|
|
"s_{j-1}\\delta_i,& i<j\\\\ \n",
|
|
"id, & i=j,j+1\\\\ \n",
|
|
"s_j\\delta_{i-1}, & i> j+1\n",
|
|
"\\end{matrix}\\right.$$\n",
|
|
"\n",
|
|
"We define the **simplicial cochain algebra** $A_{PL} = \\{(A_{PL})_n\\}_{n \\geq 0}$ by:\n",
|
|
"\n",
|
|
"The cochain algebra $(A_{PL})_n$ is given by:\n",
|
|
"$$(A_{PL})_n = \\frac{\\wedge(t_0, \\dots, t_n,y_0,\\dots, y_n)}{<\\sum{t_i}-1, \\sum{y_j}>}$$\n",
|
|
"\n",
|
|
"The face and degeneracy morphisms are the unique cochain algebra morphisms:\n",
|
|
"\n",
|
|
"$$\\delta_i: (A_{PL})_{n} \\rightarrow (A_{PL})_{n-1}, \\; 0 \\leq i \\leq n$$\n",
|
|
"\n",
|
|
"$$s_j: (A_{PL})_{n} \\rightarrow (A_{PL})_{n+1}, \\; 0 \\leq j \\leq n$$\n",
|
|
"\n",
|
|
"satisfying\n",
|
|
"\n",
|
|
"$$\\delta_i = t_k \\rightarrow \\left\\{\\begin{matrix}\n",
|
|
"t_k,& k<i\\\\ \n",
|
|
"0, & k=i\\\\ \n",
|
|
"t_{k-1}, & k>i\n",
|
|
"\\end{matrix}\\right. \\; \\; \\; \\;\\;\n",
|
|
"s_j = t_k \\rightarrow \\left\\{\\begin{matrix}\n",
|
|
"t_k,& k<j\\\\ \n",
|
|
"t_k+t_{k+1}, & k=j\\\\ \n",
|
|
"t_{k+1}, & k>j\n",
|
|
"\\end{matrix}\\right.$$\n",
|
|
"\n",
|
|
"## Implementation\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class SimplicialAplN(AplN, UniqueRepresentation):\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" The simplicial commutative cochain algebra Apl\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
"\n",
|
|
" def _base_repr(self):\n",
|
|
" \"\"\"\n",
|
|
" Return the base string representation of ``self``.\n",
|
|
" \"\"\"\n",
|
|
"\n",
|
|
" s = DifferentialGCAlgebra._base_repr(self)\n",
|
|
" old = '{}'.format(self._degrees)\n",
|
|
" new = '{}'.format([i[0] for i in self._degrees_multi])\n",
|
|
" return \"Simplicial \" + s.replace(old, new)\n",
|
|
"\n",
|
|
" class Element(AplN.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the simplicial commutative differential algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" def face_morphism(self,i):\n",
|
|
" \"\"\"\" \n",
|
|
" \n",
|
|
" Returns the morphism face 'i' of self\n",
|
|
" \n",
|
|
" INPUT::\n",
|
|
" \n",
|
|
" - i: A non-negative integer lower or equal to 'n'. Represents the face index\n",
|
|
" \n",
|
|
" OUTPUT::\n",
|
|
" \n",
|
|
" - A morphism of cochain algebras\n",
|
|
" \"\"\"\n",
|
|
" n = self.parent().n\n",
|
|
" if(n==0):\n",
|
|
" return 0\n",
|
|
" domain = self.parent()\n",
|
|
" codomain = SimplicialAlgebraplN(n-1)\n",
|
|
" tImages = []\n",
|
|
" yImages = []\n",
|
|
" n = len(domain.gens())//2\n",
|
|
" for k in range(n):\n",
|
|
" if(k<i):\n",
|
|
" tImages.append(codomain.gens()[k])\n",
|
|
" yImages.append(codomain.gens()[n-1+k])\n",
|
|
" elif(k==i):\n",
|
|
" tImages.append(0)\n",
|
|
" yImages.append(0)\n",
|
|
" elif(k>i):\n",
|
|
" tImages.append(codomain.gens()[k-1])\n",
|
|
" yImages.append(codomain.gens()[n+k-2])\n",
|
|
" images = tImages+yImages\n",
|
|
" return domain.hom(codomain=codomain,im_gens=images)\n",
|
|
" \n",
|
|
" def face(self,i):\n",
|
|
" \"\"\"\" \n",
|
|
" \n",
|
|
" Returns the face 'i' of self\n",
|
|
" \n",
|
|
" INPUT::\n",
|
|
" \n",
|
|
" - i: A non-negative integer lower or equal to 'n'. Represents the face index\n",
|
|
" \n",
|
|
" OUTPUT::\n",
|
|
" \n",
|
|
" - A polynomial that is the face 'i' of self\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" return self.face_morphism(i)(self)\n",
|
|
" \n",
|
|
" def degeneration_morphism(self,j):\n",
|
|
" \"\"\"\" \n",
|
|
" \n",
|
|
" Returns the morphism degeneration 'j' of self\n",
|
|
" \n",
|
|
" INPUT::\n",
|
|
" - j: A non-negative integer lower or equal to 'n'. Represents the degeneration index\n",
|
|
" \n",
|
|
" OUTPUT::\n",
|
|
" - A morphism of cochain algebras\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" n = self.parent().n\n",
|
|
" domain = self.parent()\n",
|
|
" codomain = SimplicialAlgebraplN(n+1)\n",
|
|
" if(j>n):\n",
|
|
" print(\"the degeneration index must be a non-negative number lower or equal to \"+str(n))\n",
|
|
" return False\n",
|
|
" elif(j<0):\n",
|
|
" print(\"the degeneration index must be non-negative\")\n",
|
|
" return False\n",
|
|
" else:\n",
|
|
" tImages = []\n",
|
|
" yImages = []\n",
|
|
" n = len(domain.gens())/2\n",
|
|
" for k in range(n):\n",
|
|
" if(k<j):\n",
|
|
" tImages.append(codomain.gens()[k])\n",
|
|
" yImages.append(codomain.gens()[n+1+k])\n",
|
|
" elif (k==j):\n",
|
|
" tImages.append(codomain.gens()[k]+codomain.gens()[k+1])\n",
|
|
" yImages.append(codomain.gens()[n+1+k]+codomain.gens()[n+1+k+1])\n",
|
|
" elif (k>j):\n",
|
|
" tImages.append(codomain.gens()[k+1])\n",
|
|
" yImages.append(codomain.gens()[n+1+k+1])\n",
|
|
" images = tImages+yImages\n",
|
|
" return domain.hom(codomain=codomain,im_gens=images)\n",
|
|
" \n",
|
|
" def degeneration(self,j):\n",
|
|
" \"\"\"\" \n",
|
|
" \n",
|
|
" Returns the degeneration 'j' of self\n",
|
|
" \n",
|
|
" INPUT::\n",
|
|
" - j: A non-negative integer lower or equal to 'n'. Represents the degeneration index\n",
|
|
" \n",
|
|
" OUTPUT::\n",
|
|
" - A polynomial that is the degeneration 'j' of self\n",
|
|
" \"\"\"\n",
|
|
" return self.degeneration_morphism(j)(self)\n",
|
|
" \n",
|
|
"def SimplicialAlgebraplN(n):\n",
|
|
" \"\"\"\n",
|
|
" Returns the graded commutative differential cochain algebra (Apl)_n as part of\n",
|
|
" the simplicial cochain algebra A_{PL}\n",
|
|
"\n",
|
|
" INPUT:\n",
|
|
"\n",
|
|
" - ``n`` -- A non-negative integer corresponding to the number of generators of degree 0.\n",
|
|
" \"\"\"\n",
|
|
"\n",
|
|
" if (n<0):\n",
|
|
" raise ValueError('`n` must be a non-negative integer')\n",
|
|
" ts = ['t'+str(t) for t in range(n+1)]\n",
|
|
" ys = ['y'+str(t) for t in range(n+1)]\n",
|
|
" degrees = tuple((n+1)*[(0,2)])+tuple((n+1)*[(1,2)])\n",
|
|
" gca = GradedCommutativeAlgebra(QQ, names=ts+ys, degrees=degrees)\n",
|
|
" differentials = {gca.gens_dict()[ts[i]]:gca.gens_dict()[ys[i]] for i in range(n+1)}\n",
|
|
" return SimplicialAplN(gca,differentials)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, t2, t3, t4, t5, y0, y1, y2, y3, y4, y5\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"s = SimplicialAlgebraplN(5)\n",
|
|
"s.inject_variables()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"True"
|
|
]
|
|
},
|
|
"execution_count": 25,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"p = t1+y2\n",
|
|
"p.degeneration(0).face(1)==p"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"True"
|
|
]
|
|
},
|
|
"execution_count": 26,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"m1 = p.degeneration(1).face_morphism(1)\n",
|
|
"m2 = p.degeneration_morphism(1)\n",
|
|
"(m1*m2).is_identity()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Adding new methods: propagate a simplex through the simplicial structure\n",
|
|
"\n",
|
|
"In this part, we want to obtain an homogeneous $(n+k)$-simplex of degree $n$, $p_{n+k} \\in (A_{PL})_{n+k}^n$, for $k>0$, where a given homogeneous $n$-simplex of degree $n$, $p_n \\in (A_{PL})_n^n$ is a face of $p_{n+k}$ of dimension $n$, and the rest of faces of dimension lower or equal to $n$ are $0$. We call this map **propagation**,denoted by $\\Gamma$ :\n",
|
|
"\n",
|
|
"$$\\Gamma_{n+k}^n: (A_{PL})_n^n \\rightarrow (A_{PL})_{n+k}^n$$\n",
|
|
"\n",
|
|
"Without lost of generality, we asume that our polynomial of degree $n$ is expressed as a polynomial in the variables $y_1,\\dots,y_n$. Let $p_n \\in (A_{PL})_n^n$ be the polynomial:\n",
|
|
"\n",
|
|
"$$p_n = q_t y_{1} \\dots y_{n}$$\n",
|
|
"\n",
|
|
"$$q_t \\in \\mathbb{Q}[t_0,\\dots,t_n]$$\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"Let $I$ be the index set $\\{0,\\dots, n+k\\}$. For some subsets $(i_1, \\dots, i_k) \\subset I$ we know by definition that \n",
|
|
"\n",
|
|
"$$p_n = \\delta_{i_1} \\dots \\delta_{i_k} \\Gamma_{n+k}^n(p_n)$$\n",
|
|
"\n",
|
|
"and due to the relations between face morphisms, we know that we can chose a unique subset $(i_1, \\dots, i_k)$ in a way that $i_1 < \\dots < i_k$.\n",
|
|
"\n",
|
|
"Just to point the definition, notice that any other combination of faces $\\delta_{j_1} \\dots \\delta_{j_k}$ not equivalent to $\\delta_{i_1} \\dots \\delta_{i_k}$ (i.e., applying the relations between face morphisms), makes the result:\n",
|
|
"\n",
|
|
"$$\\delta_{j_1} \\dots \\delta_{j_k}\\Gamma_{n+k}^n(p_n) = 0$$\n",
|
|
"\n",
|
|
"Let $J=\\{j_0,\\dots,j_n\\} \\subset I$ be the subset $\\{i_1, \\dots, i_k\\}^C$, i.e., those elements of $I$ $\\notin \\{i_1, \\dots, i_k\\}$, and where $j_l < j_m$, for $l<m$.\n",
|
|
"\n",
|
|
"Just before defining the propagation morphism, we define the morphism $\\Upsilon$ as:\n",
|
|
"\n",
|
|
"\\begin{align}\n",
|
|
" \\Upsilon: \\mathbb{Q}[t_0,\\dots, t_n] & \\longrightarrow \\mathbb{Q}[t_0, \\dots, t_{n+k}] \\\\\n",
|
|
" t_i & \\rightarrow t_{j_i}\n",
|
|
"\\end{align}\n",
|
|
"\n",
|
|
"$$j_i \\in J$$\n",
|
|
"\n",
|
|
"\n",
|
|
"Now we can define the propagation map $\\Gamma_{n+k}^n$ as:\n",
|
|
"\n",
|
|
"\n",
|
|
"$$\\Gamma_{n+k}^n(p_n) = \\Upsilon(q_t)\\sum_{k=0}^{n}{(-1)^{n-k} t_{j_{n-k}}(y_{j_0}\\dots \\widehat{y_{j_{n-k}}} \\dots y_{j_n})}$$\n",
|
|
"\n",
|
|
"where $\\widehat{y_{j}}$ means that we have removed the variable $y_{j}$.\n",
|
|
"\n",
|
|
"## Implementation\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class SimplicialAplN(SimplicialAplN,UniqueRepresentation):\n",
|
|
" class Element(SimplicialAplN.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the commutative differential multi-graded algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" def propagate(self, face_list, dest_dim):\n",
|
|
" \"\"\"\n",
|
|
" Returns a polynomial in dimension 'dest_dim' that has 'self' as a face \n",
|
|
"\n",
|
|
" INPUT:\n",
|
|
" - face_list: indexes of the elements that form the face of the simplex we want to propagate\n",
|
|
" - dest_dim: Dimension of the codomain cochain algebra\n",
|
|
" - EXAMPLE: s = SimplicialAlgebraplN(2)\n",
|
|
" s.inject_variables()\n",
|
|
" p = (t1^2+t2^2)*y1*y2\n",
|
|
" p.propagate2([0,1,2],3)\n",
|
|
" 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\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" if not (self.is_homogeneous() and self.total_degree()==self.parent().n):\n",
|
|
" raise ValueError(\"The polynomial is not homogeneous of maximum degree.\")\n",
|
|
" self_dim = self.parent().n\n",
|
|
" indexes = list(range(self_dim+1))\n",
|
|
" apl = SimplicialAlgebraplN(dest_dim)\n",
|
|
" y_gens = [apl.gens()[dest_dim+1+i] for i in face_list]\n",
|
|
" t_gens = [apl.gens()[i] for i in face_list]\n",
|
|
" graded_part = apl(0)\n",
|
|
" for i in reversed(indexes):\n",
|
|
" t = t_gens[i]\n",
|
|
" y_prod = copy.deepcopy(y_gens)\n",
|
|
" del y_prod[i]\n",
|
|
" y_prod = prod(y_prod)\n",
|
|
" graded_part += ((-1)**i)*t*y_prod#((-1)**(simplex_dim+i))*t*y_prod\n",
|
|
" terms = self.dict()\n",
|
|
" coeff_in_t = apl(0)\n",
|
|
" for exp in terms.keys():\n",
|
|
" coef = terms[exp]\n",
|
|
" ts_exp = exp[:self_dim+1]\n",
|
|
" coeff_in_t += coef*prod(list(map(lambda t, e: t^e, t_gens, ts_exp)))\n",
|
|
" return coeff_in_t*graded_part"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Example\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 43,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, t2, y0, y1, y2\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"s = SimplicialAlgebraplN(2)\n",
|
|
"s.inject_variables()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 51,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"t5^2*t7*y1*y5 + t7^3*y1*y5 - t5^3*y1*y7 - t5*t7^2*y1*y7 + t1*t5^2*y5*y7 + t1*t7^2*y5*y7\n",
|
|
"True\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"p = (t1^2+t2^2)*y1*y2\n",
|
|
"q = p.propagate([1,5,7],10)\n",
|
|
"print(q)\n",
|
|
"print(q.face(10).face(9).face(8).face(6).face(4).face(3).face(2).face(0).reduce() == p)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"True\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"q1 = p.propagate([1,5,7],10)\n",
|
|
"q2 = p.propagate([0,4,6],9)\n",
|
|
"print(q1.face(0).reduce() == q2.reduce())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, y0, y1\n",
|
|
"-t2*y1 + t1*y2\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"y2"
|
|
]
|
|
},
|
|
"execution_count": 31,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# tests torus (remove cell)\n",
|
|
"s = SimplicialAlgebraplN(1)\n",
|
|
"s.inject_variables()\n",
|
|
"p = y1\n",
|
|
"F1a = p.propagate([0,1],2)\n",
|
|
"F2a = p.propagate([1,2],2)\n",
|
|
"F1c = p.propagate([0,2],2)\n",
|
|
"F2c = p.propagate([0,2],2)\n",
|
|
"print((F2a).reduce())\n",
|
|
"C1F1 = F1a+F1c\n",
|
|
"C1F2 = F2a+F2c\n",
|
|
"C1F2.reduce()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, y0, y1\n",
|
|
"-t1*y0 - t2*y0 + t0*y1 + t0*y2\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"y2"
|
|
]
|
|
},
|
|
"execution_count": 32,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# tests torus (remove cell)\n",
|
|
"s = SimplicialAlgebraplN(1)\n",
|
|
"s.inject_variables()\n",
|
|
"p = y1\n",
|
|
"F1b = p.propagate([1,2],2)\n",
|
|
"F2b = p.propagate([0,1],2)\n",
|
|
"F1c = p.propagate([0,2],2)\n",
|
|
"F2c = p.propagate([0,2],2)\n",
|
|
"print((F2b+F2c))\n",
|
|
"C2F1 = F1b+F1c\n",
|
|
"C2F2 = F2b+F2c\n",
|
|
"C2F1.reduce()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# The cochain algebra $A_{PL}(K)$\n",
|
|
"This class implements the cochain algebra $A_{PL}(K)$. For more information, see [Rational homotopy theory, Felix, Halperin, Thomas, chapter 10.c)].\n",
|
|
"\n",
|
|
"## Definition\n",
|
|
"\n",
|
|
"Let $K$ be a simplicial set, and let $A_{PL} = \\{(A_{PL})_n\\}_{n \\geq 0}$ be the simplicial cochain algebra defined earlier. Then\n",
|
|
"\n",
|
|
"$$ A_{PL}(K) = \\{A_{PL}^p(K)\\}_{p \\geq 0}$$\n",
|
|
"\n",
|
|
"is the cochain algebra defined as follows:\n",
|
|
"\n",
|
|
"- $A_{PL}^p(K)$ is the set of simplicial set morphisms from $K$ to $A_{PL}^p$. Thus, an element $\\Phi \\in A_{PL}^p(K)$ is a mapping that assings to each $n$-simplex $\\sigma \\in K_n$ an element $\\Phi_\\sigma \\in (A_{PL}^p)_n$, such that\n",
|
|
"\n",
|
|
"$$ \\Phi_{\\delta_i(\\sigma)}=\\delta_i(\\Phi_\\sigma)$$\n",
|
|
"\n",
|
|
"$$ \\Phi_{s_j(\\sigma)}=s_j(\\Phi_\\sigma)$$\n",
|
|
"\n",
|
|
"- Addition, scalar multiplication and the differential are given by\n",
|
|
"$$ (\\Phi+\\Psi)_\\sigma = \\Phi_\\sigma + \\Psi_\\sigma$$\n",
|
|
"\n",
|
|
"$$ (\\lambda \\Phi)_\\sigma = \\lambda \\Phi_\\sigma$$\n",
|
|
"\n",
|
|
"$$ (d\\Phi)_\\sigma = d(\\Phi_\\sigma)$$\n",
|
|
"\n",
|
|
"- As $A_{PL}$ is a simplicial cochain algebra, multiplication in $A_{PL}(K)$ is given by\n",
|
|
"\n",
|
|
"$$ (\\Phi \\Psi)_\\sigma = \\Phi_\\sigma \\Psi_\\sigma$$ \n",
|
|
"\n",
|
|
"## Implementation"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 33,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from sage.structure.parent import Parent\n",
|
|
"from sage.structure.element import Element\n",
|
|
"from sage.structure.richcmp import rich_to_bool, op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE\n",
|
|
"\n",
|
|
"\n",
|
|
"class AlgebraAplK(UniqueRepresentation, Parent):\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" The graded commutative differential cochain algebra Apl(K)\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" def __init__(self,simplicial_complex, category=None):\n",
|
|
" \"\"\"\n",
|
|
" The constructor of Apl(K)\n",
|
|
"\n",
|
|
" INPUT:\n",
|
|
" - simplicial_complex: The simplicial complex used to build the algebra\n",
|
|
"\n",
|
|
" \"\"\"\n",
|
|
" self.K = simplicial_complex\n",
|
|
" self.n = simplicial_complex.dimension()\n",
|
|
" Parent.__init__(self,category=category)\n",
|
|
" f = MorphismFromQQToAplK(self)\n",
|
|
" self.register_coercion(f)\n",
|
|
" \n",
|
|
" def _repr_(self):\n",
|
|
" \"\"\"\n",
|
|
" Return the base string representation of ``self``.\n",
|
|
" \"\"\"\n",
|
|
" return \"The graded commutative differential cochain algebra Apl(K) of %s\" % self.K\n",
|
|
" \n",
|
|
" def _element_constructor_(self,values):\n",
|
|
" \"\"\"\n",
|
|
" The constructor of an element of this class\n",
|
|
" \"\"\"\n",
|
|
" return self.element_class(self,values)\n",
|
|
" \n",
|
|
" def dimension(self):\n",
|
|
" \"\"\"\n",
|
|
" The dimension of the algebra. It is equivalent to the maximum degree possible that a non-null element of this algebra can take.\n",
|
|
" \"\"\"\n",
|
|
" return self.n\n",
|
|
" \n",
|
|
" def simplicialComplex(self):\n",
|
|
" \"\"\"\n",
|
|
" The simplicial complex of this algebra.\n",
|
|
" \"\"\"\n",
|
|
" return self.K\n",
|
|
" \n",
|
|
" def _n_cells_sorted(self,n):\n",
|
|
" \"\"\"\n",
|
|
" Returns all simplices of dimension 'n', as a sorted list.\n",
|
|
" \"\"\"\n",
|
|
" return self.K._n_cells_sorted(n)\n",
|
|
" \n",
|
|
" def _faces_of_length(self, simplex, length):\n",
|
|
" \"\"\"\n",
|
|
" Returns all faces of dimension 'length' for a given simplex\n",
|
|
" \"\"\"\n",
|
|
" return [tuple(e) for e in Set(simplex).subsets(length)]\n",
|
|
" \n",
|
|
" def null_element(self):\n",
|
|
" \"\"\"\n",
|
|
" Returns the null element of the algebra respect to the addition operation\n",
|
|
" \"\"\"\n",
|
|
" values = {}\n",
|
|
" for i in range(self.K.dimension()+1):\n",
|
|
" s = SimplicialAlgebraplN(i)\n",
|
|
" for f in self.K._n_cells_sorted(i):\n",
|
|
" values[tuple(f)]=s(0)\n",
|
|
" return self._element_constructor_(values)\n",
|
|
"\n",
|
|
" class Element(Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the simplicial commutative differential algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
" def __init__(self, parent, values):\n",
|
|
" Element.__init__(self,parent)\n",
|
|
" self.elements = values\n",
|
|
" \n",
|
|
" def _repr_(self):\n",
|
|
" \"\"\"\n",
|
|
" Return the base string representation of ``self``.\n",
|
|
" \"\"\"\n",
|
|
" return str(self.elements)\n",
|
|
" \n",
|
|
" def dimension(self):\n",
|
|
" \"\"\"\n",
|
|
" Returns the dimension where 'self' lives\n",
|
|
" \"\"\"\n",
|
|
" return self.parent().dimension()\n",
|
|
" \n",
|
|
" \n",
|
|
" def _add_(self,other):\n",
|
|
" \"\"\"\n",
|
|
" Addition operation\n",
|
|
" \"\"\"\n",
|
|
" C = self.__class__\n",
|
|
" if(self.elements.keys()!=other.elements.keys()):\n",
|
|
" raise ValueError(\"error: keys do not match\")\n",
|
|
" newValues = {}\n",
|
|
" for k in self.elements.keys():\n",
|
|
" newValues[k] = self.elements[k]+other.elements[k]\n",
|
|
" return C(self.parent(),newValues)\n",
|
|
"\n",
|
|
" def _sub_(self,other):\n",
|
|
" \"\"\"\n",
|
|
" Substration operation\n",
|
|
" \"\"\"\n",
|
|
" C = self.__class__\n",
|
|
" if(self.elements.keys()!=other.elements.keys()):\n",
|
|
" raise ValueError(\"error: keys do not match\")\n",
|
|
" newValues = {}\n",
|
|
" for k in self.elements.keys():\n",
|
|
" newValues[k] = self.elements[k]-other.elements[k]\n",
|
|
" return C(self.parent(),newValues)\n",
|
|
" \n",
|
|
" def _mul_(self,other):\n",
|
|
" \"\"\"\n",
|
|
" Multiplication operation\n",
|
|
" \"\"\"\n",
|
|
" C = self.__class__\n",
|
|
" if(self.elements.keys()!=other.elements.keys()):\n",
|
|
" raise ValueError(\"error: keys do not match\")\n",
|
|
" newValues = {}\n",
|
|
" for k in self.elements.keys():\n",
|
|
" newValues[k] = self.elements[k]*other.elements[k]\n",
|
|
" return C(self.parent(),newValues)\n",
|
|
" \n",
|
|
" def __pow__(self, n):\n",
|
|
" \"\"\"\n",
|
|
" Return ``self`` raised to the power ``n``.\n",
|
|
" \"\"\"\n",
|
|
" C = self.__class__\n",
|
|
" newValues = {}\n",
|
|
" for k in self.elements.keys():\n",
|
|
" newValues[k] = self.elements[k]**n\n",
|
|
" return C(self.parent(),newValues)\n",
|
|
" \n",
|
|
"\n",
|
|
" def _richcmp_(self, other, op):\n",
|
|
" \"\"\"\n",
|
|
" Comparison operations. Only implemented equality operations (EQ and NE)\n",
|
|
" \"\"\"\n",
|
|
" if(op==op_EQ):\n",
|
|
" if(self.elements.keys()!=other.elements.keys()):\n",
|
|
" return False\n",
|
|
" for k in self.elements.keys():\n",
|
|
" if(self.elements[k]!=other.elements[k]):\n",
|
|
" return False\n",
|
|
" return True\n",
|
|
" elif(op==op_NE):\n",
|
|
" return not self._richcmp_(other,op_EQ)\n",
|
|
" else:\n",
|
|
" raise NotImplementedError(\"operation not implemented for this element class\")\n",
|
|
"\n",
|
|
" \n",
|
|
"class MorphismFromQQToAplK(Morphism):\n",
|
|
"\n",
|
|
" def __init__(self, codomain):\n",
|
|
" self.simplicialComplex = codomain.K\n",
|
|
" Morphism.__init__(self, QQ, codomain)\n",
|
|
"\n",
|
|
" def _call_(self, x):\n",
|
|
" S = self.simplicialComplex\n",
|
|
" params = {}\n",
|
|
" for d in range(S.dimension()+1):\n",
|
|
" s = SimplicialAlgebraplN(d)\n",
|
|
" for c in S._n_cells_sorted(d):\n",
|
|
" params[tuple(c)]=s(x)\n",
|
|
" A = AlgebraAplK(S)\n",
|
|
" return AlgebraAplK.Element(A, params) "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Example"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 34,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"The graded commutative differential cochain algebra Apl(K) of Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1, 2)}"
|
|
]
|
|
},
|
|
"execution_count": 34,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2]],is_mutable=False)\n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"A"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 35,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 0, (1,): 0, (2,): 0, (0, 1): 0, (0, 2): 0, (1, 2): 1, (0, 1, 2): 0}"
|
|
]
|
|
},
|
|
"execution_count": 35,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"values = {(0,): 0, (1,): 0, (2,):0, (0,1): 0, (0,2): 0, (1,2): 1, (0,1,2):0}\n",
|
|
"A._element_constructor_(values)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 36,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"values1 = {(0,): 0, (1,): 0, (2,):0, (0,1): 0, (0,2): 0, (1,2): 1, (0,1,2):0}\n",
|
|
"e1 = A._element_constructor_(values1)\n",
|
|
"values2 = {(0,): 0, (1,): 0, (2,):0, (0,1): 0, (0,2): 0, (1,2): 1, (0,1,2):0}\n",
|
|
"e2 = A._element_constructor_(values2)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 37,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 0, (1,): 0, (2,): 0, (0, 1): 0, (0, 2): 0, (1, 2): 0, (0, 1, 2): 0}"
|
|
]
|
|
},
|
|
"execution_count": 37,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"e1-e2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 38,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"True"
|
|
]
|
|
},
|
|
"execution_count": 38,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"(e1-e2)==A.null_element()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 39,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 0, (1,): 0, (2,): 0, (0, 1): 0, (0, 2): 0, (1, 2): 3, (0, 1, 2): 0}"
|
|
]
|
|
},
|
|
"execution_count": 39,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"3*e1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 40,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[(0, 1), (0, 2), (1, 2)]"
|
|
]
|
|
},
|
|
"execution_count": 40,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"simplex = S._n_cells_sorted(2)[0]\n",
|
|
"A._faces_of_length(simplex,2)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Adding methods: reduce polynomials by relations\n",
|
|
"\n",
|
|
"As the algebra $(A_{PL})_n$ is not freely generated, it could be that two apparently different elements of $A_{PL}(K)$ correspond actually to the same element in the algebra. In order to compare properly elements of the algebra, it is added a new method called _\"reduce\"_ that, $\\forall n \\geq 0$, applies the relations of $(A_{PL})_n$ to every polynomial in $ \\Phi \\in A_{PL}(K)$ in a particular way that makes the representation of every class of elements unique."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 41,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AlgebraAplK(AlgebraAplK, UniqueRepresentation):\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" The graded commutative differential cochain algebra Apl(K)\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" class Element(AlgebraAplK.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the simplicial commutative differential algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" def __init__(self, parent, values):\n",
|
|
" Element.__init__(self,parent)\n",
|
|
" self.elements = values\n",
|
|
" self.elements = self._reduce(values) \n",
|
|
" \n",
|
|
" def _reduce(self, values):\n",
|
|
" \"\"\"\n",
|
|
" Returns the polynomials given as input, after applying the corresponding relations \n",
|
|
" of the algebra where each polynomial belongs.\n",
|
|
" \n",
|
|
" INPUT:\n",
|
|
" - values: a dictionary where the values are polynomials in (Apl)n\n",
|
|
" \"\"\"\n",
|
|
" reduced_values = {}\n",
|
|
" for k in values.keys():\n",
|
|
" n = len(k)-1\n",
|
|
" reduced_values[k] = values[k].reduce()\n",
|
|
" return reduced_values\n",
|
|
" "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Example"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 42,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"The graded commutative differential cochain algebra Apl(K) of Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1, 2)}"
|
|
]
|
|
},
|
|
"execution_count": 42,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2]],is_mutable=False)\n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"A"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 43,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, t2, t3, y0, y1, y2, y3\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): y0*y1*y2*y3,\n",
|
|
" (1,): 0,\n",
|
|
" (2,): 0,\n",
|
|
" (0, 1): t1,\n",
|
|
" (0, 2): y0,\n",
|
|
" (1, 2): t0,\n",
|
|
" (0, 1, 2): 0}"
|
|
]
|
|
},
|
|
"execution_count": 43,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"s = SimplicialAlgebraplN(3)\n",
|
|
"s.inject_variables()\n",
|
|
"values = {(0,): y0*y1*y2*y3, (1,): s(0), (2,): s(0), (0,1): t1, (0,2): y0, (1,2): t0, (0,1,2): s(0)}\n",
|
|
"values"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 44,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 0, (1,): 0, (2,): 0, (0, 1): t1, (0, 2): -y1 - y2 - y3, (1, 2): -t1 - t2 - t3 + 1, (0, 1, 2): 0}"
|
|
]
|
|
},
|
|
"execution_count": 44,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"e1 = A._element_constructor_(values)\n",
|
|
"e1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Adding new methods: Check if a given assignation respects the simplicial structure\n",
|
|
"\n",
|
|
"During the construction of an element of $A_{PL}(K)$, it is important to be sure that a given assignation of polynomials to our simplicial complex respects the simplicial structure. For that reason, a method called _\"check\"_ is added. The method verifies the following condition:\n",
|
|
"\n",
|
|
"$$\\Phi (\\delta_i \\sigma) = \\delta_i \\Phi (\\sigma)$$\n",
|
|
"\n",
|
|
"$$\\forall \\sigma \\in K_{n}, n \\geq 1$$ \n",
|
|
"$$0 \\leq i \\leq n$$"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 45,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AlgebraAplK(AlgebraAplK, UniqueRepresentation):\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" The graded commutative differential cochain algebra Apl(K)\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" class Element(AlgebraAplK.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the simplicial commutative differential algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" def __init__(self, parent, values):\n",
|
|
" Element.__init__(self,parent)\n",
|
|
" self.elements = values\n",
|
|
" self.elements = self._reduce(values) \n",
|
|
" self.check() \n",
|
|
"\n",
|
|
" def check(self):\n",
|
|
" \"\"\"\n",
|
|
" Checks if the initial assignation respects the simplicial structure. For every simplex S, the algorithm checks \n",
|
|
" if the polynomial assigned to each face of S is equal to the same face of the polynomial assigned to S.\n",
|
|
" \"\"\"\n",
|
|
" S = self.parent().simplicialComplex()\n",
|
|
" dim = S.dimension()\n",
|
|
" for n in range(1,dim+1):\n",
|
|
" #print(\"Checking dimension \" + str(n))\n",
|
|
" for simplex in S._n_cells_sorted(n):\n",
|
|
" for f in range(n+1):\n",
|
|
" sFace = tuple(S.face(simplex,f))\n",
|
|
" aFace = self.elements[simplex.tuple()].face(f).reduce()\n",
|
|
" #print(\"face: \" + str(f),\"simplex: \" + str(simplex),\"sFace: \" + str(self.elements[sFace]), \"aFace: \" + str(aFace))\n",
|
|
" if(self.elements[sFace] != aFace):\n",
|
|
" raise ValueError(\"the assignation is not valid\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Example"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 46,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"The graded commutative differential cochain algebra Apl(K) of Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1, 2)}"
|
|
]
|
|
},
|
|
"execution_count": 46,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2]],is_mutable=False)\n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"A"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 47,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, y0\n",
|
|
"Defining t0, t1, y0, y1\n",
|
|
"Defining t0, t1, t2, y0, y1, y2\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 2, (1,): 1, (2,): 3, (0, 1): -t1 + 2, (0, 2): t1 + 2, (1, 2): 2*t1 + 1, (0, 1, 2): -t1 + t2 + 2}"
|
|
]
|
|
},
|
|
"execution_count": 47,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"s0 = SimplicialAlgebraplN(0)\n",
|
|
"s0.inject_variables()\n",
|
|
"p0 = s0(2)\n",
|
|
"p1 = s0(1)\n",
|
|
"p2 = s0(3)\n",
|
|
"s1 = SimplicialAlgebraplN(1)\n",
|
|
"s1.inject_variables()\n",
|
|
"p01 = 2*t0+t1\n",
|
|
"p02 = 2*t0+3*t1\n",
|
|
"p12 = t0+3*t1\n",
|
|
"s2 = SimplicialAlgebraplN(2)\n",
|
|
"s2.inject_variables()\n",
|
|
"p012 = 2-t1+t2\n",
|
|
"values = {(0,): p0, (1,): p1, (2,): p2, (0,1): p01, (0,2): p02, (1,2): p12, (0,1,2): p012}\n",
|
|
"e1 = A._element_constructor_(values)\n",
|
|
"e1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 48,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[[], [0], [1], [0, 1], [2], [0, 2], [1, 2], [0, 1, 2]]"
|
|
]
|
|
},
|
|
"execution_count": 48,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"simplex = S._n_cells_sorted(2)[0]\n",
|
|
"list(powerset(simplex))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Adding new methods: Differential\n",
|
|
"\n",
|
|
"As mentioned in the definition of $A_{PL}(K)$, the differential of $\\Phi \\in A_{PL}(K)$ is defined as \n",
|
|
"\n",
|
|
"$$(d\\Phi) (\\sigma) = d(\\Phi (\\sigma))$$"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 49,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AlgebraAplK(AlgebraAplK, UniqueRepresentation):\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" The graded commutative differential cochain algebra Apl(K)\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" class Element(AlgebraAplK.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the simplicial commutative differential algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
" def differential(self):\n",
|
|
" \"\"\"\n",
|
|
" Returns the differential of 'self'\n",
|
|
" \"\"\"\n",
|
|
" C = self.__class__\n",
|
|
" newValues = {}\n",
|
|
" for k in self.elements.keys():\n",
|
|
" newValues[k] = self.elements[k].differential()\n",
|
|
" return C(self.parent(),newValues)\n",
|
|
" \n",
|
|
" def is_closed(self):\n",
|
|
" \"\"\"\n",
|
|
" Returns 'True' if 'self' is closed, i.e., its differential is zero.\n",
|
|
" \"\"\"\n",
|
|
" diff = self.differential()\n",
|
|
" if(diff == self.parent().null_element()):\n",
|
|
" return True\n",
|
|
" else:\n",
|
|
" return False"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Example"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 50,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"The graded commutative differential cochain algebra Apl(K) of Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1, 2)}"
|
|
]
|
|
},
|
|
"execution_count": 50,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2]],is_mutable=False)\n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"A"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 51,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, y0\n",
|
|
"Defining t0, t1, y0, y1\n",
|
|
"Defining t0, t1, t2, y0, y1, y2\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 2, (1,): 1, (2,): 3, (0, 1): -t1 + 2, (0, 2): t1 + 2, (1, 2): 2*t1 + 1, (0, 1, 2): -t1 + t2 + 2}"
|
|
]
|
|
},
|
|
"execution_count": 51,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"s0 = SimplicialAlgebraplN(0)\n",
|
|
"s0.inject_variables()\n",
|
|
"p0 = s0(2)\n",
|
|
"p1 = s0(1)\n",
|
|
"p2 = s0(3)\n",
|
|
"s1 = SimplicialAlgebraplN(1)\n",
|
|
"s1.inject_variables()\n",
|
|
"p01 = 2*t0+t1\n",
|
|
"p02 = 2*t0+3*t1\n",
|
|
"p12 = t0+3*t1\n",
|
|
"s2 = SimplicialAlgebraplN(2)\n",
|
|
"s2.inject_variables()\n",
|
|
"p012 = 2-t1+t2\n",
|
|
"values = {(0,): p0, (1,): p1, (2,): p2, (0,1): p01, (0,2): p02, (1,2): p12, (0,1,2): p012}\n",
|
|
"e1 = A._element_constructor_(values)\n",
|
|
"e1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 52,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 0, (1,): 0, (2,): 0, (0, 1): -y1, (0, 2): y1, (1, 2): 2*y1, (0, 1, 2): -y1 + y2}"
|
|
]
|
|
},
|
|
"execution_count": 52,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"e1.differential()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 53,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"False"
|
|
]
|
|
},
|
|
"execution_count": 53,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"e1.is_closed()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 54,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"True"
|
|
]
|
|
},
|
|
"execution_count": 54,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"e1.differential().is_closed()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Adding new methods: Homogeneity"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 55,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AlgebraAplK(AlgebraAplK, UniqueRepresentation):\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" The graded commutative differential cochain algebra Apl(K)\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" class Element(AlgebraAplK.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the simplicial commutative differential algebra (Apl)n.\n",
|
|
" \"\"\" \n",
|
|
"\n",
|
|
" def homogeneous_part(self,degree):\n",
|
|
" \"\"\"\n",
|
|
" Returns the homogeneous component of grade 'degree' of 'self'\n",
|
|
" \"\"\"\n",
|
|
" C = self.__class__\n",
|
|
" part = {}\n",
|
|
" for k in self.elements.keys():\n",
|
|
" s = SimplicialAlgebraplN(len(k)-1)\n",
|
|
" part[k] = s(self.elements[k].homogeneous_part(degree=degree))\n",
|
|
" return C(self.parent(),part)\n",
|
|
"\n",
|
|
" def homogeneous_parts(self):\n",
|
|
" \"\"\"\n",
|
|
" Returns all graded components of 'self'\n",
|
|
" \"\"\"\n",
|
|
" parts = {}\n",
|
|
" for n in range(self.dimension()+1):\n",
|
|
" hom_part = self.homogeneous_part(degree=n)\n",
|
|
" if hom_part != self.parent().null_element():\n",
|
|
" parts[n] = hom_part\n",
|
|
" return parts\n",
|
|
"\n",
|
|
" def is_homogeneous(self):\n",
|
|
" \"\"\"\n",
|
|
" Returns 'True' if self is composed by homogeneous polynomials of the same degree\n",
|
|
" \"\"\"\n",
|
|
" isHomogeneous = True\n",
|
|
" S = self.parent().simplicialComplex()\n",
|
|
" dim = S.dimension()\n",
|
|
" for n in range(dim+1):\n",
|
|
" for simplex in S._n_cells_sorted(n):\n",
|
|
" pol = self.elements[simplex.tuple()]\n",
|
|
" if pol:\n",
|
|
" isHomogeneous = isHomogeneous and pol.is_homogeneous()\n",
|
|
" if not isHomogeneous:\n",
|
|
" break\n",
|
|
" if not isHomogeneous:\n",
|
|
" break\n",
|
|
" return isHomogeneous\n",
|
|
" \n",
|
|
" def degree(self):\n",
|
|
" if not self.is_homogeneous():\n",
|
|
" return -1\n",
|
|
" else:\n",
|
|
" degree = -1\n",
|
|
" for e in self.elements.values():\n",
|
|
" if e:\n",
|
|
" degree = e.degree()[0]\n",
|
|
" break\n",
|
|
" return degree\n",
|
|
" "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Examples"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 56,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"The graded commutative differential cochain algebra Apl(K) of Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1, 2)}"
|
|
]
|
|
},
|
|
"execution_count": 56,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2]],is_mutable=False)\n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"A"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 57,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, y0\n",
|
|
"Defining t0, t1, y0, y1\n",
|
|
"Defining t0, t1, t2, y0, y1, y2\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 2, (1,): 1, (2,): 3, (0, 1): -t1 + 2, (0, 2): t1 + 2, (1, 2): 2*t1 + 1, (0, 1, 2): -t1 + t2 + 2}"
|
|
]
|
|
},
|
|
"execution_count": 57,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"s0 = SimplicialAlgebraplN(0)\n",
|
|
"s0.inject_variables()\n",
|
|
"p0 = s0(2)\n",
|
|
"p1 = s0(1)\n",
|
|
"p2 = s0(3)\n",
|
|
"s1 = SimplicialAlgebraplN(1)\n",
|
|
"s1.inject_variables()\n",
|
|
"p01 = 2*t0+t1\n",
|
|
"p02 = 2*t0+3*t1\n",
|
|
"p12 = t0+3*t1\n",
|
|
"s2 = SimplicialAlgebraplN(2)\n",
|
|
"s2.inject_variables()\n",
|
|
"p012 = 2-t1+t2\n",
|
|
"values = {(0,): p0, (1,): p1, (2,): p2, (0,1): p01, (0,2): p02, (1,2): p12, (0,1,2): p012}\n",
|
|
"e1 = A._element_constructor_(values)\n",
|
|
"e1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 58,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"True"
|
|
]
|
|
},
|
|
"execution_count": 58,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"e1.is_homogeneous()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 59,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{0: {(0,): 2, (1,): 1, (2,): 3, (0, 1): -t1 + 2, (0, 2): t1 + 2, (1, 2): 2*t1 + 1, (0, 1, 2): -t1 + t2 + 2}}"
|
|
]
|
|
},
|
|
"execution_count": 59,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"e1.homogeneous_parts()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 60,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 2, (1,): 1, (2,): 3, (0, 1): -t1 + 2, (0, 2): t1 + 2, (1, 2): 2*t1 + 1, (0, 1, 2): -t1*y1*y2 - t2*y1*y2 - t1^2*y2 - t1*t2*y2 + y1*y2 + t1*y2 - t1 + t2 + 2}"
|
|
]
|
|
},
|
|
"execution_count": 60,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"values = {(0,): p0, (1,): p1, (2,): p2, (0,1): p01, (0,2): p02, (1,2): p12, (0,1,2): p012+t0*y1*y2+t0*t1*y2}\n",
|
|
"e2 = A._element_constructor_(values)\n",
|
|
"e2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 61,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"False"
|
|
]
|
|
},
|
|
"execution_count": 61,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"e2.is_homogeneous()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 62,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{0: {(0,): 2, (1,): 1, (2,): 3, (0, 1): -t1 + 2, (0, 2): t1 + 2, (1, 2): 2*t1 + 1, (0, 1, 2): -t1 + t2 + 2},\n",
|
|
" 1: {(0,): 0, (1,): 0, (2,): 0, (0, 1): 0, (0, 2): 0, (1, 2): 0, (0, 1, 2): -t1^2*y2 - t1*t2*y2 + t1*y2},\n",
|
|
" 2: {(0,): 0, (1,): 0, (2,): 0, (0, 1): 0, (0, 2): 0, (1, 2): 0, (0, 1, 2): -t1*y1*y2 - t2*y1*y2 + y1*y2}}"
|
|
]
|
|
},
|
|
"execution_count": 62,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"e2.homogeneous_parts()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 63,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"True"
|
|
]
|
|
},
|
|
"execution_count": 63,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"sum(e2.homogeneous_parts().values())==e2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Adding new methods: Skeleton"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 64,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AlgebraAplK(AlgebraAplK, UniqueRepresentation):\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" The graded commutative differential cochain algebra Apl(K)\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" class Element(AlgebraAplK.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the simplicial commutative differential algebra (Apl)n.\n",
|
|
" \"\"\" \n",
|
|
" def get_skeleton(self, dim):\n",
|
|
" \n",
|
|
" values = {}\n",
|
|
" facets = self._get_elements_of_dimension(dim)\n",
|
|
" for i in range(dim+1):\n",
|
|
" values.update(self._get_elements_of_dimension(i))\n",
|
|
" S = SimplicialComplex(list(facets.keys()),is_mutable=False)\n",
|
|
" A = AlgebraAplK(S)\n",
|
|
" return A._element_constructor_(values)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Example"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 65,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, y0\n",
|
|
"Defining t0, t1, y0, y1\n",
|
|
"Defining t0, t1, t2, y0, y1, y2\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 2, (1,): 1, (2,): 3, (0, 1): -t1 + 2, (0, 2): t1 + 2, (1, 2): 2*t1 + 1, (0, 1, 2): -t1*y1*y2 - t2*y1*y2 - t1^2*y2 - t1*t2*y2 + y1*y2 + t1*y2 - t1 + t2 + 2}"
|
|
]
|
|
},
|
|
"execution_count": 65,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2]],is_mutable=False)\n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"s0 = SimplicialAlgebraplN(0)\n",
|
|
"s0.inject_variables()\n",
|
|
"p0 = s0(2)\n",
|
|
"p1 = s0(1)\n",
|
|
"p2 = s0(3)\n",
|
|
"s1 = SimplicialAlgebraplN(1)\n",
|
|
"s1.inject_variables()\n",
|
|
"p01 = 2*t0+t1\n",
|
|
"p02 = 2*t0+3*t1\n",
|
|
"p12 = t0+3*t1\n",
|
|
"s2 = SimplicialAlgebraplN(2)\n",
|
|
"s2.inject_variables()\n",
|
|
"p012 = 2-t1+t2\n",
|
|
"values = {(0,): p0, (1,): p1, (2,): p2, (0,1): p01, (0,2): p02, (1,2): p12, (0,1,2): p012+t0*y1*y2+t0*t1*y2}\n",
|
|
"e2 = A._element_constructor_(values)\n",
|
|
"e2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Adding new methods: Integration map\n",
|
|
"\n",
|
|
"For $(A_{PL})_n$ we have defined the linear map:\n",
|
|
"\n",
|
|
"$$ \\int_{n}: (A_{PL})_{n}^{n} \\rightarrow \\mathbb{Q} $$\n",
|
|
"\n",
|
|
"Now we want to extend this map to $A_{PL}(K)$ in order to obtain a natural quasi-isomorphism of cochain complexes:\n",
|
|
"\n",
|
|
"$$\\oint : A_{PL}(K) \\rightarrow C^*(K)$$\n",
|
|
"\n",
|
|
"Remember that $\\Phi^n_n \\in A_{PL}(K)^n_n$ is a morphism $\\Phi^n_n: K_n \\rightarrow (A_{PL})^n_n$\n",
|
|
"\n",
|
|
"We define the integration map $ \\oint = \\begin{Bmatrix}\\oint_n\\end{Bmatrix}_{n \\geq 0}$ as \n",
|
|
"\n",
|
|
"$$ \\oint_n: A_{PL}(K)^n_n \\rightarrow C^n(K)$$\n",
|
|
"\n",
|
|
"$$ (\\oint_n(\\Phi^n_n))(\\sigma) = (-1)^{\\frac{n(n-1)}{2}}\\int_{n}(\\Phi^n_n(\\sigma))$$ \n",
|
|
"$$ \\sigma \\in K_n$$"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 66,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AlgebraAplK(AlgebraAplK, UniqueRepresentation):\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" The graded commutative differential cochain algebra Apl(K)\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" class Element(AlgebraAplK.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the simplicial commutative differential algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
" def integral(self):\n",
|
|
" \"\"\"\n",
|
|
" Returns the cochain obtained as integration of 'self'\n",
|
|
" \"\"\"\n",
|
|
" cochain = {}\n",
|
|
" #integration of each polynomial\n",
|
|
" for k in self.elements.keys():\n",
|
|
" dim = len(k)-1\n",
|
|
" # the sign is due to stoke's theorem\n",
|
|
" cochain[k] = ((-1)**(dim*(dim-1)/2))*self.elements[k].integral()\n",
|
|
" return cochain"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Examples"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 67,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"The graded commutative differential cochain algebra Apl(K) of Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1, 2)}"
|
|
]
|
|
},
|
|
"execution_count": 67,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2]],is_mutable=False)\n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"A"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 68,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, y0\n",
|
|
"Defining t0, t1, y0, y1\n",
|
|
"Defining t0, t1, t2, y0, y1, y2\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 2, (1,): 1, (2,): 3, (0, 1): -t1 + 2, (0, 2): t1 + 2, (1, 2): 2*t1 + 1, (0, 1, 2): -t1 + t2 + 2}"
|
|
]
|
|
},
|
|
"execution_count": 68,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"s0 = SimplicialAlgebraplN(0)\n",
|
|
"s0.inject_variables()\n",
|
|
"p0 = s0(2)\n",
|
|
"p1 = s0(1)\n",
|
|
"p2 = s0(3)\n",
|
|
"s1 = SimplicialAlgebraplN(1)\n",
|
|
"s1.inject_variables()\n",
|
|
"p01 = 2*t0+t1\n",
|
|
"p02 = 2*t0+3*t1\n",
|
|
"p12 = t0+3*t1\n",
|
|
"s2 = SimplicialAlgebraplN(2)\n",
|
|
"s2.inject_variables()\n",
|
|
"p012 = 2-t1+t2\n",
|
|
"values = {(0,): p0, (1,): p1, (2,): p2, (0,1): p01, (0,2): p02, (1,2): p12, (0,1,2): p012}\n",
|
|
"e1 = A._element_constructor_(values)\n",
|
|
"e1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 69,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 2, (1,): 1, (2,): 3, (0, 1): 0, (0, 2): 0, (1, 2): 0, (0, 1, 2): 0}"
|
|
]
|
|
},
|
|
"execution_count": 69,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"e1.integral()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 70,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 0, (1,): 0, (2,): 0, (0, 1): -y1, (0, 2): y1, (1, 2): 2*y1, (0, 1, 2): -y1 + y2}"
|
|
]
|
|
},
|
|
"execution_count": 70,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"e1.differential()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 71,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 0, (1,): 0, (2,): 0, (0, 1): -1, (0, 2): 1, (1, 2): 2, (0, 1, 2): 0}"
|
|
]
|
|
},
|
|
"execution_count": 71,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"e1.differential().integral()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Adding new methods: Lift cochain\n",
|
|
"\n",
|
|
"Here, we define a map\n",
|
|
"\n",
|
|
"$$\\oint^{-1} : C^*(K) \\rightarrow A_{PL}(K) $$\n",
|
|
"\n",
|
|
"that, for a given a cochain $\\chi$, we obtain an element $\\oint^{-1}\\chi \\in A_{PL}(K)$ for which\n",
|
|
"\n",
|
|
"$$\\oint\\oint^{-1} = id$$\n",
|
|
"\n",
|
|
"As the map $\\oint$ is not injective, the oposite is almost never true. In general, $\\oint^{-1}\\oint \\Phi \\neq \\Phi$, for any $\\Phi \\in A_{PL}(K)$"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 72,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AlgebraAplK(AlgebraAplK, UniqueRepresentation):\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" The graded commutative differential cochain algebra Apl(K)\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" def lift_cochain(self, cochain):\n",
|
|
" \"\"\"\n",
|
|
" Returns an element of the algebra Apl(K) whose integral is the cochain given as input.\n",
|
|
" \"\"\"\n",
|
|
" # first we find polynomials compatible with the integration value\n",
|
|
" values = {}\n",
|
|
" max_dim = 0\n",
|
|
" for k in cochain.keys():\n",
|
|
" dim = len(k)-1\n",
|
|
" if dim > max_dim:\n",
|
|
" max_dim = dim\n",
|
|
" apl = SimplicialAlgebraplN(dim)\n",
|
|
" if dim>0:\n",
|
|
" values[k] = ((-1)**(dim*(dim-1)/2))*apl.integrand(cochain[k])\n",
|
|
" else:\n",
|
|
" values[k]= apl(cochain[k])\n",
|
|
" \n",
|
|
" # second, we propagate the simplicial information\n",
|
|
" simplicial_structure = {}\n",
|
|
" for n in reversed(range(max_dim+1)):\n",
|
|
" keys = [k for k in values.keys() if len(k) == n+1] # keys of the n-simplices\n",
|
|
" for k in keys:\n",
|
|
" simplicial_structure[k] = values[k] + self._propagate(cochain, k) \n",
|
|
" #print(simplicial_structure)\n",
|
|
" return AlgebraAplK.Element(self,simplicial_structure)\n",
|
|
" \n",
|
|
" def _propagate(self, cochain, simplex):\n",
|
|
" \"\"\"\n",
|
|
" Returns the part of the polynomial assigned to 'simplex' related to the\n",
|
|
" propagation of the simplicial information of its faces\n",
|
|
" \"\"\"\n",
|
|
" dim = len(simplex)-1\n",
|
|
" apl = SimplicialAlgebraplN(dim)\n",
|
|
" propagation = apl(0)\n",
|
|
" for n in reversed(range(dim)):\n",
|
|
" faces = self._faces_of_length(simplex, n+1)\n",
|
|
" apl = SimplicialAlgebraplN(n)\n",
|
|
" pol = apl(prod(apl.gens()[n+2:])) # we propagate the polynomial (y_1...y_n)\n",
|
|
" for f in faces:\n",
|
|
" if f in cochain.keys():\n",
|
|
" value = cochain[f]\n",
|
|
" face_indexes = [simplex.index(i) for i in f]\n",
|
|
" #print(\"dim: \",n,\" pol: \",pol,\" face_idx: \",face_indexes,\" dim: \", n)\n",
|
|
" propagation += value*((-1)**(n*(n-1)/2))*factorial(n)*pol.propagate(face_indexes, dim)\n",
|
|
" return propagation"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Example"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 73,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0, 1, 2, 3): -6*y1*y2*y3 - 2*t3*y1*y2 + 2*t2*y1*y3 - 2*t1*y2*y3 - t3*y1 + t1*y3, (0, 1, 2): 0, (0, 1, 3): -t2*y1 + t1*y2, (0, 2, 3): 0, (1, 2, 3): -2*y1*y2 + t2*y1 - t1*y2 + y2, (0, 1): 0, (0, 2): 0, (0, 3): 0, (1, 2): 0, (1, 3): y1, (2, 3): 0, (0,): 0, (1,): 0, (2,): 0, (3,): 0}"
|
|
]
|
|
},
|
|
"execution_count": 73,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2,3]],is_mutable=False) \n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"cochain = {(0,): 0, (1,): 0, (2,):0, (3,): 0, (0,1): 0, (0,2): 0, (0,3): 0,(1,2): 0, (1,3): 1, (2,3): 0, (0,1,2):0, (0,1,3):0, (0,2,3):0, (1,2,3):1, (0,1,2,3):1}\n",
|
|
"p = A.lift_cochain(cochain)\n",
|
|
"p"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 74,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"True\n",
|
|
"True\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"print(p.integral()==cochain)\n",
|
|
"print(A.lift_cochain(p.integral())==p)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Adding new methods: Managing simplicial-cohomology generators"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 75,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AlgebraAplK(AlgebraAplK, UniqueRepresentation):\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" The graded commutative differential cochain algebra Apl(K)\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" def cohomology_gens(self,degree):\n",
|
|
" \"\"\"\n",
|
|
" Returns the cohomolosy generators of a given degree\n",
|
|
" \"\"\"\n",
|
|
" gens = {}\n",
|
|
" basis = self.K.cohomology_ring(QQ).basis()\n",
|
|
" for k in basis.keys():\n",
|
|
" if k[0] == degree:\n",
|
|
" gens[k] = basis[k]\n",
|
|
" return gens\n",
|
|
" \n",
|
|
" def cohomology_group(self, n):\n",
|
|
" chainComplex = self.K.chain_complex(base_ring=QQ)\n",
|
|
" cochainComplex = chainComplex.dual()\n",
|
|
" Hn = cochainComplex.differential(n).right_kernel()/cochainComplex.differential(n-1).column_space()\n",
|
|
" return Hn\n",
|
|
"\n",
|
|
" def cochain_to_vector(self, cochain, dim):\n",
|
|
" \"\"\"\n",
|
|
" Converts a cochain, given as a dictionary, to a vector\n",
|
|
" \"\"\"\n",
|
|
" basis = self.K.n_chains(dim, base_ring=QQ, cochains=True).basis()\n",
|
|
" v = vector(QQ,len(basis)*[0])\n",
|
|
" i=0\n",
|
|
" for simplex in basis.keys():\n",
|
|
" v[i] = cochain[tuple(simplex)]\n",
|
|
" i = i+1\n",
|
|
" return v\n",
|
|
"\n",
|
|
" def vector_to_cochain(self, v, dim):\n",
|
|
" \"\"\"\n",
|
|
" Converts a cochain, given as a vector, to a dictionary\n",
|
|
" \"\"\"\n",
|
|
" cochain = {}\n",
|
|
" for d in range(self.K.dimension()+1):\n",
|
|
" basis = self.K.n_chains(d, base_ring=QQ, cochains=True).basis()\n",
|
|
" if d!=dim:\n",
|
|
" for simplex in basis.keys():\n",
|
|
" cochain[tuple(simplex)] = 0\n",
|
|
" else:\n",
|
|
" i=0\n",
|
|
" for simplex in basis.keys():\n",
|
|
" cochain[tuple(simplex)] = v[i]\n",
|
|
" i = i+1\n",
|
|
" return cochain\n",
|
|
" \n",
|
|
" def lift_cochain_complex(self, cochain, dim):\n",
|
|
" \"\"\"\n",
|
|
" (REVISAR)\n",
|
|
" Returns an element of the preimage by the differential of a given cochain\n",
|
|
" \n",
|
|
" INPUT:\n",
|
|
" - cochain: a cochain as a vector\n",
|
|
" - dim: dimension of the cochain\n",
|
|
" \"\"\"\n",
|
|
" # S = the Simplicial Complex\n",
|
|
" # cochain = the cochain you want to find a preimage by the differential\n",
|
|
" # dim = the dimension of the cochain\n",
|
|
" cochain_vector = self.cochain_to_vector(cochain, dim)\n",
|
|
" cochainComplex = self.K.chain_complex(base_ring=QQ).dual()\n",
|
|
" diff = cochainComplex.differential(dim-1)\n",
|
|
" show(diff.echelon_form())\n",
|
|
" result = diff.solve_right(cochain_vector)\n",
|
|
" return self.vector_to_cochain(result)\n",
|
|
"\n",
|
|
" def lift_cohomology_generator(self, g):\n",
|
|
" \"\"\"\n",
|
|
" Returns a representative cochain associated to a given cohomology generator.\n",
|
|
" \"\"\"\n",
|
|
" cycle = g.to_cycle()\n",
|
|
" cochain = {}\n",
|
|
" for n in range(self.K.dimension()+1):\n",
|
|
" for simplex in self.K._n_cells_sorted(n):\n",
|
|
" cochain[simplex.tuple()] = 0\n",
|
|
" for i in cycle:\n",
|
|
" #print(type(i[0].tuple()))\n",
|
|
" cochain[i[0].tuple()] = i[1]\n",
|
|
" return cochain\n",
|
|
" \n",
|
|
" def get_cohomology_aplk(self,degree):\n",
|
|
" \"\"\"\n",
|
|
" Returns a set of representative elements of Apl(K), one for each cohomology generator of a given degree\n",
|
|
" \"\"\"\n",
|
|
" representative_aplk_elements = {}\n",
|
|
" dic_gens = self.cohomology_gens(degree)\n",
|
|
" for key in dic_gens.keys():\n",
|
|
" gen = dic_gens[key]\n",
|
|
" cochain = self.lift_cohomology_generator(gen)\n",
|
|
" representative_aplk_elements[key] = self.lift_cochain(cochain)\n",
|
|
" return representative_aplk_elements\n",
|
|
" \n",
|
|
" def first_cohomology_group(self):\n",
|
|
" \"\"\"\n",
|
|
" Returns the degree >= 1 of the first non-null cohomology generator. \n",
|
|
" \"\"\"\n",
|
|
" basis = self.K.cohomology_ring(base_ring=QQ).basis()\n",
|
|
" indexes = list(basis.keys())\n",
|
|
" indexes.sort(reverse=False)\n",
|
|
"# print(indexes)\n",
|
|
" for n in range(1,len(indexes)):\n",
|
|
" if indexes[n][0] > 0:\n",
|
|
" return indexes[n][0]\n",
|
|
" return -1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Examples"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 76,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(1, 0): h^{1,0}}"
|
|
]
|
|
},
|
|
"execution_count": 76,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2],[1,3],[2,3]],is_mutable=False) \n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"g = A.cohomology_gens(1)\n",
|
|
"g"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 77,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<html>\\[\\newcommand{\\Bold}[1]{\\mathbf{#1}}\\left(1,\\,0,\\,-1,\\,0,\\,0\\right)\\]</html>"
|
|
],
|
|
"text/latex": [
|
|
"$$\\newcommand{\\Bold}[1]{\\mathbf{#1}}\\left(1,\\,0,\\,-1,\\,0,\\,0\\right)$$"
|
|
],
|
|
"text/plain": [
|
|
"(1, 0, -1, 0, 0)"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 0,\n",
|
|
" (1,): 0,\n",
|
|
" (2,): 0,\n",
|
|
" (3,): 0,\n",
|
|
" (0, 1): 1,\n",
|
|
" (0, 2): 0,\n",
|
|
" (1, 2): -1,\n",
|
|
" (1, 3): 0,\n",
|
|
" (2, 3): 0,\n",
|
|
" (0, 1, 2): 0}"
|
|
]
|
|
},
|
|
"execution_count": 77,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"H1 = A.cohomology_group(1)\n",
|
|
"l = []\n",
|
|
"for v in H1.basis():\n",
|
|
" l.append(H1.lift_map()(v))\n",
|
|
"show(l[0])\n",
|
|
"A.vector_to_cochain(l[0],1)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 78,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 0,\n",
|
|
" (1,): 0,\n",
|
|
" (2,): 0,\n",
|
|
" (3,): 0,\n",
|
|
" (0, 1): 0,\n",
|
|
" (0, 2): 0,\n",
|
|
" (1, 2): 0,\n",
|
|
" (1, 3): 0,\n",
|
|
" (2, 3): 1,\n",
|
|
" (0, 1, 2): 0}"
|
|
]
|
|
},
|
|
"execution_count": 78,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"gen = list(g.values())[0]\n",
|
|
"cochain = A.lift_cohomology_generator(gen)\n",
|
|
"cochain"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 79,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(1,\n",
|
|
" 0): {(0, 1, 2): 0, (0, 1): 0, (0, 2): 0, (1, 2): 0, (1, 3): 0, (2, 3): y1, (0,): 0, (1,): 0, (2,): 0, (3,): 0}}"
|
|
]
|
|
},
|
|
"execution_count": 79,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"A.get_cohomology_aplk(1)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 80,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(2, 0): h^{2,0}, (2, 1): h^{2,1}}"
|
|
]
|
|
},
|
|
"execution_count": 80,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# get the cohomology generators of a given degree\n",
|
|
"S2 = SimplicialComplex([[0,1,2],[0,1,3],[0,2,3],[1,2,3],[3,4,5],[3,4,6],[3,5,6],[4,5,6]],is_mutable=False) \n",
|
|
"A2 = AlgebraAplK(S2)\n",
|
|
"g = A2.cohomology_gens(2)\n",
|
|
"g"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 81,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 0,\n",
|
|
" (1,): 0,\n",
|
|
" (2,): 0,\n",
|
|
" (3,): 0,\n",
|
|
" (4,): 0,\n",
|
|
" (5,): 0,\n",
|
|
" (6,): 0,\n",
|
|
" (0, 1): 0,\n",
|
|
" (0, 2): 0,\n",
|
|
" (0, 3): 0,\n",
|
|
" (1, 2): 0,\n",
|
|
" (1, 3): 0,\n",
|
|
" (2, 3): 0,\n",
|
|
" (3, 4): 0,\n",
|
|
" (3, 5): 0,\n",
|
|
" (3, 6): 0,\n",
|
|
" (4, 5): 0,\n",
|
|
" (4, 6): 0,\n",
|
|
" (5, 6): 0,\n",
|
|
" (0, 1, 2): 0,\n",
|
|
" (0, 1, 3): 0,\n",
|
|
" (0, 2, 3): 0,\n",
|
|
" (1, 2, 3): 1,\n",
|
|
" (3, 4, 5): 0,\n",
|
|
" (3, 4, 6): 0,\n",
|
|
" (3, 5, 6): 0,\n",
|
|
" (4, 5, 6): 0}"
|
|
]
|
|
},
|
|
"execution_count": 81,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# get a representative cochain for a given cohomology generator\n",
|
|
"gen = list(g.values())[0]\n",
|
|
"cochain = A2.lift_cohomology_generator(gen)\n",
|
|
"cochain"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 82,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(2,\n",
|
|
" 0): {(0, 1, 2): 0, (0, 1, 3): 0, (0, 2, 3): 0, (1, 2, 3): -2*y1*y2, (3, 4, 5): 0, (3, 4, 6): 0, (3, 5, 6): 0, (4, 5, 6): 0, (0, 1): 0, (0, 2): 0, (0, 3): 0, (1, 2): 0, (1, 3): 0, (2, 3): 0, (3, 4): 0, (3, 5): 0, (3, 6): 0, (4, 5): 0, (4, 6): 0, (5, 6): 0, (0,): 0, (1,): 0, (2,): 0, (3,): 0, (4,): 0, (5,): 0, (6,): 0},\n",
|
|
" (2,\n",
|
|
" 1): {(0, 1, 2): 0, (0, 1, 3): 0, (0, 2, 3): 0, (1, 2, 3): 0, (3, 4, 5): 0, (3, 4, 6): 0, (3, 5, 6): 0, (4, 5, 6): -2*y1*y2, (0, 1): 0, (0, 2): 0, (0, 3): 0, (1, 2): 0, (1, 3): 0, (2, 3): 0, (3, 4): 0, (3, 5): 0, (3, 6): 0, (4, 5): 0, (4, 6): 0, (5, 6): 0, (0,): 0, (1,): 0, (2,): 0, (3,): 0, (4,): 0, (5,): 0, (6,): 0}}"
|
|
]
|
|
},
|
|
"execution_count": 82,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"phi = A2.get_cohomology_aplk(2)\n",
|
|
"phi"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Adding new methods: find a primitive of a closed element"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### methods related to find a polynomial where the differential is given"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 83,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from sage.rings.polynomial.polydict import ETuple\n",
|
|
"\n",
|
|
"class SimplicialAplN(SimplicialAplN,UniqueRepresentation):\n",
|
|
" class Element(SimplicialAplN.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the commutative differential multi-graded algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
"\n",
|
|
" def _get_primitive_basis_of_a_monomial(self, monomial): \n",
|
|
" \"\"\"\n",
|
|
" Returns a basis of the primitive of a given monomial\n",
|
|
"\n",
|
|
" Example: \n",
|
|
"\n",
|
|
" \"\"\"\n",
|
|
" n_vars = len(monomial)/2\n",
|
|
" combinations = []\n",
|
|
" for i in range(n_vars):\n",
|
|
" mono = list(copy.deepcopy(monomial))\n",
|
|
" if mono[n_vars+i]:\n",
|
|
" mono[i] += 1\n",
|
|
" mono[n_vars+i] = 0\n",
|
|
" combinations.append(tuple(mono))\n",
|
|
" return list(set(combinations))\n",
|
|
"\n",
|
|
" def _add_kernel_terms_to_primitive_basis(self, basis): \n",
|
|
" new_elements = []\n",
|
|
" for e in basis:\n",
|
|
" monomial = list(copy.deepcopy(e))\n",
|
|
" n = len(e)/2\n",
|
|
" monomial[:n] = n*[0]\n",
|
|
" new_elements.append(tuple(monomial))\n",
|
|
" return new_elements\n",
|
|
" \n",
|
|
" def _get_primitive_basis(self):\n",
|
|
" \"\"\"\n",
|
|
" Returns a basis of the primitive of 'self'\n",
|
|
" \"\"\"\n",
|
|
" basis = []\n",
|
|
" p = self.reduce()\n",
|
|
" for monomial in p.dict().keys():\n",
|
|
" basis += p._get_primitive_basis_of_a_monomial(monomial)\n",
|
|
" basis = list(set(basis))\n",
|
|
" basis += p._add_kernel_terms_to_primitive_basis(basis)\n",
|
|
" basis = list(set(basis))\n",
|
|
" terms = []\n",
|
|
" apl = self.parent()\n",
|
|
" for b in basis:\n",
|
|
" dim = len(monomial)/2-1\n",
|
|
" terms.append(self._get_term(1, b, apl.gens()))\n",
|
|
" terms.sort(reverse=False)\n",
|
|
" return terms\n",
|
|
"\n",
|
|
" def _get_differential_basis(self):\n",
|
|
" \"\"\"\n",
|
|
" Returns a basis of the differential of 'self'\n",
|
|
" \"\"\"\n",
|
|
" primitive_basis = self._get_primitive_basis()\n",
|
|
" differential_basis = []\n",
|
|
" for b in primitive_basis:\n",
|
|
" diff = b.differential().reduce()\n",
|
|
" if diff: # as we want a basis, we don't consider the coeffient of the differential\n",
|
|
" for monomial in diff.dict().keys():\n",
|
|
" term = self._get_term(1, monomial, self.parent().gens())\n",
|
|
" differential_basis.append(term)\n",
|
|
" differential_basis = list(set(differential_basis))\n",
|
|
" differential_basis.sort(reverse=False)\n",
|
|
" return differential_basis\n",
|
|
"\n",
|
|
" def _get_coordinate_vector_differential(self, diff_basis):\n",
|
|
" \"\"\"\n",
|
|
" Returns the coordinates of 'self' \n",
|
|
" in terms of the differential basis\n",
|
|
" \"\"\"\n",
|
|
" p_reduced = self.reduce()\n",
|
|
" #dic = p.dict()\n",
|
|
" #terms = [p_reduced.parent()({t: dic[t]}) for t in dic.keys()]\n",
|
|
" monomials = list(p_reduced.dict().keys())\n",
|
|
" v = vector(QQ,len(diff_basis)*[0])\n",
|
|
" for i in range(len(diff_basis)):\n",
|
|
" t = diff_basis[i]\n",
|
|
" term = list(t.dict().keys())[0] # there is only one monomial\n",
|
|
" if term in monomials:\n",
|
|
" v[i] = p_reduced.dict()[term]\n",
|
|
" return v\n",
|
|
"\n",
|
|
" def _differential_matrix(self, primitive_basis, differential_basis):\n",
|
|
" \"\"\"\n",
|
|
" Returns the matrix of the differential map\n",
|
|
" \"\"\"\n",
|
|
" #primitive_basis = get_primitive_basis_of_a_polynomial(p.reduce())\n",
|
|
" #differential_basis = get_differential_basis_of_a_polynomial(p.reduce())\n",
|
|
" nrows = len(differential_basis)\n",
|
|
" ncols = len(primitive_basis)\n",
|
|
" M = matrix(QQ, nrows, ncols, nrows*ncols*[0])\n",
|
|
" for j in range(ncols):\n",
|
|
" primitive = primitive_basis[j]\n",
|
|
" #diff_dict = self._tuple_differential(primitive)\n",
|
|
" diff_primitive = primitive.differential().reduce()\n",
|
|
" monomials = list(diff_primitive.dict().keys())\n",
|
|
" for i in range(nrows):\n",
|
|
" diff_basis_element = differential_basis[i]\n",
|
|
" term = list(diff_basis_element.dict().keys())[0] # there is only one monomial\n",
|
|
" if term in monomials:\n",
|
|
" M[i,j] = diff_primitive.dict()[term] \n",
|
|
" return M\n",
|
|
"\n",
|
|
" def solve_primitive(self):\n",
|
|
" p = self.reduce()\n",
|
|
" primitive_basis = p._get_primitive_basis()\n",
|
|
" diff_basis = p._get_differential_basis()\n",
|
|
" v = p._get_coordinate_vector_differential(diff_basis)\n",
|
|
" Mdif = p._differential_matrix(primitive_basis, diff_basis)\n",
|
|
" sol = Mdif.solve_right(v)\n",
|
|
" return sum(map(lambda x,y: x*y, sol, primitive_basis))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 84,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, t2, t3, t4, t5, y0, y1, y2, y3, y4, y5\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[1, y4, y3, y2, t1^2, t2*t3*y4, t2*t4*y3, t3*t4*y2]"
|
|
]
|
|
},
|
|
"execution_count": 84,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"dim = 5\n",
|
|
"s = SimplicialAlgebraplN(dim)\n",
|
|
"s.inject_variables()\n",
|
|
"p = -3*t1^2 +10* y2*t3*t4\n",
|
|
"p = p.differential()\n",
|
|
"primitive_basis = p._get_primitive_basis()\n",
|
|
"primitive_basis"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 85,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[t1*y1, t2*y3*y4, t3*y2*y4, t4*y2*y3]"
|
|
]
|
|
},
|
|
"execution_count": 85,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"diff_basis = p._get_differential_basis()\n",
|
|
"diff_basis"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 86,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"(-6, 0, -10, -10)"
|
|
]
|
|
},
|
|
"execution_count": 86,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"v = p._get_coordinate_vector_differential(diff_basis)\n",
|
|
"v"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 87,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[ 0 0 0 0 2 0 0 0]\n",
|
|
"[ 0 0 0 0 0 1 -1 0]\n",
|
|
"[ 0 0 0 0 0 1 0 -1]\n",
|
|
"[ 0 0 0 0 0 0 1 -1]"
|
|
]
|
|
},
|
|
"execution_count": 87,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"Mdif = p._differential_matrix(primitive_basis, diff_basis)\n",
|
|
"Mdif"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 88,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"-10*t2*t4*y3 - 10*t2*t3*y4 - 3*t1^2"
|
|
]
|
|
},
|
|
"execution_count": 88,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"p.solve_primitive()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 89,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"True"
|
|
]
|
|
},
|
|
"execution_count": 89,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"p.solve_primitive().differential() == p"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### find an element of the preimage by the differential of an element of Alp(K)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 90,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class AlgebraAplK(AlgebraAplK, UniqueRepresentation):\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" The graded commutative differential cochain algebra Apl(K)\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" class Element(AlgebraAplK.Element):\n",
|
|
" \"\"\"\n",
|
|
" Element class of the simplicial commutative differential algebra (Apl)n.\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" def _face_basis(self, basis, face_idx):\n",
|
|
" face_basis = []\n",
|
|
" for b in basis:\n",
|
|
" face_pol = b.face(face_idx).reduce()\n",
|
|
" if face_pol:\n",
|
|
" for monomial in face_pol.dict().keys():\n",
|
|
" #remove coefficients\n",
|
|
" term = face_pol._get_term(1, monomial, face_pol.parent().gens())\n",
|
|
" face_basis.append(term)\n",
|
|
" face_basis = list(set(face_basis))\n",
|
|
" face_basis.sort(reverse=False)\n",
|
|
" return face_basis\n",
|
|
" \n",
|
|
" def _get_primitive_basis(self):\n",
|
|
" \n",
|
|
" primitive_basis = {}\n",
|
|
" S = self.parent().simplicialComplex()\n",
|
|
" dim = S.dimension()\n",
|
|
" min_dim = self.degree()\n",
|
|
" for n in reversed(range(min_dim,dim+1)):\n",
|
|
" for simplex in S._n_cells_sorted(n):\n",
|
|
" if simplex.tuple() not in primitive_basis.keys():\n",
|
|
" primitive_basis[simplex.tuple()] = []\n",
|
|
" # add primitive elements related to the assigned polynomial\n",
|
|
" pol = self.elements[simplex.tuple()]\n",
|
|
" primitive_basis[simplex.tuple()] += pol._get_primitive_basis()\n",
|
|
" primitive_basis[simplex.tuple()] = list(set(primitive_basis[simplex.tuple()]))\n",
|
|
" primitive_basis[simplex.tuple()].sort(reverse=False)\n",
|
|
" # propagate the primitive basis through its faces\n",
|
|
" for f in range(n+1):\n",
|
|
" simplex_face = S.face(simplex,f).tuple()\n",
|
|
" if simplex_face not in primitive_basis.keys():\n",
|
|
" primitive_basis[simplex_face] = []\n",
|
|
" primitive_basis[simplex_face] += self._face_basis(primitive_basis[simplex.tuple()], f)\n",
|
|
" primitive_basis[simplex_face] = list(set(primitive_basis[simplex_face]))\n",
|
|
" primitive_basis[simplex_face].sort(reverse=False)\n",
|
|
" return primitive_basis\n",
|
|
" \n",
|
|
" def _diff_basis(self, basis):\n",
|
|
" diff_basis = []\n",
|
|
" for b in basis:\n",
|
|
" b_diff = b.differential().reduce()\n",
|
|
" if b_diff:\n",
|
|
" for monomial in b_diff.dict().keys():\n",
|
|
" #remove coefficients\n",
|
|
" term = b_diff._get_term(1, monomial, b_diff.parent().gens())\n",
|
|
" diff_basis.append(term)\n",
|
|
" diff_basis = list(set(diff_basis))\n",
|
|
" diff_basis.sort(reverse=False)\n",
|
|
" return diff_basis\n",
|
|
" \n",
|
|
" def _get_differential_basis(self, primitive_basis):\n",
|
|
" differential_basis = {}\n",
|
|
" S = self.parent().simplicialComplex()\n",
|
|
" dim = S.dimension()\n",
|
|
" min_dim = self.degree()\n",
|
|
" for n in reversed(range(min_dim,dim+1)):\n",
|
|
" for simplex in S._n_cells_sorted(n):\n",
|
|
" prim_diff_basis = primitive_basis[simplex.tuple()]\n",
|
|
" differential_basis[simplex.tuple()] = self._diff_basis(prim_diff_basis)\n",
|
|
" return differential_basis\n",
|
|
" \n",
|
|
" def _get_differential_matrix(self, p_basis, d_basis):\n",
|
|
" S = self.parent().simplicialComplex()\n",
|
|
" dim = S.dimension()\n",
|
|
" min_dim = self.degree()\n",
|
|
" ncols = sum([len(l) for l in p_basis.values()])\n",
|
|
" nrows = sum([len(l) for l in d_basis.values()])\n",
|
|
" M = zero_matrix(QQ, nrows, ncols)\n",
|
|
" row_offset = 0\n",
|
|
" col_index = 0\n",
|
|
" for n in reversed(range(min_dim-1,dim+1)):\n",
|
|
" for simplex in S._n_cells_sorted(n):\n",
|
|
"# print(simplex.tuple(), row_offset, col_index)\n",
|
|
" if simplex.tuple() in p_basis.keys():\n",
|
|
" primitives = p_basis[simplex.tuple()]\n",
|
|
" if simplex.tuple() in d_basis.keys():\n",
|
|
" differentials = d_basis[simplex.tuple()]\n",
|
|
" if primitives and differentials:\n",
|
|
" for p in primitives:\n",
|
|
" dif_p = p.differential().reduce()\n",
|
|
" dic = dif_p.dict()\n",
|
|
" for monomial in dic.keys():\n",
|
|
" term = dif_p._get_term(1, monomial, dif_p.parent().gens())\n",
|
|
" if term in differentials:\n",
|
|
" row_index = differentials.index(term)\n",
|
|
" M[row_offset + row_index, col_index] = dic[monomial]\n",
|
|
" col_index += 1\n",
|
|
" row_offset += len(differentials)\n",
|
|
" elif primitives:\n",
|
|
" col_index += len(primitives)\n",
|
|
" elif primitives:\n",
|
|
" col_index += len(primitives)\n",
|
|
" \n",
|
|
" return M\n",
|
|
" \n",
|
|
" def _get_vector_diff_coordinates(self, d_basis):\n",
|
|
" len_v = sum([len(l) for l in d_basis.values()])\n",
|
|
" v = zero_vector(QQ, len_v)\n",
|
|
" offset = 0\n",
|
|
" S = self.parent().simplicialComplex()\n",
|
|
" dim = S.dimension()\n",
|
|
" min_dim = self.degree()\n",
|
|
" for n in reversed(range(min_dim,dim+1)):\n",
|
|
" for s in S._n_cells_sorted(n):\n",
|
|
" simplex = s.tuple()\n",
|
|
" if simplex in d_basis.keys():\n",
|
|
" differentials = d_basis[simplex]\n",
|
|
" pol = self.elements[simplex].reduce()\n",
|
|
" if pol and differentials:\n",
|
|
" dic = pol.dict()\n",
|
|
" for monomial in dic.keys():\n",
|
|
" term = pol._get_term(1, monomial, pol.parent().gens())\n",
|
|
" if term in differentials:\n",
|
|
" v_index = differentials.index(term)\n",
|
|
" v[offset + v_index] = dic[monomial]\n",
|
|
" offset += len(differentials)\n",
|
|
" return v\n",
|
|
" \n",
|
|
" def _get_offsets_matrix(self, p_basis):\n",
|
|
" offsets = {}\n",
|
|
" S = self.parent().simplicialComplex()\n",
|
|
" dim = S.dimension()\n",
|
|
" min_dim = self.degree()\n",
|
|
" offset = 0\n",
|
|
" first_simplex = True\n",
|
|
" for n in reversed(range(min_dim-1,dim+1)):\n",
|
|
" for simplex in S._n_cells_sorted(n):\n",
|
|
" if simplex.tuple() in p_basis.keys():\n",
|
|
" primitives = p_basis[simplex.tuple()]\n",
|
|
" if first_simplex:\n",
|
|
" offsets[simplex.tuple()] = 0\n",
|
|
" first_simplex = False\n",
|
|
" else:\n",
|
|
" offsets[simplex.tuple()] = offset\n",
|
|
" offset += len(primitives)\n",
|
|
" return offsets\n",
|
|
" \n",
|
|
" def _get_row_face_matrix(self, primitives, face_idx, face_basis,\n",
|
|
" offset_simplex, offset_face, len_row):\n",
|
|
" M = zero_matrix(QQ,1, len_row)\n",
|
|
" for fb in face_basis: \n",
|
|
" fb_idx = face_basis.index(fb)\n",
|
|
" row = zero_matrix(QQ,1, len_row)\n",
|
|
" row[0,offset_face+fb_idx] = -1\n",
|
|
" for term in primitives:\n",
|
|
" face_term = term.face(face_idx).reduce()\n",
|
|
" dic = face_term.dict()\n",
|
|
" i = primitives.index(term)\n",
|
|
" for monomial in dic:\n",
|
|
" t = face_term._get_term(1, monomial, face_term.parent().gens())\n",
|
|
" if t == fb:\n",
|
|
" coef = dic[monomial]\n",
|
|
" row[0,offset_simplex+i] = coef\n",
|
|
" M = M.stack(row)\n",
|
|
" return M[1:]\n",
|
|
" \n",
|
|
" \n",
|
|
" def _get_face_matrix(self, p_basis):\n",
|
|
" \n",
|
|
" offsets = self._get_offsets_matrix(p_basis)\n",
|
|
" len_row = sum([len(l) for l in p_basis.values()])\n",
|
|
" M = zero_matrix(QQ,1, len_row)\n",
|
|
" min_dim = self.degree()\n",
|
|
" for n in reversed(range(min_dim,dim+1)):\n",
|
|
" for simplex in S._n_cells_sorted(n):\n",
|
|
" offset_simplex = offsets[simplex.tuple()]\n",
|
|
" primitives = p_basis[simplex.tuple()]\n",
|
|
" for f in range(n+1):\n",
|
|
" simplex_face = S.face(simplex,f).tuple()\n",
|
|
" face_primitives = p_basis[simplex_face]\n",
|
|
" offset_face = offsets[simplex_face]\n",
|
|
" rows = self._get_row_face_matrix(primitives, f, face_primitives,\n",
|
|
" offset_simplex, offset_face,\n",
|
|
" len_row)\n",
|
|
" M = M.stack(rows)\n",
|
|
" return M[1:]\n",
|
|
" \n",
|
|
" def _get_solution(self, sol, p_basis):\n",
|
|
" S = self.parent().simplicialComplex()\n",
|
|
" dim = S.dimension()\n",
|
|
" min_dim = self.degree()-1\n",
|
|
" offset = 0\n",
|
|
" values = {}\n",
|
|
" for n in reversed(range(dim+1)):\n",
|
|
" apl = SimplicialAlgebraplN(n)\n",
|
|
" for s in S._n_cells_sorted(n):\n",
|
|
" simplex = s.tuple()\n",
|
|
" pol = apl(0)\n",
|
|
" if simplex in p_basis.keys():\n",
|
|
" primitives = p_basis[simplex]\n",
|
|
" if primitives:\n",
|
|
" for p in primitives:\n",
|
|
" i = primitives.index(p)\n",
|
|
" coef = sol[offset+i]\n",
|
|
" pol += coef*p\n",
|
|
" offset += len(primitives)\n",
|
|
" values[simplex] = pol \n",
|
|
" A = self.parent()\n",
|
|
"# return values\n",
|
|
" return A._element_constructor_(values)\n",
|
|
" \n",
|
|
" def solve_primitive(self):\n",
|
|
" p_basis = self._get_primitive_basis()\n",
|
|
" d_basis = self._get_differential_basis(p_basis)\n",
|
|
" diff_matrix = self._get_differential_matrix(p_basis, d_basis)\n",
|
|
" v_dif = self._get_vector_diff_coordinates(d_basis)\n",
|
|
" face_matrix = self._get_face_matrix(p_basis)\n",
|
|
" nrows = face_matrix.nrows()\n",
|
|
" v = vector(QQ, list(v_dif)+nrows*[0])\n",
|
|
" M = diff_matrix.stack(face_matrix)\n",
|
|
" sol = M.solve_right(v)\n",
|
|
" return self._get_solution(sol, p_basis)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Example"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 91,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, t2, y0, y1, y2\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 0, (1,): 0, (2,): 0, (3,): 0, (4,): 0, (0, 1): 0, (0, 2): 0, (0, 3): 0, (0, 4): 0, (1, 2): 0, (1, 3): 0, (1, 4): 0, (2, 3): 0, (2, 4): 0, (3, 4): 0, (0, 1, 2): 0, (0, 1, 3): 0, (0, 1, 4): 0, (0, 2, 3): 0, (0, 2, 4): 0, (0, 3, 4): 0, (1, 2, 3): 0, (1, 2, 4): 0, (1, 3, 4): 0, (2, 3, 4): 0, (0, 1, 2, 3): 3*y1*y2*y3, (0, 1, 2, 4): -3*y1*y2*y3, (0, 1, 3, 4): -3*y1*y2*y3, (0, 2, 3, 4): 0, (1, 2, 3, 4): -3*y1*y2*y3, (0, 1, 2, 3, 4): 3*y1*y2*y3 - 3*y1*y2*y4 - 3*y1*y3*y4}"
|
|
]
|
|
},
|
|
"execution_count": 91,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2,3,4]],is_mutable=False)\n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"s0 = SimplicialAlgebraplN(0)\n",
|
|
"s1 = SimplicialAlgebraplN(1)\n",
|
|
"s2 = SimplicialAlgebraplN(2)\n",
|
|
"s3 = SimplicialAlgebraplN(3)\n",
|
|
"s4 = SimplicialAlgebraplN(4)\n",
|
|
"s2.inject_variables()\n",
|
|
"p012 = y1*y2\n",
|
|
"p013 = y1*y2\n",
|
|
"p023 = y1*y2\n",
|
|
"p024 = y1*y2\n",
|
|
"p034 = y1*y2\n",
|
|
"p123 = y1*y2\n",
|
|
"p124 = y1*y2\n",
|
|
"p134 = y1*y2\n",
|
|
"p234 = y1*y2\n",
|
|
"\n",
|
|
"p0123 = p012.propagate([0,1,2],3) + p123.propagate([1,2,3],3)+p013.propagate([0,1,3],3)\n",
|
|
"p0134 = p013.propagate([0,1,2],3)\n",
|
|
"p0124 = p012.propagate([0,1,2],3)\n",
|
|
"p1234 = p123.propagate([0,1,2],3)\n",
|
|
"p01234 = p012.propagate([0,1,2],4) + p123.propagate([1,2,3],4) + p013.propagate([0,1,3],4)\n",
|
|
"\n",
|
|
"values = {(0,): s0(0), (1,): s0(0), (2,): s0(0), (3,): s0(0), (4,): s0(0), \n",
|
|
" (0,1): s1(0), (0,2): s1(0), (0,3): s1(0), (0,4): s1(0),\n",
|
|
" (1,2): s1(0), (1,3): s1(0), (1,4): s1(0), \n",
|
|
" (2,3): s1(0), (2,4): s1(0), \n",
|
|
" (3,4): s1(0), \n",
|
|
" (0,1,2): p012, (0,1,3): p013, (0,1,4): s2(0), \n",
|
|
" (0,2,3): s2(0), (0,2,4): s2(0), (0,3,4): s2(0),\n",
|
|
" (1,2,3): p123, (1,2,4): s2(0), (1,3,4): s2(0),\n",
|
|
" (2,3,4): s2(0), \n",
|
|
" (0,1,2,3): p0123,(0,1,2,4):p0124,(0,1,3,4): p0134,\n",
|
|
" (0,2,3,4): s3(0),(1,2,3,4): p1234,\n",
|
|
" (0,1,2,3,4): p01234}\n",
|
|
"e1 = A._element_constructor_(values)\n",
|
|
"dife1 = e1.differential()\n",
|
|
"dife1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 92,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0, 1, 2, 3, 4): t3*y1*y2 - t4*y1*y2 - t2*y1*y3 - t4*y1*y3 + t1*y2*y3 + t2*y1*y4 + t3*y1*y4 - t1*y2*y4 - t1*y3*y4 + y1*y2 + y1*y3, (0, 1, 2, 3): t3*y1*y2 - t2*y1*y3 + t1*y2*y3 + y1*y2 + y1*y3, (0, 1, 2, 4): -t3*y1*y2 + t2*y1*y3 - t1*y2*y3 + y1*y2, (0, 1, 3, 4): -t3*y1*y2 + t2*y1*y3 - t1*y2*y3 + y1*y2, (0, 2, 3, 4): 0, (1, 2, 3, 4): -t3*y1*y2 + t2*y1*y3 - t1*y2*y3 + y1*y2, (0, 1, 2): y1*y2, (0, 1, 3): y1*y2, (0, 1, 4): 0, (0, 2, 3): 0, (0, 2, 4): 0, (0, 3, 4): 0, (1, 2, 3): y1*y2, (1, 2, 4): 0, (1, 3, 4): 0, (2, 3, 4): 0, (0, 1): 0, (0, 2): 0, (0, 3): 0, (0, 4): 0, (1, 2): 0, (1, 3): 0, (1, 4): 0, (2, 3): 0, (2, 4): 0, (3, 4): 0, (0,): 0, (1,): 0, (2,): 0, (3,): 0, (4,): 0}"
|
|
]
|
|
},
|
|
"execution_count": 92,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"primitive = dife1.solve_primitive()\n",
|
|
"primitive"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 93,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"True"
|
|
]
|
|
},
|
|
"execution_count": 93,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"primitive.differential() == dife1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 94,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"True"
|
|
]
|
|
},
|
|
"execution_count": 94,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"primitive == e1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Example Torus"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 95,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# S = simplicial_complexes.Torus()\n",
|
|
"# A = AlgebraAplK(S)\n",
|
|
"# s0 = SimplicialAlgebraplN(0)\n",
|
|
"# s1 = SimplicialAlgebraplN(1)\n",
|
|
"# s2 = SimplicialAlgebraplN(2)\n",
|
|
"# s2.inject_variables()\n",
|
|
"# values = {(0, 1, 2): s2(0), (0, 1, 5): s2(0), (0, 2, 6): s2(0), (0, 3, 4): s2(0), (0, 3, 5): s2(0), \n",
|
|
"# (0, 4, 6): s2(0), (1, 2, 4): s2(0), (1, 3, 4): s2(0), (1, 3, 6): -y1*y2, (1, 5, 6): s2(0), \n",
|
|
"# (2, 3, 5): s2(0), (2, 3, 6): s2(0), (2, 4, 5): y1*y2, (4, 5, 6): s2(0), \n",
|
|
"# (0, 1): s1(0), (0, 2): s1(0), (0, 3): s1(0), (0, 4): s1(0), (0, 5): s1(0), (0, 6): s1(0), \n",
|
|
"# (1, 2): s1(0), (1, 3): s1(0), (1, 4): s1(0), (1, 5): s1(0), (1, 6): s1(0), (2, 3): s1(0), (2, 4): s1(0), \n",
|
|
"# (2, 5): s1(0), (2, 6): s1(0), (3, 4): s1(0), (3, 5): s1(0), (3, 6): s1(0), (4, 5): s1(0), (4, 6): s1(0), (5, 6): s1(0), \n",
|
|
"# (0,): s0(0), (1,): s0(0), (2,): s0(0), (3,): s0(0), (4,): s0(0), (5,): s0(0), (6,): s0(0)}\n",
|
|
"# e = A._element_constructor_(values)\n",
|
|
"# preimage = e.solve_primitive()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Test with random complexes and random elements of Apl(K)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 96,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def sublist(lst1, lst2):\n",
|
|
" return set(lst1) <= set(lst2)\n",
|
|
"\n",
|
|
"def sublist_of_lists(list1,list_of_lists):\n",
|
|
" is_sublist = False\n",
|
|
" for list2 in list_of_lists:\n",
|
|
" if sublist(list1,list2):\n",
|
|
" is_sublist = True\n",
|
|
" break\n",
|
|
" return is_sublist\n",
|
|
"\n",
|
|
"def random_simplicial_complex(num_vertices,max_num_facets):\n",
|
|
" vertices = list(range(num_vertices))\n",
|
|
" simplices = []\n",
|
|
" partitions = []\n",
|
|
" for length in range(num_vertices):\n",
|
|
" partitions += [tuple(e) for e in powerset(vertices) if len(e)==length and e]\n",
|
|
" for i in range(max_num_facets):\n",
|
|
" r = randint(0,len(partitions)-1)\n",
|
|
" candidate = partitions[r]\n",
|
|
" if not sublist_of_lists(candidate,simplices):\n",
|
|
" simplices.append(candidate)\n",
|
|
" return SimplicialComplex(simplices,is_mutable=False)\n",
|
|
"\n",
|
|
"def random_cochain(S):\n",
|
|
" dim = S.dimension()\n",
|
|
" cochain = {}\n",
|
|
" for n in range(dim+1):\n",
|
|
" for s in S._n_cells_sorted(n):\n",
|
|
" cochain[s.tuple()] = randint(-100,100)\n",
|
|
" return cochain"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 97,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and facets {(0,), (2, 3), (4, 5), (1, 2, 5)}"
|
|
]
|
|
},
|
|
"execution_count": 97,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = random_simplicial_complex(6,4)\n",
|
|
"# S = SimplicialComplex([5],is_mutable=False)\n",
|
|
"cochain = random_cochain(S)\n",
|
|
"S"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 98,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"A = AlgebraAplK(S)\n",
|
|
"e = A.lift_cochain(cochain)\n",
|
|
"dife = e.differential()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 99,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"deg: 1\n",
|
|
"deg: 2\n",
|
|
"dif(recover) == dif(e): True\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"hom_parts = dife.homogeneous_parts()\n",
|
|
"recover = A.null_element()\n",
|
|
"for deg in hom_parts.keys():\n",
|
|
" print(\"deg: \", deg)\n",
|
|
" recover += hom_parts[deg].solve_primitive()\n",
|
|
"print(\"dif(recover) == dif(e): \", recover.differential() == dife)\n",
|
|
"# print(\"recover == e: \", recover == e) # Although their differentials are equal, this is not always True"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Example"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 100,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, t2, t3, y0, y1, y2, y3\n",
|
|
"\n",
|
|
"e1:\n",
|
|
"{(0,): 0, (1,): 0, (2,): 0, (3,): 0, (0, 1): 0, (0, 2): 0, (0, 3): 0, (1, 2): 0, (1, 3): 0, (2, 3): 0, (0, 1, 2): 0, (0, 1, 3): 0, (0, 2, 3): 0, (1, 2, 3): 0, (0, 1, 2, 3): y1*y2*y3}\n",
|
|
"\n",
|
|
"e2\n",
|
|
"{(0, 1, 2, 3): 1/3*t3*y1*y2 - 1/3*t2*y1*y3 + 1/3*t1*y2*y3 - 1/3*y1*y2, (0, 1, 2): -1/3*y1*y2, (0, 1, 3): 0, (0, 2, 3): 0, (1, 2, 3): 0, (0, 1): 0, (0, 2): 0, (0, 3): 0, (1, 2): 0, (1, 3): 0, (2, 3): 0, (0,): 0, (1,): 0, (2,): 0, (3,): 0}\n",
|
|
"\n",
|
|
"d(e2) == e1: True\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2,3]],is_mutable=False)\n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"s0 = SimplicialAlgebraplN(0)\n",
|
|
"s1 = SimplicialAlgebraplN(1)\n",
|
|
"s2 = SimplicialAlgebraplN(2)\n",
|
|
"s3 = SimplicialAlgebraplN(3)\n",
|
|
"s3.inject_variables()\n",
|
|
"p0123 = y1*y2*y3\n",
|
|
"values = {(0,): s0(0), (1,): s0(0), (2,): s0(0), (3,): s0(0), (0,1): s1(0), (0,2): s1(0),\n",
|
|
" (0,3): s1(0), (1,2): s1(0), (1,3): s1(0), (2,3): s1(0), (0,1,2): s2(0), (0,1,3): s2(0), \n",
|
|
" (0,2,3): s2(0), (1,2,3): s2(0), (0,1,2,3): p0123}\n",
|
|
"e1 = A._element_constructor_(values)\n",
|
|
"print(\"\")\n",
|
|
"print(\"e1:\")\n",
|
|
"print(e1)\n",
|
|
"print(\"\")\n",
|
|
"e2 = e1.solve_primitive()\n",
|
|
"print(\"e2\")\n",
|
|
"print(e2)\n",
|
|
"print(\"\")\n",
|
|
"print(\"d(e2) == e1: \", e2.differential() == e1)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Example of degree 0"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 101,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, t2, y0, y1, y2\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"True"
|
|
]
|
|
},
|
|
"execution_count": 101,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2], [0,1,3]],is_mutable=False)\n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"s0 = SimplicialAlgebraplN(0)\n",
|
|
"s2 = SimplicialAlgebraplN(2)\n",
|
|
"s2.inject_variables()\n",
|
|
"p012 = y0\n",
|
|
"p013 = y0\n",
|
|
"values = {(0,): s0(0), (1,): s0(0), (2,): s0(0), (3,): s0(0), (0,1): p012.face(2), (0,2): p012.face(1),\n",
|
|
" (0,3): p013.face(1), (1,2): p012.face(0), (1,3): p013.face(0), (0,1,2): p012, (0,1,3): p013}\n",
|
|
"e1 = A._element_constructor_(values)\n",
|
|
"e2 = e1.solve_primitive()\n",
|
|
"e2.differential() == e1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Example"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 102,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, t2, t3, y0, y1, y2, y3\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"True"
|
|
]
|
|
},
|
|
"execution_count": 102,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2,3]],is_mutable=False)\n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"s0 = SimplicialAlgebraplN(0)\n",
|
|
"s1 = SimplicialAlgebraplN(1)\n",
|
|
"s2 = SimplicialAlgebraplN(2)\n",
|
|
"s3 = SimplicialAlgebraplN(3)\n",
|
|
"s3.inject_variables()\n",
|
|
"p0123 = y1*y2*y3\n",
|
|
"values = {(0,): s0(0), (1,): s0(0), (2,): s0(0), (3,): s0(0), (0,1): s1(0), (0,2): s1(0),\n",
|
|
" (0,3): s1(0), (1,2): s1(0), (1,3): s1(0), (2,3): s1(0), (0,1,2): s2(0), (0,1,3): s2(0), \n",
|
|
" (0,2,3): s2(0), (1,2,3): s2(0), (0,1,2,3): p0123}\n",
|
|
"e1 = A._element_constructor_(values)\n",
|
|
"primitive = e1.solve_primitive()\n",
|
|
"primitive.differential() == e1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Another example"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 103,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Defining t0, t1, t2, y0, y1, y2\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{(0,): 0, (1,): 0, (2,): 0, (3,): 0, (4,): 0, (0, 1): 0, (0, 2): 0, (0, 3): 0, (0, 4): 0, (1, 2): 0, (1, 3): 0, (1, 4): 0, (2, 3): 0, (2, 4): 0, (3, 4): 0, (0, 1, 2): y1*y2, (0, 1, 3): y1*y2, (0, 1, 4): 0, (0, 2, 3): 0, (0, 2, 4): 0, (0, 3, 4): 0, (1, 2, 3): y1*y2, (1, 2, 4): 0, (1, 3, 4): 0, (2, 3, 4): 0, (0, 1, 2, 3): t3*y1*y2 - t2*y1*y3 + t1*y2*y3 + y1*y2 + y1*y3, (0, 1, 2, 4): -t3*y1*y2 + t2*y1*y3 - t1*y2*y3 + y1*y2, (0, 1, 3, 4): -t3*y1*y2 + t2*y1*y3 - t1*y2*y3 + y1*y2, (0, 2, 3, 4): 0, (1, 2, 3, 4): -t3*y1*y2 + t2*y1*y3 - t1*y2*y3 + y1*y2, (0, 1, 2, 3, 4): t3*y1*y2 - t4*y1*y2 - t2*y1*y3 - t4*y1*y3 + t1*y2*y3 + t2*y1*y4 + t3*y1*y4 - t1*y2*y4 - t1*y3*y4 + y1*y2 + y1*y3}"
|
|
]
|
|
},
|
|
"execution_count": 103,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S = SimplicialComplex([[0,1,2,3,4]],is_mutable=False)\n",
|
|
"A = AlgebraAplK(S)\n",
|
|
"s0 = SimplicialAlgebraplN(0)\n",
|
|
"s1 = SimplicialAlgebraplN(1)\n",
|
|
"s2 = SimplicialAlgebraplN(2)\n",
|
|
"s3 = SimplicialAlgebraplN(3)\n",
|
|
"s4 = SimplicialAlgebraplN(4)\n",
|
|
"s2.inject_variables()\n",
|
|
"p012 = y1*y2\n",
|
|
"p013 = y1*y2\n",
|
|
"p023 = y1*y2\n",
|
|
"p024 = y1*y2\n",
|
|
"p034 = y1*y2\n",
|
|
"p123 = y1*y2\n",
|
|
"p124 = y1*y2\n",
|
|
"p134 = y1*y2\n",
|
|
"p234 = y1*y2\n",
|
|
"\n",
|
|
"p0123 = p012.propagate([0,1,2],3) + p123.propagate([1,2,3],3)+p013.propagate([0,1,3],3)\n",
|
|
"p0134 = p013.propagate([0,1,2],3)\n",
|
|
"p0124 = p012.propagate([0,1,2],3)\n",
|
|
"p1234 = p123.propagate([0,1,2],3)\n",
|
|
"p01234 = p012.propagate([0,1,2],4) + p123.propagate([1,2,3],4) + p013.propagate([0,1,3],4)\n",
|
|
"\n",
|
|
"values = {(0,): s0(0), (1,): s0(0), (2,): s0(0), (3,): s0(0), (4,): s0(0), \n",
|
|
" (0,1): s1(0), (0,2): s1(0), (0,3): s1(0), (0,4): s1(0),\n",
|
|
" (1,2): s1(0), (1,3): s1(0), (1,4): s1(0), \n",
|
|
" (2,3): s1(0), (2,4): s1(0), \n",
|
|
" (3,4): s1(0), \n",
|
|
" (0,1,2): p012, (0,1,3): p013, (0,1,4): s2(0), \n",
|
|
" (0,2,3): s2(0), (0,2,4): s2(0), (0,3,4): s2(0),\n",
|
|
" (1,2,3): p123, (1,2,4): s2(0), (1,3,4): s2(0),\n",
|
|
" (2,3,4): s2(0), \n",
|
|
" (0,1,2,3): p0123,(0,1,2,4):p0124,(0,1,3,4): p0134,\n",
|
|
" (0,2,3,4): s3(0),(1,2,3,4): p1234,\n",
|
|
" (0,1,2,3,4): p01234}\n",
|
|
"e1 = A._element_constructor_(values)\n",
|
|
"e1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 104,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"dife1 = e1.differential()\n",
|
|
"#dife1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 105,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"dif(recovery) == diff(e1): True\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"recovery = dife1.solve_primitive()\n",
|
|
"print(\"dif(recovery) == diff(e1): \",recovery.differential() == dife1)\n",
|
|
"#recovery"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Minimal model"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 106,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def update_cdga(gca, diff_dict={}):\n",
|
|
"\n",
|
|
" gens_dict = gca.gens_dict()\n",
|
|
" differentials = {}\n",
|
|
" if diff_dict:\n",
|
|
" for gen_name in diff_dict.keys():\n",
|
|
" gen = gens_dict[gen_name]\n",
|
|
" product_gens = diff_dict[gen_name]\n",
|
|
" gen0 = gens_dict[product_gens[0]]\n",
|
|
" if type(product_gens[1]) == int: # is a power\n",
|
|
" power = product_gens[1]\n",
|
|
" mult = gen0\n",
|
|
" for i in range(1, power):\n",
|
|
" mult *= gen0\n",
|
|
" differentials.update({gen:mult})\n",
|
|
" else:\n",
|
|
" gen1 = gens_dict[product_gens[1]]\n",
|
|
" differentials.update({gen:gen0*gen1})\n",
|
|
"# print(\"differentials\", differentials)\n",
|
|
" return gca.cdg_algebra(differentials) \n",
|
|
"\n",
|
|
" \n",
|
|
"def has_preimage(M, element):\n",
|
|
" \n",
|
|
" d = M.differential()\n",
|
|
" deg = element.degree()-1\n",
|
|
"# print(\"differential of \", element, \"degree: \", deg)\n",
|
|
" Md = d.differential_matrix(deg)\n",
|
|
" gens = M.basis(deg)\n",
|
|
" try:\n",
|
|
" solution = Md.solve_left(vector(QQ,element.basis_coefficients()))\n",
|
|
" primitive = sum(map(lambda coef, gen: coef*gen, solution, gens))\n",
|
|
" print(element, \" has preimage \", primitive)\n",
|
|
" return True\n",
|
|
" except ValueError:\n",
|
|
" return False\n",
|
|
"\n",
|
|
"def injectivity_step(M, phi, check_dim, names, \n",
|
|
" degrees, differentials, index=0, depth=0, max_depth=5):\n",
|
|
" \n",
|
|
" print(\"Injectivity at dimension \", check_dim)\n",
|
|
" if depth > max_depth:\n",
|
|
" return [M, phi, names, degrees, differentials, True]\n",
|
|
" deg = check_dim -1\n",
|
|
" gens = [g for g in M.gens() if g.degree() < check_dim]\n",
|
|
"# gens.sort(reverse=True)\n",
|
|
" gen_products = []\n",
|
|
" for i in range(len(gens)):\n",
|
|
" e0 = gens[i]\n",
|
|
" d = e0.degree()\n",
|
|
" mcd = gcd(d, check_dim)\n",
|
|
" if d%2 == 0 and mcd == d:\n",
|
|
" power = True\n",
|
|
" exp = check_dim / d\n",
|
|
" mult = e0\n",
|
|
" for j in range(1,exp-1):\n",
|
|
" mult *= e0\n",
|
|
" gen_products.append([e0, mult, power, exp])\n",
|
|
" for j in range(i+1,len(gens)):\n",
|
|
" power = False\n",
|
|
" e1 = gens[j]\n",
|
|
" if e0.degree() + e1.degree() == check_dim:\n",
|
|
" gen_products.append([e0, e1, power])\n",
|
|
"# print(\"products at dim \",check_dim,\": \", gen_products)\n",
|
|
" new_M = M\n",
|
|
" new_phi = phi\n",
|
|
" new_names = names\n",
|
|
" new_degrees = degrees\n",
|
|
" new_differentials = differentials\n",
|
|
" for pair in gen_products:\n",
|
|
" # Looking at the minimal model side\n",
|
|
" gen0 = pair[0]\n",
|
|
" deg_0 = gen0.degree()\n",
|
|
" gen1 = pair[1]\n",
|
|
" deg_1 = gen1.degree()\n",
|
|
" M_product = gen0*gen1\n",
|
|
" # Looking at the AplK side\n",
|
|
" gen0_name = list(M.gens_dict().keys())[list(M.gens_dict().values()).index(gen0)]\n",
|
|
" aplk_gen0 = phi[deg_0][gen0_name]\n",
|
|
" is_power = pair[2]\n",
|
|
" power = 0\n",
|
|
" if is_power:\n",
|
|
" power = pair[3]\n",
|
|
" aplk_gen1 = aplk_gen0\n",
|
|
" for i in range(1, power):\n",
|
|
" aplk_gen1 *= aplk_gen0\n",
|
|
" else:\n",
|
|
" gen1_name = list(M.gens_dict().keys())[list(M.gens_dict().values()).index(gen1)]\n",
|
|
" aplk_gen1 = phi[deg_1][gen1_name]\n",
|
|
" aplk_product = aplk_gen0*aplk_gen1\n",
|
|
" A = aplk_product.parent()\n",
|
|
" # Check conditions\n",
|
|
" if (M_product == M(0)) and (aplk_product == A.null_element()): # zero element\n",
|
|
" pass\n",
|
|
" elif (M_product == M(0)) and (aplk_product != A.null_element()): #check\n",
|
|
" if aplk_product.is_closed():\n",
|
|
" pass #trivial cohomology class (assuming aplk_product has preimage by differential)\n",
|
|
" else:\n",
|
|
" raise ValueError('zero associated to a non-closed element in AplK')\n",
|
|
" elif (M_product.differential() != 0): # is not closed\n",
|
|
" print(\"The element \",M_product, \" is not closed\")\n",
|
|
" pass \n",
|
|
" elif (M_product.differential() == 0) and aplk_product.is_closed() and has_preimage(M, M_product):\n",
|
|
" pass #trivial cohomology class (assuming aplk_product has preimage by differential)\n",
|
|
" elif (M_product.differential() == 0) and aplk_product.is_closed(): #key step because M_product doesn't have preimage\n",
|
|
" new_gen = 'y'+str(deg)+'_'+str(index)\n",
|
|
" if aplk_product != A.null_element():\n",
|
|
" try:\n",
|
|
" preimage = aplk_product.solve_primitive()\n",
|
|
" except ValueError:\n",
|
|
" print(\" The element \",M_product, \" has non trivial cohomology class. No generator added.\")\n",
|
|
" continue # we don't add a new generator because the element has non trivial cohomology class\n",
|
|
" phi_new_gen = {new_gen: preimage}\n",
|
|
" else: \n",
|
|
" phi_new_gen = {new_gen: A.null_element()}\n",
|
|
" print(\" Proceed to kill\", M_product, \" because has associated trivial cohomology class\")\n",
|
|
" print(\"Adding generator \"+new_gen)\n",
|
|
" new_names = names + [new_gen]\n",
|
|
" new_degrees = tuple(list(degrees)+[deg])\n",
|
|
" new_differentials = copy.deepcopy(differentials)\n",
|
|
" if not is_power:\n",
|
|
" new_differentials.update({new_gen: [gen0_name, gen1_name]})\n",
|
|
" else:\n",
|
|
" new_differentials.update({new_gen: [gen0_name, int(power)]})\n",
|
|
" gca = GradedCommutativeAlgebra(QQ, names=new_names, degrees=new_degrees)\n",
|
|
" new_M = update_cdga(gca, new_differentials)\n",
|
|
" new_phi = copy.deepcopy(phi)\n",
|
|
" d = new_phi[deg]\n",
|
|
" d.update(phi_new_gen)\n",
|
|
" return injectivity_step(new_M, new_phi, check_dim, new_names, \n",
|
|
" new_degrees, new_differentials, index=index+1, depth=depth+1, max_depth=max_depth)\n",
|
|
" else:\n",
|
|
" pass\n",
|
|
"\n",
|
|
" return [new_M, new_phi, new_names, new_degrees, new_differentials, False]\n",
|
|
"\n",
|
|
"def get_unmapped_generators(dim, coho_aplk, coho_gens, correspondence):\n",
|
|
"\n",
|
|
" dimensions = list(correspondence.keys())\n",
|
|
" unmmaped_elements = copy.deepcopy(coho_aplk)\n",
|
|
" for gen_key in coho_gens.keys():\n",
|
|
" gen = coho_gens[gen_key]\n",
|
|
" found = False\n",
|
|
" for i in range(1,dim):\n",
|
|
" if (not found) and (i in dimensions):\n",
|
|
" for j in range(i,dim):\n",
|
|
" if (j in dimensions) and (i+j == dim):\n",
|
|
" gensi = correspondence[i]\n",
|
|
" gensj = correspondence[j]\n",
|
|
" for gi in gensi.values():\n",
|
|
" if not found:\n",
|
|
" for gj in gensj.values():\n",
|
|
" product = gi.cup_product(gj) \n",
|
|
" if product == gen or -product == gen:\n",
|
|
" found = True\n",
|
|
" i_name = list(gensi.keys())[list(gensi.values()).index(gi)]\n",
|
|
" j_name = list(gensj.keys())[list(gensj.values()).index(gj)]\n",
|
|
" if gen_key in unmmaped_elements.keys():\n",
|
|
" print(\"The element \",i_name+\"*\"+j_name,\" is already mapped\")\n",
|
|
" del unmmaped_elements[gen_key]\n",
|
|
" break\n",
|
|
" return unmmaped_elements\n",
|
|
"\n",
|
|
"def surjective_step(A, M, phi, dim, names, degrees, differentials, cohomology_correspondence):\n",
|
|
" \n",
|
|
" print(\"Surjectivity at dimension \", dim)\n",
|
|
" coho_aplk = A.get_cohomology_aplk(dim)\n",
|
|
" cohomology_gens = A.cohomology_gens(dim)\n",
|
|
" g = get_unmapped_generators(dim, coho_aplk, cohomology_gens, cohomology_correspondence)\n",
|
|
" new_names = copy.deepcopy(names)\n",
|
|
" new_degrees = copy.deepcopy(degrees)\n",
|
|
" new_phi = copy.deepcopy(phi)\n",
|
|
" new_correspondence = copy.deepcopy(cohomology_correspondence)\n",
|
|
" phi_n_map = {}\n",
|
|
" correspondence_n_map = {}\n",
|
|
" for gen_key in g.keys():\n",
|
|
" deg = gen_key[0]\n",
|
|
" index = gen_key[1]\n",
|
|
" new_var = 'x'+str(deg)+'_'+str(index)\n",
|
|
" new_names += [new_var]\n",
|
|
" new_degrees += [deg]\n",
|
|
" phi_n_map[new_var] = g[gen_key]\n",
|
|
" correspondence_n_map[new_var] = cohomology_gens[gen_key]\n",
|
|
" gca = GradedCommutativeAlgebra(QQ, names=new_names, degrees=new_degrees)\n",
|
|
" new_M = update_cdga(gca, differentials)\n",
|
|
" new_phi[dim] = phi_n_map\n",
|
|
" new_correspondence[dim] = correspondence_n_map\n",
|
|
" return [new_M, new_phi, new_names, new_degrees, new_correspondence]\n",
|
|
" \n",
|
|
"def minimal_model(S, max_depth=5, max_dim=5):\n",
|
|
" \n",
|
|
" fundamental_group = S.fundamental_group()\n",
|
|
" if (fundamental_group.order() != 1):\n",
|
|
" print(\"Warning: The space is not simply-connected\")\n",
|
|
" phi = {}\n",
|
|
" cohomology_correspondence = {}\n",
|
|
" A = AlgebraAplK(S)\n",
|
|
" # First step of the algorithm\n",
|
|
" first_dim = A.first_cohomology_group()\n",
|
|
" phi_n_map = {}\n",
|
|
" correspondence_n_map = {}\n",
|
|
" if first_dim < 0:\n",
|
|
" return [0,{},{}] # due to the function returns multiple objects\n",
|
|
" elif first_dim > max_dim:\n",
|
|
" return [0,{},{}] # due to the function returns multiple objects\n",
|
|
" g = A.get_cohomology_aplk(first_dim)\n",
|
|
" cohomology_gens = A.cohomology_gens(first_dim)\n",
|
|
" names = []\n",
|
|
" degrees = []\n",
|
|
" for gen_key in g.keys():\n",
|
|
" deg = gen_key[0]\n",
|
|
" index = gen_key[1]\n",
|
|
" new_var = 'x'+str(deg)+'_'+str(index)\n",
|
|
" names += [new_var]\n",
|
|
" degrees += [deg]\n",
|
|
" phi_n_map[new_var] = g[gen_key]\n",
|
|
" correspondence_n_map[new_var] = cohomology_gens[gen_key]\n",
|
|
" differentials={}\n",
|
|
" gca = GradedCommutativeAlgebra(QQ, names=names, degrees=degrees)\n",
|
|
" M = gca.cdg_algebra(differentials)\n",
|
|
" phi[first_dim] = phi_n_map\n",
|
|
" cohomology_correspondence[first_dim] = correspondence_n_map\n",
|
|
" # Now we have an isomorphism in the first non-null cohomology group\n",
|
|
" # we check if phi is a monomorphism\n",
|
|
" [M, phi, names, degrees, differentials, limit] = injectivity_step(M, phi, first_dim+1, names, \n",
|
|
" degrees, differentials, index=0, depth=0, max_depth=5)\n",
|
|
" if limit:\n",
|
|
" print(\"The algorithm has reach the injectivity depth-limit at dimension \", first_dim)\n",
|
|
" return [M, phi]\n",
|
|
" else:\n",
|
|
" dim = first_dim + 1\n",
|
|
" for i in range(dim, max_dim):\n",
|
|
" [M, phi, names, degrees, cohomology_correspondence] = surjective_step(A, M, phi, i, names, degrees, \n",
|
|
" differentials, cohomology_correspondence)\n",
|
|
" [M, phi, names, degrees, differentials, limit] = injectivity_step(M, phi, i+1, names, \n",
|
|
" degrees, differentials, index=0, depth=0, max_depth=5)\n",
|
|
" if limit:\n",
|
|
" print(\"The algorithm has reach the injectivity depth-limit at dimension\", dim)\n",
|
|
" break \n",
|
|
" \n",
|
|
" return [M, phi, cohomology_correspondence]\n",
|
|
"\n",
|
|
"# def minimal_model():\n",
|
|
"# names = ['x1_0','x1_1']\n",
|
|
"# degrees = (1,1)\n",
|
|
"# differentials={}\n",
|
|
"# gca = GradedCommutativeAlgebra(QQ, names=names, degrees=degrees)\n",
|
|
"# cdga = gca.cdg_algebra(differentials)\n",
|
|
"# print(cdga)\n",
|
|
"# # añadimos el generador de grado uno con differencial producto de los anteriores\n",
|
|
"# new_gen = 'y1_0'\n",
|
|
"# names = names + [new_gen]\n",
|
|
"# deg = 1\n",
|
|
"# degrees = tuple(list(degrees)+[deg])\n",
|
|
"# differentials.update({'y1_0':['x1_0','x1_1']})\n",
|
|
"# gca = GradedCommutativeAlgebra(QQ, names=names, degrees=degrees)\n",
|
|
"# new_cdga = update_cdga(gca, differentials)\n",
|
|
"# print(new_cdga)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 107,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Injectivity at dimension 3\n",
|
|
"Surjectivity at dimension 3\n",
|
|
"Injectivity at dimension 4\n",
|
|
" Proceed to kill x2_0^2 because has associated trivial cohomology class\n",
|
|
"Adding generator y3_0\n",
|
|
"Injectivity at dimension 4\n",
|
|
"x2_0^2 has preimage y3_0\n",
|
|
" Proceed to kill x2_0*x2_1 because has associated trivial cohomology class\n",
|
|
"Adding generator y3_1\n",
|
|
"Injectivity at dimension 4\n",
|
|
"x2_0^2 has preimage y3_0\n",
|
|
"x2_0*x2_1 has preimage y3_1\n",
|
|
" Proceed to kill x2_1^2 because has associated trivial cohomology class\n",
|
|
"Adding generator y3_2\n",
|
|
"Injectivity at dimension 4\n",
|
|
"x2_0^2 has preimage y3_0\n",
|
|
"x2_0*x2_1 has preimage y3_1\n",
|
|
"x2_1^2 has preimage y3_2\n",
|
|
"Surjectivity at dimension 4\n",
|
|
"Injectivity at dimension 5\n",
|
|
"The element x2_0*y3_0 is not closed\n",
|
|
"The element x2_0*y3_1 is not closed\n",
|
|
"The element x2_0*y3_2 is not closed\n",
|
|
"The element x2_1*y3_0 is not closed\n",
|
|
"The element x2_1*y3_1 is not closed\n",
|
|
"The element x2_1*y3_2 is not closed\n",
|
|
"Surjectivity at dimension 5\n",
|
|
"Injectivity at dimension 6\n",
|
|
"x2_0^3 has preimage x2_0*y3_0\n",
|
|
"x2_1^3 has preimage x2_1*y3_2\n",
|
|
"The element y3_0*y3_1 is not closed\n",
|
|
"The element y3_0*y3_2 is not closed\n",
|
|
"The element y3_1*y3_2 is not closed\n",
|
|
"Surjectivity at dimension 6\n",
|
|
"Injectivity at dimension 7\n",
|
|
"Surjectivity at dimension 7\n",
|
|
"Injectivity at dimension 8\n",
|
|
"x2_0^4 has preimage x2_0^2*y3_0\n",
|
|
"x2_1^4 has preimage x2_1^2*y3_2\n",
|
|
"Surjectivity at dimension 8\n",
|
|
"Injectivity at dimension 9\n",
|
|
"Surjectivity at dimension 9\n",
|
|
"Injectivity at dimension 10\n",
|
|
"x2_0^5 has preimage x2_0^3*y3_0\n",
|
|
"x2_1^5 has preimage x2_1^3*y3_2\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"Commutative Differential Graded Algebra with generators ('x2_0', 'x2_1', 'y3_0', 'y3_1', 'y3_2') in degrees (2, 2, 3, 3, 3) over Rational Field with differential:\n",
|
|
" x2_0 --> 0\n",
|
|
" x2_1 --> 0\n",
|
|
" y3_0 --> x2_0^2\n",
|
|
" y3_1 --> x2_0*x2_1\n",
|
|
" y3_2 --> x2_1^2"
|
|
]
|
|
},
|
|
"execution_count": 107,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# S = SimplicialComplex([[0,1],[0,2],[1,2]],is_mutable=False) # S^1\n",
|
|
"# S = SimplicialComplex([[0,1],[0,2],[1,2],[1,3],[2,3]],is_mutable=False) # S^1 wedge S^1\n",
|
|
"# S = SimplicialComplex([[0,1,2],[0,1,3],[0,2,3],[1,2,3]],is_mutable=False) # S^2\n",
|
|
"# S = SimplicialComplex([[0,1,2],[0,1,3],[0,2,3],[1,2,3],[3,4],[3,5],[4,5]],is_mutable=False) # S^1 wedge S^2\n",
|
|
"# S = SimplicialComplex([[0,1,2],[0,3,4],[1,3,5]],is_mutable=False) # S^1 surrounded by 2-cells\n",
|
|
"# S = SimplicialComplex([[0,1,2],[0,1,3],[0,2,3],[1,2,3],[3,4,5],[3,4,6],[3,5,6],[4,5,6]],is_mutable=False) # S^2 wedge S^2\n",
|
|
"# S = SimplicialComplex([[0,1,2],[0,1,3],[0,2,3],[1,2,3],[0,2,4],[0,3,4],[2,3,4]],is_mutable=False) # S^2 wedge S^2\n",
|
|
"# S = SimplicialComplex([[0,2,3],[0,2,4,5],[0,1,2,5],[1,2,3,6],[2,3,4,6],[0,1,3,7],[0,3,4,7]],is_mutable=False) # S^2 wedge S^2\n",
|
|
"# S = simplicial_complexes.Torus()\n",
|
|
"#######################################################\n",
|
|
"# S = simplicial_complexes.Sphere(2)\n",
|
|
"#######################################################\n",
|
|
"# S = simplicial_complexes.K3Surface()\n",
|
|
"#######################################################\n",
|
|
"S1 = simplicial_complexes.Sphere(2)\n",
|
|
"S2 = simplicial_complexes.Sphere(2)\n",
|
|
"S = S1.wedge(S2, is_mutable=False)\n",
|
|
"#######################################################\n",
|
|
"#S = simplicial_complexes.ComplexProjectivePlane()\n",
|
|
"#######################################################\n",
|
|
"# S = simplicial_complexes.BrucknerGrunbaumSphere()\n",
|
|
"#######################################################\n",
|
|
"# S = simplicial_complexes.ProjectivePlane().wedge(simplicial_complexes.Sphere(2), is_mutable=False)\n",
|
|
"#######################################################\n",
|
|
"[sullivan_model, model_morphism, cohomology_correspondence] = minimal_model(S, max_depth=5, max_dim=10)\n",
|
|
"sullivan_model"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 108,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[x2_0^3, x2_0^2*x2_1, x2_0*x2_1^2, x2_1^3, y3_0*y3_1, y3_0*y3_2, y3_1*y3_2]"
|
|
]
|
|
},
|
|
"execution_count": 108,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"sullivan_model.basis(6)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 109,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{2: [x2_0, x2_1], 5: [x2_1*y3_0 - x2_0*y3_1, x2_1*y3_1 - x2_0*y3_2]}"
|
|
]
|
|
},
|
|
"execution_count": 109,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"sullivan_model.cohomology_generators(10)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 110,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"a = model_morphism[2]['x2_0']^2\n",
|
|
"b = model_morphism[3]['y3_0'] # no deberia salir 0"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 111,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"ename": "KeyError",
|
|
"evalue": "()",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[0;32m/tmp/ipykernel_7283/764669733.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msolve_primitive\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
|
"\u001b[0;32m/tmp/ipykernel_7283/334124851.py\u001b[0m in \u001b[0;36msolve_primitive\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 214\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 215\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0msolve_primitive\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 216\u001b[0;31m \u001b[0mp_basis\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_primitive_basis\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 217\u001b[0m \u001b[0md_basis\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_differential_basis\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp_basis\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 218\u001b[0m \u001b[0mdiff_matrix\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_differential_matrix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp_basis\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0md_basis\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
|
"\u001b[0;32m/tmp/ipykernel_7283/334124851.py\u001b[0m in \u001b[0;36m_get_primitive_basis\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 35\u001b[0m \u001b[0mprimitive_basis\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msimplex\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 36\u001b[0m \u001b[0;31m# add primitive elements related to the assigned polynomial\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 37\u001b[0;31m \u001b[0mpol\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0melements\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msimplex\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 38\u001b[0m \u001b[0mprimitive_basis\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msimplex\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mpol\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_primitive_basis\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 39\u001b[0m \u001b[0mprimitive_basis\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msimplex\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprimitive_basis\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msimplex\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
|
"\u001b[0;31mKeyError\u001b[0m: ()"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"a.solve_primitive()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 112,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"S1 = simplicial_complexes.Sphere(2)\n",
|
|
"S2 = simplicial_complexes.Sphere(2)\n",
|
|
"S = S1.wedge(S2, is_mutable=False)\n",
|
|
"A = AlgebraAplK(S)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 113,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"Finite family {(0, 0): h^{0,0}, (2, 0): h^{2,0}, (2, 1): h^{2,1}}"
|
|
]
|
|
},
|
|
"execution_count": 113,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"S.cohomology_ring().basis()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 137,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{[x2_1*y3_0 - x2_0*y3_1]: (), [x2_1*y3_1 - x2_0*y3_2]: ()}"
|
|
]
|
|
},
|
|
"execution_count": 137,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"#def get_ker_elements(sullivan_model, model_morphism, A, dim):\n",
|
|
"dim = 5\n",
|
|
"# Get the basis of Hm\n",
|
|
"hm_basis = sullivan_model.cohomology(dim).basis()\n",
|
|
"Hc = A.cohomology_group(dim)\n",
|
|
"apl_correspondence = {}\n",
|
|
"cochain_correspondence = {}\n",
|
|
"Hc_correspondence = {}\n",
|
|
"M = zero_matrix(QQ,len(Hc.basis()),len(hm_basis))\n",
|
|
"i = 0\n",
|
|
"hm_basis_keys = list(hm_basis.keys())\n",
|
|
"for gen in hm_basis_keys:\n",
|
|
" # get an element of the basis of Hm\n",
|
|
" # get a representative of a cohomology class in M\n",
|
|
" gen_repr = gen.representative()\n",
|
|
" # get the apl representative for each generator of M^p\n",
|
|
" m_gens = gen_repr.parent().gens()\n",
|
|
" aplgens = [model_morphism[g.degree()][str(g)] for g in m_gens]\n",
|
|
" apl_correspondence[gen] = A.null_element()\n",
|
|
" for exp in gen_repr.dict().keys():\n",
|
|
" coef = gen_repr.dict()[exp]\n",
|
|
" term = coef*prod([gen^e for gen,e in zip(aplgens, exp)])\n",
|
|
" apl_correspondence[gen] += term\n",
|
|
" cochain = apl_correspondence[gen].integral()\n",
|
|
" cochain_correspondence[gen] = cochain\n",
|
|
" vcochain = A.cochain_to_vector(cochain,dim)\n",
|
|
" Hc_correspondence[gen] = Hc(vcochain)\n",
|
|
" M[:,i] = Hc_correspondence[gen]\n",
|
|
" i+=1\n",
|
|
" \n",
|
|
"Hc_correspondence\n",
|
|
"\n",
|
|
"# falta crear la matriz"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 138,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"((1, 0), (0, 1))"
|
|
]
|
|
},
|
|
"execution_count": 138,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"Kgens = M.right_kernel().gens()\n",
|
|
"Kgens"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 148,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[x2_1*y3_0 - x2_0*y3_1, x2_1*y3_1 - x2_0*y3_2]"
|
|
]
|
|
},
|
|
"execution_count": 148,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"[e.representative() for e in hm_basis_keys]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"gdca_basis = gen_repr.parent().basis(gen_repr.degree())\n",
|
|
"gdca_basis"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"print(gen_repr.dict())\n",
|
|
"gen_repr.parent().gens()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"Hc_2 = A.cohomology_group(2).basis()\n",
|
|
"#A.lift_cochain(A.vector_to_cochain(Hc_2.lift((0,1)),2))\n",
|
|
"Hc_2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"\n",
|
|
"\n",
|
|
"element = Hm_basis[2][0] + Hm_basis[2][1]\n",
|
|
"def integralPhiCohomology(element):\n",
|
|
" aplelement = model_morphism[2][str(element)]\n",
|
|
" cochain = aplelement.integral()\n",
|
|
" vcochain = A.cochain_to_vector(cochain,2)\n",
|
|
" Hc_2 = A.cohomology_group(2)\n",
|
|
" return Hc_2(vcochain)\n",
|
|
"integralPhiCohomology(element)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"Hc_basis = A.cohomology_gens(2)\n",
|
|
"cochain0 = A.lift_cohomology_generator(list(Hc_basis.values())[0])\n",
|
|
"cochain1 = A.lift_cohomology_generator(list(Hc_basis.values())[1])\n",
|
|
"vcochain0 = A.cochain_to_vector(cochain0,2)\n",
|
|
"vcochain1 = A.cochain_to_vector(cochain1,2)\n",
|
|
"vcochain = vcochain0-3*vcochain1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"Hc_2 = A.cohomology_group(2)\n",
|
|
"Hc_2(vcochain)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Example step by step"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"K = simplicial_complexes.ComplexProjectivePlane()\n",
|
|
"A = AlgebraAplK(K)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# get the lowest dim for which H^{dim} is not trivial\n",
|
|
"first_dim = A.first_cohomology_group()\n",
|
|
"first_dim"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"g = A.get_cohomology_aplk(first_dim)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"g = A.get_cohomology_aplk(first_dim)\n",
|
|
"cohomology_gens = A.cohomology_gens(first_dim)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"cohomology_gens"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"names = []\n",
|
|
"degrees = []\n",
|
|
"phi = {}\n",
|
|
"phi_n_map = {}\n",
|
|
"cohomology_correspondence = {}\n",
|
|
"correspondence_n_map = {}\n",
|
|
"for gen_key in g.keys():\n",
|
|
" deg = gen_key[0]\n",
|
|
" index = gen_key[1]\n",
|
|
" new_var = 'x'+str(deg)+'_'+str(index)\n",
|
|
" names += [new_var]\n",
|
|
" degrees += [deg]\n",
|
|
" phi_n_map[new_var] = g[gen_key]\n",
|
|
" correspondence_n_map[new_var] = cohomology_gens[gen_key]\n",
|
|
"differentials={}\n",
|
|
"gca = GradedCommutativeAlgebra(QQ, names=names, degrees=degrees)\n",
|
|
"M = gca.cdg_algebra(differentials)\n",
|
|
"phi[first_dim] = phi_n_map\n",
|
|
"cohomology_correspondence[first_dim] = correspondence_n_map"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"r = phi[2]['x2_0']"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"count = 0\n",
|
|
"for s in r.elements.keys():\n",
|
|
" if len(s)==5:\n",
|
|
" v = r.elements[s]\n",
|
|
" if v != 0:\n",
|
|
" count += 1\n",
|
|
" print(s, \" ==> \", v)\n",
|
|
"print(count)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"r = (phi[2]['x2_0']^2)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"count = 0\n",
|
|
"for s in r.elements.keys():\n",
|
|
" if len(s)==5:\n",
|
|
" v = r.elements[s]\n",
|
|
" if v != 0:\n",
|
|
" count += 1\n",
|
|
" print(s, \" ==> \", v)\n",
|
|
"print(count)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"M.cohomology(4)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"A.cohomology_gens(4)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"c = M.cohomology(4)\n",
|
|
"c"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"K.cohomology(4,base_ring=QQ)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"M"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"dim = 2\n",
|
|
"# Get the basis of Hm\n",
|
|
"hm_basis = M.cohomology(dim).basis()\n",
|
|
"Hc = A.cohomology_group(dim)\n",
|
|
"apl_correspondence = {}\n",
|
|
"cochain_correspondence = {}\n",
|
|
"Hc_correspondence = {}\n",
|
|
"Mat = zero_matrix(QQ,len(Hc.basis()),len(hm_basis))\n",
|
|
"i = 0\n",
|
|
"for gen in list(hm_basis.keys()):\n",
|
|
" # get an element of the basis of Hm\n",
|
|
" # get a representative of a cohomology class in M\n",
|
|
" gen_repr = gen.representative()\n",
|
|
" # get the apl representative for each generator of M^p\n",
|
|
" m_gens = gen_repr.parent().gens()\n",
|
|
" aplgens = [phi[g.degree()][str(g)] for g in m_gens]\n",
|
|
" apl_correspondence[gen] = A.null_element()\n",
|
|
" for exp in gen_repr.dict().keys():\n",
|
|
" coef = gen_repr.dict()[exp]\n",
|
|
" term = coef*prod([gen^e for gen,e in zip(aplgens, exp)])\n",
|
|
" apl_correspondence[gen] += term\n",
|
|
" cochain = apl_correspondence[gen].integral()\n",
|
|
" cochain_correspondence[gen] = cochain\n",
|
|
" vcochain = A.cochain_to_vector(cochain,dim)\n",
|
|
" Hc_correspondence[gen] = Hc(vcochain)\n",
|
|
" Mat[:,i] = Hc_correspondence[gen]\n",
|
|
" i+=1\n",
|
|
"Hc_correspondence"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"M.cohomology(2)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"K.cohomology(5,base_ring=QQ)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"gca = GradedCommutativeAlgebra(QQ, names=['x2_0','y5_0'], degrees=(2,5))\n",
|
|
"differentials = {gca.gens()[1]:gca.gens()[0]^3}\n",
|
|
"M = gca.cdg_algebra(differentials)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "SageMath 9.2",
|
|
"language": "sage",
|
|
"name": "sagemath"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.8.5"
|
|
},
|
|
"toc-autonumbering": false,
|
|
"toc-showmarkdowntxt": false
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|