Package boxmin :: Package tests :: Module ModelParameters
[hide private]

Source Code for Module boxmin.tests.ModelParameters

  1  # This program is public domain. 
  2   
  3  ## \file 
  4  # \brief Parameter management class for box constrained fitting models 
  5  # 
  6   
  7  # TODO: Fix access by parameter name. 
  8  # TODO: Provide an easy way to save and restore sets of values. 
  9  # TODO: Consider using a single vector for all parameters (*) 
 10  # 
 11  # (*) When interacting with models written in C it will be convenient 
 12  # to pass a pointer to the list of parameters rather than going through 
 13  # a PyObject to double conversion on every parameter value. 
 14   
 15  from numpy import array 
 16   
17 -class ModelParameters:
18 """ 19 A model has a set of parameters associated with it. Each parameter 20 has a name, units and a value. To display fit results there is an 21 optional title separate from the name, and an expanded description 22 such as might show up in a tooltip for a fit user interface. 23 24 The value may be constrained by natural bounds such as depth greater 25 than zero or volume fraction between zero and one. The value may also 26 be constrained to be a discrete integer such as the number of repeats 27 in a layer model, though it is still represented by a double in the fit. 28 More complicated constraints such as interface depth less than layer depth 29 are not supported within the model parameter structure, though they may 30 be possible in some fitting engines. 31 32 A set of parameters with the same name, bounds, etc., can be represented 33 as a vector. 34 35 Within the model, start with a blank set of parameters and add them 36 one at a time using: 37 38 from numpy import array 39 from fit import ModelParameters 40 P = ModelParameters() 41 P.add('P1',array('d',[1]*5),tip='P1 is a vector of 5 elements') 42 P.add('P2',4,lo=0,hi=1,tip='P2 is bounded by [0,1]') 43 P.add('P3',5,discrete=True,tip='P3 is an integer defaulting to 5') 44 P.add('P4',3,units='cm',tip='P4 is measured in centimeters') 45 46 The values of the parameters can be accessed by name from the model: 47 48 P.P1[3] = 4. 49 P.P4 = 2 50 51 Note that declaring a parameter to be discrete doesn't force the value 52 to be integer. In fact it will be stored as a float, and the model will 53 have to force it to be an integer when it reads it. Not all fit engines 54 will handle discrete values properly. 55 56 The values can also be accessed by number: 57 P[0] = 4. 58 P[3] = 2 59 60 Other properties can also be accessed by number, such as title, tip 61 and bounds. 62 """ 63
64 - def add(self,name,value,units=None,lo=None,hi=None,discrete=False, 65 tip=None,title=None):
66 """Add a parameter to a model""" 67 if title==None: title = name 68 self.names.append(name) 69 self.value[name] = value 70 self.property.append({ 'units': units, 'lo': lo, 'hi': hi, 71 'discrete': discrete, 'tip': tip, 'title': title }) 72 return
73
74 - def bounds(self,n):
75 """Return (lo,hi) bounds for parameter n""" 76 p = self.property[n] 77 return (p['lo'],p['hi'])
78
79 - def name(self,n=None):
80 """Return the name of parameter n, or the list of all names""" 81 if n==None: L = self.names 82 else: L = self.names[n] 83 return L
84
85 - def title(self,n=None):
86 """Return title for parameter n or for the model if no n specified""" 87 if n == None: t = self.model_title 88 else: 89 p = self.property[n] 90 t = p['title'] 91 return t
92
93 - def tip(self,n=None):
94 """Return tip for parameter n or for the model if no n specified""" 95 if n == None: t = self.model_tip 96 else: 97 p = self.property[n] 98 t = p['tip'] 99 return t
100
101 - def units(self,n):
102 """Return units for parameter n""" 103 p = self.property[n] 104 return p['units']
105
106 - def discrete(self,n=None):
107 """Return the indices of discrete parameters, or True if parameter n is discrete""" 108 if n==None: 109 L=[] 110 for i in range(len(self.property)): 111 p = self.property[i] 112 if p['discrete']: L.append(i) 113 else: 114 p = self.property[n] 115 L = p['discrete'] 116 return L
117 118 # Make parameter P.a and P[n] work equivalently. Use P[n] from fit 119 # engine and P.a from model.
120 - def __len__(self):
121 return len(self.names)
122
123 - def __getitem__(self,n):
124 return self.value[self.names[n]]
125
126 - def __setitem__(self,n,v):
127 assert n < len(self.names),"invalid model parameter %d in %s" \ 128 % (n,self.model_title) 129 self.value[self.names[n]] = v
130
131 - def __delitem__(self,n):
132 assert n < len(self.names),"invalid model parameter %d in %s" \ 133 % (n,self.model_title) 134 n = self.names[n]
135
136 - def __get__(self,a):
137 return self.value[a]
138
139 - def __set__(self,a,v):
140 assert a in self.names,"invalid model parameter %s in %s" \ 141 % (a,self.model_title) 142 self.value[a] = v
143
144 - def __delete__(self,a):
145 assert a in self.names,"invalid model parameter %s in %s" \ 146 % (a,self.model_title) 147 del self.value[a] 148 del self.property[self.names.index(a)] 149 self.names.remove(a) 150 return
151
152 - def __contains__(self,a):
153 if isinstance(a,int): result = a < len(self.names) 154 else: result = a in self.names 155 return result
156
157 - def __init__(self,title,tip=None):
158 """Construct a set of model parameters""" 159 self.model_title=title 160 self.model_tip = tip 161 self.names = [] 162 self.value = {} 163 self.property = [] 164 return
165 166 # version 167 __id__ = "$Id: ModelParameters.py 70 2008-11-18 00:10:29Z pkienzle $" 168 169 # End of file 170