def _translate_up(self, text, node): if is_legal_name(text): return '.'.join([node, text]) expr = ExprEvaluator(text) varpath = expr.get_referenced_varpaths().pop() return transform_expression(text, { varpath: '.'.join([node, varpath]) })
def _create(self, target, low, high, scaler, adder, start, fd_step, key, scope): """ Create one Parameter or ArrayParameter. """ try: expreval = ExprEvaluator(target, scope) except Exception as err: raise err.__class__("Can't add parameter: %s" % err) if not expreval.is_valid_assignee(): raise ValueError("Can't add parameter: '%s' is not a" " valid parameter expression" % expreval.text) try: val = expreval.evaluate() except Exception as err: val = None # Let Parameter code sort out why. name = key[0] if isinstance(key, tuple) else key if isinstance(val, ndarray): return ArrayParameter(target, low=low, high=high, scaler=scaler, adder=adder, start=start, fd_step=fd_step, name=name, scope=scope, _expreval=expreval, _val=val, _allowed_types=self._allowed_types) else: return Parameter(target, low=low, high=high, scaler=scaler, adder=adder, start=start, fd_step=fd_step, name=name, scope=scope, _expreval=expreval, _val=val, _allowed_types=self._allowed_types)
def test_bogus(self): # now try some bogus expressions try: ex = ExprEvaluator('abcd.efg', self.top) ex.evaluate() except AttributeError, err: self.assertEqual(str(err), "can't evaluate expression 'abcd.efg': : object has no attribute 'abcd.efg'")
def _split_expr(text): """Take an expression string and return varpath, expr""" if text.startswith('@') or is_legal_name(text): return text, text expr = ExprEvaluator(text) return expr.get_referenced_varpaths().pop(), text
def make_graph(nodes=(), connections=()): scope = set_as_top(Assembly()) sub = scope.add('sub', Assembly()) dep = ExprMapper(sub) for name in nodes: if name.startswith('parent.'): scope.add(name.split('.', 1)[1], Simple()) else: sub.add(name, Simple()) #dep.add(name) for src, dest in connections: if '.' not in src and not sub.contains(src): if dest.startswith('parent.'): iotype = 'out' else: iotype = 'in' sub.add(src, Int(1, iotype=iotype)) if '.' not in dest and not sub.contains(dest): if src.startswith('parent.'): iotype = 'in' else: iotype = 'out' sub.add(dest, Int(1, iotype=iotype)) dep.connect(ExprEvaluator(src, sub), ExprEvaluator(dest, sub), sub) return dep, sub
def test_eq(self): ex1 = ExprEvaluator('comp.x', self.top) ex2 = ExprEvaluator('comp.x', self.top) ex3_bad = "test" self.assertTrue(ex1 == ex2) self.assertTrue(ex2 != ex3_bad)
def __init__(self, lhs, comparator, rhs, scope, jacs=None): self.lhs = ExprEvaluator(lhs, scope=scope) self._pseudo = None self.pcomp_name = None unresolved_vars = self.lhs.get_unresolved() if unresolved_vars: msg = "Left hand side of constraint '{0}' has invalid variables {1}" expression = ' '.join((lhs, comparator, rhs)) raise ExprEvaluator._invalid_expression_error(unresolved_vars, expr=expression, msg=msg) self.rhs = ExprEvaluator(rhs, scope=scope) unresolved_vars = self.rhs.get_unresolved() if unresolved_vars: msg = "Right hand side of constraint '{0}' has invalid variables {1}" expression = ' '.join((lhs, comparator, rhs)) raise ExprEvaluator._invalid_expression_error(unresolved_vars, expr=expression, msg=msg) self.comparator = comparator self._size = None # Linear flag: constraints are nonlinear by default self.linear = False # User-defined jacobian function self.jacs = jacs self._create_pseudo()
def _translate_up(self, text, node): """Upscoping""" if is_legal_name(text): return '.'.join([node, text]) expr = ExprEvaluator(text) varpath = expr.get_referenced_varpaths().pop() return transform_expression(text, { varpath: '.'.join([node, varpath]) })
def execute(self): """ Run each parameter set. """ # Prepare parameters and responses. exprs = {} case_paths = {} inputs = [] values = [] for path in self.get_parameters(): if isinstance(path, tuple): for target in path: inputs.append(target) if not is_legal_name(target): exprs[target] = ExprEvaluator(target) path = path[0] else: inputs.append(path) if not is_legal_name(path): exprs[path] = ExprEvaluator(path) path = make_legal_path(path) values.append(self.get('case_inputs.' + path)) for path in self.get_responses(): if not is_legal_name(path): exprs[path] = ExprEvaluator(path) case_paths[path] = make_legal_path(path) length = len(values[0]) if values else 0 self.init_responses(length) # Run each parameter set. for i in range(length): # Set inputs. for j, path in enumerate(inputs): value = values[j][i] expr = exprs.get(path) if expr: expr.set(value, self.parent) else: self.parent.set(path, value) # Run workflow. self.workflow.run() # Get outputs. for path in self.get_responses(): expr = exprs.get(path) if expr: value = expr.evaluate(self.parent) else: value = self.parent.get(path) path = case_paths[path] self.set('case_outputs.' + path, value, index=(i, ), force=True)
def __init__(self, target, high=None, low=None, scaler=None, adder=None, start=None, fd_step=None, scope=None, name=None, _expreval=None): """If scaler and/or adder are not None, then high, low, and start, if not None, are assumed to be expressed in unscaled form. If high and low are not supplied, then their values will be pulled from the target variable (along with a start value), and are assumed to be in scaled form, so their values will be unscaled prior to being stored in the Parameter. """ if scaler is None and adder is None: self._transform = self._do_nothing self._untransform = self._do_nothing if scaler is None: scaler = 1.0 if adder is None: adder = 0.0 self.low = low self.high = high self.scaler = scaler self.adder = adder self.start = start self.fd_step = fd_step self.name = name or target if _expreval is None: try: _expreval = ExprEvaluator(target, scope) except Exception as err: raise err.__class__("Can't add parameter: %s" % str(err)) if not _expreval.is_valid_assignee(): raise ValueError("Can't add parameter: '%s' is not a valid" " parameter expression" % _expreval.text) self._expreval = _expreval try: self._metadata = self._expreval.get_metadata() except AttributeError: raise AttributeError("Can't add parameter '%s' because it doesn't" " exist." % target) # 'raw' metadata is in the form [(varname, metadata)], # so use [0][1] to get the actual metadata dict metadata = self._metadata[0][1] if 'iotype' in metadata and metadata['iotype'] == 'out': raise RuntimeError("Can't add parameter '%s' because '%s' is an" " output." % (target, target)) try: # So, our traits might not have a vartypename? self.vartypename = metadata['vartypename'] except KeyError: self.vartypename = None
def test_bogus(self): # now try some bogus expressions try: ex = ExprEvaluator('abcd.efg', self.top) ex.evaluate() except AttributeError, err: self.assertEqual(str(err), "can't evaluate expression 'abcd.efg':" " : name 'abcd' is not defined")
def test_scope_transform(self): exp = ExprEvaluator('myvar+abs(comp.x)*a.a1d[2]', self.top) self.assertEqual(new_text(exp), "scope.get('myvar')+abs(scope.get('comp.x'))*scope.get('a.a1d',[(0,2)])") xformed = exp.scope_transform(self.top, self.top.comp) self.assertEqual(xformed, 'parent.myvar+abs(x)*parent.a.a1d[2]') exp = ExprEvaluator('parent.var+abs(x)*parent.a.a1d[2]', self.top.comp) xformed = exp.scope_transform(self.top.comp, self.top) self.assertEqual(xformed, 'var+abs(comp.x)*a.a1d[2]')
def test_multi_object(self): # verify that expressions with multiple objects raise a reasonable error message # when a set is attempted. try: ex = ExprEvaluator('comp.x+comp.x', self.top) ex.set(1) except ValueError, err: self.assertEqual( str(err), "expression 'comp.x+comp.x' can't be set to a value")
def test_bogus(self): # now try some bogus expressions try: ex = ExprEvaluator('abcd.efg', self.top) ex.evaluate() except AttributeError, err: self.assertEqual(str(err), "can't evaluate expression 'abcd.efg':" " : 'Assembly' object has no attribute 'abcd'")
def test_multi_object(self): # verify that expressions with multiple objects raise a reasonable error message # when a set is attempted. try: ex = ExprEvaluator('comp.x+comp.x', self.top) ex.set(1) except ValueError, err: self.assertEqual(str(err), "expression 'comp.x+comp.x' can't be set to a value")
def test_no_scope(self): ex = ExprEvaluator('abs(-3)+int(2.3)+math.floor(5.4)') self.assertEqual(ex.evaluate(), 10.0) ex.text = 'comp.x' try: ex.evaluate() except Exception, err: self.assertEqual(str(err), "can't evaluate expression 'comp.x': expression has no scope")
def test_eval_gradient_array(self): top = set_as_top(Assembly()) top.add('comp1', A()) top.run() # Uncomment these when arrays work exp = ExprEvaluator('4.0*comp1.b2d[0][1]*comp1.b2d[1][1]', top.driver) grad = exp.evaluate_gradient(scope=top) assert_rel_error(self, grad['comp1.b2d[0][1]'], 12.0, 0.00001) assert_rel_error(self, grad['comp1.b2d[1][1]'], 4.0, 0.00001)
def test_bogus(self): # now try some bogus expressions try: ex = ExprEvaluator('abcd.efg', self.top) ex.evaluate() except AttributeError, err: self.assertEqual( str(err), "can't evaluate expression 'abcd.efg':" " : name 'abcd' is not defined")
def test_no_scope(self): ex = ExprEvaluator('abs(-3)+int(2.3)+math.floor(5.4)') self.assertEqual(ex.evaluate(), 10.0) ex.text = 'comp.x' try: ex.evaluate() except Exception, err: self.assertEqual(str(err), "can't evaluate expression 'comp.x':" " 'NoneType' object has no attribute 'get'")
def test_resolve(self): ex = ExprEvaluator('comp.x[0] = 10*(3.2+ a.a1d[3]* 1.1*a.a1d[2 ])', self.top) self.assertEqual(ex.check_resolve(), True) ex.text = 'comp.contlist[1].a2d[2][1]' self.assertEqual(ex.check_resolve(), True) ex.scope = self.top.comp ex.text = 'contlist[1]' self.assertEqual(ex.check_resolve(), True) ex.text = 'contlist[1]-foo.flambe' self.assertEqual(ex.check_resolve(), False)
def test_eval_gradient_lots_of_vars(self): top = set_as_top(Assembly()) top.add('comp1', B()) #build expr expr = "2*comp1.in1 + 3*comp1.in11" exp = ExprEvaluator(expr, top.driver) grad = exp.evaluate_gradient(scope=top) assert_rel_error(self, grad['comp1.in1'], 2.0, 0.00001) assert_rel_error(self, grad['comp1.in11'], 3.0, 0.00001)
def __init__(self, exprs=(), derivatives=(), sleep=0, dsleep=0): super(ExecCompWithDerivatives, self).__init__() ins = set() outs = set() allvars = set() self.exprs = exprs self.codes = [compile(expr,'<string>','exec') for expr in exprs] self.sleep = sleep self.dsleep = dsleep for expr in exprs: lhs,rhs = expr.split('=') lhs = lhs.strip() lhs = lhs.split(',') outs.update(lhs) expreval = ExprEvaluator(expr, scope=self) allvars.update(expreval.get_referenced_varpaths(copy=False)) ins = allvars - outs for var in allvars: if '.' not in var: # if a varname has dots, it's outside of our scope, # so don't add a trait for it if var in outs: iotype = 'out' else: iotype = 'in' self.add(var, Float(0.0, iotype=iotype)) self.deriv_exprs = derivatives self.derivative_codes = \ [compile(expr,'<string>','exec') for expr in derivatives] self.derivative_names = [] regex = re.compile('d(.*)_d(.*)') for expr in derivatives: expreval = ExprEvaluator(expr, scope=self) exvars = expreval.get_referenced_varpaths(copy=False) lhs, _ = expr.split('=') lhs = lhs.strip() allvars.add(lhs) # Check for undefined vars the cool way with sets if len(exvars-allvars) > 0: self.raise_exception('derivative references a variable ' 'that is not defined in exprs', ValueError) names = regex.findall(lhs) num = names[0][0] wrt = names[0][1] self.derivatives.declare_first_derivative(num, wrt) self.derivative_names.append( (lhs, num, wrt) )
def __init__(self, target, high=None, low=None, scaler=None, adder=None, start=None, fd_step=None, scope=None, name=None, _expreval=None): """If scaler and/or adder are not None, then high, low, and start, if not None, are assumed to be expressed in unscaled form. If high and low are not supplied, then their values will be pulled from the target variable (along with a start value), and are assumed to be in scaled form, so their values will be unscaled prior to being stored in the Parameter. """ if scaler is None: scaler = 1.0 if adder is None: adder = 0.0 self._scaling_required = scaler != 1. or adder != 0. self.low = low self.high = high self.scaler = scaler self.adder = adder self.start = start self.fd_step = fd_step self.name = name or target if _expreval is None: try: _expreval = ExprEvaluator(target, scope) except Exception as err: raise err.__class__("Can't add parameter: %s" % str(err)) if not _expreval.is_valid_assignee(): raise ValueError("Can't add parameter: '%s' is not a valid" " parameter expression" % _expreval.text) self._expreval = _expreval try: self._metadata = self._expreval.get_metadata() except AttributeError: raise AttributeError("Can't add parameter '%s' because it doesn't" " exist." % target) # 'raw' metadata is in the form [(varname, metadata)], # so use [0][1] to get the actual metadata dict metadata = self._metadata[0][1] if 'iotype' in metadata and metadata['iotype'] == 'out': raise RuntimeError("Can't add parameter '%s' because '%s' is an" " output." % (target, target)) try: # So, our traits might not have a vartypename? self.vartypename = metadata['vartypename'] except KeyError: self.vartypename = None
def test_slice(self): ex = ExprEvaluator('a1d[1::2]', self.top.a) self.assertTrue(all(numpy.array([2.,4.,6.]) == ex.evaluate())) ex.text = 'a1d[2:4]' self.assertTrue(all(numpy.array([3.,4.]) == ex.evaluate())) ex.text = 'a1d[2:]' self.assertTrue(all(numpy.array([3.,4.,5.,6.]) == ex.evaluate())) ex.text = 'a1d[::-1]' self.assertTrue(all(numpy.array([6.,5.,4.,3.,2.,1.]) == ex.evaluate())) ex.text = 'a1d[:2]' self.assertTrue(all(numpy.array([1.,2.]) == ex.evaluate()))
def __init__(self, lhs, comparator, rhs, scope): self.lhs = ExprEvaluator(lhs, scope=scope) if not self.lhs.check_resolve(): raise ValueError("Constraint '%s' has an invalid left-hand-side." % ' '.join([lhs, comparator, rhs])) self.comparator = comparator self.rhs = ExprEvaluator(rhs, scope=scope) if not self.rhs.check_resolve(): raise ValueError("Constraint '%s' has an invalid right-hand-side." % ' '.join([lhs, comparator, rhs])) self.pcomp_name = None self._size = None
def test_get_referenced_varpaths(self): ex = ExprEvaluator('comp.x[0] = 10*(3.2+ a.a1d[3]* 1.1*a.a1d[2 ])', self.top.a) self.assertEqual(ex.get_referenced_varpaths(), set(['comp.x', 'a.a1d'])) ex.text = 'comp.contlist[1].a2d[2][1]' self.assertEqual(ex.get_referenced_varpaths(), set(['comp.contlist'])) ex.scope = self.top.comp ex.text = 'comp.contlist[1]' self.assertEqual(ex.get_referenced_varpaths(), set(['comp.contlist']))
def test_get_referenced_varpaths(self): ex = ExprEvaluator('comp.x[0] = 10*(3.2+ a.a1d[3]* 1.1*a.a1d[2 ])', self.top.a) self.assertEqual(ex.get_referenced_varpaths(), set(['comp.x','a.a1d'])) ex.text = 'comp.contlist[1].a2d[2][1]' self.assertEqual(ex.get_referenced_varpaths(), set(['comp.contlist'])) ex.scope = self.top.comp ex.text = 'comp.contlist[1]' self.assertEqual(ex.get_referenced_varpaths(), set(['comp.contlist']))
def _register_expr(self, s): """If the given string contains an expression, create an ExprEvaluator and store it in self._exprs """ match = _namecheck_rgx.match(s) if match is None or match.group() != s: expr = ExprEvaluator(s) if self._exprs is None: self._exprs = {} self._exprs[s] = expr
def add_objective(self, expr, name=None, scope=None): """Adds an objective to the driver. expr: string String containing the objective expression. name: string (optional) Name to be used to refer to the objective in place of the expression string. scope: object (optional) The object to be used as the scope when evaluating the expression. """ if self._max_objectives > 0 and len( self._objectives) >= self._max_objectives: self._parent.raise_exception( "Can't add objective '%s'. Only %d objectives are allowed" % (expr, self._max_objectives), RuntimeError) expr = _remove_spaces(expr) if expr in self._objectives: self._parent.raise_exception( "Trying to add objective " "'%s' to driver, but it's already there" % expr, AttributeError) if name is not None and name in self._objectives: self._parent.raise_exception( "Trying to add objective " "'%s' to driver using name '%s', but name is already used" % (expr, name), AttributeError) expreval = ExprEvaluator(expr, self._get_scope(scope)) if not expreval.check_resolve(): self._parent.raise_exception( "Can't add objective because I can't evaluate '%s'." % expr, ValueError) if name is None: self._objectives[expr] = expreval else: self._objectives[name] = expreval
class Constraint(object): """ Object that stores info for a single constraint. """ def __init__(self, lhs, comparator, rhs, scaler, adder, scope=None): self.lhs = ExprEvaluator(lhs, scope=scope) if not self.lhs.check_resolve(): raise ValueError("Constraint '%s' has an invalid left-hand-side." \ % ' '.join([lhs, comparator, rhs])) self.comparator = comparator self.rhs = ExprEvaluator(rhs, scope=scope) if not self.rhs.check_resolve(): raise ValueError("Constraint '%s' has an invalid right-hand-side." \ % ' '.join([lhs, comparator, rhs])) if not isinstance(scaler, float): raise ValueError("Scaler parameter should be a float") self.scaler = scaler if scaler <= 0.0: raise ValueError("Scaler parameter should be a float > 0") if not isinstance(adder, float): raise ValueError("Adder parameter should be a float") self.adder = adder def evaluate(self, scope): """Returns a tuple of the form (lhs, rhs, comparator, is_violated).""" lhs = (self.lhs.evaluate(scope) + self.adder)*self.scaler rhs = (self.rhs.evaluate(scope) + self.adder)*self.scaler return (lhs, rhs, self.comparator, not _ops[self.comparator](lhs, rhs)) def evaluate_gradient(self, scope, stepsize=1.0e-6, wrt=None): """Returns the gradient of the constraint eq/inep as a tuple of the form (lhs, rhs, comparator, is_violated).""" lhs = self.lhs.evaluate_gradient(scope=scope, stepsize=stepsize, wrt=wrt) for key, value in lhs.iteritems(): lhs[key] = (value + self.adder)*self.scaler rhs = self.rhs.evaluate_gradient(scope=scope, stepsize=stepsize, wrt=wrt) for key, value in rhs.iteritems(): rhs[key] = (value + self.adder)*self.scaler return (lhs, rhs, self.comparator, not _ops[self.comparator](lhs, rhs)) def get_referenced_compnames(self): return self.lhs.get_referenced_compnames().union(self.rhs.get_referenced_compnames()) def __str__(self): return ' '.join([self.lhs.text, self.comparator, self.rhs.text])
def __init__(self, lhs, comparator, rhs, scaler, adder, scope=None): self.lhs = ExprEvaluator(lhs, scope=scope) if not self.lhs.check_resolve(): raise ValueError("Constraint '%s' has an invalid left-hand-side." \ % ' '.join([lhs, comparator, rhs])) self.comparator = comparator self.rhs = ExprEvaluator(rhs, scope=scope) if not self.rhs.check_resolve(): raise ValueError("Constraint '%s' has an invalid right-hand-side." \ % ' '.join([lhs, comparator, rhs])) if not isinstance(scaler, float): raise ValueError("Scaler parameter should be a float") self.scaler = scaler if scaler <= 0.0: raise ValueError("Scaler parameter should be a float > 0") if not isinstance(adder, float): raise ValueError("Adder parameter should be a float") self.adder = adder
def __init__(self, exprs=()): super(ExecComp, self).__init__() ins = set() outs = set() allvars = set() self.codes = [compile(expr,'<string>','exec') for expr in exprs] for expr in exprs: lhs,rhs = expr.split('=') lhs = lhs.strip() lhs = lhs.split(',') outs.update(lhs) expreval = ExprEvaluator(expr, scope=self) allvars.update(expreval.get_referenced_varpaths(copy=False)) ins = allvars - outs for var in allvars: if '.' not in var: # if a varname has dots, it's outside of our scope, # so don't add a trait for it if var in outs: iotype = 'out' else: iotype = 'in' self.add(var, Float(iotype=iotype))
def add_objective(self, expr, name=None, scope=None): """Adds an objective to the driver. expr: string String containing the objective expression. name: string (optional) Name to be used to refer to the objective in place of the expression string. scope: object (optional) The object to be used as the scope when evaluating the expression. """ if self._max_objectives > 0 and len(self._objectives) >= self._max_objectives: self._parent.raise_exception("Can't add objective '%s'. Only %d objectives are allowed" % (expr,self._max_objectives), RuntimeError) expr = _remove_spaces(expr) if expr in self._objectives: self._parent.raise_exception("Trying to add objective " "'%s' to driver, but it's already there" % expr, AttributeError) if name is not None and name in self._objectives: self._parent.raise_exception("Trying to add objective " "'%s' to driver using name '%s', but name is already used" % (expr,name), AttributeError) expreval = ExprEvaluator(expr, self._get_scope(scope)) if not expreval.check_resolve(): self._parent.raise_exception("Can't add objective because I can't evaluate '%s'." % expr, ValueError) if name is None: self._objectives[expr] = expreval else: self._objectives[name] = expreval self._parent._invalidate()
def test_get_required_comps(self): top = set_as_top(Assembly()) top.add('comp1', Simple()) top.add('comp2', Simple()) top.add('comp3', Simple()) top.add('comp4', Simple()) top.add('comp5', Simple()) top.add('comp6', Simple()) top.add('comp7', Simple()) top.add('comp8', Simple()) top.add('comp9', Simple()) top.connect('comp1.c','comp3.a') top.connect('comp2.c','comp3.b') top.connect('comp3.c','comp5.a') top.connect('comp3.d','comp9.a') top.connect('comp3.d','comp4.a') top.connect('comp4.c','comp7.a') top.connect('comp3.c','comp6.a') top.connect('comp6.c','comp7.b') top.connect('comp8.c','comp9.b') exp = ExprEvaluator('comp9.c+comp5.d', top.driver) self.assertEqual(exp.get_required_compnames(top), set(['comp1','comp2','comp3','comp5','comp8','comp9'])) exp = ExprEvaluator('comp7.a', top.driver) self.assertEqual(exp.get_required_compnames(top), set(['comp1','comp2','comp3','comp4','comp6','comp7'])) exp = ExprEvaluator('comp8.a', top.driver) self.assertEqual(exp.get_required_compnames(top), set(['comp8'])) exp = ExprEvaluator('comp9.c+comp7.d', top.driver) self.assertEqual(exp.get_required_compnames(top), set(['comp1','comp2','comp3','comp4','comp6', 'comp7','comp8','comp9'])) exp = ExprEvaluator('sin(0.3)', top.driver) self.assertEqual(exp.get_required_compnames(top), set())
def __init__(self, lhs, comparator, rhs, scope): self.lhs = ExprEvaluator(lhs, scope=scope) unresolved_vars = self.lhs.get_unresolved() if unresolved_vars: msg = "Left hand side of constraint '{0}' has invalid variables {1}" expression = ' '.join([lhs, comparator, rhs]) raise ExprEvaluator._invalid_expression_error(unresolved_vars, expr=expression, msg=msg) self.rhs = ExprEvaluator(rhs, scope=scope) unresolved_vars = self.rhs.get_unresolved() if unresolved_vars: msg = "Right hand side of constraint '{0}' has invalid variables {1}" expression = ' '.join([lhs, comparator, rhs]) raise ExprEvaluator._invalid_expression_error(unresolved_vars, expr=expression, msg=msg) self.comparator = comparator self.pcomp_name = None self._size = None
def ensure_init(self): """Make sure our inputs and outputs have been initialized. """ # set the current value of the connected variable # into our input for ref, in_name in self._inmap.items(): setattr(self, in_name, ExprEvaluator(ref).evaluate(self.parent)) if has_interface(getattr(self, in_name), IContainer): getattr(self, in_name).name = in_name # set the initial value of the output outval = self._srcexpr.evaluate() setattr(self, 'out0', outval)
def __init__(self, exprs=(), sleep=0): super(ExecComp, self).__init__() ins = set() outs = set() allvars = set() self.exprs = exprs self.codes = [compile(expr, "<string>", "exec") for expr in exprs] self.sleep = sleep for expr in exprs: lhs, rhs = expr.split("=") lhs = lhs.strip() lhs = lhs.split(",") outs.update(lhs) expreval = ExprEvaluator(expr, scope=self) allvars.update(expreval.get_referenced_varpaths(copy=False)) ins = allvars - outs for var in allvars: if "." not in var: # if a varname has dots, it's outside of our scope, # so don't add a trait for it if var in outs: iotype = "out" else: iotype = "in" self.add(var, Float(0.0, iotype=iotype))
def __init__(self, exprs=(), sleep=0, trace=False): super(ExecComp, self).__init__() outs = set() allvars = set() self.exprs = exprs self.codes = [compile(expr, '<string>', 'exec') for expr in exprs] self.sleep = sleep self.trace = trace for expr in exprs: lhs, rhs = expr.split('=') lhs = lhs.strip() lhs = lhs.split(',') outs.update(lhs) expreval = ExprEvaluator(expr, scope=self) allvars.update(expreval.get_referenced_varpaths(copy=False)) for var in allvars: if '.' not in var: # if a varname has dots, it's outside of our scope, # so don't add a trait for it if var in outs: iotype = 'out' else: iotype = 'in' self.add(var, Float(0.0, iotype=iotype))
def test_no_scope(self): ex = ExprEvaluator('abs(-3)+int(2.3)+math.floor(5.4)') self.assertEqual(ex.evaluate(), 10.0) ex.text = 'comp.x' try: ex.evaluate() except Exception, err: self.assertEqual( str(err), "can't evaluate expression 'comp.x': expression has no scope")
def test_builtins(self): comp = self.top.comp comp.x = 1. comp.y = -3. self.assertEqual(3., ExprEvaluator('abs(comp.y)', self.top).evaluate()) self.assertAlmostEqual(0., ExprEvaluator('sin(pi)', self.top).evaluate()) comp.x = 1.35 self.assertEqual(1., ExprEvaluator('floor(comp.x)', self.top).evaluate()) self.assertEqual(2., ExprEvaluator('ceil(comp.x)', self.top).evaluate()) comp.x = 0. self.assertEqual(True, ExprEvaluator('sin(comp.x)<math.cos(comp.x)', self.top).evaluate()) comp.x = math.pi / 2. self.assertEqual(False, ExprEvaluator('sin(comp.x)<cos(comp.x)', self.top).evaluate())
def test_eval_gradient_array(self): top = set_as_top(Assembly()) top.add('comp1', A()) top.run() # Uncomment these when arrays work exp = ExprEvaluator('4.0*comp1.b2d[0][1]*comp1.b2d[1][1]', top.driver) grad = exp.evaluate_gradient(scope=top) assert_rel_error(self, grad['comp1.b2d[0][1]'], 12.0, 0.00001) assert_rel_error(self, grad['comp1.b2d[1][1]'], 4.0, 0.00001) exp = ExprEvaluator('comp1.c2d**2', top.driver) grad = exp.evaluate_gradient(scope=top) assert_rel_error(self, grad['comp1.c2d'][0,0], 0.0, 0.00001) assert_rel_error(self, grad['comp1.c2d'][1,1], 2.0, 0.00001) assert_rel_error(self, grad['comp1.c2d'][2,2], 4.0, 0.00001) assert_rel_error(self, grad['comp1.c2d'][3,3], 6.0, 0.00001) exp = ExprEvaluator('comp1.c1d**2', top.driver) grad = exp.evaluate_gradient(scope=top) assert_rel_error(self, grad['comp1.c1d'][0,0], 0.0, 0.00001) assert_rel_error(self, grad['comp1.c1d'][1,1], 2.0, 0.00001) assert_rel_error(self, grad['comp1.c1d'][2,2], 4.0, 0.00001) assert_rel_error(self, grad['comp1.c1d'][3,3], 6.0, 0.00001) exp = ExprEvaluator('comp1.a2d + comp1.c2d**2', top.driver) grad = exp.evaluate_gradient(scope=top) a2d_grad, c2d_grad = grad['comp1.a2d'], grad['comp1.c2d'] assert_rel_error(self, a2d_grad[0,0], 1.0, 0.00001) assert_rel_error(self, a2d_grad[1,1], 1.0, 0.00001) assert_rel_error(self, a2d_grad[2,2], 1.0, 0.00001) assert_rel_error(self, a2d_grad[3,3], 1.0, 0.00001) assert_rel_error(self, c2d_grad[0,0], 0.0, 0.00001) assert_rel_error(self, c2d_grad[1,1], 2.0, 0.00001) assert_rel_error(self, c2d_grad[2,2], 4.0, 0.00001) assert_rel_error(self, c2d_grad[3,3], 6.0, 0.00001)
def test_eval_gradient_lots_of_vars(self): top = set_as_top(Assembly()) top.add('comp1', B()) #build expr expr = "2*comp1.in1 + 3*comp1.in11" exp = ExprEvaluator(expr, top.driver) grad = exp.evaluate_gradient(scope=top) assert_rel_error(self, grad['comp1.in1'], 2.0, 0.00001) assert_rel_error(self, grad['comp1.in11'], 3.0, 0.00001) expr = "asin(comp1.in1)" exp = ExprEvaluator(expr, top.driver) grad = exp.evaluate_gradient(scope=top) assert_rel_error(self, grad['comp1.in1'], 1.0, 0.00001)
class Constraint(object): """ Object that stores info for a single constraint. """ def __init__(self, lhs, comparator, rhs, scaler, adder, scope=None): self.lhs = ExprEvaluator(lhs, scope=scope) if not self.lhs.check_resolve(): raise ValueError("Constraint '%s' has an invalid left-hand-side." \ % ' '.join([lhs, comparator, rhs])) self.comparator = comparator self.rhs = ExprEvaluator(rhs, scope=scope) if not self.rhs.check_resolve(): raise ValueError("Constraint '%s' has an invalid right-hand-side." \ % ' '.join([lhs, comparator, rhs])) if not isinstance(scaler, float): raise ValueError("Scaler parameter should be a float") self.scaler = scaler if scaler <= 0.0: raise ValueError("Scaler parameter should be a float > 0") if not isinstance(adder, float): raise ValueError("Adder parameter should be a float") self.adder = adder def evaluate(self, scope): """Returns a tuple of the form (lhs, rhs, comparator, is_violated).""" lhs = (self.lhs.evaluate(scope) + self.adder) * self.scaler rhs = (self.rhs.evaluate(scope) + self.adder) * self.scaler return (lhs, rhs, self.comparator, not _ops[self.comparator](lhs, rhs)) def get_referenced_compnames(self): return self.lhs.get_referenced_compnames().union( self.rhs.get_referenced_compnames()) def __str__(self): return ' '.join([self.lhs.text, self.comparator, self.rhs.text])
def _overspeed_str_changed(self, oldval, newval): self._overspeed_str_expr = ExprEvaluator(newval, scope=self.parent)
def _acceleration_str_changed(self, oldval, newval): self._acceleration_str_expr = ExprEvaluator(newval, scope=self.parent)
def _gear_str_changed(self, oldval, newval): self._gear_str_expr = ExprEvaluator(newval, scope=self.parent)
def _throttle_str_changed(self, oldval, newval): self._throttle_str_expr = ExprEvaluator(newval, scope=self.parent)