Получить доступ к переменным в функции f_grad после оптимизации с помощью RcppNumeric - PullRequest
0 голосов
/ 19 октября 2018

Я использую RcppNumeric для оптимизации и мне нужно несколько переменных, объявленных в функции f_grad после завершения оптимизации.

Чтобы объяснить мой вопрос, давайте возьмем стандартный пример в пакете RcppNumeric.Прежде всего, нам нужно создать класс.

// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppNumerical)]]

#include <RcppNumerical.h>

using namespace Numer;

// f = 100 * (x2 - x1^2)^2 + (1 - x1)^2
// True minimum: x1 = x2 = 1
class Rosenbrock: public MFuncGrad
{
public:
double f_grad(Constvec& x, Refvec grad)
    {
     double t1 = x[1] - x[0] * x[0];
     double t2 = 1 - x[0];
     grad[0] = -400 * x[0] * t1 - 2 * t2;
     grad[1] = 200 * t1;
     return 100 * t1 * t1 + t2 * t2;
    }
};

Следующий код затем используется для оптимизации.

// [[Rcpp::export]]
Rcpp::List optim_test()
{
    Eigen::VectorXd x(2);
    x[0] = -1.2;
    x[1] = 1;
    double fopt;
    Rosenbrock f;
    int res = optim_lbfgs(f, x, fopt);
    return Rcpp::List::create(
        Rcpp::Named("xopt") = x,
        Rcpp::Named("fopt") = fopt,
        Rcpp::Named("status") = res
    );
}

Как получить доступ к t1 или t2 значение после завершения оптимизации.Я хочу иметь в виду значение этих переменных для решения оптимизации.

Мой пример может быть не очень хорошим для того, что я ищу, потому что легко вычислить t1 или t2 вне оптимизации этого примера.В моем случае мне нужны переменные, которые в вычислительном отношении громоздки.Итак, если они уже рассчитаны во время оптимизации, почему бы не вернуть их (или не иметь доступа к их значениям) после оптимизации без необходимости их повторного расчета вне оптимизации?

1 Ответ

0 голосов
/ 19 октября 2018

Вы можете использовать переменные-члены для переменных, представляющих интерес.Для простоты я использую public членов здесь:

// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppNumerical)]]

#include <RcppNumerical.h>

using namespace Numer;

// f = 100 * (x2 - x1^2)^2 + (1 - x1)^2
// True minimum: x1 = x2 = 1
class Rosenbrock: public MFuncGrad
{
public:
  double t1;
  double t2;

  double f_grad(Constvec& x, Refvec grad)
  {
    t1 = x[1] - x[0] * x[0];
    t2 = 1 - x[0];
    grad[0] = -400 * x[0] * t1 - 2 * t2;
    grad[1] = 200 * t1;
    return 100 * t1 * t1 + t2 * t2;
  }
};

// [[Rcpp::export]]
Rcpp::List optim_test()
{
  Eigen::VectorXd x(2);
  x[0] = -1.2;
  x[1] = 1;
  double fopt;
  Rosenbrock f;
  int res = optim_lbfgs(f, x, fopt);
  return Rcpp::List::create(
    Rcpp::Named("xopt") = x,
    Rcpp::Named("fopt") = fopt,
    Rcpp::Named("status") = res,
    Rcpp::Named("t1") = f.t1,
    Rcpp::Named("t2") = f.t2
  );
}

/*** R
optim_test()
*/

Результат:

> optim_test()
$xopt
[1] 1 1

$fopt
[1] 3.12499e-15

$status
[1] 0

$t1
[1] -2.849634e-09

$t2
[1] -4.809313e-08
...