Ошибка сегментации: 11 — работает фортран, завернутый в python

Я новичок в Fortran и пытаюсь запустить fortran внутри python с помощью f2py. Мне повезло, когда функция fortran выдавала одно значение. Но когда я модифицировал функцию фортрана для выдачи массива, я получаю ошибки сегментации.
Может ли кто-нибудь помочь мне? Вот код:

Функция Fortran: в файле с именем 'fortfunc.f95':

function fut(x,n) 
implicit none
real, intent(in) :: x
integer, intent(in) :: n
real, dimension(2) :: fut

! My aim is to return an array fut which has 2 elements in it

fut(1)=x*n
fut(2)=x*n*100


end function fut

Затем я использую f2py для компиляции функции fortran для использования в python:

f2py -c -m func fortfunc.f95 

здесь func — это имя модуля, который нужно импортировать в python.

Код Python: (довольно просто)

import func # func is the name of module which contains function fut
x=20
n=20
res=func.fut(x,n)
print('answer is ',res)

Я хочу получить массив с двумя элементами под названием «res», но вместо этого получаю «Ошибка сегментации: 11».

Может кто-нибудь указать на мою ошибку?


person insane_oceanographer    schedule 13.07.2018    source источник
comment
То, что вы хотите, невозможно. Вам нужно создать подпрограмму и передать массив. Вы можете прочитать здесь: stackoverflow.com/questions/17474225/   -  person Chiel    schedule 13.07.2018


Ответы (1)


Если вы работаете с подпрограммой, вы можете создать возвращаемый массив перед вызовом функции. В этом случае ваш скрипт Python будет выглядеть следующим образом

import func
import numpy as np

res = np.zeros(2)
x = 20
n = 20
func.fut(res, x, n)

print("answer is", res)

А в коде на Фортране можно создать подпрограмму. Обратите внимание, что я заменил тип на double precision, так как Fortran real по умолчанию является числом с плавающей запятой одинарной точности, тогда как Python использует двойную точность.

subroutine fut(a,x,n) 
    implicit none
    double precision, intent(in) :: x
    integer, intent(in) :: n
    double precision, intent(inout), dimension(2) :: a 

    ! My aim is to return an array fut which has 2 elements in it
    a(1) = x*n
    a(2) = x*n*100
end subroutine fut
person Chiel    schedule 13.07.2018
comment
Здорово! это работает на данный момент. Спасибо @Chiel! Также интересно, есть ли способ, которым функции Fortran могут иметь массив/матрицу в качестве выходов? - person insane_oceanographer; 13.07.2018
comment
Утверждение, что Fortran real является числом с плавающей запятой одинарной точности по умолчанию, в то время как Python использует двойную точность, не совсем верно. real — это просто вид по умолчанию, который зависит от параметров компилятора и платформы, а double precision дает только удвоенный размер real в байтах. Лучше использовать real32 и real64 из модуля fortran_iso_env вместо real и double precision, которые зависят от платформы. - person King; 16.07.2018