{
"cells": [
{
"cell_type": "markdown",
"id": "southwest-albert",
"metadata": {},
"source": [
"# Greither unit index, a Sagemath implementation\n",
"Here we will implement some of the calculation from the article of Cornelius Greither: *“Improving Ramachandra’s and Levesque’s unit index”*. \n",
"In particular we will evaluate the index $i_\\beta$ in a very efficient way and the generators $\\xi_a(\\beta)$ of the group $C_\\beta$"
]
},
{
"cell_type": "markdown",
"id": "arranged-victoria",
"metadata": {},
"source": [
"## Definition of $n$ end its factorization"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "smaller-provincial",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/latex": [
"\\begin{math}\n",
"\\newcommand{\\Bold}[1]{\\mathbf{#1}}2^{2} \\cdot 3 \\cdot 7\n",
"\\end{math}"
],
"text/plain": [
"2^2 * 3 * 7"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"n=42*2\n",
"if n%4==2:\n",
" print('Error, n not accepted')\n",
"else:\n",
" fn = factor(n)\n",
" show(fn)"
]
},
{
"cell_type": "markdown",
"id": "seeing-manual",
"metadata": {},
"source": [
"Also we define these simple functions that we will use later to have a simple overview of the quatity used."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "recorded-continuity",
"metadata": {},
"outputs": [],
"source": [
"def p(i):\n",
" return fn[i-1][0]\n",
"def e(i):\n",
" return fn[i-1][1]\n",
"def pe(i):\n",
" return p(i)**e(i)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "quantitative-machine",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pe(1)"
]
},
{
"cell_type": "markdown",
"id": "differential-personality",
"metadata": {},
"source": [
"### Definition of the Power set $P_S$"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "seventh-pathology",
"metadata": {},
"outputs": [],
"source": [
"s = len(fn)\n",
"S = [ i +1 for i in range(s)]\n",
"PS = Subsets(S).list()\n",
"PS.remove(Set(S))"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "weekly-warner",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}]"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"PS"
]
},
{
"cell_type": "markdown",
"id": "minus-lover",
"metadata": {},
"source": [
"`nI(I)` evaluate the quantity $n=\\prod_{i\\in I} p_i^{e_i}$"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "addressed-kitty",
"metadata": {},
"outputs": [],
"source": [
"def nI(I):\n",
" ret = 1\n",
" for i in I:\n",
" ret *= pe(i)\n",
" return ret"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "turkish-martin",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"28"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nI({1,3})"
]
},
{
"cell_type": "markdown",
"id": "injured-butter",
"metadata": {},
"source": [
"## Definition of $\\zeta$ and the group $G$\n",
"Here we define the Cyclotomic Field $\\mathbb{Q}(\\zeta_n)$ and the variable `z` is assigned to $\\zeta_n$."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "partial-vanilla",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Cyclotomic Field of order 84 and degree 24"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Qn.=CyclotomicField(n)\n",
"(Qn)"
]
},
{
"cell_type": "markdown",
"id": "diverse-technique",
"metadata": {},
"source": [
"We could directly evaluate the group $G_0$ as the Galois group of the Field, but it uses a long computational time, so we will follows a different approach: defining $G$ directly from its elements. \n",
"Also I have done some functions to do some operations in $G$, but in the end I have not used them"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "scenic-holly",
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"(1,20,3,22,5,24)(2,21,4,23,6,19)(7,14,9,16,11,18)(8,15,10,17,12,13)"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"G_0 = Qn.galois_group() #loooooong time\n",
"G_0.an_element()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "accurate-antarctica",
"metadata": {},
"outputs": [],
"source": [
"G = [ a for a in [1..n//2] if gcd(a,n)==1]"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "floral-intention",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/latex": [
"\\begin{math}\n",
"\\newcommand{\\Bold}[1]{\\mathbf{#1}}\\left[1, 5, 11, 13, 17, 19, 23, 25, 29, 31, 37, 41\\right]\n",
"\\end{math}"
],
"text/plain": [
"[1, 5, 11, 13, 17, 19, 23, 25, 29, 31, 37, 41]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"show(G)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "hollow-offset",
"metadata": {},
"outputs": [],
"source": [
"def corr(r):\n",
" if r not in G:\n",
" r = n-r\n",
" return r\n",
"\n",
"def power(x,a):\n",
" r = power_mod(x,a,n)\n",
" return corr(r)\n",
"\n",
"def molt(x,y):\n",
" r = mod(x*y,n)\n",
" return corr(r)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "competitive-hayes",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"29"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"molt(5,11)"
]
},
{
"cell_type": "markdown",
"id": "processed-branch",
"metadata": {},
"source": [
"# Calculation of the index\n",
"First we define the number field $K$ as the Maximal Real subfield of $\\mathbb{Q}(\\zeta_n)$, using that is equal to $\\mathbb{Q}(\\zeta_n + \\zeta_n^{-1})$"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "hearing-division",
"metadata": {},
"outputs": [],
"source": [
"zz = z + z.conjugate()"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "imposed-coach",
"metadata": {},
"outputs": [],
"source": [
"K. = NumberField(zz.minpoly(),'zc')"
]
},
{
"cell_type": "markdown",
"id": "matched-julian",
"metadata": {},
"source": [
"We define $\\epsilon_i$ knowing that is equal to $\\phi(p_i^{e_i})$ and $g_i$ using its definition: we embed the the prime $p_i$ in $O_K$ and we factor it"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "passive-spectrum",
"metadata": {},
"outputs": [],
"source": [
"def eps(i):\n",
" return euler_phi(pe(i))"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "miniature-thursday",
"metadata": {},
"outputs": [],
"source": [
"def g(i):\n",
" I = K.ideal(p(i))\n",
" return len(I.factor())"
]
},
{
"cell_type": "markdown",
"id": "magnetic-circuit",
"metadata": {},
"source": [
"For $f_i$ we use the equality $[K:\\mathbb{Q}] = \\epsilon_i g_i f_i $ since we know the other three elements. \n",
"*Memo*: $[K:\\mathbb{Q}] = \\phi(n)/2 $ \n",
"Later we will see another possible evaluation (a bit slower) using the Frobenious morphism. "
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "underlying-workstation",
"metadata": {},
"outputs": [],
"source": [
"def f(i):\n",
" return euler_phi(n)/(2*g(i)*eps(i))"
]
},
{
"cell_type": "markdown",
"id": "plastic-syndication",
"metadata": {},
"source": [
"So we have that:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "taken-philippines",
"metadata": {},
"outputs": [],
"source": [
"def i_b():\n",
" i_b=1\n",
" for i in S:\n",
" i_b *= (eps(i)**(g(i)-1)) * (f(i)**(2*g(i) -1))\n",
" return i_b"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "accessory-swimming",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"648"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"i = i_b()\n",
"i"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "associate-praise",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/latex": [
"\\begin{math}\n",
"\\newcommand{\\Bold}[1]{\\mathbf{#1}}2^{3} \\cdot 3^{4}\n",
"\\end{math}"
],
"text/plain": [
"2^3 * 3^4"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"show(factor(i))"
]
},
{
"cell_type": "markdown",
"id": "helpful-arcade",
"metadata": {},
"source": [
"Here we have another evaluation of $i_\\beta$ that compress all the calculation to optimize the result"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "biological-recommendation",
"metadata": {},
"outputs": [],
"source": [
"def i_b_compressed(n):\n",
" fn = factor(n)\n",
" s = len(fn)\n",
" S = [ i +1 for i in range(s)]\n",
" K. = CyclotomicField(n)\n",
" zz = z + z.conjugate()\n",
" K = NumberField(zz.minpoly(),'a')\n",
" ibb=1\n",
" for j in S:\n",
" eps = euler_phi(fn[j-1][0]**fn[j-1][1])\n",
" g = len(K.ideal(fn[j-1][0]).factor())\n",
" f = euler_phi(n)/(2*g*eps)\n",
" ibb *= (eps**(g-1)) * (f**(2*g-1))\n",
" return ibb"
]
},
{
"cell_type": "code",
"execution_count": 47,
"id": "cooked-salem",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/latex": [
"\\begin{math}\n",
"\\newcommand{\\Bold}[1]{\\mathbf{#1}}2^{6} \\cdot 3^{8} \\cdot 5^{5}\n",
"\\end{math}"
],
"text/plain": [
"2^6 * 3^8 * 5^5"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"show(factor(i_b_compressed(5*7*11)))"
]
},
{
"cell_type": "code",
"execution_count": 48,
"id": "320bbdfa",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1312200000"
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"2**6 * 3**8 * 5**5"
]
},
{
"cell_type": "markdown",
"id": "4be9cb7a",
"metadata": {},
"source": [
"If we do the evaluation with Ramachandra's unit group we get:\n",
"$$ i_\\beta = 968 84935 06496 61515 61530 58565 67725 19049 20520 00000 $$"
]
},
{
"cell_type": "code",
"execution_count": 50,
"id": "8ef45cc9",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/latex": [
"\\begin{math}\n",
"\\newcommand{\\Bold}[1]{\\mathbf{#1}}2^{8} \\cdot 3^{2} \\cdot 5^{6} \\cdot 7^{5} \\cdot 11^{2} \\cdot 19^{4} \\cdot 31 \\cdot 61 \\cdot 71 \\cdot 181 \\cdot 191 \\cdot 281 \\cdot 521 \\cdot 1741 \\cdot 2801 \\cdot 4021 \\cdot 7621\n",
"\\end{math}"
],
"text/plain": [
"2^8 * 3^2 * 5^6 * 7^5 * 11^2 * 19^4 * 31 * 61 * 71 * 181 * 191 * 281 * 521 * 1741 * 2801 * 4021 * 7621"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"show(factor(968849350649661515615305856567725190492052000000))"
]
},
{
"cell_type": "markdown",
"id": "greenhouse-microwave",
"metadata": {},
"source": [
"# Generators construction\n",
"Now with several steps we proceed in the costruction of the generators, starting with the definition of $\\beta$"
]
},
{
"cell_type": "markdown",
"id": "handed-oklahoma",
"metadata": {},
"source": [
"## Definition the Frobenious morphism\n",
"Given $i \\in S$ we want to find a lift in $G_0$ of the frobenious morphism:\n",
"\n",
"\\begin{alignat*}{2}\n",
"\t\tF_i : \\mathbb{Q}(\\zeta_{n/p_i^{e_i}})^+ &\\longrightarrow \\: \\mathbb{Q}(\\zeta_{n/p_i^{e_i}})^+ \\\\\n",
"\t\t\\zeta_{n/p_i^{e_i}} &\\longmapsto \\: \\zeta_{n/p_i^{e_i}} ^ {p_i}\n",
"\\end{alignat*} \n",
"So we need an element $f$ that sends $\\zeta_{n/p_i^{e_i}} \\simeq \\zeta _n^{p_i^{e_i}}$ in $\\zeta _n^{p_i^{e_i+1}}= \\zeta _n^{p_i^{e_i} p_i}$"
]
},
{
"cell_type": "markdown",
"id": "correct-bleeding",
"metadata": {},
"source": [
"First we can see it as an integer in the list `G`"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "blank-leone",
"metadata": {},
"outputs": [],
"source": [
"def frob(i):\n",
" zi = z^pe(i)\n",
" for f in G:\n",
" if zi^f==zi^p(i):\n",
" return f"
]
},
{
"cell_type": "markdown",
"id": "legendary-implementation",
"metadata": {},
"source": [
"But also we can give the result directly as an automorphism of $\\mathbb{Q}(\\zeta_{n})$ (so an element in $G_0$). \n",
"**Remark**: With this costruction we directly considerate a lifting of the function without defining it on the field $\\mathbb{Q}(\\zeta_{n/p_i^{e_i}})^+$. \n",
"*Memo:* We have seen that the final results does not depends on the particular lifting"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "yellow-crash",
"metadata": {},
"outputs": [],
"source": [
"def frobhom(i):\n",
" zi = z^pe(i)\n",
" for f in G:\n",
" if zi^f==zi^p(i):\n",
" return Qn.hom([z**f])"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "finished-running",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Ring endomorphism of Cyclotomic Field of order 84 and degree 24\n",
" Defn: z |--> z^23"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(frobhom(1))"
]
},
{
"cell_type": "markdown",
"id": "medium-management",
"metadata": {},
"source": [
"Now to find the trace elements we need to have the order of the element $f$ in $G_i$. \n",
"We already know that this is the inertia degree of the prime $p_i$, but now we will follow a different approach.\n",
"Also here we define the morphism on $\\mathbb{Q}(\\zeta_{n/p_i^{e_i}})$ and we check when its generator (`zz`) is fixed. \n",
"**Remark**: is not the same of checking when $\\zeta$ is fixed"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "mathematical-marijuana",
"metadata": {},
"outputs": [],
"source": [
"def ford(i):\n",
" Qi.=CyclotomicField(n/pe(i))\n",
" f = Qi.hom([zi^p(i)])\n",
" o = 1\n",
" zz=zi+zi.conjugate()\n",
" while (not (f**o)(zz)==zz) : \n",
" o += 1\n",
" return o"
]
},
{
"cell_type": "markdown",
"id": "crucial-carbon",
"metadata": {},
"source": [
"We can see that the two results are indeed equivalent"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "studied-collective",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[True, True, True]"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"[ford(i)==f(i) for i in S]"
]
},
{
"cell_type": "markdown",
"id": "favorite-porter",
"metadata": {},
"source": [
"## Definition of $\\beta$ and its evaluation \n",
"We start defining its value on the singletons $\\{i\\}$. Also to have an elements in $\\mathbb{Z}[G_0]$ we simply use a list of elements in $G_0$, since we only need to evalutate them and we can simply use a recursive evalutation. \n",
"**Remark**: we use `f(i)` instead of `ford(i)` because it is faster"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "fifty-drove",
"metadata": {},
"outputs": [],
"source": [
"def beta0(i : int):\n",
" fi = frobhom(i)\n",
" return [ fi**j for j in range(f(i))]"
]
},
{
"cell_type": "markdown",
"id": "other-murray",
"metadata": {},
"source": [
"We anticipate the valutations on the singletons to save computational time later"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "endangered-chart",
"metadata": {},
"outputs": [],
"source": [
"vbeta = [beta0(i) for i in S]"
]
},
{
"cell_type": "markdown",
"id": "fifth-memphis",
"metadata": {},
"source": [
"For our costruction the only thing we need is $\\zeta ^{ \\beta(I)}$ (`valbeta(base,I)`), that we can evaluate starting from $\\zeta ^{ \\beta(i)}$ (`valbeta0(base,i)`) using that $\\beta(I) = \\prod_{i \\in S} \\beta(i)$ and $\\zeta^{\\gamma \\delta} = (\\zeta^\\gamma )^\\delta$"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "communist-burlington",
"metadata": {},
"outputs": [],
"source": [
"def valbeta0(base,i):\n",
" v = 1\n",
" for vf in vbeta[i-1]:\n",
" v *= vf(base)\n",
" return v"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "economic-exhibit",
"metadata": {},
"outputs": [],
"source": [
"def valbeta(base,I):\n",
" if I.is_empty():\n",
" return base\n",
" for i in I:\n",
" base = valbeta0(base,i)\n",
" return base"
]
},
{
"cell_type": "markdown",
"id": "developmental-cabin",
"metadata": {},
"source": [
"# Calculation of the generators\n",
"We proceed now with the evalutation of\n",
"\t$$ z(\\beta ):= \\prod_{I \\in P_S } z_I ^{\\beta(I)} $$ \n",
"where $ z_I := 1 - \\zeta ^{n_I}$"
]
},
{
"cell_type": "code",
"execution_count": 33,
"id": "internal-thumbnail",
"metadata": {},
"outputs": [],
"source": [
"def zbeta():\n",
" ret = 1\n",
" for I in PS:\n",
" zI= 1 - z**nI(I)\n",
" ret *= valbeta(zI,I)\n",
" return ret"
]
},