Contenuti

π day 2022

Oggi, 14 Marzo, si festeggia il $\pi$-day!

$\pi$ day 2022

Perché proprio oggi?

Nel formato inglese, le date sono generalmente scritte nell’ordine anno-mese-giorno, perciò ciò che noi scriviamo come 14-3 (ovvero 14 Marzo), nei paesi anglofoni si scrive 3-14. Se prendiamo la cifra intera del $\pi$ e le prime due cifre decimali, avremo il numero $3.14$, da cui la scelta della data.

Perché celebrare un numero?

Beh, $\pi$ non è un semplice numero, bensì una delle costanti matematiche più importanti e che compare più frequentemente nelle formule. Facciamo alcuni esempi…

Prendiamo una ruota molto grande, con diametro di 1 metro. Diamole una bella spinta e facciamole fare un giro completo. Prendendo un metro, possiamo constatare che essa avrà percorso esattamente $\pi$ metri!
La seguente animazione rubata da wikipedia rende meglio l’idea

Infatti $\pi$ è il rapporto tra il perimetro di un cerchio e il suo diametro, ovvero $$ \pi = \frac{\text{perimetro}}{2r} $$ da cui la formula del perimetro del cerchio $$ \text{perimetro} = 2\pi r $$

Un’altra apparizione di $\pi$ è nella identità di Eulero, una delle formule matematiche più eleganti di tutte, la quale racchiude tre tra le costanti più importanti: $\pi, e, i$

$$ e^{\pi i} = -1 $$ (un giorno probabilmente ne parlerò meglio).

Sull’infinito $\infty$

La prima proprietà importante di $\pi$ è che esso è un numero irrazionale. Un numero è irrazionale se non può essere espresso come una frazione $a/b$ di due numeri interi $a,b$.

Questa proprietà abbastanza banale nasconde in realtà dello strabiliante. Un numero irrazionale, in poche parole, è un numero “con la virgola” la cui parte decimale non termina mai, e dove soprattutto non compare mai una sequenza periodica.

A questo punto ti starai chiedendo

E beh? Che c'è di così tanto strabiliante?

Ora ci arrivo, dammi tempo.
Allora, abbiamo detto che le cifre decimali sono infinite e non formano mai un periodo, ovvore una sequenza che si ripete periodicamente. Facciamo un cambiamento di base, e riscriviamo $\pi$ in base binaria.

Perciò dalla base decimale

Decimal π = 3.14159 26535 89793 23846 26433
83279 50288 41971 69399 37510 58209 74944
59230 78164 06286 20899 86280 34825 34211
70679 . . .

otteniamo qualcosa del genere in base 2 (ovvero in binario)

Binary π = 11.00100 10000 11111 10110 10101
00010 00100 00101 10100 01100 00100 01101
00110 00100 11000 11001 10001 01000 10111
00000 . . .

Il fatto che $\pi$ in base decimale ha una parte decimale infinita e senza sequenze periodiche, è vero anche in qualsiasi altra base. Perciò anche espresso in binario, $\pi$ ha una sequenza infinita di 0 e 1, e non troveremo mai una sequenza che periodicamente si ripete.

A questo punto, ricordiamo che in qualsiasi aggeggo digitale, tutte le informazioni sono espresse e codificate come una sequenza di 0 e 1. Perciò, il tuo libro preferito, è codificato come una sequenza di 0 e 1. Anche il tuo nome può essere codificato in binario. La tua canzone preferita, oppure anche il tuo film preferito. In pratica, tutto ciò che può essere scritto può essere codificato come una sequenza di 0 e 1.

E con questo ?

Beh, se nel $\pi$ c’è una sequenza infinit (e sottolineo infinta) e sempre diversa (e sottolineom sempre diversa) di 0 e 1, allora prima o poi incontreremo una sequenza di 0 e 1 che, se opportunamente decodificata, rappresentano una parola sensata nella tua lingua.

Ancora, dato che è infinita, prima o poi andando avanti incontreremo una seuqnza di 0 e 1 che, se decodificate, rappresentano una serie di parole nella tua lingua (magari senza senso).

