C interfacing with Fortran

Wen-Nung Tsai tsaiwn at eecs.nwu.edu
Fri Aug 31 20:20:23 AEST 1990


In <1990Aug27.220828.9319 at metro.ucc.su.OZ.AU> glenn at qed.physics.su.oz.au writes:

>	I'm trying to write a program which uses a 2-d array of structs to
>represent a matrix of complex numbers: struct complex {double r; double i}.
>The array is dynamically allocated as it can become rather large. I don't
> want to do complex arithmetic in C (we don't have C++ :-)) so I thought I'd
> use Fortran.
> 
> Problem: How does one pass a 2-d C array of structs to a Fortran subroutine?
> 
> I've managed to do it with a 1-d array, but our Manuals (SUN OS 4.1) say
> nothing about 2-d arrays; that part seems to just be a copy (with minor changes)
> of the version 7 UNIX manual.
> ...
> 				Glenn
 
Since you already knew how to do it in one-d array, you can use the same
FORTRAN routine you have written if you want to apply the operation to
all elements of the 2-d array.
I.e., pass the address of the 2-d C array and the total-no-of-elements
to your FORTRAN routine which treats it as 1-d array.
For example, assume your FORTRAN routine looks like:
	subroutine add(aa,bb,n)
	complex aa(n), bb(n)
	...
And your C program contains:
	complex a1[3][5], a2[3][5];  /* you already defined STRUCT complex */
	int tot_ele;

Then, you can call "add" in this way:
	tot_ele=15;	/* 3*5=15 */
	add(a1,a2,&tot_ele)
NOTE the "&" sign! You can not say add(a1,a2,15), this is because :
	IN FORTRAN, parameters are always passed by REFERENCE.
	Thus, the variable "tot_ele" is necessary.

IF you insist to do it in 2-d array,(for example, you want to do
matrix operations in FORTRAN routine), it's not difficult:
    IN C:
	...
	#define CN1 5
	#define CN2 3
	#define CN3 7
	complex a1[CN1][CN2], a2[CN3][CN1];
	complex a3[CN3][CN2];
	int n1,n2,n3;
	...
	n1=CN1;  n2=CN2; n3=CN3;
	doit(a1,a2,a3,&n1,&n2,&n3)
	...
    In FORTRAN:
	subroutine doit(aa,bb,cc,n1,n2,n3)
	complex aa(n2,n1), bb(n1,1), cc(n2,*)
Comm		aa is (n2,n1), bb is (n1,n3), cc is (n2,n3)
	....
NOTE the a1[5][3] in C maps to aa(3,5) in FORTRAN routine, this is because:
    Array in C is arranged in row-major. But array in FORTRAN is column-major.
I.e., aa(1,1) is a1[0][0]; aa(2,1) is a1[0][1]; aa(3,1) is a1[0][2];
      aa(1,2) is a1[1][0];..... ................aa(i,k) is a1[k-1][i-1]
This allows the "aa" can be declared as aa(n2,*) or even aa(n2,1) in FORTRAN.

If it's a 3-d array, say c1[n1][n2][n3], it can be mapped to FORTRAN routine
as c1(n3,n2,n1) and the declaration in FORTRAN looks like:
	subroutine easy(c1,n1,n2,n3)
	complex c1(n3,n2,*)
(The last dimension of dummy(parameter) array always doesn't affect the result.
 So, you can declared it as any one of the following:
     complex c1(n3,n2,*)
     complex c1(n3,n2,1)
     complex c1(n3,n2,2)
     ...
     complex c1(n3,n2,999)
     ...
     complex c1(n3,n2,n1)
===========================Hope this can help you.

Wen-Nung
============================= Wen-Nung Tsai =============================
tsaiwn at eecs.nwu.edu             "Man invented language to satisfy his
                                 deep need to complain." -- Lily Tomlin
=========================================================================



More information about the Comp.lang.c mailing list