def test_issue_7840(): # daveknippers' example C393 = sympify( \ 'Piecewise((C391 - 1.65, C390 < 0.5), (Piecewise((C391 - 1.65, \ C391 > 2.35), (C392, True)), True))' ) C391 = sympify( \ 'Piecewise((2.05*C390**(-1.03), C390 < 0.5), (2.5*C390**(-0.625), True))' ) C393 = C393.subs('C391',C391) # simple substitution sub = {} sub['C390'] = 0.703451854 sub['C392'] = 1.01417794 ss_answer = C393.subs(sub) # cse substitutions,new_eqn = cse(C393) for pair in substitutions: sub[pair[0].name] = pair[1].subs(sub) cse_answer = new_eqn[0].subs(sub) # both methods should be the same assert ss_answer == cse_answer # GitRay's example expr = sympify( "Piecewise((Symbol('ON'), Equality(Symbol('mode'), Symbol('ON'))), \ (Piecewise((Piecewise((Symbol('OFF'), StrictLessThan(Symbol('x'), \ Symbol('threshold'))), (Symbol('ON'), true)), Equality(Symbol('mode'), \ Symbol('AUTO'))), (Symbol('OFF'), true)), true))" ) substitutions, new_eqn = cse(expr) # this Piecewise should be exactly the same assert new_eqn[0] == expr # there should not be any replacements assert len(substitutions) < 1
def test_cse_single2(): # Simple substitution, test for being able to pass the expression directly e = Add(Pow(x+y,2), sqrt(x+y)) substs, reduced = cse(e, optimizations=[]) assert substs == [(x0, x+y)] assert reduced == [sqrt(x0) + x0**2] assert isinstance(cse(Matrix([[1]]))[1][0], Matrix)
def test_issue_11230(): # a specific test that always failed a, b, f, k, l, i = symbols('a b f k l i') p = [a*b*f*k*l, a*i*k**2*l, f*i*k**2*l] R, C = cse(p) assert not any(i.is_Mul for a in C for i in a.args) # random tests for the issue from random import choice from sympy.core.function import expand_mul s = symbols('a:m') # 35 Mul tests, none of which should ever fail ex = [Mul(*[choice(s) for i in range(5)]) for i in range(7)] for p in subsets(ex, 3): p = list(p) R, C = cse(p) assert not any(i.is_Mul for a in C for i in a.args) for ri in reversed(R): for i in range(len(C)): C[i] = C[i].subs(*ri) assert p == C # 35 Add tests, none of which should ever fail ex = [Add(*[choice(s[:7]) for i in range(5)]) for i in range(7)] for p in subsets(ex, 3): p = list(p) was = R, C = cse(p) assert not any(i.is_Add for a in C for i in a.args) for ri in reversed(R): for i in range(len(C)): C[i] = C[i].subs(*ri) # use expand_mul to handle cases like this: # p = [a + 2*b + 2*e, 2*b + c + 2*e, b + 2*c + 2*g] # x0 = 2*(b + e) is identified giving a rebuilt p that # is now `[a + 2*(b + e), c + 2*(b + e), b + 2*c + 2*g]` assert p == [expand_mul(i) for i in C]
def derive_solution(): from sympy import symbols, Matrix, cse, cos, sin, Abs, Rational,acos,asin cs,K,tec,nu,phase,sigma_phase,alpha,beta,tec_p,cs_p,sigma_tec,sigma_cs = symbols('cs K tec nu phase sigma_phase alpha beta tec_p cs_p sigma_tec sigma_cs', real=True) g = K*tec/nu + cs*alpha L = Abs(g - phase)/sigma_phase + beta*((tec - tec_p)**Rational(2)/sigma_tec**Rational(2)/Rational(2) + (cs - cs_p)**Rational(2)/sigma_cs**Rational(2)/Rational(2)) req,res = cse(L,optimizations='basic') for line in req: print("{} = {}".format(line[0],line[1]).replace("Abs","np.abs").replace("cos","np.cos").replace("sin","np.sin").replace("sign","np.sign")) print("{}".format(res[0]).replace("Abs","np.abs").replace("cos","np.cos").replace("sin","np.sin").replace("sign","np.sign")) print() grad = Matrix([sigma_tec**Rational(2)*L.diff(tec), sigma_cs**Rational(2)*L.diff(cs)]) req,res = cse(grad,optimizations='basic') for line in req: print("{} = {}".format(line[0],line[1]).replace("Abs","np.abs").replace("cos","np.cos").replace("sin","np.sin").replace("sign","np.sign")) print("{}".format(res[0]).replace("Abs","np.abs").replace("cos","np.cos").replace("sin","np.sin").replace("sign","np.sign")) print() H = Matrix([[L.diff(tec).diff(tec),L.diff(tec).diff(cs)],[L.diff(cs).diff(tec),L.diff(cs).diff(cs)]]) req,res = cse(H,optimizations='basic') for line in req: print("{} = {}".format(line[0],line[1]).replace("Abs","np.abs").replace("cos","np.cos").replace("sin","np.sin").replace("sign","np.sign")) print("{}".format(res[0]).replace("Abs","np.abs").replace("cos","np.cos").replace("sin","np.sin").replace("sign","np.sign"))
def test_bypass_non_commutatives(): A, B, C = symbols('A B C', commutative=False) l = [A*B*C, A*C] assert cse(l) == ([], l) l = [A*B*C, A*B] assert cse(l) == ([], l) l = [B*C, A*B*C] assert cse(l) == ([], l)
def test_cse_MatrixSymbol(): # MatrixSymbols have non-Basic args, so make sure that works A = MatrixSymbol("A", 3, 3) assert cse(A) == ([], [A]) n = symbols('n', integer=True) B = MatrixSymbol("B", n, n) assert cse(B) == ([], [B])
def test_cse_ignore(): exprs = [exp(y)*(3*y + 3*sqrt(x+1)), exp(y)*(5*y + 5*sqrt(x+1))] subst1, red1 = cse(exprs) assert any(y in sub.free_symbols for _, sub in subst1), "cse failed to identify any term with y" subst2, red2 = cse(exprs, ignore=(y,)) # y is not allowed in substitutions assert not any(y in sub.free_symbols for _, sub in subst2), "Sub-expressions containing y must be ignored" assert any(sub - sqrt(x + 1) == 0 for _, sub in subst2), "cse failed to identify sqrt(x + 1) as sub-expression"
def test_derivative_subs(): y = Symbol("y") f = Function("f") assert Derivative(f(x), x).subs(f(x), y) != 0 assert Derivative(f(x), x).subs(f(x), y).subs(y, f(x)) == Derivative(f(x), x) # issues 1986, 1938 assert cse(Derivative(f(x), x) + f(x))[1][0].has(Derivative) assert cse(Derivative(f(x, y), x) + Derivative(f(x, y), y))[1][0].has(Derivative)
def test_cse_not_possible(): # No substitution possible. e = Add(x, y) substs, reduced = cse([e]) assert substs == [] assert reduced == [x + y] # issue 6329 eq = meijerg((1, 2), (y, 4), (5,), [], x) + meijerg((1, 3), (y, 4), (5,), [], x) assert cse(eq) == ([], [eq])
def test_cse_not_possible(): # No substitution possible. e = Add(x, y) substs, reduced = cse([e], optimizations=[]) assert substs == [] assert reduced == [x + y] # issue 3230 eq = (meijerg((1, 2), (y, 4), (5,), [], x) + \ meijerg((1, 3), (y, 4), (5,), [], x)) assert cse(eq) == ([], [eq])
def test_derivative_subs(): y = Symbol('y') f = Function('f') assert Derivative(f(x), x).subs(f(x), y) != 0 assert Derivative(f(x), x).subs(f(x), y).subs(y, f(x)) == \ Derivative(f(x), x) # issues 5085, 5037 assert cse(Derivative(f(x), x) + f(x))[1][0].has(Derivative) assert cse(Derivative(f(x, y), x) + Derivative(f(x, y), y))[1][0].has(Derivative)
def test_issue_10228(): assert cse([x*y**2 + x*y]) == ([(x0, x*y)], [x0*y + x0]) assert cse([x + y, 2*x + y]) == ([(x0, x + y)], [x0, x + x0]) assert cse((w + 2*x + y + z, w + x + 1)) == ( [(x0, w + x)], [x0 + x + y + z, x0 + 1]) assert cse(((w + x + y + z)*(w - x))/(w + x)) == ( [(x0, w + x)], [(x0 + y + z)*(w - x)/x0]) a, b, c, d, f, g, j, m = symbols('a, b, c, d, f, g, j, m') exprs = (d*g**2*j*m, 4*a*f*g*m, a*b*c*f**2) assert cse(exprs) == ( [(x0, g*m), (x1, a*f)], [d*g*j*x0, 4*x0*x1, b*c*f*x1])
def test_derivative_subs(): x = Symbol('x') y = Symbol('y') f = Function('f') assert Derivative(f(x), x).subs(f(x), y) != 0 assert Derivative(f(x), x).subs(f(x), y).subs(y, f(x)) == \ Derivative(f(x), x) # issues 1986, 1938 assert cse(Derivative(f(x), x) + f(x))[1][0].has(Derivative) assert cse(Derivative(f(x, y), x) + Derivative(f(x, y), y))[1][0].has(Derivative)
def test_derivative_subs(): y = Symbol('y') f = Function('f') assert Derivative(f(x), x).subs(f(x), y) != 0 # need xreplace to put the function back, see #13803 assert Derivative(f(x), x).subs(f(x), y).xreplace({y: f(x)}) == \ Derivative(f(x), x) # issues 5085, 5037 assert cse(Derivative(f(x), x) + f(x))[1][0].has(Derivative) assert cse(Derivative(f(x, y), x) + Derivative(f(x, y), y))[1][0].has(Derivative)
def test_cse_single(): # Simple substitution. e = Add(Pow(x + y, 2), sqrt(x + y)) substs, reduced = cse([e]) assert substs == [(x0, x + y)] assert reduced == [sqrt(x0) + x0**2] subst42, (red42,) = cse([42]) # issue_15082 assert len(subst42) == 0 and red42 == 42 subst_half, (red_half,) = cse([0.5]) assert len(subst_half) == 0 and red_half == 0.5
def test_subtraction_opt(): # Make sure subtraction is optimized. e = (x-y)*(z-y) + exp((x-y)*(z-y)) substs, reduced = cse([e], optimizations=[(cse_opts.sub_pre,cse_opts.sub_post)]) assert substs == [(x0, x - y), (x1, y - z), (x2, x0*x1)] assert reduced == [-x2 + exp(-x2)] assert cse(-(x - y)*(z - y) + exp(-(x - y)*(z - y))) == \ ([(x0, (x - y)*(y - z))], [x0 + exp(x0)]) # issue 978 n = -1 + 1/x e = n/x/(-n)**2 - 1/n/x assert cse(e) == ([], [0])
def test_cse_single2(): # Simple substitution, test for being able to pass the expression directly e = Add(Pow(x + y, 2), sqrt(x + y)) substs, reduced = cse(e) assert substs == [(x0, x + y)] assert reduced == [sqrt(x0) + x0**2] substs, reduced = cse(Matrix([[1]])) assert isinstance(reduced[0], Matrix) subst42, (red42,) = cse(42) # issue 15082 assert len(subst42) == 0 and red42 == 42 subst_half, (red_half,) = cse(0.5) # issue 15082 assert len(subst_half) == 0 and red_half == 0.5
def test_pow_invpow(): assert cse(1 / x ** 2 + x ** 2) == ([(x0, x ** 2)], [x0 + 1 / x0]) assert cse(x ** 2 + (1 + 1 / x ** 2) / x ** 2) == ([(x0, x ** 2), (x1, 1 / x0)], [x0 + x1 * (x1 + 1)]) assert cse(1 / x ** 2 + (1 + 1 / x ** 2) * x ** 2) == ([(x0, x ** 2), (x1, 1 / x0)], [x0 * (x1 + 1) + x1]) assert cse(cos(1 / x ** 2) + sin(1 / x ** 2)) == ([(x0, x ** (-2))], [sin(x0) + cos(x0)]) assert cse(cos(x ** 2) + sin(x ** 2)) == ([(x0, x ** 2)], [sin(x0) + cos(x0)]) assert cse(y / (2 + x ** 2) + z / x ** 2 / y) == ([(x0, x ** 2)], [y / (x0 + 2) + z / (x0 * y)]) assert cse(exp(x ** 2) + x ** 2 * cos(1 / x ** 2)) == ([(x0, x ** 2)], [x0 * cos(1 / x0) + exp(x0)]) assert cse((1 + 1 / x ** 2) / x ** 2) == ([(x0, x ** (-2))], [x0 * (x0 + 1)]) assert cse(x ** (2 * y) + x ** (-2 * y)) == ([(x0, x ** (2 * y))], [x0 + 1 / x0])
def test_subtraction_opt(): # Make sure subtraction is optimized. e = (x - y) * (z - y) + exp((x - y) * (z - y)) substs, reduced = cse([e], optimizations=[(cse_opts.sub_pre, cse_opts.sub_post)]) assert substs == [(x0, (x - y) * (y - z))] assert reduced == [-x0 + exp(-x0)] e = -(x - y) * (z - y) + exp(-(x - y) * (z - y)) substs, reduced = cse([e], optimizations=[(cse_opts.sub_pre, cse_opts.sub_post)]) assert substs == [(x0, (x - y) * (y - z))] assert reduced == [x0 + exp(x0)] # issue 4077 n = -1 + 1 / x e = n / x / (-n) ** 2 - 1 / n / x assert cse(e, optimizations=[(cse_opts.sub_pre, cse_opts.sub_post)]) == ([], [0])
def test_dont_cse_tuples(): from sympy import Subs f = Function("f") g = Function("g") name_val, (expr,) = cse(Subs(f(x, y), (x, y), (0, 1)) + Subs(g(x, y), (x, y), (0, 1))) assert name_val == [] assert expr == (Subs(f(x, y), (x, y), (0, 1)) + Subs(g(x, y), (x, y), (0, 1))) name_val, (expr,) = cse(Subs(f(x, y), (x, y), (0, x + y)) + Subs(g(x, y), (x, y), (0, x + y))) assert name_val == [(x0, x + y)] assert expr == Subs(f(x, y), (x, y), (0, x0)) + Subs(g(x, y), (x, y), (0, x0))
def test_cse_MatrixExpr(): from sympy import MatrixSymbol A = MatrixSymbol('A', 3, 3) y = MatrixSymbol('y', 3, 1) expr1 = (A.T*A).I * A * y expr2 = (A.T*A) * A * y replacements, reduced_exprs = cse([expr1, expr2]) assert len(replacements) > 0 replacements, reduced_exprs = cse([expr1 + expr2, expr1]) assert replacements replacements, reduced_exprs = cse([A**2, A + A**2]) assert replacements
def test_derivative_subs(): f = Function('f') g = Function('g') assert Derivative(f(x), x).subs(f(x), y) != 0 # need xreplace to put the function back, see #13803 assert Derivative(f(x), x).subs(f(x), y).xreplace({y: f(x)}) == \ Derivative(f(x), x) # issues 5085, 5037 assert cse(Derivative(f(x), x) + f(x))[1][0].has(Derivative) assert cse(Derivative(f(x, y), x) + Derivative(f(x, y), y))[1][0].has(Derivative) eq = Derivative(g(x), g(x)) assert eq.subs(g, f) == Derivative(f(x), f(x)) assert eq.subs(g(x), f(x)) == Derivative(f(x), f(x)) assert eq.subs(g, cos) == Subs(Derivative(y, y), y, cos(x))
def analytical_coefs_sympy(): import sympy from sympy.matrices import Matrix x0, x1, y0, y1, dy0, dy1, x = sympy.symbols('x0 x1 y0 y1 dy0 dy1 x') #a1,a2,a3,a4 = sympy.symbols('a0 a1 a2 a3') # ===== setup bas1=1+0*x bas2=x**2 bas3=x**4 bas4=x**6 # ===== Main dbas1=sympy.diff(bas1, x); dbas2=sympy.diff(bas2, x); dbas3=sympy.diff(bas3, x); dbas4=sympy.diff(bas4, x) #print ( " dbas1: ", dbas1); print ( " dbas2: ", dbas2); print ( " dbas3: ", dbas3); print ( " dbas4: ", dbas4) A = Matrix([ [ bas1.subs(x,x0), bas2.subs(x,x0), bas3.subs(x,x0), bas4.subs(x,x0) ], [ bas1.subs(x,x1), bas2.subs(x,x1), bas3.subs(x,x1), bas4.subs(x,x1) ], [ dbas1.subs(x,x0), dbas2.subs(x,x0), dbas3.subs(x,x0), dbas4.subs(x,x0) ], [ dbas1.subs(x,x1), dbas2.subs(x,x1), dbas3.subs(x,x1), dbas4.subs(x,x1) ]]) system = Matrix(4,1,[y0,y1,dy0,dy1]) print ("Solving matrix ...") coefs = A.LUsolve(system) print ("Symplyfying ...") for i,coef in enumerate(coefs): coef = coef.factor() coef = coef.collect([x0,x1]) #print ( " coef %i: " %i, coef ) coef_subs = sympy.cse(coef) print ( " coef %i: " %i, coef_subs )
def cached_cse(exprs, symbols): assert isinstance(symbols, _SymbolGenerator) from pytools.diskdict import get_disk_dict cache_dict = get_disk_dict("sumpy-cse-cache", version=1) # sympy expressions don't pickle properly :( # (as of Jun 7, 2013) # https://code.google.com/p/sympy/issues/detail?id=1198 from pymbolic.interop.sympy import ( SympyToPymbolicMapper, PymbolicToSympyMapper) s2p = SympyToPymbolicMapper() p2s = PymbolicToSympyMapper() key_exprs = tuple(s2p(expr) for expr in exprs) key = (key_exprs, frozenset(symbols.taken_symbols), frozenset(symbols.generated_names)) try: result = cache_dict[key] except KeyError: result = sp.cse(exprs, symbols) cache_dict[key] = _map_cse_result(s2p, result) return result else: return _map_cse_result(p2s, result)
def test_issue_3460(): assert (-12*x + y).subs(-x, 1) == 12 + y # though this involves cse it generated a failure in Mul._eval_subs x0, x1 = symbols('x0 x1') e = -log(-12*sqrt(2) + 17)/24 - log(-2*sqrt(2) + 3)/12 + sqrt(2)/3 assert cse(e) == ( [(x0, -sqrt(2))], [-x0/3 - log(2*x0 + 3)/12 - log(12*x0 + 17)/24])
def test_callback_cubature_multiple(): e1 = a*a e2 = a*a + b*b e3 = sympy.cse([e1, e2, 4*e2]) f = g.llvm_callable([a, b], e3, callback_type='cubature') # Number of input variables ndim = 2 # Number of output expression values outdim = 3 m = ctypes.c_int(ndim) fdim = ctypes.c_int(outdim) array_type = ctypes.c_double * ndim out_array_type = ctypes.c_double * outdim inp = {a: 0.2, b: 1.5} array = array_type(inp[a], inp[b]) out_array = out_array_type() jit_ret = f(m, array, None, fdim, out_array) assert jit_ret == 0 res = eval_cse(e3, inp) assert isclose(out_array[0], res[0]) assert isclose(out_array[1], res[1]) assert isclose(out_array[2], res[2])
def sol_cse (sol_dict): update, ord = sol_dict new_sym, new_exprs = cse(update.values()) ret_dict = dict(new_sym) for n, k in enumerate(update.keys()): ret_dict[k] = new_exprs[n] return ret_dict, ord
def get_cse_code(self, exprs, basename=None, dummy_groups=(), arrayify_groups=()): """ Get arrayified code for common subexpression. Parameters ---------- exprs : list of sympy expressions basename : str Stem of variable names (default: cse). dummy_groups : tuples """ if basename is None: basename = 'cse' cse_defs, cse_exprs = sympy.cse( exprs, symbols=sympy.numbered_symbols(basename)) # Let's convert the new expressions into (arrayified) code cse_defs_code = [ (vname, self.as_arrayified_code( vexpr, dummy_groups, arrayify_groups)) for vname, vexpr in cse_defs ] cse_exprs_code = [self.as_arrayified_code( x, dummy_groups, arrayify_groups) for x in cse_exprs] return cse_defs_code, cse_exprs_code
def test_issue_3460(): assert (-12 * x + y).subs(-x, 1) == 12 + y # though this involves cse it generated a failure in Mul._eval_subs x0, x1 = symbols("x0 x1") e = -log(-12 * sqrt(2) + 17) / 24 - log(-2 * sqrt(2) + 3) / 12 + sqrt(2) / 3 # XXX modify cse so x1 is eliminated and x0 = -sqrt(2)? assert cse(e) == ([(x0, sqrt(2))], [x0 / 3 - log(-12 * x0 + 17) / 24 - log(-2 * x0 + 3) / 12])
def test_issue_4499(): # previously, this gave 16 constants from sympy.abc import a, b B = Function('B') G = Function('G') t = Tuple(* (a, a + S(1)/2, 2*a, b, 2*a - b + 1, (sqrt(z)/2)**(-2*a + 1)*B(2*a - b, sqrt(z))*B(b - 1, sqrt(z))*G(b)*G(2*a - b + 1), sqrt(z)*(sqrt(z)/2)**(-2*a + 1)*B(b, sqrt(z))*B(2*a - b, sqrt(z))*G(b)*G(2*a - b + 1), sqrt(z)*(sqrt(z)/2)**(-2*a + 1)*B(b - 1, sqrt(z))*B(2*a - b + 1, sqrt(z))*G(b)*G(2*a - b + 1), (sqrt(z)/2)**(-2*a + 1)*B(b, sqrt(z))*B(2*a - b + 1, sqrt(z))*G(b)*G(2*a - b + 1), 1, 0, S(1)/2, z/2, -b + 1, -2*a + b, -2*a)) c = cse(t) # check rebuild r = c[0] tt = list(c[1][0]) for i in range(len(tt)): for re in reversed(r): tt[i] = tt[i].subs(*re) assert tt[i] == t[i] # check answer ans = ( [(x0, 2*a), (x1, -b), (x2, x0 + x1 + 1), (x3, sqrt(z)), (x4, B(x0 + x1, x3)), (x5, G(b)), (x6, G(x2)), (x7, -x0), (x8, (x3/2)**(x7 + 1)), (x9, x5*x6*x8*B(b - 1, x3)), (x10, x5*x6*x8*B(b, x3)), (x11, B(x2, x3))], [(a, a + 1/2, x0, b, x2, x4*x9, x10*x3*x4, x11*x3*x9, x10*x11, 1, 0, 1/2, z/2, x1 + 1, b + x7, x7)]) assert ans == c
def test_hollow_rejection(): eq = [x + 3, x + 4] assert cse(eq) == ([], eq)
if(command == 'diff'): for s in expression.free_symbols: if(str(s) == variable): result = sympy.diff(expression, s) elif(command == 'integrate'): for s in expression.free_symbols: if(str(s) == variable): result = sympy.integrate(expression, s) elif(command == 'extrema'): for s in expression.free_symbols: if(str(s) == variable): result = sympy.diff(expression, s) result = sympy.solve(result, s) result = result[0] elif(command == 'simplify'): result = sympy.simplify(expression) pythonDict = {} pythonDict["Variables"], pythonDict["Expression"] = sympy.cse(result) for i, expr in enumerate(pythonDict["Variables"]): tdict = {} tdict["name"] = str(expr[0]) tdict["expr"] = str(sympy.jscode(expr[1])) pythonDict["Variables"][i] = tdict pythonDict["Expression"] = sympy.jscode(pythonDict["Expression"][0]) print(json.dumps(pythonDict, indent=4)) sys.stdout.flush()
def test_postprocess(): eq = (x + 1 + exp((x + 1) / (y + 1)) + cos(y + 1)) assert cse([eq, Eq(x, z + 1), z - 2, (z + 1)*(x + 1)], postprocess=cse_main.cse_separate) == \ [[(x0, y + 1), (x2, z + 1), (x, x2), (x1, x + 1)], [x1 + exp(x1/x0) + cos(x0), z - 2, x1*x2]]
def test_issue_12070(): exprs = [x + y, 2 + x + y, x + y + z, 3 + x + y + z] subst, red = cse(exprs) assert 6 >= (len(subst) + sum([v.count_ops() for k, v in subst]) + count_ops(red))
def test_non_commutative_cse(): A, B, C = symbols("A B C", commutative=False) l = [A * B * C, A * C] assert cse(l) == ([], l) l = [A * B * C, A * B] assert cse(l) == ([(x0, A * B)], [x0 * C, x0])
def test_issue_6169(): r = CRootOf(x**6 - 4 * x**5 - 2, 1) assert cse(r) == ([], [r]) # and a check that the right thing is done with the new # mechanism assert sub_post(sub_pre((-x - y) * z - x - y)) == -z * (x + y) - x - y
def test_ignore_order_terms(): eq = exp(x).series(x, 0, 3) + sin(y + x**3) - 1 assert cse(eq) == ([], [sin(x**3 + y) + x + x**2 / 2 + O(x**3)])
def test_name_conflict(): z1 = x0 + y z2 = x2 + x3 l = [cos(z1) + z1, cos(z2) + z2, x0 + x2] substs, reduced = cse(l) assert [e.subs(reversed(substs)) for e in reduced] == l
def test_unevaluated_mul(): eq = Mul(x + y, x + y, evaluate=False) assert cse(eq) == ([(x0, x + y)], [x0**2])
def test_issue_13000(): eq = x / (-4 * x**2 + y**2) cse_eq = cse(eq)[1][0] assert cse_eq == eq
def test_issue_4498(): assert cse(w / (x - y) + z / (y - x), optimizations="basic") == ( [], [(w - z) / (x - y)], )
def test_issue_4499(): # previously, this gave 16 constants from sympy.abc import a, b B = Function("B") G = Function("G") t = Tuple(*( a, a + S.Half, 2 * a, b, 2 * a - b + 1, (sqrt(z) / 2)**(-2 * a + 1) * B(2 * a - b, sqrt(z)) * B(b - 1, sqrt(z)) * G(b) * G(2 * a - b + 1), sqrt(z) * (sqrt(z) / 2)**(-2 * a + 1) * B(b, sqrt(z)) * B(2 * a - b, sqrt(z)) * G(b) * G(2 * a - b + 1), sqrt(z) * (sqrt(z) / 2)**(-2 * a + 1) * B(b - 1, sqrt(z)) * B(2 * a - b + 1, sqrt(z)) * G(b) * G(2 * a - b + 1), (sqrt(z) / 2)**(-2 * a + 1) * B(b, sqrt(z)) * B(2 * a - b + 1, sqrt(z)) * G(b) * G(2 * a - b + 1), 1, 0, S.Half, z / 2, -b + 1, -2 * a + b, -2 * a, )) c = cse(t) ans = ( [ (x0, 2 * a), (x1, -b), (x2, x0 + x1), (x3, x2 + 1), (x4, sqrt(z)), (x5, B(b - 1, x4)), (x6, -x0), (x7, (x4 / 2)**(x6 + 1) * G(b) * G(x3)), (x8, x7 * B(x2, x4)), (x9, B(b, x4)), (x10, x7 * B(x3, x4)), ], [( a, a + S.Half, x0, b, x3, x5 * x8, x4 * x8 * x9, x10 * x4 * x5, x10 * x9, 1, 0, S.Half, z / 2, x1 + 1, b + x6, x6, )], ) assert ans == c
def test_powers(): assert cse(x * y**2 + x * y) == ([(x0, x * y)], [x0 * y + x0])
def test_issue_6263(): e = Eq(x * (-x + 1) + x * (x - 1), 0) assert cse(e, optimizations="basic") == ([], [True])
def test_non_commutative_order(): A, B, C = symbols("A B C", commutative=False) x0 = symbols("x0", commutative=False) l = [B + C, A * (B + C)] assert cse(l) == ([(x0, B + C)], [x0, A * x0])
def test_nested_substitution(): # Substitution within a substitution. e = Add(Pow(w * x + y, 2), sqrt(w * x + y)) substs, reduced = cse([e]) assert substs == [(x0, w * x + y)] assert reduced == [sqrt(x0) + x0**2]
def test_multiple_expressions(): e1 = (x + y) * z e2 = (x + y) * w substs, reduced = cse([e1, e2]) assert substs == [(x0, x + y)] assert reduced == [x0 * z, x0 * w] l = [w * x * y + z, w * y] substs, reduced = cse(l) rsubsts, _ = cse(reversed(l)) assert substs == rsubsts assert reduced == [z + x * x0, x0] l = [w * x * y, w * x * y + z, w * y] substs, reduced = cse(l) rsubsts, _ = cse(reversed(l)) assert substs == rsubsts assert reduced == [x1, x1 + z, x0] l = [(x - z) * (y - z), x - z, y - z] substs, reduced = cse(l) rsubsts, _ = cse(reversed(l)) assert substs == [(x0, -z), (x1, x + x0), (x2, x0 + y)] assert rsubsts == [(x0, -z), (x1, x0 + y), (x2, x + x0)] assert reduced == [x1 * x2, x1, x2] l = [w * y + w + x + y + z, w * x * y] assert cse(l) == ([(x0, w * y)], [w + x + x0 + y + z, x * x0]) assert cse([x + y, x + y + z]) == ([(x0, x + y)], [x0, z + x0]) assert cse([x + y, x + z]) == ([], [x + y, x + z]) assert cse([x * y, z + x * y, x * y * z + 3]) == ( [(x0, x * y)], [x0, z + x0, 3 + x0 * z], )
def test_cse_single(): # Simple substitution. e = Add(Pow(x + y, 2), sqrt(x + y)) substs, reduced = cse([e]) assert substs == [(x0, x + y)] assert reduced == [sqrt(x0) + x0**2]
def test_issue_4203(): assert cse(sin(x**x) / x**x) == ([(x0, x**x)], [sin(x0) / x0])
def test_cse_ignore_issue_15002(): l = [w * exp(x) * exp(-z), exp(y) * exp(x) * exp(-z)] substs, reduced = cse(l, ignore=(x, )) rl = [e.subs(reversed(substs)) for e in reduced] assert rl == l
def outputC(sympyexpr, output_varname_str, filename="stdout", params="", prestring="", poststring=""): outCparams = parse_outCparams_string(params) preindent = outCparams.preindent TYPE = par.parval_from_str("PRECISION") if outCparams.enable_TYPE == "False": TYPE = "" # Step 0: Initialize # commentblock: comment block containing the input SymPy string, # set only if outCverbose==True # outstring: the output C code string commentblock = "" outstring = "" # Step 1: If SIMD_enable==True, then check if TYPE=="double". If not, error out. # Otherwise set TYPE="REAL_SIMD_ARRAY", which should be #define'd # within the C code. For example for AVX-256, the C code should have # #define REAL_SIMD_ARRAY __m256d if outCparams.SIMD_enable == "True": if not (TYPE == "double" or TYPE == ""): print( "SIMD output currently only supports double precision or typeless. Sorry!" ) sys.exit(1) if TYPE == "double": TYPE = "REAL_SIMD_ARRAY" else: TYPE = "" # Step 2a: Apply sanity checks when either sympyexpr or # output_varname_str is a list. if type(output_varname_str) is list and type(sympyexpr) is not list: print( "Error: Provided a list of output variable names, but only one SymPy expression." ) sys.exit(1) if type(sympyexpr) is list: if type(output_varname_str) is not list: print( "Error: Provided a list of SymPy expressions, but no corresponding list of output variable names" ) sys.exit(1) elif len(output_varname_str) != len(sympyexpr): print("Error: Length of SymPy expressions list (" + str(len(sympyexpr)) + ") != Length of corresponding output variable name list (" + str(len(output_varname_str)) + ")") sys.exit(1) # Step 2b: If sympyexpr and output_varname_str are not lists, # convert them to lists of one element each, to # simplify proceeding code. if type(output_varname_str) is not list and type(sympyexpr) is not list: output_varname_strtmp = [output_varname_str] output_varname_str = output_varname_strtmp sympyexprtmp = [sympyexpr] sympyexpr = sympyexprtmp # Step 3: If outCparams.verbose = True, then output the original SymPy # expression(s) in code comments prior to actual C code if outCparams.outCverbose == "True": commentblock += preindent + "/*\n" + preindent + " * Original SymPy expression" if len(output_varname_str) > 1: commentblock += "s" commentblock += ":\n" for i in range(len(output_varname_str)): if i == 0: if len(output_varname_str) != 1: commentblock += preindent + " * \"[" else: commentblock += preindent + " * \"" else: commentblock += preindent + " * " commentblock += output_varname_str[i] + " = " + str(sympyexpr[i]) if i == len(output_varname_str) - 1: if len(output_varname_str) != 1: commentblock += "]\"\n" else: commentblock += "\"\n" else: commentblock += ",\n" commentblock += preindent + " */\n" # Step 4: Add proper indentation of C code: if outCparams.includebraces == "True": indent = outCparams.preindent + " " else: indent = outCparams.preindent + "" # Step 5: Should the output variable, e.g., outvar, be declared? # If so, start output line with e.g., "double outvar " outtypestring = "" if outCparams.declareoutputvars == "True": outtypestring = outCparams.preindent + indent + TYPE + " " else: outtypestring = outCparams.preindent + indent # Step 6a: If common subexpression elimination (CSE) disabled, then # just output the SymPy string in the most boring way, # nearly consistent with SymPy's ccode() function, # though with support for float & long double types # as well. SIMD_decls = "" if outCparams.CSE_enable == "False": # If CSE is disabled: for i in range(len(sympyexpr)): outstring += outtypestring + ccode_postproc( sp.ccode( sympyexpr[i], output_varname_str[i], user_functions=custom_functions_for_SymPy_ccode)) + "\n" # Step 6b: If CSE enabled, then perform CSE using SymPy and then # resulting C code. else: # If CSE is enabled: SIMD_const_varnms = [] SIMD_const_values = [] CSE_results = sp.cse(sympyexpr, sp.numbered_symbols(outCparams.CSE_varprefix), order='canonical') for commonsubexpression in CSE_results[0]: FULLTYPESTRING = "const " + TYPE + " " if outCparams.enable_TYPE == "False": FULLTYPESTRING = "" if outCparams.SIMD_enable == "True": outstring += outCparams.preindent + indent + FULLTYPESTRING + str(commonsubexpression[0]) + " = " + \ str(expr_convert_to_SIMD_intrins(commonsubexpression[1],SIMD_const_varnms,SIMD_const_values,outCparams.SIMD_const_suffix,outCparams.SIMD_debug)) + ";\n" else: outstring += outCparams.preindent + indent + FULLTYPESTRING + ccode_postproc( sp.ccode(commonsubexpression[1], commonsubexpression[0], user_functions=custom_functions_for_SymPy_ccode) ) + "\n" for i, result in enumerate(CSE_results[1]): if outCparams.SIMD_enable == "True": outstring += outtypestring + output_varname_str[i] + " = " + \ str(expr_convert_to_SIMD_intrins(result,SIMD_const_varnms,SIMD_const_values,outCparams.SIMD_const_suffix,outCparams.SIMD_debug)) + ";\n" else: outstring += outtypestring + ccode_postproc( sp.ccode(result, output_varname_str[i], user_functions=custom_functions_for_SymPy_ccode) ) + "\n" # Step 6b.i: If SIMD_enable == True , and # there is at least one SIMD const variable, # then declare the SIMD_const_varnms and SIMD_const_values arrays if outCparams.SIMD_enable == "True" and len(SIMD_const_varnms) != 0: # Step 6a) Sort the list of definitions. Idea from: # https://stackoverflow.com/questions/9764298/is-it-possible-to-sort-two-listswhich-reference-each-other-in-the-exact-same-w SIMD_const_varnms, SIMD_const_values = \ (list(t) for t in zip(*sorted(zip(SIMD_const_varnms, SIMD_const_values)))) # Step 6b) Remove duplicates uniq_varnms = superfast_uniq(SIMD_const_varnms) uniq_values = superfast_uniq(SIMD_const_values) SIMD_const_varnms = uniq_varnms SIMD_const_values = uniq_values if len(SIMD_const_varnms) != len(SIMD_const_values): print( "Error: SIMD constant declaration arrays SIMD_const_varnms[] and SIMD_const_values[] have inconsistent sizes!" ) sys.exit(1) for i in range(len(SIMD_const_varnms)): if outCparams.enable_TYPE == "False": SIMD_decls += outCparams.preindent + indent + SIMD_const_varnms[ i] + " = " + SIMD_const_values[i] + ";" else: SIMD_decls += outCparams.preindent + indent + "const double " + outCparams.CSE_varprefix + SIMD_const_varnms[ i] + " = " + SIMD_const_values[i] + ";\n" SIMD_decls += outCparams.preindent + indent + "const REAL_SIMD_ARRAY " + SIMD_const_varnms[ i] + " = ConstSIMD(" + outCparams.CSE_varprefix + SIMD_const_varnms[ i] + ");\n" SIMD_decls += "\n" # Step 7: Construct final output string final_Ccode_output_str = commentblock # Step 7a: Output C code in indented curly brackets if # outCparams.includebraces = True if outCparams.includebraces == "True": final_Ccode_output_str += outCparams.preindent + "{\n" final_Ccode_output_str += prestring + SIMD_decls + outstring + poststring if outCparams.includebraces == "True": final_Ccode_output_str += outCparams.preindent + "}\n" # Step 8: If filename == "stdout", then output # C code to standard out (useful for copy-paste or interactive # mode). Otherwise output to file specified in variable name. if filename == "stdout": # Output to standard out (stdout; "the screen") print(final_Ccode_output_str) elif filename == "returnstring": return final_Ccode_output_str else: # Output to the file specified by the function input parameter string 'filename': with open(filename, outCparams.outCfileaccess) as file: file.write(final_Ccode_output_str) successstr = "" if outCparams.outCfileaccess == "a": successstr = "Appended " elif outCparams.outCfileaccess == "w": successstr = "Wrote " print(successstr + "to file \"" + filename + "\"")
def test_issue_4020(): assert cse(x**5 + x**4 + x**3 + x**2, optimizations="basic") == ( [(x0, x**2)], [x0 * (x**3 + x + x0 + 1)], )
def test_Piecewise(): f = Piecewise((-z + x * y, Eq(y, 0)), (-z - x * y, True)) ans = cse(f) actual_ans = ([(x0, -z), (x1, x * y)], [Piecewise((x0 + x1, Eq(y, 0)), (x0 - x1, True))]) assert ans == actual_ans
def outputC(sympyexpr, output_varname_str, filename="stdout", params="", prestring="", poststring=""): outCparams = parse_outCparams_string(params) preindent = outCparams.preindent TYPE = par.parval_from_str("PRECISION") if outCparams.enable_TYPE == "False": TYPE = "" # Step 0: Initialize # commentblock: comment block containing the input SymPy string, # set only if outCverbose==True # outstring: the output C code string commentblock = "" outstring = "" # Step 1: If SIMD_enable==True, then check if TYPE=="double". If not, error out. # Otherwise set TYPE="REAL_SIMD_ARRAY", which should be #define'd # within the C code. For example for AVX-256, the C code should have # #define REAL_SIMD_ARRAY __m256d if outCparams.SIMD_enable == "True": if TYPE not in ('double', ''): print( "SIMD output currently only supports double precision or typeless. Sorry!" ) sys.exit(1) if TYPE == "double": TYPE = "REAL_SIMD_ARRAY" # Step 2a: Apply sanity checks when either sympyexpr or # output_varname_str is a list. if type(output_varname_str) is list and type(sympyexpr) is not list: print( "Error: Provided a list of output variable names, but only one SymPy expression." ) sys.exit(1) if type(sympyexpr) is list: if type(output_varname_str) is not list: print( "Error: Provided a list of SymPy expressions, but no corresponding list of output variable names" ) sys.exit(1) elif len(output_varname_str) != len(sympyexpr): print("Error: Length of SymPy expressions list (" + str(len(sympyexpr)) + ") != Length of corresponding output variable name list (" + str(len(output_varname_str)) + ")") sys.exit(1) # Step 2b: If sympyexpr and output_varname_str are not lists, # convert them to lists of one element each, to # simplify proceeding code. if type(output_varname_str) is not list and type(sympyexpr) is not list: output_varname_strtmp = [output_varname_str] output_varname_str = output_varname_strtmp sympyexprtmp = [sympyexpr] sympyexpr = sympyexprtmp sympyexpr = sympyexpr[:] # pass-by-value (copy list) # Step 3: If outCparams.verbose = True, then output the original SymPy # expression(s) in code comments prior to actual C code if outCparams.outCverbose == "True": commentblock += preindent + "/*\n" + preindent + " * Original SymPy expression" if len(output_varname_str) > 1: commentblock += "s" commentblock += ":\n" for i in range(len(output_varname_str)): if i == 0: if len(output_varname_str) != 1: commentblock += preindent + " * \"[" else: commentblock += preindent + " * \"" else: commentblock += preindent + " * " commentblock += output_varname_str[i] + " = " + str(sympyexpr[i]) if i == len(output_varname_str) - 1: if len(output_varname_str) != 1: commentblock += "]\"\n" else: commentblock += "\"\n" else: commentblock += ",\n" commentblock += preindent + " */\n" # Step 4: Add proper indentation of C code: if outCparams.includebraces == "True": indent = outCparams.preindent + " " else: indent = outCparams.preindent + "" # Step 5: Should the output variable, e.g., outvar, be declared? # If so, start output line with e.g., "double outvar " outtypestring = "" if outCparams.declareoutputvars == "True": outtypestring = outCparams.preindent + indent + TYPE + " " else: outtypestring = outCparams.preindent + indent # Step 6a: If common subexpression elimination (CSE) disabled, then # just output the SymPy string in the most boring way, # nearly consistent with SymPy's ccode() function, # though with support for float & long double types # as well. SIMD_RATIONAL_decls = RATIONAL_decls = "" if outCparams.CSE_enable == "False": # If CSE is disabled: for i in range(len(sympyexpr)): outstring += outtypestring + ccode_postproc( sp.ccode( sympyexpr[i], output_varname_str[i], user_functions=custom_functions_for_SymPy_ccode)) + "\n" # Step 6b: If CSE enabled, then perform CSE using SymPy and then # resulting C code. else: # If CSE is enabled: SIMD_const_varnms = [] SIMD_const_values = [] varprefix = '' if outCparams.CSE_varprefix == 'tmp' else outCparams.CSE_varprefix if outCparams.CSE_preprocess == "True" or outCparams.SIMD_enable == "True": # If CSE_preprocess == True, then perform partial factorization # If SIMD_enable == True, then declare _NegativeOne_ in preprocessing factor_negative = eval(outCparams.SIMD_enable) and eval( outCparams.SIMD_find_more_subs) sympyexpr, map_sym_to_rat = cse_preprocess(sympyexpr,prefix=varprefix,\ declare=eval(outCparams.SIMD_enable),negative=factor_negative,factor=eval(outCparams.CSE_preprocess)) for v in map_sym_to_rat: p, q = float(map_sym_to_rat[v].p), float(map_sym_to_rat[v].q) if outCparams.SIMD_enable == "False": RATIONAL_decls += outCparams.preindent + indent + 'const double ' + str( v) + ' = ' # Since Integer is a subclass of Rational in SymPy, we need only check whether # the denominator q = 1 to determine if a rational is an integer. if q != 1: RATIONAL_decls += str(p) + '/' + str(q) + ';\n' else: RATIONAL_decls += str(p) + ';\n' sympy_version = sp.__version__.replace('rc', '...').replace('b', '...') sympy_major_version = int(sympy_version.split(".")[0]) sympy_minor_version = int(sympy_version.split(".")[1]) if sympy_major_version < 1 or (sympy_major_version == 1 and sympy_minor_version < 3): print('Warning: SymPy version', sympy_version, 'does not support CSE postprocessing.') CSE_results = sp.cse(sympyexpr, sp.numbered_symbols(outCparams.CSE_varprefix + '_'), \ order=outCparams.CSE_sorting) else: CSE_results = cse_postprocess(sp.cse(sympyexpr, sp.numbered_symbols(outCparams.CSE_varprefix + '_'), \ order=outCparams.CSE_sorting)) for commonsubexpression in CSE_results[0]: FULLTYPESTRING = "const " + TYPE + " " if outCparams.enable_TYPE == "False": FULLTYPESTRING = "" if outCparams.SIMD_enable == "True": outstring += outCparams.preindent + indent + FULLTYPESTRING + str(commonsubexpression[0]) + " = " + \ str(expr_convert_to_SIMD_intrins(commonsubexpression[1],map_sym_to_rat,varprefix,outCparams.SIMD_find_more_FMAsFMSs)) + ";\n" else: outstring += outCparams.preindent + indent + FULLTYPESTRING + ccode_postproc( sp.ccode(commonsubexpression[1], commonsubexpression[0], user_functions=custom_functions_for_SymPy_ccode) ) + "\n" for i, result in enumerate(CSE_results[1]): if outCparams.SIMD_enable == "True": outstring += outtypestring + output_varname_str[i] + " = " + \ str(expr_convert_to_SIMD_intrins(result,map_sym_to_rat,varprefix,outCparams.SIMD_find_more_FMAsFMSs)) + ";\n" else: outstring += outtypestring + ccode_postproc( sp.ccode(result, output_varname_str[i], user_functions=custom_functions_for_SymPy_ccode) ) + "\n" # Complication: SIMD functions require numerical constants to be stored in SIMD arrays # Resolution: This function extends lists "SIMD_const_varnms" and "SIMD_const_values", # which store the name of each constant SIMD array (e.g., _Integer_1) and # the value of each variable (e.g., 1.0). if outCparams.SIMD_enable == "True": for v in map_sym_to_rat: p, q = float(map_sym_to_rat[v].p), float(map_sym_to_rat[v].q) SIMD_const_varnms.extend([str(v)]) if q != 1: SIMD_const_values.extend([str(p) + '/' + str(q)]) else: SIMD_const_values.extend([str(p)]) # Step 6b.i: If SIMD_enable == True , and # there is at least one SIMD const variable, # then declare the SIMD_const_varnms and SIMD_const_values arrays if outCparams.SIMD_enable == "True" and len(SIMD_const_varnms) != 0: # Step 6a) Sort the list of definitions. Idea from: # https://stackoverflow.com/questions/9764298/is-it-possible-to-sort-two-listswhich-reference-each-other-in-the-exact-same-w SIMD_const_varnms, SIMD_const_values = \ (list(t) for t in zip(*sorted(zip(SIMD_const_varnms, SIMD_const_values)))) # Step 6b) Remove duplicates uniq_varnms = superfast_uniq(SIMD_const_varnms) uniq_values = superfast_uniq(SIMD_const_values) SIMD_const_varnms = uniq_varnms SIMD_const_values = uniq_values if len(SIMD_const_varnms) != len(SIMD_const_values): print( "Error: SIMD constant declaration arrays SIMD_const_varnms[] and SIMD_const_values[] have inconsistent sizes!" ) sys.exit(1) for i in range(len(SIMD_const_varnms)): if outCparams.enable_TYPE == "False": SIMD_RATIONAL_decls += outCparams.preindent + indent + SIMD_const_varnms[ i] + " = " + SIMD_const_values[i] + ";" else: SIMD_RATIONAL_decls += outCparams.preindent + indent + "const double " + "tmp" + SIMD_const_varnms[ i] + " = " + SIMD_const_values[i] + ";\n" SIMD_RATIONAL_decls += outCparams.preindent + indent + "const REAL_SIMD_ARRAY " + SIMD_const_varnms[ i] + " = ConstSIMD(" + "tmp" + SIMD_const_varnms[ i] + ");\n" SIMD_RATIONAL_decls += "\n" # Step 7: Construct final output string final_Ccode_output_str = commentblock # Step 7a: Output C code in indented curly brackets if # outCparams.includebraces = True if outCparams.includebraces == "True": final_Ccode_output_str += outCparams.preindent + "{\n" final_Ccode_output_str += prestring + RATIONAL_decls + SIMD_RATIONAL_decls + outstring + poststring if outCparams.includebraces == "True": final_Ccode_output_str += outCparams.preindent + "}\n" # Step 8: If filename == "stdout", then output # C code to standard out (useful for copy-paste or interactive # mode). Otherwise output to file specified in variable name. if filename == "stdout": # Output to standard out (stdout; "the screen") print(final_Ccode_output_str) elif filename == "returnstring": return final_Ccode_output_str else: # Output to the file specified by the function input parameter string 'filename': with open(filename, outCparams.outCfileaccess) as file: file.write(final_Ccode_output_str) successstr = "" if outCparams.outCfileaccess == "a": successstr = "Appended " elif outCparams.outCfileaccess == "w": successstr = "Wrote " print(successstr + "to file \"" + filename + "\"")
def test_issue_4498(): assert cse(w/(x - y) + z/(y - x), optimizations='basic') == \ ([], [(w - z)/(x - y)])
def test_symbols_exhausted_error(): l = cos(x + y) + x + y + cos(w + y) + sin(w + y) sym = [x, y, z] with raises(ValueError): cse(l, symbols=sym)
symbol_dict = { q[1]: Symbol('q1'), q[2]: Symbol('q2'), qd[0]: Symbol('qd0'), r[0]: Symbol('rx'), r[1]: Symbol('ry'), r[2]: Symbol('rz') } for i in range(4): h[i] = h[i].subs(symbol_dict) for i in range(8): dh[i] = dh[i].subs(symbol_dict) # CSE on g's z, h_red = cse(h, numbered_symbols('z')) # Form output code for g's output_code = " // Intermediate variables for h's\n" for zi_lhs, zi_rhs in z: output_code += " {0} = {1};\n".format(zi_lhs, ccode(zi_rhs)) output_code += "\n // h's\n" for i in range(4): output_code += " h[{0}] = {1};\n".format(i, ccode(h_red[i])) # CSE on dh's z, dh_red = cse(dh, numbered_symbols('z')) # Form output code for dg's output_code += "\n // Intermediate variables for dh's\n"
def check(eq): r, c = cse(eq) assert eq.count_ops() >= len(r) + sum([i[1].count_ops() for i in r]) + count_ops(c)
def test_issue_18203(): eq = CRootOf(x**5 + 11 * x - 2, 0) + CRootOf(x**5 + 11 * x - 2, 1) assert cse(eq) == ([], [eq])
def test_name_conflict_cust_symbols(): z1 = x0 + y z2 = x2 + x3 l = [cos(z1) + z1, cos(z2) + z2, x0 + x2] substs, reduced = cse(l, symbols("x:10")) assert [e.subs(reversed(substs)) for e in reduced] == l