|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Aug 1999
Messaggi: 179
|
Aiutone in C
Devo trovare gli autovalori di una matrice 3x3 simmetrica utilizzando il linguaggio C, ho preso i seguenti 2 programmi dal sito "numerical recipies". Solamente che non so come usarli...
... so programmare in Matlab, ma non in C. 1)Vorrei sapere come si fa a definire una matrice, del tipo: a=(a11,a12,a13;a21,a22,a23;a31,a32,a33). 2)Ho scaricato il software MinGWStudio... è semplice da usare? 3) I seguenti programmi possono essere accorpati in uno solo semplicemente scrivendoli uno di seguito all'altro? GRAZIE A TUTTI ANTICIPATAMENTE. Questo è il programma che rende la matrice tridiagonale: #include <math.h> void tred2(float **a, int n, float d[], float e[]) Householder reduction of a real, symmetric matrix a[1..n][1..n]. On output, a is replaced by the orthogonal matrix Q e.ecting the transformation. d[1..n] returns the diagonal elements of the tridiagonal matrix, and e[1..n] the o.-diagonal elements, with e[1]=0. Several statements, as noted in comments, can be omitted if only eigenvalues are to be found, in which case a contains no useful information on output. Otherwise they are to be included. { int l,k,j,i; float scale,hh,h,g,f; for (i=n;i>=2;i--) { l=i-1; h=scale=0.0; if (l > 1) { for (k=1;k<=l;k++) scale += fabs(a[i][k]); if (scale == 0.0) e[i]=a[i][l]; else { for (k=1;k<=l;k++) { a[i][k] /= scale; h += a[i][k]*a[i][k]; } f=a[i][l]; g=(f >= 0.0 ? -sqrt(h) : sqrt(h)); e[i]=scale*g; h -= f*g; a[i][l]=f-g; f=0.0; for (j=1;j<=l;j++) { /* Next statement can be omitted if eigenvectors not wanted */ a[j][i]=a[i][j]/h; g=0.0; for (k=1;k<=j;k++) g += a[j][k]*a[i][k]; for (k=j+1;k<=l;k++) g += a[k][j]*a[i][k]; e[j]=g/h; f += e[j]*a[i][j]; } hh=f/(h+h); for (j=1;j<=l;j++) { f=a[i][j]; e[j]=g=e[j]-hh*f; for (k=1;k<=j;k++) a[j][k] -= (f*e[k]+g*a[i][k]); } } } else e[i]=a[i][l]; d[i]=h; } /* Next statement can be omitted if eigenvectors not wanted */ d[1]=0.0; e[1]=0.0; /* Contents of this loop can be omitted if eigenvectors not wanted except for statement d[i]=a[i][i]; */ for (i=1;i<=n;i++) { l=i-1; if (d[i]) { This block skipped when i=1. for (j=1;j<=l;j++) { g=0.0; for (k=1;k<=l;k++) g += a[i][k]*a[k][j]; for (k=1;k<=l;k++) a[k][j] -= g*a[k][i]; } } d[i]=a[i][i]; a[i][i]=1.0; for (j=1;j<=l;j++) a[j][i]=a[i][j]=0.0; } } Questo è il programma che ne trova gli autovalori: #include <math.h> #include "nrutil.h" void tqli(float d[], float e[], int n, float **z) QL algorithm with implicit shifts, to determine the eigenvalues and eigenvectors of a real, symmetric, tridiagonal matrix, or of a real, symmetric matrix previously reduced by tred2 §11.2. On input, d[1..n] contains the diagonal elements of the tridiagonal matrix. On output, it returns the eigenvalues. The vector e[1..n] inputs the subdiagonal elements of the tridiagonal matrix, with e[1] arbitrary. On output e is destroyed. When finding only the eigenvalues, several lines may be omitted, as noted in the comments. If the eigenvectors of a tridiagonal matrix are desired, the matrix z[1..n][1..n] is input as the identity matrix. If the eigenvectors of a matrix that has been reduced by tred2 are required, then z is input as the matrix output by tred2. In either case, the kth column of z returns the normalized eigenvector corresponding to d[k]. { float pythag(float a, float b); int m,l,iter,i,k; float s,r,p,g,f,dd,c,b; for (i=2;i<=n;i++) e[i-1]=e[i]; of e. e[n]=0.0; for (l=1;l<=n;l++) { iter=0; do { for (m=l;m<=n-1;m++) { dd=fabs(d[m])+fabs(d[m+1]); if ((float)(fabs(e[m])+dd) == dd) break; } if (m != l) { if (iter++ == 30) nrerror("Too many iterations in tqli"); g=(d[l+1]-d[l])/(2.0*e[l]); r=pythag(g,1.0); g=d[m]-d[l]+e[l]/(g+SIGN(r,g)); This is dm - ks. s=c=1.0; p=0.0; for (i=m-1;i>=l;i--) { f=s*e[i]; b=c*e[i]; e[i+1]=(r=pythag(f,g)); if (r == 0.0) { d[i+1] -= p; e[m]=0.0; break; } s=f/r; c=g/r; g=d[i+1]-p; r=(d[i]-g)*s+2.0*c*b; d[i+1]=g+(p=s*r); g=c*r-b; /* Next loop can be omitted if eigenvectors not wanted*/ for (k=1;k<=n;k++) { f=z[k][i+1]; z[k][i+1]=s*z[k][i]+c*f; z[k][i]=c*z[k][i]-s*f; } } if (r == 0.0 && i >= l) continue; d[l] -= p; e[l]=g; e[m]=0.0; } } while (m != l); } } |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Jul 2002
Città: Roma
Messaggi: 806
|
Allora, procediamo con ordine:
1) La matrice A, 3x3, la puoi definire così (ho usato float per esempio): float A [3][3]; short i,j; e per referenziare l'elemento aij farai: A [i][j] = ... 2) MiniGWStudio non l'ho mai usato, ma credo che sia abbastnza semplice (da quel che si sente in giro...) 3) Puoi accorpare tutto nello stesso modulo (*.c) avendo cura di: a) eliminare la definizione di #include<> ridondanti (math.h). b) devi crearti una funzione main(), che rappresenti l'entry-point del tuo programma e che poi, a sua volta, invochi le due funzioni che hai listato. Bye |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Aug 1999
Messaggi: 179
|
Grazie fpucci, G R A Z I E.
Ovviamente non ho capito bene: 1) Per definire la matrice così va bene: float A [3][3]; short i,j; A [1][1] = 1; A [1][2] = 2; A [1][3] = 3; A [2][1] = 4; A [2][2] = 5; A [2][3] = 6; A [3][1] = 7; A [3][2] = 8; A [3][3] = 9; 3a) Per eliminare gli include ridondanti basta che, ad esempio, elimino quelli del secondo programma? 3b) Non ho capito cosa devo fare.... Comunque GRAZIE ancora! |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Jul 2002
Città: Roma
Messaggi: 806
|
1) La matrice è correttamente definita, ma se usi il tipo float devi mettere anche il decimale.
Es. A [j][j] = 3.0 (invece di A [j][j] = 3 che è un numero intero) Cmq ci sono anche altri modi per inizializzare una matrice in maniera statica. Se vuoi farlo dinamicamente devi fare delle acquisizioni da input esterno (tastiera o file) 3a) esatto 3b) basta che aggiungi la procedura main() e fai una cosa del genere: Codice:
main () { ... ... tred2 (a, n, d, e); tqli (d, e, n, z); ... ... return (0); } Non ho letto nel dettaglio le due procedure, quindi non ho visto quali sono i parametri in input e quelli in output. Spero di essere stato abbastanza chiaro. |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Aug 1999
Messaggi: 179
|
Grazie.
Ancora non è tuuto chiaro, ma ci devo sbattere un po' la testa. Ci sono manuali online (magari in italiano) sul C? |
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: Jul 2002
Città: Roma
Messaggi: 806
|
Quote:
Eccone uno: http://www.strath.ac.uk/IT/Docs/Ccourse/ |
|
![]() |
![]() |
![]() |
#7 |
Junior Member
Iscritto dal: Mar 2004
Messaggi: 7
|
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 21:15.