def __init__(self, settings): defaults = {'decimales': 18, 'mode_scientifique': False, 'decimales_sci': 2 } self._default_settings.update(defaults) StrPrinter.__init__(self, settings)
def _print_Float(self, expr): exposant = None if self._settings['mode_scientifique']: # Conversion en écriture scientifique. puissance = int(floor(log(expr, 10))) flottant = self._float_evalf(expr*10**-puissance) mantisse = StrPrinter._print_Float(self, flottant) exposant = str(puissance) else: chaine = StrPrinter._print_Float(self, self._float_evalf(expr)) if 'e' in chaine: # Déjà en mode scientifique (ex: 1.3e-15) mantisse, exposant = chaine.split('e') if exposant is not None: # Affichage en mode scientifique mantisse = mantisse.rstrip('0') # On laisse la mantisse sous forme de flottant. # Ainsi, '2,00000*10^-8' devient '2,0*10^-8', et non '2*10^-8'. # Lorsqu'on sauvegarde l'état de l'interprète de la calculatrice, # les décimaux du type 0,00000002 sont ainsi sauvegardés sous # forme décimale, et non sous forme fractionnaire. if mantisse.endswith('.'): mantisse += '0' exposant = exposant.lstrip('+') return '%s*10^%s' % (mantisse, exposant) else: # Par contre, lorsque les décimaux sont des entiers, inutile de les # sauvegarder sous forme décimale. return chaine.rstrip('0').rstrip('.')
def convert_atom(atom): if atom.LETTER(): subscriptName = '' if atom.subexpr(): subscript = None if atom.subexpr().expr(): # subscript is expr subscript = convert_expr(atom.subexpr().expr()) else: # subscript is atom subscript = convert_atom(atom.subexpr().atom()) subscriptName = '_{' + StrPrinter().doprint(subscript) + '}' return sympy.Symbol(atom.LETTER().getText() + subscriptName) elif atom.SYMBOL(): s = atom.SYMBOL().getText()[1:] if s == "infty": return sympy.oo else: if atom.subexpr(): subscript = None if atom.subexpr().expr(): # subscript is expr subscript = convert_expr(atom.subexpr().expr()) else: # subscript is atom subscript = convert_atom(atom.subexpr().atom()) subscriptName = StrPrinter().doprint(subscript) s += '_{' + subscriptName + '}' return sympy.Symbol(s) elif atom.NUMBER(): s = atom.NUMBER().getText().replace(",", "") return sympy.Number(s) elif atom.DIFFERENTIAL(): var = get_differential_var(atom.DIFFERENTIAL()) return sympy.Symbol('d' + var.name) elif atom.mathit(): text = rule2text(atom.mathit().mathit_text()) return sympy.Symbol(text)
def _print_Derivative(self, e): from sympy.physics.vector.functions import dynamicsymbols t = dynamicsymbols._t if (bool(sum([i == t for i in e.variables])) & isinstance(type(e.args[0]), UndefinedFunction)): ol = str(e.args[0].func) for i, v in enumerate(e.variables): ol += dynamicsymbols._str return ol else: return StrPrinter().doprint(e)
def test_MxN_mats(): generatedAssertions = "def test_misc_mats():\n" for i in range(1, 6): for j in range(1, 6): A = Matrix([[x + y * j for x in range(j)] for y in range(i)]) gl = glsl_code(A) glTransposed = glsl_code(A, mat_transpose=True) generatedAssertions += " mat = " + StrPrinter()._print( A) + "\n\n" generatedAssertions += " gl = '''" + gl + "'''\n" generatedAssertions += " glTransposed = '''" + glTransposed + "'''\n\n" generatedAssertions += " assert glsl_code(mat) == gl\n" generatedAssertions += ( " assert glsl_code(mat,mat_transpose=True) == glTransposed\n" ) if i == 1 and j == 1: assert gl == "0" elif i <= 4 and j <= 4 and i > 1 and j > 1: assert gl.startswith("mat%s" % j) assert glTransposed.startswith("mat%s" % i) elif i == 1 and j <= 4: assert gl.startswith("vec") elif j == 1 and i <= 4: assert gl.startswith("vec") elif i == 1: assert gl.startswith("float[%s](" % j * i) assert glTransposed.startswith("float[%s](" % j * i) elif j == 1: assert gl.startswith("float[%s](" % i * j) assert glTransposed.startswith("float[%s](" % i * j) else: assert gl.startswith("float[%s](" % (i * j)) assert glTransposed.startswith("float[%s](" % (i * j)) glNested = glsl_code(A, mat_nested=True) glNestedTransposed = glsl_code(A, mat_transpose=True, mat_nested=True) assert glNested.startswith("float[%s][%s]" % (i, j)) assert glNestedTransposed.startswith("float[%s][%s]" % (j, i)) generatedAssertions += " glNested = '''" + glNested + "'''\n" generatedAssertions += (" glNestedTransposed = '''" + glNestedTransposed + "'''\n\n") generatedAssertions += ( " assert glsl_code(mat,mat_nested=True) == glNested\n") generatedAssertions += " assert glsl_code(mat,mat_nested=True,mat_transpose=True) == glNestedTransposed\n\n" generateAssertions = ( False # set this to true to write bake these generated tests to a file ) if generateAssertions: gen = open("test_glsl_generated_matrices.py", "w") gen.write(generatedAssertions) gen.close()
def test_MxN_mats(): generatedAssertions = 'def test_misc_mats():\n' for i in range(1, 6): for j in range(1, 6): A = Matrix([[x + y * j for x in range(j)] for y in range(i)]) gl = glsl_code(A) glTransposed = glsl_code(A, mat_transpose=True) generatedAssertions += ' mat = ' + StrPrinter()._print( A) + '\n\n' generatedAssertions += ' gl = \'\'\'' + gl + '\'\'\'\n' generatedAssertions += ' glTransposed = \'\'\'' + glTransposed + '\'\'\'\n\n' generatedAssertions += ' assert glsl_code(mat) == gl\n' generatedAssertions += ' assert glsl_code(mat,mat_transpose=True) == glTransposed\n' if i == 1 and j == 1: assert gl == '0' elif i <= 4 and j <= 4 and i > 1 and j > 1: assert gl.startswith('mat%s' % j) assert glTransposed.startswith('mat%s' % i) elif i == 1 and j <= 4: assert gl.startswith('vec') elif j == 1 and i <= 4: assert gl.startswith('vec') elif i == 1: assert gl.startswith('float[%s](' % j * i) assert glTransposed.startswith('float[%s](' % j * i) elif j == 1: assert gl.startswith('float[%s](' % i * j) assert glTransposed.startswith('float[%s](' % i * j) else: assert gl.startswith('float[%s](' % (i * j)) assert glTransposed.startswith('float[%s](' % (i * j)) glNested = glsl_code(A, mat_nested=True) glNestedTransposed = glsl_code(A, mat_transpose=True, mat_nested=True) assert glNested.startswith('float[%s][%s]' % (i, j)) assert glNestedTransposed.startswith('float[%s][%s]' % (j, i)) generatedAssertions += ' glNested = \'\'\'' + glNested + '\'\'\'\n' generatedAssertions += ' glNestedTransposed = \'\'\'' + glNestedTransposed + '\'\'\'\n\n' generatedAssertions += ' assert glsl_code(mat,mat_nested=True) == glNested\n' generatedAssertions += ' assert glsl_code(mat,mat_nested=True,mat_transpose=True) == glNestedTransposed\n\n' generateAssertions = False # set this to true to write bake these generated tests to a file if generateAssertions: gen = open('test_glsl_generated_matrices.py', 'w') gen.write(generatedAssertions) gen.close()
def convert_func(func): if func.func_normal(): return handle_func_normal(func) elif func.LETTER() or func.SYMBOL(): if func.LETTER(): fname = func.LETTER().getText() elif func.SYMBOL(): fname = func.SYMBOL().getText()[1:] fname = str(fname) # can't be unicode if func.subexpr(): subscript = None if func.subexpr().expr(): # subscript is expr subscript = convert_expr(func.subexpr().expr()) else: # subscript is atom subscript = convert_atom(func.subexpr().atom()) subscriptName = StrPrinter().doprint(subscript) fname += '_{' + subscriptName + '}' input_args = func.args() output_args = [] while input_args.args(): # handle multiple arguments to function output_args.append(convert_expr(input_args.expr())) input_args = input_args.args() output_args.append(convert_expr(input_args.expr())) return sympy.Function(fname)(*output_args) elif func.FUNC_INT(): return handle_integral(func) elif func.FUNC_SQRT(): expr = convert_expr(func.base) if func.root: r = convert_expr(func.root) return sympy.root(expr, r) else: return sympy.sqrt(expr) elif func.FUNC_SUM(): return handle_sum_or_prod(func, "summation") elif func.FUNC_PROD(): return handle_sum_or_prod(func, "product") elif func.FUNC_LIM(): return handle_limit(func) elif func.FUNC_LOG() or func.FUNC_LN(): return handle_log(func)
def FHamiltonian(self, n): """Set up the time-independent Floquet hamiltonian of the system defined by the total hamiltonian""" Hf = sp.Matrix([]) ndep = self.NonDiagonalElements(0, 1) nden = self.NonDiagonalElements(1, 0) for i in range(-n, n + 1): fila = sp.Matrix([]) for j in range(-n, n + 1): if j == i: fila = fila.row_join(self.DiagonalElements(i)) elif j == i + 1: fila = fila.row_join(ndep) elif j == i - 1: fila = fila.row_join(nden) else: fila = fila.row_join(sp.Matrix([[0, 0], [0, 0]])) Hf = Hf.col_join(fila) Hf.simplify() printer = StrPrinter() print(Hf.table(printer, align='center')) self.Hf = Hf
def _print_Float(self, expr): string = StrPrinter._print_Float(self, expr) return string.replace('e+', '*10^').replace('e-', '*10^-')
def doprint(self, expr): # Mieux vaut faire la substitution une seule fois dès le départ. expr = self._convert_Decim(expr) return StrPrinter.doprint(self, expr)
def print_float(x): return StrPrinter({'full_prec': False}).doprint(Float(x, 3))
def _print_Pow(self, *args, **kw): return StrPrinter._print_Pow(self, *args, **kw).replace('**', '^')
def _print_Float(self, expr): # cf # http://stackoverflow.com/questions/25222681/scientific-exponential-notation-with-sympy-in-an-ipython-notebook return StrPrinter({'full_prec': False}).doprint(Float(expr, 52))
#!/usr/bin/env python from random import randrange from sympy import Matrix, pprint, randMatrix, N, eye from sympy.printing.str import StrPrinter from sympy.abc import x filename = "test_nml_mat_lup_solve.data" num_tests = 400 min_M_cols = 1 min_M_rows = 1 max_M_cols = 25 max_M_rows = 25 min_val = 0 max_val = 100 fs = open(filename, "w") fs.write("{}".format(num_tests)) for i in range(num_tests): M_dim = randrange(min_M_cols, max_M_cols) M = randMatrix(M_dim, M_dim, min=min_val, max=max_val, percent=100) print("Creating test case: ", i) fs.write("\n{} {}\n".format(M_dim, M_dim)) fs.write(M.table(StrPrinter(), rowstart="", rowend="", colsep="\t")) fs.close()
def doprint(self, expr): return StrPrinter.doprint( self, expr) if not isinstance(expr, unicode) else expr
def _print_Function(self, e): from sympy.physics.vector.functions import dynamicsymbols t = dynamicsymbols._t if isinstance(type(e), UndefinedFunction): return StrPrinter().doprint(e).replace("(%s)" % t, '') return e.func.__name__ + "(%s)" % self.stringify(e.args, ", ")
def convert_func(func): if func.func_normal(): if func.L_PAREN(): # function called with parenthesis arg = convert_func_arg(func.func_arg()) else: arg = convert_func_arg(func.func_arg_noparens()) name = func.func_normal().start.text[1:] # change arc<trig> -> a<trig> if name in [ "arcsin", "arccos", "arctan", "arccsc", "arcsec", "arccot" ]: name = "a" + name[3:] expr = getattr(sympy.functions, name)(arg, evaluate=False) if name in ["arsinh", "arcosh", "artanh"]: name = "a" + name[2:] expr = getattr(sympy.functions, name)(arg, evaluate=False) if name == "exp": expr = sympy.exp(arg, evaluate=False) if (name == "log" or name == "ln"): if func.subexpr(): if func.subexpr().expr(): base = convert_expr(func.subexpr().expr()) else: base = convert_atom(func.subexpr().atom()) elif name == "log": base = 10 elif name == "ln": base = sympy.E expr = sympy.log(arg, base, evaluate=False) func_pow = None should_pow = True if func.supexpr(): if func.supexpr().expr(): func_pow = convert_expr(func.supexpr().expr()) else: func_pow = convert_atom(func.supexpr().atom()) if name in [ "sin", "cos", "tan", "csc", "sec", "cot", "sinh", "cosh", "tanh" ]: if func_pow == -1: name = "a" + name should_pow = False expr = getattr(sympy.functions, name)(arg, evaluate=False) if func_pow and should_pow: expr = sympy.Pow(expr, func_pow, evaluate=False) return expr elif func.LETTER() or func.SYMBOL(): if func.LETTER(): fname = func.LETTER().getText() elif func.SYMBOL(): fname = func.SYMBOL().getText()[1:] fname = str(fname) # can't be unicode if func.subexpr(): subscript = None if func.subexpr().expr(): # subscript is expr subscript = convert_expr(func.subexpr().expr()) else: # subscript is atom subscript = convert_atom(func.subexpr().atom()) subscriptName = StrPrinter().doprint(subscript) fname += '_{' + subscriptName + '}' input_args = func.args() output_args = [] while input_args.args(): # handle multiple arguments to function output_args.append(convert_expr(input_args.expr())) input_args = input_args.args() output_args.append(convert_expr(input_args.expr())) return sympy.Function(fname)(*output_args) elif func.FUNC_INT(): return handle_integral(func) elif func.FUNC_SQRT(): expr = convert_expr(func.base) if func.root: r = convert_expr(func.root) return sympy.root(expr, r, evaluate=False) else: return sympy.sqrt(expr, evaluate=False) elif func.FUNC_OVERLINE(): expr = convert_expr(func.base) return sympy.conjugate(expr, evaluate=False) elif func.FUNC_SUM(): return handle_sum_or_prod(func, "summation") elif func.FUNC_PROD(): return handle_sum_or_prod(func, "product") elif func.FUNC_LIM(): return handle_limit(func)
def convert_atom(atom): if atom.LETTER() or atom.LONGNAME(): subscriptName = '' s = atom.LETTER().getText() if atom.LETTER() else atom.LONGNAME( ).getText() if s == "I": return sympy.I if atom.subexpr(): subscript = None if atom.subexpr().expr(): # subscript is expr subscript = convert_expr(atom.subexpr().expr()) else: # subscript is atom subscript = convert_atom(atom.subexpr().atom()) subscriptName = '_{' + StrPrinter().doprint(subscript) + '}' return sympy.Symbol(s + subscriptName, real=True) elif atom.SYMBOL(): s = atom.SYMBOL().getText()[1:] if s == "infty": return sympy.oo elif s == 'pi': return sympy.pi else: if atom.subexpr(): subscript = None if atom.subexpr().expr(): # subscript is expr subscript = convert_expr(atom.subexpr().expr()) else: # subscript is atom subscript = convert_atom(atom.subexpr().atom()) subscriptName = StrPrinter().doprint(subscript) s += '_{' + subscriptName + '}' return sympy.Symbol(s, real=True) elif atom.accent(): # get name for accent name = atom.accent().start.text[1:] # exception: check if bar or overline which are treated both as bar if name in ["bar", "overline"]: name = "bar" # get the base (variable) base = atom.accent().base.getText() # set string to base+name s = base + name if atom.subexpr(): subscript = None if atom.subexpr().expr(): # subscript is expr subscript = convert_expr(atom.subexpr().expr()) else: # subscript is atom subscript = convert_atom(atom.subexpr().atom()) subscriptName = StrPrinter().doprint(subscript) s += '_{' + subscriptName + '}' return sympy.Symbol(s, real=True) elif atom.NUMBER(): s = atom.NUMBER().getText().replace(",", "") try: sr = sympy.Rational(s) return sr except e: return sympy.Number(s) elif atom.DIFFERENTIAL(): var = get_differential_var(atom.DIFFERENTIAL()) return sympy.Symbol('d' + var.name, real=True) elif atom.mathit(): text = rule2text(atom.mathit().mathit_text()) return sympy.Symbol(text, real=True) elif atom.PLACEHOLDER(): name = atom.PLACEHOLDER().getText()[2:] name = name[0:len(name) - 2] # add hash to distinguish from regular symbols hash = hashlib.md5(name.encode()).hexdigest() symbol_name = name + hash # replace the placeholder for already known placeholder values if name in PLACEHOLDER_VALUES: # if a sympy class if isinstance(PLACEHOLDER_VALUES[name], tuple(sympy.core.all_classes)): symbol = PLACEHOLDER_VALUES[name] # if NOT a sympy class else: symbol = parse_expr(str(PLACEHOLDER_VALUES[name])) else: symbol = sympy.Symbol(symbol_name, real=True) # return the symbol return symbol
def convert_atom(atom): if atom.LETTER_NO_E(): subscriptName = '' s = atom.LETTER_NO_E().getText() if s == "I": return sympy.I if atom.subexpr(): subscript = None if atom.subexpr().expr(): # subscript is expr subscript = convert_expr(atom.subexpr().expr()) else: # subscript is atom subscript = convert_atom(atom.subexpr().atom()) subscriptName = '_{' + StrPrinter().doprint(subscript) + '}' return sympy.Symbol(atom.LETTER_NO_E().getText() + subscriptName, real=True) elif atom.GREEK_LETTER(): s = atom.GREEK_LETTER().getText()[1:] if atom.subexpr(): subscript = None if atom.subexpr().expr(): # subscript is expr subscript = convert_expr(atom.subexpr().expr()) else: # subscript is atom subscript = convert_atom(atom.subexpr().atom()) subscriptName = StrPrinter().doprint(subscript) s += '_{' + subscriptName + '}' return sympy.Symbol(s, real=True) elif atom.accent(): # get name for accent name = atom.accent().start.text[1:] # exception: check if bar or overline which are treated both as bar if name in ["bar", "overline"]: name = "bar" # get the base (variable) base = atom.accent().base.getText() # set string to base+name s = base + name if atom.subexpr(): subscript = None if atom.subexpr().expr(): # subscript is expr subscript = convert_expr(atom.subexpr().expr()) else: # subscript is atom subscript = convert_atom(atom.subexpr().atom()) subscriptName = StrPrinter().doprint(subscript) s += '_{' + subscriptName + '}' return sympy.Symbol(s, real=True) elif atom.SYMBOL(): s = atom.SYMBOL().getText().replace("\\$", "").replace("\\%", "") if s == "\\infty": return sympy.oo elif s == '\\pi': return sympy.pi elif s == '\\emptyset': return sympy.S.EmptySet else: raise Exception("Unrecognized symbol") elif atom.NUMBER(): s = atom.NUMBER().getText().replace(",", "") try: sr = sympy.Rational(s) return sr except (TypeError, ValueError): return sympy.Number(s) elif atom.E_NOTATION(): s = atom.E_NOTATION().getText().replace(",", "") try: sr = sympy.Rational(s) return sr except (TypeError, ValueError): return sympy.Number(s) elif atom.DIFFERENTIAL(): var = get_differential_var(atom.DIFFERENTIAL()) return sympy.Symbol('d' + var.name, real=True) elif atom.mathit(): text = rule2text(atom.mathit().mathit_text()) return sympy.Symbol(text, real=True) elif atom.VARIABLE(): text = atom.VARIABLE().getText() is_percent = text.endswith("\\%") trim_amount = 3 if is_percent else 1 name = text[10:] name = name[0:len(name) - trim_amount] # add hash to distinguish from regular symbols hash = hashlib.md5(name.encode()).hexdigest() symbol_name = name + hash # replace the variable for already known variable values if name in VARIABLE_VALUES: # if a sympy class if isinstance(VARIABLE_VALUES[name], tuple(sympy.core.all_classes)): symbol = VARIABLE_VALUES[name] # if NOT a sympy class else: symbol = parse_expr(str(VARIABLE_VALUES[name])) else: symbol = sympy.Symbol(symbol_name, real=True) if is_percent: return sympy.Mul(symbol, sympy.Pow(100, -1, evaluate=False), evaluate=False) # return the symbol return symbol elif atom.PERCENT_NUMBER(): text = atom.PERCENT_NUMBER().getText().replace("\\%", "").replace(",", "") try: number = sympy.Rational(text) except (TypeError, ValueError): number = sympy.Number(text) percent = sympy.Rational(number, 100) return percent
from tkinter import * from tkinter import ttk from sympy.matrices import Matrix from sympy.printing.str import StrPrinter import math printer = StrPrinter() entries = [] rows = 0 master = Tk() matIn = "[1,1,1,1;2,2,2,2;3,3,3,3;4,4,4,4]" #for testing def multi(mats): return mats.pop(0) * multi(mats) if len(mats) >= 1 else 1 def parseStr2Mat( mat): #input matrix formatted as string in 'Matlab-style' => sep = ';' mat = mat.strip('[') mat = mat.strip(']') matOut = [] for elem in mat.split(';'): matOut.append(elem.split(',')) return Matrix(matOut) def genA(theta, d, alpha, a): #all inputs as string, will be parsed afterwards return parseMat(Matrix([ ['c(' + theta +')', '-s(' + theta +')*c(' + alpha + ')', 's(' + theta +')*s(' + alpha + ')', '' + a + '*c(' + theta + ')'], \ ['s(' + theta +')', 'c(' + theta +')*c(' + alpha + ')', '-c(' + theta +')*s(' + alpha + ')', '' + a + '*s(' + theta + ')'], \
def doprint(self, expr): # Mieux vaut faire la substitution une seule fois dès le départ. expr = self._convert_Decim(expr) return StrPrinter.doprint(self, expr) if not isinstance(expr, unicode) else expr
def _doprint_loops(self, expr, assign_to=None): # Here we print an expression that contains Indexed objects, they # correspond to arrays in the generated code. The low-level implementation # involves looping over array elements and possibly storing results in temporary # variables or accumulate it in the assign_to object. if self._settings.get('contract', True): from sympy.tensor import get_contraction_structure # Setup loops over non-dummy indices -- all terms need these indices = self._get_expression_indices(expr, assign_to) # Setup loops over dummy indices -- each term needs separate treatment dummies = get_contraction_structure(expr) else: indices = [] dummies = {None: (expr,)} openloop, closeloop = self._get_loop_opening_ending(indices) # terms with no summations first if None in dummies: text = StrPrinter.doprint(self, Add(*dummies[None])) else: # If all terms have summations we must initialize array to Zero text = StrPrinter.doprint(self, 0) # skip redundant assignments (where lhs == rhs) lhs_printed = self._print(assign_to) lines = [] if text != lhs_printed: lines.extend(openloop) if assign_to is not None: text = self._get_statement("%s = %s" % (lhs_printed, text)) lines.append(text) lines.extend(closeloop) # then terms with summations for d in dummies: if isinstance(d, tuple): indices = self._sort_optimized(d, expr) openloop_d, closeloop_d = self._get_loop_opening_ending( indices) for term in dummies[d]: if term in dummies and not ([list(f.keys()) for f in dummies[term]] == [[None] for f in dummies[term]]): # If one factor in the term has it's own internal # contractions, those must be computed first. # (temporary variables?) raise NotImplementedError( "FIXME: no support for contractions in factor yet") else: # We need the lhs expression as an accumulator for # the loops, i.e # # for (int d=0; d < dim; d++){ # lhs[] = lhs[] + term[][d] # } ^.................. the accumulator # # We check if the expression already contains the # lhs, and raise an exception if it does, as that # syntax is currently undefined. FIXME: What would be # a good interpretation? if assign_to is None: raise AssignmentError( "need assignment variable for loops") if term.has(assign_to): raise ValueError("FIXME: lhs present in rhs,\ this is undefined in CodePrinter") lines.extend(openloop) lines.extend(openloop_d) text = "%s = %s" % (lhs_printed, StrPrinter.doprint( self, assign_to + term)) lines.append(self._get_statement(text)) lines.extend(closeloop_d) lines.extend(closeloop) return "\n".join(lines)
def doprint(self, expr): return StrPrinter.doprint(self, expr) if not isinstance(expr, unicode) else expr
def _print_Mul(self,expr): for n,s in(1,""),(-1,"-"): args=tuple(arg for arg in expr.args if arg!=n) if len(args)==1: return s+self.doprint(args[0]) return StrPrinter._print_Mul(self,expr)
def convert_atom(atom): if atom.atom_expr(): atom_expr = atom.atom_expr() # find the atom's text atom_text = '' if atom_expr.LETTER_NO_E(): atom_text = atom_expr.LETTER_NO_E().getText() if atom_text == "I": return sympy.I elif atom_expr.GREEK_CMD(): atom_text = atom_expr.GREEK_CMD().getText()[1:].strip() elif atom_expr.accent(): atom_accent = atom_expr.accent() # get name for accent name = atom_accent.start.text[1:] # exception: check if bar or overline which are treated both as bar if name in ["bar", "overline"]: name = "bar" # get the base (variable) base = atom_accent.base.getText() # set string to base+name atom_text = base + name # find atom's subscript, if any subscript_text = '' if atom_expr.subexpr(): subexpr = atom_expr.subexpr() subscript = None if subexpr.expr(): # subscript is expr subscript = subexpr.expr().getText().strip() elif subexpr.atom(): # subscript is atom subscript = subexpr.atom().getText().strip() elif subexpr.args(): # subscript is args subscript = subexpr.args().getText().strip() subscript_inner_text = StrPrinter().doprint(subscript) if len(subscript_inner_text) > 1: subscript_text = '_{' + subscript_inner_text + '}' else: subscript_text = '_' + subscript_inner_text # construct the symbol using the text and optional subscript atom_symbol = sympy.Symbol(atom_text + subscript_text, real=True, positive=True) # find the atom's superscript, and return as a Pow if found if atom_expr.supexpr(): supexpr = atom_expr.supexpr() func_pow = None if supexpr.expr(): func_pow = convert_expr(supexpr.expr()) else: func_pow = convert_atom(supexpr.atom()) return sympy.Pow(atom_symbol, func_pow, evaluate=False) return atom_symbol elif atom.SYMBOL(): s = atom.SYMBOL().getText().replace("\\$", "").replace("\\%", "") if s == "\\infty": return sympy.oo elif s == '\\pi': return sympy.pi elif s == '\\emptyset': return sympy.S.EmptySet else: raise Exception("Unrecognized symbol") elif atom.NUMBER(): s = atom.NUMBER().getText().replace(",", "") try: sr = sympy.Rational(s) return sr except (TypeError, ValueError): return sympy.Number(s) elif atom.SCI_NOTATION_NUMBER(): s = atom.SCI_NOTATION_NUMBER().getText() s_parts = s.split('\\times 10^') s1 = s_parts[0].replace(',', '') try: n1 = sympy.Rational(s1) except (TypeError, ValueError): n1 = sympy.Number(s1) s2 = s_parts[1].replace('{', '').replace(',', '').replace('}', '') try: n2 = sympy.Rational(s2) except (TypeError, ValueError): n2 = sympy.Number(s2) n_exp = sympy.Mul(n1, sympy.Pow(10, n2)) try: n = sympy.Rational(n_exp) except (TypeError, ValueError): n = sympy.Number(n_exp) return n elif atom.FRACTION_NUMBER(): s = atom.FRACTION_NUMBER().getText().replace("\\frac{", "").replace( "}{", "/").replace("}", "").replace(",", "") try: sr = sympy.Rational(s) return sr except ZeroDivisionError: # preserve the divide by zero as an expression s_parts = s.split('/') try: p = sympy.Rational(s_parts[0]) except (TypeError, ValueError): p = sympy.Number(s_parts[0]) try: q = sympy.Rational(s_parts[1]) except (TypeError, ValueError): q = sympy.Number(s_parts[1]) return sympy.Mul(p, sympy.Pow(q, -1, evaluate=False), evaluate=False) except (TypeError, ValueError): return sympy.Number(s) elif atom.E_NOTATION(): s = atom.E_NOTATION().getText().replace(",", "") try: sr = sympy.Rational(s) return sr except (TypeError, ValueError): return sympy.Number(s) elif atom.DIFFERENTIAL(): var = get_differential_var(atom.DIFFERENTIAL()) return sympy.Symbol('d' + var.name, real=True, positive=True) elif atom.mathit(): text = rule2text(atom.mathit().mathit_text()) return sympy.Symbol(text, real=True, positive=True) elif atom.VARIABLE(): text = atom.VARIABLE().getText() is_percent = text.endswith("\\%") trim_amount = 3 if is_percent else 1 name = text[10:] name = name[0:len(name) - trim_amount] # revert any wrapping of single char subs from `pre_process_latex` name = re.sub(r'(_)\{([0-9a-zA-Z])\}', '\\1\\2', name) # add hash to distinguish from regular symbols hash = hashlib.md5(name.encode()).hexdigest() symbol_name = name + hash # replace the variable for already known variable values if name in VARIABLE_VALUES: # if a sympy class if isinstance(VARIABLE_VALUES[name], tuple(sympy.core.all_classes)): symbol = VARIABLE_VALUES[name] # if NOT a sympy class else: symbol = parse_expr(str(VARIABLE_VALUES[name])) else: symbol = sympy.Symbol(symbol_name, real=True) if is_percent: return sympy.Mul(symbol, sympy.Pow(100, -1, evaluate=False), evaluate=False) # return the symbol return symbol elif atom.PERCENT_NUMBER(): text = atom.PERCENT_NUMBER().getText().replace("\\%", "").replace(",", "") try: number = sympy.Rational(text) except (TypeError, ValueError): number = sympy.Number(text) percent = sympy.Rational(number, 100) return percent
def _doprint_loops(self, expr, assign_to=None): # Here we print an expression that contains Indexed objects, they # correspond to arrays in the generated code. The low-level implementation # involves looping over array elements and possibly storing results in temporary # variables or accumulate it in the assign_to object. if self._settings.get('contract', True): from sympy.tensor import get_contraction_structure # Setup loops over non-dummy indices -- all terms need these indices = self._get_expression_indices(expr, assign_to) # Setup loops over dummy indices -- each term needs separate treatment dummies = get_contraction_structure(expr) else: indices = [] dummies = {None: (expr,)} openloop, closeloop = self._get_loop_opening_ending(indices) # terms with no summations first if None in dummies: text = StrPrinter.doprint(self, Add(*dummies[None])) else: # If all terms have summations we must initialize array to Zero text = StrPrinter.doprint(self, 0) # skip redundant assignments (where lhs == rhs) lhs_printed = self._print(assign_to) lines = [] if text != lhs_printed: lines.extend(openloop) if assign_to is not None: text = self._get_statement("%s = %s" % (lhs_printed, text)) lines.append(text) lines.extend(closeloop) # then terms with summations for d in dummies: if isinstance(d, tuple): indices = self._sort_optimized(d, expr) openloop_d, closeloop_d = self._get_loop_opening_ending( indices) for term in dummies[d]: if term in dummies and not ([list(f.keys()) for f in dummies[term]] == [[None] for f in dummies[term]]): # If one factor in the term has it's own internal # contractions, those must be computed first. # (temporary variables?) raise NotImplementedError( "FIXME: no support for contractions in factor yet") else: # We need the lhs expression as an accumulator for # the loops, i.e # # for (int d=0; d < dim; d++){ # lhs[] = lhs[] + term[][d] # } ^.................. the accumulator # # We check if the expression already contains the # lhs, and raise an exception if it does, as that # syntax is currently undefined. FIXME: What would be # a good interpretation? if assign_to is None: raise AssignmentError( "need assignment variable for loops") if term.has(assign_to): raise ValueError("FIXME: lhs present in rhs,\ this is undefined in CodePrinter") lines.extend(openloop) lines.extend(openloop_d) text = "%s = %s" % (lhs_printed, StrPrinter.doprint( self, assign_to + term)) lines.append(self._get_statement(text)) lines.extend(closeloop_d) lines.extend(closeloop) return "\n".join(lines)
def _print_Float(self, expr): string = StrPrinter._print_Float(self, expr) return string.replace('e+', '*10^').replace('e-', '*10^-')