mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-05-27 14:25:16 +02:00
Without inheriting from numpy.ndarray. ndarray functionality missing
This commit is contained in:
parent
3b40a47cbc
commit
36e60362da
1 changed files with 90 additions and 25 deletions
|
|
@ -6,8 +6,9 @@ Created on 4 Sep 2013
|
||||||
import re
|
import re
|
||||||
import itertools
|
import itertools
|
||||||
import numpy
|
import numpy
|
||||||
from GPy.core.transformations import Logexp
|
from GPy.core.transformations import Logexp, NegativeLogexp
|
||||||
from GPy.core.index_operations import ParameterIndexOperations
|
from GPy.core.index_operations import ParameterIndexOperations
|
||||||
|
from types import FunctionType
|
||||||
_index_re = re.compile('(?:_(\d+))+') # pattern match for indices
|
_index_re = re.compile('(?:_(\d+))+') # pattern match for indices
|
||||||
|
|
||||||
def translate_param_names_to_parameters(param_names):
|
def translate_param_names_to_parameters(param_names):
|
||||||
|
|
@ -34,13 +35,13 @@ class Parameters(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return numpy.hstack([x._get_params() for x in self._params])
|
return numpy.fromiter(itertools.chain(*itertools.imap(lambda x: x._get_params(), self._params)), dtype=numpy.float64, count=sum(self.sizes))
|
||||||
|
|
||||||
def _set_params(self, params):
|
def _set_params(self, params):
|
||||||
[p._set_params(params[s]) for s in self._param_slices]
|
[p._set_params(params[s]) for s in self._param_slices]
|
||||||
|
|
||||||
def _get_params_transformed(self):
|
def _get_params_transformed(self):
|
||||||
return numpy.hstack([x._get_params_transformed() for x in self._params])
|
return numpy.fromiter(itertools.chain(*itertools.imap(lambda x: x._get_params_transformed(), self._params)), dtype=numpy.float64, count=sum(self.sizes))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def names(self):
|
def names(self):
|
||||||
|
|
@ -81,13 +82,28 @@ class Parameter(object):
|
||||||
|
|
||||||
def __init__(self, name, value, constraint=None, *args, **kwargs):
|
def __init__(self, name, value, constraint=None, *args, **kwargs):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.constraints = ParameterIndexOperations(self)
|
|
||||||
self._value = value
|
self._value = value
|
||||||
self._current_slice = slice(None)
|
self._current_slice = slice(None)
|
||||||
|
# def attribute_func(value, name):
|
||||||
for name in dir(value):
|
# value_func = self.value.__getattribute__(name)
|
||||||
if not hasattr(self, name):
|
# if isinstance(value_func, FunctionType):
|
||||||
self.__setattr__(name, value.__getattribute__(name))
|
# def f(*args, **kwargs):
|
||||||
|
# with self.slicing():
|
||||||
|
# return self.value.__getattribute__(name)(*args, **kwargs)
|
||||||
|
# else:
|
||||||
|
# with self.slicing():
|
||||||
|
# return self.value.__getattribute__(name)(*args, **kwargs)
|
||||||
|
# try:
|
||||||
|
# f.__doc__ = value_func.__doc__
|
||||||
|
# except AttributeError:
|
||||||
|
# # no docstring present
|
||||||
|
# pass
|
||||||
|
# return f
|
||||||
|
#
|
||||||
|
# for name in dir(value):
|
||||||
|
# if not hasattr(self, name):
|
||||||
|
# self.__setattr__(name, attribute_func(value, name))#value.__getattribute__(name))
|
||||||
|
self.constraints = ParameterIndexOperations(self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
|
|
@ -102,6 +118,9 @@ class Parameter(object):
|
||||||
def shape(self):
|
def shape(self):
|
||||||
return self.value.shape
|
return self.value.shape
|
||||||
@property
|
@property
|
||||||
|
def realshape(self):
|
||||||
|
return self._value.shape
|
||||||
|
@property
|
||||||
def _desc(self):
|
def _desc(self):
|
||||||
if self.size <= 1:
|
if self.size <= 1:
|
||||||
return "%f"%self.value
|
return "%f"%self.value
|
||||||
|
|
@ -109,56 +128,102 @@ class Parameter(object):
|
||||||
return self.shape
|
return self.shape
|
||||||
@property
|
@property
|
||||||
def _constr(self):
|
def _constr(self):
|
||||||
return ' '.join([str(c) if c else '' for c in self.constraints.properties.keys()])
|
return ' '.join([str(c) if c else '' for c in self.constraints.keys()])
|
||||||
|
|
||||||
def _set_params(self, param):
|
def _set_params(self, param):
|
||||||
self.value.flat = param
|
with self.slicing():
|
||||||
|
self.value.flat = param
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return self.value.flat
|
with self.slicing():
|
||||||
|
return self.value.flat
|
||||||
|
|
||||||
def _get_params_transformed(self):
|
def _get_params_transformed(self):
|
||||||
params = self.value.copy()
|
with self.slicing():
|
||||||
|
params = self.value.copy()
|
||||||
|
|
||||||
|
def constrain(self, constraint):
|
||||||
|
with self.slicing():
|
||||||
|
self.constraints.add(constraint, self._current_slice)
|
||||||
|
|
||||||
def constrain_positive(self):
|
def constrain_positive(self):
|
||||||
self.constraints.add(Logexp(), self._current_slice)
|
self.constrain(Logexp())
|
||||||
self._current_slice = slice(None)
|
|
||||||
|
def constrain_negative(self):
|
||||||
|
self.constrain(NegativeLogexp())
|
||||||
|
|
||||||
|
def unconstrain(self, constraints=None):
|
||||||
|
with self.slicing():
|
||||||
|
if constraints is None:
|
||||||
|
constraints = self.constraints.keys()
|
||||||
|
elif not isinstance(constraints, (tuple, list, numpy.ndarray)):
|
||||||
|
constraints = [constraints]
|
||||||
|
for constr in constraints:
|
||||||
|
self.constraints.remove(constr, self._current_slice)
|
||||||
|
|
||||||
|
def unconstrain_positive(self):
|
||||||
|
self.unconstrain(Logexp())
|
||||||
|
|
||||||
|
|
||||||
def __getitem__(self, s):
|
def __getitem__(self, s):
|
||||||
try:
|
try:
|
||||||
self.value[s]
|
self.value[s]
|
||||||
self._current_slice = s#[s if s else slice(s2) for s,s2 in itertools.izip_longest([s], self.shape, fillvalue=None)]
|
self._current_slice = s#[s if s else slice(s2) for s,s2 in itertools.izip_longest([s], self.shape, fillvalue=None)]
|
||||||
return self
|
return self
|
||||||
except IndexError as i:
|
except IndexError as i:
|
||||||
|
self._current_slice = slice(None)
|
||||||
raise i
|
raise i
|
||||||
|
|
||||||
def __setitem__(self, s, value):
|
def __setitem__(self, s, value):
|
||||||
try:
|
try:
|
||||||
self.value[s] = value
|
self.value[s] = value
|
||||||
|
self._current_slice = slice(None)
|
||||||
return self
|
return self
|
||||||
except IndexError as i:
|
except IndexError as i:
|
||||||
raise i
|
raise i
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self, *args, **kwargs):
|
# def __repr__(self, *args, **kwargs):
|
||||||
view = repr(self.value)
|
# view = repr(self.value)
|
||||||
self._current_slice = slice(None)
|
# self._current_slice = slice(None)
|
||||||
return view
|
# return view
|
||||||
|
|
||||||
def __str__(self, format_spec=None):
|
def __str__(self, format_spec=None):
|
||||||
if format_spec is None:
|
with self.slicing():
|
||||||
return str(self.value)
|
if format_spec is None:
|
||||||
return format_spec.format(self=self)
|
constr_matrix = numpy.empty(self.realshape, dtype=object)
|
||||||
|
constr_matrix[:] = ''
|
||||||
|
for constr, indices in self.constraints.iteritems():
|
||||||
|
constr_matrix[indices] = numpy.vectorize(lambda x: " ".join([x,str(constr)]) if x else str(constr))(constr_matrix[indices])
|
||||||
|
constr_matrix = constr_matrix.astype(numpy.string_)[self._current_slice]
|
||||||
|
p = numpy.get_printoptions()['precision']
|
||||||
|
constr = constr_matrix.flat
|
||||||
|
ind = numpy.array(list(itertools.product(*itertools.imap(range, self.realshape))))[self.constraints.create_raveled_indices(self._current_slice),...]
|
||||||
|
c_name, x_name, i_name = "Constraint", "Value", "Index"
|
||||||
|
lc = max(reduce(lambda a,b: max(a, len(b)), constr_matrix.flat, 0), len(c_name))
|
||||||
|
lx = max(reduce(lambda a,b: max(a, len("{x:=.{0}G}".format(p,x=b))), self.value.flat, 0), len(x_name))
|
||||||
|
li = max(reduce(lambda a,b: max(a, len(str(b))), ind, 0), len(i_name))
|
||||||
|
header = " {i:^{3}s} | {x:^{1}s} | {c:^{0}s}".format(lc,lx,p,li, x=x_name, c=c_name, i=i_name)
|
||||||
|
return "\n".join([header]+[" {i:^{3}s} | {x: >{1}.{2}G} | {c:^{0}s}".format(lc,lx,p,li, x=x, c=constr.next(), i=i) for i,x in itertools.izip(ind,self.value.flat)])
|
||||||
|
return format_spec.format(self=self)
|
||||||
|
|
||||||
|
import contextlib
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def slicing(self, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
self._current_slice = slice(None)
|
||||||
|
del contextlib
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
X = numpy.random.randn(3,2)
|
X = numpy.random.randn(2,4)
|
||||||
p = Parameter("X", X)
|
p = Parameter("X", X)
|
||||||
p2 = Parameter("Y", numpy.random.randn(3,1))
|
p2 = Parameter("Y", numpy.random.randn(3,1))
|
||||||
p3 = Parameter("rbf_variance", numpy.random.rand(1))
|
p3 = Parameter("rbf_variance", numpy.random.rand(1))
|
||||||
p4 = Parameter("rbf_lengthscale", numpy.random.rand(2))
|
p4 = Parameter("rbf_lengthscale", numpy.random.rand(2))
|
||||||
params = Parameters([p,p2,p3,p4])
|
params = Parameters([p,p2,p3,p4])
|
||||||
# params.X[5].constrain_positive()
|
params.X[1].constrain_positive()
|
||||||
|
print params.X
|
||||||
#params.X[1,1].constrain_positive()
|
#params.X[1,1].constrain_positive()
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue