{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Algoritmo di rappresentazione dei polinomi simmetrici negli $e_i$\n", "\n", "Lo scopo di questo notebook è implementare l'algoritmo impiegato nella dimostrazione del _Teorema fondamentale dei polinomi simmetrici_, che, dato un campo $F$, asserisce il seguente isomorfismo:\n", "\n", "$$\\operatorname{Sym}[X_n] \\cong F[e_1, \\ldots, e_n],$$\n", "\n", "dove $X_n$ è l'insieme $\\{x_1, \\ldots, x_n\\}$.\n", "\n", "Innanzitutto, si sceglie un $n \\in \\mathbb{N}^+$, che rappresenta il numero di variabili di cui è composto il polinomio simmetrico,\n", "e si crea l'anello di polinomi $\\mathbb{Q}[x_1, \\ldots, x_n]$, nel quale vale il _degree lexicographic order_ (**deglex**). Vengono\n", "infine create delle variabili simboliche a rappresentare i polinomi simmetrici elementari." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Defining x_1, x_2, x_3, x_4, x_5\n" ] }, { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}\\left(e_{0}, e_{1}, e_{2}, e_{3}, e_{4}, e_{5}\\right)\n", "\\end{math}" ], "text/plain": [ "(e_0, e_1, e_2, e_3, e_4, e_5)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%display latex\n", "n = 5\n", "\n", "P = PolynomialRing(QQ, \",\".join(f\"x_{i}\" for i in range(1, n+1)), order='deglex')\n", "P.inject_variables()\n", "\n", "var(\",\".join(f\"e_{i}\" for i in range(n+1)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si definisce il valore che deve assumere la funzione $e(d)$, che rappresenta il polinomio simmetrico $e_d$, nel\n", "seguente modo:\n", "\n", "$$e(d) = \\begin{cases}1 & \\text{se }d=0, \\\\ \\displaystyle \\sum_{1\\leq i_1 < i_2 < \\cdots < i_d \\leq n} \\underbrace{x_{i_1} \\cdots x_{i_d}}_{d\\text{ volte}} & \\text{altrimenti.} \\end{cases}$$" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from functools import reduce\n", "from itertools import combinations\n", "from operator import mul\n", "\n", "def e(d: Integer):\n", " if d == 0:\n", " return 1\n", " \n", " return sum(reduce(mul, [P(f\"x_{j}\") for j in i], 1) for i in combinations(range(1, n+1), d))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si definisce una funzione $\\beta(\\operatorname{exp\\_lt})$ che prende in ingresso una tupla ordinata $\\operatorname{exp\\_lt} \\in \\mathbb{N}^n$ e restituisce una tupla dello stesso tipo definita nel seguente modo:\n", "\n", "$$\\beta(\\operatorname{exp\\_lt})_i = \\begin{cases} \\operatorname{exp\\_lt}_i - \\operatorname{exp\\_lt}_{i+1} & \\text{se }1 \\leq i < n, \\\\ \\operatorname{exp\\_lt}_i & \\text{altrimenti.} \\end{cases}$$" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "def beta(exp_lt):\n", " return [e - exp_lt[i+1] if i != n-1 else e for i, e in enumerate(exp_lt)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si definiscono due funzioni analoghe, dette $\\operatorname{e\\_prod}$ e $\\operatorname{e\\_prod\\_value}$. La seconda restituisce lo stesso polinomio di $\\operatorname{e\\_prod}$ sostituendo ai simboli $e_i$ i corrispettivi valori $e(i)$. Pertanto si definisce solo il valore della prima funzione.\n", "\n", "Tale funzione $\\operatorname{e\\_prod}$ prende in ingresso una tupla $b \\in \\mathbb{N}^n$ e restituisce $e^b = {e_1}^{b_1} {e_2}^{b_2} \\cdots {e_n}^{b_n}$." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def e_prod(b):\n", " return reduce(mul, [eval(f\"e_{i+1}\")^k for i, k in enumerate(b)], 1)\n", "\n", "\n", "def e_prod_value(b):\n", " return reduce(mul, [e(i+1)^k for i, k in enumerate(b)], 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si definisce infine la funzione $\\operatorname{combination}(\\operatorname{poly}(x))$, che prende in ingresso un polinomio simmetrico $\\operatorname{poly}(x)$ e ne restituisce la rappresentazione in $F[e_1, \\ldots, e_n]$, secondo il seguente algoritmo.\n", "\n", " - se $\\operatorname{poly}(x)$ è $0$ o ha grado nullo, la sua rappresentazione in $F[e_1, \\ldots, e_n]$ è già $\\operatorname{poly}(x)$, e quindi la funzione restituisce il polinomio in ingresso senza modificarlo,\n", " - altrimenti, si considera, secondo il _deglex_, il _leading term_ di $\\operatorname{poly}(x)$, detto $\\operatorname{lt}$:\n", " - detta $\\alpha$ la tupla ordinata degli esponenti di $\\operatorname{lt}$, si calcola $\\beta(\\alpha)$, detto $b$,\n", " - detto $c$ il coefficiente razionale di $\\operatorname{lt}$, si restituisce la rappresentazione simbolica $c \\cdot \\operatorname{e\\_prod(b)}$, a cui si aggiunge ricorsivamente la rappresentazione del polinomio $\\operatorname{poly(x)} -\\, c \\cdot \\operatorname{e\\_prod\\_value(b)}$, ottenuta reiterando l'algoritmo su di esso." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def combination(poly):\n", " if isinstance(poly, Integer) or isinstance(poly, Rational) or poly == 0 or poly.degree() == 0:\n", " return poly\n", " \n", " lt = sorted(list(poly), reverse=True)[0]\n", " \n", " try:\n", " b = beta(lt[1].exponents()[0])\n", " return lt[0] * e_prod(b) + combination(poly - lt[0] * e_prod_value(b))\n", " except (AttributeError, TypeError):\n", " raise TypeError(\"The given polynomial is not of symmetric kind\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si sceglie inoltre un polinomio $\\operatorname{poly}(x)$ che _deve_ essere simmetrico -- qualora non fosse tale, l'algoritmo non terminerà con successo (se terminasse con successo, il polinomio sarebbe combinazione di polinomi simmetrici, e sarebbe dunque anch'esso simmetrico, ↯)." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}x_{1}^{2} x_{2}^{2} x_{3}^{2} x_{4}^{2} x_{5}^{2} - 2 x_{1}^{3} x_{2} x_{3} x_{4} x_{5} - 2 x_{1} x_{2}^{3} x_{3} x_{4} x_{5} - 2 x_{1} x_{2} x_{3}^{3} x_{4} x_{5} - 2 x_{1} x_{2} x_{3} x_{4}^{3} x_{5} - 2 x_{1} x_{2} x_{3} x_{4} x_{5}^{3} + x_{1}^{4} + 2 x_{1}^{2} x_{2}^{2} + 2 x_{1}^{2} x_{3}^{2} + 2 x_{1}^{2} x_{4}^{2} + 2 x_{1}^{2} x_{5}^{2} + x_{2}^{4} + 2 x_{2}^{2} x_{3}^{2} + 2 x_{2}^{2} x_{4}^{2} + 2 x_{2}^{2} x_{5}^{2} + x_{3}^{4} + 2 x_{3}^{2} x_{4}^{2} + 2 x_{3}^{2} x_{5}^{2} + x_{4}^{4} + 2 x_{4}^{2} x_{5}^{2} + x_{5}^{4} + x_{1} + x_{2} + x_{3} + x_{4} + x_{5}\n", "\\end{math}" ], "text/plain": [ "x_1^2*x_2^2*x_3^2*x_4^2*x_5^2 - 2*x_1^3*x_2*x_3*x_4*x_5 - 2*x_1*x_2^3*x_3*x_4*x_5 - 2*x_1*x_2*x_3^3*x_4*x_5 - 2*x_1*x_2*x_3*x_4^3*x_5 - 2*x_1*x_2*x_3*x_4*x_5^3 + x_1^4 + 2*x_1^2*x_2^2 + 2*x_1^2*x_3^2 + 2*x_1^2*x_4^2 + 2*x_1^2*x_5^2 + x_2^4 + 2*x_2^2*x_3^2 + 2*x_2^2*x_4^2 + 2*x_2^2*x_5^2 + x_3^4 + 2*x_3^2*x_4^2 + 2*x_3^2*x_5^2 + x_4^4 + 2*x_4^2*x_5^2 + x_5^4 + x_1 + x_2 + x_3 + x_4 + x_5" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Il polinomio deve essere simmetrico...\n", "poly = x_1 + x_2 + x_3 + x_4 + x_5 + (x_1^2 + x_2^2 + x_3^2 + x_4^2 + x_5^2 - x_1*x_2*x_3*x_4*x_5)^2\n", "poly" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si calcola adesso la rappresentazione di $\\operatorname{poly}(x)$ in funzione dei polinomi simmetrici elementari secondo l'implementazione di $\\operatorname{combination}$:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}e_{1}^{4} - 4 \\, e_{1}^{2} e_{2} - 2 \\, e_{1}^{2} e_{5} + 4 \\, e_{2}^{2} + 4 \\, e_{2} e_{5} + e_{5}^{2} + e_{1}\n", "\\end{math}" ], "text/plain": [ "e_1^4 - 4*e_1^2*e_2 - 2*e_1^2*e_5 + 4*e_2^2 + 4*e_2*e_5 + e_5^2 + e_1" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "combination(poly)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Data una somma di potenze simmetrica, è possibile implementare un algoritmo di rappresentazione negli $e_i$ secondo le [identità di Newton-Girard](https://it.wikipedia.org/w/index.php?title=Identit%C3%A0_di_Newton&oldid=127634236#Enunciato_in_forma_relativa_ai_polinomi_simmetrici_elementari). Si definisce allora la funzione $\\operatorname{newton\\_girard}(k)$, che prende in ingresso un $k \\in \\mathbb{N}$ e restituisce la rappresentazione di $\\sum_{i=1}^n {x_i}^k$ nel seguente modo:\n", "\n", "$$\\operatorname{newton\\_girard}(k) = \\begin{cases} n & \\text{se } k = 0, \\\\ (-1)^{k+1} \\cdot (k e_{k} + \\sum_{i=1}^{k-1} (-1)^i \\operatorname{newton\\_girard}(i) \\, e_{k-1}) & \\text{altrimenti}, \\end{cases}$$\n", "\n", "dove si pone $e_i = 0$ per ogni $i > n$.\n", "\n", "La funzione è implementata con l'ausilio di un sistema di _caching_, affinché non vengano ricalcolati i valori già calcolati." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "from functools import lru_cache\n", "\n", "@lru_cache(maxsize=None)\n", "def newton_girard(k): \n", " if k == 0:\n", " return n\n", " \n", " return ((-1)**(k+1) * ((k * eval(f\"e_{k}\") if k <= n else 0) +\n", " sum((-1)**i * newton_girard(i) * eval(f\"e_{k - i}\") for i in range(max(1, k-n), k)))).expand()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si definisce infine la funzione $\\operatorname{sum\\_of\\_powers}(k)$, che, dato in ingresso un $k \\in \\mathbb{N}$, restituisce la rappresentazione di $\\sum_{i=1}^n (x_i)^k$ secondo la funzione $\\operatorname{combination}$ già definita." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "def sum_of_powers(k):\n", " return combination(sum(eval(f\"x_{i}\")^k for i in range(1, n+1)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si sceglie infine un $k \\in \\mathbb{N}$ al quale elevare tutti le variabili della somma." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "k = 8" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si computa la rappresentazione di $\\sum_{i=1}^n (x_i)^k$ prima secondo $\\operatorname{newton\\_girard}$, e poi secondo $\\operatorname{sum\\_of\\_powers}$, e si verifica che siano uguali." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}e_{1}^{8} - 8 \\, e_{1}^{6} e_{2} + 20 \\, e_{1}^{4} e_{2}^{2} + 8 \\, e_{1}^{5} e_{3} - 16 \\, e_{1}^{2} e_{2}^{3} - 32 \\, e_{1}^{3} e_{2} e_{3} - 8 \\, e_{1}^{4} e_{4} + 2 \\, e_{2}^{4} + 24 \\, e_{1} e_{2}^{2} e_{3} + 12 \\, e_{1}^{2} e_{3}^{2} + 24 \\, e_{1}^{2} e_{2} e_{4} + 8 \\, e_{1}^{3} e_{5} - 8 \\, e_{2} e_{3}^{2} - 8 \\, e_{2}^{2} e_{4} - 16 \\, e_{1} e_{3} e_{4} - 16 \\, e_{1} e_{2} e_{5} + 4 \\, e_{4}^{2} + 8 \\, e_{3} e_{5}\n", "\\end{math}" ], "text/plain": [ "e_1^8 - 8*e_1^6*e_2 + 20*e_1^4*e_2^2 + 8*e_1^5*e_3 - 16*e_1^2*e_2^3 - 32*e_1^3*e_2*e_3 - 8*e_1^4*e_4 + 2*e_2^4 + 24*e_1*e_2^2*e_3 + 12*e_1^2*e_3^2 + 24*e_1^2*e_2*e_4 + 8*e_1^3*e_5 - 8*e_2*e_3^2 - 8*e_2^2*e_4 - 16*e_1*e_3*e_4 - 16*e_1*e_2*e_5 + 4*e_4^2 + 8*e_3*e_5" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = newton_girard(k)\n", "a" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}e_{1}^{8} - 8 \\, e_{1}^{6} e_{2} + 20 \\, e_{1}^{4} e_{2}^{2} + 8 \\, e_{1}^{5} e_{3} - 16 \\, e_{1}^{2} e_{2}^{3} - 32 \\, e_{1}^{3} e_{2} e_{3} - 8 \\, e_{1}^{4} e_{4} + 2 \\, e_{2}^{4} + 24 \\, e_{1} e_{2}^{2} e_{3} + 12 \\, e_{1}^{2} e_{3}^{2} + 24 \\, e_{1}^{2} e_{2} e_{4} + 8 \\, e_{1}^{3} e_{5} - 8 \\, e_{2} e_{3}^{2} - 8 \\, e_{2}^{2} e_{4} - 16 \\, e_{1} e_{3} e_{4} - 16 \\, e_{1} e_{2} e_{5} + 4 \\, e_{4}^{2} + 8 \\, e_{3} e_{5}\n", "\\end{math}" ], "text/plain": [ "e_1^8 - 8*e_1^6*e_2 + 20*e_1^4*e_2^2 + 8*e_1^5*e_3 - 16*e_1^2*e_2^3 - 32*e_1^3*e_2*e_3 - 8*e_1^4*e_4 + 2*e_2^4 + 24*e_1*e_2^2*e_3 + 12*e_1^2*e_3^2 + 24*e_1^2*e_2*e_4 + 8*e_1^3*e_5 - 8*e_2*e_3^2 - 8*e_2^2*e_4 - 16*e_1*e_3*e_4 - 16*e_1*e_2*e_5 + 4*e_4^2 + 8*e_3*e_5" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = sum_of_powers(k)\n", "b" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}0\n", "\\end{math}" ], "text/plain": [ "0" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a - b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sia ora:\n", "\n", "$$f(x) = x^n + a_{n-1} x^{n-1} \\ldots + a_0,$$\n", "\n", "con radici $x_1$, $x_2$, ..., $x_n$. Allora si definisce **discriminante** di $f$ la seguente produttoria:\n", "\n", "$$\\Delta(f) = \\displaystyle \\prod_{1 \\leq i < j \\leq n} (x_i - x_j)^2.$$\n", "\n", "In particolare, vale la seguente proprietà:\n", "\n", "$$\\exists\\, i \\neq j \\mid x_i = x_j \\iff \\Delta(f) = 0.$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si verifica facilmente che $\\Delta(f)$ è un polinomio simmetrico. Poiché ogni permutazione è una composizione di trasposizioni, è sufficiente verificare che invertendo due radici $x_i$ e $x_j$ il discriminante rimanga invariato:\n", "\n", " - i fattori che contengono solo uno tra $x_i$ e $x_j$ mantengono la somma della base invariata o al più cambiano di segno, e dunque, elevando al quadrato, rimangono invariati,\n", " - il fattore che contiene sia $x_i$ che $x_j$ cambia la propria base di segno, ma rimane invariato elevando al quadrato.\n", " \n", "Poiché $\\Delta(f)$ è un polinomio simmetrico nelle variabili $x_1$, ..., $x_n$, per il _Teorema fondamentale dei polinomi simmetrici_, si scrive in modo unico in funzione dei polinomi simmetrici elementari $e_i(x_1, \\ldots, x_n)$. Tuttavia tali polinomi simmetrici elementari altro non sono che i coefficienti di $f(x)$, a meno del segno. In particolare vale che:\n", "\n", "$$e_i(x_1, \\ldots, x_n) = (-1)^{i} a_{n-i}, \\quad \\text{per } 0 \\leq i \\leq n.$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si definiscono quindi i simboli $a_0$, ..., $a_n$ e si costruisce una funzione $\\Delta(n)$ che restituisce il discriminante di un generico polinomio di $n$-esimo grado dato in ingresso in funzione degli $a_i$ mediante $\\operatorname{combination}$." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "var(\",\".join(f\"a_{i}\" for i in range(n+1)))\n", "\n", "def delta(n):\n", " \n", " f = reduce(mul, (eval(f\"(x_{i}-x_{j})\")^2 for i, j in combinations(range(1, n+1), 2)), 1)\n", " c = combination(f)\n", "\n", " for i in range(1, n+1):\n", " if i % 2:\n", " c = eval(f\"c.substitute(e_{i}=-a_{n-i})\")\n", " else:\n", " c = eval(f\"c.substitute(e_{i}=a_{n-i})\")\n", "\n", " return c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dunque, per l'$n$ scelto in partenza, il discriminante del generico polinomio di $n$-esimo grado è il seguente:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}a_{1}^{2} a_{2}^{2} a_{3}^{2} a_{4}^{2} - 4 \\, a_{0} a_{2}^{3} a_{3}^{2} a_{4}^{2} - 4 \\, a_{1}^{3} a_{3}^{3} a_{4}^{2} + 18 \\, a_{0} a_{1} a_{2} a_{3}^{3} a_{4}^{2} - 27 \\, a_{0}^{2} a_{3}^{4} a_{4}^{2} - 4 \\, a_{1}^{2} a_{2}^{3} a_{4}^{3} + 16 \\, a_{0} a_{2}^{4} a_{4}^{3} + 18 \\, a_{1}^{3} a_{2} a_{3} a_{4}^{3} - 80 \\, a_{0} a_{1} a_{2}^{2} a_{3} a_{4}^{3} - 6 \\, a_{0} a_{1}^{2} a_{3}^{2} a_{4}^{3} + 144 \\, a_{0}^{2} a_{2} a_{3}^{2} a_{4}^{3} - 27 \\, a_{1}^{4} a_{4}^{4} + 144 \\, a_{0} a_{1}^{2} a_{2} a_{4}^{4} - 128 \\, a_{0}^{2} a_{2}^{2} a_{4}^{4} - 192 \\, a_{0}^{2} a_{1} a_{3} a_{4}^{4} + 256 \\, a_{0}^{3} a_{4}^{5} - 4 \\, a_{1}^{2} a_{2}^{2} a_{3}^{3} + 16 \\, a_{0} a_{2}^{3} a_{3}^{3} + 16 \\, a_{1}^{3} a_{3}^{4} - 72 \\, a_{0} a_{1} a_{2} a_{3}^{4} + 108 \\, a_{0}^{2} a_{3}^{5} + 18 \\, a_{1}^{2} a_{2}^{3} a_{3} a_{4} - 72 \\, a_{0} a_{2}^{4} a_{3} a_{4} - 80 \\, a_{1}^{3} a_{2} a_{3}^{2} a_{4} + 356 \\, a_{0} a_{1} a_{2}^{2} a_{3}^{2} a_{4} + 24 \\, a_{0} a_{1}^{2} a_{3}^{3} a_{4} - 630 \\, a_{0}^{2} a_{2} a_{3}^{3} a_{4} - 6 \\, a_{1}^{3} a_{2}^{2} a_{4}^{2} + 24 \\, a_{0} a_{1} a_{2}^{3} a_{4}^{2} + 144 \\, a_{1}^{4} a_{3} a_{4}^{2} - 746 \\, a_{0} a_{1}^{2} a_{2} a_{3} a_{4}^{2} + 560 \\, a_{0}^{2} a_{2}^{2} a_{3} a_{4}^{2} + 1020 \\, a_{0}^{2} a_{1} a_{3}^{2} a_{4}^{2} - 36 \\, a_{0} a_{1}^{3} a_{4}^{3} + 160 \\, a_{0}^{2} a_{1} a_{2} a_{4}^{3} - 1600 \\, a_{0}^{3} a_{3} a_{4}^{3} - 27 \\, a_{1}^{2} a_{2}^{4} + 108 \\, a_{0} a_{2}^{5} + 144 \\, a_{1}^{3} a_{2}^{2} a_{3} - 630 \\, a_{0} a_{1} a_{2}^{3} a_{3} - 128 \\, a_{1}^{4} a_{3}^{2} + 560 \\, a_{0} a_{1}^{2} a_{2} a_{3}^{2} + 825 \\, a_{0}^{2} a_{2}^{2} a_{3}^{2} - 900 \\, a_{0}^{2} a_{1} a_{3}^{3} - 192 \\, a_{1}^{4} a_{2} a_{4} + 1020 \\, a_{0} a_{1}^{2} a_{2}^{2} a_{4} - 900 \\, a_{0}^{2} a_{2}^{3} a_{4} + 160 \\, a_{0} a_{1}^{3} a_{3} a_{4} - 2050 \\, a_{0}^{2} a_{1} a_{2} a_{3} a_{4} + 2250 \\, a_{0}^{3} a_{3}^{2} a_{4} - 50 \\, a_{0}^{2} a_{1}^{2} a_{4}^{2} + 2000 \\, a_{0}^{3} a_{2} a_{4}^{2} + 256 \\, a_{1}^{5} - 1600 \\, a_{0} a_{1}^{3} a_{2} + 2250 \\, a_{0}^{2} a_{1} a_{2}^{2} + 2000 \\, a_{0}^{2} a_{1}^{2} a_{3} - 3750 \\, a_{0}^{3} a_{2} a_{3} - 2500 \\, a_{0}^{3} a_{1} a_{4} + 3125 \\, a_{0}^{4}\n", "\\end{math}" ], "text/plain": [ "a_1^2*a_2^2*a_3^2*a_4^2 - 4*a_0*a_2^3*a_3^2*a_4^2 - 4*a_1^3*a_3^3*a_4^2 + 18*a_0*a_1*a_2*a_3^3*a_4^2 - 27*a_0^2*a_3^4*a_4^2 - 4*a_1^2*a_2^3*a_4^3 + 16*a_0*a_2^4*a_4^3 + 18*a_1^3*a_2*a_3*a_4^3 - 80*a_0*a_1*a_2^2*a_3*a_4^3 - 6*a_0*a_1^2*a_3^2*a_4^3 + 144*a_0^2*a_2*a_3^2*a_4^3 - 27*a_1^4*a_4^4 + 144*a_0*a_1^2*a_2*a_4^4 - 128*a_0^2*a_2^2*a_4^4 - 192*a_0^2*a_1*a_3*a_4^4 + 256*a_0^3*a_4^5 - 4*a_1^2*a_2^2*a_3^3 + 16*a_0*a_2^3*a_3^3 + 16*a_1^3*a_3^4 - 72*a_0*a_1*a_2*a_3^4 + 108*a_0^2*a_3^5 + 18*a_1^2*a_2^3*a_3*a_4 - 72*a_0*a_2^4*a_3*a_4 - 80*a_1^3*a_2*a_3^2*a_4 + 356*a_0*a_1*a_2^2*a_3^2*a_4 + 24*a_0*a_1^2*a_3^3*a_4 - 630*a_0^2*a_2*a_3^3*a_4 - 6*a_1^3*a_2^2*a_4^2 + 24*a_0*a_1*a_2^3*a_4^2 + 144*a_1^4*a_3*a_4^2 - 746*a_0*a_1^2*a_2*a_3*a_4^2 + 560*a_0^2*a_2^2*a_3*a_4^2 + 1020*a_0^2*a_1*a_3^2*a_4^2 - 36*a_0*a_1^3*a_4^3 + 160*a_0^2*a_1*a_2*a_4^3 - 1600*a_0^3*a_3*a_4^3 - 27*a_1^2*a_2^4 + 108*a_0*a_2^5 + 144*a_1^3*a_2^2*a_3 - 630*a_0*a_1*a_2^3*a_3 - 128*a_1^4*a_3^2 + 560*a_0*a_1^2*a_2*a_3^2 + 825*a_0^2*a_2^2*a_3^2 - 900*a_0^2*a_1*a_3^3 - 192*a_1^4*a_2*a_4 + 1020*a_0*a_1^2*a_2^2*a_4 - 900*a_0^2*a_2^3*a_4 + 160*a_0*a_1^3*a_3*a_4 - 2050*a_0^2*a_1*a_2*a_3*a_4 + 2250*a_0^3*a_3^2*a_4 - 50*a_0^2*a_1^2*a_4^2 + 2000*a_0^3*a_2*a_4^2 + 256*a_1^5 - 1600*a_0*a_1^3*a_2 + 2250*a_0^2*a_1*a_2^2 + 2000*a_0^2*a_1^2*a_3 - 3750*a_0^3*a_2*a_3 - 2500*a_0^3*a_1*a_4 + 3125*a_0^4" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "delta(n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Infine si costruisce la funzione $\\operatorname{evaluate\\_delta}$ che, dato in ingresso un polinomio $f(x)$ di $n$-esimo grado, restituisce il valore di $\\Delta(f)$, sostituendo agli $a_i$ generici di $\\operatorname{delta}(n)$ i valori dei coefficienti di $f$." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "def evaluate_delta(f):\n", " d = delta(n)\n", " \n", " for i, a in enumerate(f.list()):\n", " d = eval(f\"d.substitute(a_{i}=a)\")\n", " \n", " return d" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si verifica adesso che per un polinomio con radici multiple il valore di $\\operatorname{evaluate\\_delta}$ è precisamente zero:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}{\\left(x - 2\\right)}^{2} {\\left(x - 3\\right)} {\\left(x - 4\\right)} {\\left(x - 5\\right)}\n", "\\end{math}" ], "text/plain": [ "(x - 2)^2*(x - 3)*(x - 4)*(x - 5)" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f = (x-2)^2*(x-3)*(x-4)*(x-5)\n", "f" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}x^{5} - 16 \\, x^{4} + 99 \\, x^{3} - 296 \\, x^{2} + 428 \\, x - 240\n", "\\end{math}" ], "text/plain": [ "x^5 - 16*x^4 + 99*x^3 - 296*x^2 + 428*x - 240" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f.expand()" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}0\n", "\\end{math}" ], "text/plain": [ "0" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "evaluate_delta(f)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Infine, si fa lo stesso con un polinomio con radici distinte, per verificare che $\\operatorname{evaluate\\_delta}$ è strettamente diverso da zero." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}{\\left(x + 2\\right)} {\\left(x + i\\right)} {\\left(x - i\\right)} {\\left(x - 1\\right)} {\\left(x - 2\\right)}\n", "\\end{math}" ], "text/plain": [ "(x + 2)*(x + I)*(x - I)*(x - 1)*(x - 2)" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g = (x+2)*(x+I)*(x-I)*(x-1)*(x-2)\n", "g" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}x^{5} - x^{4} - 3 \\, x^{3} + 3 \\, x^{2} - 4 \\, x + 4\n", "\\end{math}" ], "text/plain": [ "x^5 - x^4 - 3*x^3 + 3*x^2 - 4*x + 4" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g.expand()" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}-1440000\n", "\\end{math}" ], "text/plain": [ "-1440000" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "evaluate_delta(g)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "(c) 2022, [~videtta](https://poisson.phc.dm.unipi.it/~videtta/)" ] } ], "metadata": { "celltoolbar": "Edit 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.7.7" } }, "nbformat": 4, "nbformat_minor": 4 }