def testUnaryFunction(self): """Test function that takes single argument""" symbol_table = cexprtk.Symbol_Table({}) symbol_table.functions["plustwo"] = lambda x: x + 2 expression = cexprtk.Expression("plustwo(2)", symbol_table) assert 4 == expression() symbol_table.variables["A"] = 3.0 expression = cexprtk.Expression("plustwo(A) + 4", symbol_table) assert 3 + 2 + 4 == expression()
def testNullaryFunction(self): """Test function that takes no arguments""" symbol_table = cexprtk.Symbol_Table({}) def foo(): return 1.0 symbol_table.functions["foo"] = foo e1 = cexprtk.Expression("foo() + 1", symbol_table) assert 2.0 == e1() e2 = cexprtk.Expression("foo + 1", symbol_table) assert 2.0 == e2()
def testFunctoolsPartial(self): import functools def f(a, b, c): return 2 * a + 3 * b + c p = functools.partial(f, 1, 2) st = cexprtk.Symbol_Table({}) st.functions["f"] = f st.functions["p"] = p e1 = cexprtk.Expression("f(1,2,3)", st) e2 = cexprtk.Expression("p(3)", st) assert e1() == e2()
def evaluate_expression(expression): print('Expression: ' + expression) rounds = 100000 time_start = time.time() x = 1.0 y = 3.3 sum = 0.0 for x in range(1, rounds + 1, 1): sum += eval(expression) time_end = time.time() total_time = time_end - time_start print('[eval] Total time: %6.3fsec\tRate: %12.3fevals/sec\tSum: %f' % (total_time, rounds / total_time, sum)) time_start = time.time() symbol_table = cexprtk.Symbol_Table({"x": x, "y": y}, add_constants=True) expr = cexprtk.Expression(expression, symbol_table) x = 1.0 y = 3.3 sum = 0.0 for x in range(1, rounds + 1, 1): symbol_table.variables['x'] = x symbol_table.variables['y'] = y sum += expr() time_end = time.time() total_time = time_end - time_start print('[cexprtk] Total time: %6.3fsec\tRate: %12.3fevals/sec\tSum: %f' % (total_time, rounds / total_time, sum)) print('\n')
def testEndToEnd(self): """End to end test""" class MemoUnknownSymbolResolver(object): def __init__(self): self.callList = [] self.retList = { 'x': (True, cexprtk.USRSymbolType.VARIABLE, 1.0, ""), 'y': (True, cexprtk.USRSymbolType.CONSTANT, 2.0, ""), 'z': (True, cexprtk.USRSymbolType.VARIABLE, 3.0, "") } def __call__(self, sym): self.callList.append(sym) return self.retList[sym] unknownSymbolResolver = MemoUnknownSymbolResolver() symbolTable = cexprtk.Symbol_Table({}) expression = cexprtk.Expression("x+y+z", symbolTable, unknownSymbolResolver) assert ['x' == 'y', 'z'], unknownSymbolResolver.callList assert 6.0 == expression() expectVariables = {'x': 1.0, 'z': 3.0} assert expectVariables == dict(list(symbolTable.variables.items())) expectConstants = {'y': 2.0} assert expectConstants == dict(list(symbolTable.constants.items()))
def __init__(self, math_str, parameters): symbols = {} for param in parameters: symbols[param] = 1.0 st = cexprtk.Symbol_Table(symbols, add_constants=True) self.expression = cexprtk.Expression(math_str, st) self._constant = 1
def testWithVariables(self): """Perform a test with some variables""" st = cexprtk.Symbol_Table({'a': 2, 'b': 3}, {}) expression = cexprtk.Expression("(a+b) * 3", st) v = expression.value() self.assertAlmostEqual(15.0, v)
def comboBox_fx_TextChanged(self, text): self.symbol_dict = {} exp_variables = [] def callback(symbol): nonlocal exp_variables exp_variables.append(symbol) return (True, cexprtk.USRSymbolType.VARIABLE, 0.0, "") st = cexprtk.Symbol_Table({}, cnst.m_constants, add_constants=True) try: cexprtk.Expression(text, st, callback) for sym in sorted(exp_variables): self.symbol_dict[sym] = 0.0 self.textBrowser_x.setText('[' + ", ".join([*self.symbol_dict.keys()]) + ']') self.lineEdit_x0.setText(", ".join( [str(x) for x in self.symbol_dict.values()])) self.data_correctness_dict['fx'] = True self.data_correctness_dict['x0'] = True except: if self.comboBox_fx.currentIndex() != 0: self.comboBox_fx.removeItem(self.comboBox_fx.currentIndex()) self.comboBox_fx.setCurrentText( "Błąd odczytania funkcji. Nieznane znaki.") self.textBrowser_x.setText("[]") self.lineEdit_x0.setText("") self.data_correctness_dict['fx'] = False self.data_correctness_dict['x0'] = False self.unlock_button_rozpocznij_opt()
def __call__(self, *args): parameter_names = self._potential_form_tuple.signature.parameter_names assert len(args) == len(parameter_names) for (pn, v) in zip(parameter_names, args): self._local_symbol_table.variables[pn] = v try: if not self._expression: try: self._expression = cexprtk.Expression( self._potential_form_tuple.expression, self._local_symbol_table) except cexprtk.ParseException as pe: raise Potential_Form_Exception( "mathematical expression couldn't be parsed {}".format( pe)) retval = self._expression() return retval except Potential_Form_Exception as e: msg = e.args[0] sig = ",".join( self._potential_form_tuple.signature.parameter_names) sig = "{label}({sig})".format( label=self._potential_form_tuple.signature.label, sig=sig) msg = "In potential-form '{sig} = {expression}': {msg}".format( msg=msg, sig=sig, expression=self._potential_form_tuple.expression) raise Potential_Form_Exception(msg)
def testMultiprocesses(self): """Test with multiple processes""" exprstr = "A * exp(rho / r ) - C/(r^6)" rvals = [1.0 + x / 10.0 for x in range(100)] rhovals = [0.1, 0.2, 0.3] inputs = [] for rhoval in rhovals: for rval in rvals: inputs.append((rhoval, rval)) import math def pfunc(rho, r): return 1000.0 * math.exp(rho / r) - 32.0 / r**6 expected = [pfunc(rho, r) for (rho, r) in inputs] import multiprocessing from .multi import Worker expression = cexprtk.Expression( exprstr, cexprtk.Symbol_Table({ 'rho': 0, 'r': 0 }, { 'A': 1000.0, 'C': 32.0 })) pool = multiprocessing.Pool(4) results = pool.map(Worker(expression), inputs) assert expected == results
def testWithoutSpecificSymbolTable(self): """Test for expression with no variables""" import multiprocessing from .multi import evaluate_expression expression = cexprtk.Expression("2+2", None) pool = multiprocessing.Pool(processes=1) results = pool.map(evaluate_expression, [expression]) assert 4 == results[0]
def testCallable(self): """Test use of a varargs functions with Expression objects""" class Callable(object): def __call__(self, *args): s = 0 for i in args: s += i return s va = Callable() st = cexprtk.Symbol_Table({}) st.functions["va"] = va assert va == st.functions["va"] e = cexprtk.Expression("va(1,2,3,4)", st) assert 10 == e() e = cexprtk.Expression("va(1,2,3,4,1)", st) assert 11 == e()
def testBadSymbolType(self): """Test that condition is correctly handled if bad USRSymbolType specified""" def callback(sym): return (True, 3, 0.0, "Error text") symbolTable = cexprtk.Symbol_Table({}) with self.assertRaises(cexprtk.UnknownSymbolResolverException): expression = cexprtk.Expression("x+y+z", symbolTable, callback)
def testNoVariables(self): """Perform test with no variables""" st = cexprtk.Symbol_Table({}, {}) expression = cexprtk.Expression("2+2", st) v = expression.value() self.assertAlmostEqual(4.0, v) v = expression() self.assertAlmostEqual(4.0, v)
def testUSRException(self): """Test when the unknown symbol resolver throws""" def callback(sym): return 1.0 / 0 symbolTable = cexprtk.Symbol_Table({}) with self.assertRaises(ZeroDivisionError): expression = cexprtk.Expression("x+y+z", symbolTable, callback)
def run_benchmark(expression, f): lower_bound_x = -10.0 lower_bound_y = -10.0 upper_bound_x = +10.0 upper_bound_y = +10.0 delta = 0.0111 x = lower_bound_x total = 0.0 count = 0 stime = time.time() while x <= upper_bound_x: y = lower_bound_y while y <= upper_bound_y: total += f(x, y) count += 1 y += delta x += delta etime = time.time() native_t = (etime - stime) native_rate = count / float(native_t) symbol_table = cexprtk.Symbol_Table({ 'x': 1.0, 'y': 1.0 }, add_constants=True) eval_expression = cexprtk.Expression(expression, symbol_table) v = symbol_table.variables x = lower_bound_x total = 0.0 count = 0 stime = time.time() while x <= upper_bound_x: y = lower_bound_y while y <= upper_bound_y: v['x'] = x v['y'] = y total += eval_expression.value() count += 1 y += delta x += delta etime = time.time() cexprtk_t = (etime - stime) cexprtk_rate = count / float(cexprtk_t) print("Expression: {0}".format(expression)) print("NATIVE_PYTHON: Total Time:%12.8f Rate:%14.3f evals/sec" % (native_t, native_rate)) print("CEXPRTK: Total Time:%12.8f Rate:%14.3f evals/sec" % (cexprtk_t, cexprtk_rate))
def testResultsEmptyWithNoReturn(self): """Test that an expression has no results when it doesn't include a return statement""" st = cexprtk.Symbol_Table({}, {}) expression = cexprtk.Expression("2+2", st) v = expression.value() self.assertAlmostEqual(4.0, v) results_list = expression.results() self.assertEqual(0, len(results_list))
def testCallableAsFunction(self): """Test that objects that implement __call__ can be used as functions in expressions""" class Callable(object): def __call__(self, a): return a + 4.1 c = Callable() symbol_table = cexprtk.Symbol_Table({}) symbol_table.functions['f'] = c expression = cexprtk.Expression("f(1)", symbol_table) assert pytest.approx(5.1) == expression.value()
def stocks(self, icdict): for k, v in icdict.items(): # initialize stock values as variables in formulas if type(v) == int or type(v) == float: self.st.variables[k] = v elif type(v) == str: self.st.variables[k] = cexprtk.Expression(v, self.st).value() else: pass self.__new_state_var(k, v) self.stock[k] = v
def testFunctionThatThrows(self): """Test a function that throws an exception""" class CustomException(Exception): pass def f(a): raise CustomException() symbol_table = cexprtk.Symbol_Table({}, functions={"f": f}) expression = cexprtk.Expression("f(1)", symbol_table) with self.assertRaises(CustomException): expression.value()
def testSymbolTableProperty(self): st = cexprtk.Symbol_Table({'a': 2, 'b': 3}, {}) expression = cexprtk.Expression("(a+b) * 3", st) st = None v = expression.value() self.assertAlmostEqual(15.0, v) st = expression.symbol_table st.variables['a'] = 3.0 v = expression() self.assertAlmostEqual(18.0, v)
def testErrors(self): """Test unknown_symbol_resolver_callback when it throws errors.""" def callback(sym): if sym == 'x': return (True, cexprtk.USRSymbolType.VARIABLE, 1.0, "") else: return (False, cexprtk.USRSymbolType.VARIABLE, 0.0, "Error text") symbolTable = cexprtk.Symbol_Table({}) with self.assertRaises(cexprtk.ParseException): expression = cexprtk.Expression("x+y+z", symbolTable, callback)
def evaluate_expressions(variable_values, expressions): """ Evaluates the expressions with respect to the variable values. Parameters: + variables_values: a dict in which each element is { variables name : [ variable instance, variable value ] } + expressions: a dict in which each element is { expression name : expression instance } Returns: + a dict in which each element is { expression name : expression value } """ cexprtk_variables = {} # variable_name : variable_value result = {} # result (expression name : 0 / 1) for var_name, var_data in variable_values.iteritems(): variable = var_data[0] var_value = 0 var_type = variable['type'] if var_type == 'int': # integer if (is_int(var_data[1])): var_value = int(var_data[1]) else: var_value = int(float(var_data[1])) else: # float var_value = float(var_data[1]) cexprtk_variables[var_name] = var_value # create SymbolTable symbol_table = cexprtk.Symbol_Table(cexprtk_variables, add_constants=True) for expr_name, expression in expressions.iteritems(): expr_formula = expression['formula'] # BUG why this is unicode???? expr_type = expression['type'] decimal_places = expression['decimal_places'] cexprtk_expression = cexprtk.Expression( expr_formula.encode('utf-8'), symbol_table ) # remove unicode: http://stackoverflow.com/questions/4855645/how-to-turn-unicode-strings-into-regular-strings cexprtk_expression_value = cexprtk_expression.value() # perform the rounding appropriately if (expr_type == 'int'): result[expr_name] = round(cexprtk_expression_value, 0) else: result[expr_name] = round( cexprtk_expression_value, decimal_places ) # ??? http://stackoverflow.com/questions/455612/limiting-floats-to-two-decimal-points return result
def testVarArgs(self): """Test use of a varargs functions with Expression objects""" def va(*args): s = 0 for i in args: s += i return s st = cexprtk.Symbol_Table({}) st.functions["va"] = va assert va == st.functions["va"] e = cexprtk.Expression("va(1,2,3,4)", st) assert 10 == e()
def testShadowingOfReservedFunction(self): """Test that reserved function names cannot be overwritten""" symbol_table = cexprtk.Symbol_Table({}) expression = cexprtk.Expression("exp(2)", symbol_table) self.assertAlmostEqual(7.3890560989, expression.value()) import math def f(a): return math.exp(a) + 1 symbol_table = cexprtk.Symbol_Table({}) with self.assertRaises(ReservedFunctionShadowException): symbol_table.functions['exp'] = f
def __init__(self, model_str, variables, name=None, adj_r2=None): """ Parses a model expression and prepares it for evaluation :param model_str: Expression as string :param variables: Variable names that will be replaced with values when evaluating the model :param name: Name of the model :param adj_r2: Adjusted r^2 for the model """ self.name = name self.adj_r2 = adj_r2 self.model_str = notation_fix(model_str) self.variables = variables var_dict = dict(map(lambda x: (x, 0), variables)) # dict of variables with default value 0 self.symbols = cexprtk.Symbol_Table(var_dict, add_constants=True) self.expression = cexprtk.Expression(self.model_str, self.symbols)
def flow(self, key, f, start=None, end=None): # resolve any data sources in formula for k, v in self.data.items(): if k in f: f = f.replace(k, v) for k, v in self.noise.items(): if k in f: f = f.replace(k, "random(t," + str(v) + ")") # resolve noise in formula self.__new_state_var(key, cexprtk.Expression(f, self.st).value()) s = self.ix[start] if start is not None else None e = self.ix[end] if end is not None else None # add flows to dict self.flows[key] = {'f': f, 'start': s, 'end': e}
def parse_formula(formula, params_values): vars_func = parser.parse(formula).variables() print(vars_func) vars = list(filter(lambda x: x.find('_') != -1, vars_func)) print(vars) funcs = list(filter(lambda x: x.find('_') == -1, vars_func)) print(funcs) variables = {} for var in vars: variables[var] = params_values[int(var.split('_')[1])] print(variables) st = cexprtk.Symbol_Table(variables) for func in funcs: st.functions[func] = globals()[func] calc_exp = cexprtk.Expression(formula, st) print(calc_exp()) return calc_exp()
def f(self, y, t): self.current = y # set y to the initial condition d = np.zeros((len(y), )) for k, f in self.flows.items( ): # calculate flows only once. distribute to stocks. i = self.ix[k] # update time self.st.variables['t'] = t # update all stock variables for k, v in self.stock.items(): self.st.variables[k] = self.get_stock_value(k) # update noise generators current_time_step_index = np.where(self.t == t)[0] ft = cexprtk.Expression(f['f'], self.st).value() d[i] = ft - self.current[i] if f['start'] is not None: d[f['start']] -= ft if f['end'] is not None: d[f['end']] += ft return d
def __init__(self, emfilename=None, eventCollection=None, configfile=None): """ Initialize the class """ self.emfilname = emfilename self.configfile = configfile # Default work function of 0.05 keV/ehp self.symbolTable = cexprtk.Symbol_Table({"E": 10}, add_constants=True) self.wehpExpression = cexprtk.Expression("0.05", self.symbolTable) # Read and store settings print("Read config") if configfile: self.settings = sc.readConfigFile(configfile) else: self.settings = None warnings.warn( "No Settings File Read. Please read (or create) class settings and run applySettings()." ) return # Read and store particle data print("Read Geant4 Simulation Data") if type(eventCollection) is str: self.eventCollection = gEventCollection(eventCollection) else: self.eventCollection = eventCollection # Read and store emdata print("Read Comsol EM Data") if emfilename: self.newEmFile(emfilename) else: self.x = self.y = self.z = self.data = [] self.applySettings() if self.settings["SCALE_WEIGHTED_PHI"]: self.computeScaleFactor() else: self.scale = 1