diff --git a/algopy/tracer/tracer.py b/algopy/tracer/tracer.py index b84651b..8128de5 100644 --- a/algopy/tracer/tracer.py +++ b/algopy/tracer/tracer.py @@ -246,7 +246,10 @@ def f(x1, x2): else: x_list = [x] - utpm_x_list = [algopy.UTPM(numpy.asarray(xi).reshape((1,1) + numpy.shape(xi))) for xi in x_list] + utpm_x_list = [] + for xi in x_list: + element = numpy.asarray(xi).reshape((1,1) + numpy.shape(xi)) + utpm_x_list.append(algopy.UTPM(element)) self.pushforward(utpm_x_list) @@ -1017,6 +1020,9 @@ def __rdiv__(self, lhs): lhs = self.__class__.totype(lhs) return lhs/self + __truediv__ = __div__ + __rtruediv__ = __rdiv__ + # ######################################################### # numpy functions diff --git a/algopy/utpm/tests/test_utpm.py b/algopy/utpm/tests/test_utpm.py index 810a8f7..f263825 100644 --- a/algopy/utpm/tests/test_utpm.py +++ b/algopy/utpm/tests/test_utpm.py @@ -653,6 +653,19 @@ def test_gammaln(self): b = UTPM.gammaln(x + 1) - UTPM.log(x) assert_allclose(a.data, b.data) + def test_gammaln_pullback(self): + D,P = 2,1 + + # forward + x = UTPM(numpy.random.random((D,P))) + y = UTPM.gammaln(x) + + # reverse + ybar = UTPM(numpy.random.random((D,P))) + xbar = UTPM.pb_gammaln(ybar, x, y) + + assert_array_almost_equal(ybar.data[0]*y.data[1], xbar.data[0]*x.data[1]) + def test_hyperu(self): D,P,N,M = 5,1,3,3 diff --git a/algopy/utpm/utpm.py b/algopy/utpm/utpm.py index 1a6a967..b6de34f 100644 --- a/algopy/utpm/utpm.py +++ b/algopy/utpm/utpm.py @@ -831,7 +831,7 @@ def pb_gammaln(cls, ybar, x, y, out=None): xbar, = out cls._pb_gammaln(ybar.data, x.data, y.data, out = xbar.data) - return out + return xbar @classmethod def erf(cls, x): diff --git a/documentation/sphinx/examples/minimization/minhelper.py b/documentation/sphinx/examples/minimization/minhelper.py index ee409ba..aa03389 100644 --- a/documentation/sphinx/examples/minimization/minhelper.py +++ b/documentation/sphinx/examples/minimization/minhelper.py @@ -2,12 +2,24 @@ This is a helper module for the minimization examples. """ +#FIXME: the pyipopt stuff has been commented out for now; +#FIXME: update this code to use a better python ipopt interface when available +# https://github.com/xuy/pyipopt +# http://gitview.danfis.cz/pipopt +# https://bitbucket.org/amitibo +# https://github.com/casadi/casadi + import functools import numpy import scipy.optimize import algopy import numdifftools +#import pyipopt + +# Suppress log spam from pyipopt. +# But ipopt itself will stil spam... +#pyipopt.set_loglevel(0) def eval_grad(f, theta): @@ -18,6 +30,8 @@ def eval_hess(f, theta): theta = algopy.UTPM.init_hessian(theta) return algopy.UTPM.extract_hessian(len(theta), f(theta)) + + def show_local_curvature(f, g, h, x0): print 'point:' print x0 @@ -169,6 +183,31 @@ def do_searches(f, g, h, x0): print results print + #print 'strategy:', 'ipopt' + #print 'options:', 'default' + #print 'gradient:', 'autodiff' + #print 'hessian:', 'autodiff' + #results = pyipopt.fmin_unconstrained( + #f, + #x0, + #fprime=g, + #fhess=h, + #) + #print results + #print + + #print 'strategy:', 'ipopt' + #print 'options:', 'default' + #print 'gradient:', 'autodiff' + #print 'hessian:', 'finite differences' + #results = pyipopt.fmin_unconstrained( + #f, + #x0, + #fprime=g, + #) + #print results + #print + def show_minimization_results(f, target_in, easy_init_in, hard_init_in): """