Я не понимаю вывод функции в коде Fortran95

Я только начал работать с foran95; Мне дали код, и я его изучаю; Я наткнулся на подпрограмму, которая вызывает функцию, но я не понимаю, что на выходе:

вот подпрограмма:

SUBROUTINE collisione(vga, ga, vgb, gb)

IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(3), INTENT(INOUT) :: ga, gb    
DOUBLE PRECISION, DIMENSION(3), INTENT(INOUT) :: vga, vgb  

DOUBLE PRECISION, DIMENSION(3)   :: r, ra, rb, r_r

ra = pos_ini(ga)
rb = pos_ini(gb)


END SUBROUTINE

вот функция:

FUNCTION pos_ini(g)

IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(3) :: pos_ini
DOUBLE PRECISION, DIMENSION(3), INTENT(IN) :: g

DOUBLE PRECISION, DIMENSION(3) :: es, eg, es_p
DOUBLE PRECISION :: rnd, b, kos, ang 

CALL RANDOM_NUMBER(rnd)
b = 1.D0 - 2.D0*rnd 
kos = SQRT(1.D0 - b*b)
CALL RANDOM_NUMBER(rnd)
ang = pi2 * rnd

es(1) = kos * COS(ang)
es(2) = kos * SIN(ang)
es(3) = b

eg = g / SQRT(DOT_PRODUCT(g,g))

es_p = es - DOT_PRODUCT(es,eg) * eg

pos_ini = d * es_p/SQRT(DOT_PRODUCT(es_p,es_p)) ! IS THIS THE OUTPUT THAT GIVES THE VALUE OF ra and rb???????

END FUNCTION

(читайте комментарий). Итак, вот мой вопрос: в подпрограмме я вижу, что переменные ra и rb определяются после использования функции pos_ini, где вводом является вектор ga или gb. Однако в функции pos_ini я не понимаю, что такое вывод; это pos_ini = d * es_p/SQRT(DOT_PRODUCT(es_p,es_p)) ?? если да то почему? и почему в функции pos_ini нет намерения (OUT)?


person Federico Gentile    schedule 18.02.2015    source источник
comment
См. также stackoverflow.com/q/27827878, хотя и не очень точное дублирование.   -  person francescalus    schedule 18.02.2015


Ответы (3)


В Фортране возвращаемое значение функции связано с именем функции или переменной в необязательном предложении result. Следовательно, значением функции будет то, что оказалось значением pos_ini в конце функции.

В вашем случае это выражение d * es_p/SQRT(DOT_PRODUCT(es_p,es_p)).

Это описано в любом учебнике по Fortran.

person Vladimir F    schedule 18.02.2015

Итак, эта линия

FUNCTION pos_ini(g)

начинает определение функции с именем pos_ini. И эта линия

DOUBLE PRECISION, DIMENSION(3) :: pos_ini

сообщает нам (и компилятору), что pos_ini вернет массив двойной точности с 3 элементами. Если не указано иное (с предложением result), функция Фортрана объявляет (автоматически или, как здесь, путем явного написания кода) результирующую переменную с тем же именем, что и у функции. И линия

pos_ini = d * es_p/SQRT(DOT_PRODUCT(es_p,es_p))

который определяет значение для pos_ini определяет, что будет возвращено при вызове функции. Нет необходимости, и это было бы ошибкой, которую компилятор уловил бы, объявлять возвращаемую переменную как intent(out).

Для функций, которые возвращают скалярное значение встроенного типа, объявление типа функции (или типа возвращаемой переменной, если вы хотите так думать) вы можете написать оператор открытия функции в строках

DOUBLE PRECISION FUNCTION pos_ini(g)

но, поскольку ваша функция возвращает массив, вы должны кодировать, как у вас, явно объявляя возвращаемую переменную.

person High Performance Mark    schedule 18.02.2015

pos_ini — это функция двойной точности, возвращающая массив из трех элементов. Я предполагаю, что он объявлен внутри модуля (потому что нет объявления для pi2 и для d), но здесь это не имеет большого значения.

В Фортране возвращаемое значение устанавливается путем присваивания имени функции (или имени в предложении RESULT, что здесь не применяется). Это делается с помощью строки

pos_ini = d * es_p/SQRT(DOT_PRODUCT(es_p,es_p))

что вас озадачило.

В данном случае это присваивание массива. В Fortran вы можете иметь присваивания массивам из скаляров или других массивов, арифметику массива (которая выполняется по элементам) и смешанную арифметику между скалярами и массивами.

Поскольку d не имеет определения, я не могу сказать, что это такое. Это будет допустимо либо как массив с экстентом 3, либо как скаляр. es_p — это массив того же размера, что и pos_ini, так что все в порядке. DOT_PRODUCT не требует пояснений; это sclar, как и SQRT.

Я бы порекомендовал вам прочитать эту статью о функциях Fortran 95.

person Community    schedule 18.02.2015