使用SWIG和numpy.i包装Fortran for Python时的数组排序

2024-05-15 15:06:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个类似以下的Fortran子程序:

subroutine fsub(array, dim1, dim2) bind(c)
  use iso_c_binding, only: c_int, c_double
  integer(c_int), intent(in), value:: dim1, dim2
  real(c_double), intent(inout):: array(dim1, dim2)

  array(1, 1) = 1
  array(2, 1) = 2
  array(1, 2) = 100
end subroutine

如果我使用SWIG和numpy.I以及以下类型映射来包装它:

%apply (double* INPLACE_FARRAY2, int DIM1, int DIM2) {(double* array, int dim1, int dim2)}

%inline %{
void fsub(double* array, int dim1, int dim2);
%}

然后我必须分配一个“C”顺序数组来传入:

In [1]: import numpy as np; \
        import fmod; \
        arrayF = np.empty((100, 100), dtype=np.float_, order='F'); \
        arrayC = np.empty((100, 100), dtype=np.float_)
In [2]: fmod.fsub(arrayF)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-fa80220ec8a8> in <module>()
----> 1 fmod.fsub(arrayF)

TypeError: Array must be contiguous.  A non-contiguous array was given

In [3]: fmod.fsub(arrayC)
In [4]: arrayC[0, 0]
Out[4]: 1.0
In [5]: arrayC[1, 0]
Out[5]: 2.0
In [6]: arrayC[0, 1]
Out[6]: 100.0

我的问题是:

  1. Fortran语句array(2, 1) = 2不应该设置arrayC[0, 1]吗?你知道吗

如果我在%apply指令中有INPLACE_ARRAY2而不是INPLACE_FARRAY2,那么实际上我在调用之后会有arrayC[0,1] = 2.0。你知道吗

到底发生了什么?你知道吗

  1. 为什么不允许arrayF?如果我使用f2py,那么就必须使用arrayF,并且arrayC是不允许的,这是很直观的。你知道吗

Tags: innpoutarrayintdoublefortranfmod