Commit 70d0376b authored by Reimar Heinrich Leike's avatar Reimar Heinrich Leike

added a demo where Yango is compared to other minimizers

parent ff60953b
Pipeline #28098 passed with stage
in 14 minutes and 32 seconds
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright(C) 2013-2018 Max-Planck-Society
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes.
import numpy as np
import nifty4 as ift
IC = ift.GradientNormController(#name = 'min',
tol_abs_gradnorm=1e-6, iteration_limit=1000)
calls = 0
def test_rosenbrock_convex(minimizer):
np.random.seed(42)
space = ift.UnstructuredDomain((2,))
starting_point = ift.Field.from_random('normal', domain=space)*10
class RBEnergy(ift.Energy):
def __init__(self, position, a = 1., b= 100.):
super(RBEnergy, self).__init__(position)
self.a=a
self.b=b
global calls
calls += 1
@property
def value(self):
x = self.position.val[0]
y = self.position.val[1]
return (self.a-x)*(self.a-x)+self.b*(y-x*x)*(y-x*x)
@property
def gradient(self):
x = self.position.val[0]
y = self.position.val[1]
res = ift.Field.zeros(space)
res.val[0] = -2*(self.a-x)-4*self.b*x*(y-x*x)
res.val[1] = 2*self.b*(y-x*x)
return res
@property
def curvature(self):
class RBCurv(ift.EndomorphicOperator):
def __init__(self, loc, a, b):
self._x = loc.val[0]
self._y = loc.val[1]
self.a = a
self.b = b
@property
def domain(self):
return space
@property
def capability(self):
return self.TIMES
def apply(self, x, mode):
x = x.val
res = ift.Field.zeros(space)
res.val[0] = (2+self.b*8*self._x**2)*x[0]
res.val[0] -= self.b*4*self._x*x[1]
res.val[1] = -self.b*4*self._x*x[0]
res.val[1] += 2*self.b*x[1]
global calls
calls += 1
return res
t1 = ift.GradientNormController(tol_abs_gradnorm=1e-6,
iteration_limit=1000)
t2 = ift.ConjugateGradient(controller=t1)
return ift.InversionEnabler(RBCurv(self._position, self.a, self.b),
inverter=t2)
energy = RBEnergy(position=starting_point)
minimizer = minimizer(controller=IC)
energy, convergence = minimizer(energy)
return energy
def test_Ndim_rosenbrocklike_convex(minimizer, Ndim=3):
np.random.seed(42)
space = ift.UnstructuredDomain((Ndim,))
starting_point = ift.Field.from_random('normal', domain=space)*10
class RBLikeEnergy(ift.Energy):
def __init__(self, position, a = 1., b= 100.):
super(RBLikeEnergy, self).__init__(position)
self.a=a
self.b=b
global calls
calls += 1
@property
def value(self):
x = self.position.val
t1 = self.a-x[0]
t2 = x[1:]-x[:-1]**3
return 0.5*t1**2+0.5*self.b*np.dot(t2,t2)
@property
def gradient(self):
res = ift.Field.zeros(space)
x = self.position.val
t1 = self.a-x[0]
t2 = x[1:]-x[:-1]**3
res.val[0] = -t1
res.val[1:] += self.b*t2
res.val[:-1] += -3*self.b*x[:-1]**2*t2
return res
@property
def curvature(self):
class RBCurv(ift.EndomorphicOperator):
def __init__(self, loc, a, b):
self._x = loc.val
self.a = a
self.b = b
@property
def domain(self):
return space
@property
def capability(self):
return self.TIMES
def apply(self, z, mode):
y = z.val
res = ift.Field.zeros_like(z)
x = self._x
res.val[0] = y[0]
dt2 = y[1:] - 3*x[:-1]**2*y[:-1]
res.val[1:] += self.b*dt2
res.val[:-1] += -self.b*3*x[:-1]**2*dt2
global calls
calls += 1
return res
t1 = ift.GradientNormController(tol_abs_gradnorm=1e-6,
iteration_limit=1000)
t2 = ift.ConjugateGradient(controller=t1)
return ift.InversionEnabler(RBCurv(self._position, self.a, self.b),
inverter=t2)
energy = RBLikeEnergy(position=starting_point)
#ift.extra.check_value_gradient_consistency(energy, tol=1.)
#return
minimizer = minimizer(controller=IC)
energy, convergence = minimizer(energy)
return energy
def verbose_test(func, minimizer):
print("Testing", minimizer)
global calls
calls = 0
E = func(minimizer)
print("Used",calls,"calls.")
print("Final energy:",E.value)
if __name__ == "__main__":
verbose_test(test_rosenbrock_convex, ift.Yango)
verbose_test(test_rosenbrock_convex, ift.RelaxedNewton)
verbose_test(test_rosenbrock_convex, ift.NonlinearCG)
verbose_test(test_rosenbrock_convex, ift.L_BFGS)
verbose_test(test_Ndim_rosenbrocklike_convex, ift.Yango)
verbose_test(test_Ndim_rosenbrocklike_convex, ift.RelaxedNewton)
verbose_test(test_Ndim_rosenbrocklike_convex, ift.NonlinearCG)
verbose_test(test_Ndim_rosenbrocklike_convex, ift.L_BFGS)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment