def simplify(self): """ Simplify the expression, returns a new instance of Expression For more information about simplification: https://docs.sympy.org/latest/tutorial/simplification.html """ logger.log("EXPRESSION", (f"{self} - simplify")) return Expression(str(simp(self.expression)))
def randomProblem(self, significant=2): given = {} for key in self.given: while True: given[key] = simp(int( random() * (10**significant))) / (10**(significant - 1)) if given[key] > 0: break return Problem(self.concept, given, self.wanted, significant=significant)
def __init__(self, name, **params): self.name = name self.variables = {} self.units = {} self.givenSentences = {} self.wantedSentences = {} self.initSentence = params["init"] for i, p in enumerate(params): if p in ["init", "laws"]: continue self.variables[p] = simp("x_" + str(i)) self.units[p] = params[p][2] self.givenSentences[p] = params[p][0] self.wantedSentences[p] = params[p][1] self.laws = [] for law in params["laws"]: self.add_law(law)
def approximants(l, X=Symbol('x'), simplify=False): """ Return a generator for consecutive Pade approximants for a series. It can also be used for computing the rational generating function of a series when possible, since the last approximant returned by the generator will be the generating function (if any). The input list can contain more complex expressions than integer or rational numbers; symbols may also be involved in the computation. An example below show how to compute the generating function of the whole Pascal triangle. The generator can be asked to apply the sympy.simplify function on each generated term, which will make the computation slower; however it may be useful when symbols are involved in the expressions. Examples ======== >>> from sympy.series import approximants >>> from sympy import lucas, fibonacci, symbols, binomial >>> g = [lucas(k) for k in range(16)] >>> [e for e in approximants(g)] [2, -4/(x - 2), (5*x - 2)/(3*x - 1), (x - 2)/(x**2 + x - 1)] >>> h = [fibonacci(k) for k in range(16)] >>> [e for e in approximants(h)] [x, -x/(x - 1), (x**2 - x)/(2*x - 1), -x/(x**2 + x - 1)] >>> x, t = symbols("x,t") >>> p=[sum(binomial(k,i)*x**i for i in range(k+1)) for k in range(16)] >>> y = approximants(p, t) >>> for k in range(3): print(next(y)) 1 (x + 1)/((-x - 1)*(t*(x + 1) + (x + 1)/(-x - 1))) nan >>> y = approximants(p, t, simplify=True) >>> for k in range(3): print(next(y)) 1 -1/(t*(x + 1) - 1) nan See Also ======== See function sympy.concrete.guess.guess_generating_function_rational and function mpmath.pade """ p1, q1 = [Integer(1)], [Integer(0)] p2, q2 = [Integer(0)], [Integer(1)] while len(l): b = 0 while l[b] == 0: b += 1 if b == len(l): return m = [Integer(1) / l[b]] for k in range(b + 1, len(l)): s = 0 for j in range(b, k): s -= l[j + 1] * m[b - j - 1] m.append(s / l[b]) l = m a, l[0] = l[0], 0 p = [0] * max(len(p2), b + len(p1)) q = [0] * max(len(q2), b + len(q1)) for k in range(len(p2)): p[k] = a * p2[k] for k in range(b, b + len(p1)): p[k] += p1[k - b] for k in range(len(q2)): q[k] = a * q2[k] for k in range(b, b + len(q1)): q[k] += q1[k - b] while p[-1] == 0: p.pop() while q[-1] == 0: q.pop() p1, p2 = p2, p q1, q2 = q2, q # yield result from sympy import denom, lcm, simplify as simp c = 1 for x in p: c = lcm(c, denom(x)) for x in q: c = lcm(c, denom(x)) out = (sum(c * e * X**k for k, e in enumerate(p)) / sum(c * e * X**k for k, e in enumerate(q))) if simplify: yield (simp(out)) else: yield out return
def approximants(l, X=Symbol('x'), simplify=False): """ Return a generator for consecutive Pade approximants for a series. It can also be used for computing the rational generating function of a series when possible, since the last approximant returned by the generator will be the generating function (if any). The input list can contain more complex expressions than integer or rational numbers; symbols may also be involved in the computation. An example below show how to compute the generating function of the whole Pascal triangle. The generator can be asked to apply the sympy.simplify function on each generated term, which will make the computation slower; however it may be useful when symbols are involved in the expressions. Examples ======== >>> from sympy.series import approximants >>> from sympy import lucas, fibonacci, symbols, binomial >>> g = [lucas(k) for k in range(16)] >>> [e for e in approximants(g)] [2, -4/(x - 2), (5*x - 2)/(3*x - 1), (x - 2)/(x**2 + x - 1)] >>> h = [fibonacci(k) for k in range(16)] >>> [e for e in approximants(h)] [x, -x/(x - 1), (x**2 - x)/(2*x - 1), -x/(x**2 + x - 1)] >>> x, t = symbols("x,t") >>> p=[sum(binomial(k,i)*x**i for i in range(k+1)) for k in range(16)] >>> y = approximants(p, t) >>> for k in range(3): print(next(y)) 1 (x + 1)/((-x - 1)*(t*(x + 1) + (x + 1)/(-x - 1))) nan >>> y = approximants(p, t, simplify=True) >>> for k in range(3): print(next(y)) 1 -1/(t*(x + 1) - 1) nan See also ======== See function sympy.concrete.guess.guess_generating_function_rational and function mpmath.pade """ p1, q1 = [Integer(1)], [Integer(0)] p2, q2 = [Integer(0)], [Integer(1)] while len(l): b = 0 while l[b]==0: b += 1 if b == len(l): return m = [Integer(1)/l[b]] for k in range(b+1, len(l)): s = 0 for j in range(b, k): s -= l[j+1] * m[b-j-1] m.append(s/l[b]) l = m a, l[0] = l[0], 0 p = [0] * max(len(p2), b+len(p1)) q = [0] * max(len(q2), b+len(q1)) for k in range(len(p2)): p[k] = a*p2[k] for k in range(b, b+len(p1)): p[k] += p1[k-b] for k in range(len(q2)): q[k] = a*q2[k] for k in range(b, b+len(q1)): q[k] += q1[k-b] while p[-1]==0: p.pop() while q[-1]==0: q.pop() p1, p2 = p2, p q1, q2 = q2, q # yield result from sympy import denom, lcm, simplify as simp c = 1 for x in p: c = lcm(c, denom(x)) for x in q: c = lcm(c, denom(x)) out = ( sum(c*e*X**k for k, e in enumerate(p)) / sum(c*e*X**k for k, e in enumerate(q)) ) if simplify: yield(simp(out)) else: yield out return
def to_expr(self, formula): return simp(formula, locals=self.variables)