def eval_rational(self, dx=None, dy=None, n=15): """ Return a Rational approximation of ``self`` that has real and imaginary component approximations that are within ``dx`` and ``dy`` of the true values, respectively. Alternatively, ``n`` digits of precision can be specified. The interval is refined with bisection and is sure to converge. The root bounds are updated when the refinement is complete so recalculation at the same or lesser precision will not have to repeat the refinement and should be much faster. The following example first obtains Rational approximation to 1e-8 accuracy for all roots of the 4-th order Legendre polynomial. Since the roots are all less than 1, this will ensure the decimal representation of the approximation will be correct (including rounding) to 6 digits: >>> from sympy import legendre_poly, Symbol >>> x = Symbol("x") >>> p = legendre_poly(4, x, polys=True) >>> r = p.real_roots()[-1] >>> r.eval_rational(10**-8).n(6) 0.861136 It is not necessary to a two-step calculation, however: the decimal representation can be computed directly: >>> r.evalf(17) 0.86113631159405258 """ dy = dy or dx if dx: rtol = None dx = dx if isinstance(dx, Rational) else Rational(str(dx)) dy = dy if isinstance(dy, Rational) else Rational(str(dy)) else: # 5 binary (or 2 decimal) digits are needed to ensure that # a given digit is correctly rounded # prec_to_dps(dps_to_prec(n) + 5) - n <= 2 (tested for # n in range(1000000) rtol = S(10)**-(n + 2) # +2 for guard digits interval = self._get_interval() while True: if self.is_real: if rtol: dx = abs(interval.center * rtol) interval = interval.refine_size(dx=dx) c = interval.center real = Rational(c) imag = S.Zero if not rtol or interval.dx < abs(c * rtol): break elif self.is_imaginary: if rtol: dy = abs(interval.center[1] * rtol) dx = 1 interval = interval.refine_size(dx=dx, dy=dy) c = interval.center[1] imag = Rational(c) real = S.Zero if not rtol or interval.dy < abs(c * rtol): break else: if rtol: dx = abs(interval.center[0] * rtol) dy = abs(interval.center[1] * rtol) interval = interval.refine_size(dx, dy) c = interval.center real, imag = map(Rational, c) if not rtol or (interval.dx < abs(c[0] * rtol) and interval.dy < abs(c[1] * rtol)): break # update the interval so we at least (for this precision or # less) don't have much work to do to recompute the root self._set_interval(interval) return real + I * imag
def test_imag(): I = S('I') assert mcode(I) == "1i" assert mcode(5 * I) == "5i" assert mcode((S(3) / 2) * I) == "3*1i/2" assert mcode(3 + 4 * I) == "3 + 4i"
def pde_1st_linear_constant_coeff_homogeneous(eq, func, order, match, solvefun): r""" Solves a first order linear homogeneous partial differential equation with constant coefficients. The general form of this partial differential equation is .. math:: a \frac{df(x,y)}{dx} + b \frac{df(x,y)}{dy} + c f(x,y) = 0 where `a`, `b` and `c` are constants. The general solution is of the form:: >>> from sympy.solvers import pdsolve >>> from sympy.abc import x, y, a, b, c >>> from sympy import Function, pprint >>> f = Function('f') >>> u = f(x,y) >>> ux = u.diff(x) >>> uy = u.diff(y) >>> genform = a*ux + b*uy + c*u >>> pprint(genform) d d a*--(f(x, y)) + b*--(f(x, y)) + c*f(x, y) dx dy >>> pprint(pdsolve(genform)) -c*(a*x + b*y) --------------- 2 2 a + b f(x, y) = F(-a*y + b*x)*e Examples ======== >>> from sympy.solvers.pde import ( ... pde_1st_linear_constant_coeff_homogeneous) >>> from sympy import pdsolve >>> from sympy import Function, diff, pprint >>> from sympy.abc import x,y >>> f = Function('f') >>> pdsolve(f(x,y) + f(x,y).diff(x) + f(x,y).diff(y)) Eq(f(x, y), F(x - y)*exp(-x/2 - y/2)) >>> pprint(pdsolve(f(x,y) + f(x,y).diff(x) + f(x,y).diff(y))) x y - - - - 2 2 f(x, y) = F(x - y)*e References ========== - Viktor Grigoryan, "Partial Differential Equations" Math 124A - Fall 2010, pp.7 """ # TODO : For now homogeneous first order linear PDE's having # two variables are implemented. Once there is support for # solving systems of ODE's, this can be extended to n variables. f = func.func x = func.args[0] y = func.args[1] b = match[match['b']] c = match[match['c']] d = match[match['d']] return Eq( f(x, y), exp(-S(d) / (b**2 + c**2) * (b * x + c * y)) * solvefun(c * x - b * y))
def _expr_big_minus(cls, z, n): return HyperRep_asin1._expr_big_minus(z, n) \ /HyperRep_power1._expr_big_minus(S(1)/2, z, n)
def _expr_small_minus(cls, z): return log(S(1) / 2 + sqrt(1 + z) / 2)
def delta(self): """ A quantity related to the convergence region of the integral, c.f. references. """ return len(self.bm) + len(self.an) - S(len(self.ap) + len(self.bq)) / 2
def _expr_big_minus(cls, z, n): return S(-1)**n * (asinh(sqrt(z)) / sqrt(z) + n * pi * I / sqrt(z))
def gauss_gen_laguerre(n, alpha, n_digits): r""" Computes the generalized Gauss-Laguerre quadrature [1]_ points and weights. The generalized Gauss-Laguerre quadrature approximates the integral: .. math:: \int_{0}^\infty x^{\alpha} e^{-x} f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i) The nodes `x_i` of an order `n` quadrature rule are the roots of `L^{\alpha}_n` and the weights `w_i` are given by: .. math:: w_i = \frac{\Gamma(\alpha+n)}{n \Gamma(n) L^{\alpha}_{n-1}(x_i) L^{\alpha+1}_{n-1}(x_i)} Parameters ========== n : the order of quadrature alpha : the exponent of the singularity, `\alpha > -1` n_digits : number of significant digits of the points and weights to return Returns ======= (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats. The points `x_i` and weights `w_i` are returned as ``(x, w)`` tuple of lists. Examples ======== >>> from sympy import S >>> from sympy.integrals.quadrature import gauss_gen_laguerre >>> x, w = gauss_gen_laguerre(3, -S.Half, 5) >>> x [0.19016, 1.7845, 5.5253] >>> w [1.4493, 0.31413, 0.00906] >>> x, w = gauss_gen_laguerre(4, 3*S.Half, 5) >>> x [0.97851, 2.9904, 6.3193, 11.712] >>> w [0.53087, 0.67721, 0.11895, 0.0023152] See Also ======== gauss_legendre, gauss_laguerre, gauss_hermite, gauss_chebyshev_t, gauss_chebyshev_u, gauss_jacobi References ========== .. [1] http://en.wikipedia.org/wiki/Gauss%E2%80%93Laguerre_quadrature .. [2] http://people.sc.fsu.edu/~jburkardt/cpp_src/gen_laguerre_rule/gen_laguerre_rule.html """ x = Dummy("x") p = laguerre_poly(n, x, alpha=alpha, polys=True) p1 = laguerre_poly(n - 1, x, alpha=alpha, polys=True) p2 = laguerre_poly(n - 1, x, alpha=alpha + 1, polys=True) xi = [] w = [] for r in p.real_roots(): if isinstance(r, RootOf): r = r.eval_rational(S(1) / 10**(n_digits + 2)) xi.append(r.n(n_digits)) w.append((gamma(alpha + n) / (n * gamma(n) * p1.subs(x, r) * p2.subs(x, r))).n(n_digits)) return xi, w
def gauss_jacobi(n, alpha, beta, n_digits): r""" Computes the Gauss-Jacobi quadrature [1]_ points and weights. The Gauss-Jacobi quadrature of the first kind approximates the integral: .. math:: \int_{-1}^1 (1-x)^\alpha (1+x)^\beta f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i) The nodes `x_i` of an order `n` quadrature rule are the roots of `P^{(\alpha,\beta)}_n` and the weights `w_i` are given by: .. math:: w_i = -\frac{2n+\alpha+\beta+2}{n+\alpha+\beta+1}\frac{\Gamma(n+\alpha+1)\Gamma(n+\beta+1)} {\Gamma(n+\alpha+\beta+1)(n+1)!} \frac{2^{\alpha+\beta}}{P'_n(x_i) P^{(\alpha,\beta)}_{n+1}(x_i)} Parameters ========== n : the order of quadrature alpha : the first parameter of the Jacobi Polynomial, `\alpha > -1` beta : the second parameter of the Jacobi Polynomial, `\beta > -1` n_digits : number of significant digits of the points and weights to return Returns ======= (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats. The points `x_i` and weights `w_i` are returned as ``(x, w)`` tuple of lists. Examples ======== >>> from sympy import S >>> from sympy.integrals.quadrature import gauss_jacobi >>> x, w = gauss_jacobi(3, S.Half, -S.Half, 5) >>> x [-0.90097, -0.22252, 0.62349] >>> w [1.7063, 1.0973, 0.33795] >>> x, w = gauss_jacobi(6, 1, 1, 5) >>> x [-0.87174, -0.5917, -0.2093, 0.2093, 0.5917, 0.87174] >>> w [0.050584, 0.22169, 0.39439, 0.39439, 0.22169, 0.050584] See Also ======== gauss_legendre, gauss_laguerre, gauss_hermite, gauss_gen_laguerre, gauss_chebyshev_t, gauss_chebyshev_u References ========== .. [1] http://en.wikipedia.org/wiki/Gauss%E2%80%93Jacobi_quadrature .. [2] http://people.sc.fsu.edu/~jburkardt/cpp_src/jacobi_rule/jacobi_rule.html .. [3] http://people.sc.fsu.edu/~jburkardt/cpp_src/gegenbauer_rule/gegenbauer_rule.html """ x = Dummy("x") p = jacobi_poly(n, alpha, beta, x, polys=True) pd = p.diff(x) pn = jacobi_poly(n + 1, alpha, beta, x, polys=True) xi = [] w = [] for r in p.real_roots(): if isinstance(r, RootOf): r = r.eval_rational(S(1) / 10**(n_digits + 2)) xi.append(r.n(n_digits)) w.append( (-(2 * n + alpha + beta + 2) / (n + alpha + beta + S.One) * (gamma(n + alpha + 1) * gamma(n + beta + 1)) / (gamma(n + alpha + beta + S.One) * gamma(n + 2)) * 2**(alpha + beta) / (pd.subs(x, r) * pn.subs(x, r))).n(n_digits)) return xi, w
def gauss_legendre(n, n_digits): r""" Computes the Gauss-Legendre quadrature [1]_ points and weights. The Gauss-Legendre quadrature approximates the integral: .. math:: \int_{-1}^1 f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i) The nodes `x_i` of an order `n` quadrature rule are the roots of `P_n` and the weights `w_i` are given by: .. math:: w_i = \frac{2}{\left(1-x_i^2\right) \left(P'_n(x_i)\right)^2} Parameters ========== n : the order of quadrature n_digits : number of significant digits of the points and weights to return Returns ======= (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats. The points `x_i` and weights `w_i` are returned as ``(x, w)`` tuple of lists. Examples ======== >>> from sympy.integrals.quadrature import gauss_legendre >>> x, w = gauss_legendre(3, 5) >>> x [-0.7746, 0, 0.7746] >>> w [0.55556, 0.88889, 0.55556] >>> x, w = gauss_legendre(4, 5) >>> x [-0.86114, -0.33998, 0.33998, 0.86114] >>> w [0.34786, 0.65215, 0.65215, 0.34786] See Also ======== gauss_laguerre, gauss_gen_laguerre, gauss_hermite, gauss_chebyshev_t, gauss_chebyshev_u, gauss_jacobi References ========== .. [1] http://en.wikipedia.org/wiki/Gaussian_quadrature .. [2] http://people.sc.fsu.edu/~jburkardt/cpp_src/legendre_rule/legendre_rule.html """ x = Dummy("x") p = legendre_poly(n, x, polys=True) pd = p.diff(x) xi = [] w = [] for r in p.real_roots(): if isinstance(r, RootOf): r = r.eval_rational(S(1) / 10**(n_digits + 2)) xi.append(r.n(n_digits)) w.append((2 / ((1 - r**2) * pd.subs(x, r)**2)).n(n_digits)) return xi, w
def gauss_hermite(n, n_digits): r""" Computes the Gauss-Hermite quadrature [1]_ points and weights. The Gauss-Hermite quadrature approximates the integral: .. math:: \int_{-\infty}^{\infty} e^{-x^2} f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i) The nodes `x_i` of an order `n` quadrature rule are the roots of `H_n` and the weights `w_i` are given by: .. math:: w_i = \frac{2^{n-1} n! \sqrt{\pi}}{n^2 \left(H_{n-1}(x_i)\right)^2} Parameters ========== n : the order of quadrature n_digits : number of significant digits of the points and weights to return Returns ======= (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats. The points `x_i` and weights `w_i` are returned as ``(x, w)`` tuple of lists. Examples ======== >>> from sympy.integrals.quadrature import gauss_hermite >>> x, w = gauss_hermite(3, 5) >>> x [-1.2247, 0, 1.2247] >>> w [0.29541, 1.1816, 0.29541] >>> x, w = gauss_hermite(6, 5) >>> x [-2.3506, -1.3358, -0.43608, 0.43608, 1.3358, 2.3506] >>> w [0.00453, 0.15707, 0.72463, 0.72463, 0.15707, 0.00453] See Also ======== gauss_legendre, gauss_laguerre, gauss_gen_laguerre, gauss_chebyshev_t, gauss_chebyshev_u, gauss_jacobi References ========== .. [1] http://en.wikipedia.org/wiki/Gauss-Hermite_Quadrature .. [2] http://people.sc.fsu.edu/~jburkardt/cpp_src/hermite_rule/hermite_rule.html .. [3] http://people.sc.fsu.edu/~jburkardt/cpp_src/gen_hermite_rule/gen_hermite_rule.html """ x = Dummy("x") p = hermite_poly(n, x, polys=True) p1 = hermite_poly(n - 1, x, polys=True) xi = [] w = [] for r in p.real_roots(): if isinstance(r, RootOf): r = r.eval_rational(S(1) / 10**(n_digits + 2)) xi.append(r.n(n_digits)) w.append(((2**(n - 1) * factorial(n) * sqrt(pi)) / (n**2 * p1.subs(x, r)**2)).n(n_digits)) return xi, w
def test_deltasummation(): ds = deltasummation assert ds(x, (j, 1, 0)) == 0 assert ds(x, (j, 1, 3)) == 3*x assert ds(x + y, (j, 1, 3)) == 3*(x + y) assert ds(x*y, (j, 1, 3)) == 3*x*y assert ds(KD(i, j), (k, 1, 3)) == 3*KD(i, j) assert ds(x*KD(i, j), (k, 1, 3)) == 3*x*KD(i, j) assert ds(x*y*KD(i, j), (k, 1, 3)) == 3*x*y*KD(i, j) n = symbols('n', integer=True, nonzero=True) assert ds(KD(n, 0), (n, 1, 3)) == 0 # return unevaluated, until it gets implemented assert ds(KD(i**2, j**2), (j, -oo, oo)) == \ Sum(KD(i**2, j**2), (j, -oo, oo)) assert Piecewise((KD(i, k), And(S(1) <= i, i <= 3)), (0, True)) == \ ds(KD(i, j)*KD(j, k), (j, 1, 3)) == \ ds(KD(j, k)*KD(i, j), (j, 1, 3)) assert ds(KD(i, k), (k, -oo, oo)) == 1 assert ds(KD(i, k), (k, 0, oo)) == Piecewise((1, i >= 0), (0, True)) assert ds(KD(i, k), (k, 1, 3)) == \ Piecewise((1, And(S(1) <= i, i <= 3)), (0, True)) assert ds(k*KD(i, j)*KD(j, k), (k, -oo, oo)) == j*KD(i, j) assert ds(j*KD(i, j), (j, -oo, oo)) == i assert ds(i*KD(i, j), (i, -oo, oo)) == j assert ds(x, (i, 1, 3)) == 3*x assert ds((i + j)*KD(i, j), (j, -oo, oo)) == 2*i assert ds(KD(i, j), (j, 1, 3)) == \ Piecewise((1, And(S(1) <= i, i <= 3)), (0, True)) assert ds(KD(i, j), (j, 1, 1)) == Piecewise((1, Eq(i, 1)), (0, True)) assert ds(KD(i, j), (j, 2, 2)) == Piecewise((1, Eq(i, 2)), (0, True)) assert ds(KD(i, j), (j, 3, 3)) == Piecewise((1, Eq(i, 3)), (0, True)) assert ds(KD(i, j), (j, 1, k)) == \ Piecewise((1, And(S(1) <= i, i <= k)), (0, True)) assert ds(KD(i, j), (j, k, 3)) == \ Piecewise((1, And(k <= i, i <= 3)), (0, True)) assert ds(KD(i, j), (j, k, l)) == \ Piecewise((1, And(k <= i, i <= l)), (0, True)) assert ds(x*KD(i, j), (j, 1, 3)) == \ Piecewise((x, And(S(1) <= i, i <= 3)), (0, True)) assert ds(x*KD(i, j), (j, 1, 1)) == Piecewise((x, Eq(i, 1)), (0, True)) assert ds(x*KD(i, j), (j, 2, 2)) == Piecewise((x, Eq(i, 2)), (0, True)) assert ds(x*KD(i, j), (j, 3, 3)) == Piecewise((x, Eq(i, 3)), (0, True)) assert ds(x*KD(i, j), (j, 1, k)) == \ Piecewise((x, And(S(1) <= i, i <= k)), (0, True)) assert ds(x*KD(i, j), (j, k, 3)) == \ Piecewise((x, And(k <= i, i <= 3)), (0, True)) assert ds(x*KD(i, j), (j, k, l)) == \ Piecewise((x, And(k <= i, i <= l)), (0, True)) assert ds((x + y)*KD(i, j), (j, 1, 3)) == \ Piecewise((x + y, And(S(1) <= i, i <= 3)), (0, True)) assert ds((x + y)*KD(i, j), (j, 1, 1)) == \ Piecewise((x + y, Eq(i, 1)), (0, True)) assert ds((x + y)*KD(i, j), (j, 2, 2)) == \ Piecewise((x + y, Eq(i, 2)), (0, True)) assert ds((x + y)*KD(i, j), (j, 3, 3)) == \ Piecewise((x + y, Eq(i, 3)), (0, True)) assert ds((x + y)*KD(i, j), (j, 1, k)) == \ Piecewise((x + y, And(S(1) <= i, i <= k)), (0, True)) assert ds((x + y)*KD(i, j), (j, k, 3)) == \ Piecewise((x + y, And(k <= i, i <= 3)), (0, True)) assert ds((x + y)*KD(i, j), (j, k, l)) == \ Piecewise((x + y, And(k <= i, i <= l)), (0, True)) assert ds(KD(i, k) + KD(j, k), (k, 1, 3)) == piecewise_fold( Piecewise((1, And(S(1) <= i, i <= 3)), (0, True)) + Piecewise((1, And(S(1) <= j, j <= 3)), (0, True))) assert ds(KD(i, k) + KD(j, k), (k, 1, 1)) == piecewise_fold( Piecewise((1, Eq(i, 1)), (0, True)) + Piecewise((1, Eq(j, 1)), (0, True))) assert ds(KD(i, k) + KD(j, k), (k, 2, 2)) == piecewise_fold( Piecewise((1, Eq(i, 2)), (0, True)) + Piecewise((1, Eq(j, 2)), (0, True))) assert ds(KD(i, k) + KD(j, k), (k, 3, 3)) == piecewise_fold( Piecewise((1, Eq(i, 3)), (0, True)) + Piecewise((1, Eq(j, 3)), (0, True))) assert ds(KD(i, k) + KD(j, k), (k, 1, l)) == piecewise_fold( Piecewise((1, And(S(1) <= i, i <= l)), (0, True)) + Piecewise((1, And(S(1) <= j, j <= l)), (0, True))) assert ds(KD(i, k) + KD(j, k), (k, l, 3)) == piecewise_fold( Piecewise((1, And(l <= i, i <= 3)), (0, True)) + Piecewise((1, And(l <= j, j <= 3)), (0, True))) assert ds(KD(i, k) + KD(j, k), (k, l, m)) == piecewise_fold( Piecewise((1, And(l <= i, i <= m)), (0, True)) + Piecewise((1, And(l <= j, j <= m)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, 1, 3)) == piecewise_fold( Piecewise((x, And(S(1) <= i, i <= 3)), (0, True)) + Piecewise((1, And(S(1) <= j, j <= 3)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, 1, 1)) == piecewise_fold( Piecewise((x, Eq(i, 1)), (0, True)) + Piecewise((1, Eq(j, 1)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, 2, 2)) == piecewise_fold( Piecewise((x, Eq(i, 2)), (0, True)) + Piecewise((1, Eq(j, 2)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, 3, 3)) == piecewise_fold( Piecewise((x, Eq(i, 3)), (0, True)) + Piecewise((1, Eq(j, 3)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, 1, l)) == piecewise_fold( Piecewise((x, And(S(1) <= i, i <= l)), (0, True)) + Piecewise((1, And(S(1) <= j, j <= l)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, l, 3)) == piecewise_fold( Piecewise((x, And(l <= i, i <= 3)), (0, True)) + Piecewise((1, And(l <= j, j <= 3)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, l, m)) == piecewise_fold( Piecewise((x, And(l <= i, i <= m)), (0, True)) + Piecewise((1, And(l <= j, j <= m)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, 1, 3)) == piecewise_fold( Piecewise((x, And(S(1) <= i, i <= 3)), (0, True)) + Piecewise((x, And(S(1) <= j, j <= 3)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, 1, 1)) == piecewise_fold( Piecewise((x, Eq(i, 1)), (0, True)) + Piecewise((x, Eq(j, 1)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, 2, 2)) == piecewise_fold( Piecewise((x, Eq(i, 2)), (0, True)) + Piecewise((x, Eq(j, 2)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, 3, 3)) == piecewise_fold( Piecewise((x, Eq(i, 3)), (0, True)) + Piecewise((x, Eq(j, 3)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, 1, l)) == piecewise_fold( Piecewise((x, And(S(1) <= i, i <= l)), (0, True)) + Piecewise((x, And(S(1) <= j, j <= l)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, l, 3)) == piecewise_fold( Piecewise((x, And(l <= i, i <= 3)), (0, True)) + Piecewise((x, And(l <= j, j <= 3)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, l, m)) == piecewise_fold( Piecewise((x, And(l <= i, i <= m)), (0, True)) + Piecewise((x, And(l <= j, j <= m)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, 1, 3)) == piecewise_fold( Piecewise((x + y, And(S(1) <= i, i <= 3)), (0, True)) + Piecewise((x + y, And(S(1) <= j, j <= 3)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, 1, 1)) == piecewise_fold( Piecewise((x + y, Eq(i, 1)), (0, True)) + Piecewise((x + y, Eq(j, 1)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, 2, 2)) == piecewise_fold( Piecewise((x + y, Eq(i, 2)), (0, True)) + Piecewise((x + y, Eq(j, 2)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, 3, 3)) == piecewise_fold( Piecewise((x + y, Eq(i, 3)), (0, True)) + Piecewise((x + y, Eq(j, 3)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, 1, l)) == piecewise_fold( Piecewise((x + y, And(S(1) <= i, i <= l)), (0, True)) + Piecewise((x + y, And(S(1) <= j, j <= l)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, l, 3)) == piecewise_fold( Piecewise((x + y, And(l <= i, i <= 3)), (0, True)) + Piecewise((x + y, And(l <= j, j <= 3)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, l, m)) == piecewise_fold( Piecewise((x + y, And(l <= i, i <= m)), (0, True)) + Piecewise((x + y, And(l <= j, j <= m)), (0, True))) assert ds(x*y + x*KD(i, j), (j, 1, 3)) == \ Piecewise((3*x*y + x, And(S(1) <= i, i <= 3)), (3*x*y, True)) assert ds(x*y + x*KD(i, j), (j, 1, 1)) == \ Piecewise((x*y + x, Eq(i, 1)), (x*y, True)) assert ds(x*y + x*KD(i, j), (j, 2, 2)) == \ Piecewise((x*y + x, Eq(i, 2)), (x*y, True)) assert ds(x*y + x*KD(i, j), (j, 3, 3)) == \ Piecewise((x*y + x, Eq(i, 3)), (x*y, True)) assert ds(x*y + x*KD(i, j), (j, 1, k)) == \ Piecewise((k*x*y + x, And(S(1) <= i, i <= k)), (k*x*y, True)) assert ds(x*y + x*KD(i, j), (j, k, 3)) == \ Piecewise(((4 - k)*x*y + x, And(k <= i, i <= 3)), ((4 - k)*x*y, True)) assert ds(x*y + x*KD(i, j), (j, k, l)) == Piecewise( ((l - k + 1)*x*y + x, And(k <= i, i <= l)), ((l - k + 1)*x*y, True)) assert ds(x*(y + KD(i, j)), (j, 1, 3)) == \ Piecewise((3*x*y + x, And(S(1) <= i, i <= 3)), (3*x*y, True)) assert ds(x*(y + KD(i, j)), (j, 1, 1)) == \ Piecewise((x*y + x, Eq(i, 1)), (x*y, True)) assert ds(x*(y + KD(i, j)), (j, 2, 2)) == \ Piecewise((x*y + x, Eq(i, 2)), (x*y, True)) assert ds(x*(y + KD(i, j)), (j, 3, 3)) == \ Piecewise((x*y + x, Eq(i, 3)), (x*y, True)) assert ds(x*(y + KD(i, j)), (j, 1, k)) == \ Piecewise((k*x*y + x, And(S(1) <= i, i <= k)), (k*x*y, True)) assert ds(x*(y + KD(i, j)), (j, k, 3)) == \ Piecewise(((4 - k)*x*y + x, And(k <= i, i <= 3)), ((4 - k)*x*y, True)) assert ds(x*(y + KD(i, j)), (j, k, l)) == Piecewise( ((l - k + 1)*x*y + x, And(k <= i, i <= l)), ((l - k + 1)*x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, 1, 3)) == \ Piecewise((3*x*y + 2*x, And(S(1) <= i, i <= 3)), (3*x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, 1, 1)) == \ Piecewise((x*y + 2*x, Eq(i, 1)), (x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, 2, 2)) == \ Piecewise((x*y + 2*x, Eq(i, 2)), (x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, 3, 3)) == \ Piecewise((x*y + 2*x, Eq(i, 3)), (x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, 1, k)) == \ Piecewise((k*x*y + 2*x, And(S(1) <= i, i <= k)), (k*x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, k, 3)) == Piecewise( ((4 - k)*x*y + 2*x, And(k <= i, i <= 3)), ((4 - k)*x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, k, l)) == Piecewise( ((l - k + 1)*x*y + 2*x, And(k <= i, i <= l)), ((l - k + 1)*x*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, 1, 3)) == Piecewise( (3*(x + y)*y + x + y, And(S(1) <= i, i <= 3)), (3*(x + y)*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, 1, 1)) == \ Piecewise(((x + y)*y + x + y, Eq(i, 1)), ((x + y)*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, 2, 2)) == \ Piecewise(((x + y)*y + x + y, Eq(i, 2)), ((x + y)*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, 3, 3)) == \ Piecewise(((x + y)*y + x + y, Eq(i, 3)), ((x + y)*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, 1, k)) == Piecewise( (k*(x + y)*y + x + y, And(S(1) <= i, i <= k)), (k*(x + y)*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, k, 3)) == Piecewise( ((4 - k)*(x + y)*y + x + y, And(k <= i, i <= 3)), ((4 - k)*(x + y)*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, k, l)) == Piecewise( ((l - k + 1)*(x + y)*y + x + y, And(k <= i, i <= l)), ((l - k + 1)*(x + y)*y, True)) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 1, 3)) == piecewise_fold( Piecewise((KD(i, k) + x, And(S(1) <= i, i <= 3)), (0, True)) + 3*(KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 1, 1)) == piecewise_fold( Piecewise((KD(i, k) + x, Eq(i, 1)), (0, True)) + (KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 2, 2)) == piecewise_fold( Piecewise((KD(i, k) + x, Eq(i, 2)), (0, True)) + (KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 3, 3)) == piecewise_fold( Piecewise((KD(i, k) + x, Eq(i, 3)), (0, True)) + (KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 1, k)) == piecewise_fold( Piecewise((KD(i, k) + x, And(S(1) <= i, i <= k)), (0, True)) + k*(KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, k, 3)) == piecewise_fold( Piecewise((KD(i, k) + x, And(k <= i, i <= 3)), (0, True)) + (4 - k)*(KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, k, l)) == piecewise_fold( Piecewise((KD(i, k) + x, And(k <= i, i <= l)), (0, True)) + (l - k + 1)*(KD(i, k) + x)*y)
def equivalence_hypergeometric(A, B, func): # This method for finding the equivalence is only for 2F1 type. # We can extend it for 1F1 and 0F1 type also. x = func.args[0] # making given equation in normal form I1 = factor(cancel(A.diff(x) / 2 + A**2 / 4 - B)) # computing shifted invariant(J1) of the equation J1 = factor(cancel(x**2 * I1 + S(1) / 4)) num, dem = J1.as_numer_denom() num = powdenest(expand(num)) dem = powdenest(expand(dem)) # this function will compute the different powers of variable(x) in J1. # then it will help in finding value of k. k is power of x such that we can express # J1 = x**k * J0(x**k) then all the powers in J0 become integers. def _power_counting(num): _pow = {0} for val in num: if val.has(x): if isinstance(val, Pow) and val.as_base_exp()[0] == x: _pow.add(val.as_base_exp()[1]) elif val == x: _pow.add(val.as_base_exp()[1]) else: _pow.update(_power_counting(val.args)) return _pow pow_num = _power_counting((num, )) pow_dem = _power_counting((dem, )) pow_dem.update(pow_num) _pow = pow_dem k = gcd(_pow) # computing I0 of the given equation I0 = powdenest(simplify(factor(((J1 / k**2) - S(1) / 4) / ((x**k)**2))), force=True) I0 = factor(cancel(powdenest(I0.subs(x, x**(S(1) / k)), force=True))) # Before this point I0, J1 might be functions of e.g. sqrt(x) but replacing # x with x**(1/k) should result in I0 being a rational function of x or # otherwise the hypergeometric solver cannot be used. Note that k can be a # non-integer rational such as 2/7. if not I0.is_rational_function(x): return None num, dem = I0.as_numer_denom() max_num_pow = max(_power_counting((num, ))) dem_args = dem.args sing_point = [] dem_pow = [] # calculating singular point of I0. for arg in dem_args: if arg.has(x): if isinstance(arg, Pow): # (x-a)**n dem_pow.append(arg.as_base_exp()[1]) sing_point.append( list(roots(arg.as_base_exp()[0], x).keys())[0]) else: # (x-a) type dem_pow.append(arg.as_base_exp()[1]) sing_point.append(list(roots(arg, x).keys())[0]) dem_pow.sort() # checking if equivalence is exists or not. if equivalence(max_num_pow, dem_pow) == "2F1": return {'I0': I0, 'k': k, 'sing_point': sing_point, 'type': "2F1"} else: return None
def test_one_is_composite(): assert S(1).is_composite is False
def roots_quintic(f): """ Calculate exact roots of a solvable quintic """ result = [] coeff_5, coeff_4, p, q, r, s = f.all_coeffs() # Eqn must be of the form x^5 + px^3 + qx^2 + rx + s if coeff_4: return result if coeff_5 != 1: l = [p / coeff_5, q / coeff_5, r / coeff_5, s / coeff_5] if not all(coeff.is_Rational for coeff in l): return result f = Poly(f / coeff_5) elif not all(coeff.is_Rational for coeff in (p, q, r, s)): return result quintic = PolyQuintic(f) # Eqn standardized. Algo for solving starts here if not f.is_irreducible: return result f20 = quintic.f20 # Check if f20 has linear factors over domain Z if f20.is_irreducible: return result # Now, we know that f is solvable for _factor in f20.factor_list()[1]: if _factor[0].is_linear: theta = _factor[0].root(0) break d = discriminant(f) delta = sqrt(d) # zeta = a fifth root of unity zeta1, zeta2, zeta3, zeta4 = quintic.zeta T = quintic.T(theta, d) tol = S(1e-10) alpha = T[1] + T[2] * delta alpha_bar = T[1] - T[2] * delta beta = T[3] + T[4] * delta beta_bar = T[3] - T[4] * delta disc = alpha**2 - 4 * beta disc_bar = alpha_bar**2 - 4 * beta_bar l0 = quintic.l0(theta) Stwo = S(2) l1 = _quintic_simplify((-alpha + sqrt(disc)) / Stwo) l4 = _quintic_simplify((-alpha - sqrt(disc)) / Stwo) l2 = _quintic_simplify((-alpha_bar + sqrt(disc_bar)) / Stwo) l3 = _quintic_simplify((-alpha_bar - sqrt(disc_bar)) / Stwo) order = quintic.order(theta, d) test = (order * delta.n()) - ((l1.n() - l4.n()) * (l2.n() - l3.n())) # Comparing floats if not comp(test, 0, tol): l2, l3 = l3, l2 # Now we have correct order of l's R1 = l0 + l1 * zeta1 + l2 * zeta2 + l3 * zeta3 + l4 * zeta4 R2 = l0 + l3 * zeta1 + l1 * zeta2 + l4 * zeta3 + l2 * zeta4 R3 = l0 + l2 * zeta1 + l4 * zeta2 + l1 * zeta3 + l3 * zeta4 R4 = l0 + l4 * zeta1 + l3 * zeta2 + l2 * zeta3 + l1 * zeta4 Res = [None, [None] * 5, [None] * 5, [None] * 5, [None] * 5] Res_n = [None, [None] * 5, [None] * 5, [None] * 5, [None] * 5] sol = Symbol('sol') # Simplifying improves performance a lot for exact expressions R1 = _quintic_simplify(R1) R2 = _quintic_simplify(R2) R3 = _quintic_simplify(R3) R4 = _quintic_simplify(R4) # Solve imported here. Causing problems if imported as 'solve' # and hence the changed name from sympy.solvers.solvers import solve as _solve a, b = symbols('a b', cls=Dummy) _sol = _solve(sol**5 - a - I * b, sol) for i in range(5): _sol[i] = factor(_sol[i]) R1 = R1.as_real_imag() R2 = R2.as_real_imag() R3 = R3.as_real_imag() R4 = R4.as_real_imag() for i, currentroot in enumerate(_sol): Res[1][i] = _quintic_simplify(currentroot.subs({a: R1[0], b: R1[1]})) Res[2][i] = _quintic_simplify(currentroot.subs({a: R2[0], b: R2[1]})) Res[3][i] = _quintic_simplify(currentroot.subs({a: R3[0], b: R3[1]})) Res[4][i] = _quintic_simplify(currentroot.subs({a: R4[0], b: R4[1]})) for i in range(1, 5): for j in range(5): Res_n[i][j] = Res[i][j].n() Res[i][j] = _quintic_simplify(Res[i][j]) r1 = Res[1][0] r1_n = Res_n[1][0] for i in range(5): if comp(im(r1_n * Res_n[4][i]), 0, tol): r4 = Res[4][i] break # Now we have various Res values. Each will be a list of five # values. We have to pick one r value from those five for each Res u, v = quintic.uv(theta, d) testplus = (u + v * delta * sqrt(5)).n() testminus = (u - v * delta * sqrt(5)).n() # Evaluated numbers suffixed with _n # We will use evaluated numbers for calculation. Much faster. r4_n = r4.n() r2 = r3 = None for i in range(5): r2temp_n = Res_n[2][i] for j in range(5): # Again storing away the exact number and using # evaluated numbers in computations r3temp_n = Res_n[3][j] if (comp((r1_n * r2temp_n**2 + r4_n * r3temp_n**2 - testplus).n(), 0, tol) and comp( (r3temp_n * r1_n**2 + r2temp_n * r4_n**2 - testminus).n(), 0, tol)): r2 = Res[2][i] r3 = Res[3][j] break if r2: break else: return [] # fall back to normal solve # Now, we have r's so we can get roots x1 = (r1 + r2 + r3 + r4) / 5 x2 = (r1 * zeta4 + r2 * zeta3 + r3 * zeta2 + r4 * zeta1) / 5 x3 = (r1 * zeta3 + r2 * zeta1 + r3 * zeta4 + r4 * zeta2) / 5 x4 = (r1 * zeta2 + r2 * zeta4 + r3 * zeta1 + r4 * zeta3) / 5 x5 = (r1 * zeta1 + r2 * zeta2 + r3 * zeta3 + r4 * zeta4) / 5 result = [x1, x2, x3, x4, x5] # Now check if solutions are distinct saw = set() for r in result: r = r.n(2) if r in saw: # Roots were identical. Abort, return [] # and fall back to usual solve return [] saw.add(r) return result
def gauss_laguerre(n, n_digits): r""" Computes the Gauss-Laguerre quadrature [1]_ points and weights. The Gauss-Laguerre quadrature approximates the integral: .. math:: \int_0^{\infty} e^{-x} f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i) The nodes `x_i` of an order `n` quadrature rule are the roots of `L_n` and the weights `w_i` are given by: .. math:: w_i = \frac{x_i}{(n+1)^2 \left(L_{n+1}(x_i)\right)^2} Parameters ========== n : the order of quadrature n_digits : number of significant digits of the points and weights to return Returns ======= (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats. The points `x_i` and weights `w_i` are returned as ``(x, w)`` tuple of lists. Examples ======== >>> from sympy.integrals.quadrature import gauss_laguerre >>> x, w = gauss_laguerre(3, 5) >>> x [0.41577, 2.2943, 6.2899] >>> w [0.71109, 0.27852, 0.010389] >>> x, w = gauss_laguerre(6, 5) >>> x [0.22285, 1.1889, 2.9927, 5.7751, 9.8375, 15.983] >>> w [0.45896, 0.417, 0.11337, 0.010399, 0.00026102, 8.9855e-7] See Also ======== gauss_legendre, gauss_gen_laguerre, gauss_hermite, gauss_chebyshev_t, gauss_chebyshev_u, gauss_jacobi References ========== .. [1] http://en.wikipedia.org/wiki/Gauss%E2%80%93Laguerre_quadrature .. [2] http://people.sc.fsu.edu/~jburkardt/cpp_src/laguerre_rule/laguerre_rule.html """ x = Dummy("x") p = laguerre_poly(n, x, polys=True) p1 = laguerre_poly(n + 1, x, polys=True) xi = [] w = [] for r in p.real_roots(): if isinstance(r, RootOf): r = r.eval_rational(S(1) / 10**(n_digits + 2)) xi.append(r.n(n_digits)) w.append((r / ((n + 1)**2 * p1.subs(x, r)**2)).n(n_digits)) return xi, w
def gosper_term(f, n): r""" Compute Gosper's hypergeometric term for ``f``. Suppose ``f`` is a hypergeometric term such that: .. math:: s_n = \sum_{k=0}^{n-1} f_k and `f_k` doesn't depend on `n`. Returns a hypergeometric term `g_n` such that `g_{n+1} - g_n = f_n`. Examples ======== >>> from sympy.concrete.gosper import gosper_term >>> from sympy.functions import factorial >>> from sympy.abc import n >>> gosper_term((4*n + 1)*factorial(n)/factorial(2*n + 1), n) (-n - 1/2)/(n + 1/4) """ r = hypersimp(f, n) if r is None: return None # 'f' is *not* a hypergeometric term p, q = r.as_numer_denom() A, B, C = gosper_normal(p, q, n) B = B.shift(-1) N = S(A.degree()) M = S(B.degree()) K = S(C.degree()) if (N != M) or (A.LC() != B.LC()): D = set([K - max(N, M)]) elif not N: D = set([K - N + 1, S(0)]) else: D = set([K - N + 1, (B.nth(N - 1) - A.nth(N - 1))/A.LC()]) for d in set(D): if not d.is_Integer or d < 0: D.remove(d) if not D: return None # 'f(n)' is *not* Gosper-summable d = max(D) coeffs = symbols('c:%s' % (d + 1), cls=Dummy) domain = A.get_domain().inject(*coeffs) x = Poly(coeffs, n, domain=domain) H = A*x.shift(1) - B*x - C solution = solve(H.coeffs(), coeffs) if solution is None: return None # 'f(n)' is *not* Gosper-summable x = x.as_expr().subs(solution) for coeff in coeffs: if coeff not in solution: x = x.subs(coeff, 0) if x is S.Zero: return None # 'f(n)' is *not* Gosper-summable else: return B.as_expr()*x/C.as_expr()
def apart_full_decomposition(P, Q): """ Bronstein's full partial fraction decomposition algorithm. Given a univariate rational function ``f``, performing only GCD operations over the algebraic closure of the initial ground domain of definition, compute full partial fraction decomposition with fractions having linear denominators. Note that no factorization of the initial denominator of ``f`` is performed. The final decomposition is formed in terms of a sum of :class:`RootSum` instances. **References** 1. [Bronstein93]_ """ f, x, U = P/Q, P.gen, [] u = Function('u')(x) a = Dummy('a') partial = S(0) for d, n in Q.sqf_list_include(all=True): b = d.as_expr() U += [ u.diff(x, n-1) ] h = cancel(f*b**n) / u**n H, subs = [h], [] for j in range(1, n): H += [ H[-1].diff(x) / j ] for j in range(1, n+1): subs += [ (U[j-1], b.diff(x, j) / j) ] for j in range(0, n): P, Q = cancel(H[j]).as_numer_denom() for i in range(0, j+1): P = P.subs(*subs[j-i]) Q = Q.subs(*subs[0]) P = Poly(P, x) Q = Poly(Q, x) G = P.gcd(d) D = d.quo(G) B, g = Q.half_gcdex(D) b = (P * B.quo(g)).rem(D) numer = b.as_expr() denom = (x-a)**(n-j) func = Lambda(a, numer.subs(x, a)/denom) partial += RootSum(D, func, auto=False) return partial
def _expr_big(cls, z, n): return S(-1)**n * ( (S(1) / 2 - n) * pi / sqrt(z) + I * acosh(sqrt(z)) / sqrt(z))
def _expr_big(cls, z, n): if n.is_even: return (n - S(1)/2)*pi*I + log(sqrt(z)/2) + I*asin(1/sqrt(z)) else: return (n - S(1)/2)*pi*I + log(sqrt(z)/2) - I*asin(1/sqrt(z))
def _expr_small_minus(cls, z): return HyperRep_asin1._expr_small_minus(z) \ /HyperRep_power1._expr_small_minus(S(1)/2, z)
def test_del_operator(): # Tests for curl assert delop ^ Vector.zero == Vector.zero assert ((delop ^ Vector.zero).doit() == Vector.zero == curl(Vector.zero)) assert delop.cross(Vector.zero) == delop ^ Vector.zero assert (delop ^ i).doit() == Vector.zero assert delop.cross(2 * y**2 * j, doit=True) == Vector.zero assert delop.cross(2 * y**2 * j) == delop ^ 2 * y**2 * j v = x * y * z * (i + j + k) assert ((delop ^ v).doit() == (-x * y + x * z) * i + (x * y - y * z) * j + (-x * z + y * z) * k == curl(v)) assert delop ^ v == delop.cross(v) assert (delop.cross( 2 * x**2 * j) == (Derivative(0, C.y) - Derivative(2 * C.x**2, C.z)) * C.i + (-Derivative(0, C.x) + Derivative(0, C.z)) * C.j + (-Derivative(0, C.y) + Derivative(2 * C.x**2, C.x)) * C.k) assert (delop.cross(2 * x**2 * j, doit=True) == 4 * x * k == curl( 2 * x**2 * j)) #Tests for divergence assert delop & Vector.zero == S(0) == divergence(Vector.zero) assert (delop & Vector.zero).doit() == S(0) assert delop.dot(Vector.zero) == delop & Vector.zero assert (delop & i).doit() == S(0) assert (delop & x**2 * i).doit() == 2 * x == divergence(x**2 * i) assert (delop.dot(v, doit=True) == x * y + y * z + z * x == divergence(v)) assert delop & v == delop.dot(v) assert delop.dot(1/(x*y*z) * (i + j + k), doit=True) == \ - 1 / (x*y*z**2) - 1 / (x*y**2*z) - 1 / (x**2*y*z) v = x * i + y * j + z * k assert (delop & v == Derivative(C.x, C.x) + Derivative(C.y, C.y) + Derivative(C.z, C.z)) assert delop.dot(v, doit=True) == 3 == divergence(v) assert delop & v == delop.dot(v) assert simplify((delop & v).doit()) == 3 #Tests for gradient assert (delop.gradient(0, doit=True) == Vector.zero == gradient(0)) assert delop.gradient(0) == delop(0) assert (delop(S(0))).doit() == Vector.zero assert (delop(x) == (Derivative(C.x, C.x)) * C.i + (Derivative(C.x, C.y)) * C.j + (Derivative(C.x, C.z)) * C.k) assert (delop(x)).doit() == i == gradient(x) assert (delop(x * y * z) == (Derivative(C.x * C.y * C.z, C.x)) * C.i + (Derivative(C.x * C.y * C.z, C.y)) * C.j + (Derivative(C.x * C.y * C.z, C.z)) * C.k) assert (delop.gradient(x * y * z, doit=True) == y * z * i + z * x * j + x * y * k == gradient(x * y * z)) assert delop(x * y * z) == delop.gradient(x * y * z) assert (delop(2 * x**2)).doit() == 4 * x * i assert ((delop(a * sin(y) / x)).doit() == -a * sin(y) / x**2 * i + a * cos(y) / x * j) #Tests for directional derivative assert (Vector.zero & delop)(a) == S(0) assert ((Vector.zero & delop)(a)).doit() == S(0) assert ((v & delop)(Vector.zero)).doit() == Vector.zero assert ((v & delop)(S(0))).doit() == S(0) assert ((i & delop)(x)).doit() == 1 assert ((j & delop)(y)).doit() == 1 assert ((k & delop)(z)).doit() == 1 assert ((i & delop)(x * y * z)).doit() == y * z assert ((v & delop)(x)).doit() == x assert ((v & delop)(x * y * z)).doit() == 3 * x * y * z assert (v & delop)(x + y + z) == C.x + C.y + C.z assert ((v & delop)(x + y + z)).doit() == x + y + z assert ((v & delop)(v)).doit() == v assert ((i & delop)(v)).doit() == i assert ((j & delop)(v)).doit() == j assert ((k & delop)(v)).doit() == k assert ((v & delop)(Vector.zero)).doit() == Vector.zero
def _expr_small(cls, z): return log(S(1) / 2 + sqrt(1 - z) / 2)
def test_linrec(): assert linrec(coeffs=[1, 1], init=[1, 1], n=20) == 10946 assert linrec(coeffs=[1, 2, 3, 4, 5], init=[1, 1, 0, 2], n=10) == 1040 assert linrec(coeffs=[0, 0, 11, 13], init=[23, 27], n=25) == 59628567384 assert linrec(coeffs=[0, 0, 1, 1, 2], init=[1, 5, 3], n=15) == 165 assert linrec(coeffs=[11, 13, 15, 17], init=[1, 2, 3, 4], n=70) == \ 56889923441670659718376223533331214868804815612050381493741233489928913241 assert linrec(coeffs=[0]*55 + [1, 1, 2, 3], init=[0]*50 + [1, 2, 3], n=4000) == \ 702633573874937994980598979769135096432444135301118916539 assert linrec(coeffs=[11, 13, 15, 17], init=[1, 2, 3, 4], n=10**4) assert linrec(coeffs=[11, 13, 15, 17], init=[1, 2, 3, 4], n=10**5) assert all( linrec(coeffs=[1, 1], init=[0, 1], n=n) == fibonacci(n) for n in range(95, 115)) assert all( linrec(coeffs=[1, 1], init=[1, 1], n=n) == fibonacci(n + 1) for n in range(595, 615)) a = [S(1) / 2, S(3) / 4, S(5) / 6, 7, S(8) / 9, S(3) / 5] b = [1, 2, 8, S(5) / 7, S(3) / 7, S(2) / 9, 6] x, y, z = symbols('x y z') assert linrec(coeffs=a[:5], init=b[:4], n=80) == \ Rational(1726244235456268979436592226626304376013002142588105090705187189, 1960143456748895967474334873705475211264) assert linrec(coeffs=a[:4], init=b[:4], n=50) == \ Rational(368949940033050147080268092104304441, 504857282956046106624) assert linrec(coeffs=a[3:], init=b[:3], n=35) == \ Rational(97409272177295731943657945116791049305244422833125109, 814315512679031689453125) assert linrec(coeffs=[0]*60 + [S(2)/3, S(4)/5], init=b, n=3000) == \ 26777668739896791448594650497024/S(48084516708184142230517578125) raises(TypeError, lambda: linrec(coeffs=[11, 13, 15, 17], init=[1, 2, 3, 4, 5], n=1)) raises(TypeError, lambda: linrec(coeffs=a[:4], init=b[:5], n=10000)) raises(ValueError, lambda: linrec(coeffs=a[:4], init=b[:4], n=-10000)) raises(TypeError, lambda: linrec(x, b, n=10000)) raises(TypeError, lambda: linrec(a, y, n=10000)) assert linrec(coeffs=[x, y, z], init=[1, 1, 1], n=4) == \ x**2 + x*y + x*z + y + z assert linrec(coeffs=[1, 2, 1], init=[x, y, z], n=20) == \ 269542*x + 664575*y + 578949*z assert linrec(coeffs=[0, 3, 1, 2], init=[x, y], n=30) == \ 58516436*x + 56372788*y assert linrec(coeffs=[0]*50 + [1, 2, 3], init=[x, y, z], n=1000) == \ 11477135884896*x + 25999077948732*y + 41975630244216*z assert linrec(coeffs=[], init=[1, 1], n=20) == 0
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 _eval_rewrite_as_Piecewise(self, arg): if arg.is_real: return Piecewise((1, arg > 0), (S(1) / 2, Eq(arg, 0)), (0, True))
def as_real_imag(self): from sympy import I real = (S(1) / 2) * (self + self._eval_conjugate()) im = (self - self._eval_conjugate()) / (2 * I) return (real, im)
def _eval_Mod(self, q): n, k = self.args if any(x.is_integer is False for x in (n, k, q)): raise ValueError("Integers expected for binomial Mod") if all(x.is_Integer for x in (n, k, q)): n, k = map(int, (n, k)) aq, res = abs(q), 1 # handle negative integers k or n if k < 0: return S.Zero if n < 0: n = -n + k - 1 res = -1 if k % 2 else 1 # non negative integers k and n if k > n: return S.Zero isprime = aq.is_prime aq = int(aq) if isprime: if aq < n: # use Lucas Theorem N, K = n, k while N or K: res = res * binomial(N % aq, K % aq) % aq N, K = N // aq, K // aq else: # use Factorial Modulo d = n - k if k > d: k, d = d, k kf = 1 for i in range(2, k + 1): kf = kf * i % aq df = kf for i in range(k + 1, d + 1): df = df * i % aq res *= df for i in range(d + 1, n + 1): res = res * i % aq res *= pow(kf * df % aq, aq - 2, aq) res %= aq else: # Binomial Factorization is performed by calculating the # exponents of primes <= n in `n! /(k! (n - k)!)`, # for non-negative integers n and k. As the exponent of # prime in n! is e_p(n) = [n/p] + [n/p**2] + ... # the exponent of prime in binomial(n, k) would be # e_p(n) - e_p(k) - e_p(n - k) M = int(_sqrt(n)) for prime in sieve.primerange(2, n + 1): if prime > n - k: res = res * prime % aq elif prime > n // 2: continue elif prime > M: if n % prime < k % prime: res = res * prime % aq else: N, K = n, k exp = a = 0 while N > 0: a = int((N % prime) < (K % prime + a)) N, K = N // prime, K // prime exp += a if exp > 0: res *= pow(prime, exp, aq) res %= aq return S(res % q)
def pde_1st_linear_constant_coeff(eq, func, order, match, solvefun): r""" Solves a first order linear partial differential equation with constant coefficients. The general form of this partial differential equation is .. math:: a \frac{df(x,y)}{dx} + b \frac{df(x,y)}{dy} + c f(x,y) = G(x,y) where `a`, `b` and `c` are constants and `G(x, y)` can be an arbitrary function in `x` and `y`. The general solution of the PDE is:: >>> from sympy.solvers import pdsolve >>> from sympy.abc import x, y, a, b, c >>> from sympy import Function, pprint >>> f = Function('f') >>> G = Function('G') >>> u = f(x,y) >>> ux = u.diff(x) >>> uy = u.diff(y) >>> genform = a*u + b*ux + c*uy - G(x,y) >>> pprint(genform) d d a*f(x, y) + b*--(f(x, y)) + c*--(f(x, y)) - G(x, y) dx dy >>> pprint(pdsolve(genform, hint='1st_linear_constant_coeff_Integral')) // b*x + c*y \ || / | || | | || | a*xi | || | ------- | || | 2 2 | || | /b*xi + c*eta -b*eta + c*xi\ b + c | || | G|------------, -------------|*e d(xi)| || | | 2 2 2 2 | | || | \ b + c b + c / | || | | || / | || | f(x, y) = ||F(eta) + -------------------------------------------------------|* || 2 2 | \\ b + c / <BLANKLINE> \| || || || || || || || || -a*xi || -------|| 2 2|| b + c || e || || /|eta=-b*y + c*x, xi=b*x + c*y Examples ======== >>> from sympy.solvers.pde import pdsolve >>> from sympy import Function, diff, pprint, exp >>> from sympy.abc import x,y >>> f = Function('f') >>> eq = -2*f(x,y).diff(x) + 4*f(x,y).diff(y) + 5*f(x,y) - exp(x + 3*y) >>> pdsolve(eq) Eq(f(x, y), (F(4*x + 2*y) + exp(x/2 + 4*y)/15)*exp(x/2 - y)) References ========== - Viktor Grigoryan, "Partial Differential Equations" Math 124A - Fall 2010, pp.7 """ # TODO : For now homogeneous first order linear PDE's having # two variables are implemented. Once there is support for # solving systems of ODE's, this can be extended to n variables. xi, eta = symbols("xi eta") f = func.func x = func.args[0] y = func.args[1] b = match[match['b']] c = match[match['c']] d = match[match['d']] e = -match[match['e']] expterm = exp(-S(d) / (b**2 + c**2) * xi) functerm = solvefun(eta) solvedict = solve((b * x + c * y - xi, c * x - b * y - eta), x, y) # Integral should remain as it is in terms of xi, # doit() should be done in _handle_Integral. genterm = (1 / S(b**2 + c**2)) * Integral( (1 / expterm * e).subs(solvedict), (xi, b * x + c * y)) return Eq( f(x, y), Subs(expterm * (functerm + genterm), (eta, xi), (c * x - b * y, b * x + c * y)))
def interpolate(data, x): """ Construct an interpolating polynomial for the data points evaluated at point x (which can be symbolic or numeric). Examples ======== >>> from sympy.polys.polyfuncs import interpolate >>> from sympy.abc import a, b, x A list is interpreted as though it were paired with a range starting from 1: >>> interpolate([1, 4, 9, 16], x) x**2 This can be made explicit by giving a list of coordinates: >>> interpolate([(1, 1), (2, 4), (3, 9)], x) x**2 The (x, y) coordinates can also be given as keys and values of a dictionary (and the points need not be equispaced): >>> interpolate([(-1, 2), (1, 2), (2, 5)], x) x**2 + 1 >>> interpolate({-1: 2, 1: 2, 2: 5}, x) x**2 + 1 If the interpolation is going to be used only once then the value of interest can be passed instead of passing a symbol: >>> interpolate([1, 4, 9], 5) 25 Symbolic coordinates are also supported: >>> [(i,interpolate((a, b), i)) for i in range(1, 4)] [(1, a), (2, b), (3, -a + 2*b)] """ n = len(data) if isinstance(data, dict): if x in data: return S(data[x]) X, Y = list(zip(*data.items())) else: if isinstance(data[0], tuple): X, Y = list(zip(*data)) if x in X: return S(Y[X.index(x)]) else: if x in range(1, n + 1): return S(data[x - 1]) Y = list(data) X = list(range(1, n + 1)) try: return interpolating_poly(n, x, X, Y).expand() except ValueError: d = Dummy() return interpolating_poly(n, d, X, Y).expand().subs(d, x)