Continuando a inoltrarci nell’infinito, prima o poi non solo incontreremo una sequenza di 0 e 1 che rappresentano una serie di parole nella tua lingua, ma magari questa serie di parole formano anche una frase di senso compiuto.

Non finisce qui!
Prima o poi, troveremo una seuqnza di 0 e 1 che rappresentano una serie di frasi consecutive e sensate.

Così via, prima o poi troveremo una sequenza di 0 e 1 che se codificata, genera esattamente tutta la Divina Commedia di Dante!

Ancora, prima o poi troveremo la sequenza che rappresenta il tuo libro preferito, e così via…

Ma questo non vale solo per le parole, ma per qualsiasi sequanza di informazioni che può essere codificata. Perciò prima o poi puoi ritrovare codificato in binario tutta la trilogia del signore degli anelli, con tanto di colonna sonora, e in tutte le lingue!

E non è tutto!
Prima o poi, sicuramente, troveremo una seuqnza di 0 e 1 che descrive esattamente la sequenza di proteine del tua DNA!

Peggio, prima o poi, troveremo quella sequanza che descrive esattamente tutti gli avvenimenti della tua vita fin da quando sei nato…

… e prima o poi troveremo la sequanza di 0 e 1 che descrive esattamente tutti gli avvenimenti che succederanno nella tua vita, discrivendo con precisione tutto fino all’ultimo istante.

In poche parole nel $\pi$ sono presenti tutte le informazioni dell’universo, passate, presenti e future!

Approssimare $\pi$

Dopo questa affascinante e alquanto inquietante digressione, torniamo sulle implicazioni reali di questo numero, e lasciamoci la fantascienza alle spalle.

Come fantascienza?
Quella che mi hai raccontanto prima è solo fantasia?

Beh, quello che ti ho raccontato prima sarebbe anche vero, se esistesse l’infinito, e quindi il continuo. Però, personalmente, ritengo che la realtà è troppo complessa per ridurla al misticismo dell’infinito. Ma questo è un altro discorso, sul quale molti non sono d’accordo con me, semplicemente perché scelgono di seguire la strada più semplice, quella del

Io percepisco continuo, capisco continuo, penso continuo.
Pericò il continuo esiste.

Ma non divaghiamo, altrimenti non terminiamo più (esattamente come la seuqnza di cifre decimali di $\pi$).

Dicevamo, il $\pi$ è una costante matematica utilizzata in tantissime formule che servono per far funzionare qualsiasi cosa noi utilizziamo: campionare le onde radio nelle comunicazioni, fare conti per assicurarci che il ponte che stiamo construendo un giorno non ci cada in testa, assicurarci che la forma di un aereo sia abbastanza aerodinamica da non farlo preciptare con noi dentro, ecc…

Perciò, non potendo calcolare una sequenza infinita di numeri, quantomeno cerchiamo di approssimare $\pi$ nella maniera più precisa possibile. Dove per preciso si intende a fini utilitari. Ovvero, per risolvere il problema di matematica approssimare $\pi \approx 3.14$ va più che bene, ma se dobbiamo calcolare il moto della stazione spaziale internazionale per lanciare un razzo con nuovi scienziati che la raggiungano, approssimare $\pi$ a $3.14$ sarebbe una catastrofe.

Comunque, di modi per approssimare $\pi$ ce ne sono una infinità, alcuni anche estremamente efficienti.

Io invece oggi voglio proporvi un metodo “classico” che, anche se estremamente lento, risluta molto elegante (a parer mio). E questo metodo utilizza un altro costrutto umano che a me piace tanto, la probabilità.

Perché hai scelto un metodo lento?

Principalmente per due motivi:

  1. è abbastanza “semplice” da poter essere mostrato in un blogpost.
  2. la computazione di questo metodo può essere visualizzata, perciò farò vedere una piccola animazione di come funziona questo metodo.

Metodo Montecarlo per approssimare $\pi$

Perdiamo il piano cartesiamo, e consideriamo un quadrato di lato 2 centrato nell’origine. Ovvero un quadrato le cui coordinate degli spigoli sono $(-1,1), (1,1), (1,-1), (-1,-1)$.

La precedente animazione è stata fatta in manim, e per tutti gli amici curiosi che mi chiedono sempre a riguardo, ecco il pezzo di codice usato per questa animazione.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from manim import *
from random import random, shuffle

class MontecarloScene(MovingCameraScene):
    def construct(self):
        grid = NumberPlane(
            background_line_style={
                "stroke_color": TEAL,
                "stroke_width": 1,
                "stroke_opacity": 1
            }
        )
        fsize = 24
        zero = MathTex("0", font_size=fsize).shift(RIGHT*.2 + DOWN*.2)
        self.play(Create(grid), Create(zero))
        self.wait()
        
        square = Square(
            side_length=2,
            color=RED,
            stroke_width=6
        )
        coords = [
            MathTex("(-1,1)", font_size=fsize).next_to(square.get_corner(UP+LEFT), UP+LEFT),
            MathTex("(1,1)", font_size=fsize).next_to(square.get_corner(UP+RIGHT), UP+RIGHT),
            MathTex("(1,-1)", font_size=fsize).next_to(square.get_corner(DOWN+RIGHT), DOWN+RIGHT),
            MathTex("(-1,-1)", font_size=fsize).next_to(square.get_corner(DOWN+LEFT), DOWN+LEFT),
        ]

        self.play(
            Create(square),
            AnimationGroup(*[Write(coords[i]) for i in range(len(coords))])
        )
        self.wait(1)

        self.play(self.camera.frame.animate.scale(0.45))
        self.wait(3)

        # ...

Torniamo a noi. Restringendoci al quadrato centrato nell’origine e scegliamo uniformemente a caso $n$ punti al suo interno. Facciamo per esempio $n = 200$.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
        # ...

        red_points, blue_points = [], []
        n = 200

        for _ in range(n):
            x = random()*2 - 1
            y = random()*2 - 1
            if x**2 + y**2 <= 1:
                red_points.append(Dot(radius=.02, color=WHITE).move_to([x*_radius,y*_radius,0]))
            else:
                blue_points.append(Dot(radius=.02, color=WHITE).move_to([x*_radius,y*_radius,0]))
        
        # mischio l'ordine in cui disegnare i punti tra le due liste
        all_points = red_points+blue_points
        shuffle(all_points)

        self.play(
            AnimationGroup(
                *[FadeIn(p) for p in all_points],
                lag_ratio=.5,
                run_time=6,
                rate_func=rate_functions.exponential_decay
            )
        )
        self.wait(2)

        # ...

Consideriamo ora un cerchio di raggio 1, centrato nell’origine. Osserviamo che questo cerchio sarà inscritto nel quadrato, ovvero tocca i quattro lati del quadrato.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
        # ...

        c = Circle(
            radius=_radius,
            color=YELLOW,
            fill_opacity=.1,
            stroke_width=1.5
        ).move_to(ORIGIN)

        self.play(DrawBorderThenFill(c))
        self.wait(2)

        # ...

In fine, contiamo quanti punti sono finiti all’interno del cerchio giallo, moltiplichiamo per 4 e dividiamo per $n$ (il numero totale di punti). Abbiamo ottenuto così la nostra approssiamzione di $\pi$!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
        # ...

        fsize = 32
        _pi = MathTex("\\pi = ", font_size=fsize).shift(1.5*RIGHT + .5*UP)
        _k = MathTex(f"{len(red_points)}", font_size=fsize).next_to(_pi, RIGHT*.75)

        self.add(_pi)
        self.play(
            AnimationGroup(
                *[
                    p.animate.set_color(RED) for p in red_points
                ]
            )
        )
        self.wait(2)

        red_points_group = VGroup(*[p.copy() for p in red_points])
        self.play(ReplacementTransform(red_points_group, _k))
        self.wait(2)

        self.play(
            Transform(_k, MathTex("\\frac{" + str(len(red_points)) + "}{" + str(n) + "}", font_size=24).move_to(_k.get_center()))
        )
        self.wait(1)
        
        _four = MathTex("\\times 4", font_size=24).next_to(_k, RIGHT*.5)
        self.play(FadeIn(_four, shift=RIGHT*.3))
        self.wait(2)
        
        result = MathTex(str( (len(red_points)/n) * 4), font_size=fsize).next_to(_pi, RIGHT*.75)
        self.play(ReplacementTransform(VGroup(_k, _four), result))
        self.wait()
        self.play(Circumscribe(result))
        self.wait(2)
