#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:
Я вижу три возможности:
-
Вы компилируете программу на Fortran отдельно и вызываете ее с помощью R-функции
system()
. Вам нужно будет передавать данные через файлы в формате, доступном для чтения этой программой. -
Вы компилируете DLL, которую загружаете из R с помощью
dyn.load()
, затем вызываете функцию Fortran с помощью.Fortran()
. Вы можете легко передавать числовые данные (скаляры, векторы или массивы), но со строковыми данными сложнее обращаться. И массивы копируются. -
Этот механизм вызова функции 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 не распознается в командной строке.