【问题标题】:How do I pass my (7, 3, 3, 3) array to a fortran subroutine?如何将我的 (7, 3, 3, 3) 数组传递给 fortran 子例程?
【发布时间】:2015-07-29 12:35:00
【问题描述】:

我已经通过 f2py 命令编写了一个 fortran 子例程,以便在 python 中使用。

子例程采用形状为 (7, 3, 3, 3) 的 numpy ndarray。该数组是一个由 7 个立方体组成的数组,大小为 3x3x3。我还将整数 7 和 3 传递给子程序。

这里是代码

        subroutine fit(n, m, a)

c ===================================================================
c                            ArrayTest.f
c ===================================================================
c       n            - number of cubes being passed
c
c       m            - edge of cube size
c
c       a(n,m,m,m)   - array of shape (n,m,m,m)
c
c ===================================================================

        implicit none
        integer m
        integer n
        double precision a(n,m,m,m)

        end subroutine fit

这只是看看我是否可以传递数组。当我从 python 编译和调用它时,我得到以下错误。

import ArrayTest as AT 
import numpy as np

n = 7
m = 3
a = np.ones((n,m,m,m))

AT.fit(n, m, a)

抛出

ArrayTest.error: (shape(a,0)==n) failed for 1st keyword n: fit:n=3

我不知道发生了什么。将 fortran 中的数组定义为 a(m,m,m,m) 不会引发任何问题,只有当我尝试从两个整数定义它时才会导致问题,即使我同时设置了 m = n = 3。如何我应该将我的 (7, 3, 3, 3) 数组传递给 fortran 子例程吗?

【问题讨论】:

    标签: python arrays numpy fortran f2py


    【解决方案1】:

    看一下 f2py 创建的 Python 函数的文档字符串:

    fit(a,[n,m])
    
    Wrapper for ``fit``.
    
    Parameters
    ----------
    a : input rank-4 array('d') with bounds (n,m,m,m)
    
    Other Parameters
    ----------------
    n : input int, optional
        Default: shape(a,0)
    m : input int, optional
        Default: shape(a,1)
    

    f2py 认识到 nm 描述了 a 的形状,因此不是 Python 函数的必需参数,因为可以通过检查 numpy 数组的形状找到它们。所以它们是 Python 函数fit 的可选第二个和第三个参数:

    In [8]: import ArrayTest as AT
    
    In [9]: n = 7
    
    In [10]: m = 3
    
    In [11]: a = np.zeros((n, m, m, m))
    
    In [12]: AT.fit(a, n, m)
    
    In [13]: AT.fit(a)
    

    【讨论】:

    • 非常感谢,调用 fit(a,[n,m]) 效果很好。我猜 f2py 比我在这种情况下更聪明!
    • 嗨沃伦,我遇到了类似的问题。 ==== 子程序 sdk(a,nx,ny,nz,axis,nsd,sdkrt) 双精度, dimension(nx,ny,nz), intent(in) :: a integer, intent(in) :: nx, ny,nz,axis,nsd 双精度,维度(nsd),intent(out) ::sdkrt DO SOME STUFF ==== 如果我用 (nx,ny,nz) 调用它,我会得到与 Adam 相同的错误。但是,如果我跳过 nx,ny,nz (因为它们是可选的),我会遇到分段错误。你对如何调试这个有什么建议吗?谢谢!
    猜你喜欢
    • 2018-01-15
    • 1970-01-01
    • 2012-10-15
    • 1970-01-01
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 2023-01-25
    相关资源
    最近更新 更多