Как вызвать R-функции из Fortran?

Согласно http://gallery.rcpp.org/articles/r-function-from-c++  Rcpp позволяет пользователям вызывать функции R из С++. Здесь что-то подобное в Фортране, чтобы люди могли вызвать функцию R в Код Fortran?

Ответ 1

Я считаю, что вы должны смотреть на RFortran? AFAIK это единственное связывание Fortran объектов R, плюс это открытый исходный код.

ИЗМЕНИТЬ

В соответствии с приведенными ниже комментариями я не знал, что RFortran применим только к Windows. Таким образом, для более портативного ответа создайте пример, в котором я буду использовать RInside, что упростит внедрение функций R в код на С++. Я также использовал бы iso_c_binding для интерфейса с C.

testC.cpp

#include <iostream>
#include <RInside.h>                    

void helloR_(int argc, char *argv[], const char *msg);

extern "C" void helloR(int argc, char *argv[], const char *msg) {

    // create an embedded R instance
    RInside R(argc, argv);              

    // convert to string for RInside assignment
    std::string txt = std::string(msg);

    // C++ Notice
    std::cout << "This is C++, " << txt << std::endl;

    // Assign string to R object
    R.assign(txt, "txt");

    // eval the string, give R notice
    R.parseEvalQ("cat('This is R, ', txt, '\n')");
}

testF.f

  PROGRAM MAIN
    USE iso_c_binding
    IMPLICIT NONE
    INTEGER :: argc
    CHARACTER(len=32) :: arg
    CHARACTER(len=32) :: msg

    INTERFACE
      SUBROUTINE R_FUN(argc, arg, msg) bind(C, name="helloR")
        USE iso_c_binding
        INTEGER(kind=c_int), INTENT(IN) :: argc
        CHARACTER(kind=c_char), INTENT(IN) :: arg(*)
        CHARACTER(kind = C_CHAR), INTENT(IN) :: msg(*)
      END SUBROUTINE R_FUN
    END INTERFACE

    print *, "Fortran Calling RInside"
    CALL R_FUN (argc, arg, "Hello World"//C_NULL_CHAR)

  END PROGRAM

Компиляция Fortran проста:

gfortran -c testF.f

Компиляция С++ немного сложна, учитывая, что вы должны знать, где находятся ваши каталоги include для R, Rcpp и RInside.

g++ testC.cpp -c -I/path/to/RInside/include -I/path/to/Rcpp/include -I/usr/share/R/include

Затем для связывания вам необходимо предоставить правильные библиотеки и флаг lgfortran.

g++ -o fcr testF.o testC.o -L/usr/lib/R/lib -lR -L/path/to/RInside/lib/ -lRInside -L/path/to/Rcpp/libs/ -Wl,-rpath,/home/path/to/RInside/lib/ -lRInside -Wl,-rpath,/path/to/Rcpp/libs/ -lgfortran

Теперь у меня есть небольшая программа, демонстрирующая, как получить доступ к функциям R формы Fortran

./fcr
 Fortran Calling RInside
This is C++, Hello World
This is R,  Hello World 

Ответ 2

Общее решение состоит в том, чтобы записать данные в файл из программы Fortran, вызвать EXECUTE_COMMAND_LINE (стандартный Fortran 2003) или что-то вроде SYSTEM (общее расширение) для вызова R script, который записывает свои результаты в файл, а затем прочитать эти результаты из программы Fortran.

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

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