2016-02-20 35 views
1

我寫了一個小的Fortran函數,並在Python中使用f2py將參數傳遞給它。不知何故,在傳輸過程中,參數的順序是混亂的,我不知道爲什麼。f2py - 函數參數的順序亂了

的Fortran函數(其是在名爲calc_density.f95文件)的相關部分:

subroutine calc_density(position, nparticles, ncells, L, density) 

implicit none 

integer, intent(in) :: nparticles 
integer, intent(in) :: ncells 
double precision, intent(in) :: L 
double precision, dimension(nparticles), intent(in) :: position 
double precision, dimension(ncells), intent(out) :: density 

double precision :: sumBuf, offSum 
integer :: pLower, pUpper, pBuf, numBuf, last, idx 
double precision, dimension(nparticles) :: sorted 

print *, 'Fortran ', 'position length ', size(position), & 
    'density length ', size(density), 'nparticles ', nparticles, & 
    'ncells ', ncells, 'L ', L 

end subroutine calc_density 

f2py編譯命令:

f2py -c --fcompiler=gnu95 -m fortran_calc_density calc_density.f95 

的Python代碼的相關部分:

from fortran_calc_density import calc_density as densityCalc 
from numpy import array, float64 

def calc_density(position, ncells, L): 
    arg = array(position, dtype = float64, order = 'F') 
    nparticles = len(position) 
    density = densityCalc(position, nparticles, ncells, L) 

    print 'Python ', 'position length ', len(position), 'density length', len(density), 'nparticles ', nparticles, 'ncells ', ncells, 'L ', L 
    return density 

屏幕輸出顯示所有傳輸變量不匹配的示例:

Fortran position length   12 density length   100 nparticles   12 ncells   100 L 20.000000000000000  
Python position length 100 density length 100 nparticles 100 ncells 20 L 12.5663706144 

從Python中的打印輸出顯示的值,除了密度陣列這應該是等於NCELLS的長度,因此20由Fortran函數的設計中,正是因爲他們應該。然而,Fortran值完全關閉,所以在傳輸過程中必然發生了一些事情,這些爭議攪亂了爭論。

我在這裏做錯了什麼?

+0

爲了避免混淆:即使在Python打印語句之前調用了densityCalc,您是否可以仔細檢查Fortran行在Python行之後是否打印*? – Evert

+0

對不起,這是誤導。實際上首先打印Fortran打印。 Python和Fortran函數實際上是在一個循環中調用的,因此可以連續打印到屏幕上。我只是挑選了兩個後續的輸出來顯示這個問題。結果在循環之間不會改變。現在已更正帖子,因此它顯示正確的打印順序。 – Marcel

回答

2

望着由f2py創建的文檔(編譯gfortran-5.3.0):

>>> print calc_density.__doc__ 

Wrapper for ``calc_density``. 

Parameters 
---------- 
position : input rank-1 array('d') with bounds (nparticles) 
ncells : input int 
l : input float 


Other Parameters 
---------------- 
nparticles : input int, optional 
    Default: len(position) 

Returns 
------- 
density : rank-1 array('d') with bounds (cells) 

你可以看到,nparticles是可選的(這是由f2py自動完成),而默認值是len(position) 。默認情況下,可選參數將移動到參數列表的末尾。因此,在您的通話中,最後一個參數被解釋爲nparticles

您可以將nparticles置於函數調用之外或將其移至最後一個參數。兩者:

density = densityCalc(position, ncells, L) 
density = densityCalc(position, ncells, L, nparticles) 

應導致正確的結果。如果你想保持FORTRAN子程序的參數列表的順序,你也可以使用關鍵字:

density = densityCalc(position=position, nparticles=nparticles, ncells=ncells, l=L) 

要注意,Fortran不區分大小寫,因此關鍵字必須是小寫l = L

+0

謝謝!現在神祕解決了,它工作正常:) – Marcel