Controllo programma in C

valentina921
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) :

#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
apatriarca
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?

vict85
Ci sono varie cose che metterei a posto:

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.

valentina921
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!

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.