
{
"cell_type": "markdown",
"id": "impaired-plaza",
"metadata": {},
"source": [
"We store it in the memory to save computational time later, also we can see that this is a very long and complicate element"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "naked-woman",
"metadata": {},
"outputs": [],
"source": [
"zb = zbeta()"
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "suitable-playlist",
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/latex": [
"\\begin{math}\n",
"\\newcommand{\\Bold}[1]{\\mathbf{#1}}4000752 z^{23} + 4000752 z^{22} + 2000376 z^{21} - 2000376 z^{19} - 4000752 z^{18} - 4000752 z^{17} + 4000752 z^{12} + 2000376 z^{11} + 2000376 z^{10} - 4000752 z^{9} - 2000376 z^{8} - 4000752 z^{7} - 2000376 z^{6} - 2000376 z^{5} + 2000376 z^{4} + 2000376 z^{2} + 2000376 z + 4000752\n",
"\\end{math}"
],
"text/plain": [
"4000752*z^23 + 4000752*z^22 + 2000376*z^21 - 2000376*z^19 - 4000752*z^18 - 4000752*z^17 + 4000752*z^12 + 2000376*z^11 + 2000376*z^10 - 4000752*z^9 - 2000376*z^8 - 4000752*z^7 - 2000376*z^6 - 2000376*z^5 + 2000376*z^4 + 2000376*z^2 + 2000376*z + 4000752"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"show(zb)"
]
},
{
"cell_type": "markdown",
"id": "fewer-sperm",
"metadata": {},
"source": [
"An interesting wall of numbers, however now we can use it to evaluate the elements \n",
"$$ \\zeta ^{\\frac{(1-a)}{2} n_I \\beta (I)} $$ \n",
"and\n",
"\\begin{equation}\n",
"\t\t\\zeta ^{(1-a)\\frac{t}{2}} \\text{ with } t = \\sum_{I \\in P_S} n_I \\beta(I) \n",
"\t\\end{equation}"
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "declared-russell",
"metadata": {},
"outputs": [],
"source": [
"def zdbeta(a,I):\n",
" d = (1-a)*nI(I)/2\n",
" valbeta(z^d,I)"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "hollow-techno",
"metadata": {},
"outputs": [],
"source": [
"def zdbeta(a):\n",
" ret = 1\n",
" d= (1-a)/2\n",
" for I in PS:\n",
" ret *= valbeta(z^(d*nI(I)),I)\n",
" return ret"
]
},
{
"cell_type": "markdown",
"id": "positive-intersection",
"metadata": {},
"source": [
"And finally we can evaluate\n",
"\t\\begin{equation}\n",
"\t\t\\xi_a (\\beta) := \\zeta ^{d_a (\\beta)} \\frac{\\sigma_a (z(\\beta))}{z(\\beta)} \\text{ with } d_a(\\beta)= (1-a)\\frac{t}{2}\n",
"\t\\end{equation}"
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "decent-psychology",
"metadata": {},
"outputs": [],
"source": [
"def xibeta(a):\n",
" sa = Qn.hom([z**a])\n",
" return zdbeta(a)*sa(zb)/zb"
]
},
{
"cell_type": "markdown",
"id": "selected-commission",
"metadata": {},
"source": [
"Consider a particulare case, we can easly see that the result is in the ring of integer $\\mathbb{Z}[\\zeta]$ and that it is real comparing itself with the conjugate"
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "miniature-scene",
"metadata": {},
"outputs": [],
"source": [
"a = G[3]\n",
"xi = xibeta(a)"
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "stainless-kitchen",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/latex": [
"\\begin{math}\n",
"\\newcommand{\\Bold}[1]{\\mathbf{#1}}11 z^{23} + 11 z^{22} + 20 z^{21} + 20 z^{20} + 20 z^{19} + 14 z^{18} + 3 z^{17} + 3 z^{16} - 14 z^{15} - 11 z^{14} - 14 z^{13} - 14 z^{12} - 3 z^{11} - 3 z^{10} - 3 z^{9} - 9 z^{8} - 12 z^{7} - 20 z^{6} - 31 z^{5} - 25 z^{4} - 31 z^{3} - 25 z^{2} - 14 z - 14\n",
"\\end{math}"
],
"text/plain": [
"11*z^23 + 11*z^22 + 20*z^21 + 20*z^20 + 20*z^19 + 14*z^18 + 3*z^17 + 3*z^16 - 14*z^15 - 11*z^14 - 14*z^13 - 14*z^12 - 3*z^11 - 3*z^10 - 3*z^9 - 9*z^8 - 12*z^7 - 20*z^6 - 31*z^5 - 25*z^4 - 31*z^3 - 25*z^2 - 14*z - 14"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"show(xi)"
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "american-aluminum",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"xi.conjugate()==xi"
]
},