Вызов оптимизации BFGS в C ++ из optim.c - PullRequest
0 голосов
/ 06 марта 2019

Итак, я должен переписать свой R-код на C ++.Это относительно просто, учитывая пакет Rcpp.Я столкнулся с проблемой при решении проблемы оптимизации.В вызове RI:

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 function from 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)

Дело не в том, что я не приложил никаких усилий к поиску - я просто не могу найти описание ... Может ли кто-нибудь помочь в вызове этой функции в моем конкретном случае (и скажите, чтоаргументы есть)?

1 Ответ

2 голосов
/ 06 марта 2019

Похоже, вы уже использовали этот совет, но вам нужно пойти немного глубже: "Использовать источник, Люк" .

Моя отправная точка состояла в том, чтобы с консоли R набрать просто

optim

Это печатает исходный код R этой функции. Там я увидел, что он звонит

.External2(C_optim, par, fn1, gr1, method, con, lower, upper)

Мое любимое зеркало для исходного кода R - , это репозиторий GitHub . Если вы направитесь туда, ищите «optim» и отфильтруете только результаты C, мы перейдем к главному хиту, src/library/stats/src/optim.c. Тогда мы можем увидеть, как функция уровня C optim() (строка 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"), вы увидите

Аргумент «control» - это список, который может содержать любой из следующих компонентов:
"След" ...

Функция C ссылается на этот список с именем options, на которое вы несколько раз ссылались в приведенной выше таблице.

...