Identità di Newton in Python: Calcolare Somme di Potenze con SymPy senza Risolvere il Polinomio

Cerca:

Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors

Quando compare un polinomio di grado elevato, il riflesso naturale è quasi sempre lo stesso: trovare le radici.

Ma spesso è la strada più scomoda.

Esistono situazioni in cui non ci interessa conoscere le radici una per una.
Magari vogliamo soltanto calcolare quantità come:

[math]
r_1^5+r_2^5+r_3^5
[/math]

oppure:

[math]
r_1^{20}+r_2^{20}+r_3^{20}
[/math]

Farlo direttamente può diventare rapidamente ingestibile.

Ed è qui che entrano in gioco le identità di Newton: relazioni algebriche che collegano le somme di potenze delle radici ai coefficienti del polinomio.

La parte interessante è che queste formule si prestano perfettamente all’automazione.

Con poche righe di Python e la libreria SymPy possiamo costruire ricorrenze simboliche, generare formule automaticamente e verificare numericamente i risultati senza risolvere esplicitamente il polinomio.

In questo tutorial vedremo:

  • come funzionano le identità di Newton
  • come implementarle in Python
  • come automatizzare le ricorrenze
  • come usare il calcolo simbolico
  • come verificare numericamente i risultati
  • perché questa tecnica è importante nell’algebra computazionale

Tutto il codice è compatibile con Google Colab.

Pubblicità

Il problema matematico

Supponiamo di avere un polinomio:

[math]P(x) = x^3 – e_1x^2 + e_2x – e_3[/math]

con radici:

[math]r_1, r_2, r_3[/math]

Definiamo le somme di potenze:

[math]S_n = r_1^n + r_2^n + r_3^n[/math]

A prima vista sembra impossibile calcolare quantità come:

[math]
S_5,\ S_{10},\ S_{20}
[/math]

senza conoscere le radici.

Eppure le identità di Newton permettono di farlo lavorando esclusivamente sui coefficienti del polinomio.

La ricorrenza fondamentale

Per un polinomio cubico monico vale la relazione:

[math]S_n = e_1 S_{n-1} – e_2 S_{n-2} + e_3 S_{n-3}[/math]

dove:

[math]e_1 = r_1 + r_2 + r_3[/math]

[math]e_2 = r_1 r_2 + r_1 r_3 + r_2 r_3[/math]

[math]e_3 = r_1 r_2 r_3[/math]

Questa formula è il cuore delle identità di Newton.

Una volta note alcune somme iniziali, possiamo generare automaticamente tutte le successive.

Vuoi capire la teoria matematica dietro il codice?

In questo articolo abbiamo implementato le identità di Newton usando Python e SymPy.

Forse potrebbe interessarti anche:  Matrici a Gradini e Multicollinearità: Guida Diagnostica all’Algebra Lineare per Data Scientist

Se vuoi approfondire:

  • le formule di Newton-Girard
  • le relazioni tra radici e coefficienti
  • gli esercizi svolti passo passo
  • la derivazione delle ricorrenze

👉Identità di Newton: guida pratica alle formule di Newton-Girard con esempi svolti

Installazione e import

In Google Colab SymPy è già disponibile.

Importiamo tutto ciò che serve.

import sympy as sp

Primo esempio simbolico

Definiamo i coefficienti simbolici.

e1, e2, e3 = sp.symbols('e1 e2 e3')

Definiamo anche alcune somme iniziali.

S1, S2, S3 = sp.symbols('S1 S2 S3')

Ora implementiamo la formula di Newton.

S4 = e1*S3 - e2*S2 + e3*S1

print(S4)

Output:

S1*e3 - S2*e2 + S3*e1

Abbiamo ottenuto una formula completamente simbolica.

Implementazione automatica della ricorrenza

Ora costruiamo una funzione generale.

def newton_sums(e1, e2, e3, S1, S2, S3, n_max):
    
    sums = {
        1: S1,
        2: S2,
        3: S3
    }

    for n in range(4, n_max + 1):
        
        sums[n] = (
            e1*sums[n-1]
            - e2*sums[n-2]
            + e3*sums[n-3]
        )

    return sums

Test della funzione

Usiamo:

[math]\displaystyle \begin{aligned}
e_1=1, \quad e_2=-\frac{1}{2}, \quad e_3=\frac{1}{6}
\end{aligned}[/math]

e:

[math]S_1=1, \quad S_2=2, \quad S_3=3[/math]

Codice

sums = newton_sums(
    e1=1,
    e2=-sp.Rational(1,2),
    e3=sp.Rational(1,6),
    S1=1,
    S2=2,
    S3=3,
    n_max=8
)

for k, v in sums.items():
    print(f"S_{k} =", sp.simplify(v))

Output atteso

S_1 = 1
S_2 = 2
S_3 = 3
S_4 = 25/6
S_5 = 6
S_6 = 301/36
S_7 = 665/54
S_8 = 1705/108

Interpretazione

Abbiamo generato automaticamente:

[math]r_1^n + r_2^n + r_3^n[/math]

senza conoscere:

  • [math]r_1[/math]
  • [math]r_2[/math]
  • [math]r_3[/math]

Questo è il cuore delle identità di Newton.

Calcolo diretto dai coefficienti del polinomio

Consideriamo il polinomio:

[math]x^3 – 2x^2 – x + 1[/math]

Costruiamolo in SymPy

x = sp.Symbol('x')

P = x**3 - 2*x**2 - x + 1

print(P)
x**3 - 2*x**2 - x + 1

Estrazione automatica dei coefficienti

poly = sp.Poly(P, x)

coeffs = poly.all_coeffs()

print(coeffs)
[1, -2, -1, 1]

Ricaviamo

[math]e_1, e_2, e_3[/math]

Per:

[math]x^3 – e_1x^2 + e_2x – e_3[/math]

abbiamo:

e1 = 2
e2 = -1
e3 = -1

Calcolo automatico delle somme iniziali

Possiamo usare le formule:

[math]S_1[/math]

[math]S_1 = e_1[/math]

[math]S_2[/math]

[math]S_2 = e_1^2 – 2e_2[/math]

[math]S_3[/math]

[math]\displaystyle \begin{aligned}
S_3 = e_1S_2 – e_2S_1 + 3e_3
\end{aligned}[/math]

Forse potrebbe interessarti anche:  Python: La libreria Sympy. Costruire una matrice -2-

Codice

S1 = e1

S2 = e1**2 - 2*e2

S3 = e1*S2 - e2*S1 + 3*e3

print(S1, S2, S3)
e1 e1**2 - 2*e2 -e1*e2 + e1*(e1**2 - 2*e2) + 3*e3

Generazione completa automatica

sums = newton_sums(
    e1,
    e2,
    e3,
    S1,
    S2,
    S3,
    10
)

for n, val in sums.items():
    print(f"S_{n} =", sp.expand(val))
S_1 = S1
S_2 = S2
S_3 = S3
S_4 = S1*e3 - S2*e2 + S3*e1
S_5 = S1*e1*e3 - S2*e1*e2 + S2*e3 + S3*e1**2 - S3*e2
S_6 = S1*e1**2*e3 - S1*e2*e3 - S2*e1**2*e2 + S2*e1*e3 + S2*e2**2 + S3*e1**3 - 2*S3*e1*e2 + S3*e3

.........

Verifica usando le radici reali

Dopo aver calcolato le somme di potenze tramite le identità di Newton, è naturale chiedersi:

“Il risultato è davvero corretto?”

Per verificarlo possiamo usare un approccio completamente diverso:

  1. trovare numericamente le radici del polinomio
  2. elevare direttamente le radici alla potenza desiderata
  3. sommare i risultati
  4. confrontare con la formula ricorsiva

Questa è una verifica numerica indipendente.

Avevamo il polinomio:

[math]P(x) = x^3 – 2x^2 – x + 1[/math]

e tramite Newton avevamo calcolato:

[math]S_5 = r_1^5 + r_2^5 + r_3^5[/math]

senza conoscere le radici.

Ora vogliamo controllare il risultato usando le radici reali (o complesse) del polinomio.

Troviamo le radici

roots = sp.nroots(P)

print(roots)

[-0.801937735804838, 0.554958132087371, 2.24697960371747]

Cosa fa nroots()?

La funzione:

sp.nroots()

significa:

numeric roots

cioè:

“trova approssimazioni numeriche delle radici”.

Differenza con solve()

solve()

cerca formule esatte:

[math]\displaystyle \begin{aligned}
\sqrt{2}, \quad \frac{1+\sqrt{5}}{2}, \dots
\end{aligned}[/math]

nroots()

calcola approssimazioni decimali:

1.7320508,  0.6180339,…

Perché usare nroots()?

Perché molti polinomi:

  • non hanno formule semplici
  • hanno radici irrazionali
  • hanno radici complesse

nroots() usa metodi numerici iterativi molto efficienti.

Verifica numerica

S5_numeric = sum(r**5 for r in roots)

print(sp.N(S5_numeric))
57.0000000000000

Cosa abbiamo dimostrato con la verifica numerica?

Abbiamo verificato la correttezza delle identità di Newton

Con la ricorrenza avevamo calcolato:

[math]
S_5 = r_1^5 + r_2^5 + r_3^5
[/math]

senza conoscere le radici del polinomio.

Poi abbiamo:

  • trovato numericamente le radici
  • elevato ciascuna alla quinta
  • sommato i risultati

ottenendo lo stesso valore:

[math]
57
[/math]

Questo significa che:

[math]
\boxed{
\text{la ricorrenza di Newton produce il risultato corretto}
}
[/math]

Forse potrebbe interessarti anche:  Python: La libreria Sympy. Operazioni algebriche con le matrici

Abbiamo confrontato due mondi diversi

La parte interessante è che i due metodi usati sono completamente differenti.

Metodo 1 — Algebra simbolica

Usa:

  • coefficienti del polinomio
  • relazioni simmetriche
  • ricorrenze
  • identità di Newton

senza conoscere:
[math]
r_1,r_2,r_3
[/math]

Metodo 2 — Calcolo numerico diretto

Usa:

  • approssimazioni numeriche delle radici
  • elevamenti a potenza
  • somme dirette

Se i risultati coincidono…

allora:

  • la teoria è corretta
  • il codice Python è corretto
  • l’implementazione della ricorrenza funziona

Abbiamo mostrato che non serve risolvere il polinomio

Questo è il punto matematico più profondo.

Normalmente, per calcolare:

[math]
r_1^5+r_2^5+r_3^5
[/math]

penseremmo di dover:

  1. trovare le radici
  2. elevare alla quinta
  3. sommare

Le identità di Newton mostrano invece che:

[math]
\boxed{
\text{non è necessario conoscere le radici}
}
[/math]

Bastano:

  • i coefficienti del polinomio
  • alcune somme iniziali
  • una ricorrenza

Abbiamo verificato una proprietà strutturale del polinomio

Le somme:

[math]
S_n=r_1^n+r_2^n+r_3^n
[/math]

non dipendono dal modo in cui troviamo le radici.

Dipendono solo:

  • dalla struttura del polinomio
  • dai suoi coefficienti

Questa è una proprietà fondamentale dell’algebra.

Abbiamo visto la differenza tra simbolico e numerico

Questo esempio è perfetto per capire la differenza tra:

Calcolo simbolico

Manipola formule esatte:

[math]
\frac{25}{6},\quad e_1^3-3e_1e_2+3e_3
[/math]

vantaggi:

  • precisione assoluta
  • formule generali
  • algebra esatta

Calcolo numerico

Lavora con approssimazioni:

57.0000000000000
vantaggi:
  • velocità
  • applicabilità pratica
  • gestione di polinomi molto grandi

Pubblicità