Ma come?
Il π non è uguale a 3.06

Innanzitutto, come già ampiamente discusso, non è possibile calcolare tutte le cifre decimali di $\pi$ a meno che non si abbia infinito tempo a disposizione. Sicuramente tu che stai leggendo questo post hai tantissimo tempo libero (e nulla di meglio da fare), ma ti assicuro che non basta. Perciò noi vogliamo approssimare, ovvero trovare un numero che ci si avvicina.

Però 3.06 non ci si avvicina quasi per niente.

Beh, se arrotondiamo la seconda cifra decimale, otterremo come stima $3.1$, che appuntto approssima perfettamente $\pi$ fino alla prima cifra decimale.

Tutto questo casino per approssimare a 3.1 ?

Aspetta un attimo, ora ti spiego. Questo metodo in particolare, è un metodo statistico, perciò non basta campionare $n = 200$ punti all’interno del quadrato per avere una buona stima, bensì ne servono un’infinità di più. Si parla di centinaia di migliaia, o milioni di punti prima di intravedere una buona approssimazione. Però come già detto, questo metodo è lento!

Inoltre, essendo un metodo statistico, esso restituirà un valore sempre differente, che però in media vale $\pi$.

È arrivato il momento di fare due conti per svelare l’arcano.

Breve analisi

Indichiamo con $X_i$ una variabile aleatoria binaria che vale 1 se il putno $i$-esimo con coordinate $(x_i, y_i)$ finisce all’interno del cerchio di raggio 1, o 0 altrimenti.

$$ X_i = 1 \iff x_i^2 + y_i^2 \leq 1 $$ $$ \forall i = 1, …, n $$

Calcoliamo la probabilità che l'$i$-esimo punto finisca all’interno del cerchio, ovvero la probabilità che $X_i = 1$. Dato che ogni punto lo scegliamo uniformemente a caso all’interno del quadrato, avremo che tale probabilità sarà pari all'area del cerchio fratto l'area del quadrato (casi favorevoli su casi possibili) $$ \mathcal{P}(x_i^2 + y_i^2 \leq 1) = \mathcal{P}(X_i = 1) $$ $$ = \frac{\text{area cerchio}}{\text{area quadrato}} = \frac{\pi r^2}{2 \cdot 2} = \frac{\pi}{4} $$ dove $r=1$ è il raggio del cerchio, perciò $r^2=1$.

Calcoliamo ora la media (o valore atteso) della variabile $X_i$. Per definizione essa è pari a $$ \mathbb{E}\left[ X_i \right] = 1 \cdot \mathcal{P}(X_i = 1) + 0 \cdot \mathcal{P}(X_i = 0) = \mathcal{P}(X_i = 1) = \frac{\pi}{4} $$

Indichiamo ora con $Y$ il numero totale di punti che finiscono nel cerchio. Ovvero $Y = X_1 + X_2 + … + X_n$. Notare che per ogni punto $i$ nel cerchio, il suo contributo alla somma totale sarà esattamente di 1. Pericò la media di $Y$ sarà $$ \mathbb{E}\left[ Y \right] = \mathbb{E}\left[ X_1 + … + X_n \right] $$ $$ = \mathbb{E}\left[ X_1 \right] + … + \mathbb{E}\left[ X_n \right] = n \cdot \frac{\pi}{4} $$

Se noi pensiamo a $Y$ come un contatore che viene incrementato ogni qualvolta che un punto finisce nel cerchio, alla fine del nostro programma basterà moltiplicare il contatore per $4$ e dividerlo per $n$, ottenendo così (in media) $\pi$.

Svelata la magia!

Una simulazione più lunga

Per convincerti in maniera evidente che questo metodo approssima $\pi$, anche se mooolto lentamente, ho preparato un piccolo programma che esegue il metodo su un numero parecchio più grande di punti. Buona visione.

Notare che ha impiegato ben 5 minuti per approssimare a malapena 3 cifre decimali!



P.S. Ho scritto un piccolo programmino per la generazione dell’immagine di copertina di questo post. In futuri post mi piacerebbe mostrare come generare queste ascii arts. Pericò stay tuned.