Я разработал пакет R, который обеспечивает обертку вокруг функции CVODE Солнечные часы (Библиотека решений ODE).
Пакет включает в себя функции источника (в src
а также inst/include
папки) и компилирует статические ссылки (.a
) а также .dll
файлы на лету (при компиляции пакета), поэтому не требуется SUNDIALS
пакет для установки в систему в качестве предварительного условия. Исходный код пакета можно найти по адресу
https://github.com/sn248/Rcppsbmod
Тем не мение, SUNDIALS
требует, чтобы функция ODE имела следующую подпись
int ODE_fun (realtype time, N_Vector y, N_Vector ydot, void *user_data);
куда realtype
, N_Vector
типы данных, определенные библиотекой SUNDIALS. Таким образом, примерная функция ODE будет определена следующим образом
#include <Rcpp.h>
using namespace Rcpp;
#include <cvode/cvode.h> /* prototypes for CVODE fcts., consts. */
#include <nvector/nvector_serial.h> /* serial N_Vector types, fcts., macros */
#define Ith(v,i) NV_Ith_S(v,i-1)
#define k1 0.04
#define k2 1e04
#define k3 3e07int test1 (realtype t, N_Vector y, N_Vector ydot){ // , void *user_data
// static keyword before int is not really required here
realtype y1 = Ith(y, 1);
realtype y2 = Ith(y, 2);
realtype y3 = Ith(y, 3);
realtype yd1 = Ith(ydot, 1);
realtype yd2 = Ith(ydot, 2);
realtype yd3 = Ith(ydot, 3);
yd1 = -k1 * y1 + k2 * y2 * y3;
yd3 = k3 * y2 * y2;
yd2 = -y1 - y3;return(0);
}
Компиляция этой функции, однако, требует cvode.h
а также nvector_serial.h
файлы заголовков, таким образом, требующие установки SUNDIALS.
Однако я хочу, чтобы пользователь мог определять ODE, используя Rcpp
только, т.е.
#include <Rcpp.h>
using namespace Rcpp;
#define k1 0.04
#define k2 1e04
#define k3 3e07int test2 (double t, NumericVector y, NumericVector ydot, void *user_data) {
ydot[0] = -k1 * y[0] + k2 * y[1] * y[2];
ydot[2] = k3 * y[1] * y[1];
ydot[1] = -y[0] - y[2];
return(0);
}
который затем будет направлен на cvode
функционировать как SEXP
(Вот ODE_fun
параметр) из пакета, который имеет подпись
cvode(NumericVector time_vec, NumericVector IC,
SEXP ODE_fun, double reltolerance, NumericVector abstolerance)
В настоящее время ODE_fun
указатель на функцию с typedef
typedef int (*funcPtr)(realtype t, N_Vector y, N_Vector ydot, void *user_data);
test1
преобразуется в XPtr
используя следующий код
// [[Rcpp::export]]
XPtr<funcPtr> putFunPtrInXPtr() {
XPtr<funcPtr> testptr(new funcPtr(&test), false);
return testptr;
}
Всю процедуру запуска примера примера можно найти в пакете вики.
Я не уверен, как вводить test2
(Функция ODE определена с использованием Rcpp
только) и преобразовать его в функцию с подписью, требуемой CVODE
решатель внутри пакета. Любые предложения или указания или, если есть лучший способ достичь моей цели, будет очень приветствоваться!
Спасибо
Задача ещё не решена.
Других решений пока нет …