def taxa_anuidade(E,P,a): Esym,t,asym,Psym = sy.symbols('Esym t asym Psym') fsym = Esym*t/( 12*(1 - 1/(1 + t/12)**(12*asym) ) ) - Psym dfsym = sy.diff(fsym,t) f = fsym.subs({'Esym':E,'asym':a,'Psym':P}) df = dfsym.subs({'Esym':E,'asym':a,'Psym':P}) ft = eval(lambdastr(t,f)) dft = eval(lambdastr(t,df)) # Aplicação do método de Newton # parâmetros t0 = 1.0 # estimativa inicial tole=1e-3 # tolerância de erro nmax=50 # número máximo de iterações # método de Newton t = newton(ft,t0,dft,tol=tole,maxiter=nmax) msg = "A taxa do empréstimo é de {0:.2f}% a.a.".format(t*100) return (t,msg)
def test_lambdify_Derivative_arg_issue_16468(): f = Function('f')(x) fx = f.diff() assert lambdify((f, fx), f + fx)(10, 5) == 15 assert eval(lambdastr((f, fx), f/fx))(10, 5) == 2 raises(SyntaxError, lambda: eval(lambdastr((f, fx), f/fx, dummify=False))) assert eval(lambdastr((f, fx), f/fx, dummify=True))(10, 5) == 2 assert eval(lambdastr((fx, f), f/fx, dummify=True))(10, 5) == S.Half assert lambdify(fx, 1 + fx)(41) == 42 assert eval(lambdastr(fx, 1 + fx, dummify=True))(41) == 42
def test_lambdify_Derivative_arg_issue_16468(): f = Function('f')(x) fx = f.diff() assert lambdify((f, fx), f + fx)(10, 5) == 15 assert eval(lambdastr((f, fx), f / fx))(10, 5) == 2 raises(SyntaxError, lambda: eval(lambdastr( (f, fx), f / fx, dummify=False))) assert eval(lambdastr((f, fx), f / fx, dummify=True))(10, 5) == 2 assert eval(lambdastr((fx, f), f / fx, dummify=True))(S(10), 5) == S.Half assert lambdify(fx, 1 + fx)(41) == 42 assert eval(lambdastr(fx, 1 + fx, dummify=True))(41) == 42
def do_filter(node): def strip_index(toks): indexing = 0 func_str = '' for i, t in enumerate(toks): if t == '[': indexing = indexing + 1 if not indexing: func_str = func_str + t if t == ']': indexing = indexing - 1 return func_str def actual_func(cond_func, func, **kwargs): cond_filter = cond_func(**kwargs) filtered_args = {} for k, v in kwargs.items(): filtered_args[k] = [ val for val, cond in zip(v, cond_filter) if cond ] return func(**filtered_args) assert node.val.scripted start = node.val.toks.index(Names.listCond) end = node.val.toks.index(')', start) cond_toks = node.val.toks[start + 1:end] cond_str = strip_index(cond_toks) func_toks = node.val.toks[:start] + node.val.toks[end:] func_str = strip_index(func_toks) syms = {} for name in node.val.names: syms.update(SympyHelper.initSyms(name)) cond_exprs = SympyHelper.initExprs([cond_str], syms) func_exprs = SympyHelper.initExprs([func_str], syms) cond_sol = simplify(cond_exprs)[0] func_sol = list( solve(func_exprs, exclude=list( SympyHelper.initSyms(node.ordered_given).values()), check=False, manual=True, rational=False)[0].values())[0] cond_func = lambdify(tuple(node.ordered_given), cond_sol, modules=[{ 'umin': umin, 'ufloor': ufloor }, mcerp.umath, 'numpy', 'sympy']) func = lambdify(tuple(node.ordered_given), func_sol, modules=[{ 'umin': umin, 'ufloor': ufloor }, mcerp.umath, 'numpy', 'sympy']) node.func = functools.partial(actual_func, cond_func=cond_func, func=func) node.func_str = lambdastr(tuple(node.ordered_given), func_sol)
def sym_to_num(func): return njit()(eval(lambdastr(*func.args), { **globals(), **{ "sqrt": np.sqrt } }))
def numbafy(self, expression, coordinates=None, parameters=None, name='trial_func'): if coordinates: code_coord = [] for i, x in enumerate(coordinates): code_coord.append(f'{x} = coordinates[{i}]') code_coord = '\n '.join(code_coord) if parameters: code_param = [] for i, x in enumerate(parameters): code_param.append(f'{x} = parameters[{i}]') code_param = '\n '.join(code_param) temp = lambdastr((), expression) temp = temp[len('lambda : '):] temp = temp.replace('math.exp', 'np.exp') code_expression = f'{temp}' template = f""" @njit def {name}(coordinates, parameters): {code_coord} {code_param} return {code_expression}""" print('Numba function template generated! Its name is ', name) return template
def lambdify_mpf(dims, exprs): # Perform the initial lambdification ls = [lambdastr(dims, ex.evalf(mp.dps)) for ex in exprs] csf = {} # Locate all numerical constants in these lambdified expressions for l in ls: for m in re.findall('([0-9]*\.[0-9]+(?:[eE][-+]?[0-9]+)?)', l): if m not in csf: csf[m] = mp.mpf(m) # Sort the keys by their length to prevent erroneous substitutions cs = sorted(csf, key=len, reverse=True) # Name these constants csn = {s: '__c%d' % i for i, s in enumerate(cs)} cnf = {n: csf[s] for s, n in csn.iteritems()} # Substitute lex = [] for l in ls: for s in cs: l = l.replace(s, csn[s]) lex.append(eval(l, cnf)) return lex
def make_return_string(expr): """Process a sympy expression into an evaluatable Python return statement. Parameters: ----------- expr : sympy.Expr instance Returns: -------- output : string A return string that can be used to assemble a Kwant value function. func_symbols : set of sympy.Symbol instances All space dependent functions that appear in the expression. const_symbols : set of sympy.Symbol instances All constants that appear in the expression. """ func_symbols = {sympy.Symbol(i.func.__name__) for i in expr.atoms(AppliedUndef)} free_symbols = {i for i in expr.free_symbols if i.name not in ['x', 'y', 'z']} const_symbols = free_symbols - func_symbols expr = expr.subs(sympy.I, sympy.Symbol('1.j')) # quick hack output = lambdastr((), expr, printer=NumericPrinter)[len('lambda : '):] output = output.replace('MutableDenseMatrix', 'np.array') output = output.replace('ImmutableMatrix', 'np.array') return 'return {}'.format(output), func_symbols, const_symbols
def do_generation(cur, do_solve=False): assert isinstance(cur.val, Relation) syms = {} for name in cur.val.names: syms.update( SympyHelper.initSyms( name, self.v2v[getBaseName(name)].vector and cur.val.deferred)) exprs = SympyHelper.initExprs([cur.val.str], syms) # Sympy bug workaround: # Must set rational to False, otherwise piecewise function cannot be solved correctly. if do_solve: solutions = solve(exprs, exclude=cur.ordered_given, check=False, manual=True, rational=False) solution = solutions[0].values()[0] else: solutions = simplify(exprs) solution = solutions[0] if len(solutions) != 1: # We cannot handle multiplte solutions yet. raise NotImplementedError cur.func = lambdify(tuple(cur.ordered_given), solution, modules=[{ 'umin': umin, 'ufloor': ufloor }, mcerp.umath, 'numpy', 'sympy']) cur.func_str = lambdastr(tuple(cur.ordered_given), solution)
def logL_alt(self, a, b, c): subst = [(self.a, a), (self.b, b), (self.c, c)] for x, kv in enumerate(self.kVec): subst.append((self.k[x], kv)) subst.append((self.t[x], self.tVec[x])) ll = lambdastr((self.a, self.b, self.c, self.k, self.t), self.logL_eqn.doit()) print(ll(a, b, c))
def make_return_string(expr): """Process a sympy expression into an evaluatable Python return statement. Parameters: ----------- expr : sympy.Expr instance Returns: -------- output : string A return string that can be used to assemble a Kwant value function. func_symbols : set of sympy.Symbol instances All space dependent functions that appear in the expression. const_symbols : set of sympy.Symbol instances All constants that appear in the expression. """ func_symbols = { sympy.Symbol(i.func.__name__) for i in expr.atoms(AppliedUndef) } free_symbols = { i for i in expr.free_symbols if i.name not in ['x', 'y', 'z'] } const_symbols = free_symbols - func_symbols expr = expr.subs(sympy.I, sympy.Symbol('1.j')) # quick hack output = lambdastr((), expr, printer=NumericPrinter)[len('lambda : '):] output = output.replace('MutableDenseMatrix', 'np.array') output = output.replace('ImmutableMatrix', 'np.array') return 'return {}'.format(output), func_symbols, const_symbols
def bracket_product_scipy_tplquad(wave_function, wave_function_prime, operator=None): """ Compute the scalar product <bra|operator|ket> with scipy and the integrate algorithm tplquad :param wave_function: bra :param wave_function_prime: ket :param operator: operator :return: bracket product (float) """ from sympy.utilities.lambdify import lambdastr r, theta, phi = sp.Symbol("r", real=True), sp.Symbol( "theta", real=True), sp.Symbol("phi", real=True) jacobian = (r**2) * sp.sin(theta) integral_core = sp.conjugate(wave_function) * ( operator if operator is not None else 1) * wave_function_prime # integral_core_expension = sp.expand(sp.FU["TR8"](jacobian * integral_core), func=True).simplify() integral_core_expension = sp.expand(jacobian * integral_core, func=True).simplify() # Process the integral with scipy integral_core_lambdify = sp.lambdify((theta, r, phi), integral_core_expension, modules="numpy") print(lambdastr((theta, r, phi), integral_core_expension)) bracket_product = QuantumFactory.complex_quadrature( sc.integrate.tplquad, integral_core_lambdify, 0, 2 * np.pi, lambda b_phi: 0, lambda b_phi: np.inf, lambda b_theta, b_r: 0, lambda b_theta, b_r: np.pi)[0] # bracket_product = sc.integrate.tplquad(integral_core_lambdify, # 0, 2 * np.pi, lambda b_phi: 0, lambda b_phi: np.inf, # lambda b_theta, b_r: 0, lambda b_theta, b_r: np.pi)[0] return bracket_product
def _expr2code(self, arg_list, expr): """Convert the given symbolic expression into code.""" code = lambdastr(arg_list, expr) function_code = code.split(':')[1].strip() #for arg in arg_list: # function_code = function_code.replace(arg.name, 'self.'+arg.name) return function_code
def parse_math(expr): if expr != '': # вот здесь самая главная часть программы res = lambdastr(x, expr) res = eval(res) # ---------- return res else: return False
def buildstr(exp): exp=exp.subs(hzN,zN/zeta) exp=exp.subs(hxN,xN/xi) exp=exp.subs(zN,zN2zh) exp=exp.subs(xN,xN2xb) exp=exp.subs(Mki**2,-Mki**2) args=(M,Mh,xb,zh,eta,Q,T.t,xi,zeta,dk.t,ki.t,Mki,Mkf) out=lambdastr(args, exp) out=out.replace('math.','') return out
def make_jit_fn(args, fn_expr): fn_str = lambdastr(args, fn_expr).replace('MutableDenseMatrix', '') \ .replace('(([[', '[') \ .replace(']]))', ']') f = eval(fn_str) try: jit_fn = numba.jit(nopython=True)(f) jit_fn(*np.ones(len(args), dtype=float)) except: jit_fn = f return jit_fn
def string_lambdastr_as_function(expr, x, a=None, fun_name=None, use_numpy=False, include_imports=False): if fun_name is None: fun_name = "calc_expression" s_lambda = lambdastr(x, expr) x_name = get_symbol_name(x) header, content = s_lambda.split(":") x_tuple_str = string_inputs_as_tuple_descontruction(x) if a is not None: a_name = get_symbol_name(a) a_tuple_str = string_inputs_as_tuple_descontruction(a) header = "def {}({}, {}):\n".format(fun_name, x_name, a_name) else: header = "def {}({}):\n".format(fun_name, x_name) a_tuple_str = "" content = content.strip() content = content[1:-1] # Im not sure when math is applyed to the converted string or not by sympy # FIXME: for now i will force removing math to them applying it again content = content.replace("math.", "") content = content.replace("sqrt(", "math.sqrt(") content = content.replace("log(", "math.log(") content = content.replace("cos(", "math.cos(") content = content.replace( "erf(", "math.erf(" ) # this is an error, lambdastr should be keeping math or numpy, check later if use_numpy: content = content.replace("math", "numpy") full = "{}\t{}\n\t{}\n\tr = {}\n\treturn r\n".format( header, x_tuple_str, a_tuple_str, content) if include_imports: is_numpy = "import numpy\n" if "numpy" in full else "" is_math = "import math\n" if "math" in full else "" full = is_numpy + is_math + "\n" + full return full
def display_orbital(n, l, m, n_o_c, box_size, resolution, isostep): """Diplays a 3D view of electron orbitals""" P_tex = "" #initialize the LaTex string of the probabilities #Validate the quantum numbers assert (n >= 1), "n must be greater or equal to 1" #validate the value of n assert (0 <= l <= n - 1), "l must be between 0 and n-1" #validate the value of l assert (-l <= m <= l), "p must be between -l and l" #validate the value of p #Determine the probability equation symbolically and convert #it to a string prob = lambdastr((radius, angle_phi, angle_theta), P(radius, n, l, m, angle_phi, angle_theta)) # print(prob) #record the probability equation as a LaTex string P_eq = simplify(P(r, n, l, m, phi, theta)) P_tex += "$$P =" + latex(P_eq) + "$$ \n\n " if '(nan)' in prob: #Check for errors in the equation print("There is a problem with the probability function.") raise ValueError #Convert the finctions in the probability equation from the sympy #library to the numpy library to allow for the use of matrix #calculations prob = prob.replace('math.sin', 'np.sin') #convert to numpy prob = prob.replace('math.cos', 'np.cos') #convert to numpy prob = prob.replace('math.Abs', 'np.abs') #convert to numpy prob = prob.replace('math.pi', 'np.pi') #convert to numpy prob = prob.replace('math.exp', 'np.exp') #convert to numpy # print("Sybolic Prob function: ") # print(prob) #convert the converted string to a callable functio Prob = eval(prob) #go and let the marching boxes do their thing and create the isosurface mesh main(Prob, r_fun, phi_fun, theta_fun, n_o_c, box_size, resolution, isostep) return
def __init__(self, expr, all_vars, variable_list): ''' Sets up the initial class, accepts a sympy expression and a list of variables. ''' try: self.expr = expr # self.expr stores the function to be evaluated, this stores a sympy function # this is limited right now to a rank 1 tensor that can be embeded into a R^n vector-space self.dim = len( self.expr ) # the dimension of the function, IE f is a member of R^2 or a member of R^9001 self.variable_list = variable_list # this stores the list of variables to be used in the function self.in_args = [ i for i in range(len(self.variable_list)) ] # this enumerates the absolute order of the variable in the evaluation list # IE: f such that R^5 -> R^5 where a,b,x,z,p belong to R; therefore f(a,b,x,z,p) maps to R^5 and "a" has the absolute position in # the evaluation list of f as 0, b as 1, x as 2, z as 3, and p as 4 self.results = [ {} for x in self.in_args ] # assign an empty set to each function output, this is kept as an empty set so # that tensors of rank 2 or more can be evaluated at a later version of this module self.vars = { variable: 0 for variable in all_vars } # set the variable as a key into a dictionary with an initial value of 0 self.var_dict = { i: self.variable_list[i] for i in range(self.dim) } # link each variable to a enumeratable key value instead of the name # IE: {a: 1, b: 2, c: 3} allows f to be evaluated by positional arguments f(1,2,3) and calls the values from self.vars self.lambda_expr = [ lambdastr(self.variable_list[i], self.expr[key]) for i, key in enumerate(self.var_dict) ] # c style lambda function for # quicker evaluation of mathematical functions over pure python evaluation. Makes use of cython or direct evaluation of static bytecode return except Exception as e: print( 'Error in Symbolic Function module : __init__.\n{}'.format(e)) PrintException()
def vegafy(self, expression, coordinates=None, name='vega_func'): if coordinates: code_coord = [] for i, x in enumerate(coordinates): code_coord.append(f'{x} = coordinates[:,{i}]') code_coord = '\n '.join(code_coord) temp = lambdastr((), expression) temp = temp[len('lambda : '):] temp = temp.replace('math.exp', 'np.exp') code_expression = f'{temp}' template = f""" @vegas.batchintegrand def {name}(coordinates): {code_coord} return {code_expression}""" print('Vega function template generated! Its name is ', name) return template
def numbafy(expression, parameters=None, constants=None, use_cse=False, new_function_name='numbafy_func'): cse = sym.cse(expression) code_parameters = '' code_constants = '' code_cse = '' if parameters: code_parameters = ', '.join(f'{p}' for p in parameters) if constants: code_constants = [] for k, v in constants.items(): code_constants.append(f'{k} = {v}') code_constants = '\n '.join(code_constants) if use_cse: expressions = sym.cse(expression) code_cse = [] for e in expressions[0]: k, v = e code_cse.append(f'{k} = {v}') code_cse = '\n '.join(code_cse) code_expression = f'{expressions[1][0]}' else: temp = lambdastr((), expression) temp = temp[len('lambda : '):] code_expression = f'{temp}' template = f"""@jit def {new_function_name}({code_parameters}): {code_constants} {code_cse} return {code_expression}""" return template
def display_orbital(n, l, m_, no_of_contours=16, Opaque=0.5): """Diplays a 3D view of electron orbitals""" # The plot density settings (don't mess with unless you are sure) rng = 12 * n * 1.5 # This determines the size of the box _steps = 55j # (it needs to be bigger with n). _x, _y, _z = np.ogrid[-rng:rng:_steps, -rng:rng:_steps, -rng:rng:_steps] # Plot tweaks color = (0, 1.0, 1.0) # relative RGB color (0-1.0 vs 0-255) mlab.figure(bgcolor=color) # set the background color of the plot P_tex = "" # initialize the LaTex string of the probabilities # Validate the quantum numbers # validate the value of n assert (n >= 1), "n must be greater or equal to 1" # validate the value of l assert (0 <= l <= n - 1), "l must be between 0 and n-1" # validate the value of p assert (-l <= max(m_) <= l), "p must be between -l and l" # validate the value of p assert (-l <= min(m_) <= l), "p must be between -l and l" for m in m_: # Determine the probability equation symbolically and convert # it to a string prob = lambdastr((radius, angle_phi, angle_theta), P(radius, n, l, m, angle_phi, angle_theta)) # record the probability equation as a LaTex string P_eq = simplify(P(r, n, l, m, phi, theta)) P_tex += "$$P =" + latex(P_eq) + "$$ \n\n " # print("prob before substitution = \n\n".format(prob)) #for debugging if '(nan)' in prob: # Check for errors in the equation print("There is a problem with the probability function.") raise ValueError # Convert the finctions in the probability equation from the sympy # library to the numpy library to allow for the use of matrix # calculations # prob = prob.replace('sin', 'np.sin') # convert to numpy # prob = prob.replace('cos', 'np.cos') # convert to numpy # prob = prob.replace('Abs', 'np.abs') # convert to numpy # prob = prob.replace('pi', 'np.pi') # convert to numpy # prob = prob.replace('exp', 'np.exp') # convert to numpy # print("prob after substitution = \n\n".format(prob)) #for debugging # convert the converted string to a callable function Prob = eval(prob) # generate a set of data to plot the contours of. w = Prob(r_fun(_x, _y, _z), phi_fun(_x, _y, _z), theta_fun(_x, _y, _z)) # add the generated data to the plot mlab.contour3d(w, contours=no_of_contours, opacity=Opaque, transparent=True) mlab.colorbar() mlab.outline() mlab.show() # this pops up a interactive window that allows you to # rotate the view # Information used for the 2D slices below limits = [] lengths = [] for cor in (_x, _y, _z): limit = (np.min(cor), np.max(cor)) limits.append(limit) # print(np.size(cor)) lengths.append(np.size(cor)) # print(limit) return (limits, lengths, _x, _y, _z, P_tex)
import sympy from sympy.utilities.lambdify import lambdastr # A line through the 3 dimensional vector a in direction s has points # (ax+t*sx, ay+t*sy, az+t*sz). To find the distance from a point at # the origin, where the derivative of the distance function (as a # function of t) has its inflection. a = sympy.DeferredVector('a') s = sympy.DeferredVector('x') t = sympy.Symbol('t') dist2 = (a[0] + s[0] * t)**2 + (a[1] + s[1] * t)**2 + (a[2] + s[2] * t)**2 ddist2_dt = sympy.diff(dist2, t) func = sympy.solvers.solve(ddist2_dt, t) #print func print lambdastr((a, s), func[0])
import sympy from sympy.utilities.lambdify import lambdastr # A line through the 3 dimensional vector a in direction s has points # (ax+t*sx, ay+t*sy, az+t*sz). To find the distance from a point at # the origin, where the derivative of the distance function (as a # function of t) has its inflection. a = sympy.DeferredVector('a') s = sympy.DeferredVector('x') t=sympy.Symbol('t') dist2 = (a[0]+s[0]*t)**2 + (a[1]+s[1]*t)**2 + (a[2]+s[2]*t)**2 ddist2_dt = sympy.diff(dist2,t) func = sympy.solvers.solve(ddist2_dt, t) #print func print lambdastr((a,s),func[0])
e_equil = -((-(9.81 * rod_mass) / rod_spring) + e_offset_scalar) if j == 0: p = ((r21_x * x + a2_x * r1_x) * z - r21_z * x**2 + (r1_z * r2_x - r1_x * r2_z + a2_x * r21_z - a2_z * r2_x) * x + r1_x * (a2_x * r2_z - a2_z * r2_x)) equation_all = p.subs({ H: workspace_width, a: plate_width, b: plate_height, phi: theta, e: e_equil }).evalf() equation_all = equation_all.simplify() lambda_str1 = lambdastr((theta), equation_all) lambda_str2 = lambda_str1.replace('sin', 'np.sin') lambda_str3 = lambda_str2.replace('cos', 'np.cos') lambda_str4 = lambda_str3.replace('x', 'x_temp') lambda_str = lambda_str4.replace('z', 'z_temp') func1 = eval(lambda_str) # In[4]: x_values_heat = np.linspace(x_begin, x_end, 100) z_values_heat = np.linspace(z_begin, z_end, 100) theta_values_heat = [] x_values_heatp = [] z_values_heatp = [] for j in range(100):
def __init__(self, model, *setup, **operation): # Collect parameter values environment = dict() for s in setup + (operation,): if isinstance(s, dict): environment.update(s) elif isinstance(s, System): environment.update(s.environment) else: environment.update(s.__dict__) E = self.environment = environment M = self.model = (sympify(pythonify(model), self._skip.copy()) if isinstance(model, str) else (model[0] if len(model) == 1 else Matrix(model)) if isinstance(model, list) else model) S = symbols = (dict([(a.name, a) for a in M.atoms(Symbol)]) if isinstance(M, Basic) else dict()) # Find applicable substitutions and remaning undefined parameters. A = self.applied = dictmap(set(S).intersection(E), E.get) I = self.implicit = dict() R = self.remaining = dictmap(set(S).difference(A), S.get) # S = A + R now. # Use I for objects in A that sympy can't handle. if A: # Evaluate all sub-expressions. May expand A + I + R. for n, v in A.copy().items(): if isinstance(v, Basic) and not isinstance(v, Symbol): try: assert len(v.atoms(Symbol)) > 1 except: continue v = v(E) if isinstance(v, System) else System(v, E) A.update(v.applied) A[n] = v.result I.update(v.implicit) R.update(v.remaining) # M /. E == M /. A now. A may contain sympy-incompatible objects. # Categorize A. Q = dict([(n, v) for n, v in A.items() if isinstance(v, Quantity) and not n[0] == '_']) I.update([(n, v) for n, v in A.items() if isinstance(v, Iterable) and not n in Q]) OK = dictmap(set(A).difference(Q).difference(I), A.get) # M /. E == M /. (OK + I + Q) now. Only OK is sympy-compatible. # Eliminate Q by expanding OK and I. for n, q in Q.items(): q = SymQuantity(q, n) I.update(q.implicit) OK[n] = q.result # M /. E == M /. (OK + I) == (M /. OK) /. I now. # Evalute M /. OK symbolically. try: result = M.subs(OK).evalf() except Exception as err: raise Exception('%s /. %s: %s' % (M, params(OK), err)) # M /. E == result /. I now. # If possible, evaluate result /. I numerically. if not R and isinstance(result, Basic): try: result = eval(lambdastr(I, result))(*I.values()) except Exception as err: raise Exception('%s /. %s: %s' % (result, params(I), err)) self.implicit = dict() self.result = result else: self.result = M self.implicit = dict()
def __repr__(self) -> str: '''Returns a string of the vector field in angle-bracket notation with lambda parameters.''' x, y = sym.symbols('x y') return '{} = <{}, {}>'.format(self.name, lambdastr((x, y), self.__usym), lambdastr((x, y), self.__vsym))
def display_orbital(n, l, m_, no_of_contours=16, Opaque=0.5): """Diplays a 3D view of electron orbitals""" #The plot density settings (don't mess with unless you are sure) rng = 12 * n * 1.5 #This determines the size of the box _steps = 100j # (it needs to be bigger with n). steps = _steps.imag _x, _y, _z = np.ogrid[-rng:rng:_steps, -rng:rng:_steps, -rng:rng:_steps] P_tex = "" #initialize the LaTex string of the probabilities #Validate the quantum numbers assert (n >= 1), "n must be greater or equal to 1" #validate the value of n assert (0 <= l <= n - 1), "l must be between 0 and n-1" #validate the value of l assert (-l <= max(m_) <= l), "p must be between -l and l" #validate the value of p assert (-l <= min(m_) <= l), "p must be between -l and l" #validate the value of p for m in m_: #Determine the probability equation symbolically and convert #it to a string prob = lambdastr((radius, angle_phi, angle_theta), P(radius, n, l, m, angle_phi, angle_theta)) #record the probability equation as a LaTex string P_eq = simplify(P(r, n, l, m, phi, theta)) P_tex += "$$P =" + latex(P_eq) + "$$ \n\n " if '(nan)' in prob: #Check for errors in the equation print("There is a problem with the probability function.") raise ValueError #Convert the finctions in the probability equation from the sympy #library to the numpy library to allow for the use of matrix #calculations prob = prob.replace('sin', 'np.sin') #convert to numpy prob = prob.replace('cos', 'np.cos') #convert to numpy prob = prob.replace('Abs', 'np.abs') #convert to numpy prob = prob.replace('pi', 'np.pi') #convert to numpy prob = prob.replace('exp', 'np.exp') #convert to numpy #convert the converted string to a callable function Prob = eval(prob) #generate a set of data to plot the contours of. w = Prob(r_fun(_x, _y, _z), phi_fun(_x, _y, _z), theta_fun(_x, _y, _z)) #Remove nan's in grid w w[np.isnan(w)] = 0 #Determine minimum and maximum value (probability density) in the grid w minw = np.nanmin(w) maxw = np.nanmax(w) # print(minw, maxw) #Determine value slices colorSlice = (maxw - minw) / (no_of_contours) #Create contour lookup array pr = np.linspace(minw, maxw, no_of_contours) # print(pr) buildGridAndCreate(int(steps), pr, w) ######### #select object as active and change toggle to editmode bpy.context.scene.objects.active = bpy.data.objects['Orbital'] bpy.ops.object.mode_set(mode='EDIT') # Get the active mesh ob = bpy.context.edit_object me = ob.data # Get a BMesh representation bm = bmesh.from_edit_mesh(me) # Modify the BMesh, can do anything here... for v in bm.verts: v.co.x += 1.0 # Show the updates in the viewport # and recalculate n-gon tessellation. bmesh.update_edit_mesh(me, True) bpy.ops.object.mode_set(mode='OBJECT') ######## #Information used for the 2D slices below limits = [] lengths = [] for cor in (_x, _y, _z): limit = (np.min(cor), np.max(cor)) limits.append(limit) #print(np.size(cor)) lengths.append(np.size(cor)) #print(limit) return (limits, lengths, _x, _y, _z, P_tex)
f1 = (_E1.T * _E1 - ONE)**2 + (_E2.T * _E2 - ONE)**2 + (_E1.T * _E2)**2 f2 = (R.T * R - ONE)**2 + (_E1.T * R - E1.T * R)**2 + (_E2.T * R - E2.T * R)**2 f3 = (P_i.T * _E1 - Matrix([x2_s]))**2 + (P_i.T * _E2 - Matrix([y2_s]))**2 #f1 = sq(_E1.T * _E1, ONE) + sq(_E2.T * _E2, ONE) + sq(_E1.T * _E2, ZERO) print(f1) substitution = [(_E1, F1), (_E2, F2), (_R, R)] f = f1 + f2 + f3 func = Matrix(f.subs(substitution)) #f = f.subs(_E2, F2) #f.subs(_R, R) lam_f = lambdify(var, func, 'numpy') print(lambdastr(var,func)) def lam(x2, y2, p, e_1, e_2): return lambda a1,b1,c1,a2,b2,c2,t,s: \ lam_f(x2, y2, p, e_1, e_2, a1, b1, c1, a2, b2, c2, t, s) arr_init = np.array([1, 0, 0, 0, 1, 0, 1, 1]) print("lambda: ready") ######## Graph Drawing ######## root = Tk() w = Canvas(root, width=_wid, height=_hei, bg='White') w.pack() circles = [] lines = [] r = 10
_E1.dot(_E1) - 1, _E2.dot(_E2) - 1, _E1.dot(_E2), R.dot(R) - 1, _E1.dot(R) - sp.Matrix(E1).dot(R), _E2.dot(R) - sp.Matrix(E2).dot(R), sp.Matrix(P_i).dot(_E1) - x2_s, sp.Matrix(P_i).dot(_E2) - y2_s ]) [e * e for e in [e1, e2, e3]] func = sp.simplify(sp.Matrix.norm(f)) lam_f = lambdify(var, func, 'numpy') print(lambdastr(var, func)) print(lambdastr(var, _E1)) print(lambdastr(var,_E1.dot(_E1))) def lam(x2, y2, p, e_1, e_2): return lambda a1,b1,c1,a2,b2,c2,t,s: \ lam_f(x2, y2, p, e_1, e_2, a1, b1, c1, a2, b2, c2, t, s) arr = np.array([1, 1, 1, 1, 1, 1, 1, 1]) print("lambda: ready") #X_sample = 3 * np.random.random_sample((100, 1)) - 1.5 #Y_sample = 3 * np.random.random_sample((100, 1)) - 1.5 print("ready") """
def make_njit_fn(args, fn_expr): fn_str = lambdastr(args, fn_expr).replace('MutableDenseMatrix', '')\ .replace('(([[', '[') \ .replace(']]))', ']') jit_fn = numba.njit(parallel=True)(eval(fn_str)) return jit_fn
def gen_ode_model(self): """ Generate a lambda (self.f_model) from the Sympy expressions in self.equations that takes the values for all species and parameters and returns dX/dt. Returns ------- None """ # Prune any term from an equation that is not either a constant or the LHS of another equation. pruned_eqs = [] lhs = [eq.lhs.args[0] for eq in self.equations] for eq in self.equations: for arg in self.ravel_expression(eq.rhs): if arg not in lhs and not isinstance(arg, Constant): eq = eq.subs(arg, 0) pruned_eqs.append(eq) self.equations = pruned_eqs # Process rhss = [i.rhs for i in self.equations] all_args = [] for eq in rhss: args = self.ravel_expression(eq) for a in args: all_args.append(a) # remove duplicates unique_sels = [] unique_consts = [] seen_sel = [] seen_const = [] for val in all_args: if isinstance(val, Selector): if val.selector not in seen_sel: seen_sel.append(val.selector) unique_sels.append(val) elif isinstance(val, Constant): if val.name not in seen_const: seen_const.append(val.name) unique_consts.append(val) else: print('unable to handle %s' % val) self.species = unique_sels self.params = unique_consts # We need the rhss in the same order as the same order as the unique_sels to pass to lambdify. ordered_rhss = [] # In the process, we will rearrange self.equations to be in the same order. ordered_equations = [] for arg in unique_sels: for eq in self.equations: if eq.lhs.args[0].selector == arg.selector: ordered_rhss.append(eq.rhs) ordered_equations.append(eq) self.equations = ordered_equations unique_args = unique_sels + unique_consts self.unique_args = unique_args self.ordered_rhss = ordered_rhss self.f_model = sy.lambdify(unique_args, ordered_rhss) self.f_model = njit(self.f_model) print( "celltx ODELayer: Successfully compiled self.f_model to C via njit." ) self.lambda_string = lambdastr(unique_args, ordered_rhss, dummify=True) # Also generate starting conditions self.x0 (zeros for each species) self.x0 = np.zeros(len(self.species))
def compute(self, maximize=False, constraints=None): """ Solves the system and computes the responses. """ # Expand expressions on first time. if not self.exprs: self.exprs = self.parser.expand(self.exprs_str, self.idx_bounds, self.syms) u_math = umath if not self.analytical else a_umath # Generate an ordering for inputs. if not self.ordered_given: for (k, v) in self.given.iteritems(): self.ordered_given.append(k) q_ordered_given = [] # Ordered given list fed to optimization, might be different from ordered_given. opt_ordered_given = [] opt_q_ordered_given = [] self.opts = [] for (k, v) in self.given.iteritems(): if isinstance(v, str) and v == 'opt': self.opts.append(k) else: opt_ordered_given.append(k) opt_q_ordered_given.append(v) # Do minimization if needed. if self.opts: opt_given = [] for k in self.opts: opt_given.append(k) opt_ordered_given = opt_given + opt_ordered_given opt_val = self.optimize(opt_ordered_given, opt_q_ordered_given, maximize) # Assemble q_ordered_given according to ordered_given. for k in self.ordered_given: if isinstance(self.given[k], str) and self.given[k] == 'opt': q_ordered_given.append(opt_val[k]) else: q_ordered_given.append(self.given[k]) # Solve for intermediate solution set, use cached version if possible. if not self.sol_inter_set: self.sol_inter_set = solve(self.exprs, exclude=self.ordered_given, check=False, manual=True)[0] """ Uncomment following code to print intermediate solution set. logging.debug('Sheet -- Partial Solutions:') for k, s in self.sol_inter_set.iteritems(): logging.debug('Inter -- {}: {}'.format(k, s)) """ # Generate intermediate funcs, use cached version if possible. if not self.inter_funcs: for var in self.intermediates.keys(): if var in self.sol_inter_set: logging.debug('{} Lambdification -- {}'.format(var, self.sol_inter_set[var])) self.inter_funcs[var] = lambdify(tuple(self.ordered_given), self.sol_inter_set[var], modules=[self.sym2func, u_math]) else: print "WARN: ignoring %r, no solution found!" % var else: # Make sure that all intermediates have a solution. for k in self.intermediates.keys(): assert(k in self.inter_funcs) # Before generating quantities for intermediates, # if we are performing analytical analysis, # we need to convert any MC given to analytical form when needed. if self.analytical: q_ordered_given = self.conv2analytical(q_ordered_given) for q in q_ordered_given: assert(not isinstance(q, UncertainFunction)) # Organize intermediates based on an ordering. ordered_intermediates = [] q_ordered_intermediates = [] for (k, v) in self.intermediates.iteritems(): if k in self.inter_funcs: ordered_intermediates.append(k) mean_intermediate = float(self.inter_funcs[k](*tuple(q_ordered_given))) assert(callable(v)) q_ordered_intermediates.append(v(mean_intermediate)) logging.debug('Sheet -- Inter {}: {}'.format( ordered_intermediates[-1], q_ordered_intermediates[-1])) # Solve for final solution set, use cached version if possible. if not self.sol_final_set: self.sol_final_set = solve(self.exprs, exclude=self.ordered_given + ordered_intermediates, check=False, manual=True)[0] """ Uncomment the following to print final solution set. logging.debug('Sheet -- Final Solutions:') for k, s in self.sol_final_set.iteritems(): logging.debug('Final -- {}: {}'.format(k, s)) """ # Generate target funcs, use cached version if possible. if not self.target_funcs: for var in self.response: logging.debug('{} Lambdification -- {}'.format(var, lambdastr(tuple(self.ordered_given + ordered_intermediates), self.sol_final_set[var]))) self.target_funcs[var] = lambdify(tuple(self.ordered_given + ordered_intermediates), self.sol_final_set[var], modules=[self.sym2func, u_math]) # Before generating quantities for final responses, # we need to convert any MC intermediate quantities to analytical form when needed. if self.analytical: q_ordered_intermediates = self.conv2analytical(q_ordered_intermediates) for q in q_ordered_intermediates: assert(not isinstance(q, UncertainFunction)) # Compute response. q_response = {} for var in self.response: logging.debug('Solving {}'.format(str(var))) perf = self.target_funcs[var](*tuple(q_ordered_given + q_ordered_intermediates)) q_response[str(var)] = perf return q_response
def _print_sympy(expr): return lambdastr((), expr, printer=_NumericPrinter)[len('lambda : '):]
def compute(self, maximize=False, constraints=None): """ Solve the system and apply the quantification. """ # Expand expressions on first time. if not self.exprs: self.exprs = self.parser.expand(self.exprs_str, self.idx_bounds, self.syms) u_math = umath if not self.analytical else a_umath # Generate an ordering for inputs. if not self.ordered_given: for (k, v) in self.given.iteritems(): self.ordered_given.append(k) q_ordered_given = [] # Ordered given list fed to optimization, might be different from ordered_given. opt_ordered_given = [] opt_q_ordered_given = [] self.opts = [] for (k, v) in self.given.iteritems(): if isinstance(v, str) and v == 'opt': self.opts.append(k) else: opt_ordered_given.append(k) opt_q_ordered_given.append(v) # Do minimization if needed. if self.opts: opt_given = [] for k in self.opts: opt_given.append(k) opt_ordered_given = opt_given + opt_ordered_given opt_val = self.optimize(opt_ordered_given, opt_q_ordered_given, maximize) # Assemble q_ordered_given according to ordered_given. for k in self.ordered_given: if isinstance(self.given[k], str) and self.given[k] == 'opt': q_ordered_given.append(opt_val[k]) else: q_ordered_given.append(self.given[k]) # Solve for final solution set, use cached version if possible. if not self.sol_set: sol_sets = solve(self.exprs, exclude=self.ordered_given, check=False, manual=True) assert len(sol_sets) == 1, 'Multiple solutios possible, consider rewrite model.' self.sol_set = sol_sets[0] logging.debug('Sheet -- Given: {}'.format(self.ordered_given)) logging.debug('Sheet -- Solutions:') for k, s in self.sol_set.iteritems(): logging.debug('\t{}: {}'.format(k, s)) # Generate target funcs, use cached version if possible. for var in self.response: if var not in self.target_funcs: self.target_funcs[var] = (lambdify(tuple(self.ordered_given), self.sol_set[var], modules=[self.sym2func, u_math])) logging.debug('Lamdification {} {} --\n\t{}'.format(var, self.target_funcs[var], lambdastr(tuple(self.ordered_given), self.sol_set[var]))) # Compute response. q_response = {} for var in self.response: logging.debug('Solving {}'.format(str(var))) logging.debug('Params:\n{}\n{}'.format( self.ordered_given, q_ordered_given)) logging.debug('Calling {}'.format(self.target_funcs[var])) perf = self.target_funcs[var](*tuple(q_ordered_given)) q_response[str(var)] = perf return q_response
d_inner_by_dt = partial_L_by_partial_qdot.jacobian(Matrix( [q])) * qdot + partial_L_by_partial_qdot.jacobian(Matrix([qdot])) * qddot # Euler-Lagrange equation lagrange_eq = partial_L_by_partial_q - d_inner_by_dt + Matrix([f, 0, 0]) # solve the lagrange equation for qddot and simplify print("Calculations take a while...") r = sympy.solvers.solve(simplify(lagrange_eq), Matrix([qddot])) qddot_0 = simplify(r[qddot_0]) qddot_1 = simplify(r[qddot_1]) qddot_2 = simplify(r[qddot_2]) print('qddot_0 = {}\n'.format(qddot_0)) print('qddot_1 = {}\n'.format(qddot_1)) print('qddot_2 = {}\n'.format(qddot_2)) # generate python function s = lambdastr( (q_0, q_1, q_2, qdot_0, qdot_1, qdot_2, f, r_1, r_2, m_c, m_1, m_2, g), [qdot_0, qdot_1, qdot_2, qddot_0, qddot_1, qddot_2]) f_gen = open("dpc_dynamics_generated.py", 'w') f_gen.write( "import math\ndef dpc_dynamics_generated(q_0, q_1, q_2, qdot_0, qdot_1, qdot_2, f, r_1, r_2, m_c, m_1, m_2, g):\n\tfun=" + s + "\n\treturn fun(q_0, q_1, q_2, qdot_0, qdot_1, qdot_2, f, r_1, r_2, m_c, m_1, m_2, g)" ) f_gen.close()