nlopt_optimizer.cpp 2.09 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "nlopt_optimizer.hpp"
#include "nlopt.hpp"

#include "Utils.hpp"
#include <iostream>

namespace xacc {
OptResult NLOptimizer::optimize(OptFunction &function) {

  auto dim = function.dimensions();
  nlopt::algorithm algo = nlopt::algorithm::LN_COBYLA;
  double tol = 1e-8;
  int maxeval = 1000;

Mccaskey, Alex's avatar
Mccaskey, Alex committed
15
16
  if (options.stringExists("nlopt-optimizer")) {
    auto optimizerAlgo = options.getString("nlopt-optimizer");
17
18
19
20
21
22
23
24
25
26
    if (optimizerAlgo == "cobyla") {
      algo = nlopt::algorithm::LN_COBYLA;
    } else if (optimizerAlgo == "nelder-mead") {
      algo = nlopt::algorithm::LN_NELDERMEAD;
    } else {
      xacc::XACCLogger::instance()->error("Invalid optimizer at this time: " +
                                          optimizerAlgo);
    }
  }

27
28
  if (options.keyExists<double>("nlopt-ftol")) {
    tol = options.get<double>("nlopt-ftol");
29
30
  }

31
32
  if (options.keyExists<int>("nlopt-maxeval")) {
    maxeval = options.get<int>("nlopt-maxeval");
33
34
  }

35
  std::vector<double> x(dim);
36
37
38
39
40
  if (options.keyExists<std::vector<double>>("initial-parameters")) {
        x = options.get_with_throw<std::vector<double>>("initial-parameters");
  } else if (options.keyExists<std::vector<int>>("initial-parameters")) {
    auto tmpx = options.get<std::vector<int>>("initial-parameters");
    x = std::vector<double>(tmpx.begin(), tmpx.end());
41
  }
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  nlopt::opt _opt(algo, dim);
  std::function<double(const std::vector<double> &, std::vector<double> &,
                       void *)>
      f = [&](const std::vector<double> &x, std::vector<double> &grad,
              void *f_data) -> double { return function(x); };

  auto fptr = LambdaToVFunc::ptr(f);

  _opt.set_min_objective(fptr, NULL);
  _opt.set_lower_bounds(std::vector<double>(dim, -3.1415926));
  _opt.set_upper_bounds(std::vector<double>(dim, 3.1415926));
  _opt.set_maxeval(maxeval);
  _opt.set_ftol_rel(tol);

  double optF;
  try {
    auto result = _opt.optimize(x, optF);
  } catch (std::exception &e) {
    xacc::XACCLogger::instance()->error("NLOpt failed: " +
                                        std::string(e.what()));
  }
  return OptResult{optF, x};
}

} // namespace xacc