def radsimp(expr): """ Rationalize the denominator. Examples: ========= >>> from sympy import * >>> radsimp(1/(2+sqrt(2))) 1 - 2**(1/2)/2 >>> x,y = map(Symbol, 'xy') >>> e = ( (2+2*sqrt(2))*x+(2+sqrt(8))*y )/( 2+sqrt(2) ) >>> radsimp(e) x*2**(1/2) + y*2**(1/2) """ n,d = fraction(expr) a,b,c = map(Wild, 'abc') r = d.match(a+b*sqrt(c)) if r is not None: a = r[a] if r[b] == 0: b,c = 0,0 else: b,c = r[b],r[c] syms = list(n.atoms(Symbol)) n = collect( (n*(a-b*sqrt(c))).expand(), syms ) d = a**2 - c*b**2 return n/d
def sqrtsimp(expr): """ >>> from sympy import * >>> from symplus.strplus import init_mprinting >>> init_mprinting() >>> expand((2+sqrt(3))**2) 4*sqrt(3) + 7 >>> sqrtsimp(sqrt(_)) sqrt(3) + 2 >>> expand((6+sqrt(17))**(-2)) 1/(12*sqrt(17) + 53) >>> sqrtsimp(sqrt(_)) 1/(sqrt(17) + 6) """ from sympy.functions import sqrt, sign from sympy.core import Wild def sqrtofsqrtsimp(a=0, b=0, c=0): # sqrt(a + b*sqrt(c)) q = sqrt(a**2 - b**2*c) if not q.is_Rational: return None return sqrt((a+q)/2) + sign(b)*sqrt((a-q)/2) def sqrtofsqrtsimp_(a=0, b=0, c=0): # 1/sqrt(a + b*sqrt(c)) q = sqrt(a**2 - b**2*c) if not q.is_Rational: return None return 1/(sqrt((a+q)/2) + sign(b)*sqrt((a-q)/2)) a, b, c = Wild('a'), Wild('b'), Wild('c') expr = expr.replace(sqrt(a + b*sqrt(c)), sqrtofsqrtsimp, exact=True) expr = expr.replace(1/sqrt(a + b*sqrt(c)), sqrtofsqrtsimp_, exact=True) return expr
def test_functional_diffgeom_ch2(): x0, y0, r0, theta0 = symbols('x0, y0, r0, theta0', real=True) x, y = symbols('x, y', real=True) f = Function('f') assert (R2_p.point_to_coords(R2_r.point([x0, y0])) == Matrix([sqrt(x0**2 + y0**2), atan2(y0, x0)])) assert (R2_r.point_to_coords(R2_p.point([r0, theta0])) == Matrix([r0*cos(theta0), r0*sin(theta0)])) assert R2_p.jacobian(R2_r, [r0, theta0]) == Matrix( [[cos(theta0), -r0*sin(theta0)], [sin(theta0), r0*cos(theta0)]]) field = f(R2.x, R2.y) p1_in_rect = R2_r.point([x0, y0]) p1_in_polar = R2_p.point([sqrt(x0**2 + y0**2), atan2(y0, x0)]) assert field.rcall(p1_in_rect) == f(x0, y0) assert field.rcall(p1_in_polar) == f(x0, y0) p_r = R2_r.point([x0, y0]) p_p = R2_p.point([r0, theta0]) assert R2.x(p_r) == x0 assert R2.x(p_p) == r0*cos(theta0) assert R2.r(p_p) == r0 assert R2.r(p_r) == sqrt(x0**2 + y0**2) assert R2.theta(p_r) == atan2(y0, x0) h = R2.x*R2.r**2 + R2.y**3 assert h.rcall(p_r) == x0*(x0**2 + y0**2) + y0**3 assert h.rcall(p_p) == r0**3*sin(theta0)**3 + r0**3*cos(theta0)
def rmat2rquat(rmat): """ >>> from sympy import * >>> from symplus.strplus import init_mprinting >>> init_mprinting() >>> t = Symbol('t', positive=True) >>> rquat(pi/3, i+j) [sqrt(3)/2 sqrt(2)/4 sqrt(2)/4 0]' >>> simplify(rmat2rquat(rquat2rmat(rquat(pi/3, i+j)))) [sqrt(3)/2 sqrt(2)/4 sqrt(2)/4 0]' >>> rquat(t, i) [cos(t/2) sin(t/2) 0 0]' >>> simplify(rmat2rquat(rquat2rmat(rquat(t, i)))) [|cos(t/2)| sin(t)/(2*|cos(t/2)|) 0 0]' >>> rquat(t, i+k) [cos(t/2) sqrt(2)*sin(t/2)/2 0 sqrt(2)*sin(t/2)/2]' >>> simplify(rmat2rquat(rquat2rmat(rquat(t, i+k)))) [|cos(t/2)| sqrt(2)*sin(t)/(4*|cos(t/2)|) 0 sqrt(2)*sin(t)/(4*|cos(t/2)|)]' """ w = sqrt(1+trace(rmat))/2 if w != 0: x = (rmat[2,1]-rmat[1,2])/(4*w) y = (rmat[0,2]-rmat[2,0])/(4*w) z = (rmat[1,0]-rmat[0,1])/(4*w) return Mat([w,x,y,z]) else: x = sqrt(1+rmat[0,0]-rmat[1,1]-rmat[2,2])/2 y = (rmat[0,1]+rmat[1,0])/(4*x) z = (rmat[0,2]+rmat[2,0])/(4*x) w = (rmat[2,1]-rmat[1,2])/(4*x) return Mat([w,x,y,z])
def test_Pow(): assert rust_code(1/x) == "x.recip()" assert rust_code(x**-1) == rust_code(x**-1.0) == "x.recip()" assert rust_code(sqrt(x)) == "x.sqrt()" assert rust_code(x**S.Half) == rust_code(x**0.5) == "x.sqrt()" assert rust_code(1/sqrt(x)) == "x.sqrt().recip()" assert rust_code(x**-S.Half) == rust_code(x**-0.5) == "x.sqrt().recip()" assert rust_code(1/pi) == "PI.recip()" assert rust_code(pi**-1) == rust_code(pi**-1.0) == "PI.recip()" assert rust_code(pi**-0.5) == "PI.sqrt().recip()" assert rust_code(x**Rational(1, 3)) == "x.cbrt()" assert rust_code(2**x) == "x.exp2()" assert rust_code(exp(x)) == "x.exp()" assert rust_code(x**3) == "x.powi(3)" assert rust_code(x**(y**3)) == "x.powf(y.powi(3))" assert rust_code(x**Rational(2, 3)) == "x.powf(2_f64/3.0)" g = implemented_function('g', Lambda(x, 2*x)) assert rust_code(1/(g(x)*3.5)**(x - y**x)/(x**2 + y)) == \ "(3.5*2*x).powf(-x + y.powf(x))/(x.powi(2) + y)" _cond_cfunc = [(lambda base, exp: exp.is_integer, "dpowi", 1), (lambda base, exp: not exp.is_integer, "pow", 1)] assert rust_code(x**3, user_functions={'Pow': _cond_cfunc}) == 'x.dpowi(3)' assert rust_code(x**3.2, user_functions={'Pow': _cond_cfunc}) == 'x.pow(3.2)'
def psi_n(n, x, m, omega): """ Returns the wavefunction psi_{n} for the One-dimensional harmonic oscillator. ``n`` the "nodal" quantum number. Corresponds to the number of nodes in the wavefunction. n >= 0 ``x`` x coordinate ``m`` mass of the particle ``omega`` angular frequency of the oscillator :Examples ======== >>> from sympy.physics.qho_1d import psi_n >>> from sympy import var >>> var("x m omega") (x, m, omega) >>> psi_n(0, x, m, omega) (m*omega)**(1/4)*exp(-m*omega*x**2/(2*hbar))/(hbar**(1/4)*pi**(1/4)) """ # sympify arguments n, x, m, omega = map(S, [n, x, m, omega]) nu = m * omega / hbar # normalization coefficient C = (nu/pi)**(S(1)/4) * sqrt(1/(2**n*factorial(n))) return C * exp(-nu* x**2 /2) * hermite(n, sqrt(nu)*x)
def roots_quadratic(f): """Returns a list of roots of a quadratic polynomial.""" a, b, c = f.all_coeffs() dom = f.get_domain() add_comment('This equation is quadratic') def _simplify(expr): if dom.is_Composite: s = factor(expr) else: s = simplify(expr) return s if c is S.Zero: add_comment("The equation can be rewritten as") add_eq(Mul(f.gen, (a*f.gen + b), evaluate=False), 0) r0, r1 = S.Zero, -b/a if not dom.is_Numerical: r1 = _simplify(r1) elif b is S.Zero: add_comment("The equation can be rewritten as") add_eq(f.gen**2, -c/a) r = -c/a if not dom.is_Numerical: R = sqrt(_simplify(r)) else: R = sqrt(r) r0 = R r1 = -R else: d = b**2 - S(4)*a*c add_comment('The discriminant is') add_eq('D', d.simplify()) d.clear_repr() add_comment("Use the formulas") add_eq(f.gen, Mul(Add(-b, Pow(d, S(1)/2, evaluate=False), evaluate=False), Pow(Mul(S(2), a, evaluate=False), -1, evaluate=False), evaluate=False)) add_eq(f.gen, Mul(Add(-b, Mul(-1, Pow(d, S(1)/2, evaluate=False), evaluate=False), evaluate=False), Pow(Mul(S(2), a, evaluate=False), -1, evaluate=False), evaluate=False)) if dom.is_Numerical: D = sqrt(d) r0 = (-b + D) / (S(2)*a) r1 = (-b - D) / (S(2)*a) else: D = sqrt(_simplify(d)) A = 2*a E = _simplify(-b/A) F = D/A r0 = E + F r1 = E - F add_comment("Therefore the roots of this quadratic equation are") add_eq(f.gen, r0) add_eq(f.gen, r1) return sorted([expand_2arg(i) for i in (r0, r1)], key=default_sort_key)
def roots_cubic(f, trig=False): """Returns a list of roots of a cubic polynomial.""" if trig: a, b, c, d = f.all_coeffs() p = (3*a*c - b**2)/3/a**2 q = (2*b**3 - 9*a*b*c + 27*a**2*d)/(27*a**3) D = 18*a*b*c*d - 4*b**3*d + b**2*c**2 - 4*a*c**3 - 27*a**2*d**2 if (D > 0) == True: rv = [] for k in range(3): rv.append(2*sqrt(-p/3)*cos(acos(3*q/2/p*sqrt(-3/p))/3 - k*2*pi/3)) return [i - b/3/a for i in rv] _, a, b, c = f.monic().all_coeffs() if c is S.Zero: x1, x2 = roots([1, a, b], multiple=True) return [x1, S.Zero, x2] p = b - a**2/3 q = c - a*b/3 + 2*a**3/27 pon3 = p/3 aon3 = a/3 if p is S.Zero: if q is S.Zero: return [-aon3]*3 else: if q.is_real: if (q > 0) == True: u1 = -root(q, 3) else: u1 = root(-q, 3) else: u1 = root(-q, 3) elif q is S.Zero: y1, y2 = roots([1, 0, p], multiple=True) return [tmp - aon3 for tmp in [y1, S.Zero, y2]] elif q.is_real and q < 0: u1 = -root(-q/2 + sqrt(q**2/4 + pon3**3), 3) else: u1 = root(q/2 + sqrt(q**2/4 + pon3**3), 3) coeff = I*sqrt(3)/2 u2 = u1*(-S.Half + coeff) u3 = u1*(-S.Half - coeff) if p is S.Zero: return [u1 - aon3, u2 - aon3, u3 - aon3] soln = [ -u1 + pon3/u1 - aon3, -u2 + pon3/u2 - aon3, -u3 + pon3/u3 - aon3 ] return soln
def _sqrt_symbolic_denest(a, b, r): """Given an expression, sqrt(a + b*sqrt(b)), return the denested expression or None. Algorithm: If r = ra + rb*sqrt(rr), try replacing sqrt(rr) in ``a`` with (y**2 - ra)/rb, and if the result is a quadratic, ca*y**2 + cb*y + cc, and (cb + b)**2 - 4*ca*cc is 0, then sqrt(a + b*sqrt(r)) can be rewritten as sqrt(ca*(sqrt(r) + (cb + b)/(2*ca))**2). Examples ======== >>> from sympy.simplify.sqrtdenest import _sqrt_symbolic_denest, sqrtdenest >>> from sympy import sqrt, Symbol >>> from sympy.abc import x >>> a, b, r = 16 - 2*sqrt(29), 2, -10*sqrt(29) + 55 >>> _sqrt_symbolic_denest(a, b, r) sqrt(-2*sqrt(29) + 11) + sqrt(5) If the expression is numeric, it will be simplified: >>> w = sqrt(sqrt(sqrt(3) + 1) + 1) + 1 + sqrt(2) >>> sqrtdenest(sqrt((w**2).expand())) 1 + sqrt(2) + sqrt(1 + sqrt(1 + sqrt(3))) Otherwise, it will only be simplified if assumptions allow: >>> w = w.subs(sqrt(3), sqrt(x + 3)) >>> sqrtdenest(sqrt((w**2).expand())) sqrt((sqrt(sqrt(sqrt(x + 3) + 1) + 1) + 1 + sqrt(2))**2) Notice that the argument of the sqrt is a square. If x is made positive then the sqrt of the square is resolved: >>> _.subs(x, Symbol('x', positive=True)) sqrt(sqrt(sqrt(x + 3) + 1) + 1) + 1 + sqrt(2) """ a, b, r = map(sympify, (a, b, r)) rval = _sqrt_match(r) if not rval: return None ra, rb, rr = rval if rb: y = Dummy('y', positive=True) try: newa = Poly(a.subs(sqrt(rr), (y**2 - ra)/rb), y) except PolynomialError: return None if newa.degree() == 2: ca, cb, cc = newa.all_coeffs() cb += b if _mexpand(cb**2 - 4*ca*cc).equals(0): z = sqrt(ca*(sqrt(r) + cb/(2*ca))**2) if z.is_number: z = _mexpand(Mul._from_args(z.as_content_primitive())) return z
def _expr_big(cls, a, z, n): if n.is_even: return ((sqrt(z) + 1)**(2*a)*exp(2*pi*I*n*a) + (sqrt(z) - 1)**(2*a)*exp(2*pi*I*(n - 1)*a))/2 else: n -= 1 return ((sqrt(z) - 1)**(2*a)*exp(2*pi*I*a*(n + 1)) + (sqrt(z) + 1)**(2*a)*exp(2*pi*I*a*n))/2
def crack_when_pq_close(n): t = ceiling(sqrt(n)) while True: k = t**2 - n if k > 0: s = round(int(sqrt(t**2 - n))) if s**2 + n == t**2: return t + s, t - s t += 1
def test_wavefunction(): Psi = { 0: (nu/pi)**(S(1)/4) * exp(-nu * x**2 /2), 1: (nu/pi)**(S(1)/4) * sqrt(2*nu) * x * exp(-nu * x**2 /2), 2: (nu/pi)**(S(1)/4) * (2 * nu * x**2 - 1)/sqrt(2) * exp(-nu * x**2 /2), 3: (nu/pi)**(S(1)/4) * sqrt(nu/3) * (2 * nu * x**3 - 3 * x) * exp(-nu * x**2 /2) } for n in Psi: assert simplify(psi_n(n, x, m, omega) - Psi[n]) == 0
def solve_ODE_second_order(eq, f): """ solves many kinds of second order odes, different methods are used depending on the form of the given equation. So far the constants coefficients case and a special case are implemented. """ x = f.args[0] f = f.func #constant coefficients case: af''(x)+bf'(x)+cf(x)=0 a = Wild('a', exclude=[x]) b = Wild('b', exclude=[x]) c = Wild('c', exclude=[x]) r = eq.match(a*f(x).diff(x,x) + c*f(x)) if r: return Symbol("C1")*C.sin(sqrt(r[c]/r[a])*x)+Symbol("C2")*C.cos(sqrt(r[c]/r[a])*x) r = eq.match(a*f(x).diff(x,x) + b*diff(f(x),x) + c*f(x)) if r: r1 = solve(r[a]*x**2 + r[b]*x + r[c], x) if r1[0].is_real: if len(r1) == 1: return (Symbol("C1") + Symbol("C2")*x)*exp(r1[0]*x) else: return Symbol("C1")*exp(r1[0]*x) + Symbol("C2")*exp(r1[1]*x) else: r2 = abs((r1[0] - r1[1])/(2*S.ImaginaryUnit)) return (Symbol("C2")*C.cos(r2*x) + Symbol("C1")*C.sin(r2*x))*exp((r1[0] + r1[1])*x/2) #other cases of the second order odes will be implemented here #special equations, that we know how to solve a = Wild('a') t = x*exp(f(x)) tt = a*t.diff(x, x)/t r = eq.match(tt.expand()) if r: return -solve_ODE_1(f(x), x) t = x*exp(-f(x)) tt = a*t.diff(x, x)/t r = eq.match(tt.expand()) if r: #check, that we've rewritten the equation correctly: #assert ( r[a]*t.diff(x,2)/t ) == eq.subs(f, t) return solve_ODE_1(f(x), x) neq = eq*exp(f(x))/exp(-f(x)) r = neq.match(tt.expand()) if r: #check, that we've rewritten the equation correctly: #assert ( t.diff(x,2)*r[a]/t ).expand() == eq return solve_ODE_1(f(x), x) raise NotImplementedError("solve_ODE_second_order: cannot solve " + str(eq))
def R_nl(n, l, nu, r): """ Returns the radial wavefunction R_{nl} for a 3d isotropic harmonic oscillator. ``n`` the "nodal" quantum number. Corresponds to the number of nodes in the wavefunction. n >= 0 ``l`` the quantum number for orbital angular momentum ``nu`` mass-scaled frequency: nu = m*omega/(2*hbar) where `m` is the mass and `omega` the frequency of the oscillator. (in atomic units nu == omega/2) ``r`` Radial coordinate Examples ======== >>> from sympy.physics.sho import R_nl >>> from sympy import var >>> var("r nu l") (r, nu, l) >>> R_nl(0, 0, 1, r) 2*2**(3/4)*exp(-r**2)/pi**(1/4) >>> R_nl(1, 0, 1, r) 4*2**(1/4)*sqrt(3)*(-2*r**2 + 3/2)*exp(-r**2)/(3*pi**(1/4)) l, nu and r may be symbolic: >>> R_nl(0, 0, nu, r) 2*2**(3/4)*sqrt(nu**(3/2))*exp(-nu*r**2)/pi**(1/4) >>> R_nl(0, l, 1, r) r**l*sqrt(2**(l + 3/2)*2**(l + 2)/factorial2(2*l + 1))*exp(-r**2)/pi**(1/4) The normalization of the radial wavefunction is: >>> from sympy import Integral, oo >>> Integral(R_nl(0, 0, 1, r)**2 * r**2, (r, 0, oo)).n() 1.00000000000000 >>> Integral(R_nl(1, 0, 1, r)**2 * r**2, (r, 0, oo)).n() 1.00000000000000 >>> Integral(R_nl(1, 1, 1, r)**2 * r**2, (r, 0, oo)).n() 1.00000000000000 """ n, l, nu, r = map(S, [n, l, nu, r]) # formula uses n >= 1 (instead of nodal n >= 0) n = n + 1 C = sqrt( ((2 * nu) ** (l + Rational(3, 2)) * 2 ** (n + l + 1) * factorial(n - 1)) / (sqrt(pi) * (factorial2(2 * n + 2 * l - 1))) ) return C * r ** (l) * exp(-nu * r ** 2) * assoc_laguerre(n - 1, l + S(1) / 2, 2 * nu * r ** 2)
def _roots_quartic_euler(p, q, r, a): """ Descartes-Euler solution of the quartic equation Parameters ========== p, q, r: coefficients of ``x**4 + p*x**2 + q*x + r`` a: shift of the roots Notes ===== This is a helper function for ``roots_quartic``. Look for solutions of the form :: ``x1 = sqrt(R) - sqrt(A + B*sqrt(R))`` ``x2 = -sqrt(R) - sqrt(A - B*sqrt(R))`` ``x3 = -sqrt(R) + sqrt(A - B*sqrt(R))`` ``x4 = sqrt(R) + sqrt(A + B*sqrt(R))`` To satisfy the quartic equation one must have ``p = -2*(R + A); q = -4*B*R; r = (R - A)**2 - B**2*R`` so that ``R`` must satisfy the Descartes-Euler resolvent equation ``64*R**3 + 32*p*R**2 + (4*p**2 - 16*r)*R - q**2 = 0`` If the resolvent does not have a rational solution, return None; in that case it is likely that the Ferrari method gives a simpler solution. Examples ======== >>> from sympy import S >>> from sympy.polys.polyroots import _roots_quartic_euler >>> p, q, r = -S(64)/5, -S(512)/125, -S(1024)/3125 >>> _roots_quartic_euler(p, q, r, S(0))[0] -sqrt(32*sqrt(5)/125 + 16/5) + 4*sqrt(5)/5 """ from sympy.solvers import solve # solve the resolvent equation x = Symbol("x") eq = 64 * x ** 3 + 32 * p * x ** 2 + (4 * p ** 2 - 16 * r) * x - q ** 2 xsols = list(roots(Poly(eq, x), cubics=False).keys()) xsols = [sol for sol in xsols if sol.is_rational] if not xsols: return None R = max(xsols) c1 = sqrt(R) B = -q * c1 / (4 * R) A = -R - p / 2 c2 = sqrt(A + B) c3 = sqrt(A - B) return [c1 - c2 - a, -c1 - c3 - a, -c1 + c3 - a, c1 + c2 - a]
def _ans(y): w = sqrt(e + 2*y) arg1 = 3*e + 2*y arg2 = 2*f/w ans = [] for s in [-1, 1]: root = sqrt(-(arg1 + s*arg2)) for t in [-1, 1]: ans.append((s*w - t*root)/2 - aon4) return ans
def find(a): n = len(a) for i in range(n - 1): for j in range(i + 1, n): s1 = a[i].base s2 = a[j].base p = _mexpand(s1 * s2) s = sqrtdenest(sqrt(p)) if s != sqrt(p): return s, i, j
def test_5(): test = [ [(S(1) + a*x)**(S(3)/S(2))/sqrt(S(1) - a*x), x, S(4), S(3)/S(2)*arcsin(a*x)/a - S(1)/S(2)*(S(1) + a*x)**(S(3)/S(2))*sqrt(S(1) - a*x)/a - S(3)/S(2)*sqrt(S(1) - a*x)*sqrt(S(1) + a*x)/a], [(S(1) - x)**(S(1)/S(2))/(S(1) + x)**(S(1)/S(2)), x, S(3), arcsin(x) + sqrt(S(1) - x)*sqrt(S(1) + x)], [S(1)/((S(1) - x)**(S(1)/S(2))*(S(1) + x)**(S(3)/S(2))), x, S(1), - sqrt(S(1) - x)/sqrt(S(1) + x)], [(a + a*x)**(S(5)/S(2))*(c - c*x)**(S(5)/S(2)), x, S(5), S(5)/S(24)*a*c*x*(a + a*x)**(S(3)/S(2))*(c - c*x)**(S(3)/S(2)) + S(1)/S(6)*x*(a + a*x)**(S(5)/S(2))*(c - c*x)**(S(5)/S(2)) + S(5)/S(8)*a**(S(5)/S(2))*c**(S(5)/S(2))*arctan(sqrt(c)*sqrt(a + a*x)/(sqrt(a)*sqrt(c - c*x))) + S(5)/S(16)*a**S(2)*c**S(2)*x*sqrt(a + a*x)*sqrt(c - c*x)], [S(1)/((a + a*x)**(S(5)/S(2))*(c - c*x)**(S(5)/S(2))), x, S(2), S(1)/S(3)*x/(a*c*(a + a*x)**(S(3)/S(2))*(c - c*x)**(S(3)/S(2))) + S(2)/S(3)*x/(a**S(2)*c**S(2)*sqrt(a + a*x)*sqrt(c - c*x))], [(S(3) - x)**(S(1)/S(2))*( - S(2) + x)**(S(1)/S(2)), x, S(5), - S(1)/S(8)*arcsin(S(5) - S(2)*x) - S(1)/S(2)*(S(3) - x)**(S(3)/S(2))*sqrt( - S(2) + x) + S(1)/S(4)*sqrt(S(3) - x)*sqrt( - S(2) + x)], [S(1)/(sqrt(a + b*x)*sqrt( - a*d + b*d*x)), x, S(2), S(2)*arctanh(sqrt(d)*sqrt(a + b*x)/sqrt( - a*d + b*d*x))/(b*sqrt(d))], [S(1)/((a - I*a*x)**(S(7)/S(4))*(a + I*a*x)**(S(1)/S(4))), x, S(1), - S(2)/S(3)*I*(a + I*a*x)**(S(3)/S(4))/(a**S(2)*(a - I*a*x)**(S(3)/S(4)))], [(a + b*x)**S(2)*(a*c - b*c*x)**n, x, S(2), - S(4)*a**S(2)*(a*c - b*c*x)**(S(1) + n)/(b*c*(S(1) + n)) + S(4)*a*(a*c - b*c*x)**(S(2) + n)/(b*c**S(2)*(S(2) + n)) - (a*c - b*c*x)**(S(3) + n)/(b*c**S(3)*(S(3) + n))], [(a + b*x)**S(4)*(c + d*x), x, S(2), S(1)/S(5)*(b*c - a*d)*(a + b*x)**S(5)/b**S(2) + S(1)/S(6)*d*(a + b*x)**S(6)/b**S(2)], [(a + b*x)*(c + d*x), x, S(2), a*c*x + S(1)/S(2)*(b*c + a*d)*x**S(2) + S(1)/S(3)*b*d*x**S(3)], [(a + b*x)**S(5)/(c + d*x), x, S(2), b*(b*c - a*d)**S(4)*x/d**S(5) - S(1)/S(2)*(b*c - a*d)**S(3)*(a + b*x)**S(2)/d**S(4) + S(1)/S(3)*(b*c - a*d)**S(2)*(a + b*x)**S(3)/d**S(3) - S(1)/S(4)*(b*c - a*d)*(a + b*x)**S(4)/d**S(2) + S(1)/S(5)*(a + b*x)**S(5)/d - (b*c - a*d)**S(5)*log(c + d*x)/d**S(6)], [(a + b*x)/(c + d*x)**S(3), x, S(1), S(1)/S(2)*(a + b*x)**S(2)/((b*c - a*d)*(c + d*x)**S(2))], [(a + b*x)**S(5)*(c + d*x)**(S(1)/S(2)), x, S(2), - S(2)/S(3)*(b*c - a*d)**S(5)*(c + d*x)**(S(3)/S(2))/d**S(6) + S(2)*b*(b*c - a*d)**S(4)*(c + d*x)**(S(5)/S(2))/d**S(6) - S(20)/S(7)*b**S(2)*(b*c - a*d)**S(3)*(c + d*x)**(S(7)/S(2))/d**S(6) + S(20)/S(9)*b**S(3)*(b*c - a*d)**S(2)*(c + d*x)**(S(9)/S(2))/d**S(6) - S(10)/S(11)*b**S(4)*(b*c - a*d)*(c + d*x)**(S(11)/S(2))/d**S(6) + S(2)/S(13)*b**S(5)*(c + d*x)**(S(13)/S(2))/d**S(6)], [(c + d*x)**(S(1)/S(2))/(a + b*x)**S(2), x, S(3), - d*arctanh(sqrt(b)*sqrt(c + d*x)/sqrt(b*c - a*d))/(b**(S(3)/S(2))*sqrt(b*c - a*d)) - sqrt(c + d*x)/(b*(a + b*x))], ] for i in test: r = rubi_integrate(i[0], i[1]) if len(i) == 5: assert rubi_test(r, i[1], i[3], expand=True, _diff=True) or rubi_test(r, i[1], i[4], expand=True, _diff=True) else: assert rubi_test(r, i[1], i[3], expand=True, _diff=True)
def _sqrtdenest_rec(expr): """Helper that denests the square root of three or more surds. It returns the denested expression; if it cannot be denested it throws SqrtdenestStopIteration Algorithm: expr.base is in the extension Q_m = Q(sqrt(r_1),..,sqrt(r_k)); split expr.base = a + b*sqrt(r_k), where `a` and `b` are on Q_(m-1) = Q(sqrt(r_1),..,sqrt(r_(k-1))); then a**2 - b**2*r_k is on Q_(m-1); denest sqrt(a**2 - b**2*r_k) and so on. See [1], section 6. Examples ======== >>> from sympy import sqrt >>> from sympy.simplify.sqrtdenest import _sqrtdenest_rec >>> _sqrtdenest_rec(sqrt(-72*sqrt(2) + 158*sqrt(5) + 498)) -sqrt(10) + sqrt(2) + 9 + 9*sqrt(5) >>> w=-6*sqrt(55)-6*sqrt(35)-2*sqrt(22)-2*sqrt(14)+2*sqrt(77)+6*sqrt(10)+65 >>> _sqrtdenest_rec(sqrt(w)) -sqrt(11) - sqrt(7) + sqrt(2) + 3*sqrt(5) """ from sympy.simplify.simplify import radsimp, split_surds, rad_rationalize if expr.base < 0: return sqrt(-1)*_sqrtdenest_rec(sqrt(-expr.base)) a, b = split_surds(expr.base) if a < b: a, b = b, a c2 = _mexpand(a**2 - b**2) if len(c2.args) > 2: a1, b1 = split_surds(c2) if a1 < b1: a1, b1 = b1, a1 c2_1 = _mexpand(a1**2 - b1**2) c_1 = _sqrtdenest_rec(sqrt(c2_1)) d_1 = _sqrtdenest_rec(sqrt(a1 + c_1)) num, den = rad_rationalize(b1, d_1) c = _mexpand(d_1/sqrt(2) + num/(den*sqrt(2))) else: c = _sqrtdenest1(sqrt(c2)) if sqrt_depth(c) > 1: raise SqrtdenestStopIteration ac = a + c if len(ac.args) >= len(expr.args): if count_ops(ac) >= count_ops(expr.base): raise SqrtdenestStopIteration d = sqrtdenest(sqrt(ac)) if sqrt_depth(d) > 1: raise SqrtdenestStopIteration num, den = rad_rationalize(b, d) r = d/sqrt(2) + num/(den*sqrt(2)) r = radsimp(r) return _mexpand(r)
def test_1_over_x_and_sqrt(): # 1.0 and 0.5 would do something different in regular StrPrinter, # but these are exact in IEEE floating point so no different here. assert julia_code(1/x) == '1./x' assert julia_code(x**-1) == julia_code(x**-1.0) == '1./x' assert julia_code(1/sqrt(x)) == '1./sqrt(x)' assert julia_code(x**-S.Half) == julia_code(x**-0.5) == '1./sqrt(x)' assert julia_code(sqrt(x)) == 'sqrt(x)' assert julia_code(x**S.Half) == julia_code(x**0.5) == 'sqrt(x)' assert julia_code(1/pi) == '1/pi' assert julia_code(pi**-1) == julia_code(pi**-1.0) == '1/pi' assert julia_code(pi**-0.5) == '1/sqrt(pi)'
def test_eval_args(): # check instance created assert isinstance(Density([Ket(0), 0.5], [Ket(1), 0.5]), Density) assert isinstance(Density([Qubit('00'), 1/sqrt(2)], [Qubit('11'), 1/sqrt(2)]), Density) #test if Qubit object type preserved d = Density([Qubit('00'), 1/sqrt(2)], [Qubit('11'), 1/sqrt(2)]) for (state, prob) in d.args: assert isinstance(state, Qubit) # check for value error, when prob is not provided raises(ValueError, lambda: Density([Ket(0)], [Ket(1)]))
def roots_quadratic(f): """Returns a list of roots of a quadratic polynomial. If the domain is ZZ then the roots will be sorted with negatives coming before positives. The ordering will be the same for any numerical coefficients as long as the assumptions tested are correct, otherwise the ordering will not be sorted (but will be canonical). """ a, b, c = f.all_coeffs() dom = f.get_domain() def _simplify(expr): if dom.is_Composite: return factor(expr) else: return simplify(expr) if c is S.Zero: r0, r1 = S.Zero, -b/a if not dom.is_Numerical: r1 = _simplify(r1) elif r1.is_negative: r0, r1 = r1, r0 elif b is S.Zero: r = -c/a if not dom.is_Numerical: r = _simplify(r) R = sqrt(r) r0 = -R r1 = R else: d = b**2 - 4*a*c A = 2*a B = -b/A if not dom.is_Numerical: d = _simplify(d) B = _simplify(B) D = sqrt(d)/A r0 = B - D r1 = B + D if a.is_negative: r0, r1 = r1, r0 elif not dom.is_Numerical: r0, r1 = [expand_2arg(i) for i in (r0, r1)] return [r0, r1]
def _sqrt_numeric_denest(a, b, r, d2): """Helper that denest expr = a + b*sqrt(r), with d2 = a**2 - b**2*r > 0 or returns None if not denested. """ from sympy.simplify.simplify import radsimp depthr = sqrt_depth(r) d = sqrt(d2) vad = a + d # sqrt_depth(res) <= sqrt_depth(vad) + 1 # sqrt_depth(expr) = depthr + 2 # there is denesting if sqrt_depth(vad)+1 < depthr + 2 # if vad**2 is Number there is a fourth root if sqrt_depth(vad) < depthr + 1 or (vad**2).is_Rational: vad1 = radsimp(1/vad) return (sqrt(vad/2) + sign(b)*sqrt((b**2*r*vad1/2).expand())).expand()
def roots_quadratic(f, sort=True): """Returns a list of roots of a quadratic polynomial.""" a, b, c = f.all_coeffs() dom = f.get_domain() def _simplify(expr): if dom.is_Composite: return factor(expr) else: return simplify(expr) if c is S.Zero: r0, r1 = S.Zero, -b/a if not dom.is_Numerical: r1 = _simplify(r1) elif b is S.Zero: r = -c/a if not dom.is_Numerical: R = sqrt(_simplify(r)) else: R = sqrt(r) r0 = R r1 = -R else: d = b**2 - 4*a*c if dom.is_Numerical: D = sqrt(d) r0 = (-b + D) / (2*a) r1 = (-b - D) / (2*a) else: D = sqrt(_simplify(d)) A = 2*a E = _simplify(-b/A) F = D/A r0 = E + F r1 = E - F roots = list(map(expand_2arg, (r0, r1))) if sort: return sorted(roots, key=default_sort_key) return roots
def roots_cubic(f): """Returns a list of roots of a cubic polynomial.""" _, a, b, c = f.monic().all_coeffs() if c is S.Zero: x1, x2 = roots([1, a, b], multiple=True) return [x1, S.Zero, x2] p = b - a**2/3 q = c - a*b/3 + 2*a**3/27 pon3 = p/3 aon3 = a/3 if p is S.Zero: if q is S.Zero: return [-aon3]*3 else: if q.is_real: if (q > 0) is True: u1 = -q**Rational(1, 3) else: u1 = (-q)**Rational(1, 3) else: u1 = (-q)**Rational(1, 3) elif q is S.Zero: y1, y2 = roots([1, 0, p], multiple=True) return [tmp - aon3 for tmp in [y1, S.Zero, y2]] elif q.is_real and q < 0: u1 = -(-q/2 + sqrt(q**2/4 + pon3**3))**Rational(1, 3) else: u1 = (q/2 + sqrt(q**2/4 + pon3**3))**Rational(1, 3) coeff = S.ImaginaryUnit*sqrt(3)/2 u2 = u1*(-S.Half + coeff) u3 = u1*(-S.Half - coeff) if p is S.Zero: return [u1 - aon3, u2 - aon3, u3 - aon3] soln = [ -u1 + pon3/u1 - aon3, -u2 + pon3/u2 - aon3, -u3 + pon3/u3 - aon3 ] return soln
def _sqrt(d): # remove squares from square root since both will be represented # in the results; a similar thing is happening in roots() but # must be duplicated here because not all quadratics are binomials co = [] other = [] for di in Mul.make_args(d): if di.is_Pow and di.exp.is_Integer and di.exp % 2 == 0: co.append(Pow(di.base, di.exp//2)) else: other.append(di) if co: d = Mul(*other) co = Mul(*co) return co*sqrt(d) return sqrt(d)
def _represent_ZGate(self, basis, **options): """ Represents the (I)QFT In the Z Basis """ nqubits = options.get('nqubits',0) if nqubits == 0: raise QuantumError('The number of qubits must be given as nqubits.') if nqubits < self.min_qubits: raise QuantumError( 'The number of qubits %r is too small for the gate.' % nqubits ) size = self.size omega = self.omega #Make a matrix that has the basic Fourier Transform Matrix arrayFT = [[omega**(i*j%size)/sqrt(size) for i in range(size)] for j in range(size)] matrixFT = Matrix(arrayFT) #Embed the FT Matrix in a higher space, if necessary if self.label[0] != 0: matrixFT = matrix_tensor_product(eye(2**self.label[0]), matrixFT) if self.min_qubits < nqubits: matrixFT = matrix_tensor_product(matrixFT, eye(2**(nqubits-self.min_qubits))) return matrixFT
def _expr_big(cls, a, x, n): sgn = -1 if n.is_odd: sgn = 1 n -= 1 return 2**(2*a - 1)*(1 + sgn*I*sqrt(x - 1))**(1 - 2*a) \ *exp(-2*n*pi*I*a)
def test_catalan(): n = Symbol('n', integer=True) m = Symbol('n', integer=True, positive=True) catalans = [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786] for i, c in enumerate(catalans): assert catalan(i) == c assert catalan(n).rewrite(factorial).subs(n, i) == c assert catalan(n).rewrite(Product).subs(n, i).doit() == c assert catalan(x) == catalan(x) assert catalan(2*x).rewrite(binomial) == binomial(4*x, 2*x)/(2*x + 1) assert catalan(Rational(1, 2)).rewrite(gamma) == 8/(3*pi) assert catalan(Rational(1, 2)).rewrite(factorial).rewrite(gamma) ==\ 8 / (3 * pi) assert catalan(3*x).rewrite(gamma) == 4**( 3*x)*gamma(3*x + Rational(1, 2))/(sqrt(pi)*gamma(3*x + 2)) assert catalan(x).rewrite(hyper) == hyper((-x + 1, -x), (2,), 1) assert catalan(n).rewrite(factorial) == factorial(2*n) / (factorial(n + 1) * factorial(n)) assert isinstance(catalan(n).rewrite(Product), catalan) assert isinstance(catalan(m).rewrite(Product), Product) assert diff(catalan(x), x) == (polygamma( 0, x + Rational(1, 2)) - polygamma(0, x + 2) + log(4))*catalan(x) assert catalan(x).evalf() == catalan(x) c = catalan(S.Half).evalf() assert str(c) == '0.848826363156775' c = catalan(I).evalf(3) assert str((re(c), im(c))) == '(0.398, -0.0209)'
def test_Matrix_printing(): # Test returning a Matrix mat = Matrix([x*y, Piecewise((2 + x, y>0), (y, True)), sin(z)]) A = MatrixSymbol('A', 3, 1) p = rcode(mat, A) assert p == ( "A[0] = x*y;\n" "A[1] = ifelse(y > 0,x + 2,y);\n" "A[2] = sin(z);") # Test using MatrixElements in expressions expr = Piecewise((2*A[2, 0], x > 0), (A[2, 0], True)) + sin(A[1, 0]) + A[0, 0] p = rcode(expr) assert p == ("ifelse(x > 0,2*A[2],A[2]) + sin(A[1]) + A[0]") # Test using MatrixElements in a Matrix q = MatrixSymbol('q', 5, 1) M = MatrixSymbol('M', 3, 3) m = Matrix([[sin(q[1,0]), 0, cos(q[2,0])], [q[1,0] + q[2,0], q[3, 0], 5], [2*q[4, 0]/q[1,0], sqrt(q[0,0]) + 4, 0]]) assert rcode(m, M) == ( "M[0] = sin(q[1]);\n" "M[1] = 0;\n" "M[2] = cos(q[2]);\n" "M[3] = q[1] + q[2];\n" "M[4] = q[3];\n" "M[5] = 5;\n" "M[6] = 2*q[4]/q[1];\n" "M[7] = sqrt(q[0]) + 4;\n" "M[8] = 0;")
def test_pickling_polys_numberfields(): from sympy.polys.numberfields import AlgebraicNumber for c in (AlgebraicNumber, AlgebraicNumber(sqrt(3))): check(c, check_attr=False)
def _expr_small(cls, a, z): return cos(2 * a * asin(sqrt(z)))
def _expr_big(cls, a, z, n): return cosh(2 * a * acosh(sqrt(z)) + a * pi * I * (2 * n - 1))
def _expr_small(cls, a, z): return sqrt(z) / sqrt(1 - z) * sin(2 * a * asin(sqrt(z)))
def _expr_big(cls, a, z, n): return -1 / sqrt(1 - 1 / z) * sinh(2 * a * acosh(sqrt(z)) + a * pi * I * (2 * n - 1))
def roots_quartic(f): r""" Returns a list of roots of a quartic polynomial. There are many references for solving quartic expressions available [1-5]. This reviewer has found that many of them require one to select from among 2 or more possible sets of solutions and that some solutions work when one is searching for real roots but don't work when searching for complex roots (though this is not always stated clearly). The following routine has been tested and found to be correct for 0, 2 or 4 complex roots. The quasisymmetric case solution [6] looks for quartics that have the form `x**4 + A*x**3 + B*x**2 + C*x + D = 0` where `(C/A)**2 = D`. Although there is a general solution, simpler results can be obtained for certain values of the coefficients. In all cases, 4 roots are returned: 1) `f = c + a*(a**2/8 - b/2) == 0` 2) `g = d - a*(a*(3*a**2/256 - b/16) + c/4) = 0` 3) if `f != 0` and `g != 0` and `p = -d + a*c/4 - b**2/12` then a) `p == 0` b) `p != 0` **Examples** >>> from sympy import Poly, symbols, I >>> from sympy.polys.polyroots import roots_quartic >>> r = roots_quartic(Poly('x**4-6*x**3+17*x**2-26*x+20')) >>> # 4 complex roots: 1+-I*sqrt(3), 2+-I >>> sorted(str(tmp.evalf(n=2)) for tmp in r) ['1.0 + 1.7*I', '1.0 - 1.7*I', '2.0 + I', '2.0 - 1.0*I'] **References** 1. http://mathforum.org/dr.math/faq/faq.cubic.equations.html 2. http://en.wikipedia.org/wiki/Quartic_function#Summary_of_Ferrari.27s_method 3. http://planetmath.org/encyclopedia/GaloisTheoreticDerivationOfTheQuarticFormula.html 4. http://staff.bath.ac.uk/masjhd/JHD-CA.pdf 5. http://www.albmath.org/files/Math_5713.pdf 6. http://www.statemaster.com/encyclopedia/Quartic-equation """ _, a, b, c, d = f.monic().all_coeffs() if not d: return [S.Zero] + roots([1, a, b, c], multiple=True) elif (c / a)**2 == d: x, m = f.gen, c / a g = Poly(x**2 + a * x + b - 2 * m, x) z1, z2 = roots_quadratic(g) h1 = Poly(x**2 - z1 * x + m, x) h2 = Poly(x**2 - z2 * x + m, x) r1 = roots_quadratic(h1) r2 = roots_quadratic(h2) return r1 + r2 else: a2 = a**2 e = b - 3 * a2 / 8 f = c + a * (a2 / 8 - b / 2) g = d - a * (a * (3 * a2 / 256 - b / 16) + c / 4) aon4 = a / 4 ans = [] if f is S.Zero: y1, y2 = [tmp**S.Half for tmp in roots([1, e, g], multiple=True)] return [tmp - aon4 for tmp in [-y1, -y2, y1, y2]] if g is S.Zero: y = [S.Zero] + roots([1, 0, e, f], multiple=True) return [tmp - aon4 for tmp in y] else: p = -e**2 / 12 - g q = -e**3 / 108 + e * g / 3 - f**2 / 8 TH = Rational(1, 3) if p is S.Zero: y = -5 * e / 6 - q**TH else: # with p !=0 then u below is not 0 root = sqrt(q**2 / 4 + p**3 / 27) r = -q / 2 + root # or -q/2 - root u = r**TH # primary root of solve(x**3-r, x) y = -5 * e / 6 + u - p / u / 3 w = sqrt(e + 2 * y) arg1 = 3 * e + 2 * y arg2 = 2 * f / w for s in [-1, 1]: root = sqrt(-(arg1 + s * arg2)) for t in [-1, 1]: ans.append((s * w - t * root) / 2 - aon4) return ans
def _expr_big_minus(cls, z, n): return S(-1)**n * (asinh(sqrt(z)) / sqrt(z) + n * pi * I / sqrt(z))
def _expr_small(cls, a, z): return ((1 - sqrt(z))**(2 * a) + (1 + sqrt(z))**(2 * a)) / 2
def _expr_small_minus(cls, a, z): return (1 + z)**a * cos(2 * a * atan(sqrt(z)))
def _expr_small(cls, a, z): return sqrt(z) * ((1 - sqrt(z))**(2 * a) - (1 + sqrt(z))**(2 * a)) / 2
def _expr_small_minus(cls, a, z): return sqrt(z) * (1 + z)**a * sin(2 * a * atan(sqrt(z)))
def _expr_small(cls, z): return log(S(1) / 2 + sqrt(1 - z) / 2)
def _expr_big_minus(cls, z, n): if n.is_even: return pi * I * n + log(S(1) / 2 + sqrt(1 + z) / 2) else: return pi * I * n + log(sqrt(1 + z) / 2 - S(1) / 2)
def _expr_big_minus(cls, a, x, n): sgn = 1 if n.is_odd: sgn = -1 return sgn * 2**(2 * a - 1) * (sqrt(1 + x) + sgn)**(1 - 2 * a) * exp( -2 * pi * I * a * n)
def _expr_small_minus(cls, a, x): return 2**(2 * a - 1) * (1 + sqrt(1 + x))**(1 - 2 * a)
def _expr_big_minus(cls, a, z, n): return -1 / sqrt(1 + 1 / z) * sinh(2 * a * asinh(sqrt(z)) + 2 * a * pi * I * n)
def _expr_big(cls, z, n): return S(-1)**n * ( (S(1) / 2 - n) * pi / sqrt(z) + I * acosh(sqrt(z)) / sqrt(z))
def test_ccode_sqrt(): assert ccode(sqrt(x)) == "sqrt(x)" assert ccode(x**0.5) == "sqrt(x)" assert ccode(sqrt(x)) == "sqrt(x)"
def _expr_small(cls, a, x): return 2**(2 * a - 1) * (1 + sqrt(1 - x))**(1 - 2 * a)
def _expr_small_minus(cls, z): return asinh(sqrt(z)) / sqrt(z)
def _expr_small(cls, z): return asin(sqrt(z)) / sqrt(z)
def _expr_big_minus(cls, x, n): if n.is_even: return atan(sqrt(x)) / sqrt(x) else: return (atan(sqrt(x)) - pi) / sqrt(x)
def _expr_small_minus(cls, a, z): return -sqrt(z) / sqrt(1 + z) * sinh(2 * a * asinh(sqrt(z)))
def _expr_big(cls, x, n): if n.is_even: return (acoth(sqrt(x)) + I * pi / 2) / sqrt(x) else: return (acoth(sqrt(x)) - I * pi / 2) / sqrt(x)
def _expr_big_minus(cls, a, z, n): return cosh(2 * a * asinh(sqrt(z)) + 2 * a * pi * I * n)
def _expr_small_minus(cls, x): return atan(sqrt(x)) / sqrt(x)
def _expr_small_minus(cls, a, z): return cosh(2 * a * asinh(sqrt(z)))
def _expr_small(cls, x): return atanh(sqrt(x)) / sqrt(x)
def match_2nd_2F1_hypergeometric(I, k, sing_point, func): x = func.args[0] a = Wild("a") b = Wild("b") c = Wild("c") t = Wild("t") s = Wild("s") r = Wild("r") alpha = Wild("alpha") beta = Wild("beta") gamma = Wild("gamma") delta = Wild("delta") # I0 of the standerd 2F1 equation. I0 = ((a - b + 1) * (a - b - 1) * x**2 + 2 * ((1 - a - b) * c + 2 * a * b) * x + c * (c - 2)) / (4 * x**2 * (x - 1)**2) if sing_point != [0, 1]: # If singular point is [0, 1] then we have standerd equation. eqs = [] sing_eqs = [ -beta / alpha, -delta / gamma, (delta - beta) / (alpha - gamma) ] # making equations for the finding the mobius transformation for i in range(3): if i < len(sing_point): eqs.append(Eq(sing_eqs[i], sing_point[i])) else: eqs.append(Eq(1 / sing_eqs[i], 0)) # solving above equations for the mobius transformation _beta = -alpha * sing_point[0] _delta = -gamma * sing_point[1] _gamma = alpha if len(sing_point) == 3: _gamma = (_beta + sing_point[2] * alpha) / (sing_point[2] - sing_point[1]) mob = (alpha * x + beta) / (gamma * x + delta) mob = mob.subs(beta, _beta) mob = mob.subs(delta, _delta) mob = mob.subs(gamma, _gamma) mob = cancel(mob) t = (beta - delta * x) / (gamma * x - alpha) t = cancel(((t.subs(beta, _beta)).subs(delta, _delta)).subs(gamma, _gamma)) else: mob = x t = x # applying mobius transformation in I to make it into I0. I = I.subs(x, t) I = I * (t.diff(x))**2 I = factor(I) dict_I = {x**2: 0, x: 0, 1: 0} I0_num, I0_dem = I0.as_numer_denom() # collecting coeff of (x**2, x), of the standerd equation. # substituting (a-b) = s, (a+b) = r dict_I0 = { x**2: s**2 - 1, x: (2 * (1 - r) * c + (r + s) * (r - s)), 1: c * (c - 2) } # collecting coeff of (x**2, x) from I0 of the given equation. dict_I.update( collect(expand(cancel(I * I0_dem)), [x**2, x], evaluate=False)) eqs = [] # We are comparing the coeff of powers of different x, for finding the values of # parameters of standerd equation. for key in [x**2, x, 1]: eqs.append(Eq(dict_I[key], dict_I0[key])) # We can have many possible roots for the equation. # I am selecting the root on the basis that when we have # standard equation eq = x*(x-1)*f(x).diff(x, 2) + ((a+b+1)*x-c)*f(x).diff(x) + a*b*f(x) # then root should be a, b, c. _c = 1 - factor(sqrt(1 + eqs[2].lhs)) if not _c.has(Symbol): _c = min(list(roots(eqs[2], c))) _s = factor(sqrt(eqs[0].lhs + 1)) _r = _c - factor(sqrt(_c**2 + _s**2 + eqs[1].lhs - 2 * _c)) _a = (_r + _s) / 2 _b = (_r - _s) / 2 rn = { 'a': simplify(_a), 'b': simplify(_b), 'c': simplify(_c), 'k': k, 'mobius': mob, 'type': "2F1" } return rn
def _expr_small_minus(cls, z): return log(S(1) / 2 + sqrt(1 + z) / 2)