can someone please help me ?
I'm using LAPACK fortran library in C by intel MKL, but have some
difficulty in using array.
for example, when we call fortran function like dgemv for matrix vector
multiplication and dgels for QR factorization,
dgemv(trans, m, n, apha, a, lda, x, incx, beta, y, incy)
dgels(trnas, m, n, nrhs, a, lda, b, ldb, work, lwork, info)
here a is 2 dim array and x, y, b are one dim array. I tried one-dim
array for a then dgemv works but dgels does not. what I did was defining
a[100] instead of a[10][10] and put this a into those function,
Can someone please inform me how to define two dim arrays for those
functions ?
Several things to remember about passing data between C and Fortran
routines. First, Fortran stores arrays in column-major order, whereas
C stores them in row-major order. In other words, if you have a 2x2
array in C of {{0,1},{2,3}}, Fortran will read it as {{0,2},{1,3}}.
You'll have to transpose your matrices before passing them to the
Fortran routine.
Second, Fortran expects scalars to be passed by reference, meaning you
need to pass pointers to those variables.
To pass an array to a Fortran routine, you pass the address of the
first element in the array, regardless of the number of dimensions.
Here's a quick-n-dirty example I womped up on my Red Hat box (no
warranties express or implied):
argtst.f:
C2345678
subroutine argtst(a, rw, cl)
integer*4 rw,cl
integer*4 a(rw,cl)
do 10 i=1,rw
do 20 j=1,cl
print *, 'a at',i,j,'=',a(i,j)
20 continue
10 continue
end
argtst.c:
#include <stdio.h>
/**
* Declaration for external F77 subroutine
* Note that the array parameter is a simple
* pointer to int, rather than a pointer to
* an array or double pointer to int.
* Also note that the row and
* column parameters are passed as pointers
*
* g77 appends an underscore to the function
* name, which is why the function is called
* argtst_ in the C file.
*/
extern argtst_(int *arr, int *rw, int *cl);
int main(void)
{
/**
* 2x2 array; v1t is the transposed
* version of v1
*/
int v1[2][2] = {{0,1},{2,3}};
int v1t[2][2] = {{0,2},{1,3}};
/**
* 3x4 array; v2t is the transposed version
* of v2
*/
int v2[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
int v2t[4][3] = {{0,4,8},{1,5,9},{2,6,10},{3,7,11}};
int rw, cl;
rw = cl = 2;
/**
* Pass the non-transposed version of v1 to argtst,
* followed by the transposed version, and compare
* output.
*
* Remember that we are passing the address of the
* first element of the array, which is a simple
* pointer to int.
*/
argtst_(&v1[0][0], &rw, &cl);
argtst_(&v1t[0][0], &rw, &cl);
rw = 3;
cl = 4;
/**
* Pass the non-transposed version of v1 to argtst,
* followed by the transposed version. Note that
* we do *not* change the values of rw and cl for
* v2t, even though v2t's dimensions are 4x3 instead
* of 3x4.
*/
argtst_(&v2[0][0], &rw, &cl);
argtst_(&v2t[0][0], &rw, &cl);
return 0;
}
So you start with an NxM array, then you need to transpose it to an
MxN array, and then you need to pass the address of the first element
of the transposed array to the routine.
Hope that helps (and is at least partially correct).