def test_wild_str(): # Check expressions containing Wild not causing infinite recursion w = Wild('x') assert str(w + 1) == 'x_ + 1' assert str(exp(2**w) + 5) == 'exp(2**x_) + 5' assert str(3 * w + 1) == '3*x_ + 1' assert str(1 / w + 1) == '1 + 1/x_' assert str(w**2 + 1) == 'x_**2 + 1' assert str(1 / (1 - w)) == '1/(1 - x_)'
def test_issue_4883(): a = Wild('a') x = Symbol('x') e = [i**2 for i in (x - 2, 2 - x)] p = [i**2 for i in (x - a, a- x)] for eq in e: for pat in p: assert eq.match(pat) == {a: 2}
def __new__(cls, f, limits, exprs): f = sympify(f) limits = sympify(limits) exprs = sympify(exprs) if not (type(exprs) == Tuple and len(exprs) == 3): # exprs is not of form (a0, an, bn) # Converts the expression to fourier form c, e = exprs.as_coeff_add() rexpr = c + Add(*[TR10(i) for i in e]) a0, exp_ls = rexpr.expand(trig=False, power_base=False, power_exp=False, log=False).as_coeff_add() x = limits[0] L = abs(limits[2] - limits[1]) / 2 a = Wild('a', properties=[ lambda k: k.is_Integer, lambda k: k is not S.Zero, ]) b = Wild('b', properties=[ lambda k: x not in k.free_symbols, ]) an = dict() bn = dict() # separates the coefficients of sin and cos terms in dictionaries an, and bn for p in exp_ls: t = p.match(b * cos(a * (pi / L) * x)) q = p.match(b * sin(a * (pi / L) * x)) if t: an[t[a]] = t[b] + an.get(t[a], S.Zero) elif q: bn[q[a]] = q[b] + bn.get(q[a], S.Zero) else: a0 += p exprs = Tuple(a0, an, bn) return Expr.__new__(cls, f, limits, exprs)
def find_limit(cls, f, x): """Basically identical to: return limit(f, x, 0, dir="+") but first trying some easy cases (like x**2) using heuristics, to avoid infinite recursion. This is only needed in the Order class and series expansion (that shouldn't rely on the Gruntz algorithm too much), that's why find_limit() is defined here. """ from sympy import limit, Wild, log if f.is_Pow: if f.args[0] == x: if f.args[1].is_Rational: if f.args[1] > 0: return S.Zero else: return oo if f.args[1].is_number: if f.args[1].evalf() > 0: return S.Zero else: return oo if f == x: return S.Zero p, q = Wild("p"), Wild("q") r = f.match(x**p * log(x)**q) if r: p, q = r[p], r[q] if q.is_number and p.is_number: if q > 0: if p > 0: return S.Zero else: return -oo elif q < 0: if p >= 0: return S.Zero else: return -oo return limit(f, x, 0, dir="+")
def get_units_map(self): """Maps from string units to symbolic units""" d = dict() star = Wild('star') for k, v in list(self.signatures.items()): unit = get_unit(v['units']) d[k] = unit d[v['symbol']] = unit return d
def _eval_imageset(self, f): from sympy import Wild expr = f.expr if len(f.variables) > 1: return n = f.variables[0] a = Wild('a') b = Wild('b') match = expr.match(a * n + b) if match[a].is_negative: expr = -expr match = expr.match(a * n + b) if match[a] is S.One and match[b].is_integer: expr = expr - match[b] return ImageSet(Lambda(n, expr), S.Integers)
def Function_derivatives(eq): Functions_extra = [] for ifun, f in zip(range(len(fvec)), fvec): neq1rgs = len(f.args) ff = f.func w = [Wild('w{}'.format(i)) for i in range(neq1rgs)] for i in range(neq1rgs): replace_what = Derivative(ff(*w), w[i]) eq = eq.replace(replace_what, fval[i + 1, ifun]) eq = eq.replace(ff(*w), fval[0, ifun]) return eq.doit()
def test_issue_13143(): fx = f(x).diff(x) e = f(x) + fx + f(x)*fx # collect function before derivative assert collect(e, Wild('w')) == f(x)*(fx + 1) + fx e = f(x) + f(x)*fx + x*fx*f(x) assert collect(e, fx) == (x*f(x) + f(x))*fx + f(x) assert collect(e, f(x)) == (x*fx + fx + 1)*f(x) e = f(x) + fx + f(x)*fx assert collect(e, [f(x), fx]) == f(x)*(1 + fx) + fx assert collect(e, [fx, f(x)]) == fx*(1 + f(x)) + f(x)
def test_match_exclude(): x = Symbol('x') y = Symbol('y') p = Wild("p") q = Wild("q") r = Wild("r") e = Rational(6) assert e.match(2 * p) == {p: 3} e = 3 / (4 * x + 5) assert e.match(3 / (p * x + q)) == {p: 4, q: 5} e = 3 / (4 * x + 5) assert e.match(p / (q * x + r)) == {p: 3, q: 4, r: 5} e = 2 / (x + 1) assert e.match(p / (q * x + r)) == {p: 2, q: 1, r: 1} e = 1 / (x + 1) assert e.match(p / (q * x + r)) == {p: 1, q: 1, r: 1} e = 4 * x + 5 assert e.match(p * x + q) == {p: 4, q: 5} e = 4 * x + 5 * y + 6 assert e.match(p * x + q * y + r) == {p: 4, q: 5, r: 6} a = Wild('a', exclude=[x]) e = 3 * x assert e.match(p * x) == {p: 3} assert e.match(a * x) == {a: 3} e = 3 * x**2 assert e.match(p * x) == {p: 3 * x} assert e.match(a * x) is None e = 3 * x + 3 + 6 / x assert e.match(p * x**2 + p * x + 2 * p) == {p: 3 / x} assert e.match(a * x**2 + a * x + 2 * a) is None
def _set_function(f, self): expr = f.expr if not isinstance(expr, Expr): return n = f.variables[0] if expr == abs(n): return S.Naturals0 # f(x) + c and f(-x) + c cover the same integers # so choose the form that has the fewest negatives c = f(0) fx = f(n) - c f_x = f(-n) - c neg_count = lambda e: sum(_coeff_isneg(_) for _ in Add.make_args(e)) if neg_count(f_x) < neg_count(fx): expr = f_x + c a = Wild('a', exclude=[n]) b = Wild('b', exclude=[n]) match = expr.match(a * n + b) if match and match[a]: # canonical shift b = match[b] if abs(match[a]) == 1: nonint = [] for bi in Add.make_args(b): if not bi.is_integer: nonint.append(bi) b = Add(*nonint) if b.is_number and match[a].is_real: mod = b % match[a] reps = dict([(m, m.args[0]) for m in mod.atoms(Mod) if not m.args[0].is_real]) mod = mod.xreplace(reps) expr = match[a] * n + mod else: expr = match[a] * n + b if expr != f.expr: return ImageSet(Lambda(n, expr), S.Integers)
def test_exclude(): x, y, a = map(Symbol, 'xya') p = Wild('p', exclude=[1, x]) q = Wild('q') r = Wild('r', exclude=[sin, y]) assert sin(x).match(r) is None assert cos(y).match(r) is None e = 3 * x**2 + y * x + a assert e.match(p * x**2 + q * x + r) == {p: 3, q: y, r: a} e = x + 1 assert e.match(x + p) is None assert e.match(p + 1) is None assert e.match(x + 1 + p) == {p: 0} e = cos(x) + 5 * sin(y) assert e.match(r) is None assert e.match(cos(y) + r) is None assert e.match(r + p * sin(q)) == {r: cos(x), p: 5, q: y}
def _eval_expand_func(self, **hints): arg = self.args[0] symbs = arg.atoms(Symbol) if len(symbs) == 1: z = symbs.pop() c = Wild("c", exclude=[z]) d = Wild("d", exclude=[z]) m = Wild("m", exclude=[z]) n = Wild("n", exclude=[z]) M = arg.match(c*(d*z**n)**m) if M is not None: m = M[m] # The transformation is given by 03.05.16.0001.01 # http://functions.wolfram.com/Bessel-TypeFunctions/AiryAi/16/01/01/0001/ if (3*m).is_integer: c = M[c] d = M[d] n = M[n] pf = (d * z**n)**m / (d**m * z**(m*n)) newarg = c * d**m * z**(m*n) return S.Half * ((pf + S.One)*airyai(newarg) - (pf - S.One)/sqrt(3)*airybi(newarg))
def test_match_deriv_bug1(): n = Function("n") l = Function("l") x = Symbol("x") p = Wild("p") e = (diff(l(x), x) / x - diff(diff(n(x), x), x) / 2 - diff(n(x), x)**2 / 4 + diff(n(x), x) * diff(l(x), x) / 4) e = e.subs(n(x), -l(x)).doit() t = x * exp(-l(x)) t2 = t.diff(x, x) / t assert e.match((p * t2).expand()) == {p: Rational(-1, 2)}
def test_match_deriv_bug1(): n = Function('n') l = Function('l') x = Symbol('x') p = Wild('p') e = diff(l(x), x)/x - diff(diff(n(x), x), x)/2 - \ diff(n(x), x)**2/4 + diff(n(x), x)*diff(l(x), x)/4 e = e.subs(n(x), -l(x)).doit() t = x * exp(-l(x)) t2 = t.diff(x, x) / t assert e.match((p * t2).expand()) == {p: Rational(-1, 2)}
def definition(self): e, S = self.args from sympy.concrete.expr_with_limits import Exists condition_set = S.condition_set() if condition_set: condition = condition_set.condition if condition_set.variable != e: condition = condition._subs(condition_set.variable, e) return And(condition, self.func(e, condition_set.base_set), equivalent=self) image_set = S.image_set() if image_set is not None: expr, variables, base_set = image_set from sympy import Wild variables_ = Wild(variables.name, **variables.dtype.dict) assert variables_.shape == variables.shape e = e.subs_limits_with_epitome(expr) dic = e.match(expr.subs(variables, variables_)) if dic: variables_ = dic[variables_] if variables.dtype != variables_.dtype: assert len(variables.shape) == 1 variables_ = variables_[:variables.shape[-1]] return Contains(variables_, base_set, equivalent=self) if e._has(variables): _variables = base_set.element_symbol(e.free_symbols) assert _variables.dtype == variables.dtype expr = expr._subs(variables, _variables) variables = _variables assert not e._has(variables) return Exists(Equality(e, expr, evaluate=False), (variables, base_set), equivalent=self) if S.is_UNION: for v in S.variables: if self.lhs._has(v): _v = v.generate_free_symbol(self.free_symbols, **v.dtype.dict) S = S.limits_subs(v, _v) contains = Contains(self.lhs, S.function).simplify() contains.equivalent = None return Exists(contains, *S.limits, equivalent=self).simplify() return self
def replace_powers_with_gray_functions(expr, repl, up_to_exponent=4): """repls is a dictionary of the form: {exponent_of_the_power: sympy.Function("GRAY_FUNCTION")}. GRAY_FUNCTIONS have to be defined in GRay! The definition can be added to the template of the output file. """ if (not isinstance(expr, Basic)): raise TypeError( "replace_powers_with_gray_functions can only handle sympy expressions!" ) # Instead of having pow(x,3), write x*x*x # create_expand_pow_optimization(N) performs this substitution # up to the power N expand_opt = create_expand_pow_optimization(up_to_exponent) expr = expand_opt(expr) # The previous substitution does not work when there are multiple # symbols involved, for example (a+b)**2 # Having performed cse, these expressions should not be too bad a, b = Wild('a'), Wild('b') for e in repl.keys(): expr = expr.replace((a + b)**e, lambda a, b: repl[e](a + b)) expr = expr.replace((a + b)**-e, lambda a, b: 1 / repl[e](a + b)) # For the square roots we also match single symbols # Square roots are identified by non-integer exponents sqrt_elems = [e for e in repl.keys() if type(e) is float] for e in sqrt_elems: expr = expr.replace(a**e, lambda a: repl[e](a)) expr = expr.replace(a**-e, lambda a: 1 / repl[e](a)) return expr
def __inv_laplace(self, tf_terms): ''' custom inverse laplace ''' _K = Wild("_K") _p = Wild("_p") _m = Wild("_m") t = Symbol('t', real=True) s = Symbol('s', real=True) # Why does 's' symbol disappear y = 0 basis_expr = [] for e in tf_terms: fixproblem = False mdict = e.match(_K / (s + _p)**_m) for v in mdict.values(): # need this because of sympy.match bug if list(v.find(s)) != []: fixproblem = True if fixproblem: mdict = e.match(_K / s) mdict[_p] = 0 mdict[_m] = 1 term = mdict[_K] * t**(mdict[_m] - 1) * exp(-mdict[_p] * t) basis_expr.append(self.__convert_to_basis_expr(mdict)) y += term return y, basis_expr
def test_solve_linear(): x, y = symbols('x y') w = Wild('w') assert solve_linear(x, x) == (0, 1) assert solve_linear(x, y - 2*x) in [(x, y/3), (y, 3*x)] assert solve_linear(x, y - 2*x, exclude=[x]) ==(y, 3*x) assert solve_linear(3*x - y, 0) in [(x, y/3), (y, 3*x)] assert solve_linear(3*x - y, 0, [x]) == (x, y/3) assert solve_linear(3*x - y, 0, [y]) == (y, 3*x) assert solve_linear(x**2/y, 1) == (y, x**2) assert solve_linear(w, x) in [(w, x), (x, w)] assert solve_linear(cos(x)**2 + sin(x)**2 + 2 + y) == \ (y, -2 - cos(x)**2 - sin(x)**2) assert solve_linear(cos(x)**2 + sin(x)**2 + 2 + y, x=[x]) == (0, 1)
def _check_varsh_sum_872_4(e): a = Wild('a') alpha = Wild('alpha') b = Wild('b') beta = Wild('beta') c = Wild('c') cp = Wild('cp') gamma = Wild('gamma') gammap = Wild('gammap') match1 = e.match(Sum(CG(a,alpha,b,beta,c,gamma)*CG(a,alpha,b,beta,cp,gammap),(alpha,-a,a),(beta,-b,b))) if match1 is not None and len(match1) == 8: return (KroneckerDelta(c,cp)*KroneckerDelta(gamma,gammap)).subs(match1) match2 = e.match(Sum(CG(a,alpha,b,beta,c,gamma)**2,(alpha,-a,a),(beta,-b,b))) if match2 is not None and len(match2) == 6: return 1 return e
def test_gate(): """Test a basic gate.""" h = HadamardGate(1) assert h.min_qubits == 2 assert h.nqubits == 1 i0 = Wild('i0') i1 = Wild('i1') h0_w1 = HadamardGate(i0) h0_w2 = HadamardGate(i0) h1_w1 = HadamardGate(i1) assert h0_w1 == h0_w2 assert h0_w1 != h1_w1 assert h1_w1 != h0_w2 cnot_10_w1 = CNOT(i1, i0) cnot_10_w2 = CNOT(i1, i0) cnot_01_w1 = CNOT(i0, i1) assert cnot_10_w1 == cnot_10_w2 assert cnot_10_w1 != cnot_01_w1 assert cnot_10_w2 != cnot_01_w1
def test_count(): expr = (x + y + 2 + sin(3 * x)) assert expr.count(lambda u: u.is_Integer) == 2 assert expr.count(lambda u: u.is_Symbol) == 3 assert expr.count(Integer) == 2 assert expr.count(Symbol) == 3 a = Wild('a') assert expr.count(sin) == 1 assert expr.count(sin(a)) == 1 assert expr.count(lambda u: type(u) is sin) == 1
def get_poly_conversion(shell_type): # conversion from normalised Cartesian to normalized pure assert shell_type < -1 alpha = Symbol("alpha") x = Symbol("x") y = Symbol("y") z = Symbol("z") xyz = (x,y,z) px = Wild("px") py = Wild("py") pz = Wild("pz") c = Wild("c") num_dof_in = get_shell_dof(-shell_type) num_dof_out = get_shell_dof(shell_type) lcs = numpy.zeros((num_dof_in, num_dof_out), dtype=object) for i_out, (poly, pure_wfn_norm) in enumerate(get_polys(shell_type, alpha, xyz)): poly = poly.expand() if isinstance(poly, C.Add): terms = poly.args else: terms = [poly] coeffs = {} for term in terms: d = term.evalf(20).match(c*x**px*y**py*z**pz) key = (int(d[px]), int(d[py]), int(d[pz])) coeffs[key] = d[c] for i_in, key in enumerate(iter_cartesian_powers(abs(shell_type))): cart_wfn_norm = get_cartesian_wfn_norm(alpha, key[0], key[1], key[2]) norm_ratio = mypowsimp((cart_wfn_norm/pure_wfn_norm).evalf(20)) lc = float(coeffs.get(key, 0)*norm_ratio) if abs(lc-int(lc)) < 1e-12: lc = int(lc) lcs[i_in,i_out] = lc return lcs
def test_issue_3883(): from sympy.abc import gamma, mu, x f = (-gamma * (x - mu)**2 - log(gamma) + log(2 * pi)) / 2 a, b, c = symbols("a b c", cls=Wild, exclude=(gamma, )) assert f.match(a * log(gamma) + b * gamma + c) == { a: Rational(-1, 2), b: -((x - mu)**2) / 2, c: log(2 * pi) / 2, } assert f.expand().collect(gamma).match(a * log(gamma) + b * gamma + c) == { a: Rational(-1, 2), b: (-((x - mu)**2) / 2).expand(), c: (log(2 * pi) / 2).expand(), } g1 = Wild("g1", exclude=[gamma]) g2 = Wild("g2", exclude=[gamma]) g3 = Wild("g3", exclude=[gamma]) assert f.expand().match(g1 * log(gamma) + g2 * gamma + g3) == { g3: log(2) / 2 + log(pi) / 2, g1: Rational(-1, 2), g2: -(mu**2) / 2 + mu * x - x**2 / 2, }
def _eval_expand_func(self, **hints): arg = self.args[0] symbs = arg.atoms(Symbol) if len(symbs) == 1: z = symbs.pop() c = Wild("c", exclude=[z]) d = Wild("d", exclude=[z]) m = Wild("m", exclude=[z]) n = Wild("n", exclude=[z]) M = arg.match(c*(d*z**n)**m) if M is not None: m = M[m] # The transformation is in principle # given by 03.08.16.0001.01 but note # that there is an error in this formule. # http://functions.wolfram.com/Bessel-TypeFunctions/AiryBiPrime/16/01/01/0001/ if (3*m).is_integer: c = M[c] d = M[d] n = M[n] pf = (d**m * z**(n*m)) / (d * z**n)**m newarg = c * d**m * z**(n*m) return S.Half * (sqrt(3)*(pf - S.One)*airyaiprime(newarg) + (pf + S.One)*airybiprime(newarg))
def test_match_wild_wild(): p = Wild('p') q = Wild('q') r = Wild('r') assert p.match(q + r) in [ {q: p, r: 0}, {q: 0, r: p} ] assert p.match(q*r) in [ {q: p, r: 1}, {q: 1, r: p} ] p = Wild('p') q = Wild('q', exclude=[p]) r = Wild('r') assert p.match(q + r) == {q: 0, r: p} assert p.match(q*r) == {q: 1, r: p} p = Wild('p') q = Wild('q', exclude=[p]) r = Wild('r', exclude=[p]) assert p.match(q + r) is None assert p.match(q*r) is None
def test_solve_linear(): w = Wild('w') assert solve_linear(x, x) == (0, 1) assert solve_linear(x, y - 2*x) in [(x, y/3), (y, 3*x)] assert solve_linear(x, y - 2*x, exclude=[x]) ==(y, 3*x) assert solve_linear(3*x - y, 0) in [(x, y/3), (y, 3*x)] assert solve_linear(3*x - y, 0, [x]) == (x, y/3) assert solve_linear(3*x - y, 0, [y]) == (y, 3*x) assert solve_linear(x**2/y, 1) == (y, x**2) assert solve_linear(w, x) in [(w, x), (x, w)] assert solve_linear(cos(x)**2 + sin(x)**2 + 2 + y) == \ (y, -2 - cos(x)**2 - sin(x)**2) assert solve_linear(cos(x)**2 + sin(x)**2 + 2 + y, symbols=[x]) == (0, 1) assert solve_linear(Eq(x, 3)) == (x, 3) assert solve_linear(1/(1/x - 2)) == (0, 0) raises(ValueError, lambda: solve_linear(Eq(x, 3), 3))
def simplify_int_limits(self, function): for i, domain in self.limits_dict.items(): if not i.is_integer or i.shape or isinstance(domain, Boolean): continue i_expr = [] patterns = [] non_i_expr = set() from sympy import Wild _i = Wild('_i', **i.type.dict) for eq in function.args: if eq._has(i): i_expr.append(eq) patterns.append(eq._subs(i, _i)) else: non_i_expr.add(eq) matched_dic = {} for eq in non_i_expr: for pattern in patterns: res = eq.match(pattern) if not res: continue t, *_ = res.values() if t in matched_dic: matched_dic[t].add(eq) else: matched_dic[t] = {eq} break new_set = set() for t, eqs in matched_dic.items(): if len(eqs) != len(non_i_expr): continue non_i_expr -= eqs new_set.add(t) if not new_set: continue eqs = i_expr + [*non_i_expr] limits = self.limits_update(i, domain | new_set) function = function.func(*eqs) return function, limits
def exprMag(expr): """ Estimate the magnitude of an expression """ # Replace all sin, cos with 1 any = Wild('a') # Wildcard expr = expr.replace(sin(any), 1.0) expr = expr.replace(cos(any), 1.0) # Pick maximum values of x,y,z expr = expr.subs(x, 1.0) expr = expr.subs(y, 2. * pi) expr = expr.subs(z, 2. * pi) return expr.evalf()
def test_Wild_properties(): # these tests only include Atoms x = Symbol("x") y = Symbol("y") p = Symbol("p", positive=True) k = Symbol("k", integer=True) n = Symbol("n", integer=True, positive=True) given_patterns = [ x, y, p, k, -k, n, -n, sympify(-3), sympify(3), pi, Rational(3, 2), I, ] integerp = lambda k: k.is_integer positivep = lambda k: k.is_positive symbolp = lambda k: k.is_Symbol realp = lambda k: k.is_extended_real S = Wild("S", properties=[symbolp]) R = Wild("R", properties=[realp]) Y = Wild("Y", exclude=[x, p, k, n]) P = Wild("P", properties=[positivep]) K = Wild("K", properties=[integerp]) N = Wild("N", properties=[positivep, integerp]) given_wildcards = [S, R, Y, P, K, N] goodmatch = { S: (x, y, p, k, n), R: (p, k, -k, n, -n, -3, 3, pi, Rational(3, 2)), Y: (y, -3, 3, pi, Rational(3, 2), I), P: (p, n, 3, pi, Rational(3, 2)), K: (k, -k, n, -n, -3, 3), N: (n, 3), } for A in given_wildcards: for pat in given_patterns: d = pat.match(A) if pat in goodmatch[A]: assert d[A] in goodmatch[A] else: assert d is None
def discriminant(polynome): u"Calcule le discriminant d'un polynôme du second degré." a = Wild('a') b = Wild('b') c = Wild('c') x = Wild('x') dico = polynome.match(a*x**2 + b*x + c) if dico is None: raise NotImplementedError a, b, c, x = dico[a], dico[b], dico[c], dico[x] if not x.is_Symbol or a.has(x) or b.has(x) or c.has(x): raise NotImplementedError return b**2 - 4*a*c
def definition(self): e, S = self.args from sympy.concrete.expr_with_limits import ForAll image_set = S.image_set() if image_set is not None: expr, variables, base_set = image_set from sympy import Wild variables_ = Wild(variables.name, **variables.dtype.dict) e = e.subs_limits_with_epitome(expr) dic = e.match(expr.subs(variables, variables_)) if dic: variables_ = dic[variables_] if variables.dtype != variables_.dtype: assert len(variables.shape) == 1 variables_ = variables_[:variables.shape[-1]] return self.func(variables_, base_set, equivalent=self) if e.has(variables): _variables = base_set.element_symbol(e.free_symbols) assert _variables.dtype == variables.dtype expr = expr._subs(variables, _variables) variables = _variables assert not e.has(variables) return ForAll(Unequality(e, expr, evaluate=False), (variables, base_set), equivalent=self) condition_set = S.condition_set() if condition_set: return Or( ~condition_set.condition._subs(condition_set.variable, e), ~self.func(e, condition_set.base_set), equivalent=self) if S.is_UNION: contains = self.func(self.lhs, S.function).simplify() contains.equivalent = None return ForAll(contains, *S.limits, equivalent=self).simplify() return self
def test_replace(): f = log(sin(x)) + tan(sin(x**2)) assert f.replace(sin, cos) == log(cos(x)) + tan(cos(x**2)) assert f.replace(sin, lambda a: sin(2*a)) == log(sin(2*x)) + tan(sin(2*x**2)) a = Wild('a') assert f.replace(sin(a), cos(a)) == log(cos(x)) + tan(cos(x**2)) assert f.replace(sin(a), lambda a: sin(2*a)) == log(sin(2*x)) + tan(sin(2*x**2)) g = 2*sin(x**3) assert g.replace(lambda expr: expr.is_Number, lambda expr: expr**2) == 4*sin(x**9) assert cos(x).replace(cos, sin, map=True) == (sin(x), {cos(x): sin(x)}) assert sin(x).replace(cos, sin) == sin(x) assert (y*sin(x)).replace(sin, lambda expr: sin(expr)/y) == sin(x)
def canonique(polynome): u"Met un polynôme du second degré sous forme canonique." a = Wild('a') b = Wild('b') c = Wild('c') x = Wild('x') dico = polynome.match(a*x**2 + b*x + c) if dico is None: return polynome a, b, c, x = dico[a], dico[b], dico[c], dico[x] if not x.is_Symbol or a.has(x) or b.has(x) or c.has(x): return polynome alpha = -b/(2*a) beta = (4*a*c - b**2)/(4*a) return a*(x - alpha)**2 + beta