Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    [c++] array e ciclo for

    Salve a tutti, sono nuovo in questo forum e scrivo perchè ho un problema nel programma che sto sviluppando.
    Ho creato un programma che genera le traiettorie di un sistema planetario. Questo funziona perfettamente. Successivamente ho iniziato a parallelizzare il programma utilizzando le librerie dell'MPI e sono incappato in una strana cosa. Nel programma tutti i dati relativi ai pianeti sono inseriti in un unico array (non so se è importante, ma è un array dinamico) e succede che se entro in un ciclo for magicamente tutti i termini dell'array diventan "nan". Mi spiegi meglio:
    Se scrivo

    ...
    cout << v[0];
    for (int t =MIN; t<MAX; t+=h)
    {
    ...

    mi da come output il valore inserito effettivamente in v[0]. Se scrivo

    ...
    for (int t =MIN; t<MAX; t+=h)
    {
    cout << v[0];
    ...

    mi da come output nan. Non riesco proprio a capire cosa diavolo possa essere... Spero che qualcuno riesca a spiegarmi l'arcano.

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Mah ... detto così, non c'è spiegazione ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Prova ad isolare il problema in un blocco di codice che puoi postare e che noi possiamo provare.
    Amaro C++, il gusto pieno dell'undefined behavior.

  4. #4
    Ok ora vi posto il programma

  5. #5
    Ok, vi posto l'intero main: la variabile mype rappresenta il processore che sta leggendo,

    #include <iostream>
    #include <cmath>
    #include <fstream>
    #include <mpi.h>
    #define G 6.67428e-11
    #define M 1.9891e30
    #define MIN 0.
    #define MAX 1000000000.


    int x,y,vx,vy;


    int main(int argc,char** argv)
    {
    using namespace std;
    int nprocs, mype;
    MPI_Status status;
    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
    MPI_Comm_rank(MPI_COMM_WORLD, &mype);

    int N;
    if (mype == 0)
    {
    cout << "Inserisci il numero di pianeti: ";
    cin >> N;
    for (int k=1; k<4;k++)
    MPI_Send(&N,1,MPI_INTEGER,k,k,MPI_COMM_WORLD);
    }
    if (mype != 0) MPI_Recv(&N,1,MPI_INTEGER,0,MPI_ANY_TAG,MPI_COMM_W ORLD,&status);


    int i,n=4*N;

    double h=10000.;
    double *v=new double[n];
    double *m=new double[N];
    double a,e,AM,nn;
    if (mype == 0)
    {
    for (i =0; i<N ; i++)
    {
    cout << "Inserisci il semiasse maggiore a del pianeta " << i+1 << ": ";
    cin >> a;
    cout << "Inserisici l'eccentricità e del pianeta " << i+1 << ": ";
    cin >> e;
    cout << "Inserisci l'anomalia media M del pianeta " << i+1 << ": ";
    cin >> AM;
    cout << "Inserisci la massa del pianeta " << i+1 << ": ";
    cin >> m[i];
    nn=sqrt(G*(M+m[i])/(pow(a,3)));
    orb_to_car(a,e,AM,nn,v,i);
    ele_pia(i);
    cout << "x: " << v[x] << "y: " << v[y] << "vx: " << v[vx] << "vy: " << v[vy] << endl;
    }
    }
    MPI_Barrier(MPI_COMM_WORLD);
    MPI_Bcast(v,n,MPI_DOUBLE_PRECISION,0,MPI_COMM_WORL D);
    MPI_Bcast(m,N,MPI_DOUBLE_PRECISION,0,MPI_COMM_WORL D);


    /*----------------------------------------------------*/


    ofstream out;
    if (mype == 0) out.open("dati.dat");
    for (double t=MIN; t<=MAX; t+=h)
    {
    runge5(v,h,m,N,mype);
    if (mype==0)
    {
    for (i=0; i<N;i++)
    {
    ele_pia(i);
    out << v[x] << " " << v[y] << " ";
    }
    out << endl;
    }
    }

    /*----------------------------------------------------*/

    if (mype == 0) out.close();
    MPI_Finalize();

    return 0;

    }


    Ho evidenzioto il ciclo for in questione. Se metto un "cout << v[0];" prima del for allora mi da come output il valore esatto che avevo inserito, se lo metto dentro il ciclo allora mi da nan.

  6. #6
    Non c'è proprio nessuno che riesca a darmi una mano? Mi sembra una cosa assurda che il programma si comporti in questa maniera...

  7. #7
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Probabilmente dipende dalla libreria che usi. Non ti posso dire nulla perché non la uso (e non intendo installarla ...).

    Piuttosto, fai una prova a compilare il codice senza chiamate alla libreria ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  8. #8
    Intendi senza usare la libreria mpi.h? Il programma senza la libreria l'ho già compilato e funziona perfettamente, solo che devo parallelizzarlo e per farlo devo usare proprio la libreria dell'MPI...
    Cavoli... non capisco proprio cosa gli prende...
    Al max, sai suggerirmi qulche forum in cui si occupano proprio di programmazione parallela a cui potrei rivolgermi per risolvere questo problema?

  9. #9
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    A parte che il codice andrebbe postato come da regolamento (punto 6) perché così non si capisce granché, ci sono alcuni indici come x e y che usi nel main() ma che non hai inizializzato da nessuna parte. Li hai dichiarati globalmente, quindi è probabile che vengano modificati in una delle funzioni come orb_to_car() o ele_pia(), di cui non hai postato il codice... del resto le funzioni di libreria MPI che usi non penso scombinino molte cose perché non fanno nulla di particolare... l'unica cosa che non mi convince è

    codice:
    MPI_Send(&N,1,MPI_INTEGER,k,k,MPI_COMM_WORLD);
    ...
    MPI_Recv(&N,1,MPI_INTEGER,0,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
    ...
    perché la Send ha come tag k (con k che va da 1 a 3) e le Recv corrispondenti hanno tutte tag MPI_ANY_TAG? Sei sicuro che funzioni? E poi perché hai scritto k < 4? 4 sono i processori? Perché non hai usato nprocs che sarebbe stato più corretto e generale? Io cambierei con

    codice:
    MPI_Send(&N,1,MPI_INTEGER,k,k,MPI_COMM_WORLD);
    ...
    MPI_Recv(&N,1,MPI_INTEGER,0,mype,MPI_COMM_WORLD,&status);
    senza contare comunque che puoi sostituire il tutto con una semplice MPI_Bcast()...

    In ogni caso secondo me è impossibile individuare il problema così, se vuoi/puoi posta il programma completo (e secondo le regole!) a meno che non sia chilometrico e cerchiamo di darti un aiuto migliore.

    EDIT - un'altra cosa: perché usi i tipi di dato di libreria in stile Fortran (MPI_INTEGER, MPI_DOUBLE_PRECISION) anziché quelli in C (MPI_INT, MPI_DOUBLE) ?
    every day above ground is a good one

  10. #10
    Sì scusate, posto tutto il programma e stavolta sotto forma di codice. Ho corretto anche quelle cosette che mi hai suggerito.

    codice:
    #include <iostream>
    
    #include <cmath>
    
    #include <fstream>
    
    #include <iomanip>
    
    #include <mpi.h>
    
    
    #define G 6.67428e-11
    
    #define M 1.9891e30
    
    #define MIN 0.
    
    #define MAX 1000000000.
    
    
    
    
    void orb_to_car(double a, double e, double AM, double n, double v[],int i);
    
    void ele_pia(int i);
    
    void runge5 (double k[], double h, double m[], int N, int mype);
    
    double f(double g[], int i, double m[], int N);
    
    
    
    
    int x,y,vx,vy;
    
    
    
    int main(int argc,char** argv)
    
    {
    
    using namespace std;
    
    int nprocs, mype;
    
    MPI_Status status;
    
    MPI_Init(&argc,&argv);
    
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
    
    MPI_Comm_rank(MPI_COMM_WORLD, &mype);
    
    
    
    int N;    
    
    
    if (mype == 0)
    
      {
    
      cout << "Inserisci il numero di pianeti: ";
    
      cin >> N;
    
      MPI_Bcast(&N,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
    
      }
    
    
    
    int i,n=4*N;
    
    
    double h=10000.;
    
    double *v=new double[n];
    
    double *m=new double[N];
    
    double a,e,AM,nn;
    
    
    
    
    if (mype == 0)
    
    {
    
    for (i =0; i<N ; i++)
    
      {
    
      cout << "Inserisci il semiasse maggiore a del pianeta " << i+1 << ": ";
    
      cin >> a;
    
      cout << "Inserisici l'eccentricità e del pianeta " << i+1 << ": ";
    
      cin >> e;
    
      cout << "Inserisci l'anomalia media M del pianeta " << i+1 << ": ";
    
      cin >> AM;
    
      cout << "Inserisci la massa del pianeta " << i+1 << ": ";
    
      cin >> m[i];
    
      nn=sqrt(G*(M+m[i])/(pow(a,3)));
    
      orb_to_car(a,e,AM,nn,v,i);
    
      ele_pia(i);
    
      cout << "x: " << v[x] << "y: " << v[y] << "vx: " << v[vx] << "vy: " << v[vy] << endl;
    
      }
    
    }
    
    MPI_Barrier(MPI_COMM_WORLD);
    
    MPI_Bcast(v,n,MPI_DOUBLE,0,MPI_COMM_WORLD);
    
    MPI_Bcast(m,N,MPI_DOUBLE,0,MPI_COMM_WORLD);
    
    
    
    ofstream out;
    
    
    if (mype == 0) out.open("dati.dat");
    
    
    
    for (double t=MIN; t<=MAX; t+=h)
                 //<---------------------------------------------------------------------
      {
    
      runge5(v,h,m,N,mype);
    
      MPI_Barrier(MPI_COMM_WORLD);
    
      if (mype==0)
    
        {
    
        for (i=0; i<N;i++)
    
          {
    
          ele_pia(i);
    
          out << v[x] << " " << v[y] << " ";
    
          }
    
        out << endl;
    
        }
    
      }
    
    if (mype == 0) out.close();
    
    
    MPI_Finalize();
    
    return 0;
    
    }
    
    
    
    
    void ele_pia(int i)
    
    {
    
    x=4*i;
    
    y=x+1;
    
    vx=y+1;
    
    vy=vx+1;
    
    }
    
    
    
    
    void orb_to_car(double a, double e, double AM, double n, double v[],int i)
    
    {
    
    double U,Up,f,r;
    
    ele_pia(i);
    
    U=f=r=0.;
    
    Up=1.;
    
    for (int l=0; fabs(U-Up)>0.000001; l++)
    
      {
    
      Up=U;
    
      U=Up-(Up-(e*sin(Up*(M_PI/180)))-AM)/(1-e*cos(Up*(M_PI/180)));
    
      }
    
    r=a*(1-e*cos(U*(M_PI/180)));
    
    f=2*atan(sqrt((1+e)/(1-e))*tan(U*(M_PI/180)*0.5))*(180/M_PI);
    
    v[x]=r*cos(f*(M_PI/180));
    
    v[y]=r*sin(f*(M_PI/180));
    
    v[vx]=-(n*a*sin(U*(M_PI/180)))/(1-e*cos(U*(M_PI/180)));
    
    v[vy]=(n*a*cos(U*(M_PI/180))*sqrt(1-e*e))/(1-e*cos(U*(M_PI/180)));
    
    }
    
    
    
    
    void runge5 (double k[], double h, double m[], int N, int mype)
    
    {
    
    double *F1=new double[4*N];
    
    double *F2=new double[4*N];
    
    double *F3=new double[4*N];
    
    double *F4=new double[4*N];
    
    double *F5=new double[4*N];
    
    double *F6=new double[4*N];
    
    double *t2=new double[4*N];
    
    double *t3=new double[4*N];
    
    double *t4=new double[4*N];
    
    double *t5=new double[4*N];
    
    double *t6=new double[4*N];
    
    
    int i,q;
    
    for (int j=0; j<4; j++)
    
      {
    
      for(int s=0;s< N/4.;s++)
    
        {
    
    	q=4*j+16*s;
    
    	if((mype==j) && (q<4*N))
    
    	  {
    
          for (i=q; i<q+4; i++) t2[i]= k[i]+h*(2./9.)*(F1[i]=f(k,i,m,N));
    
          for (i=q; i<q+4; i++) t3[i]= k[i]+h*((1./12.)*F1[i]+(1./4.)*(F2[i]=f(t2,i,m,N)));
    
          for (i=q; i<q+4; i++) t4[i]= k[i]+h*((69./128.)*F1[i]-(243./128.)*F2[i]+(135./64.)*(F3[i]=f(t3,i,m,N)));
    
          for (i=q; i<q+4; i++) t5[i]= k[i]+h*(-(17./12.)*F1[i]+(27./4.)*F2[i]-(27./5.)*F3[i]+(16./15.)*(F4[i]=f(t4,i,m,N)));
    
          for (i=q; i<q+4; i++) t6[i]= k[i]+h*((65./432.)*F1[i]-(5./16.)*F2[i]+(13./16.)*F3[i]+(4./27.)*F4[i]+(5./144.)*(F5[i]=f(t5,i,m,N)));
    
          for (i=q; i<q+4; i++) F6[i]= f(t6,i,m,N);
    
        
    
          for (i=q; i<q+4; i++) k[i]+=h*((47./450.)*F1[i]+(12./25.)*F3[i] +(32./225.)*F4[i]+(1./30.)*F5[i]+(6./25.)*F6[i]);
    
    	  MPI_Bcast(&k[q],4,MPI_DOUBLE_PRECISION,0,MPI_COMM_WORLD);
    
          }
    
        }
    
      }
    
    }
    
    
    
    
    double f(double g[], int i,double m[], int N)
    
    {
    
    int p=i/4;
    
    ele_pia(p);
    
    if (i%4==0) return (g[vx]);
    
    if (i%4==1) return (g[vy]);
    
    double sum=0.;
    
    if (i%4==2)
    
      {
    
      for (int j=0; j<4*N; j+=4)
    
        {
    
        if (j/4!=p)
    
        sum+=G*m[j/4]*(((g[j]-g[x])/(pow(pow(g[j]-g[x],2)+pow(g[j+1]-g[y],2),1.5)))+(g[j]/(pow(g[j]*g[j]+g[j+1]*g[j+1],1.5))));
    
        }
    
      return ((-G*(M+m[p])*g[x]/(pow(g[x]*g[x]+g[y]*g[y],1.5)))+sum);
    
      }
    
    if (i%4==3)
    
        {
    
      for (int j=1; j<4*N; j+=4)
    
        {
    
        if (j/4!=p)
    
        sum+=G*m[j/4]*(((g[j]-g[y])/(pow(pow(g[j-1]-g[x],2)+pow(g[j]-g[y],2),1.5)))+(g[j]/(pow(g[j-1]*g[j-1]+g[j]*g[j],1.5))));
    
        }
    
      return ((-G*(M+m[p])*g[y]/(pow(g[x]*g[x]+g[y]*g[y],1.5)))+sum);
    
      }
    
    else return 0;
    
    }
    Ho evidenziato il ciclo for in questione. Il programma così scritto può essere compilato senza problemi, anche se forse non darà in output ciò che effettivamente è stato progettato di dare. Tuttavia è sufficiente per poter mostrare il mio problema. Provate a inserire il codice
    codice:
    if (mype==0) cout << "-------->" << v[0];
    fuori e dentro il ciclo for e dovrebbe darvi il primo un numero, il secondo "nan".

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.