Функция возвращает разные ответы с одинаковыми аргументами

Я перехожу из MATLAB в Fortran и сталкиваюсь со всеми видами странного поведения, которого я никогда не ожидал от MATLAB. Вот тот, который озадачил меня:

Program pruebanormal

double precision :: g01eaf, x, y

character :: T*1

integer :: Iffail

Iffail = 0

T = 'L'

x = 0.0

y = g01eaf('L',0.0,Iffail)

write(*,*) 'y = ',y

end program pruebanormal

У меня есть эта довольно простая программа, в которой я пытаюсь найти PDF при x=0 стандартной переменной N(0,1) (должно быть 0,5). g01eaf() это функция библиотеки NAG, которая делает это для меня. Я использую Gfortran для компиляции.

Оставляя остальную часть программы без изменений, в зависимости от того, как я пишу аргументы в g01eaf()Я получаю разные ответы:

a) g01eaf(T,x,Iffail)

b) g01eaf(T,0.0,Iffail)

c) g01eaf(T,x,0)

Теперь в MATLAB я получу один и тот же (правильный) ответ в любом случае: y = 0.500000. Однако под Fortran я получаю:

a) y = 0.500000

b) y = 1.000000

c) Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0xB766C163
#1  0xB766C800
#2  0xB77763FF
#3  0x804982E in g01eafn_
Violación de segmento (`core' generado)

У меня нет слов для ответа в (б) и понятия не имею, что (с) даже означает.

1 ответ

Решение

Очень быстрый ответ на "неправильный результат" заключается в том, что в

y = g01eaf('L',0.0,Iffail)

вы передаете вещественную переменную другого типа, чем в

double precision x
x = 0.0   ! x is still double precision.
y = g01eaf('L',x,Iffail)

Функция g01eaf вероятно, ожидает двойной точности: вы должны очень внимательно прочитать документацию NAG.

y = g01eaf('L', 0d0, Iffail)

Теперь уточним.

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

Если у вас есть актуальная версия библиотеки, вы хотите сделать что-то вроде

use nag_library, only : g01eaf, nag_wp
implicit none

integer Iffail
real(kind=nag_wp) y
y = g01eaf('L', 0._nag_wp, Iffail)

end

Снова смотрите документацию. Как для библиотеки, так и для значения модулей и т. Д.

Для более старых версий у вас должен быть доступный модуль, но его можно назвать чем-то другим, и nag_wp не может быть определено (это означает, что вы должны тщательно выбирать виды).

Модуль также приведет к жалобе, что Iffail требует возможности быть установленным, поэтому должна быть переменная, а не 0, Это объясняет (с).

Другие вопросы по тегам