Поэтому мне нужно переписать мой код R на C++. Это относительно легко, учитывая пакет Rcpp. Я столкнулся с проблемой при решении задачи оптимизации. В Р я звоню:
optimum_optim = optim(par=A, fn=negative_LL, gr=negative_grad_LL, .c = c, .t = t, .i = i, .N = N, method = 'BFGS')
Учитывая, что я уже переписал функции negative_LL и negative_grad_LL в свой файл C++, я хотел вызвать базовую процедуру для оптимизации BFGS из R: это функция vmmin из optim.c
У меня проблема в том, что я не могу понять подпись этой функции. Это:
vmmin(int n0, double *b, double *Fmin, optimfn fminfn, optimgr fmingr,
int maxit, int trace, int *mask,
double abstol, double reltol, int nREPORT, void *ex,
int *fncount, int *grcount, int *fail)
Не то чтобы я не прилагал никаких усилий к поиску - я просто не могу найти описание... Может ли кто-нибудь помочь вызвать эту функцию в моем конкретном случае (и сказать, какие аргументы)?





Похоже, вы уже использовали этот совет, но вам нужно пойти немного глубже: "Используй источник, Люк".
Моей отправной точкой было набрать в консоли R просто
optim
Это напечатает исходный код R этой функции. Там я видел, как он звонит
.External2(C_optim, par, fn1, gr1, method, con, lower, upper)
Мое любимое зеркало исходного кода R — это репозиторий GitHub. Если вы направитесь туда, наберете «оптимальный» и отфильтруете только результаты C, мы перейдем к лучшему совпадению, src/library/stats/src/optim.c. Затем мы можем увидеть, как optim() уровня C (строка 177) выполняет функцию звонки vmmin() (строка 295).
Способ optim() инициализирует эти аргументы следующим образом.
int n length(par)
double *b vect(npar); dpar[i] = REAL(par)[i] / (OS->parscale[i])
double *Fmin 0.0
optimfn fn function defined in the C code
optimgr gr function defined in the C code
int maxit asInteger(getListElement(options, "maxit"))
int trace asInteger(getListElement(options, "trace"))
int *mask mask = (int *) R_alloc(npar, sizeof(int));
for (i = 0; i < npar; i++) mask[i] = 1;
double abstol asInteger(getListElement(options, "abstol"))
double reltol asInteger(getListElement(options, "reltol"))
int nREPORT asInteger(getListElement(options, "REPORT"));
void *ex OptStruct OS; /* tons of stuff done to this */
int *fncount 0
int *grcount 0
int *fail 0
Я не описывал здесь все детали, но я считаю, что этого должно быть достаточно, чтобы помочь вам понять, как вам нужно использовать эти вещи в вашей собственной функции, как только вы узнаете еще об одной вещи: контрольном списке в optim(). Если вы заметили в вызове .External2() сверху, есть аргумент с именем con. Это определяется в коде R как
con <- list(trace = 0, fnscale = 1, parscale = rep.int(1, npar),
ndeps = rep.int(1e-3, npar),
maxit = 100L, abstol = -Inf, reltol = sqrt(.Machine$double.eps),
alpha = 1.0, beta = 0.5, gamma = 2.0,
REPORT = 10, warn.1d.NelderMead = TRUE,
type = 1,
lmm = 5, factr = 1e7, pgtol = 0,
tmax = 10, temp = 10.0)
хотя эти элементы могут быть переопределены пользовательским вводом в аргументе control, и если вы проверите help("optim"), вы увидите
The ‘control’ argument is a list that can supply any of the following components:
‘trace’ ...
Функция C обращается к этому списку по имени options, которое вы видите несколько раз в таблице, которую я построил выше.