{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We want to compute $A_4^*$. In other words, we are looking for the coefficients of a convex polynomial\n",
"$$p(x, y) = \\sum_{i=0}^{2d} c_i x^i y^{2d-i}$$\n",
"that maximizes\n",
"$$\\frac{c_4}{70}.$$\n",
"and satisfies\n",
"$p(1, 0) + p(0, 1) = 2$, or equivalently $c_0 + c_8 = 1$.\n",
"\n",
"In the following we perform a series of symmetry reduction techniques that will allow us to solve this problem analytically.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"code_folding": [
3,
17
]
},
"outputs": [],
"source": [
"# Some helpful functions\n",
"\n",
"# The following function creates an N x N symmetric symbolic matrix\n",
"def symb_matrix(N, base_name='Q_%d%d', sym=False):\n",
" var_swapper = lambda i,j: (i, j)\n",
" if sym:\n",
" var_swapper = lambda i,j: (min(i,j), max(i,j))\n",
" \n",
" Q_varnames = ','.join([base_name % var_swapper( i,j) for (i,j) in cartesian_product([range(N),range(N)])])\n",
" Q_vars = var(Q_varnames) \n",
" Q = matrix(SR,N,N,Q_vars)\n",
" \n",
" return Q\n",
"\n",
"\n",
"# the following function gives a full rank description of\n",
"# matrices `Q` that satisfy the equations in `eqn`\n",
"def eliminate_var_matrix(Q, eqn, name, additional_vars=[]):\n",
" all_vars = list(Q.variables())\n",
" all_vars += additional_vars\n",
" all_vars = map(SR, all_vars)\n",
"\n",
" sols = solve(map(lambda eqn_i: SR(eqn_i) == 0, eqn), all_vars)\n",
" sols = sols[0]\n",
" \n",
" # write Q as sum ri * Fi, where Fi are constant matrices\n",
" r_F = [(term.rhs(), jacobian(Q, term.lhs())[0,0]) for term in sols]\n",
" Fr = sum([ri * Fi for ri, Fi in r_F])\n",
" \n",
" # substitue the variables ri with their full rank descirption\n",
" var_to_sub = sum([list(term.rhs().variables()) for term in sols], [])\n",
" var_sub = {v: var(name+str(i)) for i,v in enumerate(var_to_sub)}\n",
" return Fr.subs(var_sub)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Reducing the number of coefficients in $p$\n",
"\n",
"Note that if $p$ is such a polynomial, then so is $p(-x, -y)$, so we\n",
"can assume that $p$ is even (i.e., $c_i = 0$ for $i=1,3,5,7$). Furthermore, if $p$ is a solution, so is\n",
"$p(y, x)$, so we can assume that $p$ is symmetric (i.e., $c_i = c_{8-i}$). All in all, without\n",
"loss of generality we assume\n",
"\n",
"$$p(x, y) = x^8 + y^8 + \\alpha x^4y^4 + \\beta (x^2y^6 + x^6y^2) \\text{ for some $\\alpha, \\beta \\in \\mathbb R$}.$$\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
"b*x^6*y^2 + a*x^4*y^4 + b*x^2*y^6 + x^8 + y^8"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%display latex\n",
"d = 4\n",
"R. = QQ['a,b,x,y,u,v']\n",
"vars = [x,y,u,v]\n",
"q = x^8 + y^8 + a*x^4*y^4 + b*(x^2*y^6 + x^6*y^2)\n",
"q"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Formulating the problem as an SDP\n",
"Because of Theorem 3.6, imposing the condition on the convexity of $p$ we can formulated as a search problem for an $8 \\times 8$ positive semidefinite matrix $Q$ that satisfies\n",
" $${\\mathbf u}^T\\nabla^2q({\\mathbf x}){\\mathbf u} = z^TQz \\quad \\forall {\\mathbf x},{\\mathbf u} \\in \\mathbb R^2$$\n",
" where\n",
"$$z^T({\\mathbf x}, {\\mathbf u}) = (u x^{2d}, ux^{2d-1}y, \\ldots, v y^{2d}, v x^{2d}, v x^{2d-1}y, \\ldots, v y^{2d}).$$\n",
"\n",
"Once we have $Q$, we can recover the polynomial $q$ via Euler's identity as follows:\n",
"\n",
"$$q(\\mathbf x) = \\frac1{8 \\cdot 7} z(\\mathbf x, \\mathbf x)^T Q z(\\mathbf x, \\mathbf x)$$\n",
"\n",
"\n",
"Therefore, the objective function ca be written exclusively in terms of the matrix $Q$, and we can rewrite our optimization problem (*) completely in terms of the matrix $Q$ as follows:\n",
"\n",
"$$\\max_{Q \\succeq 0} Q \\text{ s.t. } Q \\in \\mathcal L$$\n",
"where $\\mathcal L$ is the following linear space\n",
"$$\\{Q \\; | \\; \\exists q = x^8 + y^8 + \\alpha x^4y^4 + \\beta (x^2y^6 + x^6y^2) \\text{ s.t. } {\\mathbf u}^T\\nabla^2q({\\mathbf x}){\\mathbf u} = z^TQz.\\}$$"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"code_folding": []
},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
"[Q_00 Q_01 Q_02 Q_03 Q_04 Q_05 Q_06 Q_07]\n",
"[Q_01 Q_11 Q_12 Q_13 Q_14 Q_15 Q_16 Q_17]\n",
"[Q_02 Q_12 Q_22 Q_23 Q_24 Q_25 Q_26 Q_27]\n",
"[Q_03 Q_13 Q_23 Q_33 Q_34 Q_35 Q_36 Q_37]\n",
"[Q_04 Q_14 Q_24 Q_34 Q_44 Q_45 Q_46 Q_47]\n",
"[Q_05 Q_15 Q_25 Q_35 Q_45 Q_55 Q_56 Q_57]\n",
"[Q_06 Q_16 Q_26 Q_36 Q_46 Q_56 Q_66 Q_67]\n",
"[Q_07 Q_17 Q_27 Q_37 Q_47 Q_57 Q_67 Q_77]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\n",
"Q = symb_matrix(8, 'Q_%d%d', sym=True)\n",
"Q"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"code_folding": []
},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
"[-w53 + 2*w62 - 2*w63 - 28*w68 + w71 + w73 - 2*w74 + 28 w62 - w63 - 12*w68 + w72 0 w65 - w67 + w70 -1/2*w48 + 1/2*w56 + w57 -1/2*w48 - 1/2*w56 1/2*w44 - 1/2*w54 + w55 -1/2*w44 - 1/2*w54]\n",
"[ w62 - w63 - 12*w68 + w72 w53 w65 -w67 - w70 w48 -w57 w44 -w55]\n",
"[ 0 w65 w53 - 2*w62 + 2*w63 + 28*w68 - w71 - w73 + 2*w74 + 28 w62 -1/2*w44 + 1/2*w54 - w55 -1/2*w44 - 1/2*w54 1/2*w48 - 1/2*w56 - w57 -1/2*w48 - 1/2*w56]\n",
"[ w65 - w67 + w70 -w67 - w70 w62 -w53 - 2*w63 - 2*w72 + 12*w74 w54 w55 w56 w57]\n",
"[ -1/2*w48 + 1/2*w56 + w57 w48 -1/2*w44 + 1/2*w54 - w55 w54 -4*w62 + 2*w63 + 54*w68 - w71 - 2*w72 w63 -2*w65 + w67 - w70 w67]\n",
"[ -1/2*w48 - 1/2*w56 -w57 -1/2*w44 - 1/2*w54 w55 w63 2*w68 - w73 w70 0]\n",
"[ 1/2*w44 - 1/2*w54 + w55 w44 1/2*w48 - 1/2*w56 - w57 w56 -2*w65 + w67 - w70 w70 w71 w72]\n",
"[ -1/2*w44 - 1/2*w54 -w55 -1/2*w48 - 1/2*w56 w57 w67 0 w72 w73]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# vector of monomial\n",
"z = vector((x^3*u - y^3*v, x*y^2*u - x^2*y*v,\n",
" x^3*u + y^3*v, x*y^2*u + x^2*y*v, \n",
" x^2*y*u - x*y^2*v, y^3*u - x^3*v,\n",
" x^2*y*u + x*y^2*v, y^3*u + x^3*v))\n",
"\n",
"# hessian of q\n",
"Hq = jacobian(jacobian(q, (x, y)), (x, y))\n",
"\n",
"# Q is in L if the following polynomial has all its coefficients equal to 0\n",
"diff = z * Q * z - vector([u,v]) * Hq * vector([u, v])\n",
"eqn_L = QQ[Q.variables() + (a,b)][x,y,u,v](diff).coefficients()\n",
"\n",
"\n",
"Q_L = eliminate_var_matrix(Q, eqn_L, 'w', [a])\n",
"Q_L"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
"1/70*w74"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# write the objective function in terms of the new paramterization\n",
"q_from_Q = (z*Q_L*z).subs({u:x, v:y}) / (2*d*(2*d-1))\n",
"q_from_Q = QQ[Q_L.variables()][x,y](q_from_Q)\n",
"objective = q_from_Q.coefficient({xi: 4 for xi in q_from_Q.variables()}) / binomial(2*d, d)\n",
"objective = objective.base_ring()(objective)\n",
"objective"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## Symmetry reduction techniques applied to $Q$\n",
"\n",
"Let $\\rho: \\mathbb R^4 \\mapsto \\mathbb R^4$ be any linear transformation of the variables $(x,y,u,v)$ that leaves the coefficient of $x^4y^4$ in $p$ invariant and leaves polynomial $q(x,y,u,v) := {\\mathbf u}^T\\nabla^2q({\\mathbf x}){\\mathbf u}$ invariant, i.e.\n",
"$$q(x,y,u,v) = q \\circ \\rho(x,y,u,v).$$\n",
"The function $\\rho$ naturally acts linearly on the vector $z(\\mathbf x, \\mathbf y)$. If we call the $8 \\times 8$ matrix of this linear operator $M_\\rho$, then \n",
"\n",
"$$Q \\in \\mathcal L \\iff M_\\rho^T Q M_\\rho \\in \\mathcal L.$$\n",
" \n",
" \n",
"Let $G$ be a group of such transformations $\\rho$, then $Q$ is an optimal solution for (*) if and only if\n",
"\n",
"$$Q^* = \\frac1{|G|} \\sum_{\\rho \\in G} M_\\rho^T Q M_\\rho$$\n",
"\n",
"is also a solution. \n",
"\n",
"We will take $G$ to be the group generated by the following transformations\n",
"\n",
"\\begin{align*}\n",
" (x,y,u,v) & \\mapsto (y,x,v,u)\\\\\n",
" \\cdot \\quad & \\mapsto (-x,y,-u,v)\\\\\n",
" \\cdot \\quad & \\mapsto (-x,-y,u,v)\\\\\n",
" \\cdot \\quad & \\mapsto (-x,y,u,-v).\n",
"\\end{align*}\n",
"\n",
"The matrix $Q^*$ will have a very structured sparsity pattern.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To make our computations exact, we work over the ring $R := \\mathbb Q[x,y,u,v]$ of polynomials in the variables $x,y,u,v$ with rational coefficients."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
"[\n",
"[0 1 0 0] [-1 0 0 0] [-1 0 0 0] [-1 0 0 0] [ 1 0 0 0]\n",
"[1 0 0 0] [ 0 1 0 0] [ 0 -1 0 0] [ 0 1 0 0] [ 0 -1 0 0]\n",
"[0 0 0 1] [ 0 0 -1 0] [ 0 0 1 0] [ 0 0 1 0] [ 0 0 1 0]\n",
"[0 0 1 0], [ 0 0 0 1], [ 0 0 0 1], [ 0 0 0 -1], [ 0 0 0 -1],\n",
"\n",
"[ 1 0 0 0]\n",
"[ 0 -1 0 0]\n",
"[ 0 0 -1 0]\n",
"[ 0 0 0 1]\n",
"]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"symmetries =[[y,x,v,u],\n",
" [-x,y,-u,v],\n",
" [-x,-y,u,v],\n",
" [-x,y,u,-v],\n",
" [x, -y, u, -v],\n",
" [x, -y, -u, v]]\n",
"symmetries_rho = map(lambda sym_i: matrix(QQ, jacobian(sym_i, vars)), symmetries)\n",
"symmetries_rho"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The group G has 16 elements\n"
]
}
],
"source": [
"G = gap.Group(symmetries_rho)\n",
"G = gap.Elements(G).sage()\n",
"G = [matrix(QQ, g_elem_i) for g_elem_i in G]\n",
"print(\"The group G has %d elements\"% len(G))"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"First two elements of M_rho\n"
]
},
{
"data": {
"text/html": [
""
],
"text/plain": [
"[\n",
"[1 0 0 0 0 0 0 0] [-1 0 0 0 0 0 0 0]\n",
"[0 1 0 0 0 0 0 0] [ 0 -1 0 0 0 0 0 0]\n",
"[0 0 1 0 0 0 0 0] [ 0 0 -1 0 0 0 0 0]\n",
"[0 0 0 1 0 0 0 0] [ 0 0 0 -1 0 0 0 0]\n",
"[0 0 0 0 1 0 0 0] [ 0 0 0 0 -1 0 0 0]\n",
"[0 0 0 0 0 1 0 0] [ 0 0 0 0 0 -1 0 0]\n",
"[0 0 0 0 0 0 1 0] [ 0 0 0 0 0 0 -1 0]\n",
"[0 0 0 0 0 0 0 1], [ 0 0 0 0 0 0 0 -1]\n",
"]"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# action of G on the vector of monomials z\n",
"rho_acting_on_z = [z.subs({vi: subi for vi,subi in zip(vars, g*vector(vars))}) for g in G]\n",
"\n",
"# matrix representation of that action\n",
"def compute_M_rho(rho_z):\n",
" return matrix(QQ,\n",
" [ [1 if zj == zi else -1 if zj == -zi else 0 for zi in z]\n",
" for zj in rho_z])\n",
"\n",
"M_rho = map(compute_M_rho, rho_acting_on_z)\n",
"print(\"First two elements of M_rho\")\n",
"M_rho[:2]"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Blocks on the diagonal of Q:\n"
]
},
{
"data": {
"text/html": [
""
],
"text/plain": [
"[\n",
"[-w53 + 2*w62 - 2*w63 - 28*w68 + w71 + w73 - 2*w74 + 28 w62 - w63 - 12*w68 + w72] [w53 - 2*w62 + 2*w63 + 28*w68 - w71 - w73 + 2*w74 + 28 w62] [-4*w62 + 2*w63 + 54*w68 - w71 - 2*w72 w63]\n",
"[ w62 - w63 - 12*w68 + w72 w53], [ w62 -w53 - 2*w63 - 2*w72 + 12*w74], [ w63 2*w68 - w73],\n",
"\n",
"[w71 w72]\n",
"[w72 w73]\n",
"]"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Thanks to the symmetry, Q^* is block diagonal\n",
"Q_star = sum(M.T *Q_L*M for M in M_rho) / len(M_rho)\n",
"print(\"Blocks on the diagonal of Q:\")\n",
"[Q_star[i:i+2, i:i+2] for i in range(0, 8, 2)]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The matrix $Q^*$ has therefore the form\n",
"$Q^* = diag(Q_1, Q_2, Q_3, Q_4)$,\n",
"where the $Q_i$ are $2 \\times 2$ symmetric matrices. $Q^* \\succeq 0$ if and only if $Q_1,\\ldots,Q_4 \\succeq 0$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Dual \n",
"\n",
"Let us now derive the dual of the previous problem"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
"[D0_00 D0_01| 0 0| 0 0| 0 0]\n",
"[D0_01 D0_11| 0 0| 0 0| 0 0]\n",
"[-----------+-----------+-----------+-----------]\n",
"[ 0 0|D1_00 D1_01| 0 0| 0 0]\n",
"[ 0 0|D1_01 D1_11| 0 0| 0 0]\n",
"[-----------+-----------+-----------+-----------]\n",
"[ 0 0| 0 0|D2_00 D2_01| 0 0]\n",
"[ 0 0| 0 0|D2_01 D2_11| 0 0]\n",
"[-----------+-----------+-----------+-----------]\n",
"[ 0 0| 0 0| 0 0|D3_00 D3_01]\n",
"[ 0 0| 0 0| 0 0|D3_01 D3_11]"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#DQ is the dual variable\n",
"DQi = [symb_matrix(2, 'D'+str(i)+'_%d%d', sym=True) for i in range(4)]\n",
"DQ = block_diagonal_matrix(DQi)\n",
"DQ"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us compute the lagrangian\n",
"\n",
"$$L(Q, D) = \\langle Q, D \\rangle + \\text{objective function}$$"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
"(-D0_00 + D0_11 + D1_00 - D1_11)*w53 + (2*D0_00 + 2*D0_01 - 2*D1_00 + 2*D1_01 - 4*D2_00)*w62 + (-2*D0_00 - 2*D0_01 + 2*D1_00 - 2*D1_11 + 2*D2_00 + 2*D2_01)*w63 + (-28*D0_00 - 24*D0_01 + 28*D1_00 + 54*D2_00 + 2*D2_11)*w68 + (D0_00 - D1_00 - D2_00 + D3_00)*w71 + (2*D0_01 - 2*D1_11 - 2*D2_00 + 2*D3_01)*w72 + (D0_00 - D1_00 - D2_11 + D3_11)*w73 + (-2*D0_00 + 2*D1_00 + 12*D1_11 + 1/70)*w74 + 28*D0_00 + 28*D1_00"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hessian = lambda pp: jacobian(jacobian(pp, (x,y)), (x,y))\n",
"dot = lambda u,v: vector(u) * vector(v)\n",
"mdot = lambda A, B: dot(A.list(), B.list())\n",
"\n",
"\n",
"lagrangian = mdot(DQ, Q_star) + objective\n",
"var_primal = Q_star.variables()\n",
"var_dual = DQ.variables()\n",
"lagrangian = QQ[var_dual][var_primal] (lagrangian)\n",
"lagrangian"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
"[ z28 z29 0 0 0 0 0 0]\n",
"[ z29 -7/6*z27 + 7/6*z28 - 1/840 0 0 0 0 0 0]\n",
"[ 0 0 z27 z27 - z28 - z29 + 2*z30 0 0 0 0]\n",
"[ 0 0 z27 - z28 - z29 + 2*z30 -1/6*z27 + 1/6*z28 - 1/840 0 0 0 0]\n",
"[ 0 0 0 0 z30 -7/6*z27 + 7/6*z28 + z29 - z30 - 1/840 0 0]\n",
"[ 0 0 0 0 -7/6*z27 + 7/6*z28 + z29 - z30 - 1/840 -14*z27 + 14*z28 + 12*z29 - 27*z30 0 0]\n",
"[ 0 0 0 0 0 0 z27 - z28 + z30 -1/6*z27 + 1/6*z28 - z29 + z30 - 1/840]\n",
"[ 0 0 0 0 0 0 -1/6*z27 + 1/6*z28 - z29 + z30 - 1/840 -13*z27 + 13*z28 + 12*z29 - 27*z30]"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Find a full rank description of the dual varialbe DQ\n",
"lagrang_coeffs = jacobian(lagrangian, var_primal)[0]\n",
"lagrang_coeffs = list(lagrang_coeffs)\n",
"DQ_star = eliminate_var_matrix(DQ, lagrang_coeffs, 'z')\n",
"DQ_star"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# use KKT conditions to transform the SDP to a system of polynomial equations"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"R = QQ[DQ_star.variables() + Q_star.variables()]\n",
"\n",
"# KKT equations\n",
"KKT_eqn = (DQ_star * Q_star).list()\n",
"KKT_eqn = list(set(KKT_eqn))\n",
"\n",
"# ideal generated by the KKT equations\n",
"I = map(lambda p: R(p), KKT_eqn)\n",
"I = R*I"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Ideal I has 17 equations in 12 variables\n"
]
}
],
"source": [
"print(\"Ideal I is generated by %d equations in %d variables\" % (len(I.gens()), len(R.gens())))"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
"Ideal (9*w74^14 - 2070*w74^13 + 170888*w74^12 - 5575088*w74^11 + 24286192*w74^10 + 1799298144*w74^9 - 13606662400*w74^8 - 140207761920*w74^7 + 434444465920*w74^6 + 3454598698496*w74^5 - 69628131328*w74^4 - 12362877284352*w74^3 - 5808164827136*w74^2 + 2696323768320*w74) of Multivariate Polynomial Ring in z27, z28, z29, z30, w53, w62, w63, w68, w71, w72, w73, w74 over Rational Field"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# eliminate all variables except those present in the objective function\n",
"I_a = I.elimination_ideal([v for v in R.gens() if SR(v) not in objective.variables()])\n",
"I_a"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The ideal I_a has 1 generator\n"
]
}
],
"source": [
"print(\"The ideal I_a has %d generator\" % len(I_a.gens()))"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
"6884147200*(42875*t^3 - 40425*t^2 - 2975*t + 13)*(3675*t^2 - 2870*t - 37)*(35*t + 1)*(35*t - 1)*(35*t - 3)*(35*t - 19)*(15*t + 1)*(5*t + 1)*(5*t - 1)*(t - 1)*t"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"var('t')\n",
"p = SR(I_a.gens()[0]).subs({SR(objective.variables()[0]): 70*t})\n",
"factor(p)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
"t^3 - 33/35*t^2 - 17/245*t + 13/42875"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"minimal_poly = p.factor_list()[0][0]\n",
"minimal_poly /= minimal_poly.coefficient(t^3)\n",
"minimal_poly"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
"[(-1/2*(I*sqrt(3) + 1)*(256/55125*I*sqrt(3) + 256/6125)^(1/3) - 32/525*(-I*sqrt(3) + 1)/(256/55125*I*sqrt(3) + 256/6125)^(1/3) + 11/35,\n",
" 1),\n",
" (-1/2*(256/55125*I*sqrt(3) + 256/6125)^(1/3)*(-I*sqrt(3) + 1) - 32/525*(I*sqrt(3) + 1)/(256/55125*I*sqrt(3) + 256/6125)^(1/3) + 11/35,\n",
" 1),\n",
" ((256/55125*I*sqrt(3) + 256/6125)^(1/3) + 64/525/(256/55125*I*sqrt(3) + 256/6125)^(1/3) + 11/35,\n",
" 1)]"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"minimal_poly.roots()"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
"[(-0.07246205065830763, 1),\n",
" (0.0041380873389235545, 1),\n",
" (1.0111811061765266, 1)]"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"minimal_poly.roots(ring=RDF)"
]
}
],
"metadata": {
"@webio": {
"lastCommId": null,
"lastKernelId": null
},
"kernelspec": {
"display_name": "SageMath 8.6",
"language": "",
"name": "sagemath"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.16"
}
},
"nbformat": 4,
"nbformat_minor": 2
}