{ "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 }