Modifications to transformations ... not sure which tests to run to make sure I haven't messed things up. New code avoids exponentiating values greater than -log(eps) or less than log(eps). Also changed negative code to call the positive code (I think they should inherit the positive code ... but maybe not.

This commit is contained in:
Neil Lawrence 2013-08-16 18:28:16 +01:00
parent 9e0795afc4
commit 7aac769d37
5 changed files with 58 additions and 28 deletions

View file

@ -4,6 +4,8 @@
import numpy as np
from GPy.core.domains import POSITIVE, NEGATIVE, BOUNDED
import sys
lim_val = -np.log(sys.float_info.epsilon)
class transformation(object):
domain = None
@ -17,7 +19,7 @@ class transformation(object):
""" df_dx evaluated at self.f(x)=f"""
raise NotImplementedError
def initialize(self, f):
""" produce a sensible initial values for f(x)"""
""" produce a sensible initial value for f(x)"""
raise NotImplementedError
def __str__(self):
raise NotImplementedError
@ -25,13 +27,14 @@ class transformation(object):
class logexp(transformation):
domain = POSITIVE
def f(self, x):
return np.log(1. + np.exp(x))
return np.where(x>lim_val, x, np.log(1. + np.exp(x)))
def finv(self, f):
return np.log(np.exp(f) - 1.)
return np.where(f>lim_val, f, np.log(np.exp(f) - 1.))
def gradfactor(self, f):
ef = np.exp(f)
return (ef - 1.) / ef
return np.where(f>lim_val, 1., 1 - np.exp(-f))
def initialize(self, f):
if np.any(f < 0.):
print "Warning: changing parameters to satisfy constraints"
return np.abs(f)
def __str__(self):
return '(+ve)'
@ -39,18 +42,19 @@ class logexp(transformation):
class negative_logexp(transformation):
domain = NEGATIVE
def f(self, x):
return -np.log(1. + np.exp(x))
return -logexp.f(x) #np.log(1. + np.exp(x))
def finv(self, f):
return np.log(np.exp(-f) - 1.)
return logexp.finv(-f) #np.log(np.exp(-f) - 1.)
def gradfactor(self, f):
ef = np.exp(-f)
return -(ef - 1.) / ef
return -logexp.gradfactor(-f)
#ef = np.exp(-f)
#return -(ef - 1.) / ef
def initialize(self, f):
return -np.abs(f)
return -logexp.initialize(f) #np.abs(f)
def __str__(self):
return '(-ve)'
class logexp_clipped(transformation):
class logexp_clipped(logexp):
max_bound = 1e100
min_bound = 1e-10
log_max_bound = np.log(max_bound)
@ -78,9 +82,10 @@ class logexp_clipped(transformation):
return '(+ve_c)'
class exponent(transformation):
# TODO: can't allow this to go to zero, need to set a lower bound. Similar with negative exponent below. See old MATLAB code.
domain = POSITIVE
def f(self, x):
return np.exp(x)
return np.where(x<lim_val, np.where(x>-lim_val, np.exp(x), np.exp(-lim_val)), np.exp(lim_val))
def finv(self, x):
return np.log(x)
def gradfactor(self, f):
@ -92,18 +97,16 @@ class exponent(transformation):
def __str__(self):
return '(+ve)'
class negative_exponent(transformation):
class negative_exponent(exponent):
domain = NEGATIVE
def f(self, x):
return -np.exp(x)
def finv(self, x):
return np.log(-x)
return -exponent.f(x)
def finv(self, f):
return exponent.finv(-f)
def gradfactor(self, f):
return f
def initialize(self, f):
if np.any(f > 0.):
print "Warning: changing parameters to satisfy constraints"
return -np.abs(f)
return -exponent.initialize(f) #np.abs(f)
def __str__(self):
return '(-ve)'