
{
"cell_type": "markdown",
"id": "digital-mambo",
"metadata": {},
"source": [
"Without looking to the the monomials we can also direclty look for coefficents not in $\\mathbb{Z}$"
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "described-still",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"[i for i in range(euler_phi(n)) if not (xi[i] in ZZ) ]"
]
},
{
"cell_type": "markdown",
"id": "bound-bible",
"metadata": {},
"source": [
"Infact the list is empty"
]
},
{
"cell_type": "code",
"execution_count": 43,
"id": "available-superior",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/latex": [
"\\begin{math}\n",
"\\newcommand{\\Bold}[1]{\\mathbf{#1}}28 z^{23} + 12 z^{22} + 6 z^{21} - 20 z^{20} - 34 z^{19} - 14 z^{18} - 14 z^{17} + 22 z^{16} + 14 z^{15} + 11 z^{14} + 3 z^{13} - 11 z^{12} + 14 z^{11} + 3 z^{10} - 11 z^{9} - 14 z^{8} - 29 z^{7} - 3 z^{6} + 6 z^{5} + 25 z^{4} + 31 z^{3} + 3 z - 22\n",
"\\end{math}"
],
"text/plain": [
"28*z^23 + 12*z^22 + 6*z^21 - 20*z^20 - 34*z^19 - 14*z^18 - 14*z^17 + 22*z^16 + 14*z^15 + 11*z^14 + 3*z^13 - 11*z^12 + 14*z^11 + 3*z^10 - 11*z^9 - 14*z^8 - 29*z^7 - 3*z^6 + 6*z^5 + 25*z^4 + 31*z^3 + 3*z - 22"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"show(xi^(-1))"
]
},
{
"cell_type": "markdown",
"id": "flush-storage",
"metadata": {},
"source": [
"# Calculation of the class number"
]
},
{
"cell_type": "markdown",
"id": "4f89e417",
"metadata": {},
"source": [
"We create the group:\n",
"$$ C_\\beta = \\left< -1 , \\xi_\\beta^a , \\text{ for } a \\in G \\right> $$"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "virtual-commodity",
"metadata": {},
"outputs": [],
"source": [
"C = [xibeta(a) for a in G[1:]]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "billion-amateur",
"metadata": {},
"outputs": [],
"source": [
"C.append(-(xi^0))"
]
},
{
"cell_type": "markdown",
"id": "5f88638d",
"metadata": {},
"source": [
"We consider the maximal real subfield $K$ and its unit group"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "amazing-guinea",
"metadata": {},
"outputs": [],
"source": [
"KK = Qn.subfield(zz)[0]\n",
"KK"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "rental-quality",
"metadata": {},
"outputs": [],
"source": [
"EK = UnitGroup(KK)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7c5b80d5",
"metadata": {},
"outputs": [],
"source": [
"We check that it contains the units"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "normal-royal",
"metadata": {},
"outputs": [],
"source": [
"[C[i] in EK for i in range(len(C)) ]"
]
},
{
"cell_type": "markdown",
"id": "55636c82",
"metadata": {},
"source": [
"We evaluate the subgroup of $E_K$ and its index (the cardinality of $E_K / C_\\beta$)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "impressed-baseline",
"metadata": {},
"outputs": [],
"source": [
"Cb = EK.subgroup(C)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "grave-testing",
"metadata": {},
"outputs": [],
"source": [
"H = EK.quotient(Cb)"
]
},
{
"cell_type": "markdown",
"id": "b9b0f3fd",
"metadata": {},
"source": [
"We use that \n",
"$$ [E_K:C_\\beta]=h_K i_\\beta $$\n",
"to finf the **Class number**"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b6fa6e4c",
"metadata": {},
"outputs": [],
"source": [
"H.cardinality()/i"
]
}
],
"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.9.1"
}
},
"nbformat": 4,
"nbformat_minor": 5
}