科学計算の場合、行列式や1次元配列、2次元配列が頻繁に出てくる…と思われる。
Fortran の場合、あまり可変配列を使わずに、あらかじめメモリ領域を確保する固定配列を使う…ってそうしていたのだが、最近はどうなのだろう。可変にするとメモリの確保に時間がかかってスピードに問題がでるので、固定長さの配列のほうが有利。
module structmodule
implicit none
! struct define
type F3D
double precision :: x,y,z
end type F3D
contains
! one array
integer function sum1( v, count )
integer :: v(10)
integer :: i, total
integer :: count
total = 0
do i=1,count
print *, 'in sum1: ', i, v(i)
total = total + v(i)
end do
sum1 = total
end function sum1
! 二次元配列を渡す
integer function sum2( v, cnti, cntj )
integer :: v(3,4)
integer :: cnti, cntj
integer :: i,j
integer :: total
total = 0
do i=1,cnti
do j=1,cntj
print *,i,j,v(i,j)
total = total + v(i,j)
end do
end do
sum2 = total
end function sum2
end module structmodule
引き数で配列の数を渡しているが、内部で固定にしかならないので、この場合はあまり意味がない。
最大長をチェックしてオーバーフローにならないように気を付けるとか。
extern "C" {
// 1次元配列
int STRUCTMODULE_mp_SUM1( int ary[], int *count );
// 2次元配列
int STRUCTMODULE_mp_SUM2( int ary[][3], int *cnti, int *cntj );
}
int v1[] = {1,2,3,4,5,6,7,8,9,10};
int count = 10;
int sum1 = STRUCTMODULE_mp_SUM1( v1, &count );
cout << "ans:" << sum1 << endl;
int v2[4][3] = {
{1,2,3},
{2,3,4},
{3,4,5},
{4,5,6},
};
int cnti = 3, cntj = 4;
int sum2 = STRUCTMODULE_mp_SUM2( v2, &cnti, &cntj );
cout << "ans:" << sum2 << endl;
注意しないといけないのは、Fortranは「1」始まりで、C++は「0」始まりということ。なので、Fortranで「3」番目にアクセスをすると、C++では添え字の「2」にアクセスする(0始まりなので、3番目の要素になる)。配列そのものを扱う場合には気にならないが、index を渡す場合には注意が必要。
Fortranのほうを0始まりにできるオプションもあるらしいのだが、元のソースに合わせるとすると標準的な1始まりの配列を扱うほうがよかろう。
あと、2次元配列の場合は、次元が逆のように見える。これは、Fortranのほうにあわせて作る。
