mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-06-11 15:15:15 +02:00
parameter indexing now linear in number of printed values
This commit is contained in:
parent
be5081bd82
commit
94d344db0b
2 changed files with 475 additions and 191 deletions
|
|
@ -7,6 +7,7 @@ import itertools
|
|||
import numpy
|
||||
from transformations import Logexp, NegativeLogexp
|
||||
from GPy.core.transformations import Logistic
|
||||
import collections
|
||||
|
||||
###### printing
|
||||
__constraints_name__ = "Constraint"
|
||||
|
|
@ -19,6 +20,10 @@ class Param(numpy.ndarray):
|
|||
"""
|
||||
Parameter object for GPy models.
|
||||
|
||||
:param name: name of the parameter to be printed
|
||||
:param input_array: array which this parameter handles
|
||||
:param gradient: callable with one argument, which is the model of this parameter
|
||||
|
||||
You can add/remove constraints by calling the constrain on the parameter itself, e.g:
|
||||
|
||||
- self[:,1].constrain_positive()
|
||||
|
|
@ -32,26 +37,60 @@ class Param(numpy.ndarray):
|
|||
|
||||
See :py:class:`GPy.core.parameterized.Parameterized` for more details.
|
||||
"""
|
||||
fixed = False # if this parameter is fixed
|
||||
__array_priority__ = -1. # Allways give back Param
|
||||
def __new__(cls, name, input_array):
|
||||
__array_priority__ = -numpy.inf # Never give back Param
|
||||
def __new__(cls, name, input_array, gradient):
|
||||
obj = numpy.atleast_1d(numpy.array(input_array)).view(cls)
|
||||
obj.name = name
|
||||
obj._parent = None
|
||||
obj._parent_index = None
|
||||
obj._current_slice = slice(None)
|
||||
obj._realshape = obj.shape
|
||||
obj._realsize = obj.size
|
||||
obj._name_ = name
|
||||
obj._parent_ = None
|
||||
obj._parent_index_ = None
|
||||
obj._gradient_ = gradient
|
||||
obj._current_slice_ = [slice(obj.shape[0])]
|
||||
obj._realshape_ = obj.shape
|
||||
obj._realsize_ = obj.size
|
||||
obj._realndim_ = obj.ndim
|
||||
obj._flat_indices_ = None
|
||||
return obj
|
||||
def __array_finalize__(self, obj):
|
||||
# see InfoArray.__array_finalize__ for comments
|
||||
if obj is None: return
|
||||
self.name = getattr(obj, 'name', None)
|
||||
self._current_slice = getattr(obj, '_current_slice', None)
|
||||
self._parent = getattr(obj, '_parent', None)
|
||||
self._parent_index = getattr(obj, '_parent_index', None)
|
||||
self._realshape = getattr(obj, '_realshape', None)
|
||||
self._realsize = getattr(obj, '_realsize', None)
|
||||
self._name_ = getattr(obj, '_name_', None)
|
||||
self._current_slice_ = getattr(obj, '_current_slice_', None)
|
||||
self._parent_ = getattr(obj, '_parent_', None)
|
||||
self._parent_index_ = getattr(obj, '_parent_index_', None)
|
||||
self._flat_indices_ = getattr(obj, '_flat_indices_', None)
|
||||
self._gradient_ = getattr(obj, '_gradient_', None)
|
||||
self._realshape_ = getattr(obj, '_realshape_', None)
|
||||
self._realsize_ = getattr(obj, '_realsize_', None)
|
||||
self._realndim_ = getattr(obj, '_realndim_', None)
|
||||
def __array_wrap__(self, out_arr, context=None):
|
||||
return out_arr.view(numpy.ndarray)
|
||||
#===========================================================================
|
||||
# Pickling operations
|
||||
#===========================================================================
|
||||
def __reduce__(self):
|
||||
func, args, state = super(Param, self).__reduce__()
|
||||
return func, args, (state,
|
||||
(self._name_,
|
||||
self._parent_,
|
||||
self._parent_index_,
|
||||
self._gradient_,
|
||||
self._current_slice_,
|
||||
self._realshape_,
|
||||
self._realsize_,
|
||||
self._realndim_,
|
||||
)
|
||||
)
|
||||
def __setstate__(self, state):
|
||||
super(Param, self).__setstate__(state[0])
|
||||
state = list(state[1])
|
||||
self._realndim_ = state.pop()
|
||||
self._realsize_ = state.pop()
|
||||
self._realshape_ = state.pop()
|
||||
self._current_slice_ = state.pop()
|
||||
self._parent_index_ = state.pop()
|
||||
self._gradient_ = state.pop()
|
||||
self._parent_ = state.pop()
|
||||
self._name_ = state.pop()
|
||||
#===========================================================================
|
||||
# get/set parameters
|
||||
#===========================================================================
|
||||
|
|
@ -59,6 +98,21 @@ class Param(numpy.ndarray):
|
|||
self.flat = param
|
||||
def _get_params(self):
|
||||
return self.flat
|
||||
@property
|
||||
def name(self):
|
||||
"""
|
||||
Name of this parameter.
|
||||
This can be a callable without parameters. The callable will be called
|
||||
every time the name property is accessed.
|
||||
"""
|
||||
if callable(self._name_):
|
||||
return self._name_()
|
||||
return self._name_
|
||||
@name.setter
|
||||
def name(self, new_name):
|
||||
from_name = self.name
|
||||
self._name_ = new_name
|
||||
self._parent_._name_changed(self, from_name)
|
||||
#===========================================================================
|
||||
# Fixing Parameters:
|
||||
#===========================================================================
|
||||
|
|
@ -68,12 +122,14 @@ class Param(numpy.ndarray):
|
|||
|
||||
:param warning: print a warning for overwriting constraints.
|
||||
"""
|
||||
self._parent._fix(self,warning)
|
||||
self._parent_._fix(self,warning)
|
||||
fix = constrain_fixed
|
||||
def unconstrain_fixed(self):
|
||||
"""
|
||||
This parameter will no longer be fixed.
|
||||
"""
|
||||
self._parent._unfix(self)
|
||||
self._parent_._unfix(self)
|
||||
unfix = unconstrain_fixed
|
||||
#===========================================================================
|
||||
# Constrain operations -> done
|
||||
#===========================================================================
|
||||
|
|
@ -86,8 +142,8 @@ class Param(numpy.ndarray):
|
|||
Constrain the parameter to the given
|
||||
:py:class:`GPy.core.transformations.Transformation`.
|
||||
"""
|
||||
self._parent._add_constrain(self, transform, warning)
|
||||
self[...] = transform.initialize(self)
|
||||
self._parent_._add_constrain(self, transform, warning)
|
||||
def constrain_positive(self, warning=True):
|
||||
"""
|
||||
:param warning: print a warning if re-constraining parameters.
|
||||
|
|
@ -117,7 +173,7 @@ class Param(numpy.ndarray):
|
|||
remove all :py:class:`GPy.core.transformations.Transformation`
|
||||
transformats of this parameter object.
|
||||
"""
|
||||
self._parent._remove_constrain(self, *transforms)
|
||||
self._parent_._remove_constrain(self, *transforms)
|
||||
def unconstrain_positive(self):
|
||||
"""
|
||||
Remove positive constraint of this parameter.
|
||||
|
|
@ -150,37 +206,99 @@ class Param(numpy.ndarray):
|
|||
assert isinstance(param, Param), "Argument {1} not of type {0}".format(Param,param.__class__)
|
||||
try:
|
||||
self[...] = param
|
||||
self._parent._add_tie(self, param)
|
||||
self._parent_._add_tie(self, param)
|
||||
if self.base is None: # this happens when indexing created a copy of the array
|
||||
self._parent_._handle_ties()
|
||||
except ValueError:
|
||||
raise ValueError("Trying to tie {} with shape {} to {} with shape {}".format(self.name, self.shape, param.name, param.shape))
|
||||
def untie(self, *params):
|
||||
"""
|
||||
:param params: parameters to untie from
|
||||
|
||||
remove ties to the paramters given.
|
||||
remove ties to parameters given.
|
||||
"""
|
||||
if len(params) == 0:
|
||||
params = self._parent._ties.properties()
|
||||
for p in self._parent._ties.properties():
|
||||
if any((p == x).all() for x in params):
|
||||
self._parent._remove_tie(self, params)
|
||||
params = self._parent_._ties_.properties()
|
||||
self._parent_._remove_tie(self, params)
|
||||
#===========================================================================
|
||||
# Prior Operations
|
||||
#===========================================================================
|
||||
def set_prior(self, prior):
|
||||
"""
|
||||
:param prior: prior to be set for this parameter
|
||||
|
||||
Set prior for this parameter.
|
||||
"""
|
||||
if not hasattr(self._parent_, '_set_prior'):
|
||||
raise AttributeError("Parent of type {} does not support priors".format(self._parent_.__class__))
|
||||
self._parent_._set_prior(self, prior)
|
||||
def unset_prior(self, *priors):
|
||||
"""
|
||||
:param priors: priors to remove from this parameter
|
||||
|
||||
Remove all priors from this parameter
|
||||
"""
|
||||
self._parent_._remove_prior(self, *priors)
|
||||
#===========================================================================
|
||||
# Array operations -> done
|
||||
#===========================================================================
|
||||
def __getitem__(self, s, *args, **kwargs):
|
||||
if not isinstance(s, tuple):
|
||||
s = (s,)
|
||||
if not( Ellipsis in s):
|
||||
s = (s + (Ellipsis,))
|
||||
if not reduce(lambda a,b: a or numpy.any(b is Ellipsis), s, False):
|
||||
s += (Ellipsis,)
|
||||
new_arr = numpy.ndarray.__getitem__(self, s, *args, **kwargs)
|
||||
try: new_arr._current_slice = s
|
||||
try: new_arr._current_slice_ = s
|
||||
except AttributeError: pass# returning 0d array or float, double etc
|
||||
return new_arr
|
||||
def __getslice__(self, start, stop):
|
||||
return self.__getitem__(slice(start, stop))
|
||||
def __setitem__(self, *args, **kwargs):
|
||||
numpy.ndarray.__setitem__(self, *args, **kwargs)
|
||||
self._parent._handle_ties()
|
||||
self._parent_.parameters_changed()
|
||||
#===========================================================================
|
||||
# Index Operations:
|
||||
#===========================================================================
|
||||
def _internal_offset(self):
|
||||
internal_offset = 0
|
||||
extended_realshape = numpy.cumprod((1,) + self._realshape_[:0:-1])[::-1]
|
||||
for i, si in enumerate(self._current_slice_[:self._realndim_]):
|
||||
if numpy.all(si == Ellipsis):
|
||||
continue
|
||||
if isinstance(si, slice):
|
||||
a = si.indices(self._realshape_[i])[0]
|
||||
elif isinstance(si, (list,numpy.ndarray,tuple)):
|
||||
a = si[0]
|
||||
else: a = si
|
||||
if a<0:
|
||||
a = self._realshape_[i]+a
|
||||
internal_offset += a * extended_realshape[i]
|
||||
return internal_offset
|
||||
def _raveled_index(self):
|
||||
# return an index array on the raveled array, which is formed by the current_slice
|
||||
# of this object
|
||||
extended_realshape = numpy.cumprod((1,) + self._realshape_[:0:-1])[::-1]
|
||||
ind = self._indices()
|
||||
if ind.ndim < 2: ind=ind[:,None]
|
||||
return numpy.apply_along_axis(lambda x: numpy.sum(extended_realshape*x), 1, ind)
|
||||
def _expand_index(self):
|
||||
# this calculates the full indexing arrays from the slicing objects given by get_item for _real..._ attributes
|
||||
# it basically translates slices to their respective index arrays and turns negative indices around
|
||||
# it tells you in the second return argument if it has only seen arrays as indices
|
||||
def f(a):
|
||||
a, b = a
|
||||
if a not in (slice(None), Ellipsis):
|
||||
if isinstance(a, slice):
|
||||
start, stop, step = a.indices(b)
|
||||
return numpy.r_[start:stop:step]
|
||||
elif isinstance(a, (list,numpy.ndarray,tuple)):
|
||||
a = numpy.asarray(a, dtype=int)
|
||||
a[a<0] = b + a[a<0]
|
||||
elif a<0:
|
||||
a = b+a
|
||||
return numpy.r_[a]
|
||||
return numpy.r_[:b]
|
||||
return itertools.imap(f, itertools.izip_longest(self._current_slice_[:self._realndim_], self._realshape_, fillvalue=slice(None)))
|
||||
#===========================================================================
|
||||
# Printing -> done
|
||||
#===========================================================================
|
||||
|
|
@ -190,16 +308,16 @@ class Param(numpy.ndarray):
|
|||
else: return str(self.shape)
|
||||
@property
|
||||
def _constr(self):
|
||||
return ' '.join(map(lambda c: str(c[0]) if len(c[1])==self._realsize else "{"+str(c[0])+"}", self._parent._constraints_iter_items(self)))
|
||||
return ' '.join(map(lambda c: str(c[0]) if c[1].size==self._realsize_ else "{"+str(c[0])+"}", self._parent_._constraints_iter_items(self)))
|
||||
@property
|
||||
def _t(self):
|
||||
# indices one by one: "".join(map(str,c[0]._indices()))
|
||||
def decide(c):
|
||||
if c[0]._realsize > 1:
|
||||
if c[0]._realsize_ > 1 and not c[0].size==self.size:
|
||||
return c[0].name + "".join(map(str,c[0]._indices()))
|
||||
else:
|
||||
return c[0].name
|
||||
return ' '.join(map(lambda c: decide(c), self._parent._ties_iter_items(self)))
|
||||
return ' '.join(map(lambda c: decide(c), self._parent_._ties_iter_items(self)))
|
||||
def round(self, decimals=0, out=None):
|
||||
view = super(Param, self).round(decimals, out).view(Param)
|
||||
view.__array_finalize__(self)
|
||||
|
|
@ -207,44 +325,83 @@ class Param(numpy.ndarray):
|
|||
round.__doc__ = numpy.round.__doc__
|
||||
def __repr__(self, *args, **kwargs):
|
||||
return "\033[1m{x:s}\033[0;0m:\n".format(x=self.name)+super(Param, self).__repr__(*args,**kwargs)
|
||||
def _constr_matrix_str(self):
|
||||
# create a matrix, which shows the constraints of all indices
|
||||
constr_matrix = numpy.empty(self._realsize, dtype=object) # we need the whole constraints matrix
|
||||
constr_matrix[:] = ''
|
||||
for constr, indices in self._parent._constraints_iter_items(self): # put in all the constraints:
|
||||
cstr = ""+str(constr)+""
|
||||
constr_matrix[indices] = numpy.vectorize(lambda x:" ".join([x, cstr]) if x else cstr, otypes=[str])(constr_matrix[indices])
|
||||
return constr_matrix.astype(numpy.string_).reshape(self._realshape)[self._current_slice].flatten() # and get the slice we did before
|
||||
def _ties_matrix_str(self):
|
||||
# create a matrix, which shows the ties of all indices
|
||||
ties_matr = numpy.empty(self._realsize, dtype=object) # we need the whole constraints matrix
|
||||
ties_matr[:] = ''
|
||||
for tie, indices in self._parent._ties_iter_items(self): # go through all ties
|
||||
tie_cycle = itertools.cycle(tie._indices()) if tie._realsize > 1 else itertools.repeat('')
|
||||
ties_matr[indices] = numpy.vectorize(lambda x:" ".join([x, str(tie.name) + str(str(tie_cycle.next()))]) if x else str(tie.name)+str(str(tie_cycle.next())), otypes=[str])(ties_matr[indices])
|
||||
return ties_matr.astype(numpy.string_).reshape(*(self._realshape+(-1,)))[self._current_slice] # and get the slice we did before
|
||||
# def _constr_matrix_str(self):
|
||||
# create an iterator, which shows the constraints of all indices
|
||||
# cons_turnaround = collections.defaultdict(list)
|
||||
# for c, index in self._parent_._constraints_iter_items(self):
|
||||
# for i in index:
|
||||
# cons_turnaround[i] += [str(c)]
|
||||
# offset = self._internal_offset()
|
||||
# return [" ".join(cons_turnaround[i]) for i in xrange(offset, offset+self.size)]
|
||||
# self._str_dummy_ = numpy.empty(self._realshape_, dtype=object)
|
||||
# constr_matrix = self._str_dummy_ # we need the whole constraints matrix
|
||||
# constr_matrix[:] = ''
|
||||
# for constr, indices in self._parent_._constraints_iter_items(self): # put in all the constraints:
|
||||
# cstr = ""+str(constr)+""
|
||||
# constr_matrix[indices] = numpy.vectorize(lambda x:" ".join([x, cstr]) if x else cstr, otypes=[str])(constr_matrix[indices])
|
||||
# return constr_matrix.astype(numpy.string_).reshape(self._realshape_)[self._current_slice_].flatten() # and get the slice we did before
|
||||
# def _ties_matrix_str(self):
|
||||
# create an iterator, which shows the ties of all indices
|
||||
# ties_turnaround = collections.defaultdict(list)
|
||||
# for tie, index in self._parent_._ties_iter_items(self):
|
||||
# for i in index:
|
||||
# ties_turnaround[i] += [str(tie)]
|
||||
# offset = self._internal_offset()
|
||||
# return [" ".join(ties_turnaround[i]) for i in xrange(offset, offset+self.size)]
|
||||
# for i in xrange(self.size):
|
||||
# yield " ".join(ties_turnaround[i])
|
||||
# if self._str_dummy_ is None:
|
||||
# self._str_dummy_ = numpy.empty(self._realshape_, dtype=object)
|
||||
# ties_matr = self._str_dummy_; ties_matr[:] = ''
|
||||
# for tie, indices in self._parent_._ties_iter_items(self): # go through all ties
|
||||
# tie_cycle = itertools.cycle(tie._indices()) if tie._realsize_ > 1 else itertools.repeat('')
|
||||
# ties_matr[indices] = numpy.vectorize(lambda x:" ".join([x, str(tie.name) + str(str(tie_cycle.next()))]) if x else str(tie.name)+str(str(tie_cycle.next())), otypes=[str])(ties_matr[indices])
|
||||
# return ties_matr.astype(numpy.string_).reshape(*(self._realshape_+(-1,)))[self._current_slice_] # and get the slice we did before
|
||||
|
||||
# def _in_index(self, i, index):
|
||||
# if isinstance(index, slice):
|
||||
# start,stop,step = index.indices()
|
||||
# return i>=start and i<stop and step%i==0
|
||||
# elif index.dtype in (numpy.bool, numpy.bool_):
|
||||
# return index[]
|
||||
def _ties_for(self, index):
|
||||
return self._parent_._ties_for(self, index)
|
||||
def _constraints_for(self, index):
|
||||
return self._parent_._constraints_for(self, index)
|
||||
def _indices(self):
|
||||
# get a int-array containing all indices in the first axis.
|
||||
flat_indices = numpy.array(list(itertools.product(*itertools.imap(range, self._realshape)))).reshape(self._realshape + (-1,))
|
||||
return flat_indices[self._current_slice].reshape(self.size, -1) # find out which indices to print
|
||||
def _max_len_names(self, constr_matrix, header):
|
||||
return max(reduce(lambda a, b:max(a, len(b)), constr_matrix.flat, 0), len(header))
|
||||
if isinstance(self._current_slice_, (tuple, list)):
|
||||
clean_curr_slice = [s for s in self._current_slice_ if s != Ellipsis]
|
||||
if (all(isinstance(n, (numpy.ndarray, list, tuple)) for n in clean_curr_slice)
|
||||
and len(set(map(len,clean_curr_slice))) <= 1):
|
||||
return numpy.fromiter(itertools.izip(*self._expand_index()),
|
||||
dtype=[('',int)]*self._realndim_,count=self.size).view((int, self._realndim_))
|
||||
return numpy.fromiter(itertools.product(*self._expand_index()),
|
||||
dtype=[('',int)]*self._realndim_,count=self.size).view((int, self._realndim_))
|
||||
def _max_len_names(self, gen, header):
|
||||
return reduce(lambda a, b:max(a, len(b)), gen, len(header))
|
||||
def _max_len_values(self):
|
||||
return max(reduce(lambda a, b:max(a, len("{x:=.{0}G}".format(__precision__, x=b))), self.flat, 0), len(self.name))
|
||||
return reduce(lambda a, b:max(a, len("{x:=.{0}G}".format(__precision__, x=b))), self.flat, len(self.name))
|
||||
def _max_len_index(self, ind):
|
||||
return max(reduce(lambda a, b:max(a, len(str(b))), ind, 0), len(__index_name__))
|
||||
return reduce(lambda a, b:max(a, len(str(b))), ind, len(__index_name__))
|
||||
def _short(self):
|
||||
if self._realsize_ < 2:
|
||||
return self.name
|
||||
ind = self._indices()
|
||||
if self.size > 4: indstr = ','.join(map(str,ind[:2])) + "..." + ','.join(map(str,ind[-2:]))
|
||||
else: indstr = ','.join(map(str,ind))
|
||||
return self.name+'['+indstr+']'
|
||||
def __str__(self, constr_matrix=None, indices=None, ties=None, lc=None, lx=None, li=None, lt=None):
|
||||
if indices is None: indices = self._indices()
|
||||
if constr_matrix is None: constr_matrix = self._constr_matrix_str()
|
||||
if ties is None: ties = self._ties_matrix_str()
|
||||
if indices is None: indices = self._indices()
|
||||
ravi = self._raveled_index()
|
||||
if constr_matrix is None: constr_matrix = self._constraints_for(ravi)
|
||||
if ties is None: ties = self._ties_for(ravi)
|
||||
if lc is None: lc = self._max_len_names(constr_matrix, __constraints_name__)
|
||||
if lx is None: lx = self._max_len_values()
|
||||
if li is None: li = self._max_len_index(indices)
|
||||
if lt is None: lt = self._max_len_names(ties, __tie_name__)
|
||||
constr = constr_matrix.flat
|
||||
ties = ties.flat
|
||||
if li is None: li = self._max_len_index(self._indices())
|
||||
if lt is None: lt = self._max_len_names(ties[0], __tie_name__)
|
||||
header = " {i:^{2}s} | \033[1m{x:^{1}s}\033[0;0m | {c:^{0}s} | {t:^{3}s}".format(lc,lx,li,lt, x=self.name, c=__constraints_name__, i=__index_name__, t=__tie_name__) # nice header for printing
|
||||
return "\n".join([header]+[" {i:^{3}s} | {x: >{1}.{2}G} | {c:^{0}s} | {t:^{4}} ".format(lc,lx,__precision__,li,lt, x=x, c=constr.next(), t=ties.next(), i=i) for i,x in itertools.izip(indices,self.flat)]) # return all the constraints with right indices
|
||||
return "\n".join([header]+[" {i!s:^{3}s} | {x: >{1}.{2}G} | {c:^{0}s} | {t:^{4}} ".format(lc,lx,__precision__,li,lt, x=x, c=" ".join(map(str,c)), t=" ".join([tie._short() for tie in t]), i=i) for i,x,c,t in itertools.izip(indices,self.flat,constr_matrix,ties[0])]) # return all the constraints with right indices
|
||||
#except: return super(Param, self).__str__()
|
||||
|
||||
class ParamConcatenation(object):
|
||||
|
|
@ -286,6 +443,7 @@ class ParamConcatenation(object):
|
|||
def constrain_fixed(self, warning=True):
|
||||
[param.constrain_fixed(warning) for param in self.params]
|
||||
constrain_fixed.__doc__ = Param.constrain_fixed.__doc__
|
||||
fix = constrain_fixed
|
||||
def constrain_negative(self, warning=True):
|
||||
[param.constrain_negative(warning) for param in self.params]
|
||||
constrain_negative.__doc__ = Param.constrain_negative.__doc__
|
||||
|
|
@ -304,6 +462,7 @@ class ParamConcatenation(object):
|
|||
def unconstrain_fixed(self):
|
||||
[param.unconstrain_fixed() for param in self.params]
|
||||
unconstrain_fixed.__doc__ = Param.unconstrain_fixed.__doc__
|
||||
unfix = unconstrain_fixed
|
||||
def unconstrain_bounded(self, lower, upper):
|
||||
[param.unconstrain_bounded(lower, upper) for param in self.params]
|
||||
unconstrain_bounded.__doc__ = Param.unconstrain_bounded.__doc__
|
||||
|
|
@ -328,16 +487,19 @@ class ParamConcatenation(object):
|
|||
|
||||
if __name__ == '__main__':
|
||||
from GPy.core.parameterized import Parameterized
|
||||
X = numpy.random.randn(4,2)
|
||||
p = Param("q_mean", X)
|
||||
p1 = Param("q_variance", numpy.random.rand(*p.shape))
|
||||
p2 = Param("Y", numpy.random.randn(p.shape[0],1))
|
||||
p3 = Param("rbf_variance", numpy.random.rand())
|
||||
p4 = Param("rbf_lengthscale", numpy.random.rand(2))
|
||||
m = Parameterized([p,p1,p2,p3,p4])
|
||||
#X = numpy.random.randn(2,3,1,5,2,4,3)
|
||||
X = numpy.random.randn(800,1e4)
|
||||
p = Param("q_mean", X, None)
|
||||
p1 = Param("q_variance", numpy.random.rand(*p.shape), None)
|
||||
p2 = Param("Y", numpy.random.randn(p.shape[0],1), None)
|
||||
p3 = Param("rbf_variance", numpy.random.rand(), None)
|
||||
p4 = Param("rbf_lengthscale", numpy.random.rand(2), None)
|
||||
m = Parameterized()
|
||||
m.set_as_parameters(p,p1,p2,p3,p4)
|
||||
#print m.q_v[3:5,[1,4,5]]
|
||||
m[".*variance"].constrain_positive()
|
||||
m.rbf.constrain_positive()
|
||||
m.q_v.tie_to(m.rbf_v)
|
||||
#m.q_v.tie_to(m.rbf_v)
|
||||
# m.rbf_l.tie_to(m.rbf_va)
|
||||
# pt = numpy.array(params._get_params_transformed())
|
||||
# ptr = numpy.random.randn(*pt.shape)
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@
|
|||
import numpy
|
||||
import copy
|
||||
import cPickle
|
||||
import transformations
|
||||
from parameter import ParamConcatenation
|
||||
from index_operations import ConstraintIndexOperations,\
|
||||
from parameter import ParamConcatenation, Param
|
||||
from index_operations import ParameterIndexOperations,\
|
||||
TieIndexOperations, create_raveled_indices, index_empty
|
||||
import itertools
|
||||
from re import compile, _pattern_type
|
||||
import sys
|
||||
|
||||
#===============================================================================
|
||||
# Printing:
|
||||
|
|
@ -62,58 +62,173 @@ class Parameterized(object):
|
|||
If you want to operate on all parameters use m[''] to wildcard select all paramters
|
||||
and concatenate them. Printing m[''] will result in printing of all parameters in detail.
|
||||
"""
|
||||
def __init__(self, parameterlist, prefix=None, *args, **kwargs):
|
||||
self._init = True
|
||||
self._params = []
|
||||
for p in parameterlist: # flatten paramter list
|
||||
if isinstance(p, Parameterized):
|
||||
self._params.extend(p._params)
|
||||
else:
|
||||
self._params.append(p)
|
||||
self._constraints = ConstraintIndexOperations()
|
||||
self._ties = TieIndexOperations(self)
|
||||
self._ties_fixes = None
|
||||
def __init__(self):
|
||||
self._constraints_ = ParameterIndexOperations()
|
||||
self._ties_ = TieIndexOperations(self)
|
||||
self._ties_fixes_ = None
|
||||
self._in_init_ = True
|
||||
if not hasattr(self, "_parameters_"):
|
||||
self._parameters_ = []
|
||||
self._connect_parameters()
|
||||
self._init = False
|
||||
del self._in_init_
|
||||
#===========================================================================
|
||||
# Parameter connection for model creation:
|
||||
#===========================================================================
|
||||
def set_as_parameter(self, name, array, gradient, index=None):
|
||||
"""
|
||||
:param name: name of the parameter (in print and plots), can be callable without parameters
|
||||
:type name: str, callable
|
||||
:param array: array which the parameter consists of
|
||||
:type array: array-like
|
||||
:param gradient: gradient method of the parameter
|
||||
:type gradient: callable
|
||||
:param index: (optional) index of the parameter when printing
|
||||
|
||||
Set array (e.g. self.X) as parameter with name and gradient.
|
||||
I.e: self.set_as_parameter('curvature', self.lengthscale, self.dK_dlengthscale)
|
||||
|
||||
Note: the order in which parameters are added can be adjusted by
|
||||
giving an index, of where to put this parameter in printing
|
||||
"""
|
||||
if index is None:
|
||||
self._parameters_.append(Param(name, array, gradient))
|
||||
else:
|
||||
self._parameters_.insert(index, Param(name, array, gradient))
|
||||
self._connect_parameters()
|
||||
def set_as_parameters(self, *parameters, **kwargs):
|
||||
"""
|
||||
:param parameters: the parameters to add
|
||||
:param index: index of where to put parameters
|
||||
Add all parameters to this parameter class, you can insert parameters
|
||||
at any given point using the :py:func:`list.insert` syntax
|
||||
"""
|
||||
if kwargs.get('index',None) is None:
|
||||
self._parameters_.extend(parameters)
|
||||
else:
|
||||
self._parameters_.insert(kwargs['index'], parameters)
|
||||
self._connect_parameters()
|
||||
def remove_parameter(self, *names_params_indices):
|
||||
"""
|
||||
:param names_params_indices: mix of parameter_names, parameter objects, or indices
|
||||
to remove from being a parameter of this parameterized object.
|
||||
|
||||
note: if it is a string object it will be regexp-matched automatically
|
||||
"""
|
||||
self._parameters_ = [p for p in self._parameters_
|
||||
if not (p._parent_index_ in names_params_indices
|
||||
or p.name in names_params_indices
|
||||
or p in names_params_indices)]
|
||||
self._connect_parameters()
|
||||
def parameters_changed(self):
|
||||
# will be called as soon as paramters have changed
|
||||
pass
|
||||
def _connect_parameters(self):
|
||||
# connect parameterlist to this parameterized object
|
||||
# This just sets up the right connection for the params objects
|
||||
# to be used as parameters
|
||||
sizes = numpy.cumsum([0] + self.parameter_sizes)
|
||||
if not hasattr(self, "_parameters_") or len(self._parameters_) < 1:
|
||||
# no parameters for this class
|
||||
return
|
||||
sizes = numpy.cumsum([0] + self._parameter_sizes_)
|
||||
self._param_slices = [slice(start, stop) for start,stop in zip(sizes, sizes[1:])]
|
||||
for i, p in enumerate(self._params):
|
||||
p._parent = self
|
||||
p._parent_index = i
|
||||
for i, p in enumerate(self._parameters_):
|
||||
p._parent_ = self
|
||||
p._parent_index_ = i
|
||||
not_unique = []
|
||||
if p.name in self.__dict__:
|
||||
not_unique.append(p.name)
|
||||
del self.__dict__[p.name]
|
||||
if p.base is self.__dict__[p.name]:
|
||||
self.__dict__[p.name] = p
|
||||
else:
|
||||
not_unique.append(p.name)
|
||||
del self.__dict__[p.name]
|
||||
elif not (p.name in not_unique):
|
||||
self.__dict__[p.name] = p
|
||||
|
||||
self.__dict__[p.name] = p
|
||||
#===========================================================================
|
||||
# Pickling operations
|
||||
#===========================================================================
|
||||
def pickle(self, f, protocol=-1):
|
||||
"""
|
||||
:param f: either filename or open file object to write to.
|
||||
if it is an open buffer, you have to make sure to close
|
||||
it properly.
|
||||
:param protocol: pickling protocol to use, python-pickle for details.
|
||||
"""
|
||||
if isinstance(f, str):
|
||||
with open(f, 'w') as f:
|
||||
cPickle.dump(self, f, protocol)
|
||||
else:
|
||||
cPickle.dump(self, f, protocol)
|
||||
def copy(self):
|
||||
"""Returns a (deep) copy of the current model """
|
||||
return copy.deepcopy(self)
|
||||
def __getstate__(self):
|
||||
if self._has_get_set_state():
|
||||
return self.getstate()
|
||||
return self.__dict__
|
||||
def __setstate__(self, state):
|
||||
if self._has_get_set_state():
|
||||
self.setstate(state) # set state
|
||||
#self._set_params(self._get_params()) # restore all values
|
||||
return
|
||||
self.__dict__ = state
|
||||
def _has_get_set_state(self):
|
||||
return 'getstate' in vars(self.__class__) and 'setstate' in vars(self.__class__)
|
||||
def getstate(self):
|
||||
"""
|
||||
Get the current state of the class,
|
||||
here just all the indices, rest can get recomputed
|
||||
For inheriting from Parameterized:
|
||||
|
||||
Allways append the state of the inherited object
|
||||
and call down to the inherited object in setstate!!
|
||||
"""
|
||||
return [self._ties_,
|
||||
self._constraints_,
|
||||
self._parameters_,
|
||||
]
|
||||
def setstate(self, state):
|
||||
self._parameters_ = state.pop()
|
||||
self._connect_parameters()
|
||||
self._priors = state.pop()
|
||||
self._constraints_ = state.pop()
|
||||
self._ties_ = state.pop()
|
||||
self._ties_fixes_ = numpy.ones(self._parameter_size_, dtype=bool)
|
||||
for f, (fixed, ind) in itertools.izip_longest(self._ties_.iter_from_indices(), self._constraints_.iteritems()):
|
||||
if f is not None:
|
||||
self._ties_fixes_[f] = False
|
||||
if fixed == __fixed__:
|
||||
self._ties_fixes_[ind] = False
|
||||
if numpy.all(self._ties_fixes_):
|
||||
self._ties_fixes_ = None
|
||||
self.parameters_changed()
|
||||
#===========================================================================
|
||||
# Optimization handles:
|
||||
#===========================================================================
|
||||
def _get_params(self):
|
||||
# don't overright this anymore!
|
||||
return numpy.hstack([x._get_params() for x in self._params])#numpy.fromiter(itertools.chain(*itertools.imap(lambda x: x._get_params(), self._params)), dtype=numpy.float64, count=sum(self.parameter_sizes))
|
||||
# don't overwrite this anymore!
|
||||
return numpy.hstack([x._get_params() for x in self._parameters_])#numpy.fromiter(itertools.chain(*itertools.imap(lambda x: x._get_params(), self._parameters_)), dtype=numpy.float64, count=sum(self._parameter_sizes_))
|
||||
def _set_params(self, params):
|
||||
# don't overright this anymore!
|
||||
[p._set_params(params[s]) for p,s in itertools.izip(self._params,self._param_slices)]
|
||||
# don't overwrite this anymore!
|
||||
[p._set_params(params[s]) for p,s in itertools.izip(self._parameters_,self._param_slices)]
|
||||
self.parameters_changed()
|
||||
def _get_params_transformed(self):
|
||||
p = self._get_params()
|
||||
[numpy.put(p, ind, c.finv(p[ind])) for c,ind in self._constraints.iteritems() if c is not __fixed__]
|
||||
if self._ties_fixes is not None:
|
||||
return p[self._ties_fixes]
|
||||
[numpy.put(p, ind, c.finv(p[ind])) for c,ind in self._constraints_.iteritems() if c != __fixed__]
|
||||
if self._ties_fixes_ is not None:
|
||||
return p[self._ties_fixes_]
|
||||
return p
|
||||
def _set_params_transformed(self, p):
|
||||
if self._ties_fixes is not None: tmp = self._get_params(); tmp[self._ties_fixes] = p; p = tmp; del tmp
|
||||
[numpy.put(p, ind, c.f(p[ind])) for c,ind in self._constraints.iteritems() if c is not __fixed__]
|
||||
[numpy.put(p, f, p[t]) for f,t in self._ties.iter_from_to_indices()]
|
||||
if self._ties_fixes_ is not None: tmp = self._get_params(); tmp[self._ties_fixes_] = p; p = tmp; del tmp
|
||||
[numpy.put(p, ind, c.f(p[ind])) for c,ind in self._constraints_.iteritems() if c != __fixed__]
|
||||
[numpy.put(p, f, p[t]) for f,t in self._ties_.iter_from_to_indices()]
|
||||
self._set_params(p)
|
||||
def _handle_ties(self):
|
||||
if not self._init:
|
||||
if not hasattr(self, '_in_init_'):
|
||||
self._set_params_transformed(self._get_params_transformed())
|
||||
def _name_changed(self, param, old_name):
|
||||
if hasattr(self, old_name):
|
||||
delattr(self, old_name)
|
||||
self.__dict__[param.name] = param
|
||||
#===========================================================================
|
||||
# Index Handling
|
||||
#===========================================================================
|
||||
|
|
@ -121,38 +236,34 @@ class Parameterized(object):
|
|||
# translate an index in parameterized indexing into the index of param
|
||||
ind = ind-self._offset(param)
|
||||
ind = ind[ind >= 0]
|
||||
internal_offset = (numpy.arange(param._realsize).reshape(param._realshape)[param._current_slice]).flat[0]
|
||||
internal_offset = param._internal_offset()
|
||||
internal_offset_old = (numpy.arange(param._realsize_).reshape(param._realshape_)[param._current_slice_]).flat[0]
|
||||
assert internal_offset == internal_offset_old
|
||||
ind = ind[ind < param.size + internal_offset]
|
||||
return ind
|
||||
def _offset(self, param):
|
||||
# get the offset in the parameterized index array for param
|
||||
return self._param_slices[param._parent_index].start
|
||||
return self._param_slices[param._parent_index_].start
|
||||
#===========================================================================
|
||||
# Handle ties:
|
||||
#===========================================================================
|
||||
def _add_tie(self, param, tied_to):
|
||||
# tie param to tie_to, if the values match (with broadcasting)
|
||||
try:
|
||||
param[...] = tied_to
|
||||
except ValueError:
|
||||
raise ValueError("Trying to tie {} with shape {} to {} with shape {}".format(self.name, self.shape, param.name, param.shape))
|
||||
self._ties.add(param, tied_to)
|
||||
if self._ties_fixes is None: self._ties_fixes = numpy.ones(self.parameter_size, dtype=bool)
|
||||
f = create_raveled_indices(param._current_slice, param._realshape, self._offset(param))
|
||||
self._ties_fixes[f] = False
|
||||
self._ties_.add(param, tied_to)
|
||||
if self._ties_fixes_ is None: self._ties_fixes_ = numpy.ones(self._parameter_size_, dtype=bool)
|
||||
f = create_raveled_indices(param._current_slice_, param._realshape_, self._offset(param))
|
||||
self._ties_fixes_[f] = False
|
||||
def _remove_tie(self, param, *params):
|
||||
# remove the tie from param to all *params (can be None, so all ties get deleted for param)
|
||||
if len(params) == 0:
|
||||
params = self._ties.properties()
|
||||
for p in self._ties.properties():
|
||||
for a in params:
|
||||
if numpy.all(a==p):
|
||||
ind = create_raveled_indices(p._current_slice, param._realshape, self._offset(param))
|
||||
self._ties.remove(param, p)
|
||||
self._ties_fixes[ind] = True
|
||||
if numpy.all(self._ties_fixes): self._ties_fixes = None
|
||||
params = self._ties_.properties()
|
||||
for p in params:
|
||||
ind = create_raveled_indices(p._current_slice_, param._realshape_, self._offset(param))
|
||||
self._ties_.remove(param, p)
|
||||
self._ties_fixes_[ind] = True
|
||||
if numpy.all(self._ties_fixes_): self._ties_fixes_ = None
|
||||
def _ties_iter_items(self, param):
|
||||
for tied_to, ind in self._ties.iter_from_items():
|
||||
for tied_to, ind in self._ties_.iter_from_items():
|
||||
ind = self._backtranslate_index(param, ind)
|
||||
if not index_empty(ind):
|
||||
yield tied_to, ind
|
||||
|
|
@ -162,41 +273,43 @@ class Parameterized(object):
|
|||
def _ties_iter_indices(self, param):
|
||||
for _, ind in self._ties_iter_items(param):
|
||||
yield ind
|
||||
#===========================================================================
|
||||
def _ties_for(self, param, index):
|
||||
return self._ties_.from_to_for(index+self._offset(param))
|
||||
#===========================================================================
|
||||
# Fixing parameters:
|
||||
#===========================================================================
|
||||
def _fix(self, param, warning=True):
|
||||
self._add_constrain(param, __fixed__, warning)
|
||||
if self._ties_fixes is None: self._ties_fixes = numpy.ones(self.parameter_size, dtype=bool)
|
||||
f = create_raveled_indices(param._current_slice, param._realshape, self._offset(param))
|
||||
self._ties_fixes[f] = False
|
||||
if self._ties_fixes_ is None: self._ties_fixes_ = numpy.ones(self._parameter_size_, dtype=bool)
|
||||
f = create_raveled_indices(param._current_slice_, param._realshape_, self._offset(param))
|
||||
self._ties_fixes_[f] = False
|
||||
def _unfix(self, param):
|
||||
self._remove_constrain(param, __fixed__)
|
||||
ind = create_raveled_indices(param._current_slice, param._realshape, self._offset(param))
|
||||
self._ties_fixes[ind] = True
|
||||
if numpy.all(self._ties_fixes): self._ties_fixes = None
|
||||
ind = create_raveled_indices(param._current_slice_, param._realshape_, self._offset(param))
|
||||
self._ties_fixes_[ind] = True
|
||||
if numpy.all(self._ties_fixes_): self._ties_fixes_ = None
|
||||
#===========================================================================
|
||||
# Constraint Handling:
|
||||
#===========================================================================
|
||||
def _add_constrain(self, param, transform, warning=True):
|
||||
reconstrained = self._remove_constrain(param, None) # remove constraints before
|
||||
self._constraints.add(transform, param._current_slice, param._realshape, self._offset(param))
|
||||
reconstrained = self._remove_constrain(param) # remove constraints before
|
||||
# if removing constraints before adding new is not wanted, just delete the above line!
|
||||
self._constraints_.add(transform, param._current_slice_, param._realshape_, self._offset(param))
|
||||
if warning and any(reconstrained):
|
||||
# if you want to print the whole params object, which was reconstrained use:
|
||||
# m = str(param[self._backtranslate_index(param, reconstrained)])
|
||||
m = param.name + str("".join(map(str,param._indices()[self._backtranslate_index(param, reconstrained)])))
|
||||
print "Warning: re-constraining parameters:\n{}".format(m)
|
||||
print "Warning: re-constraining parameters:\n{}".format(param._short())
|
||||
def _remove_constrain(self, param, *transforms):
|
||||
if transforms is ():
|
||||
transforms = self._constraints.properties()
|
||||
transforms = self._constraints_.properties()
|
||||
removed_indices = numpy.array([]).astype(int)
|
||||
for constr in transforms:
|
||||
removed = self._constraints.remove(constr, param._current_slice, param._realshape, self._offset(param))
|
||||
removed = self._constraints_.remove(constr, param._current_slice_, param._realshape_, self._offset(param))
|
||||
removed_indices = numpy.union1d(removed_indices, removed)
|
||||
return removed_indices
|
||||
# convienience for iterating over items
|
||||
def _constraints_iter_items(self, param):
|
||||
for constr, ind in self._constraints.iteritems():
|
||||
for constr, ind in self._constraints_.iteritems():
|
||||
ind = self._backtranslate_index(param, ind)
|
||||
if not index_empty(ind):
|
||||
yield constr, ind
|
||||
|
|
@ -207,7 +320,9 @@ class Parameterized(object):
|
|||
for _, ind in self._constraints_iter_items(param):
|
||||
yield ind
|
||||
def _constraint_indices(self, param, constraint):
|
||||
return self._backtranslate_index(param, self._constraints[constraint])
|
||||
return self._backtranslate_index(param, self._constraints_[constraint])
|
||||
def _constraints_for(self, param, index):
|
||||
return self._constraints_.properties_for(index+self._offset(param))
|
||||
#===========================================================================
|
||||
# Get/set parameters:
|
||||
#===========================================================================
|
||||
|
|
@ -216,8 +331,7 @@ class Parameterized(object):
|
|||
create a list of parameters, matching regular expression regexp
|
||||
"""
|
||||
if not isinstance(regexp, _pattern_type): regexp = compile(regexp)
|
||||
paramlist = [param for param in self._params if regexp.match(param.name) is not None]
|
||||
return paramlist
|
||||
return [param for param in self._parameters_ if regexp.match(param.name) is not None]
|
||||
def __getitem__(self, name, paramlist=None):
|
||||
if paramlist is None:
|
||||
paramlist = self.grep_param_names(name)
|
||||
|
|
@ -227,50 +341,58 @@ class Parameterized(object):
|
|||
def __setitem__(self, name, value, paramlist=None):
|
||||
try: param = self.__getitem__(name, paramlist)
|
||||
except AttributeError as a: raise a
|
||||
param[...] = value
|
||||
def __getattr__(self, name, *args, **kwargs):
|
||||
return self.__getitem__(name)
|
||||
param[:] = value
|
||||
self._handle_ties()
|
||||
def __getattribute__(self, name):
|
||||
try:
|
||||
return object.__getattribute__(self, name)
|
||||
except AttributeError:
|
||||
_, a, tb = sys.exc_info()
|
||||
try:
|
||||
return self.__getitem__(name)
|
||||
except AttributeError:
|
||||
raise AttributeError, a.message, tb
|
||||
def __setattr__(self, name, val):
|
||||
# override the default behaviour, if setting a parameter, so broadcasting can by used
|
||||
if hasattr(self, "_params"):
|
||||
if hasattr(self, "_parameters_"):
|
||||
paramlist = self.grep_param_names(name)
|
||||
if len(paramlist) > 1: object.__setattr__(self, name, val); return# raise AttributeError("Non-unique params identified {}".format([p.name for p in paramlist]))
|
||||
if len(paramlist) == 1: self.__setitem__(name, val, paramlist); return
|
||||
object.__setattr__(self, name, val);
|
||||
#===========================================================================
|
||||
# Printing:
|
||||
#===========================================================================
|
||||
@property
|
||||
def names(self):
|
||||
return [x.name for x in self._params]
|
||||
def parameter_names(self):
|
||||
return [x.name for x in self._parameters_]
|
||||
@property
|
||||
def parameter_size(self):
|
||||
return sum(self.parameter_sizes)
|
||||
def _parameter_size_(self):
|
||||
return sum(self._parameter_sizes_)
|
||||
@property
|
||||
def parameter_sizes(self):
|
||||
return [x.size for x in self._params]
|
||||
def _parameter_sizes_(self):
|
||||
return [x.size for x in self._parameters_]
|
||||
@property
|
||||
def parameter_size_transformed(self):
|
||||
return sum(self._ties_fixes)
|
||||
def _parameter_size_transformed_(self):
|
||||
return sum(self._ties_fixes_)
|
||||
@property
|
||||
def parameter_shapes(self):
|
||||
return [x.shape for x in self._params]
|
||||
def _parameter_shapes_(self):
|
||||
return [x.shape for x in self._parameters_]
|
||||
@property
|
||||
def _constrs(self):
|
||||
return [p._constr for p in self._params]
|
||||
return [p._constr for p in self._parameters_]
|
||||
@property
|
||||
def _descs(self):
|
||||
return [x._desc for x in self._params]
|
||||
return [x._desc for x in self._parameters_]
|
||||
@property
|
||||
def _ts(self):
|
||||
return [x._t for x in self._params]
|
||||
return [x._t for x in self._parameters_]
|
||||
def __str__(self, header=True):
|
||||
nl = max([len(str(x)) for x in self.names + ["Name"]])
|
||||
nl = max([len(str(x)) for x in self.parameter_names + ["Name"]])
|
||||
sl = max([len(str(x)) for x in self._descs + ["Value"]])
|
||||
cl = max([len(str(x)) if x else 0 for x in self._constrs + ["Constraint"]])
|
||||
tl = max([len(str(x)) if x else 0 for x in self._ts + ["Tied to"]])
|
||||
format_spec = " \033[1m{{p.name:^{0}s}}\033[0;0m | {{p._desc:^{1}s}} | {{p._constr:^{2}s}} | {{p._t:^{2}s}}".format(nl, sl, cl)
|
||||
to_print = [format_spec.format(p=p) for p in self._params]
|
||||
constrs = self._constrs; ts = self._ts
|
||||
cl = max([len(str(x)) if x else 0 for x in constrs + ["Constraint"]])
|
||||
tl = max([len(str(x)) if x else 0 for x in ts + ["Tied to"]])
|
||||
format_spec = " \033[1m{{p.name:^{0}s}}\033[0;0m | {{p._desc:^{1}s}} | {{const:^{2}s}} | {{t:^{2}s}}".format(nl, sl, cl)
|
||||
to_print = [format_spec.format(p=p, const=c, t=t) for p, c, t in itertools.izip(self._parameters_, constrs, ts)]
|
||||
sep = '-'*len(to_print[0])
|
||||
if header:
|
||||
header = " {{0:^{0}s}} | {{1:^{1}s}} | {{2:^{2}s}} | {{3:^{3}s}}".format(nl, sl, cl, tl).format("Name", "Value", "Constraint", "Tied to")
|
||||
|
|
@ -299,7 +421,7 @@ class Parameterized(object):
|
|||
# def _get_param_names(self):
|
||||
# raise NotImplementedError, "this needs to be implemented to use the Parameterized class"
|
||||
# #def _get_print_names(self):
|
||||
# # """ Override for which names to print out, when using print m """
|
||||
# # """ Override for which parameter_names to print out, when using print m """
|
||||
# # return self._get_param_names()
|
||||
#
|
||||
# def pickle(self, filename, protocol=None):
|
||||
|
|
@ -404,7 +526,7 @@ class Parameterized(object):
|
|||
#
|
||||
# def grep_param_names(self, regexp, transformed=False, search=False):
|
||||
# """
|
||||
# :param regexp: regular expression to select parameter names
|
||||
# :param regexp: regular expression to select parameter parameter_names
|
||||
# :type regexp: re | str | int
|
||||
# :rtype: the indices of self._get_param_names which match the regular expression.
|
||||
#
|
||||
|
|
@ -413,9 +535,9 @@ class Parameterized(object):
|
|||
# """
|
||||
#
|
||||
# if transformed:
|
||||
# names = self._get_param_names_transformed()
|
||||
# parameter_names = self._get_param_names_transformed()
|
||||
# else:
|
||||
# names = self._get_param_names()
|
||||
# parameter_names = self._get_param_names()
|
||||
#
|
||||
# if type(regexp) in [str, np.string_, np.str]:
|
||||
# regexp = re.compile(regexp)
|
||||
|
|
@ -424,9 +546,9 @@ class Parameterized(object):
|
|||
# else:
|
||||
# return regexp
|
||||
# if search:
|
||||
# return np.nonzero([regexp.search(name) for name in names])[0]
|
||||
# return np.nonzero([regexp.search(name) for name in parameter_names])[0]
|
||||
# else:
|
||||
# return np.nonzero([regexp.match(name) for name in names])[0]
|
||||
# return np.nonzero([regexp.match(name) for name in parameter_names])[0]
|
||||
#
|
||||
# def num_params_transformed(self):
|
||||
# removed = 0
|
||||
|
|
@ -514,7 +636,7 @@ class Parameterized(object):
|
|||
#
|
||||
# Fixing a parameter which is tied to another, or constrained in some way will result in an error.
|
||||
#
|
||||
# To fix multiple parameters to the same value, simply pass a regular expression which matches both parameter names, or pass both of the indexes.
|
||||
# To fix multiple parameters to the same value, simply pass a regular expression which matches both parameter parameter_names, or pass both of the indexes.
|
||||
#
|
||||
# """
|
||||
# matches = self.grep_param_names(regexp)
|
||||
|
|
@ -586,12 +708,12 @@ class Parameterized(object):
|
|||
#
|
||||
# def _get_param_names_transformed(self):
|
||||
# """
|
||||
# Returns the parameter names as propagated after constraining,
|
||||
# Returns the parameter parameter_names as propagated after constraining,
|
||||
# tying or fixing, i.e. a list of the same length as _get_params_transformed()
|
||||
# """
|
||||
# n = self._get_param_names()
|
||||
#
|
||||
# # remove/concatenate the tied parameter names
|
||||
# # remove/concatenate the tied parameter parameter_names
|
||||
# if len(self.tied_indices):
|
||||
# for t in self.tied_indices:
|
||||
# n[t[0]] = "<tie>".join([n[tt] for tt in t])
|
||||
|
|
@ -616,16 +738,16 @@ class Parameterized(object):
|
|||
# # return self.__str__(self._get_param_names())
|
||||
#
|
||||
#
|
||||
# #def __str__(self, names=None, nw=30):
|
||||
# #def __str__(self, parameter_names=None, nw=30):
|
||||
# def __str__(self, nw=30):
|
||||
# """
|
||||
# Return a string describing the parameter names and their ties and constraints
|
||||
# Return a string describing the parameter parameter_names and their ties and constraints
|
||||
# """
|
||||
# names = self._get_param_names()
|
||||
# #if names is None:
|
||||
# # names = self._get_print_names()
|
||||
# #name_indices = self.grep_param_names("|".join(names))
|
||||
# N = len(names)
|
||||
# parameter_names = self._get_param_names()
|
||||
# #if parameter_names is None:
|
||||
# # parameter_names = self._get_print_names()
|
||||
# #name_indices = self.grep_param_names("|".join(parameter_names))
|
||||
# N = len(parameter_names)
|
||||
#
|
||||
# if not N:
|
||||
# return "This object has no free parameters."
|
||||
|
|
@ -633,7 +755,7 @@ class Parameterized(object):
|
|||
# values = self._get_params() # map(str,self._get_params())
|
||||
# #values = self._get_params()[name_indices] # map(str,self._get_params())
|
||||
# # sort out the constraints
|
||||
# constraints = [''] * len(names)
|
||||
# constraints = [''] * len(parameter_names)
|
||||
# #constraints = [''] * len(self._get_param_names())
|
||||
# for i, t in zip(self.constrained_indices, self.constraints):
|
||||
# for ii in i:
|
||||
|
|
@ -642,7 +764,7 @@ class Parameterized(object):
|
|||
# for ii in i:
|
||||
# constraints[ii] = 'Fixed'
|
||||
# # sort out the ties
|
||||
# ties = [''] * len(names)
|
||||
# ties = [''] * len(parameter_names)
|
||||
# for i, tie in enumerate(self.tied_indices):
|
||||
# for j in tie:
|
||||
# ties[j] = '(' + str(i) + ')'
|
||||
|
|
@ -651,7 +773,7 @@ class Parameterized(object):
|
|||
# values = ['%.4f' %float(values)]
|
||||
# else:
|
||||
# values = ['%.4f' % float(v) for v in values]
|
||||
# max_names = max([len(names[i]) for i in range(len(names))] + [len(header[0])])
|
||||
# max_names = max([len(parameter_names[i]) for i in range(len(parameter_names))] + [len(header[0])])
|
||||
# max_values = max([len(values[i]) for i in range(len(values))] + [len(header[1])])
|
||||
# max_constraint = max([len(constraints[i]) for i in range(len(constraints))] + [len(header[2])])
|
||||
# max_ties = max([len(ties[i]) for i in range(len(ties))] + [len(header[3])])
|
||||
|
|
@ -661,7 +783,7 @@ class Parameterized(object):
|
|||
# header_string = ["{h:^{col}}".format(h=header[i], col=cols[i]) for i in range(len(cols))]
|
||||
# header_string = map(lambda x: '|'.join(x), [header_string])
|
||||
# separator = '-' * len(header_string[0])
|
||||
# param_string = ["{n:^{c0}}|{v:^{c1}}|{c:^{c2}}|{t:^{c3}}".format(n=names[i], v=values[i], c=constraints[i], t=ties[i], c0=cols[0], c1=cols[1], c2=cols[2], c3=cols[3]) for i in range(len(values))]
|
||||
# param_string = ["{n:^{c0}}|{v:^{c1}}|{c:^{c2}}|{t:^{c3}}".format(n=parameter_names[i], v=values[i], c=constraints[i], t=ties[i], c0=cols[0], c1=cols[1], c2=cols[2], c3=cols[3]) for i in range(len(values))]
|
||||
#
|
||||
#
|
||||
# return ('\n'.join([header_string[0], separator] + param_string)) + '\n'
|
||||
|
|
@ -670,8 +792,8 @@ class Parameterized(object):
|
|||
# regexp_indices = self.grep_param_names(regexp)
|
||||
# all_names = self._get_param_names()
|
||||
#
|
||||
# names = [all_names[pj] for pj in regexp_indices]
|
||||
# N = len(names)
|
||||
# parameter_names = [all_names[pj] for pj in regexp_indices]
|
||||
# N = len(parameter_names)
|
||||
#
|
||||
# if not N:
|
||||
# return "Match not found."
|
||||
|
|
@ -679,12 +801,12 @@ class Parameterized(object):
|
|||
# header = ['Name', 'Value', 'Constraints', 'Ties']
|
||||
# all_values = self._get_params()
|
||||
# values = np.array([all_values[pj] for pj in regexp_indices])
|
||||
# constraints = [''] * len(names)
|
||||
# constraints = [''] * len(parameter_names)
|
||||
#
|
||||
# _constrained_indices,aux = self._pick_elements(regexp_indices,self.constrained_indices)
|
||||
# _constraints = [self.constraints[pj] for pj in aux]
|
||||
# _constraints_ = [self.constraints[pj] for pj in aux]
|
||||
#
|
||||
# for i, t in zip(_constrained_indices, _constraints):
|
||||
# for i, t in zip(_constrained_indices, _constraints_):
|
||||
# for ii in i:
|
||||
# iii = regexp_indices.tolist().index(ii)
|
||||
# constraints[iii] = t.__str__()
|
||||
|
|
@ -696,7 +818,7 @@ class Parameterized(object):
|
|||
# constraints[ii] = 'Fixed'
|
||||
#
|
||||
# _tied_indices,aux = self._pick_elements(regexp_indices,self.tied_indices)
|
||||
# ties = [''] * len(names)
|
||||
# ties = [''] * len(parameter_names)
|
||||
# for i,ti in zip(_tied_indices,aux):
|
||||
# for ii in i:
|
||||
# iii = regexp_indices.tolist().index(ii)
|
||||
|
|
@ -707,7 +829,7 @@ class Parameterized(object):
|
|||
# else:
|
||||
# values = ['%.4f' % float(v) for v in values]
|
||||
#
|
||||
# max_names = max([len(names[i]) for i in range(len(names))] + [len(header[0])])
|
||||
# max_names = max([len(parameter_names[i]) for i in range(len(parameter_names))] + [len(header[0])])
|
||||
# max_values = max([len(values[i]) for i in range(len(values))] + [len(header[1])])
|
||||
# max_constraint = max([len(constraints[i]) for i in range(len(constraints))] + [len(header[2])])
|
||||
# max_ties = max([len(ties[i]) for i in range(len(ties))] + [len(header[3])])
|
||||
|
|
@ -716,7 +838,7 @@ class Parameterized(object):
|
|||
# header_string = ["{h:^{col}}".format(h=header[i], col=cols[i]) for i in range(len(cols))]
|
||||
# header_string = map(lambda x: '|'.join(x), [header_string])
|
||||
# separator = '-' * len(header_string[0])
|
||||
# param_string = ["{n:^{c0}}|{v:^{c1}}|{c:^{c2}}|{t:^{c3}}".format(n=names[i], v=values[i], c=constraints[i], t=ties[i], c0=cols[0], c1=cols[1], c2=cols[2], c3=cols[3]) for i in range(len(values))]
|
||||
# param_string = ["{n:^{c0}}|{v:^{c1}}|{c:^{c2}}|{t:^{c3}}".format(n=parameter_names[i], v=values[i], c=constraints[i], t=ties[i], c0=cols[0], c1=cols[1], c2=cols[2], c3=cols[3]) for i in range(len(values))]
|
||||
#
|
||||
# print header_string[0]
|
||||
# print separator
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue