def ratint_ratpart(f, g, x): """Horowitz-Ostrogradsky algorithm. Given a field K and polynomials f and g in K[x], such that f and g are coprime and deg(f) < deg(g), returns fractions A and B in K(x), such that f/g = A' + B and B has square-free denominator. """ f = Poly(f, x) g = Poly(g, x) u, v, _ = g.cofactors(g.diff()) n = u.degree() m = v.degree() A_coeffs = [ Dummy('a' + str(n-i)) for i in xrange(0, n) ] B_coeffs = [ Dummy('b' + str(m-i)) for i in xrange(0, m) ] C_coeffs = A_coeffs + B_coeffs A = Poly(A_coeffs, x, domain=ZZ[C_coeffs]) B = Poly(B_coeffs, x, domain=ZZ[C_coeffs]) H = f - A.diff()*v + A*(u.diff()*v).quo(u) - B*u result = solve(H.coeffs(), C_coeffs) A = A.as_expr().subs(result) B = B.as_expr().subs(result) rat_part = cancel(A/u.as_expr(), x) log_part = cancel(B/v.as_expr(), x) return rat_part, log_part
def test_atan2_expansion(): assert cancel(atan2(x + 1, x ** 2).diff(x) - atan((x + 1) / x ** 2).diff(x)) == 0 assert cancel(atan(x / y).series(x, 0, 5) - atan2(x, y).series(x, 0, 5) + atan2(0, y) - atan(0)) == O(x ** 5) assert cancel(atan(x / y).series(y, 1, 4) - atan2(x, y).series(y, 1, 4) + atan2(x, 1) - atan(x)) == O(y ** 4) assert cancel( atan((x + y) / y).series(y, 1, 3) - atan2(x + y, y).series(y, 1, 3) + atan2(1 + x, 1) - atan(1 + x) ) == O(y ** 3) assert Matrix([atan2(x, y)]).jacobian([x, y]) == Matrix([[y / (x ** 2 + y ** 2), -x / (x ** 2 + y ** 2)]])
def test_atan2_expansion(): assert cancel(atan2(x ** 2, x + 1).diff(x) - atan(x ** 2 / (x + 1)).diff(x)) == 0 assert cancel(atan(y / x).series(y, 0, 5) - atan2(y, x).series(y, 0, 5) + atan2(0, x) - atan(0)) == O(y ** 5) assert cancel(atan(y / x).series(x, 1, 4) - atan2(y, x).series(x, 1, 4) + atan2(y, 1) - atan(y)) == O(x ** 4) assert cancel( atan((y + x) / x).series(x, 1, 3) - atan2(y + x, x).series(x, 1, 3) + atan2(1 + y, 1) - atan(1 + y) ) == O(x ** 3) assert Matrix([atan2(y, x)]).jacobian([y, x]) == Matrix([[x / (y ** 2 + x ** 2), -y / (y ** 2 + x ** 2)]])
def ratint_ratpart(f, g, x): """ Horowitz-Ostrogradsky algorithm. Given a field K and polynomials f and g in K[x], such that f and g are coprime and deg(f) < deg(g), returns fractions A and B in K(x), such that f/g = A' + B and B has square-free denominator. Examples ======== >>> from sympy.integrals.rationaltools import ratint_ratpart >>> from sympy.abc import x, y >>> from sympy import Poly >>> ratint_ratpart(Poly(1, x, domain='ZZ'), ... Poly(x + 1, x, domain='ZZ'), x) (0, 1/(x + 1)) >>> ratint_ratpart(Poly(1, x, domain='EX'), ... Poly(x**2 + y**2, x, domain='EX'), x) (0, 1/(x**2 + y**2)) >>> ratint_ratpart(Poly(36, x, domain='ZZ'), ... Poly(x**5 - 2*x**4 - 2*x**3 + 4*x**2 + x - 2, x, domain='ZZ'), x) ((12*x + 6)/(x**2 - 1), 12/(x**2 - x - 2)) See Also ======== ratint, ratint_logpart """ from sympy import solve f = Poly(f, x) g = Poly(g, x) u, v, _ = g.cofactors(g.diff()) n = u.degree() m = v.degree() A_coeffs = [ Dummy('a' + str(n - i)) for i in range(0, n) ] B_coeffs = [ Dummy('b' + str(m - i)) for i in range(0, m) ] C_coeffs = A_coeffs + B_coeffs A = Poly(A_coeffs, x, domain=ZZ[C_coeffs]) B = Poly(B_coeffs, x, domain=ZZ[C_coeffs]) H = f - A.diff()*v + A*(u.diff()*v).quo(u) - B*u result = solve(H.coeffs(), C_coeffs) A = A.as_expr().subs(result) B = B.as_expr().subs(result) rat_part = cancel(A/u.as_expr(), x) log_part = cancel(B/v.as_expr(), x) return rat_part, log_part
def solve(self): """ Solves the instance that is: V - node voltage vector V = [Vi ; Vp] Vi - inner nodes voltage Vp - port nodes vector Vi = Ap*Vp + V0 Ap - linear function matrix (Attenuation matrix) V0 - inner nodes voltage vector for Vp = 0 By solving instance we provide update Ap matrix and V0 vector. G * V = I [G_i, G+p] * [Vi ; Vp] = I G_i*Vi + G_p*Vp = I Vi = -G_i^-1*G_p*Vp + G_i^-1*I Vi = Ap*Vp + V0 Thus we update G matrix (write the equations), and by doing linear algebra we calculate the results. """ for subname,subinstance in self.subinstances.iteritems(): subinstance.solve() N = len(self.nets) Ni = len(self.inner_nets) Np = len(self.port_nets) for i in range(N): self.net_name_index.update({self.nets[i]:i}) G_m = [] I_v = [] self.used_voltage_sources = [] for net in self.inner_nets: G_v = [0 for i in range(len(self.nets))] I = [0] if not self.update_eq_with_vs(net,G_v,I): for element in self.elements_on_net[net]: self.update_current_v(element,net,G_v,I) #G_m.append(G_v) G_m.append([sympy.cancel(tmp) for tmp in G_v]) I_v.append([sympy.cancel(tmp) for tmp in I]) #Make and slice the Matrix G_M = [G_i | G_p] G_m = sympy.Matrix(G_m) I_v = sympy.Matrix(I_v) G_i = G_m[:,:Ni] G_p = G_m[:,Ni:] # G_i*V_i + G_p*V_p = I_v # V_i = G_i^-1 I_v - G_i^-1 * G_p * V_p # V_i = Vo +Ap * vp try: G_i_inv = G_i.inv() except ValueError, e: raise scs_errors.ScsElementError("%s is ill conditioned, and has no unique solution." % self.name if self.name else "TOP INSTANCE")
def resonator_parallel_fzq(f, z, q=None): w = 2*pi*f l = cancel(z / w) c = cancel(1 / (w*z)) if q is not None: g = 1 / (q*z) else: g = 0 return resonator_parallel_lcg(l, c, g)
def resonator_series_fzq(f, z, q=None): w = 2*pi*f l = cancel(z / w) c = cancel(1 / (w*z)) if q is not None: r = z / q else: r = 0 return resonator_series_lcr(l, c, r)
def __init__(self, m, **kwargs): (a, b), (c, d) = m a = cancel(a) b = collect(b, ohm) c = collect(c, 1/ohm) d = cancel(d) super(Transmission, self).__init__([[a, b], [c, d]], **kwargs) if self.shape != (2, 2): raise ValueError("Transmission Matrix must be 2x2")
def test_issue_9398(): from sympy import Number, cancel assert cancel(1e-14) != 0 assert cancel(1e-14*I) != 0 assert simplify(1e-14) != 0 assert simplify(1e-14*I) != 0 assert (I*Number(1.)*Number(10)**Number(-14)).simplify() != 0 assert cancel(1e-20) != 0 assert cancel(1e-20*I) != 0 assert simplify(1e-20) != 0 assert simplify(1e-20*I) != 0 assert cancel(1e-100) != 0 assert cancel(1e-100*I) != 0 assert simplify(1e-100) != 0 assert simplify(1e-100*I) != 0 f = Float("1e-1000") assert cancel(f) != 0 assert cancel(f*I) != 0 assert simplify(f) != 0 assert simplify(f*I) != 0
def _eval_nseries(self, x, n, logx): # NOTE Please see the comment at the beginning of this file, labelled # IMPORTANT. from sympy import cancel if not logx: logx = log(x) if self.args[0] == x: return logx arg = self.args[0] k, l = Wild("k"), Wild("l") r = arg.match(k*x**l) if r is not None: #k = r.get(r, S.One) #l = r.get(l, S.Zero) k, l = r[k], r[l] if l != 0 and not l.has(x) and not k.has(x): r = log(k) + l*logx # XXX true regardless of assumptions? return r # TODO new and probably slow s = self.args[0].nseries(x, n=n, logx=logx) while s.is_Order: n += 1 s = self.args[0].nseries(x, n=n, logx=logx) a, b = s.leadterm(x) p = cancel(s/(a*x**b) - 1) g = None l = [] for i in xrange(n + 2): g = log.taylor_term(i, p, g) g = g.nseries(x, n=n, logx=logx) l.append(g) return log(a) + b*logx + Add(*l) + C.Order(p**n, x)
def canonical(self): """Convert rational function to canonical form with unity highest power of denominator. See also general, partfrac, mixedfrac, and ZPK""" try: N, D, delay, undef = self.as_ratfun_delay_undef() except ValueError: # TODO: copy? return self.expr var = self.var Dpoly = sym.Poly(D, var) Npoly = sym.Poly(N, var) K = sym.cancel(Npoly.LC() / Dpoly.LC()) if delay != 0: K *= sym.exp(self.var * delay) # Divide by leading coefficient Nm = Npoly.monic() Dm = Dpoly.monic() expr = K * (Nm / Dm) return expr * undef
def test_SVCVS_laplace_d3_n1(): """Test VCCS with a laplace defined transfer function with second order numerator and third order denominator """ pycircuit.circuit.circuit.default_toolkit = symbolic cir = SubCircuit() n1,n2 = cir.add_nodes('1','2') b0,a0,a1,a2,a3,Gdc = [sympy.Symbol(symname, real=True) for symname in 'b0,a0,a1,a2,a3,Gdc' .split(',')] s = sympy.Symbol('s', complex=True) cir['VS'] = VS( n1, gnd, vac=1) cir['VCVS'] = SVCVS( n1, gnd, n2, gnd, denominator = [a0, a1, a2, a3], numerator = [b0, 0, 0]) res = AC(cir, toolkit=symbolic).solve(s, complexfreq=True) assert_equal(sympy.cancel(sympy.expand(res.v(n2,gnd))), sympy.expand((b0*s*s)/(a0*s*s*s+a1*s*s+a2*s+a3)))
def timeconst(self): """Convert rational function to time constant form with unity lowest power of denominator. See also canonical, general, partfrac, mixedfrac, and ZPK""" try: N, D, delay, undef = self.as_ratfun_delay_undef() except ValueError: # TODO: copy? return self.expr var = self.var Npoly = sym.Poly(N, var) Dpoly = sym.Poly(D, var) K = sym.cancel(Npoly.EC() / Dpoly.EC()) if delay != 0: K *= sym.exp(self.var * delay) # Divide by leading coefficient Nm = (Npoly / Npoly.EC()).simplify() Dm = (Dpoly / Dpoly.EC()).simplify() expr = K * (Nm / Dm) return expr * undef
def test_loggamma(): s1 = loggamma(1/(x+sin(x))+cos(x)).nseries(x,n=4) s2 = (-log(2*x)-1)/(2*x) - log(x/pi)/2 + (4-log(2*x))*x/24 + O(x**2) assert cancel(s1 - s2).removeO() == 0 s1 = loggamma(1/x).series(x) s2 = (1/x-S(1)/2)*log(1/x) - 1/x + log(2*pi)/2 + \ x/12 - x**3/360 + x**5/1260 + O(x**7) assert cancel(s1 - s2).removeO() == 0 def tN(N, M): assert loggamma(1/x)._eval_nseries(x,n=N,logx=None).getn() == M tN(0, 0) tN(1, 1) tN(2, 3) tN(3, 3) tN(4, 5) tN(5, 5)
def ricci_scalar(ricci_t, metric): scalar = 0 inverse = inverse_metric(metric) for alpha in range(4): for beta in range(4): scalar += inverse[alpha][beta] * ricci_t[alpha][beta] scalar = sp.cancel(scalar) return scalar
def cancel(expr): if expr.has_form('Plus', None): return Expression('Plus', *[cancel(leaf) for leaf in expr.leaves]) else: result = expr.to_sympy() #result = sympy.powsimp(result, deep=True) result = sympy.cancel(result) result = sympy_factor(result) # cancel factors out rationals, so we factor them again return from_sympy(result)
def ricci_tensor(reimann): ricci = tensor(2) for alpha in range(4): for beta in range(4): total = 0 for gamma in range(4): total += reimann[gamma][alpha][gamma][beta] ricci[alpha][beta] = sp.cancel(total) return ricci
def apply(self, expr, evaluation): 'Simplify[expr_]' expr_sympy = expr.to_sympy() result = expr_sympy result = sympy.simplify(result) result = sympy.trigsimp(result) result = sympy.together(result) result = sympy.cancel(result) result = from_sympy(result) return result
def PoliLagr(datax, c): n = len(datax) x = sym.symbols('x') p = 0 for j in range(n): t = 1 for k in range(n): if j != k: t *= (x - datax[k]) p += c[j]*t return(sym.cancel(p)).evalf(n = 4)
def canonical(self, factor_const=True): """Convert rational function to canonical form; this is like general form but with a unity highest power of denominator. For example, (5 * s**2 + 5 * s + 5) / (s**2 + 4) If factor_const is True, factor constants from numerator, for example, 5 * (s**2 + s + 1) / (s**2 + 4) See also general, partfrac, standard, timeconst, and ZPK """ try: N, D, delay, undef = self.as_ratfun_delay_undef() except ValueError: # TODO: copy? return self.expr var = self.var Dpoly = sym.Poly(D, var) Npoly = sym.Poly(N, var) if factor_const: K = sym.cancel(Npoly.LC() / Dpoly.LC()) if delay != 0: K *= sym.exp(self.var * delay) # Divide by leading coefficient N = Npoly.monic().as_expr() D = Dpoly.monic().as_expr() if D == 1: expr = N else: expr = sym.Mul(N, 1 / D, evaluate=False) expr = sym.Mul(K, expr, undef, evaluate=False) else: C = Dpoly.LC() D = Dpoly.monic().as_expr() N = (Npoly.as_expr() / C).simplify() if D == 1: expr = N else: expr = sym.Mul(N, 1 / D, evaluate=False) if delay != 0: expr *= sym.exp(self.var * delay) expr *= undef return expr
def general(self): """Convert rational function to general form. See also canonical, partfrac, standard, timeconst, and ZPK""" N, D, delay, undef = self.as_ratfun_delay_undef() expr = sym.cancel(N / D, self.var) if delay != 0: expr *= sym.exp(self.var * delay) return expr * undef
def general(self): """Convert rational function to general form. See also canonical, partfrac, mixedfrac, and ZPK""" N, D, delay = self._as_ratfun_delay() expr = sym.cancel(N / D, self.var) if delay != 0: expr *= sym.exp(self.var * delay) return self.__class__(expr)
def gen(i_deg): l_xi1 = sympy.symbols('xi_1') # first tetrahedral coord l_xi2 = sympy.symbols('xi_2') # second tetrahedral coord l_xi3 = sympy.symbols('xi_3') # third tetrahedral coord l_eta1 = sympy.symbols('eta_1') # first collapsed coord l_eta2 = sympy.symbols('eta_2') # second collapsed coord l_eta3 = sympy.symbols('eta_3') # third collapsed coord # basis l_basis = [] # derive basis functions for l_de in range(0, i_deg + 1): for l_p1 in range(0, l_de + 1): # first principal function l_psiA = sympy.jacobi(l_p1, 0, 0, l_eta1) for l_p2 in range(0, l_de + 1): # second principal function l_psiB = (((1 - l_eta2) / 2)**l_p1 * sympy.jacobi(l_p2, 2 * l_p1 + 1, 0, l_eta2)) for l_p3 in range(0, l_de + 1): if ( l_p1 + l_p2 + l_p3 == l_de ): # build hierarchical basis following pascals triangle # third principal function l_psiC = ( (1 - l_eta3) / 2)**(l_p1 + l_p2) * sympy.jacobi( l_p3, 2 * l_p1 + 2 * l_p2 + 2, 0, l_eta3) l_basis = l_basis + [l_psiA * l_psiB * l_psiC] # insert tetrahedral coordinates l_basis[-1] = l_basis[-1].subs( l_eta1, 2 * (1 + l_xi1) / (-l_xi2 - l_xi3) - 1) l_basis[-1] = l_basis[-1].subs( l_eta2, 2 * (1 + l_xi2) / (1 - l_xi3) - 1) l_basis[-1] = l_basis[-1].subs(l_eta3, l_xi3) # use tets with xi1, xi2, xi3 in [0,1] l_basis[-1] = l_basis[-1].subs(l_xi1, 2 * l_xi1 - 1) l_basis[-1] = l_basis[-1].subs(l_xi2, 2 * l_xi2 - 1) l_basis[-1] = l_basis[-1].subs(l_xi3, 2 * l_xi3 - 1) # simplify basis l_basis[-1] = sympy.simplify(l_basis[-1]) # cancel denominators l_basis[-1] = sympy.cancel(l_basis[-1]) return [l_xi1, l_xi2, l_xi3], l_basis
def test_binomial_symbolic(): n = 10 # Because we're using for loops, can't do symbolic n p = symbols('p', positive=True) X = Binomial('X', n, p) assert simplify(E(X)) == n * p == simplify(moment(X, 1)) assert simplify(variance(X)) == n * p * (1 - p) == simplify(cmoment(X, 2)) assert cancel((skewness(X) - (1 - 2 * p) / sqrt(n * p * (1 - p)))) == 0 # Test ability to change success/failure winnings H, T = symbols('H T') Y = Binomial('Y', n, p, succ=H, fail=T) assert simplify(E(Y) - (n * (H * p + T * (1 - p)))) == 0
def test_binomial_symbolic(): n = 10 # Because we're using for loops, can't do symbolic n p = symbols('p', positive=True) X = Binomial('X', n, p) assert simplify(E(X)) == n*p == simplify(moment(X, 1)) assert simplify(variance(X)) == n*p*(1 - p) == simplify(cmoment(X, 2)) assert cancel((skewness(X) - (1-2*p)/sqrt(n*p*(1-p)))) == 0 # Test ability to change success/failure winnings H, T = symbols('H T') Y = Binomial('Y', n, p, succ=H, fail=T) assert simplify(E(Y) - (n*(H*p + T*(1 - p)))) == 0
def general(self): """Convert rational function to general form. See also canonical, partfrac, mixedfrac, and ZPK""" N, D, delay = self.as_ratfun_delay() expr = sym.cancel(N / D, self.var) if delay != 0: expr *= sym.exp(self.var * delay) return expr
def canonical(self, factor_const=True): """Convert rational function to canonical form; this is like general form but with a unity highest power of denominator. For example, (5 * s**2 + 5 * s + 5) / (s**2 + 4) If factor_const is True, factor constants from numerator, for example, 5 * (s**2 + s + 1) / (s**2 + 4) See also general, partfrac, standard, timeconst, and ZPK """ var = self.var Apoly = self.Apoly Bpoly = self.Bpoly delay = self.delay if factor_const: K = sym.cancel(Bpoly.LC() / Apoly.LC()) if delay != 0: K *= sym.exp(self.var * delay) # Divide by leading coefficient N = Bpoly.monic().as_expr() D = Apoly.monic().as_expr() if D == 1: expr = N else: expr = sym.Mul(N, 1 / D, evaluate=False) if K != 1: expr = sym.Mul(K, expr, evaluate=False) expr *= self.undef else: C = Apoly.LC() D = Apoly.monic().as_expr() N = (Bpoly.as_expr() / C).simplify() if D == 1: expr = N else: if N == 1: expr = 1 / D else: expr = sym.Mul(N, 1 / D, evaluate=False) if delay != 0: expr *= sym.exp(self.var * delay) expr *= self.undef return expr
def test_risch_integrate(): assert risch_integrate(t0 * exp(x), x) == t0 * exp(x) assert risch_integrate( sin(x), x, rewrite_complex=True) == -exp(I * x) / 2 - exp(-I * x) / 2 # From my GSoC writeup assert risch_integrate((1 + 2*x**2 + x**4 + 2*x**3*exp(2*x**2))/ (x**4*exp(x**2) + 2*x**2*exp(x**2) + exp(x**2)), x) == \ NonElementaryIntegral(exp(-x**2), x) + exp(x**2)/(1 + x**2) assert risch_integrate(0, x) == 0 # also tests prde_cancel() e1 = log(x / exp(x) + 1) ans1 = risch_integrate(e1, x) assert ans1 == (x * log(x * exp(-x) + 1) + NonElementaryIntegral( (x**2 - x) / (x + exp(x)), x)) assert cancel(diff(ans1, x) - e1) == 0 # also tests issue #10798 e2 = (log(-1 / y) / 2 - log(1 / y) / 2) / y - (log(1 - 1 / y) / 2 - log(1 + 1 / y) / 2) / y ans2 = risch_integrate(e2, y) assert ans2 == log(1/y)*log(1 - 1/y)/2 - log(1/y)*log(1 + 1/y)/2 + \ NonElementaryIntegral((I*pi*y**2 - 2*y*log(1/y) - I*pi)/(2*y**3 - 2*y), y) assert expand_log(cancel(diff(ans2, y) - e2), force=True) == 0 # These are tested here in addition to in test_DifferentialExtension above # (symlogs) to test that backsubs works correctly. The integrals should be # written in terms of the original logarithms in the integrands. # XXX: Unfortunately, making backsubs work on this one is a little # trickier, because x**x is converted to exp(x*log(x)), and so log(x**x) # is converted to x*log(x). (x**2*log(x)).subs(x*log(x), log(x**x)) is # smart enough, the issue is that these splits happen at different places # in the algorithm. Maybe a heuristic is in order assert risch_integrate(log(x**x), x) == x**2 * log(x) / 2 - x**2 / 4 assert risch_integrate(log(x**y), x) == x * log(x**y) - x * y assert risch_integrate(log(sqrt(x)), x) == x * log(sqrt(x)) - x / 2
def simplify(self, level=0): """ Simplify the .aform : param level: simplificatio level level == 0: basic simplification through sympy.cancel. It performs simple transformation that puts the expression into the standard form p/q, which is much faster than a generic .simplify level == 1: full simplification through sympy.simplify """ if level == 0: self.aform = sympy.cancel(self.__initial_aform) elif level == 1: self.aform = sympy.simplify(self.__initial_aform)
def cancel(expr): if expr.has_form('Plus', None): return Expression('Plus', *[cancel(leaf) for leaf in expr.leaves]) else: try: result = expr.to_sympy() #result = sympy.powsimp(result, deep=True) result = sympy.cancel(result) result = sympy_factor(result) # cancel factors out rationals, so we factor them again return from_sympy(result) except sympy.PolynomialError: # e.g. for non-commutative expressions return expr
def test_risch_integrate(): assert risch_integrate(t0*exp(x), x) == t0*exp(x) assert risch_integrate(sin(x), x, rewrite_complex=True) == -exp(I*x)/2 - exp(-I*x)/2 # From my GSoC writeup assert risch_integrate((1 + 2*x**2 + x**4 + 2*x**3*exp(2*x**2))/ (x**4*exp(x**2) + 2*x**2*exp(x**2) + exp(x**2)), x) == \ NonElementaryIntegral(exp(-x**2), x) + exp(x**2)/(1 + x**2) assert risch_integrate(0, x) == 0 # also tests prde_cancel() e1 = log(x/exp(x) + 1) ans1 = risch_integrate(e1, x) assert ans1 == (x*log(x*exp(-x) + 1) + NonElementaryIntegral((x**2 - x)/(x + exp(x)), x)) assert cancel(diff(ans1, x) - e1) == 0 # also tests issue #10798 e2 = (log(-1/y)/2 - log(1/y)/2)/y - (log(1 - 1/y)/2 - log(1 + 1/y)/2)/y ans2 = risch_integrate(e2, y) assert ans2 == log(1/y)*log(1 - 1/y)/2 - log(1/y)*log(1 + 1/y)/2 + \ NonElementaryIntegral((I*pi*y**2 - 2*y*log(1/y) - I*pi)/(2*y**3 - 2*y), y) assert expand_log(cancel(diff(ans2, y) - e2), force=True) == 0 # These are tested here in addition to in test_DifferentialExtension above # (symlogs) to test that backsubs works correctly. The integrals should be # written in terms of the original logarithms in the integrands. # XXX: Unfortunately, making backsubs work on this one is a little # trickier, because x**x is converted to exp(x*log(x)), and so log(x**x) # is converted to x*log(x). (x**2*log(x)).subs(x*log(x), log(x**x)) is # smart enough, the issue is that these splits happen at different places # in the algorithm. Maybe a heuristic is in order assert risch_integrate(log(x**x), x) == x**2*log(x)/2 - x**2/4 assert risch_integrate(log(x**y), x) == x*log(x**y) - x*y assert risch_integrate(log(sqrt(x)), x) == x*log(sqrt(x)) - x/2
def reimann_tensor(chris_sym, metric_key): reimann = tensor(4) for alpha in range(4): for beta in range(4): for gamma in range(4): for delta in range(4): total = 0 total += sp.diff(chris_sym[alpha][beta][delta], metric_key[gamma]) total -= sp.diff(chris_sym[alpha][beta][gamma], metric_key[delta]) for epsilon in range(4): total += chris_sym[alpha][gamma][epsilon]*chris_sym[epsilon][beta][delta] total -= chris_sym[alpha][delta][epsilon]*chris_sym[epsilon][beta][gamma] reimann[alpha][beta][gamma][delta] = sp.cancel(total) return reimann
def solveswc(ecu_list, res_list): """ Solves simplifying big linear systems. """ A, B = syst2matrix(ecu_list, res_list) Den = Matrix(A) den = simplify(factordet(Den)) Num, num = [], [] for i in range(A.cols): Num.append(Matrix(A)) Num[i][i] = B num.append(factordet(Num[i])) Den = Den.det_bareis() return {res_list[i]: cancel(num[i]/den)*Num[i].det_bareis()/Den for i in range(len(res_list))}
def solve_eq(pad: Expr) -> dict: # expand left term left = cancel(expand_func(pad).subs(sin(theta)**2, 1 - cos(theta)**2)) terms_lft = tuple(expend_cos(left, theta)) # expand right term b0, b1, b2, b3, b4 = symbols('b_0 b_1 b_2 b_3 b_4', real=True) right = cancel(b0 + b1 * legendre(1, cos(theta)) + b2 * legendre(2, cos(theta)) + b3 * legendre(3, cos(theta)) + b4 * legendre(4, cos(theta))) terms_rgt = tuple(expend_cos(right, theta)) # solve equations b4_cmpx = simplify(cancel(solve((terms_lft[4] - terms_rgt[4]), b4)[0])) b4_real = simplify(re(expand(b4_cmpx))) b3_cmpx = simplify(cancel(solve((terms_lft[3] - terms_rgt[3]), b3)[0])) b3_real = simplify(re(expand(b3_cmpx))) b3_amp, b3_shift = amp_and_shift(b3_real, phi) b2_cmpx = simplify( cancel(solve((terms_lft[2] - terms_rgt[2]).subs(b4, b4_cmpx), b2)[0])) b2_real = simplify(re(expand(b2_cmpx))) b1_cmpx = simplify( cancel(solve((terms_lft[1] - terms_rgt[1]).subs(b3, b3_cmpx), b1)[0])) b1_real = simplify(re(expand(b1_cmpx))) b1_amp, b1_shift = amp_and_shift(b1_real, phi) b0_cmpx = simplify( cancel( solve( (terms_lft[0] - terms_rgt[0]).subs(b4, b4_cmpx).subs(b2, b2_cmpx), b0)[0])) b0_real = simplify(re(expand(b0_cmpx))) b1m3_real = simplify(cancel(b1_real - b3_real * 2 / 3)) b1m3_amp, b1m3_shift = amp_and_shift(b1m3_real, phi) return { 'beta1': b1_real / b0_real, 'beta1_amp': b1_amp / b0_real, 'beta1_shift': b1_shift, 'beta2': b2_real / b0_real, 'beta3': b3_real / b0_real, 'beta3_amp': b3_amp / b0_real, 'beta3_shift': b3_shift, 'beta4': b4_real / b0_real, 'beta1m3': b1m3_real / b0_real, 'beta1m3_amp': b1m3_amp / b0_real, 'beta1m3_shift': b1m3_shift, }
def ZPK(self): """Convert to pole-zero-gain (PZK) form. See also canonical, general, mixedfrac, and partfrac""" N, D, delay = self.as_ratfun_delay() K = sym.cancel(N.LC() / D.LC()) if delay != 0: K *= sym.exp(self.var * delay) zeros = sym.roots(N) poles = sym.roots(D) return _zp2tf(zeros, poles, K, self.var)
def apply(self, expr, evaluation): 'Simplify[expr_]' expr_sympy = expr.to_sympy() result = expr_sympy try: result = sympy.simplify(result) except TypeError: # XXX What's going on here? pass result = sympy.trigsimp(result) result = sympy.together(result) result = sympy.cancel(result) result = from_sympy(result) return result
def cancel(expr): if expr.has_form('Plus', None): return Expression('Plus', *[cancel(leaf) for leaf in expr.leaves]) else: try: result = expr.to_sympy() #result = sympy.powsimp(result, deep=True) result = sympy.cancel(result) result = sympy_factor( result ) # cancel factors out rationals, so we factor them again return from_sympy(result) except sympy.PolynomialError: # e.g. for non-commutative expressions return expr
def ZPK(self): """Convert to pole-zero-gain (PZK) form. See also canonical, general, mixedfrac, and partfrac""" N, D, delay = self._as_ratfun_delay() K = sym.cancel(N.LC() / D.LC()) if delay != 0: K *= sym.exp(self.var * delay) zeros = sym.roots(N) poles = sym.roots(D) return self.__class__(_zp2tf(zeros, poles, K, self.var))
def apply(self, expr, evaluation): 'Simplify[expr_]' expr_sympy = expr.to_sympy() result = expr_sympy try: result = sympy.simplify(result) except TypeError: #XXX What's going on here? pass result = sympy.trigsimp(result) result = sympy.together(result) result = sympy.cancel(result) result = from_sympy(result) return result
def test_action_verbs(): assert nsimplify((1/(exp(3*pi*x/5)+1))) == (1/(exp(3*pi*x/5)+1)).nsimplify() assert ratsimp(1/x + 1/y) == (1/x + 1/y).ratsimp() assert trigsimp(log(x), deep=True) == (log(x)).trigsimp(deep = True) assert radsimp(1/(2+sqrt(2))) == (1/(2+sqrt(2))).radsimp() assert powsimp(x**y*x**z*y**z, combine='all') == (x**y*x**z*y**z).powsimp(combine='all') assert simplify(x**y*x**z*y**z) == (x**y*x**z*y**z).simplify() assert together(1/x + 1/y) == (1/x + 1/y).together() assert separate((x*(y*z)**3)**2) == ((x*(y*z)**3)**2).separate() assert collect(a*x**2 + b*x**2 + a*x - b*x + c, x) == (a*x**2 + b*x**2 + a*x - b*x + c).collect(x) assert apart(y/(y+2)/(y+1), y) == (y/(y+2)/(y+1)).apart(y) assert combsimp(y/(x+2)/(x+1)) == (y/(x+2)/(x+1)).combsimp() assert factor(x**2+5*x+6) == (x**2+5*x+6).factor() assert refine(sqrt(x**2)) == sqrt(x**2).refine() assert cancel((x**2+5*x+6)/(x+2)) == ((x**2+5*x+6)/(x+2)).cancel()
def __str__(self): '''Print a "nice" human - readable representation of the tensor''' self.getNonZero() # We will print only non-zero components unless all the components are zero ttl = "" if self.nonzero: print(70 * '=') print('The non-zero components of ' + str(self.symbol) + ' are:') for i in range(len(self.nonzero)): ttl = (str(self.nonzero[i][0]) + " : " + str(sp.cancel(self.nonzero[i][1]))) print(ttl) print(70 * '=') else: print('All the components of ' + str(self.symbol) + ' are 0!')
def ratint_ratpart(f, g, x): """Horowitz-Ostrogradsky algorithm. Given a field K and polynomials f and g in K[x], such that f and g are coprime and deg(f) < deg(g), returns fractions A and B in K(x), such that f/g = A' + B and B has square-free denominator. """ f = Poly(f, x) g = Poly(g, x) u, v, _ = g.cofactors(g.diff()) n = u.degree() m = v.degree() d = g.degree() A_coeffs = [Dummy('a' + str(n - i)) for i in xrange(0, n)] B_coeffs = [Dummy('b' + str(m - i)) for i in xrange(0, m)] C_coeffs = A_coeffs + B_coeffs A = Poly(A_coeffs, x, domain=ZZ[C_coeffs]) B = Poly(B_coeffs, x, domain=ZZ[C_coeffs]) H = f - A.diff() * v + A * (u.diff() * v).exquo(u) - B * u result = solve(H.coeffs(), C_coeffs) A = A.as_basic().subs(result) B = B.as_basic().subs(result) rat_part = cancel(A / u.as_basic(), x) log_part = cancel(B / v.as_basic(), x) return rat_part, log_part
def simplify_program(self): print(self) print("") expre = self.InfixExpression() print(expre) print("") expreSim = cancel(expre) print(expreSim) print("") expre = InfToPre(expre, expreSim) expre.transform() self.program = expre.prefix print(self) print("") self.validate_program()
def mixedfrac(self): """Convert rational function into mixed fraction form. See also canonical, general, partfrac and ZPK""" N, D, delay, undef = self.as_ratfun_delay_undef() var = self.var # Perform polynomial long division so expr = Q + M / D Q, M = sym.div(N, D, var) expr = Q + sym.cancel(M / D, var) if delay != 0: expr *= sym.exp(-self.var * delay) return expr * undef
def test_binomial_symbolic(): n = 2 # Because we're using for loops, can't do symbolic n p = symbols('p', positive=True) X = Binomial('X', n, p) t = Symbol('t') assert simplify(E(X)) == n*p == simplify(moment(X, 1)) assert simplify(variance(X)) == n*p*(1 - p) == simplify(cmoment(X, 2)) assert cancel((skewness(X) - (1 - 2*p)/sqrt(n*p*(1 - p)))) == 0 assert characteristic_function(X)(t) == p ** 2 * exp(2 * I * t) + 2 * p * (-p + 1) * exp(I * t) + (-p + 1) ** 2 assert moment_generating_function(X)(t) == p ** 2 * exp(2 * t) + 2 * p * (-p + 1) * exp(t) + (-p + 1) ** 2 # Test ability to change success/failure winnings H, T = symbols('H T') Y = Binomial('Y', n, p, succ=H, fail=T) assert simplify(E(Y) - (n*(H*p + T*(1 - p)))) == 0
def mixedfrac(self): """Convert rational function into mixed fraction form. See also canonical, general, partfrac and ZPK""" N, D, delay = self.as_ratfun_delay() var = self.var # Perform polynomial long division so expr = Q + M / D Q, M = sym.div(N, D, var) expr = Q + sym.cancel(M / D, var) if delay != 0: expr *= sym.exp(-self.var * delay) return expr
def standard(self): """Convert rational function into mixed fraction form. This is the sum of strictly proper rational function and a polynomial. See also canonical, general, partfrac, timeconst, and ZPK""" Q, M, A, delay, undef = self.as_QMA() expr = Q + sym.cancel(M / A, self.var) if delay != 0: expr *= sym.exp(-self.var * delay) return expr * undef
def test_binomial_symbolic(): n = 2 # Because we're using for loops, can't do symbolic n p = symbols('p', positive=True) X = Binomial('X', n, p) t = Symbol('t') assert simplify(E(X)) == n * p == simplify(moment(X, 1)) assert simplify(variance(X)) == n * p * (1 - p) == simplify(cmoment(X, 2)) assert cancel((skewness(X) - (1 - 2 * p) / sqrt(n * p * (1 - p)))) == 0 assert characteristic_function(X)(t) == p**2 * exp( 2 * I * t) + 2 * p * (-p + 1) * exp(I * t) + (-p + 1)**2 # Test ability to change success/failure winnings H, T = symbols('H T') Y = Binomial('Y', n, p, succ=H, fail=T) assert simplify(E(Y) - (n * (H * p + T * (1 - p)))) == 0
def as_ZPK(self): """Decompose expression into zeros, poles, gain, undef where expression = K * (prod_n (var - z_n) / (prod_n (var - p_n)) * undef """ Bpoly = self.Bpoly Apoly = self.Apoly K = sym.cancel(Bpoly.LC() / Apoly.LC()) if self.delay != 0: K *= sym.exp(self.var * self.delay) zeros = sym.roots(Bpoly) poles = sym.roots(Apoly) return zeros, poles, K, self.undef
def metric(self): temp = sp.eye(self.dim) for key in self.components.keys(): # print('key = ', key) id = tuple(np.abs(key)) # print('id =',id) temp[id] = self.components[key] # print('compo = ',self.components[key]) # print('temp = ', temp) # print('self = ', self) # for i in range(self.dim): # for j in range(self.dim): # temp[i,j] = self.components[-i,-j] # print('compo = ',self.components[-i,-j]) self.metric = temp # def determinant(self): # self.metric() self.determinant = sp.cancel(self.metric.berkowitz_det())
def ZPK(self): """Convert to zero-pole-gain (ZPK) form. See also canonical, general, standard, timeconst, and partfrac""" N, D, delay, undef = self.as_ratfun_delay_undef() var = self.var Npoly = sym.Poly(N, var) Dpoly = sym.Poly(D, var) K = sym.cancel(Npoly.LC() / Dpoly.LC()) if delay != 0: K *= sym.exp(self.var * delay) zeros = sym.roots(Npoly) poles = sym.roots(Dpoly) return _zp2tf(zeros, poles, K, self.var) * undef
def canonical(self): """Convert rational function to canonical form with unity highest power of denominator. See also general, partfrac, mixedfrac, and ZPK""" N, D, delay = self._as_ratfun_delay() K = sym.cancel(N.LC() / D.LC()) if delay != 0: K *= sym.exp(self.var * delay) # Divide by leading coefficient N = N.monic() D = D.monic() expr = K * (N / D) return self.__class__(expr)
def get_simplifications(self) -> List['Expression']: simplifications = [] posible_simplifications = [ Expression(sympy.expand(self.sympy_expr)), Expression(sympy.cancel(self.sympy_expr)), Expression(sympy.simplify(self.sympy_expr)), Expression(sympy.factor(self.sympy_expr)) ] original_integral_amount = self.amount_of_integrals() # TODO check how to do this (Integral(x,x) + Integral(cos(x), x) is simplified to Integral(x+cos(x)) # This workaround solves that problem for posible_simplification in posible_simplifications: if posible_simplification.amount_of_integrals( ) == original_integral_amount: simplifications.append(posible_simplification) return simplifications
def _eval_nseries(self, x, n, logx, cdir=0): # NOTE Please see the comment at the beginning of this file, labelled # IMPORTANT. from sympy import im, cancel, I, Order, logcombine if not logx: logx = log(x) if self.args[0] == x: return logx arg = self.args[0] k, l = Wild("k"), Wild("l") r = arg.match(k * x**l) if r is not None: k, l = r[k], r[l] if l != 0 and not l.has(x) and not k.has(x): r = log(k) + l * logx # XXX true regardless of assumptions? return r # TODO new and probably slow try: a, b = arg.leadterm(x) s = arg.nseries(x, n=n + b, logx=logx) except (ValueError, NotImplementedError): s = arg.nseries(x, n=n, logx=logx) while s.is_Order: n += 1 s = arg.nseries(x, n=n, logx=logx) a, b = s.removeO().leadterm(x) p = cancel(s / (a * x**b) - 1) if p.has(exp): p = logcombine(p) g = None l = [] for i in range(n + 2): g = log.taylor_term(i, p, g) g = g.nseries(x, n=n, logx=logx) l.append(g) res = log(a) + b * logx if cdir != 0: cdir = self.args[0].dir(x, cdir) if a.is_real and a.is_negative and im(cdir) < 0: res -= 2 * I * S.Pi return res + Add(*l) + Order(p**n, x)
def concretize_probability(pdf: str, output_variable: str, bad_output: OutputType) -> float: # replace the variables in the pdf expression with concrete values of bad output for index, value in enumerate(bad_output): pdf = pdf.replace(f'{output_variable}{index}', str(value)) # finally replace the length variable pdf = pdf.replace('length', str(len(bad_output))) logger.debug('Start evaluating...') # replace [ with ( and ] with ) since PSI uses [] to represent parentheses where PSI does not recognize probability = pdf.replace('[', '(').replace(']', ')') # use sympy to first cancel out the trivial parts probability = str(sp.cancel(probability)) # replace the trivial values probability = probability.replace('Boole(True)', '1').replace( 'Boole(False)', '0').replace('DiracDelta(0)', '1') logger.debug('Final probability: {}'.format(probability)) # now run sympy to simplify the final transformed expression, we should have a constant now return float(sp.simplify(probability).evalf())
def main(): parser = ArgumentParser(description=__doc__) parser.add_argument('-m', '--max-order', metavar='order', type=int, action='store', dest='max_order', default=10, help=helps['max_order']) parser.add_argument('output_dir', help=helps['output_dir']) options = parser.parse_args() indir = InDir(options.output_dir) a, b = symbols("a, b") r, s = symbols("r, s") x, y = symbols("x, y") order = options.max_order dim = 2 n_el_nod = get_n_el_nod(order, dim) # number of DOFs per element simplexP = [] exponentM = np.zeros((n_el_nod, 3), dtype=np.int32) coefM = np.zeros((n_el_nod, n_el_nod)) exponentList = [] for m, idx in enumerate(iter_by_order(order, dim)): # print(m, idx) exponentM[m, :dim] = idx pa = jacobi_P(idx[0], 0, 0, a) pb = jacobi_P(idx[1], 2 * idx[0] + 1, 0, b) * (1 - b) ** idx[0] # print("P_{} = {}".format(m, pa*pb)) polrs = cancel((pa * pb).subs(b, s).subs( a, 2 * (1 + r) / (1 - s) - 1)) # print("P_{} = {}".format(m, polrs)) polxy = expand(polrs.subs(r, 2 * x - 1).subs(s, 2 * y - 1)) # polxy = expand(polrs.subs(r, x).subs(s, y)) simplexP.append(simplify(polxy)) exponentList.append(x ** idx[0] * y ** idx[1]) for j, exponent in enumerate(exponentList): coefM[m, j] = simplexP[m].as_coefficients_dict()[exponent] print("P_{}{} = {}".format(m, idx, simplexP[m])) print() np.savetxt(indir("legendre2D_simplex_expos.txt"), exponentM, fmt="%d") # are coefs always integers? np.savetxt(indir("legendre2D_simplex_coefs.txt"), coefM, fmt="%d")
def timeconst(self): """Convert rational function to time constant form with unity lowest power of denominator. See also canonical, general, partfrac, standard, and ZPK""" N, D, delay, undef = self.as_ratfun_delay_undef() var = self.var Npoly = sym.Poly(N, var) Dpoly = sym.Poly(D, var) K = sym.cancel(Npoly.LC() / Dpoly.LC()) if delay != 0: K *= sym.exp(self.var * delay) zeros = sym.roots(Npoly) poles = sym.roots(Dpoly) return _tc2tf(zeros, poles, K, self.var) * undef