def rhs_name_transform_inplace(self, name_map): """Replace atoms on the RHS with values in the name_map""" for name in name_map: replacment = name_map[name] self.rhs = MathUtil.str_expr_replacement(name, replacment, self.rhs)
def __init__(self, ode, parent_regime): self.parent_regime = parent_regime parent_component = parent_regime.parent_component name_map = parent_component.name_map self.dependent_variable = ode.dependent_variable rhs = MathUtil.get_rhs_substituted(ode, name_map) self.CODE = name_map[ode.dependent_variable] + " += (" + rhs + ")*h;"
def __init__(self, assignment, parent_trans): self.parent_trans = parent_trans self.assginment = assignment parent_component = parent_trans.parent_component name_map = parent_component.name_map rhs = MathUtil.get_rhs_substituted( assignment, name_map ) self.CODE = name_map[assignment.lhs]+" = "+rhs+";"
def __init__(self, assignment, parent_trans): self.parent_trans = parent_trans self.assginment = assignment parent_component = parent_trans.parent_component name_map = parent_component.name_map rhs = MathUtil.get_rhs_substituted(assignment, name_map) self.CODE = name_map[assignment.lhs] + " = " + rhs + ";"
def __init__(self, ode, parent_regime): self.parent_regime = parent_regime parent_component = parent_regime.parent_component name_map = parent_component.name_map self.dependent_variable = ode.dependent_variable rhs = MathUtil.get_rhs_substituted( ode, name_map ) self.CODE = name_map[ode.dependent_variable] + " += (" + rhs + ")*h;"
def test_str_expr_replacement(self): # Signature: name(cls, frm, to, expr_string, func_ok=False) # replaces all occurences of name 'frm' with 'to' in expr_string # ('frm' may not occur as a function name on the rhs) ... # 'to' can be an arbitrary string so this function can also be used for # argument substitution. # # Returns the resulting string. # from nineml.abstraction_layer.component.util import MathUtil t = "b*c + d/(e*sin(f+g/e)) + b1 + e_ / exp(12*g)" t = MathUtil.str_expr_replacement("b", "B", t) self.assertEqual(t, "B*c + d/(e*sin(f+g/e)) + b1 + e_ / exp(12*g)") # 'e' is a builtin, so this function doesn't care. t = MathUtil.str_expr_replacement(frm="e", to="E", expr_string=t) self.assertEqual(t, "B*c + d/(E*sin(f+g/E)) + b1 + e_ / exp(12*g)")
def visit_timederivative(self, time_derivative, **kwargs): prefix = kwargs.get('prefix', '') prefix_excludes = kwargs.get('prefix_excludes', []) dep = self.prefix_variable(time_derivative.dependent_variable, **kwargs) rhs = MathUtil.get_prefixed_rhs_string( expr_obj=time_derivative, prefix=prefix, exclude=prefix_excludes) return time_derivative.__class__(dependent_variable=dep, rhs=rhs)
def visit_assignment(self, assignment, **kwargs): prefix = kwargs.get('prefix', '') prefix_excludes = kwargs.get('prefix_excludes', []) lhs = self.prefix_variable(assignment.lhs, **kwargs) rhs = MathUtil.get_prefixed_rhs_string( expr_obj=assignment, prefix=prefix, exclude=prefix_excludes) return assignment.__class__(lhs=lhs, rhs=rhs)
def test_get_prefixed_rhs_string(self): # Signature: name(cls, expr_obj, prefix='', exclude=None) # No Docstring # from nineml.abstraction_layer.component.util import MathUtil e = StrToExpr.alias("a := b*c + d/(e*sin(f+g/e)) + b1 + e_ / exp(12*g)") rhs_sub = MathUtil.get_prefixed_rhs_string(e, prefix="U_", exclude=["c", "e_"]) self.assertEqual(rhs_sub, "U_b*c + U_d/(e*sin(U_f+U_g/e)) + U_b1 + e_ / exp(12*U_g)")
def test_get_rhs_substituted(self): # Signature: name(cls, expr_obj, namemap) # No Docstring # from nineml.abstraction_layer.component.util import MathUtil e = StrToExpr.alias("a := b*c + d/(e*sin(f+g/e)) + b1 + e_ / exp(12*g)") rhs_sub = MathUtil.get_rhs_substituted(e, {"b": "B", "e": "E"}) self.assertEqual(rhs_sub, "B*c + d/(E*sin(f+g/E)) + b1 + e_ / exp(12*g)")
def __init__(self, lhs, rhs): ExpressionWithLHS.__init__(self, rhs) if not MathUtil.is_single_symbol(lhs): err = 'Expecting a single symbol on the LHS; got: %s' % lhs raise NineMLRuntimeError(err) if not is_valid_lhs_target(lhs): err = 'Invalid LHS target: %s' % lhs raise NineMLRuntimeError(err) self._lhs = lhs.strip()
def __init__(self, condition, parent_trans): self.parent_trans = parent_trans self.condition = condition parent_component = parent_trans.parent_component name_map = parent_component.name_map # code to evaluate the condition condition_expr = MathUtil.get_rhs_substituted( condition, name_map ) self.CODE = "transPendingTmp[%d] = (%s)" % (parent_trans.index, condition_expr) # where the state of the evaluated condition may be stored self.PENDING = "transPendingTmp[%d]" % parent_trans.index # conditions, unlike eventports, can happen only once self.PENDING_FINALIZE = "break;"
def __init__(self, condition, parent_trans): self.parent_trans = parent_trans self.condition = condition parent_component = parent_trans.parent_component name_map = parent_component.name_map # code to evaluate the condition condition_expr = MathUtil.get_rhs_substituted(condition, name_map) self.CODE = "transPendingTmp[%d] = (%s)" % (parent_trans.index, condition_expr) # where the state of the evaluated condition may be stored self.PENDING = "transPendingTmp[%d]" % parent_trans.index # conditions, unlike eventports, can happen only once self.PENDING_FINALIZE = "break;"
def action_assignment(self, assignment, **kwargs): rand_map = { 'normal' : r'nineml_random_normal(\1,\2)', 'uniform' : r'nineml_random_uniform(\1,\2)', 'binomial' : r'nineml_random_binomial(\1,\2)', 'poisson' : r'nineml_random_poisson(\1)', 'exponential' : r'nineml_random_exponential(\1)', } expr = assignment.rhs for atom in assignment.rhs_atoms_in_namespace('random'): if not atom in rand_map: err = 'Neuron Simulator does not support: %s'%atom raise nineml.exceptions.NineMLRuntimeError(err) expr = MathUtil.rename_function(expr, '%s.%s'%('random',atom), rand_map[atom] ) self.required_random_functions.add(atom) assignment.neuron_rhs = expr
def rhs_as_python_func(self, namespace={}): """ Returns a python callable which evaluates the expression in namespace and returns the result """ rhs = self.rhs rhs = rhs.replace('!', ' not ') rhs = rhs.replace('&', ' and ') rhs = rhs.replace('|', ' or ') name_map = { 'true': 'True', 'false': 'False' } for frm, to in name_map.iteritems(): rhs = MathUtil.str_expr_replacement(frm, to, rhs) lmda_str = "lambda %s: %s" % (','.join(self.rhs_names), rhs) return eval(lmda_str, str_to_npfunc_map, namespace)
def On(trigger, do=None, to=None): if isinstance(do, (OutputEvent, basestring)): do = [do] elif do == None: do = [] else: pass if isinstance(trigger, basestring): if MathUtil.is_single_symbol(trigger): return DoOnEvent(input_event=trigger, do=do, to=to) else: return DoOnCondition(condition=trigger, do=do, to=to) elif isinstance(trigger, OnCondition): return DoOnCondition(condition=trigger, do=do, to=to) else: err = "Unexpected Type for On() trigger: %s %s" % (type(trigger), str(trigger)) raise NineMLRuntimeError(err)
def test_is_single_symbol(self): # Signature: name(cls, expr) # Returns ``True`` if the expression is a single symbol, possibly # surrounded with white-spaces # # >>> is_single_symbol('hello') # True # # >>> is_single_symbol('hello * world') # False self.assertTrue(MathUtil.is_single_symbol("t")) self.assertTrue(MathUtil.is_single_symbol("var_1")) self.assertTrue(MathUtil.is_single_symbol("var_long_name")) self.assertTrue(MathUtil.is_single_symbol("_myName")) self.assertFalse(MathUtil.is_single_symbol("r + y")) self.assertFalse(MathUtil.is_single_symbol("r+y")) self.assertFalse(MathUtil.is_single_symbol("sin(y)"))
def visit_condition(self, condition, **kwargs): prefix = kwargs.get('prefix', '') prefix_excludes = kwargs.get('prefix_excludes', []) rhs = MathUtil.get_prefixed_rhs_string( expr_obj=condition, prefix=prefix, exclude=prefix_excludes) return condition.__class__(rhs=rhs)