nlopt_solver.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <stdlib.h>
3 #include <nlopt.h>
4 
5 #include "nlopt_solver.h"
6 //#include "eus_function.cpp"
7 
9  const double* x_min,
10  const double* x_max,
11  int (*f)(double*,double*), int (*df)(double*,double*),
12  int (*g)(double*,double*), int (*dg)(double*,double*),
13  int (*h)(double*,double*), int (*dh)(double*,double*),
14  int m_x, int m_g, int m_h,
15  double ftol, double xtol, double eqthre, int max_eval, double max_time,
17  :
18  x(x), m_x(m_x), m_g(m_g), m_h(m_h), iteration(0), n_f(0), n_df(0), n_g(0), n_dg(0), n_h(0), n_dh(0) {
19  this->f = f ;
20  this->df = df;
21  this->g = g ;
22  this->dg = dg;
23  this->h = h ;
24  this->dh = dh;
25  //
26  this->fbuf = (double*)malloc(sizeof(double)*1) ;
27  this->fbuf[0] = 0 ;
28  this->dfbuf = (double*)malloc(sizeof(double)*1*m_x) ;
29  for ( uint i=0 ; i<1*m_x ; i++ ) this->dfbuf[i] = 0 ;
30  this->gbuf = (double*)malloc(sizeof(double)*m_g) ;
31  for ( uint i=0 ; i<m_g ; i++ ) this->gbuf[i] = 0 ;
32  this->dgbuf = (double*)malloc(sizeof(double)*m_g*m_x) ;
33  for ( uint i=0 ; i<m_x*m_g ; i++ ) this->dgbuf[i] = 0 ;
34  this->hbuf = (double*)malloc(sizeof(double)*m_h) ;
35  for ( uint i=0 ; i<m_h ; i++ ) this->hbuf[i] = 0 ;
36  this->dhbuf = (double*)malloc(sizeof(double)*m_h*m_x) ;
37  for ( uint i=0 ; i<m_x*m_h ; i++ ) this->dhbuf[i] = 0 ;
38  //
39  // ラグランジュ法を用いて全てのアルゴリズムで制約条件を扱えるようにする
40  if(algorithm == Optimization::NLopt::ISRES || algorithm == Optimization::NLopt::SLSQP)
41  {
42  core_solver = nlopt_create(NLOPT_LD_CCSAQ, m_x); // dummy
43  if(algorithm == Optimization::NLopt::ISRES)
44  {
45  solver = nlopt_create(NLOPT_GN_ISRES, m_x);
46  nlopt_set_maxeval(solver, 1e6);
47  nlopt_set_maxtime(solver, 24*60*60);
48  }
49  else
50  {
51  solver = nlopt_create(NLOPT_LD_SLSQP, m_x);
52  nlopt_set_ftol_rel(solver, ftol);
53  nlopt_set_xtol_rel(solver, xtol);
54  //nlopt_set_maxeval(solver, 1e3);
55  }
56  }
57  else if(algorithm == Optimization::NLopt::G_DIRECT || algorithm == Optimization::NLopt::G_DIRECT_L || algorithm == Optimization::NLopt::CCSA)
58  {
59  // nlopt_opt core_solver;
60  if(algorithm == Optimization::NLopt::CCSA)
61  {
62  core_solver = nlopt_create(NLOPT_LD_CCSAQ, m_x);
63  nlopt_set_ftol_rel(core_solver, ftol);
64  nlopt_set_xtol_rel(core_solver, xtol);
65  nlopt_set_maxeval(core_solver, 1e6);
66  }
67  else
68  {
69  if(algorithm == Optimization::NLopt::G_DIRECT)
70  {
71  core_solver = nlopt_create(NLOPT_GN_ORIG_DIRECT, m_x);
72  }
73  else
74  {
75  core_solver = nlopt_create(NLOPT_GN_ORIG_DIRECT_L, m_x);
76  }
77  nlopt_set_maxeval(core_solver, 1e6);
78  nlopt_set_maxtime(core_solver, 24*60*60);
79  nlopt_set_ftol_rel(core_solver, ftol);
80  nlopt_set_xtol_rel(core_solver, xtol);
81  }
82  solver = nlopt_create(NLOPT_AUGLAG_EQ, m_x);
83  nlopt_set_local_optimizer(solver, core_solver);
84  nlopt_set_ftol_rel(solver, ftol);
85  nlopt_set_xtol_rel(solver, xtol);
86  nlopt_set_maxeval(solver, 1e6);
87  // nlopt_destroy(core_solver);
88  }
89  else if(algorithm == Optimization::NLopt::DIRECT || algorithm == Optimization::NLopt::DIRECT_L || algorithm == Optimization::NLopt::CRS || algorithm == Optimization::NLopt::STOGO || algorithm == Optimization::NLopt::L_BFGS || algorithm == Optimization::NLopt::TN || algorithm == Optimization::NLopt::SL_VM)
90  {
91  // nlopt_opt core_solver;
92  if(algorithm == Optimization::NLopt::DIRECT || algorithm == Optimization::NLopt::DIRECT_L || algorithm == Optimization::NLopt::CRS || algorithm == Optimization::NLopt::STOGO)
93  {
94  if(algorithm == Optimization::NLopt::DIRECT)
95  {
96  core_solver = nlopt_create(NLOPT_GN_DIRECT, m_x);
97  }
98  else if(algorithm == Optimization::NLopt::DIRECT_L)
99  {
100  core_solver = nlopt_create(NLOPT_GN_DIRECT_L, m_x);
101  }
102  else if(algorithm == Optimization::NLopt::CRS)
103  {
104  core_solver = nlopt_create(NLOPT_GN_CRS2_LM, m_x);
105  }
106  else
107  {
108  core_solver = nlopt_create(NLOPT_GD_STOGO, m_x);
109  }
110  nlopt_set_maxeval(core_solver, 1e6);
111  nlopt_set_maxtime(core_solver, 24*60*60);
112  nlopt_set_ftol_rel(core_solver, ftol);
113  nlopt_set_xtol_rel(core_solver, xtol);
114  }
115  else
116  {
117  if(algorithm == Optimization::NLopt::L_BFGS)
118  {
119  core_solver = nlopt_create(NLOPT_LD_LBFGS, m_x);
120  }
121  else if(algorithm == Optimization::NLopt::TN)
122  {
123  core_solver = nlopt_create(NLOPT_LD_TNEWTON_PRECOND_RESTART, m_x);
124  }
125  else
126  {
127  core_solver = nlopt_create(NLOPT_LD_VAR2, m_x);
128  }
129  nlopt_set_ftol_rel(core_solver, ftol);
130  nlopt_set_xtol_rel(core_solver, xtol);
131  //nlopt_set_maxeval(core_solver, 1e3);
132  }
133  solver = nlopt_create(NLOPT_AUGLAG, m_x);
134  nlopt_set_local_optimizer(solver, core_solver);
135  nlopt_set_ftol_rel(solver, ftol);
136  nlopt_set_xtol_rel(solver, xtol);
137  //nlopt_set_maxeval(solver, 1e3);
138  // nlopt_destroy(core_solver);
139  } else if ( algorithm == Optimization::NLopt::COBYLA ||
140  algorithm == Optimization::NLopt::BOBYQA ||
141  algorithm == Optimization::NLopt::NEWUOA ||
142  algorithm == Optimization::NLopt::PRAXIS ||
144  algorithm == Optimization::NLopt::Sbplx ){
145  core_solver = nlopt_create(NLOPT_LD_CCSAQ, m_x); // dummy
146  if(algorithm == Optimization::NLopt::COBYLA)
147  {
148  solver = nlopt_create(NLOPT_LN_COBYLA, m_x);
149  nlopt_set_ftol_rel(solver, ftol);
150  nlopt_set_xtol_rel(solver, xtol);
151  }
152  else if(algorithm == Optimization::NLopt::BOBYQA)
153  {
154  solver = nlopt_create(NLOPT_LN_BOBYQA, m_x);
155  nlopt_set_ftol_rel(solver, ftol);
156  nlopt_set_xtol_rel(solver, xtol);
157  }
158  else if(algorithm == Optimization::NLopt::NEWUOA)
159  {
160  solver = nlopt_create(NLOPT_LN_NEWUOA, m_x);
161  nlopt_set_ftol_rel(solver, ftol);
162  nlopt_set_xtol_rel(solver, xtol);
163  }
164  else if(algorithm == Optimization::NLopt::PRAXIS)
165  {
166  solver = nlopt_create(NLOPT_LN_PRAXIS, m_x);
167  nlopt_set_ftol_rel(solver, ftol);
168  nlopt_set_xtol_rel(solver, xtol);
169  }
170  else if(algorithm == Optimization::NLopt::NelderMeadSimplex)
171  {
172  solver = nlopt_create( NLOPT_LN_NELDERMEAD, m_x);
173  nlopt_set_ftol_rel(solver, ftol);
174  nlopt_set_xtol_rel(solver, xtol);
175  }
176  else if(algorithm == Optimization::NLopt::Sbplx)
177  {
178  solver = nlopt_create(NLOPT_LN_SBPLX, m_x);
179  nlopt_set_ftol_rel(solver, ftol);
180  nlopt_set_xtol_rel(solver, xtol);
181  }
182  }
183  //
184  if ( max_eval > 0 ) nlopt_set_maxeval(solver,max_eval) ;
185  if ( max_time > 0 ) nlopt_set_maxtime(solver,max_time) ;
186  // 定義域の設定
187  nlopt_set_lower_bounds(solver, x_min);
188  nlopt_set_upper_bounds(solver, x_max);
189  // 評価関数の設定
190  nlopt_set_min_objective(solver, NLoptSolver::ObjectiveFunctionWrapper, this);
191  // 等式制約条件の設定
192  // 数値的安定性のためにある程度の誤差を許容する
193  double equality_constraint_tolerance[m_g];
194  std::fill(equality_constraint_tolerance, equality_constraint_tolerance + m_g, eqthre);
195  nlopt_add_equality_mconstraint(solver, m_g, NLoptSolver::EqualityConstraintWrapper, this, equality_constraint_tolerance);
196  // 不等式制約条件の設定
197  // 数値的安定性のためにある程度の誤差を許容する
198  double inequality_constraint_tolerance[m_h];
199  std::fill(inequality_constraint_tolerance, inequality_constraint_tolerance + m_h, eqthre);
200  nlopt_add_inequality_mconstraint(solver, m_h, NLoptSolver::InequalityConstraintWrapper, this, inequality_constraint_tolerance);
201  int major, minor, bugfix;
202  nlopt_version(&major, &minor, &bugfix);
203 }
204 
206 {
207  nlopt_destroy(solver);
208  if ( core_solver ) {
209  nlopt_destroy(core_solver);
210  core_solver = NULL;
211  }
212 }
213 
214 double NLoptSolver::ObjectiveFunctionWrapper(unsigned int n, const double* x, double* df, void* self)
215 {
216  // 変数に代入する
217  NLoptSolver* self_=reinterpret_cast<NLoptSolver*>(self);
218  my_copy((double*)x,self_->x,self_->m_x) ; //self_->x = (double*)x ;
219  // 評価関数の計算
220  double f=self_->ObjectiveFunctionCost();
221  // 各イテレーションの結果を出力する
222 // OutputLog(self_->log_file, self_->frequency, std::setw(6) << std::right << self_->iteration << " " << std::scientific << std::setw(13) << f);
223  // 勾配ベクトルの計算
224  if(df != NULL)
225  {
226  my_copy(df,self_->dfbuf,1 * self_->m_x) ;
227  self_->ObjectiveFunctionGradient(self_->dfbuf);
228  my_copy(self_->dfbuf, df,1 * self_->m_x) ;
229  // 勾配ベクトルのノルムを出力する
230 // OutputIterationLog(self_->log_file, self_->frequency, std::setw(13) << df_.norm());
231  }
232  else
233  {
234  // 勾配ベクトルがない時は-を出力する
235 // OutputIterationLog(self_->log_file, self_->frequency, " - ");
236  }
237  // イテレーション数のカウント
238  self_->iteration++;
239  return f;
240 }
241 
242 // 評価関数
244 {
245  this->n_f++;
246  // 評価関数の和
247  if ( this->f ) (*(this->f))(this->x,this->fbuf) ;
248  return this->fbuf[0];
249 }
250 
251 // 評価関数の勾配
253 {
254  this->n_df++;
255  // 評価関数の和の勾配ベクトル
256 
257 // dfbuf[0] = 0 ;
258  if ( this->df ) (*(this->df))(this->x,dfbuf) ;
259 }
260 
261 void NLoptSolver::EqualityConstraintWrapper(unsigned int m, double* g, unsigned int n, const double* x, double* dg, void* self)
262 {
263  // 変数に代入する
264  NLoptSolver* self_=reinterpret_cast<NLoptSolver*>(self);
265 
266  my_copy((double*)x,self_->x,self_->m_x) ; //self_->x = (double*)x ;
267  // 不等式制約条件
268  my_copy(g,self_->gbuf,self_->m_g) ;
269  self_->EqualityConstraintCost(self_->gbuf);
270  my_copy(self_->gbuf,g,self_->m_g) ;
271  // 勾配計算
272  if(dg != NULL)
273  {
274  my_copy(dg,self_->dgbuf,self_->m_x * self_->m_g) ;
275  self_->EqualityConstraintGradient(self_->dgbuf);
276  my_copy(self_->dgbuf,dg,self_->m_x * self_->m_g) ;
277  }
278 }
279 
280 // 等式制約条件
282 {
283  this->n_g++;
284  if ( this->g && this->m_g>0 ) (*(this->g))(this->x,gbuf) ;
285  //this->gbuf = gbuf ;
286  // 等式制約条件を縦に並べる
287 }
288 
289 // 等式制約条件の勾配
291 {
292  this->n_dg++;
293  if ( this->dg && this->m_g>0 ) (*(this->dg))(this->x,dgbuf) ;
294 }
295 
296 void NLoptSolver::InequalityConstraintWrapper(unsigned int m, double* h, unsigned int n, const double* x, double* dh, void* self)
297 {
298  // 変数に代入する
299  NLoptSolver* self_=reinterpret_cast<NLoptSolver*>(self);
300  my_copy((double*)x,self_->x,self_->m_x) ; //self_->x = (double*)x ;
301  // 不等式制約条件
302  my_copy(h,self_->hbuf,self_->m_h) ;
303  self_->InequalityConstraintCost(self_->hbuf);
304  my_copy(self_->hbuf,h,self_->m_h) ;
305  // 勾配行列計算
306  if(dh != NULL)
307  {
308  my_copy(dh,self_->dhbuf,self_->m_x * self_->m_h) ;
309  self_->InequalityConstraintGradient(self_->dhbuf);
310  my_copy(self_->dhbuf,dh,self_->m_x * self_->m_h) ;
311  }
312  // 各イテレーションの結果を出力する
313  //OutputIterationLog(self_->log_file, self_->frequency, std::setw(14) << h_.maxCoeff() << std::fixed << std::endl);
314 }
315 
316 // 不等式制約条件
318 {
319  this->n_h++;
320  if ( this->h && this->m_h>0 ) (*(this->h))(this->x,hbuf) ;
321  //this->hbuf = hbuf ;
322 }
323 
324 // 不等式制約条件の勾配
326 {
327  this->n_dh++;
328  if ( this->dh && this->m_h>0) (*(this->dh))(this->x,dhbuf) ;
329 }
330 
331 // 最適化計算
333 {
334  // 最適化計算
335  double cost;
336  nlopt_result result=nlopt_optimize(this->solver, this->x, &cost);
337  //this->output_result(result) ;
338  this->fbuf[0] = cost;
339  return result ;
340 }
double ObjectiveFunctionCost()
評価関数の和を計算する
int(* f)(double *, double *)
Definition: nlopt_solver.h:130
unsigned int n_df
評価関数の勾配の計算回数
Definition: nlopt_solver.h:147
void InequalityConstraintGradient(double *dh)
不等式制約条件の勾配
unsigned int m_g
等式制約条件の次元
Definition: nlopt_solver.h:137
unsigned int m_x
Definition: nlopt_solver.h:135
int(*)(*) df(double *, double *)
Definition: nlopt_solver.h:130
unsigned int n_g
等式制約条件の計算回数
Definition: nlopt_solver.h:149
static void InequalityConstraintWrapper(unsigned int m, double *h, unsigned int n, const double *x, double *dh, void *self)
不等式制約条件のラッパー
double * fbuf
Definition: nlopt_solver.h:37
int result
Algorithm
NLoptに実装されているアルゴリズム
Definition: my_param.h:41
void InequalityConstraintCost(double *h)
不等式制約条件
double * x
Definition: nlopt_solver.h:37
static void EqualityConstraintWrapper(unsigned int m, double *g, unsigned int n, const double *x, double *dg, void *self)
等式制約条件のラッパー
double * gbuf
Definition: nlopt_solver.h:37
double * hbuf
Definition: nlopt_solver.h:37
unsigned int n_f
評価関数の計算回数
Definition: nlopt_solver.h:145
void ObjectiveFunctionGradient(double *df)
評価関数の和の勾配を計算する
double * dfbuf
Definition: nlopt_solver.h:37
int(* h)(double *, double *)
不等式制約条件
Definition: nlopt_solver.h:134
void EqualityConstraintCost(double *g)
等式制約条件
int(* g)(double *, double *)
等式制約条件
Definition: nlopt_solver.h:132
double * dhbuf
Definition: nlopt_solver.h:37
double * dgbuf
Definition: nlopt_solver.h:37
unsigned int iteration
最適化計算のイテレーション数
Definition: nlopt_solver.h:143
static void my_copy(double *in, double *out, int size)
Definition: nlopt_solver.h:63
nlopt_opt solver
Definition: nlopt_solver.h:127
unsigned int n_dh
不等式制約条件の勾配の計算回数
Definition: nlopt_solver.h:155
void EqualityConstraintGradient(double *dg)
等式制約条件の勾配
unsigned int n_dg
等式制約条件の勾配の計算回数
Definition: nlopt_solver.h:151
#define NULL
int f(double *x, double *ret)
Definition: test.cpp:11
unsigned int n_h
不等式制約条件の計算回数
Definition: nlopt_solver.h:153
unsigned int m_h
不等式制約条件の次元
Definition: nlopt_solver.h:139
NLoptSolver(double *x, const double *x_min, const double *x_max, int(*f)(double *, double *), int(*df)(double *, double *), int(*g)(double *, double *), int(*dg)(double *, double *), int(*h)(double *, double *), int(*dh)(double *, double *), int m_x, int m_g, int m_h, double ftol, double xtol, double eqthre, int max_eval, double max_time, Optimization::NLopt::Algorithm algorithm)
Definition: nlopt_solver.cpp:8
static double ObjectiveFunctionWrapper(unsigned int n, const double *x, double *df, void *self)
評価関数のラッパー
nlopt_opt core_solver
Definition: nlopt_solver.h:128
int(*)(*) dh(double *, double *)
Definition: nlopt_solver.h:134
int(*)(*) dg(double *, double *)
Definition: nlopt_solver.h:132
int df(double *x, double *grad)
Definition: test.cpp:17


eus_nlopt
Author(s):
autogenerated on Fri May 14 2021 02:51:41