Diff of /cmaes/solver.py [000000] .. [077a87]

Switch to side-by-side view

--- a
+++ b/cmaes/solver.py
@@ -0,0 +1,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)