|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
[C] Passaggio array a funzione
Dal titolo il problema sembrerebbe semplice ma spiegando meglio credo che sia ancora piu semplice. Sto utilizzando del codice al cui interno è presente una funzione con la seguente intestazione:
Codice:
void func(double *p, double *x, int m, int n, void *data) Codice:
void func(double *p, double *x, int m, int n, double *data1, double *data2, double *data2) In un primo momento avevo pensato di inserire all'interno della funzione la lettura dei file e creare li dentro gli array di cui ho bisogno. Questa soluzione salvo mie sviste non è possibile poiche ci deve essere all'interno del programma un ciclo for che mi fa eseguire la lettura n volte. Volevo sapere una vostra idea sulla soluzione di questo problema. Per adesso ancora non ho provato ma cercando su internet ho trovato questa soluzione, ditemi se è giusta: Codice:
typedef double **matrice; matrice data; /* Dichiara la matrice */ ... /* Trova il valore di n */ a = calloc(dim1, sizeof *a); /* Alloca vettore di puntatori */ if ( !a ) { ... } for (i=0: i<n: i++) { a[i] = calloc(dim2, sizeof *a) /* Alloca i-esima riga */ if ( !a[i] ) { ... } } ... /* Usa la matrice */ for (i=0; i<n; i++) /* Libera la memoria */ free(a[i]); free(a); ![]() Codice:
dim1=3; dim2=numero_punti; Grazie a tutti.
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." Ultima modifica di salvodel : 02-01-2008 alle 08:21. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
# How can I pass my own data?
Assume that you want to pass two arrays, one of doubles and one of integers. A quick but not very elegant solution is to use global variables. The simplest way to avoid using globals is to declare a structure as struct mydata{ double dar[XXX]; int iar[YYY]; }; where XXX and YYY denote the appropriate array sizes. Then, define a structure variable with struct mydata data; and fill it: data.dar[0]=7.0; data.iar[0]=-17; // etc Following this, call the appropriate LM routine passing it the address of data as the adata argument, e.g. ret=dlevmar_der(func, fjac, ..., (void *)&data); Your func and fjac routines should interpret the supplied data using type casting: struct mydata *dptr; dptr=(struct mydata *)adata; // adata is passed as void * // supplied data can now be accessed as dptr->dar[0], etc Ho trovato questa soluzione ma non ho ben capito i passaggi nelle righe finali. Nella prima parte crea una struttura dati e passa l'indirizzo. Successivamente fa il type casting ma non ho capito bene. Provo ascrivere come ho capito: Codice:
struct mydata { double vet1[100]; double vet2[100]; } ..... struct mydata dati; Cioè mi ricreo una nuova variabile Codice:
struct mydata *dati_fun; Codice:
dati_fun=(struct mydata *)????? Codice:
dati_fun.vet1[]; dati_fun.vet2[]; ![]() Grazie a tutti e buon inizio anno.
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." Ultima modifica di salvodel : 02-01-2008 alle 08:48. |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Allora...
struct MyData { double *data1; double *data2; double *data3; double *data4; double *data5; } data; data.data1 = myData1; ... ... data.data5 = myData5; func(a, b, c, d, e, (void *)&data); Dentro a func ovviamente se vuoi usare i tuoi dati devi ottenere nuovamente il puntatore alla struttura: struct MyData *myData = (struct MyData *)data; //data è il puntatore a void passato A questo punto puoi utilizzare come vuoi la struttura con myData->data1...etc etc |
![]() |
![]() |
![]() |
#4 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Quote:
Ho provato a farlo girare ma non va ma credo di aver fatto alcuni errori Codice:
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <float.h> #include "lm.h" #define batch 10 #define stringa "OUTPUT.DAT" void errore(double *p, double *x, int m, int n, (void *)&data) { int ii,jj,kk,t; int S=10; struct mydata *matricedati= (struct mydata *)data; double u[2][batch]; double d[2][batch]; double err; /*..................*/ } int main() { struct mydata { double vet1[100]; double vet2[100]; } struct mydata data; register int i, j; int problem, ret; /*..................*/ ret=dlevmar_dif(errore, p, x, m, n, 1000, opts, info, NULL, NULL, NULL); /*..................*/ return 0; } Codice:
extern int dlevmar_dif( void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, int itmax, double *opts, double *info, double *work, double *covar, void *adata);
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
La funzione la devi definire così:
void errore(double *p, double *x, int m, int n, void *data) { } Il passaggio del parametro lo devi fare con (void *)&data. Inoltre la struct la devi dichiarare all'esterno del main e prima della definizione di errore. Mi dici chi ti ha nominato dlevmar_dif ? Non mi sembra di averne mai parlato nel post precedente ![]() |
![]() |
![]() |
![]() |
#6 | |||
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Quote:
Quote:
Correggimi se sbaglio: Nella dlevmar_dif passo i dati come mi hai detto tu (void *)&data nel terzo NULL in rosso poi credo che lo faccia in automatico la dlevmar_dif il passaggio dei dati alla funzione errore. Nella funzione errore invece devo mettere Codice:
struct mydata *matricedati= (struct mydata *)data; Quote:
Di nuovo grazie
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." Ultima modifica di salvodel : 03-01-2008 alle 10:47. |
|||
![]() |
![]() |
![]() |
#7 | |||
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quote:
void errore(double *p, double *x, int m, int n, (void *)&data) { } Quella modifica non va fatta... Quote:
![]() (void *)&data lo devi fare nella chiamata della funzione errore, non nella definizione della funziona come avevi messo... Quote:
![]() myData è un puntatore e come tale per accedere agli elementi della struttura dati bisogna usare l'operatore ->. myData->data1 equivale a (*myData).data1 |
|||
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Grazie a qualche tua strigliata
![]() ![]() Quote:
Io scrivo la funzione errore e le operazioni base le fa la funzione dlevmar_dif. Per passare i dati alla funzione errore non devo far altro che passarli alla funzione dlevmar_dif che li passa alla funzione errore. Il mio problema ora è che quello che faccio dentro la funzione errore mi viene ripetuto troppe volte...ma di questo te ne parlero nelle prossime ore dopo averci sbattutto un bel po la testa. Grazie
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Io non ho capito ancora cos'è questa dlevmar_dif e se fa parte della tua libreria o no
![]() Non è che mi dici come è definita ? |
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Quote:
Codice:
extern int dlevmar_dif( void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, int itmax, double *opts, double *info, double *work, double *covar, void *adata); Ora ho un dubbio: l'ultimo parametro della func si chiama data ma se faccio come mi dice le edit
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." Ultima modifica di salvodel : 04-01-2008 alle 09:50. |
|
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Mi fai vedere come richiami il tutto ?
|
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Per problemi di stabilità
![]() Ora ho un dubbio: l'ultimo parametro della func si chiama data ma se faccio come mi dice leFAQ mi da errore? Se invece metto data il programma gira e si pianta per altri motivi che adesso andrò ad indagare Come al solito grazie per l'interessamento. Ti invio il programma spolpato di tutte le cose che non servono...se cosi è poco chiaro ti metto anche il resto. Codice:
/******************************************************************************** * Levenberg-Marquardt minimization. ********************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <float.h> #include "lm.h" #define stringa "OUTPUT.DAT" #define esp 2.718281828459 struct mydata{ double t[100]; double X[100]; double XP[100]; double XPP[100]; double TETAG[100]; double WIND[100]; double d[100]; } data; /******************************************************************************** * Lettura dati da file "OUTPUT.DAT". ********************************************************************************/ int legge(int punti) { FILE *fp; int i=0; if((fp=fopen(stringa,"r"))==NULL) printf("Impossibile aprire il file"); else { printf("Dati letti:\n"); while(fscanf(fp,"%LE %LE %LE %LE %LE %LE %LE",&data.t[i],&data.X[i],&data.XP[i],&data.XPP[i],&data.TETAG[i],&data.WIND[i],&data.d[i])>0) { printf("."); i++; if(i>100) { printf("\n"); break; } } for(i=0;i<100;i++) printf("%.4g\t",data.t[i]); printf("\n"); } fclose(fp); return i; } /******************************************************************************** * Funzione dell'errore quadratico. ********************************************************************************/ void errore(double *p, double *x, int m, int n, void *data) { struct mydata *dptr; dptr=(struct mydata *)adata; /*Definizione delle coppie ingresso-uscita*/ for(t=0; t<40; t++) { u[0][t] = dptr->X[t]; u[1][t] = dptr->XP[t]; u[2][t] = dptr->XPP[t]; u[3][t] = dptr->TETAG[t]; u[4][t] = dptr->WIND[t]; } printf("\nAssegnazione vaolri u \n"); for(t=0; t<40; t++) { d[0][t] = dptr->X[t]; d[1][t] = dptr->XP[t]; d[2][t] = dptr->XPP[t]; } } /******************************************************************************** * M A I N. ********************************************************************************/ int main() { legge(punti); ret=dlevmar_dif(errore, p, x, m, n, 1000, opts, info, NULL, NULL, (void *)&data); }
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Ovviamente lì ci deve essere data e non adata
![]() La chiamata dovrebbe essere corretta. |
![]() |
![]() |
![]() |
#14 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Quote:
![]()
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
|
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
|
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Quote:
Visto che ci siamo ti chiedo un'altra cosa: ho 7 vettori ma non voglio passarli come Codice:
struct mydata { double vet1; double vet2; ...... double vet7; } data; Codice:
struct mydata { double mat[7][100]; } data; for(i=0;i<7;i++) for(j=0;j<100;j++) data.mat[i][j] Grazie
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
|
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Puoi mettere anche una matrice così come l'hai definita te...in pratica in quella struttura ci puoi mettere quello che ti pare
![]() La struttura la devi definire globale...l'istanza della struttura (cioè "data") la devi dichiarare locale. Infatti dice che definire quella struttura è un modo per evitare variabili globali. Ultima modifica di cionci : 04-01-2008 alle 13:54. |
![]() |
![]() |
![]() |
#18 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Quote:
![]() Cmq oggi, finalmente, sono riuscito ad utilizzare questo programmino ed il merito è tuo. Ti ringrazio per la pazienza ed i tanti consigli che mi hai dato. Visto che siamo in fase di ringraziamento anche se quasi certamente non apriranno mai questo post voglio ringraziare variabilepippo wingman87 amedeoviscido Ziosilvio gepeppe 71104 andbin yorkeiser Un ultimo speciale ringraziamento lo devo fare a mad_hhatter che mi ha spesso aiutato su alcuni dubbi "matematici". Di nuovo grazie a tutti anche a chi non compare nella lista per una mia mancanza. ![]() ![]() ![]() ![]() ![]()
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." Ultima modifica di salvodel : 04-01-2008 alle 15:05. |
|
![]() |
![]() |
![]() |
#19 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Bene
![]() ![]() |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 19:05.