Controllo programma in C
Salve a tutti,
ho scritto questo programma (è quello cui si riferisce il mio post precedente, ma fate conto che sia un altro, l'ho modificato e comunque l'altro problema rimane, ma non c'entra niente con quello che voglio chiedere adesso) :
la formula che voglio che calcoli persigmay è: $\sum_{i} (y_i-a-bx_i)^2$ ; mi sembra di averla scritta bene nel codice, ma il risultato che dovrei ottenere, facendo la prova con i dati, è sballato! Perchè quella che ho scritto è sbagliata, come dovrebbe essere?
Grazie in anticipo
Valentina
ho scritto questo programma (è quello cui si riferisce il mio post precedente, ma fate conto che sia un altro, l'ho modificato e comunque l'altro problema rimane, ma non c'entra niente con quello che voglio chiedere adesso) :
#include <stdio.h> #include <math.h> int main() { int n, i; double x[1000]={0}, y[1000]={0}, sumx=0, sumy=0, sumxquad=0, sumxy=0, a, b, persigmay=0, sigmay, erra, errb; printf ("\nQuesto programma utilizza il metodo dei minimi quadrati per stimare i parametri a e b di una retta di equazione y=ax+b ; si è ipotizzato che i dati sperimentali ottenuti siano legati da una dipendenza lineare. \nE' importante specificare che i valori che il programma restituisce sono validi solo nel caso in cui le varianze di tutte le y dei valori siano uguali."); printf ("\n\nInserire il numero di dati del campione (numero delle coppie): "); scanf ("%d",&n); for (i=0; i<n; i++) { printf ("\nInserire il dato x: "); scanf ("%lf", &x[i]); } for (i=0; i<n; i++) { printf ("\nInserire il dato y: "); scanf ("%lf", &y[i]); } for (i=0; i<n; i++) { sumx+=x[i]; sumy+=y[i]; sumxquad+=pow(x[i],2); sumxy+=x[i]*y[i]; } a=(n*sumxy-sumy*sumx)/(n*sumxquad-pow(sumx,2)); b=(sumy*sumxquad-sumx*sumxy)/(n*sumxquad-pow(sumx,2)); printf ("\nDella retta y=ax+b, il valore di a è %f", a); printf ("\nDella retta y=ax+b, il valore di b è %f", b); printf ("\nInserire la varianza delle y(inserire 0 se non è nota): "); scanf ("%lf",&sigmay); if (sigmay==0) { for (i=0; i<n; i++) { persigmay+=pow((y[i]-a-b*x[i]),2); } sigmay=sqrt(persigmay/(double)(n-2)); } printf ("\npersigmay=%f", persigmay); printf ("\nsigmay=%f", sigmay); erra=sigmay*sqrt(n/(n*sumxquad-pow(sumx,2))); errb=sigmay*sqrt(sumxquad/(n*sumxquad-pow(sumx,2))); printf ("\nL'indeterminazione associata al parametro a della retta y=ax+b è %f", erra); printf ("\nL'indeterminazione associata al parametro b della retta y=ax+b è %f", errb); }
la formula che voglio che calcoli persigmay è: $\sum_{i} (y_i-a-bx_i)^2$ ; mi sembra di averla scritta bene nel codice, ma il risultato che dovrei ottenere, facendo la prova con i dati, è sballato! Perchè quella che ho scritto è sbagliata, come dovrebbe essere?
Grazie in anticipo
Valentina
Risposte
NdM: Inserisci il codice utilizzando il tag code quando desideri inserire del codice. Questa volta l'ho fatto io.
Sarebbe utile se ci fornissi maggiori informazioni. In che senso il risultato è sbagliato? Con quale input l'hai testato? Quale risultato ti aspettavi? Hai provato a fare un debug?
Sarebbe utile se ci fornissi maggiori informazioni. In che senso il risultato è sbagliato? Con quale input l'hai testato? Quale risultato ti aspettavi? Hai provato a fare un debug?
Ci sono varie cose che metterei a posto:
1) Inserire la x e la y di una rilevazione nello stesso ciclo.
Quindi invece di:
scrivere:
2) Usare x*x invece di pow(x,2). Ragionevolmente la prima è sia più veloce che più precisa della seconda.
3) Volendo puoi calcolarti a a partire da b usando meno calcoli. Ma la differenza in termini di performance e/o precisione sono insignificanti.
4) Per il pow usato per persigmay potevi scrivere:
------------------------------
Non comprendo bene perché hai usato il termine varianza e per quale ragioni ritieni di conoscerla già... L'errore medio rispetto alla retta non è proprio quello che di solito viene chiamato varianza dei dati.
1) Inserire la x e la y di una rilevazione nello stesso ciclo.
Quindi invece di:
for (i=0; i<n; i++) { printf ("\nInserire il dato x: "); scanf ("%lf", &x[i]); } for (i=0; i<n; i++) { printf ("\nInserire il dato y: "); scanf ("%lf", &y[i]); }
scrivere:
for (i=0; i<n; i++) { printf ("\nInserire il dato x: "); scanf ("%lf", &x[i]); printf ("\nInserire il dato y: "); scanf ("%lf", &y[i]); }
2) Usare x*x invece di pow(x,2). Ragionevolmente la prima è sia più veloce che più precisa della seconda.
3) Volendo puoi calcolarti a a partire da b usando meno calcoli. Ma la differenza in termini di performance e/o precisione sono insignificanti.
4) Per il pow usato per persigmay potevi scrivere:
for (i=0; i<n; i++) { double const temp = (y[i]-a-b*x[i]); persigmay += (temp * temp); }
------------------------------
Non comprendo bene perché hai usato il termine varianza e per quale ragioni ritieni di conoscerla già... L'errore medio rispetto alla retta non è proprio quello che di solito viene chiamato varianza dei dati.
Grazie a entrambi, mi scuso per non aver messo subito il tag del codice, non sapevo come si faceva, ma adesso guardando un po' ho capito e la prossima volta lo farò! In effetti si, mettere un unico ciclo for è decisamente più conveniente, lo cambio subito. Mi sono accorta che il risultato era sbagliato nel senso che l'indeterminazione che doveva venirmi su a era diversa da quella di un esempio del libro (per testare se il programma funzionava ho provato con un esempio già svolto) ; poi adesso, riguardandolo, ho visto che avevo invertito due lettere, e quindi adesso viene. Solo che quando lo eseguo, se inserisco i dati velocemente funziona fino alla fine, se invece vado a una velocità normale si ferma prima da solo. E' strano. Ne ho parlato in un altro topic, quindi non importa! grazie dei consigli!