Как вызвать программу на Fortran из R

#r #fortran #interop

#r #fortran #Взаимодействие

Вопрос:

Я совершенно новичок в Fortran и хорошо разбираюсь в R. Мне передали огромную программу на Fortran, содержащую около 30 подпрограмм, около 15 функций и множество других строк кода. Мне сказали, что мне нужно вызвать программу Fortran из R. Я искал в Интернете способы создания этого моста между R и Fortran с очень небольшим успехом. Я могу успешно выполнить исполняемый файл Fortran из командной строки и создать желаемые выходные данные. Файл fortran называется «FortFish.f»

Вопрос:

Из R я вызываю программу на Fortran или мне нужно вызывать функции и подпрограммы Fortran отдельно?

Из R я вызываю всю программу Fortran таким образом?: Запустите CMD SHLIB FortFish.f, а затем используйте: dyn.load(«FortFish.so «)

Если я не смогу запустить всю программу Fortran сразу, я опубликую пару небольших функций и подпрограмм fortran по запросу. Есть ли у кого-нибудь работающий пример использования R и Fortran, который можно использовать совместно?

Мой код на Fortran чрезвычайно большой, в противном случае я бы разместил его здесь. Спасибо.

Комментарии:

1. Если подходит программа Fortran, работающая в трех командных строках, то не является ли ее вызов с помощью system() из R столь же подходящим?

2. Не уверен, подходит ли.

Ответ №1:

Я вижу три возможности:

  1. Вы компилируете программу на Fortran отдельно и вызываете ее с помощью R-функции system() . Вам нужно будет передавать данные через файлы в формате, доступном для чтения этой программой.

  2. Вы компилируете DLL, которую загружаете из R с помощью dyn.load() , затем вызываете функцию Fortran с помощью .Fortran() . Вы можете легко передавать числовые данные (скаляры, векторы или массивы), но со строковыми данными сложнее обращаться. И массивы копируются.

  3. Этот механизм вызова функции DLL считается слишком упрощенным и в настоящее время .Call() является предпочтительным, но для использования .Call() вам пришлось бы написать C-оболочки.

Я приведу пример второй возможности. Рассмотрим подпрограмму на Fortran, которая вычисляет многочлен по алгоритму Хорнера:

 subroutine horner(n, a, x, y)
    implicit none
    integer :: n, i
    double precision :: a(n), x, y

    y = a(n)
    do i = n - 1, 1, -1
        y = y * x   a(i)
    end do
end subroutine
  

Скомпилируйте из командной строки с:

 R CMD SHLIB horner.f90
  

Чтобы вызвать ее из R:

 dyn.load("horner.dll")

horner <- function(a, x) {
  .Fortran("horner", as.integer(length(a)), a, x, y=0)$y
}

horner(c(-2, 0, 1), 1.414)
  

Если вы хотите, чтобы ваши подпрограммы Fortran выводили что-либо на консоль RStudio, вам нужно выполнить (по крайней мере, в Windows):

 Sys.unsetenv("GFORTRAN_STDOUT_UNIT")
Sys.unsetenv("GFORTRAN_STDERR_UNIT")
  

Это действительно тривиальный пример, и более сложная программа потребует больше работы, но вы уловили идею.


Если ваша программа на Fortran является автономной (она имеет модуль «program» и должна быть скомпилирована в исполняемый файл, вызываемый из командной строки), и если вы новичок в Fortran, я бы посоветовал придерживаться первого варианта, который будет намного проще. Вот что делает сезонный пакет: вызывает исполняемый файл Census’ X13AS изнутри R. Исполняемый файл находится в x13binary пакете.

Комментарии:

1. «вам пришлось бы написать оболочки C», или .Call совместимую с C процедуру Fortran (которая может быть оболочкой, если исходные процедуры Fortran не совместимы или не хотят, чтобы их меняли на быть).

2. @francescalus правильно. Я никогда не утруждал себя этим, но я думаю, что это было бы возможно.

3. Я обычно предпочитаю, .Call потому что .Fortran это действительно довольно паршиво, и человек настолько ограничен в том, что совместимо с R, что, по сути, он почти полностью совместим с C. (Обсуждение может сильно отклониться от темы из-за вашего ответа.)

4. @Жан-Клод Арбо — Я пытался воссоздать для вас пример horner.f90, но мне не удалось скомпилировать. У меня установлен Rtools3.5 и на моем пути, но я получаю сообщение об ошибке, что R не распознан. Посмотрите на скриншоты ниже: у меня есть «horner.f90», сохраненный на C:Fortran На самом деле я не могу добавлять скриншоты?

5. @Жан-Клод — Не могли бы вы поделиться тем, как вы настроили Rtools в своем PATH? У меня есть: C:Rtoolsbin ;C:Rtoolsmingw_64bin ;C:Rtoolsmingw_32bin ;C:Program FilesRR-3.6.3bini386; но R не распознается в командной строке.