Skip to content

Commit 64e1ed7

Browse files
author
Emmanuel Benazera
committed
TPA testing / performance assessment exe, ref #88
1 parent f4a94f4 commit 64e1ed7

File tree

2 files changed

+186
-1
lines changed

2 files changed

+186
-1
lines changed

tests/Makefile.am

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
AUTOMAKE_OPTIONS = subdir-objects
2-
bin_PROGRAMS=simple_test edm
2+
bin_PROGRAMS=simple_test edm tpa_tests
33
if HAVE_GFLAGS
44
bin_PROGRAMS += test_functions
55
test_functions_SOURCES=test-functions.cc
66
endif
77
simple_test_SOURCES=simple-test.cc
8+
tpa_tests_SOURCES=tpa-tests.cc
89
edm_SOURCES=edm.cc
910
if HAVE_BBOB
1011
libbbobdir = $(libdir)

tests/tpa-tests.cc

+184
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/**
2+
* CMA-ES, Covariance Matrix Adaptation Evolution Strategy
3+
* Copyright (c) 2014 Inria
4+
* Author: Emmanuel Benazera <[email protected]>
5+
*
6+
* This file is part of libcmaes.
7+
*
8+
* libcmaes is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU Lesser General Public License as published by
10+
* the Free Software Foundation, either version 3 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* libcmaes is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU Lesser General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public License
19+
* along with libcmaes. If not, see <http://www.gnu.org/licenses/>.
20+
*/
21+
22+
#include "cmaes.h"
23+
#include <gflags/gflags.h>
24+
25+
using namespace libcmaes;
26+
27+
DEFINE_string(fname,"fsphere","name of the function to optimize");
28+
DEFINE_string(dims,"10","comma-separated list of problem dimension");
29+
//DEFINE_bool(tpa,false,"whether to use two-point adapation for step-size update");
30+
DEFINE_string(alg,"cmaes","algorithm, among cmaes, ipop, bipop, acmaes, aipop, abipop, sepcmaes, sepipop, sepbipop, sepacmaes, sepaipop, sepabipop");
31+
DEFINE_int32(runs,10,"number of runs for each configuration");
32+
//DEFINE_bool(with_gradient,false,"whether to use the function gradient when available in closed form");
33+
34+
FitFunc fsphere = [](const double *x, const int N)
35+
{
36+
double val = 0.0;
37+
for (int i=0;i<N;i++)
38+
val += x[i]*x[i];
39+
return val;
40+
};
41+
42+
GradFunc grad_fsphere = [](const double *x, const int N)
43+
{
44+
dVec grad(N);
45+
for (int i=0;i<N;i++)
46+
grad(i) = 2.0*x[i];
47+
return grad;
48+
};
49+
50+
FitFunc rosenbrock = [](const double *x, const int N)
51+
{
52+
double val = 0.0;
53+
for (int i=0;i<N-1;i++)
54+
{
55+
val += 100.0*pow((x[i+1]-x[i]*x[i]),2) + pow((x[i]-1.0),2);
56+
}
57+
return val;
58+
};
59+
60+
GradFunc grad_rosenbrock = [](const double *x, const int N)
61+
{
62+
dVec grad = dVec::Zero(N);
63+
for (int i=0;i<N-1;i++)
64+
{
65+
grad(i) = -400.0*x[i]*(x[i+1]-x[i]*x[i])-2.0*(1.0-x[i]);
66+
grad(i+1) += 200.0*(x[i+1]-x[i]*x[i]);
67+
}
68+
return grad;
69+
};
70+
71+
FitFunc elli = [](const double *x, const int N)
72+
{
73+
if (N == 1)
74+
return x[0] * x[0];
75+
double val = 0.0;
76+
for (int i=0;i<N;i++)
77+
val += exp(log(1e3)*2.0*static_cast<double>(i)/static_cast<double>((N-1))) * x[i]*x[i];
78+
return val;
79+
};
80+
81+
GradFunc grad_elli = [](const double *x, const int N)
82+
{
83+
dVec grad(N);
84+
if (N == 1)
85+
{
86+
grad(0) = 2.0*x[0];
87+
return grad;
88+
}
89+
for (int i=0;i<N;i++)
90+
grad(i) = exp(log(1e3)*2.0*static_cast<double>(i)/static_cast<double>((N-1)))*2.0*x[i];
91+
return grad;
92+
};
93+
94+
std::map<std::string,FitFunc> mfuncs;
95+
std::map<std::string,GradFunc> mgfuncs;
96+
97+
void tokenize(const std::string &str,
98+
std::vector<std::string> &tokens,
99+
const std::string &delim)
100+
{
101+
102+
// Skip delimiters at beginning.
103+
std::string::size_type lastPos = str.find_first_not_of(delim, 0);
104+
// Find first "non-delimiter".
105+
std::string::size_type pos = str.find_first_of(delim, lastPos);
106+
while (std::string::npos != pos || std::string::npos != lastPos)
107+
{
108+
// Found a token, add it to the vector.
109+
tokens.push_back(str.substr(lastPos, pos - lastPos));
110+
// Skip delimiters. Note the "not_of"
111+
lastPos = str.find_first_not_of(delim, pos);
112+
// Find next "non-delimiter"
113+
pos = str.find_first_of(delim, lastPos);
114+
}
115+
}
116+
117+
void run(const int &dim, const bool &gi, const bool &tpa, const std::string &alg,
118+
double &fevals_avg, double &succ_runs)
119+
{
120+
fevals_avg = 0.0;
121+
succ_runs = 0.0;
122+
for (int r=0;r<FLAGS_runs;r++)
123+
{
124+
std::vector<double> x0(dim,-std::numeric_limits<double>::max());
125+
CMAParameters<> cmaparams(x0,-1);
126+
cmaparams.set_tpa(tpa);
127+
cmaparams.set_gradient(gi);
128+
cmaparams.set_str_algo(alg);
129+
cmaparams.set_ftarget(1e-8);
130+
cmaparams.set_stopping_criteria(STAGNATION,false);
131+
//cmaparams.set_quiet(false);
132+
GradFunc gfunc = nullptr;
133+
if (gi)
134+
gfunc = mgfuncs[FLAGS_fname];
135+
CMASolutions cmasols = cmaes<>(mfuncs[FLAGS_fname],cmaparams,CMAStrategy<CovarianceUpdate>::_defaultPFunc,gfunc);
136+
if (cmasols.best_candidate().get_fvalue() <= 1e-8)
137+
succ_runs++;
138+
fevals_avg += cmasols.fevals();
139+
}
140+
fevals_avg /= succ_runs;
141+
}
142+
143+
int main(int argc, char *argv[])
144+
{
145+
mfuncs["fsphere"]=fsphere;
146+
mgfuncs["fsphere"]=grad_fsphere;
147+
mfuncs["rosenbrock"]=rosenbrock;
148+
mgfuncs["rosenbrock"]=grad_rosenbrock;
149+
mfuncs["elli"]=elli;
150+
mgfuncs["elli"]=grad_elli;
151+
152+
google::ParseCommandLineFlags(&argc, &argv, true);
153+
154+
// dims
155+
std::vector<std::string> vdims_str;
156+
tokenize(FLAGS_dims,vdims_str,",");
157+
std::vector<int> vdims;
158+
for (size_t i=0;i<vdims_str.size();i++)
159+
vdims.push_back(atoi(vdims_str.at(i).c_str()));
160+
161+
// dsigma
162+
/*std::vector<std::string> vds_str;
163+
tokenize(FLAGS_tpa_dsigmas,vds_str,",");
164+
std::vector<double> vds;
165+
for (size_t i=0;i<vds_str.size();i++)
166+
vds.push_back(strtod(vds_str.at(i).c_str(),NULL));*/
167+
168+
// runs
169+
std::cout << "D\tfevals_avg\t\tfevals_avg_tpa\t\tfevals_avg_gi\t\tfevals_avg_gi_tpa\n";
170+
for (size_t d=0;d<vdims.size();d++)
171+
{
172+
int dim = vdims.at(d);
173+
double fevals_avg,fevals_avg_tpa,fevals_avg_gi,fevals_avg_gi_tpa;
174+
double succ_runs,succ_runs_tpa,succ_runs_gi,succ_runs_gi_tpa;
175+
run(dim,false,false,FLAGS_alg,fevals_avg,succ_runs);
176+
run(dim,false,true,FLAGS_alg,fevals_avg_tpa,succ_runs_tpa);
177+
run(dim,true,false,FLAGS_alg,fevals_avg_gi,succ_runs_gi);
178+
run(dim,true,true,FLAGS_alg,fevals_avg_gi_tpa,succ_runs_gi_tpa);
179+
std::cout << dim << "\t" << fevals_avg << " (" << succ_runs << ")\t\t"
180+
<< fevals_avg_tpa << " (" << succ_runs_tpa << ")\t\t"
181+
<< fevals_avg_gi << " (" << succ_runs_gi << ")\t\t"
182+
<< fevals_avg_gi_tpa << "(" << succ_runs_gi_tpa << ")\n";
183+
}
184+
}

0 commit comments

Comments
 (0)