Package ComboCode :: Package cc :: Package ivs :: Package sigproc :: Package lmfit :: Module parameter
[hide private]
[frames] | no frames]

Source Code for Module ComboCode.cc.ivs.sigproc.lmfit.parameter

  1  """ 
  2  Parameter class 
  3  """ 
  4  from numpy import arcsin, cos, sin, sqrt, inf, nan, random 
  5   
  6  try: 
  7      from collections import OrderedDict 
  8  except ImportError: 
  9      from ordereddict import OrderedDict 
 10   
 11  import re 
 12  from . import uncertainties 
 13   
 14   
 15  RESERVED_WORDS = ('and', 'as', 'assert', 'break', 'class', 'continue', 
 16                    'def', 'del', 'elif', 'else', 'except', 'exec', 
 17                    'finally', 'for', 'from', 'global', 'if', 'import', 'in', 
 18                    'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 
 19                    'return', 'try', 'while', 'with', 'True', 'False', 
 20                    'None', 'eval', 'execfile', '__import__', '__package__') 
 21   
 22  NAME_MATCH = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$").match 
23 24 -def valid_symbol_name(name):
25 "input is a valid name" 26 if name in RESERVED_WORDS: 27 return False 28 return NAME_MATCH(name) is not None
29
30 31 -class Parameters(OrderedDict):
32 """a custom dictionary of Parameters. All keys must be 33 strings, and valid Python symbol names, and all values 34 must be Parameters. 35 36 Custom methods: 37 --------------- 38 39 add() 40 add_many() 41 """
42 - def __init__(self, *args, **kwds):
43 OrderedDict.__init__(self) 44 self.update(*args, **kwds)
45
46 - def __setitem__(self, key, value):
47 if key not in self: 48 if not valid_symbol_name(key): 49 raise KeyError("'%s' is not a valid Parameters name" % key) 50 if value is not None and not isinstance(value, Parameter): 51 raise ValueError("'%s' is not a Parameter" % value) 52 OrderedDict.__setitem__(self, key, value) 53 value.name = key
54
55 - def add(self, name, value=None, vary=True, min=None, max=None, expr=None):
56 """convenience function for adding a Parameter: 57 with p = Parameters() 58 p.add(name, value=XX, ....) 59 60 is equivalent to 61 p[name] = Parameter(name=name, value=XX, .... 62 """ 63 self.__setitem__(name, Parameter(value=value, name=name, vary=vary, 64 min=min, max=max, expr=expr))
65
66 - def add_many(self, *parlist):
67 """convenience function for adding a list of Parameters: 68 Here, you must provide a sequence of tuples, each containing 69 at least the name. The order in each tuple is the following: 70 name, value, vary, min, max, expr 71 with p = Parameters() 72 p.add_many( (name1, val1, True, None, None, None), 73 (name2, val2, True, 0.0, None, None), 74 (name3, val3, False, None, None, None), 75 (name4, val4)) 76 77 """ 78 for para in parlist: 79 self.add(*para)
80
81 -class Parameter(object):
82 """A Parameter is the basic Parameter going 83 into Fit Model. The Parameter holds many attributes: 84 value, vary, max_value, min_value, constraint expression. 85 The value and min/max values will be be set to floats. 86 """
87 - def __init__(self, name=None, value=None, vary=True, 88 min=None, max=None, expr=None):
89 self.name = name 90 self._val = value 91 self.user_value = value 92 self.init_value = value 93 self.min = min 94 self.max = max 95 self.vary = vary 96 self.expr = expr 97 self.deps = None 98 self.stderr = None 99 self.correl = None 100 if self.max is not None and value > self.max: 101 self._val = self.max 102 if self.min is not None and value < self.min: 103 self._val = self.min 104 self.from_internal = lambda val: val
105
106 - def __repr__(self):
107 s = [] 108 if self.name is not None: 109 s.append("'%s'" % self.name) 110 sval = repr(self._val) 111 if self.stderr is not None: 112 sval = "value=%s +/- %.3g" % (sval, self.stderr) 113 if not self.vary and self.expr is None: 114 sval = "value=%s (fixed)" % (sval) 115 s.append(sval) 116 s.append("bounds=[%s:%s]" % (repr(self.min), repr(self.max))) 117 if self.expr is not None: 118 s.append("expr='%s'" % (self.expr)) 119 return "<Parameter %s>" % ', '.join(s)
120
121 - def setup_bounds(self):
122 """set up Minuit-style internal/external parameter transformation 123 of min/max bounds. 124 125 returns internal value for parameter from self.value (which holds 126 the external, user-expected value). This internal values should 127 actually be used in a fit.... 128 129 As a side-effect, this also defines the self.from_internal method 130 used to re-calculate self.value from the internal value, applying 131 the inverse Minuit-style transformation. This method should be 132 called prior to passing a Parameter to the user-defined objective 133 function. 134 135 This code borrows heavily from JJ Helmus' leastsqbound.py 136 """ 137 if self.min in (None, -inf) and self.max in (None, inf): 138 self.from_internal = lambda val: val 139 _val = self._val 140 elif self.max in (None, inf): 141 self.from_internal = lambda val: self.min - 1 + sqrt(val*val + 1) 142 _val = sqrt((self._val - self.min + 1)**2 - 1) 143 elif self.min in (None, -inf): 144 self.from_internal = lambda val: self.max + 1 - sqrt(val*val + 1) 145 _val = sqrt((self.max - self._val + 1)**2 - 1) 146 else: 147 self.from_internal = lambda val: self.min + (sin(val) + 1) * \ 148 (self.max - self.min) / 2 149 _val = arcsin(2*(self._val - self.min)/(self.max - self.min) - 1) 150 return _val
151
152 - def scale_gradient(self, val):
153 """returns scaling factor for gradient the according to Minuit-style 154 transformation. 155 """ 156 if self.min in (None, -inf) and self.max in (None, inf): 157 return 1.0 158 elif self.max in (None, inf): 159 return val / sqrt(val*val + 1) 160 elif self.min in (None, -inf): 161 return -val / sqrt(val*val + 1) 162 else: 163 return cos(val) * (self.max - self.min) / 2.0
164 165
166 - def _getval(self):
167 """get value, with bounds applied""" 168 if (self._val is not nan and 169 isinstance(self._val, uncertainties.Variable)): 170 self._val = self._val.nominal_value 171 172 if self.min is None: 173 self.min = -inf 174 if self.max is None: 175 self.max = inf 176 if self.max < self.min: 177 self.max, self.min = self.min, self.max 178 179 try: 180 if self.min > -inf: 181 self._val = max(self.min, self._val) 182 if self.max < inf: 183 self._val = min(self.max, self._val) 184 except(TypeError, ValueError): 185 self._val = nan 186 return self._val
187 188 @property
189 - def value(self):
190 "get value" 191 return self._getval()
192 193 @value.setter
194 - def value(self, val):
195 "set value" 196 self._val = val
197 - def __str__(self):
198 "string" 199 return self.__repr__()
200
201 - def __abs__(self):
202 "abs" 203 return abs(self._getval())
204
205 - def __neg__(self):
206 "neg" 207 return -self._getval()
208
209 - def __pos__(self):
210 "positive" 211 return +self._getval()
212
213 - def __nonzero__(self):
214 "not zero" 215 return self._getval() != 0
216
217 - def __int__(self):
218 "int" 219 return int(self._getval())
220
221 - def __long__(self):
222 "long" 223 return long(self._getval())
224
225 - def __float__(self):
226 "float" 227 return float(self._getval())
228
229 - def __trunc__(self):
230 "trunc" 231 return self._getval().__trunc__()
232
233 - def __add__(self, other):
234 "+" 235 return self._getval() + other
236
237 - def __sub__(self, other):
238 "-" 239 return self._getval() - other
240
241 - def __div__(self, other):
242 "/" 243 return self._getval() / other
244 __truediv__ = __div__ 245
246 - def __floordiv__(self, other):
247 "//" 248 return self._getval() // other
249
250 - def __divmod__(self, other):
251 "divmod" 252 return divmod(self._getval(), other)
253
254 - def __mod__(self, other):
255 "%" 256 return self._getval() % other
257
258 - def __mul__(self, other):
259 "*" 260 return self._getval() * other
261
262 - def __pow__(self, other):
263 "**" 264 return self._getval() ** other
265
266 - def __gt__(self, other):
267 ">" 268 return self._getval() > other
269
270 - def __ge__(self, other):
271 ">=" 272 return self._getval() >= other
273
274 - def __le__(self, other):
275 "<=" 276 return self._getval() <= other
277
278 - def __lt__(self, other):
279 "<" 280 return self._getval() < other
281
282 - def __eq__(self, other):
283 "==" 284 return self._getval() == other
285 - def __ne__(self, other):
286 "!=" 287 return self._getval() != other
288
289 - def __radd__(self, other):
290 "+ (right)" 291 return other + self._getval()
292
293 - def __rdiv__(self, other):
294 "/ (right)" 295 return other / self._getval()
296 __rtruediv__ = __rdiv__ 297
298 - def __rdivmod__(self, other):
299 "divmod (right)" 300 return divmod(other, self._getval())
301
302 - def __rfloordiv__(self, other):
303 "// (right)" 304 return other // self._getval()
305
306 - def __rmod__(self, other):
307 "% (right)" 308 return other % self._getval()
309
310 - def __rmul__(self, other):
311 "* (right)" 312 return other * self._getval()
313
314 - def __rpow__(self, other):
315 "** (right)" 316 return other ** self._getval()
317
318 - def __rsub__(self, other):
319 "- (right)" 320 return other - self._getval()
321
322 -def isParameter(x):
323 "test for Parameter-ness" 324 return (isinstance(x, Parameter) or 325 x.__class__.__name__ == 'Parameter')
326