|
Package parasol ::
Module parameters
|
|
1
2 __author__ = "Charlie Taylor (charlietaylor@sourceforge.net)"
3 __version__ = " 1.0 "
4 __date__ = "Jan 1, 2009"
5 __copyright__ = "Copyright (c) 2009 Charlie Taylor"
6 __license__ = "BSD"
7
8 from Goal import Goal
9 from cast import floatDammit, intDammit
10 from scipy.optimize import fminbound
11
12 POS_INF = 1.0E300
13 NEG_INF = -1.0E300
14
15
17 '''
18 A MinMaxPair is a paired InputParam and OutputParam
19 where the val property of the InputParam is found
20 such that the val property of the OutputParam is minimized
21 or maximized for the mathematical model under consideration
22 (i.e. as modeled by the function call, functionToCall).
23
24 @note: The InputParam's val property will be found in the range minVal to maxVal
25 such that OutputParam.val is optimized when calling functionToCall
26 (i.e. a Min/Max constraint is applied to the parameter pair).
27
28 @note: It is the users responsibility to assure that InputParam.val is used
29 in functionToCall
30 AND that functionToCall reassigns the val property of OutputParam
31 '''
32 - def __init__(self, inpParam=None, outParam=None, functionToCall=None,
33 findmin=0, tolerance=1.0E-6, maxLoops=400, failValue=None):
34
35 '''Initialize parameter properties
36
37 @param inpParam: input parameter object (InputParam)
38 @param outParam: output parameter object (OutputParam)
39 @param functionToCall: function using InputParam to calc OutputParam (callable)
40 @param findmin: findmin is a logic flag (1=minimize, 0=maximize) (int)
41 @param tolerance: allowable error of OutputParam.val (float)
42 @param maxLoops: maximum loops in root solver
43 @param failValue: returned value if solution attempt fails,
44 (if not input use inpParam.minVal)
45 '''
46 self.inpParam = inpParam
47 self.outParam = outParam
48 self.functionToCall = functionToCall
49 self.findmin = floatDammit(findmin)
50 self.tolerance = floatDammit(tolerance)
51 self.maxLoops = intDammit(maxLoops)
52
53 if failValue==None:
54 failValue = inpParam.minVal
55 self.failValue = failValue
56
57
59 self.inpParam.val = val
60 self.functionToCall()
61
62
63
64 if self.findmin:
65 return self.outParam.val
66 else:
67 return -1.0 * self.outParam.val
68
70 '''calculate the value of inpParam.val that optimizes outParam.val
71 Show non-convergence notification messages if applicable.
72 '''
73
74 val, fval, ierror, numFuncCalls = fminbound(self.optFunc,
75 self.inpParam.minVal, self.inpParam.maxVal,
76 args=(), xtol=self.tolerance, maxfun=self.maxLoops, full_output=1, disp=1)
77
78
79
80 if ierror:
81 self.inpParam.val = floatDammit(self.failValue)
82 else:
83 self.inpParam.val = val
84
85
87 '''
88 A FeasiblePair is a paired InputParam and OutputParam
89 where the val property of the InputParam is found
90 such that the val property of the OutputParam is equal to
91 the desired feasibleVal for the mathematical model under consideration
92 (i.e. as modeled by the function call, functionToCall).
93
94 @note: The InputParam's val property will be found in the range minVal to maxVal
95 such that OutputParam.val==feasibleVal when calling functionToCall
96 (i.e. A Feasibilty constraint is applied to the parameter pair).
97
98 @note: It is the users responsibility to assure that InputParam.val is used
99 in functionToCall
100 AND that functionToCall reassigns the val property of OutputParam
101 '''
102 - def __init__(self, inpParam=None, outParam=None, functionToCall=None,
103 feasibleVal=0.0, tolerance=1.0E-6, maxLoops=40, failValue=None):
104
105 '''Initialize parameter properties
106
107 @param inpParam: input parameter object (InputParam)
108 @param outParam: output parameter object (OutputParam)
109 @param functionToCall: function using InputParam to calc OutputParam (callable)
110 @param feasibleVal: feasible value that OutputParam Must have (float)
111 @param tolerance: allowable error of OutputParam.val (float)
112 @param maxLoops: maximum loops in root solver
113 @param failValue: returned value if solution attempt fails,
114 (if not input use inpParam.minVal)
115 '''
116 self.inpParam = inpParam
117 self.outParam = outParam
118 self.functionToCall = functionToCall
119 self.feasibleVal = floatDammit(feasibleVal)
120 self.tolerance = floatDammit(tolerance)
121 self.maxLoops = intDammit(maxLoops)
122
123 if failValue==None:
124 failValue = inpParam.minVal
125 self.failValue = failValue
126
127 self.G = Goal(goalVal=feasibleVal, minX=inpParam.minVal, maxX=inpParam.maxVal,
128 funcOfX=self.feasibleFunc, tolerance=tolerance, maxLoops=maxLoops, failValue=failValue)
129
131 self.inpParam.val = val
132 self.functionToCall()
133 return self.outParam.val
134
136 '''calculate the value of inpParam.val that gives feasibleVal==outParam.val'''
137
138 val, ierror = self.G()
139 if ierror:
140 self.inpParam.val = floatDammit(self.failValue)
141 else:
142 self.inpParam.val = val
143
145 '''
146 Generic Output Parameter.
147
148 Output Parameter has a current value and limit values.
149
150 @note: If loLimit and hiLimit are reversed, they are corrected;
151 Their default values are effectively at negative and positive infinity.
152
153 @note: If assigning val, limits are NOT checked, however,
154 "inRange" function will return false; this is because out-of-range
155 assignments are allowed and expected.
156 '''
157 - def __init__(self, name='a', description='speed of sound', units='ft/sec',
158 val=1.0, loLimit=NEG_INF, hiLimit=POS_INF):
159
160 '''Initialize parameter properties
161
162 @param name: simple name (str)
163 @param description: long description (str)
164 @param units: physical units; Blank string if no units (str)
165 @param val: current numeric value (float)
166 @param loLimit: lower limit value (float)
167 @param hiLimit: upper limit value value (float)
168 '''
169
170
171 if loLimit > hiLimit:
172 loLimit, hiLimit = hiLimit, loLimit
173
174 self.name = name
175 self.description = description
176 self.units = units
177 self.val = floatDammit(val)
178 self.loLimit = floatDammit(loLimit)
179 self.hiLimit = floatDammit(hiLimit)
180
182 '''returns True if val is within limits, False otherwise'''
183 return self.val>=self.loLimit and self.val<=self.hiLimit
184
186 '''returns True if loLimit is > NEG_INF'''
187 return self.loLimit > NEG_INF
188
190 '''returns True if hiLimit is < POS_INF'''
191 return self.hiLimit < POS_INF
192
195
196
304
305 if __name__ == "__main__":
306
307 IP = InputParam(name='a', description='speed of sound', units='ft/sec',
308 val=1.0, minVal=1000.0, maxVal=6000.0, NSteps=5, stepVal=None, linear=1)
309 print 'check linear range'
310 print IP.rangeL
311
312 print 'check output param'
313 OP = OutputParam(name='delay', description='delay in sound arrival', units='sec',
314 val=1.0, loLimit=1.0, hiLimit=10.0)
315
316 OP.val = 0.0
317 print OP.val,'within limits=',OP.inRange()
318
319 print
320 print 'checking feasible pair'
322 OP.val = 7000./IP.val
323 return
324
325 FP = FeasiblePair( inpParam=IP, outParam=OP, functionToCall=feasTest,
326 feasibleVal=5.0, tolerance=1.0E-6, maxLoops=40, failValue=None)
327 FP.reCalc()
328 print 'for IP.val=',IP.val,'OP.val=',OP.val,'IP.val should be 1400.0'
329
330
331 print
332 print 'checking min/max pair'
334 x = (IP.val-1000.0)/1000.0
335 OP.val = 10.0 * (x**2 - x**3)
336 return
337
338 MP = MinMaxPair( inpParam=IP, outParam=OP, functionToCall=minmaxTest,
339 findmin=0, tolerance=1.0E-6, maxLoops=400, failValue=None)
340 MP.reCalc()
341 print 'for IP.val=',IP.val,'OP.val=',OP.val,'IP.val should be 1666.666...'
342