[077a87]: / cmaes / solver.py

Download this file

155 lines (132 with data), 4.6 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 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
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# Copyright (c) 2015, Disney Research
# All rights reserved.
#
# Author(s): Sehoon Ha <sehoon.ha@disneyresearch.com>
# Disney Research Robotics Group
"""
Example Usage:
# prob has f() and g() as member functions
solver = Solver(prob)
res = solver.solve()
x = res['x']
f = res['f']
"""
import cmaes.utils
import numpy as np
class Solver(object):
def __init__(self, prob):
self.prob = prob
self.eval_counter = 0
self.numerical_diff_step = 1e-4
self.iter_values = list()
self.verbose = True
self.check_gradient = False
def get_check_gradient(self, ):
return self.check_gradient
def set_check_gradient(self, check_gradient=True):
self.check_gradient = check_gradient
def eval_f(self, x):
ret = self.prob.f(x)
self.eval_counter += 1
self.last_x = x
self.last_f = ret
self.iter_values.append(ret)
if hasattr(self.prob, 'on_eval_f'):
self.prob.on_eval_f(self)
return ret
def eval_g(self, x):
if hasattr(self.prob, 'g'):
ret = self.prob.g(x)
if self.get_check_gradient():
h = self.numerical_diff_step
ret2 = utils.grad(self.prob.f, x, h)
isgood = np.allclose(ret, ret2, atol=1e-05)
if not isgood:
print(ret)
print(ret2)
print("diff = %.12f" % np.linalg.norm(ret - ret2))
print('check_gradient... %s' % isgood)
else:
h = self.numerical_diff_step
ret = utils.grad(self.prob.f, x, h)
return ret
def eval_c_eq_jac(self, x, i):
if hasattr(self.prob, 'c_eq_jac'):
ret = self.prob.c_eq_jac(x, i)
else:
h = self.numerical_diff_step
def c_eq_f(x):
return self.prob.c_eq(x, i)
ret = utils.grad(c_eq_f, x, h)
return ret
def eval_c_ineq_jac(self, x, i):
if hasattr(self.prob, 'c_ineq_jac'):
ret1 = self.prob.c_ineq_jac(x, i)
return ret1
else:
h = self.numerical_diff_step
def c_ineq_f(x):
return self.prob.c_ineq(x, i)
ret2 = utils.grad(c_ineq_f, x, h)
return ret2
def collect_constraints(self):
constraints = list()
if hasattr(self.prob, 'num_eq_constraints'):
num = self.prob.num_eq_constraints()
if self.verbose:
print(' [Solver]: num_eq_constraints = %d' % num)
for i in range(num):
c = dict()
c['type'] = 'eq'
assert(hasattr(self.prob, 'c_eq'))
c['fun'] = self.prob.c_eq
c['jac'] = self.eval_c_eq_jac
c['args'] = [i]
constraints.append(c)
if hasattr(self.prob, 'num_ineq_constraints'):
num = self.prob.num_ineq_constraints()
if self.verbose:
print(' [Solver]: num_ineq_constraints = %d' % num)
for i in range(num):
c = dict()
c['type'] = 'ineq'
assert(hasattr(self.prob, 'c_ineq'))
c['fun'] = self.prob.c_ineq
c['jac'] = self.eval_c_ineq_jac
c['args'] = [i]
constraints.append(c)
if self.verbose:
print(' [Solver]: num_constraints = %d' % len(constraints))
return constraints
def bounds(self):
if hasattr(self.prob, 'bounds'):
return self.prob.bounds()
else:
return None
def solve(self, x0=None):
pass
def set_verbose(self, verbose):
self.verbose = verbose
def plot_convergence(self, filename=None):
yy = self.iter_values
xx = range(len(yy))
import matplotlib.pyplot as plt
# Plot
plt.ioff()
fig = plt.figure()
fig.set_size_inches(18.5, 10.5)
font = {'size': 28}
plt.title('Value over # evaluations')
plt.xlabel('X', fontdict=font)
plt.ylabel('Y', fontdict=font)
plt.plot(xx, yy)
plt.axes().set_yscale('log')
if filename is None:
filename = 'plots/iter.png'
plt.savefig(filename, bbox_inches='tight')
plt.close(fig)
print('plotting convergence OK.. ' + filename)
def save_result(self, res, filename):
with open(filename, 'w+') as fin:
fin.write(str(res))
print('writing result OK.. ' + filename)