alexbid | Bonjour tout le monde!
Voici mon premier code, alors soyez un peu indulgent. Je poste ce petit bout de code car je n ai pas trouve l equivalent sur ce forum mais aussi car j ai besoin d aide pour l ameliorer...
Ce code permet d inverser une matrice (n x n) (DIM x DIM en l occurence...) sous VBA via une DLL codee en C++.
Mes problemes sont les suivants:
1/ je suis oblige de rentrer la dimension de la matrice manuellement dans la DLL (?!! c est nul) => Cf. ligne1
je pense pouvoir recuperer la dimension du tableau par un safearrayget... mais je ne sais pas comment dimensionner un tableau avec des indices dynamiques...
2/ je suis oblige de faire une boucle pour construire un tableau 2 dimensions.... Cf. Ligne 44/52
Par contre l algorythme d inversion est tres puissant (LU decomposition trouvee sur internet).
Voila, vos commentaires sur ce code sont les bienvenus!
A+
Alex
Code :
- #define DIM 38
- long _stdcall MatriceInv(LPSAFEARRAY FAR *ArrayData1, LPSAFEARRAY FAR *ArrayData2)
- {
- // n est le rang de la matrice ArrayDAta1 et aussi de ArrayData2 !
- // renvoie 1 si inversible, 0 sinon
- // ArrayData1 est la matrice a inverser, ArrayData est le resultat
- /*****************************************************************************************
- ******************************************************************************************
- ************************** O) Initialisation des Variables *******************************
- ******************************************************************************************
- ******************************************************************************************/
- /*long a[DIM+1][DIM+1]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // dimension n x n
- double b[DIM+1][DIM+1]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};*/ // dimension n x n
- double a[DIM+1][DIM+1]= {0}; // dimension n x n
- double b[DIM+1][DIM+1]= {0}; // dimension n x n
- double c[(DIM+1) * (DIM+1)] = {0}; // dimension n^2
- double t[DIM+1][2*DIM+1]; // dimension n x 2*n-1
- int n = DIM;
- /*****************************************************************************************
- ******************************************************************************************
- ****************************** I) Get The Tableau! ***************************************
- ******************************************************************************************
- ******************************************************************************************/
- long rgIndices[2] = {0,0};
- double element = 0;
- int u, v;
- int w = 0;
- for (v = 0; v < n+1; v++)
- {
- for (u = 0; u < n+1; u++)
- {
- rgIndices[0] = u;
- rgIndices[1] = v;
- SafeArrayGetElement (*ArrayData1, rgIndices, &element);
- c[w] = element;
- w = w + 1;
- }
- }
- w= 0;
- for (v = 0; v < n+1; v++)
- {
- for (u = 0; u < n+1; u++)
- {
- a[u][v] = c[w];
- w = w + 1;
- }
- }
- /* // On test!
- ofstream fout("dict.txt",ios::app);
- for (v = 0; v < 16; v++)
- {
- fout << "\n" << "c[";
- fout << v;
- fout <<"] := ";
- fout << c[v];
- }
- for (u = 0; u < 3+1; u++)
- {
- for (v = 0; v < 3+1; v++)
- {
- fout << "\n" << "a[";
- fout << u;
- fout << "],[";
- fout << v;
- fout <<"] := ";
- fout << a[u][v];
- }
- }/*
-
- /*****************************************************************************************
- ******************************************************************************************
- **************************** II) Inverse la Bête! ****************************************
- ******************************************************************************************
- ******************************************************************************************/
- int i,j,k,l;
- float max,pivot,coef;
- for(i=1;i<=n;i++)
- for(j=1;j<=n;j++)
- {
- t[i][j]=a[i][j];
- if (i==j) t[i][j+n]=1.0;else t[i][j+n]=0.0;
- }
- int err=1;
- k=1;
- while (err==1 && k<=n)
- {
- max = fabs(t[k][k]);
- l=k;
- for(i=k+1;i<=n;i++)
- if(max<fabs(t[i][k]))
- {
- max = fabs(t[i][k]);
- l=i;
- }
- if(max!=0)
- {
- for(j=k;j<=2*n;j++)
- {
- max=t[k][j];
- t[k][j]=t[l][j];
- t[l][j]=max;
- }
- pivot=t[k][k];
- for(j=k+1;j<=2*n;j++)
- {
- t[k][j] /= pivot;
- }
-
- for(i=1;i<=n;i++)
- {
- if(i!=k)
- {
- coef=t[i][k];
- for(j=k+1;j<=2*n;j++)
- t[i][j] -= coef*t[k][j];
- }
- }
- }
- else err=0;
- k++;
- }
- for(i=1;i<=n;i++)
- {
- for(j=1;j<=n;j++)
- {
- b[i][j]=t[i][j+n];
- }
- }
- /* // On test encore!
- ofstream fout("dict.txt",ios::app);
- for (u = 1; u < n+1; u++)
- {
- for (v = 1; v < n+1; v++)
- {
- fout << "\n" << "b[";
- fout << u;
- fout << "],[";
- fout << v;
- fout <<"] := ";
- fout << b[u][v];
- }
- }*/
- /*****************************************************************************************
- ******************************************************************************************
- ********************* III) Retourne le resultat dans ArrayData2 **************************
- ******************************************************************************************
- ******************************************************************************************/
- for (v = 0; v < n+1; v++)
- {
- for (u = 0; u < n+1; u++)
- {
- rgIndices[0] = u;
- rgIndices[1] = v;
- element = b[u][v];
- SafeArrayPutElement (*ArrayData2, rgIndices, &element);
- w = w + 1;
- }
- }
- return(err);
- }
|
Appel en VBA:
Code :
- Declare Function MatriceInv Lib "C:\misc\Test3.dll" (integerArrayA() As Double, integerArrayB() As Double) As Long
- Sub test1()
- Dim a() As Double
- Dim b() As Double
- ReDim a(1 To 38, 1 To 38) As Double
- ReDim b(1 To 38, 1 To 38) As Double
- '''''''''''''''''''''''''''''''''''''''''''''''''''''
- For u = 1 To 38
- For v = 1 To 38
- b(u, v) = 0
- Next
- Next
- '''''''''''''''''''''''''''''''''''''''''''''''''''''
- a(1, 1) = 36
- *
- *
- *
- a(38, 38) = 225
- '''''''''''''''''''''''''''''''''''''''''''''''''''''
- tt = MatriceInv(a(), b())
- ' l inverse de a() est b()!
- End Sub
|
|