PGreco

Stato
Discussione chiusa ad ulteriori risposte.
noooooooooooooooooooooooooooooooooooooookooooooooooooo
o_O. Ok solo se mi date un-1 meno pgrrco approssimato per o intero successivo

T_T
 
Pi è dato eccome da un rapporto. Ma d'altronde, chi ha mai detto che la lunghezza di un diametro o di una circonferenza debbano a tutti i costi essere numeri razionali? La lunghezza che misuriamo noi forse, ma quella è vincolata dai nostri strumenti di misura.

In ogni caso, esercizio per calcolare Pi greco e l'autore propone 22/7 ? :omfg: :omfg: :omfg:
Questo è un programmino che avevo fatto tempo fa, che calcola Pi greco con un livello di precisione arbitrario, come integrale calcolato fra 0 e 1 di 1/(1+x²) moltiplicato per 4. Sappiamo tutti che la primitiva di 1/(1/x²) è arctan(x). L'arcotangente di x calcolata fra 0 e 1 è pi/4 [ arctan(1) - arctan(0) = pi/4 - 0 ]. Se moltiplico per 4, ottengo Pi greco dal calcolo di un integrale di una funzione non irrazionale e con la precisione che voglio. Il numero di passi passato in input determina la precisione del risultato, anche se ovviamente, dato che per la risoluzione dell'integrale applico il metodo dei rettangoli per difetto e per eccesso, un aumento lineare del numero di steps provoca un aumento esponenziale della complessità algoritmica, dato che il numero di segmenti in cui viene diviso l'intervallo [0,1] è proprio pari a 2^steps.

Codice:
#include <stdio.h>
#include <stdlib.h>

int my_pow(int steps);

main()  {
        double *f,*a,*A;
        double base,pi,a1=0,A1=0,x=0;
        int i,steps;

        printf( "\nAttenzione: Maggiore sarà il numero di passi di approssimazione, maggiore sarà il tempo\n"
                "che il calcolatore impiegherà a calcolare pi!\n\n");
        
        printf( "Quanti passi di approssimazione devo effetturare? (1-100) ");
        scanf("%d",&steps);

        if ((steps<1) || (steps>100))  {
                printf( "Numero di passi non valido\n");
                return -1;
        }

        f = (double*) malloc (my_pow(steps-1)*sizeof(double));
        a = (double*) malloc (my_pow(steps-1)*sizeof(double));
        A = (double*) malloc (my_pow(steps-1)*sizeof(double));
        
        base = (float) 1/(my_pow(steps-1));
        f[0] = 1;

        for (i=1; i<=my_pow(steps-1); i++)  {
                x += base;
                f[i] = 1/(1+x*x);
                a[i] = base*f[i];
                A[i] = base*f[i-1];
        }

        for (i=1; i<=my_pow(steps-1); i++) { 
                A1 += A[i];
                a1 += a[i];
        }

        pi = (A1+a1)*2;

        printf("Approssimazione di pi: %.40lf\n",pi);
}

int my_pow(int steps)  {
        int i,res=1;
        
        for (i=0; i<steps; i++)
                res*=2;

        return res;
}
 
BlackLight ha detto:
Sappiamo tutti che la primitiva di 1/(1/x²) è arctan(x). L'arcotangente di x calcolata fra 0 e 1 è pi/4 [ arctan(1) - arctan(0) = pi/4 - 0 ].
:lol::lol::lol: sicuro? :lol::lol::lol:

PS: l'esame di :hail: analisi matematica I :hail: è stato il più duro (tra l'altro superato discretamente a dispetto di tutto) ma devo dire che ti apre un mondo...
 
Sappiamo tutti che la primitiva di 1/(1/x²) è arctan(x). L'arcotangente di x calcolata fra 0 e 1 è pi/4 [ arctan(1) - arctan(0) = pi/4 - 0 ].

questo punto mi interessa... la funzione [atan2(1) - atan2(0)]*4 non può essermi di aiuto... Il problema mio è nel calcolare l'arcotangente di un numero... In teoria posso far anche:

In perl:
Codice:
$a = 1/(1/1*1);
$b = 1/(1/0*0);
$ris = $a - $b;
$pi = $ris * 4;

print "Il PGreco è $pi"

Ma ho errore: Illegal Division By Zero At Line 2...Consigli?

Edit: Ho provato in pascal, che mi calcola lui le arcotangenti:
Codice:
begin
var A,B,C: integer;
	A:= ARCTAN(1);
	B:= ARCTAN(0);
	C:= ( A - B ) * 4;
	writeln("Il Valore di PI e", C);
end.

Mi da un errore nel compile...
 
Di fatto l'arcotangente non la devi mai calcolare direttamente, è in questo che sta il punto di forza dell'algoritmo...
Il calcolo dell'arcotangente di un numero a livello computazionale è un'operazione che ha la sua complessità (dato che l'arcotangente va sviluppata in serie di Taylor a livello del calcolatore, con un grado di precisione arbitrario). Ma la notevole proprietà dell'arcotangente è che, pur essendo una funzione trigonometrica relativamente complessa, la sua derivata è f'(x) = 1/(1+x²), che è una funzione razionale relativamente semplice. Quindi di fatto non devi mai calcolare direttamente l'arcotangente, ma passi per il calcolo dell'integrale della sua derivata. E il calcolo lo fai dividendo via via l'intervallo fra 0 e 1 di f'(x) in segmenti sempre più piccoli (più piccoli sono i segmenti in cui vai a tagliare l'intervallo, maggiore sarà il numero di rettangoli e quindi la "risoluzione" dell'integrale, e maggiore sarà anche la precisione del calcolo di pi greco).

Ad esempio

f'(0) = 1/(1+0) = 1
f'(1) = 1/(1+1) = 0.5

In questo primo passo considero il rettangolo avente base = 1 (tutto l'intervallo) e altezza pari al minimo fra i due valori calcolati (0.5). Il rettangolo calcolato così per difetto avrà quindi area pari a 1*0.5 = 0.5. Il rettangolo calcolato per eccesso avrà area pari alla base per il massimo valore (1), quindi 1*1 = 1. Il valore più vicino all'area effettiva dell'integrale è dato dalla media, ovvero (1+0.5)/2 = 0.75. Moltiplicato per 4, ottengo 0.75*4 = 3. E questa è una prima approssimazione ottenuta dividendo l'intervallo [0,1] di f'(x) = 1/(1+x²) in sé stesso, e considerando il rettangolo costruito prendendo come altezza il valore massimo assunto in uno dei due estremi (f'(0) = 1) e quello costruito prendendo come altezza il valore minimo (f'(1) = 0.5) per poi farne la media e moltiplicarla per 4. Se suddivido l'intervallo in vari sotto-intervalli, con i relativi rettangolini che vado poi a sommare, ottengo un valore via via più preciso.
 
[ot]
la_paura.jpg
[/ot]
 
Codice:
import javax.swing.*;
class pgreco
{
public void main(String[] args)
{
double a = 1/(1/1*1);
double b = 1/(1/0*0);
double risultato = a-b;
double pigreco  = risultato*4;
string comp = "Pi greco vale: "+pigreco+" ";
Jframe finestra = new JFrame("Pigreco vale...");
JLabel  PGrec = new JLabel(comp);
finestra.setSize(200,60);
finestra.add(PGrec);
}
}
 
BlackLight ha detto:
Di fatto l'arcotangente non la devi mai calcolare direttamente, è in questo che sta il punto di forza dell'algoritmo...
Il calcolo dell'arcotangente di un numero a livello computazionale è un'operazione che ha la sua complessità (dato che l'arcotangente va sviluppata in serie di Taylor a livello del calcolatore, con un grado di precisione arbitrario). Ma la notevole proprietà dell'arcotangente è che, pur essendo una funzione trigonometrica relativamente complessa, la sua derivata è f'(x) = 1/(1+x²), che è una funzione razionale relativamente semplice. Quindi di fatto non devi mai calcolare direttamente l'arcotangente, ma passi per il calcolo dell'integrale della sua derivata. E il calcolo lo fai dividendo via via l'intervallo fra 0 e 1 di f'(x) in segmenti sempre più piccoli (più piccoli sono i segmenti in cui vai a tagliare l'intervallo, maggiore sarà il numero di rettangoli e quindi la "risoluzione" dell'integrale, e maggiore sarà anche la precisione del calcolo di pi greco).

Ad esempio

f'(0) = 1/(1+0) = 1
f'(1) = 1/(1+1) = 0.5

In questo primo passo considero il rettangolo avente base = 1 (tutto l'intervallo) e altezza pari al minimo fra i due valori calcolati (0.5). Il rettangolo calcolato così per difetto avrà quindi area pari a 1*0.5 = 0.5. Il rettangolo calcolato per eccesso avrà area pari alla base per il massimo valore (1), quindi 1*1 = 1. Il valore più vicino all'area effettiva dell'integrale è dato dalla media, ovvero (1+0.5)/2 = 0.75. Moltiplicato per 4, ottengo 0.75*4 = 3. E questa è una prima approssimazione ottenuta dividendo l'intervallo [0,1] di f'(x) = 1/(1+x²) in sé stesso, e considerando il rettangolo costruito prendendo come altezza il valore massimo assunto in uno dei due estremi (f'(0) = 1) e quello costruito prendendo come altezza il valore minimo (f'(1) = 0.5) per poi farne la media e moltiplicarla per 4. Se suddivido l'intervallo in vari sotto-intervalli, con i relativi rettangolini che vado poi a sommare, ottengo un valore via via più preciso.

Diciamo che rileggendo più volte, sommi capi ho capito ;D Be allora devo vedere come interfacciare l'algoritmo meglio... Dato che come hai detto tu il tutto sta nel valore che gli si attribuisce, più vicino al valore medio, e poi approssimato, cose che usando la calcolatrice non son previste...

Be interessante come cosa, appena avrò le conoscenze più adatte a riprendere l'argomento, vorrei approfondire ( Dopo tutto, faccio solo la prima superiore XD )

Grazie mille per le spiegazioni, ancora una volta molto molto esaudiente :D
 
Uhm mi rendo conto ora dopo aver riletto quello che ho scritto che mi sono espresso in modo più o meno incomprensibile a chiunque non abbia mai fatto analisi matematica in vita sua...
Al di là del formalismo matematico, il concetto è abbastanza semplice. Quello che devo fare è calcolare l'area sottesa alla curva di equazione 1/(1+x²) sul piano cartesiano. Si dimostra, attraverso il calcolo integrale, che la primitiva di questa funzione è l'arcotangente di x, e poiché l'area sottesa a una curva fra due estremi [a,b] è pari al valore della sua primitiva calcolata in b meno il valore della sua primitiva calcolata in a, l'area sottesa a 1/(1+x²) fra 0 e 1 è pari a arctan(1)-arctan(0), ovvero (pi/4)-(0), ovvero pi/4. Se moltiplico questo valore per 4, ottengo pi greco.

Il punto è che non esiste un modo per calcolare con assoluta precisione l'integrale di una funzione in un intervallo usando un calcolatore. Ci sono le regole del calcolo integrale e dell'analisi matematica, ma sono regole che non si possono implementare in un calcolatore, e quindi un computer deve ricorrere a strategie diverse per calcolare un integrale definito. Una di queste strategie è quella di dividere l'area sottesa ad una curva in tanti rettangoli o trapezi, e approssimare l'integrale della curva su [a,b] alla somma delle aree di questi rettangoli. Nel caso specifico di 1/(1+x²):



Ovviamente, maggiore sarà il numero di segmenti in cui divido l'intervallo [a,b], maggiore sarà il numero di rettangoli, quindi maggiore sarà la precisione con cui calcolerò l'integrale. Il caso limite è quello di considerare "scheletri" di rettangoli con base nulla. In tal caso sommo fra loro i valori che assume la funzione in ogni punto dell'intervallo, ottenendo quindi il valore esatto dell'integrale. Ovviamente però questa strategia non è possibile, dato che il numero di numeri presenti in qualsiasi intervallo è infinito, quindi si ricorre all'approssimazione dei rettangoli. Per essere ancora più precisi in genere si considera la somma per difetto della somma dei rettangoli (ovvero la somma dei rettangoli che "sta sotto" la curva) e quella per eccesso (ovvero la somma dei rettangoli che "sta sopra" la curva), e si fa la media fra queste due somme, che sarà il valore che si avvicina generalmente di più al valore effettivo dell'integrale reale.

@kripnos: Hai semplicemente calcolato l'approssimazione di pi greco come media fra il valore assunto da 1/(1+x²) nel punto 0 e valore assunto nel punto 1...un'approssimazione di pi greco è ben altra cosa, quello che ho fatto nel mio esempio era solo il caso base da considerare. Se guardi il mio sorgente in C l'algoritmo ideale per l'approssimazione di pi greco è flessibile e può suddividere l'intervallo [0,1] in un numero qualsiasi di rettangoli...
 
Ora ho capito, mi è tutto più chiaro... Avevo letto dell'inscrizione dei triangoli, ma mi sfuggiva qualcosa... Ora ho capito meglio... Ma Ho ancora le idee più confuse su come applicare il tutto sul pc :D ( In linea teorica ok, non mi sembra di aver fatto troppa confusione, ma sui pc nada de nada... ) Scusa se ti posso sembrar stupido facendo domande, forse per altri scontate, ma mi sembra più stupido non farle ^^

EDIT: Rileggendo potrei provare a fare un paio di cosette, se mi riesce posto il source :D
 
Comunque, visto che Black l'ha fatto col metodo dei rettangoli di Riemann io utilizzo i trapezi :D
Codice:
#include <stdio.h>
#include <stdlib.h>

double f(double p);

int main()  {
        int n;
        double p=0,yn,i,ap;
        printf( "Numero di intervalli: ");
        scanf("%d",&n);

        p= 1/(double)n;
        ap=p;

        for(i=1;i<n;i++)  {
            yn+=f(ap);
            ap+=p;
        }
        yn=p*(((f(0)+f(1))/2)+yn);
        printf("Approssimazione di pi: %.40lf\n",yn*4);
}

double f(double p) {
    return (1/(1+(p*p)));
}

Comunque, per quanto riguarda il codice di Black, farlo così è un cazzotto nelle palle, cioè in realtà tu effettui due volte un ciclo relativamente grande, il primo per calcolarti i valori e il secondo per fare le somme, in realtà è una cosa più o meno inutile, nel senso che vai a salvare in una struttura dati dei valori che in realtà a te non servono al fine del problema (le aree parziali dei rettangoli non è che servano a qualcosa, a te interessa la somma totale, tantovale usare una sola variabile invece di un array). In più, vabè ma questo è una cosa puramente matematica, potresti moltiplicare la base una volta sola, cioè y=base*altezza1+base*altezza2=base*(altezza1+altezza2).
 
Forse non hai capito una sottile differenza.. Matematica si fa a scuola. ANALISI Matematica si fa all'università. Non credo che tu sia uno studente universitario.
 
[Python]
Codice:
from math import atan
long=int(raw_input("Inserisci la quantita' di decimali: "))
pg=(atan(1)-atan(0))*4
pg=list(str(pg))
global tot
tot=[]
tot.append(pg[0])
tot.append(pg[1])
del pg[0]
del pg[0]
for i in range(0, long):
	tot.append(pg[i])
print ''.join(tot)
Ringrazio BlackLight per la spiegazione sopra, non sapevo come calcolarlo sto PGreco.
 
Stato
Discussione chiusa ad ulteriori risposte.