def print_jacobian_component(self, s1, s2, assign_to=None, print_zeros=True): if s1 == self.energy_term: st = sum( self.cooling_actions[ca].equation for ca in sorted(self.cooling_actions) ) else: st = self.species_total(s1) if assign_to is None: assign_to = sympy.Symbol("d_%s_%s" % (s1.name, s2.name)) if isinstance(st, (list, tuple)): codes = [] for temp_name, temp_eq in st[0]: teq = sympy.sympify(temp_eq) codes.append(ccode(teq, assign_to=temp_name)) codes.append(ccode(st[1], assign_to=assign_to)) return "\n".join(codes) eq = sympy.diff(st, s2.symbol) #eq = eq.replace( # lambda x: x.is_Pow and x.exp > 0 and x.exp == sympy.Integer, # lambda x: sympy.Symbol("*".join([x.base.name] * x.exp)), #) if eq == sympy.sympify("0") and not print_zeros: return return ccode(eq, assign_to=assign_to)
def test_goto_Label(): s = 'early_exit' g = goto(s) assert g.func(*g.args) == g assert g != goto('foobar') assert ccode(g) == 'goto early_exit' l1 = Label(s) assert ccode(l1) == 'early_exit:' assert l1 == Label('early_exit') assert l1 != Label('foobar') body = [PreIncrement(x)] l2 = Label(s, body) assert l2.name == String("early_exit") assert l2.body == CodeBlock(PreIncrement(x)) assert ccode(l2) == ("early_exit:\n" "++(x);") body = [PreIncrement(x), PreDecrement(y)] l2 = Label(s, body) assert l2.name == String("early_exit") assert l2.body == CodeBlock(PreIncrement(x), PreDecrement(y)) assert ccode(l2) == ("early_exit:\n" "{\n ++(x);\n --(y);\n}")
def genEval(self): text = " bool evaluate(\n" args=[] for name,v in self.variables: if v.is_Matrix: args.append(" const Eigen::MatrixXd & %s" % name) else: args.append(" double %s" % name) args.append(" bool evalF=true,bool evalJ=true") text += ",\n".join(args) + ") {\n" text += " if (evalF) {\n" (interm, expr) = cse(self.function,numbered_symbols("__x")); for dummy,exp in interm: text += " double %s = %s;\n" % (str(dummy),ccode(exp)) for i in range(self.function.rows): text += " F(%d) = %s;\n" % (i,ccode(expr[0][i])) text += " }\n" text += " if (evalJ) {\n" (interm, expr) = cse(self.J,numbered_symbols("__x")); for dummy,exp in interm: text += " double %s = %s;\n" % (str(dummy),ccode(exp)) for i in range(self.J.rows): for j in range(self.J.cols): text += " J(%d,%d) = %s;\n" % (i,j,ccode(expr[0][i,j])) text += " }\n" text += " return true;\n" text += " }\n" return text
def commonsubelim(filename1, filename2): modifiedlines = [] with open(filename1, 'r') as file: for line in file: line = line.strip('\n') currentline = line + '\n' flag = False if ('=' in line): line = line.strip(';') lines = line.split('=') docse = False lines[1] = lines[1].replace(' ', '') docse = re.search("[0-9]", lines[1]) if (not docse): lines[1] = eval(lines[1]) compressedexpr = cse(lines[1], numbered_symbols("help")) currentline = lines[0] + '=' for helper in compressedexpr[0]: flag = True #currentline=currentline+str(ccode(helper[1],helper[0]))+"\n" modifiedlines.append("int " + str(ccode(helper[1], helper[0])) + "\n") for i, result in enumerate(compressedexpr[1]): modifiedlines.append("int " + (ccode(result, "result"))) modifiedlines.append("\n") if (flag == False): modifiedlines.append(currentline) with open(filename2, 'w') as file: for line in modifiedlines: file.write(line) file.write('\n') file.truncate()
def get_Integrand_with_c(self): ''' For all of this i used the ccode function of sympy to generate C code for the integrand. What's happening is, that a C-File with the function, which will get integrated over later on, gets created and compiled. The generated C-code has not the form i need it to be, so some symbols need to be modified. Like exp to cexp and so on. I have an option self.Comp_String, which when True causes the C-File to get compiled in one OS-Command instead of seperate commands. I tried this out, because i thought that the first option could be faster. But it was not, if i remember correctly. Also that's not the Bottleneck of my programm, so i didn't focus on that any longer. Since the integration algorithm is in another file and is except for the integration boundaries fixed, i decided just to do it by hand every time. Those boundaries are for now also fixed, so it's ok. ''' a = ccode(self.lagrangian_without_bound_constr()) b = ccode(self.boundadness_constraint()) g = open(get_data('funcprint2.txt'), 'r') g1 = g.read() g.close() Whole_String = '' Bibliotheken = '#include <math.h>\n' + '#include <complex.h>\n' + '#include <stdio.h>\n' Prototypen = 'static float xsav;\n' + 'static float(*nrfunc)(float,float);\n' Integranddef = "float f(float r, float t)" + "{return" Begin_von_Func = " 1/(2*cpow(M_PI,2)) + (fmax(creall(" Func1 = a.replace("exp", "cexp").replace("pow", "cpow").replace( "r_0", "r").replace("t_0", "t") Func1_End = "),0)" Whole_String += Bibliotheken + Prototypen + Integranddef + Begin_von_Func + Func1 + Func1_End Func2_Anf = "+ creall(" Func2 = b.replace("exp", "cexp").replace("pow", "cpow").replace( "r_0", "r").replace("t_0", "t") if self.Schwartzfunktion: Func22 = '))*sin(1.0L*r)*sin(1.0L*r)' Func2_End = '*cexp(-(cpow(t,2)/' + "cpow(%2.0f,2)))" % ( self.T) + ';' + '}\n' Whole_String += Func2_Anf + Func2 + Func22 + Func2_End + g1 else: Func22 = '))*sin(1.0L*r)*sin(1.0L*r);}\n' Whole_String += Func2_Anf + Func2 + Func22 + g1 if self.Comp_String: os.system('gcc -o testlib2' + ' << EOF ' + Whole_String + 'EOF -lm') else: f = open('testlib2.c', 'w') f.write(Whole_String) f.close() os.system('gcc -o testlib2 testlib2.c -lm')
def temperature_calculation(self, derivative=False, derivative_dge_dT=False, get_dge=False): # If derivative=True, returns the derivative of # temperature with respect to ge. Otherwise, # returns just the temperature function ge = sympy.Symbol('ge') function_eq = (sympy.Symbol('density') * ge * sympy.Symbol('mh')) / \ (sympy.Symbol('kb') * (self.gamma_factor())) #function_eq = (ge) / \ # (sympy.Symbol('kb') * (self.gamma_factor())) if derivative == True: deriv_eq = sympy.diff(function_eq, ge) return ccode(deriv_eq) elif derivative_dge_dT == True: # when H2 presents, the gamma is dependent on temperature # therefore temperature must iterate to a convergence for a given ge # this part evaluates the derivatives of the function ge with respect to T T = sympy.Symbol('T') f = self.gamma_factor(temp=True) * sympy.Symbol('kb') * sympy.Symbol('T') \ / sympy.Symbol('mh') / sympy.Symbol('density') dge_dT = sympy.diff(f, T) tmp = sympy.Symbol('tmp') for sp in self.interpolate_gamma_species: # substitute the sympy function with sympy Symbols sym_fgamma = sympy.Function('gamma%s' % sp.name)(T) sym_dfgamma = sympy.diff(sym_fgamma, T) dgamma = sympy.Symbol('dgamma%s_dT' % sp.name) dge_dT = dge_dT.subs({sym_dfgamma: dgamma}) fgamma = sympy.Symbol('gamma%s' % sp.name) dge_dT = dge_dT.subs({sym_fgamma: tmp}) dge_dT = dge_dT.subs({tmp: fgamma}) return ccode(dge_dT) elif get_dge == True: T = sympy.Symbol('T') dge = self.gamma_factor( temp=True) * sympy.Symbol('kb') * T / sympy.Symbol( 'mh') / sympy.Symbol('density') - sympy.Symbol('ge') tmp = sympy.Symbol('tmp') for sp in self.interpolate_gamma_species: sym_fgamma = sympy.Function('gamma%s' % sp.name)(T) fgamma = sympy.Symbol('gamma%s' % sp.name) dge = dge.subs({sym_fgamma: tmp}) dge = dge.subs({tmp: fgamma}) return ccode(dge) else: return ccode(function_eq)
def test_goto_Label(): s = 'early_exit' g = goto(s) assert g.func(*g.args) == g assert g != goto('foobar') assert ccode(g) == 'goto early_exit' l = Label(s) assert l.is_Atom assert ccode(l) == 'early_exit:' assert g.label == l assert l == Label(s) assert l != Label('foobar')
def C99_print(expr): CSE_results = cse(expr, numbered_symbols("helper_"), optimizations='basic') lines = [] for helper in CSE_results[0]: if isinstance(helper[1], MatrixSymbol): lines.append('const auto ' + str(helper[0]) + '[' + str(helper[1].rows * helper[1].cols) + '];') lines.append(ccode(helper[1], helper[0])) else: lines.append('const auto ' + ccode(helper[1], helper[0])) for i, result in enumerate(CSE_results[1]): lines.append(ccode(result, "result_%d" % i)) return '\n'.join(lines)
def test_compiled_ccode_with_rewriting(): if not cython: skip("cython not installed.") if not has_c(): skip("No C compiler found.") x = Symbol('x') about_two = 2**(58/S(117))*3**(97/S(117))*5**(4/S(39))*7**(92/S(117))/S(30)*pi # about_two: 1.999999999999581826 unchanged = 2*exp(x) - about_two xval = S(10)**-11 ref = unchanged.subs(x, xval).n(19) # 2.0418173913673213e-11 rewritten = optimize(2*exp(x) - about_two, [expm1_opt]) # Unfortunately, we need to call ``.n()`` on our expressions before we hand them # to ``ccode``, and we need to request a large number of significant digits. # In this test, results converged for double precision when the following number # of significant digits were chosen: NUMBER_OF_DIGITS = 25 # TODO: this should ideally be automatically handled. func_c = ''' #include <math.h> double func_unchanged(double x) { return %(unchanged)s; } double func_rewritten(double x) { return %(rewritten)s; } ''' % dict(unchanged=ccode(unchanged.n(NUMBER_OF_DIGITS)), rewritten=ccode(rewritten.n(NUMBER_OF_DIGITS))) func_pyx = ''' #cython: language_level=3 cdef extern double func_unchanged(double) cdef extern double func_rewritten(double) def py_unchanged(x): return func_unchanged(x) def py_rewritten(x): return func_rewritten(x) ''' with tempfile.TemporaryDirectory() as folder: mod, info = compile_link_import_strings( [('func.c', func_c), ('_func.pyx', func_pyx)], build_dir=folder, compile_kwargs=dict(std='c99') ) err_rewritten = abs(mod.py_rewritten(1e-11) - ref) err_unchanged = abs(mod.py_unchanged(1e-11) - ref) assert 1e-27 < err_rewritten < 1e-25 # highly accurate. assert 1e-19 < err_unchanged < 1e-16 # quite poor.
def build_cse_fn(symname, symfunc, symbolslist): tmpsyms = numbered_symbols("R") symbols, simple = cse(symfunc, symbols=tmpsyms) code = "double %s(%s)\n" % (str(symname), ", ".join( "double const& %s" % x for x in symbolslist)) code += "{\n" for s in symbols: code += " double %s = %s;\n" % (ccode(s[0]), ccode(s[1])) code += " double result = %s;\n" % ccode(simple[0]) code += " return result;\n" code += "}\n" return code
def temperature_calculation(self, derivative=False): # If derivative=True, returns the derivative of # temperature with respect to ge. Otherwise, # returns just the temperature function ge = sympy.Symbol('ge') function_eq = (sympy.Symbol('density') * ge * sympy.Symbol('mh')) / \ (sympy.Symbol('kb') * (self.gamma_factor())) #function_eq = (ge) / \ # (sympy.Symbol('kb') * (self.gamma_factor())) if derivative == True: deriv_eq = sympy.diff(function_eq, ge) return ccode(deriv_eq) else: return ccode(function_eq) return ccode(eq)
def get_Integrand_with_ctypes(self): a = ccode(self.lagrangian_without_bound_constr()) b = ccode(self.boundadness_constraint()) Whole_String = '' Bibliotheken = '#include <math.h>\n' + '#include <complex.h>\n' + '#include <stdio.h>\n' Integranddef = "double f(int n, double args[n])" + "{return" Begin_von_Func = " 1/(2*cpow(M_PI,2)) + (fmax(creall(" #I added, 1/2*pi^2 because #the Integral can be zero, #and then the integration takes #very long due to error control. #By adding the factor above we make #the integral one bigger, and then #at the and we just need to substract it #again. Func1 = a.replace("exp", "cexp").replace("r_0", "args[0]").replace( "pow", "cpow").replace("t_0", "args[1]") Func1_End = "),0)" Whole_String += Bibliotheken + Integranddef + Begin_von_Func + Func1 + Func1_End Func2_Anf = "+ creall(" Func2 = b.replace("exp", "cexp").replace("r_0", "args[0]").replace( "pow", "cpow").replace("t_0", "args[1]") g = open(get_data('funcprint.c'), 'r') g1 = g.read() if self.Schwartzfunktion: Func22 = '))*sin(1.0L*args[0])*sin(1.0L*args[0])' Func2_End = '*cexp(-(cpow(args[1],2)/' + "cpow(%2.0f,2)))" % ( self.T) + ';' + '}\n' Whole_String += Func2_Anf + Func2 + Func22 + Func2_End + g1 else: Func22 = '))*sin(1.0L*args[0])*sin(1.0L*args[0]);}\n' Whole_String += Func2_Anf + Func2 + Func22 + g1 if self.Comp_String: os.system('gcc -x c -shared -o testlib2.so -fPIC' + ' << EOF ' + Whole_String + 'EOF') else: f = open('testlib2.c', 'w') f.write(Whole_String) f.close() os.system('gcc -x c -shared -o testlib2.so -fPIC testlib2.c') g.close()
def __init__(self, symbsol, V, kappa=1): x, y, t = smp.symbols('x[0], x[1], t') rhs = symbsol.diff(t) \ + (kappa * (symbsol.diff(x))).diff(x) \ + (kappa * (symbsol.diff(y))).diff(y) from sympy.printing import ccode self.sol = Expression(ccode(symbsol), t=0.0) self.rhs = Expression(ccode(rhs), t=0.0) self.V = V v = TestFunction(V) u = TrialFunction(V) # Assemble system M = assemble(inner(u, v)*dx) A = assemble(kappa * inner(grad(u), grad(v)) * dx) # Convert DOLFIN representation to numpy arrays rows, cols, values = M.data() self.M = sps.csr_matrix((values, cols, rows)) """csr matrix for the mass""" rows, cols, values = A.data() self.A = sps.csr_matrix((values, cols, rows)) """csr matrix representing the weak discrete :math:`-\\nabla \\cdot (\\kappa \\nabla )` operator""" # treatment of the boundary values nv = self.A.shape[0] auxu = np.zeros((nv,1)) self.bcinds = [] self.bc = DirichletBC(self.V, self.sol, 'on_boundary') self.bcdict = self.bc.get_boundary_values() auxu[self.bcdict.keys(),0] = self.bcdict.values() self.bcinds.extend(self.bcdict.keys()) self.rhsbc = - self.A*auxu # indices of the innernodes self.invinds = np.setdiff1d(range(nv),self.bcinds).astype(np.int32) # condense the coeff mats to the inner nodes self.M = self.M[self.invinds,:][:,self.invinds] self.A = self.A[self.invinds,:][:,self.invinds] self.rhsbc = self.rhsbc[self.invinds,:] self.bcvals = auxu[self.bcinds]
def extraToFile(self, path): raw = """double %sOrbitals::get_dell_alpha_phi(const Walker* walker, int qnum, int i){ double dphi; __code__ return dphi; }""" % self.name shell = """if (qnum == _q_) { __necessities__ //__simple__ dphi = __expr__ } else """ Z = Symbol('Z', positive=True, real=True) code = " " for i in range(self.maxImplemented/2): psi = self.orbitals[i] qNums = self.stateMap[i] genFac = self.genericFactor(qNums, basic=False) kdiff = diff(psi, k).factor(genFac)/psi*Z simple = self.makeReadable(str(kdiff)) nec, necList = self.getNecessities(kdiff) expr = printing.ccode(kdiff) + ";" expr = self.replaceCCode(expr, necList) #hack to get the right indent nec = "\n".join([" "*4 + nec_i for nec_i in nec.split("\n")]) subCode = shell subCode = subCode.replace("\n\n __necessities__", nec)\ .replace("__expr__", expr)\ .replace("__simple__", simple)\ .replace("_q_", str(i)) code += subCode code = code.strip("else ") ccode = raw.replace("__code__", code) with open(pjoin(path, "%sOrbitalsAlphaDeriv.cpp" % self.name), 'w') as f: f.write(ccode) f.close()
def solve_equilibrium_abundance(self, species): """write the equilibrium abundance of species sp""" from sympy.solvers import solve eq = self.species_total(species) equil_sol = solve(eq, species) return ccode(equil_sol[0], assign_to=species)
def getNecessities(self, expr): s = printing.ccode(expr) nec = [] necS = "" necS2 = "" for i, x in enumerate(self.xi): l = len(regxp.findall("pow\(%s\, \d+\)" % x, s)) if regxp.findall("[^\w]?%s[^\w]" % x, s): nec.append(x) necS += " %s = walker->r(i, %d);\n" % (x, i) if l > 0: x2 = x + "2" nec.append(x2) necS2 += " %s = %s*%s;\n" % (x2, x, x) necS = ("%s\n%s" % (necS, necS2)).strip("\n") #Manually add the lineshifts so that if no nec, then no lineshift if necS: necS = "\n\n" + necS return necS, nec
def rhs_xml(self): rhs = self.expand_integer_powers(self.rhs) s = ccode(rhs, user_functions=self._random_map) s = self.strip_L_from_rationals(s) s = self._ccode_print_warn_re.sub('', s) s = self._multiple_whitespace_re.sub(' ', s) return s
def test_sizeof(): typename = 'unsigned int' sz = sizeof(typename) assert ccode(sz) == 'sizeof(%s)' % typename assert sz.func(*sz.args) == sz assert not sz.is_Atom assert sz.atoms() == {String('unsigned int'), String('sizeof')}
def GenerateInterpolationFunction(et, p, scalar): ir = getReferenceRules(p, 0)[et] basis = getBasisFunctions(et, p) ndof = len(basis) nips = len(ir) if nips!=ndof: raise RuntimeError("Number of ips ({}) and dofs ({}) doesn't match for element {} and order {}".format(nips, ndof, et,p)) # mat = zeros((ndof,ndof), numpy.float64) mat = zeros(ndof) for i,ip in enumerate(ir): for j,phi in enumerate(basis): mat[i,j] = phi(*ip) invmat = mat**-1 # invmat = numpy.linalg.inv(mat) code = "#ifdef {}\n".format(str(et).replace('.','_')) code += "#if ORDER=={}\n".format(p) code += GetHeader(et, p, basis, scalar) x, y, z = symbols("x y z") func = 0*x values = symbols(("f[{}] "*ndof).format(*range(ndof))) for i in range(ndof): func += basis[i](x,y,z)*sum([invmat[i,j]*values[j] for j in range(ndof)]) code += " return " + str(ccode(horner(func,wrt=x))) + ";\n" code += "}\n" code += "#endif\n" code += "#endif\n\n" return code
def assign_str(self, lhs, rhs): rhs = Expression.expand_integer_powers(rhs) nmodl_str = ccode(rhs, user_functions=Expression._cfunc_map, assign_to=lhs) nmodl_str = Expression.strip_L_from_rationals(nmodl_str) nmodl_str = nmodl_str.replace(';', '') return nmodl_str
def print_jacobian_component(self, s1, s2, assign_to=None): if s1 == self.energy_term: st = sum(self.cooling_actions[ca].equation for ca in sorted(self.cooling_actions)) else: st = self.species_total(s1) if assign_to is None: assign_to = sympy.Symbol("d_%s_%s" % (s1.name, s2.name)) if isinstance(st, (list, tuple)): codes = [] for temp_name, temp_eq in st[0]: teq = sympy.sympify(temp_eq) codes.append(ccode(teq, assign_to=temp_name)) codes.append(ccode(st[1], assign_to=assign_to)) return "\n".join(codes) return ccode(sympy.diff(st, s2.symbol), assign_to=assign_to)
def print_ccode(self, species, assign_to=None): #assign_to = sympy.IndexedBase("d_%s" % species.name, (count_m,)) if assign_to is None: assign_to = sympy.Symbol("d_%s[i]" % species.name) if species == self.energy_term: return self.print_cooling(assign_to) return ccode(self.species_total(species), assign_to=assign_to)
def convert_to_c(self): """Returns a list with the c source code for the SymPy expressions Examples ======== >>> from sympy.parsing.sym_expr import SymPyExpression >>> src2 = ''' ... integer :: a, b, c, d ... real :: p, q, r, s ... c = a/b ... d = c/a ... s = p/q ... r = q/p ... ''' >>> p = SymPyExpression() >>> p.convert_to_expr(src2, 'f') >>> p.convert_to_c() ['int a = 0', 'int b = 0', 'int c = 0', 'int d = 0', 'double p = 0.0', 'double q = 0.0', 'double r = 0.0', 'double s = 0.0', 'c = a/b;', 'd = c/a;', 's = p/q;', 'r = q/p;'] """ self._ccode = [] for iter in self._expr: self._ccode.append(ccode(iter)) return self._ccode
def generate_a_code_line_simplfied(input , optimize=False): i, e, input_subs = input # Use common sub expressions instead of simpilfy # Generate directly unique CSE Symbols and tranlate them to ccode if optimize: common_sub_expressions, main_expression = cse(e.simplify()) else: common_sub_expressions, main_expression = cse(e) # Generate unique symbols for the common subexpressions cse_subs = {} common_sub_expressions_unique = [] for this_cse in common_sub_expressions: gen_sym = str(this_cse[0]) unique_sym = Symbol("cse_{}_{}".format(i,gen_sym)) cse_subs[ this_cse[0]] = unique_sym common_sub_expressions_unique.append( [unique_sym,this_cse[1]] ) # Substitute the cse symbols in mainexpression and other cse for this_cse in common_sub_expressions_unique: this_cse[1] = this_cse[1].subs(cse_subs) main_expression = main_expression[0].subs(cse_subs) cython_code = '' for this_cse in common_sub_expressions_unique: cython_code=cython_code+'double {} = {} ;\n'.format(str(this_cse[0]), ccode(this_cse[1],standard='C99')) cython_code = cython_code+"output_array[{}] = {} ;".format(i,ccode(main_expression ,standard='C99') ) # Substitute integers in the cython code cython_code = re.sub(r"(\ |\+|[^e]\-|\*|\(|\)|\/|\,)([1-9])(\ |\+|\-|\*|\(|\)|\/|\,)", r"\1 \2.0 \3 ", cython_code) for str_sym, array_sym in input_subs.items(): cython_code = re.sub(r"(\ |\+|\-|\*|\(|\)|\/|\,)({})(\ |\+|\-|\*|\(|\)|\/|\,)".format(str_sym), r"\1 {} \3 ".format(array_sym), cython_code) return cython_code
def print_mass_density(self): # Note: this assumes things are number density at this point eq = sympy.sympify("0") for s in sorted(self.required_species): if (s.weight > 0): if s.name in self.skip_weight: continue eq += s.symbol * s.weight return ccode(eq)
def _call_printer(self, routine): code_lines = [] # Compose a list of symbols to be dereferenced in the function # body. These are the arguments that were passed by a reference # pointer, excluding arrays. dereference = [] for arg in routine.arguments: if isinstance(arg, ResultBase) and not arg.dimensions: dereference.append(arg.name) return_val = None for result in routine.result_variables: if isinstance(result, Result): assign_to = routine.name + "_result" t = result.get_datatype('c') code_lines.append("{0} {1};\n".format(t, str(assign_to))) return_val = assign_to else: assign_to = result.result_var try: # order='none' is an optimization not in upstream constants, not_c, c_expr = ccode(result.expr, human=False, assign_to=assign_to, dereference=dereference, order='none') except AssignmentError: assign_to = result.result_var code_lines.append("%s %s;\n" % (result.get_datatype('c'), str(assign_to))) constants, not_c, c_expr = ccode(result.expr, human=False, assign_to=assign_to, dereference=dereference, order='none') for name, value in sorted(constants, key=str): code_lines.append("double const %s = %s;\n" % (name, value)) code_lines.append("%s\n" % c_expr) if return_val: code_lines.append(" return %s;\n" % return_val) return code_lines
def renderModelMethodImplementation(self): if self.expression is not None: implementation = ccode(self.expression) else: implementation = "ASSERT(False)" return render('model_methodImplementation.cc', dict(evalClassName=self.d['evalClassName'], myMethod=self.d['myKeyMethod'], myMethodDeclarationArgs=self.d['myMethodDeclarationArgs'], myMethodImplementation=implementation))
def test_ccode_boolean(): assert ccode(x&y) == "x&&y" assert ccode(x|y) == "x||y" assert ccode(~x) == "!x" assert ccode(x&y&z) == "x&&y&&z" assert ccode(x|y|z) == "x||y||z" assert ccode((x&y)|z) == "x&&y||z" assert ccode((x|y)&z) == "(x||y)&&z"
def test_create_expand_pow_optimization(): cc = lambda x: ccode( optimize(x, [create_expand_pow_optimization(4)])) x = Symbol('x') assert cc(x**4) == 'x*x*x*x' assert cc(x**4 + x**2) == 'x*x + x*x*x*x' assert cc(x**5 + x**4) == 'pow(x, 5) + x*x*x*x' assert cc(sin(x)**4) == 'pow(sin(x), 4)' # gh issue 15335 assert cc(x**(-4)) == '1.0/(x*x*x*x)' assert cc(x**(-5)) == 'pow(x, -5)' assert cc(-x**4) == '-x*x*x*x' assert cc(x**4 - x**2) == '-x*x + x*x*x*x' i = Symbol('i', integer=True) assert cc(x**i - x**2) == 'pow(x, i) - x*x' # gh issue 20753 cc2 = lambda x: ccode(optimize(x, [create_expand_pow_optimization( 4, base_req=lambda b: b.is_Function)])) assert cc2(x**3 + sin(x)**3) == "pow(x, 3) + sin(x)*sin(x)*sin(x)"
def print_cooling(self, assign_to): eq = sympy.sympify("0") for term in self.cooling_actions: eq += self.cooling_actions[term].equation if self.cie_cooling == 1: cie_fudge = self.cie_optical_depth_correction() eq = eq * cie_fudge return ccode(eq, assign_to=assign_to)
def generate_a_code_line(input, optimize=False): i, e, input_subs = input if optimize: cython_code = "output_array[{}] = {} ".format(i, ccode(e.simplify()), standard='C99') else: cython_code = "output_array[{}] = {} ".format(i,ccode(e, standard='C99')) # Substitute integers in the cython code cython_code = re.sub(r"(\ |\+|[^e]\-|\*|\(|\)|\/|\,)([1-9])(\ |\+|\-|\*|\(|\)|\/|\,)", r"\1 \2.0 \3 ", cython_code) for str_sym, array_sym in input_subs.items(): cython_code = re.sub(r"(\ |\+|\-|\*|\(|\)|\/|\,)({})(\ |\+|\-|\*|\(|\)|\/|\,)".format(str_sym), r"\1 {} \3 ".format(array_sym), cython_code) return cython_code
def _str_scal_func_update(method, name, objlabel): expr = getattr(method, name + '_expr') update_h = '\nvoid {0}_update();'.format(name) update_cpp = '\nvoid {0}::{1}_update()'.format(objlabel, name) + '{' symbs = expr.free_symbols if any(symb in method.args for symb in symbs): c = ccode(expr, dereference=dereference(method)) update_cpp += '\n_{0} = {1};'.format(name, c) update_cpp += '\n};' return update_h, update_cpp
def GenCode(exp): # From http://docs.sympy.org/dev/modules/utilities/codegen.html [(c_name, c_code), (h_name, c_header)] = codegen( ("exp", exp), "C", "test", header=False, empty=False) print("c_code = %s" % c_code) print("ccode = %s" % ccode(exp)) #!!!! TODO TODO TODO: we should check if we have symbolic denominator and generate code that takes care to check if the denominator is 0 and if so to abort the compuatation return None
def _str_scal_func_init_data(method, name): expr = getattr(method, name + '_expr') init_data = '{1} {0}_data = '.format(name, CONFIG_CPP['float']) symbs = expr.free_symbols if any(symb in method.args for symb in symbs): init_data += "0.;" else: c = ccode(expr, dereference=dereference(method)) init_data += '{};'.format(c) return init_data
def _str_mat_func_update(method, name, objlabel): mat = types.matrix_types[0](getattr(method, name + '_expr')) update_h = '\nvoid {0}_update();'.format(name) update_cpp = '\nvoid {0}::{1}_update()'.format(objlabel, name) + '{' for m, n, expr in mat.row_list(): symbs = expr.free_symbols if any(symb in method.args() for symb in symbs): c = ccode(expr, dereference=dereference(method)) update_cpp += '\n_{0}({1}, {2}) = {3};'.format(name, m, n, c) update_cpp += '\n};' return update_h, update_cpp
def test_ccode_Piecewise(): p = ccode(Piecewise((x,x<1),(x**2,True))) s = \ """\ if (x < 1) { x } else { pow(x,2) }\ """ assert p == s
def _call_printer(self, routine): code_lines = [] # Compose a list of symbols to be dereferenced in the function # body. These are the arguments that were passed by a reference # pointer, excluding arrays. dereference = [] for arg in routine.arguments: if isinstance(arg, ResultBase) and not arg.dimensions: dereference.append(arg.name) return_val = None for result in routine.result_variables: if isinstance(result, Result): assign_to = routine.name + "_result" t = result.get_datatype('c') code_lines.append("{0} {1};\n".format(t, str(assign_to))) return_val = assign_to else: assign_to = result.result_var try: # order='none' is an optimization not in upstream constants, not_c, c_expr = ccode(result.expr, human=False, assign_to=assign_to, dereference=dereference, order='none') except AssignmentError: assign_to = result.result_var code_lines.append( "%s %s;\n" % (result.get_datatype('c'), str(assign_to))) constants, not_c, c_expr = ccode(result.expr, human=False, assign_to=assign_to, dereference=dereference, order='none') for name, value in sorted(constants, key=str): code_lines.append("double const %s = %s;\n" % (name, value)) code_lines.append("%s\n" % c_expr) if return_val: code_lines.append(" return %s;\n" % return_val) return code_lines
def __init__(self, N, omega=None, nu=None, scheme='TH'): self.N = N if scheme == 'TH': self.mesh = smamin_thcr_mesh.getmake_mesh(N) self.V = dolfin.VectorFunctionSpace(self.mesh, "CG", 2) self.Q = dolfin.FunctionSpace(self.mesh, "CG", 1) elif scheme == 'CR': self.mesh = dolfin.UnitSquareMesh(N, N) # , 'crossed') self.V = dolfin.VectorFunctionSpace(self.mesh, "CR", 1) self.Q = dolfin.FunctionSpace(self.mesh, "DG", 0) self.velbcs = setget_velbcs_zerosq(self.mesh, self.V) self.Pdof = 0 # dof removed in the p approximation self.omega = omega self.nu = nu x, y, t, nu, om = smp.symbols('x[0], x[1], t, nu, omega') ft = smp.sin(om*t) u1 = ft*x*x*(1 - x)*(1 - x)*2*y*(1 - y)*(2*y - 1) u2 = ft*y*y*(1 - y)*(1 - y)*2*x*(1 - x)*(1 - 2*x) p = ft*x*(1 - x)*y*(1 - y) du1 = smp.diff(u1, t) du2 = smp.diff(u2, t) rhs1, rhs2, rhs3 = comp_symb_nserhs(u=u1, v=u2, p=p, nu=self.nu) from sympy.printing import ccode self.v = Expression((ccode(u1), ccode(u2)), t=0.0, omega=self.omega) self.p = Expression((ccode(p)), t=0.0, omega=self.omega) self.fv = Expression((ccode(rhs1), ccode(rhs2)), t=0.0, omega=self.omega, nu=self.nu) self.fp = Expression((ccode(rhs3)), t=0.0, omega=self.omega) self.vdot = Expression((ccode(du1), ccode(du2)), t=0.0, omega=self.omega) bcinds = [] for bc in self.velbcs: bcdict = bc.get_boundary_values() bcinds.extend(bcdict.keys()) # indices of the inner velocity nodes self.invinds = np.setdiff1d(range(self.V.dim()), bcinds)
def genEval(self): text = " bool evaluate(\n" args=[] for name,v,lD in self.variables: if isinstance(v, Matrix): args.append(" const Eigen::Matrix<double, %d, 1> & %s" % (v.rows, name)) else: args.append(" double %s" % name) args.append(" Eigen::Matrix<double, %d, 1> * F" % self.function.rows) for name,v,localDim in self.variables: if isinstance(v, Matrix): args.append(" Eigen::Matrix<double, %d, %d> * J%s" % (self.J.rows, localDim, name)) else: args.append(" Eigen::Matrix<double, %d, 1> * J%s" % (self.J.rows, name)) text += ",\n".join(args) + ") {\n" text += " if (F) {\n" (interm, expr) = cse(self.function,numbered_symbols("__x")); for dummy,exp in interm: text += " double %s = %s;\n" % (str(dummy),ccode(exp)) for i in range(self.function.rows): text += " (*F)(%d) = %s;\n" % (i,ccode(expr[0][i])) text += " }\n" text += " if (%s) {\n" % " && ".join([ "J" + name for name,v,lD in self.variables ]) (interm, expr) = cse(self.J,numbered_symbols("__x")); for dummy,exp in interm: text += " double %s = %s;\n" % (str(dummy),ccode(exp)) colBase = 0; for name,v,localDim in self.variables: for i in range(self.J.rows): for j in range(0, localDim): text += " (*J%s)(%d,%d) = %s;\n" % (name, i,j,ccode(expr[0][i,colBase + j])) colBase+=localDim text += " }\n" text += " return true;\n" text += " }\n" return text
def renderModelDerivImplementations(self): impls = [] for arg,var in zip(self.args,self.vars): if self.expression is not None: print "differentiation of", self.expression, "with respect to", var implementation = ccode(self.expression.diff(var)) else: implementation = "ASSERT(False)" impls.append(render('model_methodImplementation.cc', dict(evalClassName=self.d['evalClassName'], myMethod="D%sD%s"%(self.d['myKeyMethod'],''.join([word[0].upper()+word[1:] for word in arg.split("_")])), myMethodDeclarationArgs=self.d['myMethodDeclarationArgs'], myMethodImplementation=implementation))) return '\n\n'.join(impls)
def make_C_term(self, term, no_correct_rate, derivate=None, inverse=None, human=False, force_par=False, xify=None, set_t0=False): """transform a term into its ssm C expression OR the ssm C expression of its derivate, differentiating against the derivate (if derivate not None) OR compute inverse function """ #prefix all the state variable and parameters by ssm___ to #avoid namespace collision with Sympy as QCOSINE letters are #used by SymPy myterm = self.change_user_input(term) safe = '' for r in myterm: if r in self.all_par: safe += 'ssm___' + r elif inverse and r == inverse: safe += 'ssm___' + r else: safe += r if derivate: sy = Symbol(str('ssm___' + derivate)) if derivate != 'x' else Symbol(derivate) pterm = diff(sympify(safe), sy) elif inverse: if inverse in myterm: sy = Symbol(str('ssm___' + inverse)) pterm = solve(sympify(safe), sy) if not pterm: raise SsmError("can't find a solution to " + term + "=0 solving for " + inverse) elif len(pterm)!=1: raise SsmError("no unique solution for " + term + "=0 solving for " + inverse) else: pterm = pterm[0] else: pterm = sympify(safe) else: pterm = sympify(safe) #remove the ssm___ prefix #term = ccode(simplify(pterm)).replace('ssm___', '') ##NOTE simplify is just too slow to be used... term = ccode(pterm).replace('ssm___', '') #make the ssm C expression return self.generator_C(term, no_correct_rate, force_par=force_par, xify=xify, human=human, set_t0=set_t0)
def __init__(self, convection_field, forcing_function): self._forcing_function = forcing_function self._convection_field = convection_field dx0 = sg.diff(convection_field[0], x) dx1 = sg.diff(convection_field[1], x) dy0 = sg.diff(convection_field[0], y) dy1 = sg.diff(convection_field[1], y) to_ccode = lambda u: sp.ccode( sympy.sympify(sg.symbolic_expression(u)._sympy_())) self._forcing_code = _forcing_template.format( **{'forcing_expr': to_ccode(forcing_function)}) self._convection_code = _convection_template.format(** {'value0_expr': to_ccode(convection_field[0]), 'value1_expr': to_ccode(convection_field[1]), 'dx0_expr': to_ccode(dx0), 'dx1_expr': to_ccode(dx1), 'dy0_expr': to_ccode(dy0), 'dy1_expr': to_ccode(dy1)}) self.so_folder = tf.mkdtemp(prefix="cfem_") + os.sep # even if the object is not instantiated, we can still clean it up at # exit. atexit.register(lambda folder=self.so_folder: shutil.rmtree(folder)) shutil.copy(_module_path + "makefile", self.so_folder) shutil.copy(_module_path + "cfem.h", self.so_folder) with open(self.so_folder + "funcs.c", 'w') as fhandle: fhandle.write("#include <math.h>\n") fhandle.write("#include \"cfem.h\"\n") fhandle.write(self._forcing_code) fhandle.write(self._convection_code) current_directory = os.getcwd() try: os.chdir(self.so_folder) util.run_make(command="autogenerated_functions") self.so = np.ctypeslib.load_library("libfuncs.so", "./") self.so.cf_forcing.restype = ct.c_double self.so.cf_forcing.argtypes = [ct.c_double, ct.c_double, ct.c_double] self.so.cf_convection.restype = CConvection self.so.cf_convection.argtypes = [ct.c_double, ct.c_double] finally: os.chdir(current_directory)
def expr_body(expr, **kwargs): if not hasattr(expr, '__len__'): # Defined in terms of some coordinates xyz = set(sp.symbols('x[0], x[1], x[2]')) xyz_used = xyz & expr.free_symbols assert xyz_used <= xyz # Expression params which need default values params = (expr.free_symbols - xyz_used) & set(kwargs.keys()) # Body expr = ccode(expr).replace('M_PI', 'pi') # Default to zero kwargs.update(dict((str(p), 0.) for p in params)) # Convert return expr # Vectors, Matrices as iterables of expressions else: return [expr_body(e, **kwargs) for e in expr]
def _str_args_init_data(method, name): mat = types.matrix_types[0](method.inits[name]) mat_dic = dict((((i, j), e) for i, j, e in mat.row_list())) init_data = 'vector<{1}> {0}_data ='.format(name, CONFIG_CPP['float']) + ' {' crop = False for n in range(mat.shape[1]): for m in range(mat.shape[0]): crop = True data = "0., " if (m, n) in mat_dic.keys(): expr = mat[m, n] symbs = expr.free_symbols if not any(symb in method.args() for symb in symbs): c = ccode(expr, dereference=dereference(method)) data = 'float({0}), '.format(c) init_data += data if crop: init_data = init_data[:-2] init_data += '};' return init_data
def make_C_term(self, term, no_correct_rate, derivate=None, human=False): """transform a term into its plom C expression OR the plom C expression of its derivate, differentiating against the derivate (if derivate not None) """ #prefix all the state variable and parameters by plom___ to #avoid namespace collision with Sympy as QCOSINE letters are #used by SymPy myterm = self.change_user_input(term) safe = '' for r in myterm: if r in self.all_par: safe += 'plom___' + r else: safe += r if derivate: sy = Symbol(str('plom___'+derivate)) pterm = diff(sympify(safe), sy) else: pterm = sympify(safe) #remove the plom___ prefix #term = ccode(simplify(pterm)).replace('plom___', '') ##NOTE simplify is just too slow to be used... term = ccode(pterm).replace('plom___', '') #make the plom C expression if human: return term else: return self.generator_C(term, no_correct_rate)
def expr_body(expr, **kwargs): if not hasattr(expr, '__len__'): # Defined in terms of some coordinates xyz = set(sp.symbols('x[0], x[1], x[2]')) xyz_used = xyz & expr.free_symbols assert xyz_used <= xyz # Expression params which need default values params = (expr.free_symbols - xyz_used) & set(kwargs.keys()) # Body expr = ccode(expr).replace('M_PI', 'pi') # Default to zero kwargs.update(dict((str(p), 0.) for p in params)) # Convert return expr # Vectors, Matrices as iterables of expressions else: foo = tuple(expr_body(e, **kwargs) for e in expr) # sp.Matrix flattens so we need to reshape back if isinstance(expr, sp.Matrix): if expr.is_square: matrix = np.array(foo).reshape(expr.shape) foo = tuple(tuple(row) for row in matrix) return foo
def exact_stokes_sol(): import sympy as smp from sympy import diff, sin, cos, pi from sympy.printing import ccode x, y, t, nu, om = smp.symbols('x[0],x[1],t,nu,om') ft = smp.sin(om*t) u1 = ft*x*x*(1-x)*(1-x)*2*y*(1-y)*(2*y-1) u2 = ft*y*y*(1-y)*(1-y)*2*x*(1-x)*(1-2*x) p = ft*x*(1-x)*y*(1-y) # Stokes case rhs1 = smp.simplify(diff(u1,t) - nu*(diff(u1,x,x) + diff(u1,y,y)) + diff(p,x)) rhs2 = smp.simplify(diff(u2,t) - nu*(diff(u2,x,x) + diff(u2,y,y)) + diff(p,y)) rhs3 = smp.simplify(diff(u1,x) + diff(u2,y)) sol_p = Expression(ccode(p), om=1, t=0) sol_v = Expression((ccode(u1), ccode(u2)), om=1, t=0) fv = Expression((ccode(rhs1), ccode(rhs2)), om=1, nu=1, t=0) fp = Expression(ccode(rhs3)) return sol_v, sol_p, fv, fp
f.write("// Bardell's hierarchical functions\n\n") f.write('// Number of terms: {0}\n\n'.format(len(u))) f.write('#include <stdlib.h>\n') f.write('#include <math.h>\n\n') f.write('#if defined(_WIN32) || defined(__WIN32__)\n') f.write(' #define EXPORTIT __declspec(dllexport)\n') f.write('#else\n') f.write(' #define EXPORTIT\n') f.write('#endif\n\n') f.write('EXPORTIT void calc_vec_f(double *f, double xi,\n' + ' double xi1t, double xi1r, double xi2t, double xi2r) {\n') consts = {0:'xi1t', 1:'xi1r', 2:'xi2t', 3:'xi2r'} for i in range(len(u)): const = consts.get(i) if const is None: f.write(' f[%d] = %s;\n' % (i, ccode(u[i]))) else: f.write(' f[%d] = %s*(%s);\n' % (i, const, ccode(u[i]))) f.write('}\n') f.write('\n\n') f.write('EXPORTIT void calc_vec_fxi(double *fxi, double xi,\n' + ' double xi1t, double xi1r, double xi2t, double xi2r) {\n') for i in range(len(u)): const = consts.get(i) if const is None: f.write(' fxi[%d] = %s;\n' % (i, ccode(diff(u[i], xi)))) else: f.write(' fxi[%d] = %s*(%s);\n' % (i, const, ccode(diff(u[i], xi)))) f.write('}\n')
def test_printmethod(): class fabs(abs): def _ccode_(self): return "fabs(%s);" % ccode(self.args[0]) assert ccode(fabs(x)) == "fabs(x);"
def test_ccode_Exp1(): assert ccode(exp(1)) == "exp(1)"
def test_ccode_Pow(): assert ccode(x**3) == "pow(x,3)" assert ccode(x**(y**3)) == "pow(x,(pow(y,3)))" assert ccode(1/(g(x)*3.5)**(x - y**x)/(x**2 + y)) == \ "pow((3.5*g(x)),(-x + pow(y,x)))/(y + pow(x,2))"
def _ccode_(self): return "fabs(%s);" % ccode(self.args[0])
def write_ode_c(self, fname): f = open(fname, 'w') f.write("#include \"auto_f2c.h\"\n") f.write("#include \"math.h\"\n") f.write("int func (integer ndim, const doublereal *u, const integer *icp,\n") f.write(" const doublereal *par, integer ijac,\n") f.write(" doublereal *f, doublereal *dfdu, doublereal *dfdp)\n{\n") f.write(" /* System generated locals */\n") f.write(" integer dfdu_dim1 = ndim, dfdp_dim1 = ndim;\n") f.write(" //variables\n") for i in xrange(len(self.x)): f.write(" double %s = u[%d];\n" % (self.x[i].name, i)) f.write("\n //parameters\n") for i in xrange(len(self.pv)): f.write(" double %s = par[%d];\n" % (self.pv[i].name, i)) for i in xrange(len(self.pc)): f.write(" double %s = %f;\n" % (self.pc[i].name, self.pinit[self.pc[i].name] )) f.write("\n\t//System\n") for i in xrange(len(self.ode)): f.write( " f[%d] = %s;\n" % (i, ccode(self.ode[i])) ) f.write("\n //Jacobian\n") f.write(" if (ijac == 0)\n {\n return 0;\n }\n") for i, j in np.ndindex((len(self.ode), len(self.x))): f.write(" ARRAY2D(dfdu, %d, %d) = %s;\n" % (i, j, ccode(sympy.diff(self.ode[i], self.x[j])) ) ) f.write(" //Jacobian for parameters\n") f.write("\n if (ijac == 1) \n {\n return 0;\n }\n") for i, j in np.ndindex((len(self.ode), len(self.pv))): f.write(" ARRAY2D(dfdp, %d, %d) = %s;\n" % (i, j, ccode(sympy.diff(self.ode[i], self.pv[j])) ) ) f.write("\n return 0;\n}\n\n\n") f.write("int stpnt (integer ndim, doublereal t, doublereal *u, doublereal *par)\n") f.write("{\n //init params\n") for i in range(len(self.pv)): f.write(" par[%d] = %f;\n" % (i, self.pinit[self.pv[i].name] )) f.write("\n //init variables\n") for i in range(len(self.x)): f.write(" u[%d] = %2.1f;\n" % (i, self.xinit[self.x[i].name] )) f.write(" return 0;\n}\n\n") f.write("int pvls (integer ndim, const doublereal *u, doublereal *par)\n") f.write("{ return 0;}\n\n") f.write("int bcnd (integer ndim, const doublereal *par, const integer *icp,\n") f.write(" integer nbc, const doublereal *u0, const doublereal *u1, integer ijac,\n") f.write(" doublereal *fb, doublereal *dbc)\n") f.write("{ return 0;}\n\n\n") f.write("int icnd (integer ndim, const doublereal *par, const integer *icp,\n") f.write(" integer nint, const doublereal *u, const doublereal *uold,\n") f.write(" const doublereal *udot, const doublereal *upold, integer ijac,\n") f.write(" doublereal *fi, doublereal *dint)\n") f.write("{ return 0;}\n\n\n") f.write("int fopt (integer ndim, const doublereal *u, const integer *icp,\n") f.write(" const doublereal *par, integer ijac,\n") f.write(" doublereal *fs, doublereal *dfdu, doublereal *dfdp)\n") f.write("{ return 0; }\n") f.close()