def _eval_rewrite_as_sign(self, arg, H0=None, **kwargs): """ Represents the Heaviside function in the form of sign function. Explanation =========== The value of the second argument of Heaviside must specify Heaviside(0) = 1/2 for rewritting as sign to be strictly equivalent. For easier usage, we also allow this rewriting when Heaviside(0) is undefined. Examples ======== >>> from sympy import Heaviside, Symbol, sign, S >>> x = Symbol('x', real=True) >>> Heaviside(x, H0=S.Half).rewrite(sign) sign(x)/2 + 1/2 >>> Heaviside(x, 0).rewrite(sign) Piecewise((sign(x)/2 + 1/2, Ne(x, 0)), (0, True)) >>> Heaviside(x - 2, H0=S.Half).rewrite(sign) sign(x - 2)/2 + 1/2 >>> Heaviside(x**2 - 2*x + 1, H0=S.Half).rewrite(sign) sign(x**2 - 2*x + 1)/2 + 1/2 >>> y = Symbol('y') >>> Heaviside(y).rewrite(sign) Heaviside(y) >>> Heaviside(y**2 - 2*y + 1).rewrite(sign) Heaviside(y**2 - 2*y + 1) See Also ======== sign """ if arg.is_extended_real: pw1 = Piecewise(((sign(arg) + 1) / 2, Ne(arg, 0)), (Heaviside(0, H0=H0), True)) pw2 = Piecewise( ((sign(arg) + 1) / 2, Eq(Heaviside(0, H0=H0), S(1) / 2)), (pw1, True)) return pw2
def test_issue_6167_6151(): n = pi**1000 i = int(n) assert sign(n - i) == 1 assert abs(n - i) == n - i x = Symbol('x') eps = pi**-1500 big = pi**1000 one = cos(x)**2 + sin(x)**2 e = big * one - big + eps from sympy.simplify.simplify import simplify assert sign(simplify(e)) == 1 for xi in (111, 11, 1, Rational(1, 10)): assert sign(e.subs(x, xi)) == 1
def _eval_power(self, e): from .evalf import pure_complex from .relational import is_eq if len(self.args) == 2 and any(_.is_infinite for _ in self.args): if e.is_zero is False and is_eq(e, S.One) is False: # looking for literal a + I*b a, b = self.args if a.coeff(S.ImaginaryUnit): a, b = b, a ico = b.coeff(S.ImaginaryUnit) if ico and ico.is_extended_real and a.is_extended_real: if e.is_extended_negative: return S.Zero if e.is_extended_positive: return S.ComplexInfinity return if e.is_Rational and self.is_number: ri = pure_complex(self) if ri: r, i = ri if e.q == 2: from sympy.functions.elementary.miscellaneous import sqrt D = sqrt(r**2 + i**2) if D.is_Rational: from .exprtools import factor_terms from sympy.functions.elementary.complexes import sign from .function import expand_multinomial # (r, i, D) is a Pythagorean triple root = sqrt(factor_terms((D - r) / 2))**e.p return root * expand_multinomial(( # principle value (D + r) / abs(i) + sign(i) * S.ImaginaryUnit)**e.p) elif e == -1: return _unevaluated_Mul(r - i * S.ImaginaryUnit, 1 / (r**2 + i**2)) elif e.is_Number and abs(e) != 1: # handle the Float case: (2.0 + 4*x)**e -> 4**e*(0.5 + x)**e c, m = zip(*[i.as_coeff_Mul() for i in self.args]) if any(i.is_Float for i in c): # XXX should this always be done? big = -1 for i in c: if abs(i) >= big: big = abs(i) if big > 0 and big != 1: from sympy.functions.elementary.complexes import sign bigs = (big, -big) c = [sign(i) if i in bigs else i / big for i in c] addpow = Add(*[c * m for c, m in zip(c, m)])**e return big**e * addpow
def _eval_rewrite_as_sign(self, arg): """Represents the Heaviside function in the form of sign function. Examples ======== >>> from sympy import Heaviside, Symbol, sign >>> x = Symbol('x', real=True) >>> Heaviside(x).rewrite(sign) sign(x)/2 + 1/2 >>> Heaviside(x - 2).rewrite(sign) sign(x - 2)/2 + 1/2 >>> Heaviside(x**2 - 2*x + 1).rewrite(sign) sign(x**2 - 2*x + 1)/2 + 1/2 >>> y = Symbol('y') >>> Heaviside(y).rewrite(sign) Heaviside(y) >>> Heaviside(y**2 - 2*y + 1).rewrite(sign) Heaviside(y**2 - 2*y + 1) See Also ======== sign """ if arg.is_real: return (sign(arg)+1)/2
def real_root(arg, n=None, evaluate=None): """Return the real *n*'th-root of *arg* if possible. Parameters ========== n : int or None, optional If *n* is ``None``, then all instances of ``(-n)**(1/odd)`` will be changed to ``-n**(1/odd)``. This will only create a real root of a principal root. The presence of other factors may cause the result to not be real. evaluate : bool, optional The parameter determines if the expression should be evaluated. If ``None``, its value is taken from ``global_parameters.evaluate``. Examples ======== >>> from sympy import root, real_root >>> real_root(-8, 3) -2 >>> root(-8, 3) 2*(-1)**(1/3) >>> real_root(_) -2 If one creates a non-principal root and applies real_root, the result will not be real (so use with caution): >>> root(-8, 3, 2) -2*(-1)**(2/3) >>> real_root(_) -2*(-1)**(2/3) See Also ======== sympy.polys.rootoftools.rootof sympy.core.power.integer_nthroot root, sqrt """ from sympy.functions.elementary.complexes import Abs, im, sign from sympy.functions.elementary.piecewise import Piecewise if n is not None: return Piecewise((root(arg, n, evaluate=evaluate), Or(Eq(n, S.One), Eq(n, S.NegativeOne))), (Mul(sign(arg), root(Abs(arg), n, evaluate=evaluate), evaluate=evaluate), And(Eq(im(arg), S.Zero), Eq(Mod(n, 2), S.One))), (root(arg, n, evaluate=evaluate), True)) rv = sympify(arg) n1pow = Transform( lambda x: -(-x.base)**x.exp, lambda x: x.is_Pow and x.base.is_negative and x.exp.is_Rational and x.exp.p == 1 and x.exp.q % 2) return rv.xreplace(n1pow)
def _updated_range(r, first): st = sign(r.step)*step if r.start.is_finite: rv = Range(first, r.stop, st) else: rv = Range(r.start, first + st, st) return rv
def _updated_range(r, first): st = sign(r.step) * step if r.start.is_finite: rv = Range(first, r.stop, st) else: rv = Range(r.start, first + st, st) return rv
def eval(cls, n, m, z=None): if z is not None: n, z, m = n, m, z k = 2 * z / pi if n == S.Zero: return elliptic_f(z, m) elif n == S.One: return elliptic_f(z, m) + (sqrt(1 - m * sin(z) ** 2) * tan(z) - elliptic_e(z, m)) / (1 - m) elif k.is_integer: return k * elliptic_pi(n, m) elif m == S.Zero: return atanh(sqrt(n - 1) * tan(z)) / sqrt(n - 1) elif n == m: return elliptic_f(z, n) - elliptic_pi(1, z, n) + tan(z) / sqrt(1 - n * sin(z) ** 2) elif n in (S.Infinity, S.NegativeInfinity): return S.Zero elif m in (S.Infinity, S.NegativeInfinity): return S.Zero elif z.could_extract_minus_sign(): return -elliptic_pi(n, -z, m) else: if n == S.Zero: return elliptic_k(m) elif n == S.One: return S.ComplexInfinity elif m == S.Zero: return pi / (2 * sqrt(1 - n)) elif m == S.One: return -S.Infinity / sign(n - 1) elif n == m: return elliptic_e(n) / (1 - n) elif n in (S.Infinity, S.NegativeInfinity): return S.Zero elif m in (S.Infinity, S.NegativeInfinity): return S.Zero
def test_rewrite(): x, y = Symbol('x', real=True), Symbol('y') assert Heaviside(x).rewrite(Piecewise) == ( Piecewise((0, x < 0), (Heaviside(0), Eq(x, 0)), (1, x > 0))) assert Heaviside(y).rewrite(Piecewise) == ( Piecewise((0, y < 0), (Heaviside(0), Eq(y, 0)), (1, y > 0))) assert Heaviside(x, y).rewrite(Piecewise) == ( Piecewise((0, x < 0), (y, Eq(x, 0)), (1, x > 0))) assert Heaviside(x, 0).rewrite(Piecewise) == ( Piecewise((0, x <= 0), (1, x > 0))) assert Heaviside(x, 1).rewrite(Piecewise) == ( Piecewise((0, x < 0), (1, x >= 0))) assert Heaviside(x, nan).rewrite(Piecewise) == ( Piecewise((0, x < 0), (nan, Eq(x, 0)), (1, x > 0))) assert Heaviside(x).rewrite(sign) == \ Heaviside(x, H0=Heaviside(0)).rewrite(sign) == \ Piecewise( (sign(x)/2 + S(1)/2, Eq(Heaviside(0), S(1)/2)), (Piecewise( (sign(x)/2 + S(1)/2, Ne(x, 0)), (Heaviside(0), True)), True) ) assert Heaviside(y).rewrite(sign) == Heaviside(y) assert Heaviside(x, S.Half).rewrite(sign) == (sign(x)+1)/2 assert Heaviside(x, y).rewrite(sign) == \ Piecewise( (sign(x)/2 + S(1)/2, Eq(y, S(1)/2)), (Piecewise( (sign(x)/2 + S(1)/2, Ne(x, 0)), (y, True)), True) ) assert DiracDelta(y).rewrite(Piecewise) == Piecewise((DiracDelta(0), Eq(y, 0)), (0, True)) assert DiracDelta(y, 1).rewrite(Piecewise) == DiracDelta(y, 1) assert DiracDelta(x - 5).rewrite(Piecewise) == ( Piecewise((DiracDelta(0), Eq(x - 5, 0)), (0, True))) assert (x*DiracDelta(x - 10)).rewrite(SingularityFunction) == x*SingularityFunction(x, 10, -1) assert 5*x*y*DiracDelta(y, 1).rewrite(SingularityFunction) == 5*x*y*SingularityFunction(y, 0, -2) assert DiracDelta(0).rewrite(SingularityFunction) == SingularityFunction(0, 0, -1) assert DiracDelta(0, 1).rewrite(SingularityFunction) == SingularityFunction(0, 0, -2) assert Heaviside(x).rewrite(SingularityFunction) == SingularityFunction(x, 0, 0) assert 5*x*y*Heaviside(y + 1).rewrite(SingularityFunction) == 5*x*y*SingularityFunction(y, -1, 0) assert ((x - 3)**3*Heaviside(x - 3)).rewrite(SingularityFunction) == (x - 3)**3*SingularityFunction(x, 3, 0) assert Heaviside(0).rewrite(SingularityFunction) == S.Half
def from_rotation_matrix(cls, M): """Returns the equivalent quaternion of a matrix. The quaternion will be normalized only if the matrix is special orthogonal (orthogonal and det(M) = 1). Parameters ========== M : Matrix Input matrix to be converted to equivalent quaternion. M must be special orthogonal (orthogonal and det(M) = 1) for the quaternion to be normalized. Returns ======= Quaternion The quaternion equivalent to given matrix. Examples ======== >>> from sympy import Quaternion >>> from sympy import Matrix, symbols, cos, sin, trigsimp >>> x = symbols('x') >>> M = Matrix([[cos(x), -sin(x), 0], [sin(x), cos(x), 0], [0, 0, 1]]) >>> q = trigsimp(Quaternion.from_rotation_matrix(M)) >>> q sqrt(2)*sqrt(cos(x) + 1)/2 + 0*i + 0*j + sqrt(2 - 2*cos(x))*sign(sin(x))/2*k """ absQ = M.det()**Rational(1, 3) a = sqrt(absQ + M[0, 0] + M[1, 1] + M[2, 2]) / 2 b = sqrt(absQ + M[0, 0] - M[1, 1] - M[2, 2]) / 2 c = sqrt(absQ - M[0, 0] + M[1, 1] - M[2, 2]) / 2 d = sqrt(absQ - M[0, 0] - M[1, 1] + M[2, 2]) / 2 b = b * sign(M[2, 1] - M[1, 2]) c = c * sign(M[0, 2] - M[2, 0]) d = d * sign(M[1, 0] - M[0, 1]) return Quaternion(a, b, c, d)
def test_sign_issue_3068(): n = pi**1000 i = int(n) x = Symbol('x') assert (n - i).round() == 1 # doesn't hang assert sign(n - i) == 1 # perhaps it's not possible to get the sign right when # only 1 digit is being requested for this situation; # 2 digits works assert (n - x).n(1, subs={x: i}) > 0 assert (n - x).n(2, subs={x: i}) > 0
def real_root(arg, n=None, evaluate=None): """Return the real nth-root of arg if possible. If n is omitted then all instances of (-n)**(1/odd) will be changed to -n**(1/odd); this will only create a real root of a principal root -- the presence of other factors may cause the result to not be real. The parameter evaluate determines if the expression should be evaluated. If None, its value is taken from global_evaluate. Examples ======== >>> from sympy import root, real_root, Rational >>> from sympy.abc import x, n >>> real_root(-8, 3) -2 >>> root(-8, 3) 2*(-1)**(1/3) >>> real_root(_) -2 If one creates a non-principal root and applies real_root, the result will not be real (so use with caution): >>> root(-8, 3, 2) -2*(-1)**(2/3) >>> real_root(_) -2*(-1)**(2/3) See Also ======== sympy.polys.rootoftools.rootof sympy.core.power.integer_nthroot root, sqrt """ from sympy.functions.elementary.complexes import Abs, im, sign from sympy.functions.elementary.piecewise import Piecewise if n is not None: return Piecewise( (root(arg, n, evaluate=evaluate), Or(Eq(n, S.One), Eq(n, S.NegativeOne))), (Mul(sign(arg), root(Abs(arg), n, evaluate=evaluate), evaluate=evaluate), And(Eq(im(arg), S.Zero), Eq(Mod(n, 2), S.One))), (root(arg, n, evaluate=evaluate), True)) rv = sympify(arg) n1pow = Transform(lambda x: -(-x.base)**x.exp, lambda x: x.is_Pow and x.base.is_negative and x.exp.is_Rational and x.exp.p == 1 and x.exp.q % 2) return rv.xreplace(n1pow)
def _first_finite_point(r1, c): if c == r1.start: return c # st is the signed step we need to take to # get from c to r1.start st = sign(r1.start - c)*step # use Range to calculate the first point: # we want to get as close as possible to # r1.start; the Range will not be null since # it will at least contain c s1 = Range(c, r1.start + st, st)[-1] if s1 == r1.start: pass else: # if we didn't hit r1.start then, if the # sign of st didn't match the sign of r1.step # we are off by one and s1 is not in r1 if sign(r1.step) != sign(st): s1 -= st if s1 not in r1: return return s1
def _first_finite_point(r1, c): if c == r1.start: return c # st is the signed step we need to take to # get from c to r1.start st = sign(r1.start - c) * step # use Range to calculate the first point: # we want to get as close as possible to # r1.start; the Range will not be null since # it will at least contain c s1 = Range(c, r1.start + st, st)[-1] if s1 == r1.start: pass else: # if we didn't hit r1.start then, if the # sign of st didn't match the sign of r1.step # we are off by one and s1 is not in r1 if sign(r1.step) != sign(st): s1 -= st if s1 not in r1: return return s1
def test_conjugate(): a = Symbol("a", real=True) b = Symbol("b", real=True) c = Symbol("c", imaginary=True) d = Symbol("d", imaginary=True) x = Symbol('x') z = a + I * b + c + I * d zc = a - I * b - c + I * d assert conjugate(z) == zc assert conjugate(exp(z)) == exp(zc) assert conjugate(exp(I * x)) == exp(-I * conjugate(x)) assert conjugate(z**5) == zc**5 assert conjugate(abs(x)) == abs(x) assert conjugate(sign(z)) == sign(zc) assert conjugate(sin(z)) == sin(zc) assert conjugate(cos(z)) == cos(zc) assert conjugate(tan(z)) == tan(zc) assert conjugate(cot(z)) == cot(zc) assert conjugate(sinh(z)) == sinh(zc) assert conjugate(cosh(z)) == cosh(zc) assert conjugate(tanh(z)) == tanh(zc) assert conjugate(coth(z)) == coth(zc)
def real_root(arg, n=None): """Return the real nth-root of arg if possible. If n is omitted then all instances of (-n)**(1/odd) will be changed to -n**(1/odd); this will only create a real root of a principal root -- the presence of other factors may cause the result to not be real. Examples ======== >>> from sympy import root, real_root, Rational >>> from sympy.abc import x, n >>> real_root(-8, 3) -2 >>> root(-8, 3) 2*(-1)**(1/3) >>> real_root(_) -2 If one creates a non-principal root and applies real_root, the result will not be real (so use with caution): >>> root(-8, 3, 2) -2*(-1)**(2/3) >>> real_root(_) -2*(-1)**(2/3) See Also ======== sympy.polys.rootoftools.rootof sympy.core.power.integer_nthroot root, sqrt """ from sympy.functions.elementary.complexes import Abs, im, sign from sympy.functions.elementary.piecewise import Piecewise if n is not None: return Piecewise( (root(arg, n), Or(Eq(n, S.One), Eq(n, S.NegativeOne))), (sign(arg)*root(Abs(arg), n), And(Eq(im(arg), S.Zero), Eq(Mod(n, 2), S.One))), (root(arg, n), True)) rv = sympify(arg) n1pow = Transform(lambda x: -(-x.base)**x.exp, lambda x: x.is_Pow and x.base.is_negative and x.exp.is_Rational and x.exp.p == 1 and x.exp.q % 2) return rv.xreplace(n1pow)
def _eval_power(self, e): if e.is_Rational and self.is_number: from sympy.core.evalf import pure_complex from sympy.core.mul import _unevaluated_Mul from sympy.core.exprtools import factor_terms from sympy.core.function import expand_multinomial from sympy.functions.elementary.complexes import sign from sympy.functions.elementary.miscellaneous import sqrt ri = pure_complex(self) if ri: r, i = ri if e.q == 2: D = sqrt(r**2 + i**2) if D.is_Rational: # (r, i, D) is a Pythagorean triple root = sqrt(factor_terms((D - r) / 2))**e.p return root * expand_multinomial(( # principle value (D + r) / abs(i) + sign(i) * S.ImaginaryUnit)**e.p) elif e == -1: return _unevaluated_Mul(r - i * S.ImaginaryUnit, 1 / (r**2 + i**2)) elif e.is_Number and abs(e) != 1: # handle the Float case: (2.0 + 4*x)**e -> 4**e*(0.5 + x)**e c, m = zip(*[i.as_coeff_Mul() for i in self.args]) if any(i.is_Float for i in c): # XXX should this always be done? big = -1 for i in c: if abs(i) >= big: big = abs(i) if big > 0 and big != 1: from sympy.functions.elementary.complexes import sign bigs = (big, -big) c = [sign(i) if i in bigs else i / big for i in c] addpow = Add(*[c * m for c, m in zip(c, m)])**e return big**e * addpow
def test_quaternion_construction(): q = Quaternion(w, x, y, z) assert q + q == Quaternion(2*w, 2*x, 2*y, 2*z) q2 = Quaternion.from_axis_angle((sqrt(3)/3, sqrt(3)/3, sqrt(3)/3), pi*Rational(2, 3)) assert q2 == Quaternion(S.Half, S.Half, S.Half, S.Half) M = Matrix([[cos(phi), -sin(phi), 0], [sin(phi), cos(phi), 0], [0, 0, 1]]) q3 = trigsimp(Quaternion.from_rotation_matrix(M)) assert q3 == Quaternion(sqrt(2)*sqrt(cos(phi) + 1)/2, 0, 0, sqrt(2 - 2*cos(phi))*sign(sin(phi))/2) nc = Symbol('nc', commutative=False) raises(ValueError, lambda: Quaternion(w, x, nc, z))
def eval(cls, n, m, z=None): if z is not None: n, z, m = n, m, z if n.is_zero: return elliptic_f(z, m) elif n is S.One: return (elliptic_f(z, m) + (sqrt(1 - m*sin(z)**2)*tan(z) - elliptic_e(z, m))/(1 - m)) k = 2*z/pi if k.is_integer: return k*elliptic_pi(n, m) elif m.is_zero: return atanh(sqrt(n - 1)*tan(z))/sqrt(n - 1) elif n == m: return (elliptic_f(z, n) - elliptic_pi(1, z, n) + tan(z)/sqrt(1 - n*sin(z)**2)) elif n in (S.Infinity, S.NegativeInfinity): return S.Zero elif m in (S.Infinity, S.NegativeInfinity): return S.Zero elif z.could_extract_minus_sign(): return -elliptic_pi(n, -z, m) if n.is_zero: return elliptic_f(z, m) if m.is_extended_real and m.is_infinite or \ n.is_extended_real and n.is_infinite: return S.Zero else: if n.is_zero: return elliptic_k(m) elif n is S.One: return S.ComplexInfinity elif m.is_zero: return pi/(2*sqrt(1 - n)) elif m == S.One: return S.NegativeInfinity/sign(n - 1) elif n == m: return elliptic_e(n)/(1 - n) elif n in (S.Infinity, S.NegativeInfinity): return S.Zero elif m in (S.Infinity, S.NegativeInfinity): return S.Zero if n.is_zero: return elliptic_k(m) if m.is_extended_real and m.is_infinite or \ n.is_extended_real and n.is_infinite: return S.Zero
def limit_at_inf(num, den, x): """ Find the limit of a rational function at oo """ # pwr = degree(num) - degree(den) pwr = -val_at_inf(num, den, x) # Numerator has a greater degree than denominator # Limit at infinity would depend on the sign of the # leading coefficients of numerator and denominator if pwr > 0: return oo*sign(num.LC()/den.LC()) # Degree of numerator is equal to that of denominator # Limit at infinity is just the ratio of leading coeffs elif pwr == 0: return num.LC()/den.LC() # Degree of numerator is less than that of denominator # Limit at infinity is just 0 else: return 0
def _eval_rewrite_as_sign(self, arg, H0=None, **kwargs): """Represents the Heaviside function in the form of sign function. The value of the second argument of Heaviside must specify Heaviside(0) = 1/2 for rewritting as sign to be strictly equivalent. For easier usage, we also allow this rewriting when Heaviside(0) is undefined. Examples ======== >>> from sympy import Heaviside, Symbol, sign >>> x = Symbol('x', real=True) >>> Heaviside(x).rewrite(sign) sign(x)/2 + 1/2 >>> Heaviside(x, 0).rewrite(sign) Heaviside(x, 0) >>> Heaviside(x - 2).rewrite(sign) sign(x - 2)/2 + 1/2 >>> Heaviside(x**2 - 2*x + 1).rewrite(sign) sign(x**2 - 2*x + 1)/2 + 1/2 >>> y = Symbol('y') >>> Heaviside(y).rewrite(sign) Heaviside(y) >>> Heaviside(y**2 - 2*y + 1).rewrite(sign) Heaviside(y**2 - 2*y + 1) See Also ======== sign """ if arg.is_extended_real: if H0 is None or H0 == S.Half: return (sign(arg) + 1) / 2
def _eval_rewrite_as_sign(self, arg, H0=None): """Represents the Heaviside function in the form of sign function. The value of the second argument of Heaviside must specify Heaviside(0) = 1/2 for rewritting as sign to be strictly equivalent. For easier usage, we also allow this rewriting when Heaviside(0) is undefined. Examples ======== >>> from sympy import Heaviside, Symbol, sign >>> x = Symbol('x', real=True) >>> Heaviside(x).rewrite(sign) sign(x)/2 + 1/2 >>> Heaviside(x, 0).rewrite(sign) Heaviside(x, 0) >>> Heaviside(x - 2).rewrite(sign) sign(x - 2)/2 + 1/2 >>> Heaviside(x**2 - 2*x + 1).rewrite(sign) sign(x**2 - 2*x + 1)/2 + 1/2 >>> y = Symbol('y') >>> Heaviside(y).rewrite(sign) Heaviside(y) >>> Heaviside(y**2 - 2*y + 1).rewrite(sign) Heaviside(y**2 - 2*y + 1) See Also ======== sign """ if arg.is_real: if H0 is None or H0 == S.Half: return (sign(arg)+1)/2
def eval(cls, *args): if len(args) == 3: n, z, m = args k = 2 * z / pi if n == S.Zero: return elliptic_f(z, m) elif n == S.One: return (elliptic_f(z, m) + (sqrt(1 - m * sin(z)**2) * tan(z) - elliptic_e(z, m)) / (1 - m)) elif k.is_integer: return k * elliptic_pi(n, m) elif m == S.Zero: return atanh(sqrt(n - 1) * tan(z)) / sqrt(n - 1) elif n == m: return (elliptic_f(z, n) - elliptic_pi(1, z, n) + tan(z) / sqrt(1 - n * sin(z)**2)) elif n in (S.Infinity, S.NegativeInfinity): return S.Zero elif m in (S.Infinity, S.NegativeInfinity): return S.Zero elif z.could_extract_minus_sign(): return -elliptic_pi(n, -z, m) else: n, m = args if n == S.Zero: return elliptic_k(m) elif n == S.One: return S.ComplexInfinity elif m == S.Zero: return pi / (2 * sqrt(1 - n)) elif m == S.One: return -S.Infinity / sign(n - 1) elif n == m: return elliptic_e(n) / (1 - n) elif n in (S.Infinity, S.NegativeInfinity): return S.Zero elif m in (S.Infinity, S.NegativeInfinity): return S.Zero
def _eval_power(self, e): if e.is_Rational and self.is_number: from sympy.core.evalf import pure_complex from sympy.core.mul import _unevaluated_Mul from sympy.core.exprtools import factor_terms from sympy.core.function import expand_multinomial from sympy.functions.elementary.complexes import sign from sympy.functions.elementary.miscellaneous import sqrt ri = pure_complex(self) if ri: r, i = ri if e.q == 2: D = sqrt(r**2 + i**2) if D.is_Rational: # (r, i, D) is a Pythagorean triple root = sqrt(factor_terms((D - r) / 2))**e.p return root * expand_multinomial(( # principle value (D + r) / abs(i) + sign(i) * S.ImaginaryUnit)**e.p) elif e == -1: return _unevaluated_Mul(r - i * S.ImaginaryUnit, 1 / (r**2 + i**2))
def _eval_power(self, e): if e.is_Rational and self.is_number: from sympy.core.evalf import pure_complex from sympy.core.mul import _unevaluated_Mul from sympy.core.exprtools import factor_terms from sympy.core.function import expand_multinomial from sympy.functions.elementary.complexes import sign from sympy.functions.elementary.miscellaneous import sqrt ri = pure_complex(self) if ri: r, i = ri if e.q == 2: D = sqrt(r**2 + i**2) if D.is_Rational: # (r, i, D) is a Pythagorean triple root = sqrt(factor_terms((D - r)/2))**e.p return root*expand_multinomial(( # principle value (D + r)/abs(i) + sign(i)*S.ImaginaryUnit)**e.p) elif e == -1: return _unevaluated_Mul( r - i*S.ImaginaryUnit, 1/(r**2 + i**2))
def _eval_power(self, e): if e.is_Rational and self.is_number: from sympy.core.evalf import pure_complex from sympy.core.mul import _unevaluated_Mul from sympy.core.exprtools import factor_terms from sympy.core.function import expand_multinomial from sympy.functions.elementary.complexes import sign from sympy.functions.elementary.miscellaneous import sqrt ri = pure_complex(self) if ri: r, i = ri if e.q == 2: D = sqrt(r**2 + i**2) if D.is_Rational: # (r, i, D) is a Pythagorean triple root = sqrt(factor_terms((D - r) / 2))**e.p return root * expand_multinomial(( # principle value (D + r) / abs(i) + sign(i) * S.ImaginaryUnit)**e.p) elif e == -1: return _unevaluated_Mul(r - i * S.ImaginaryUnit, 1 / (r**2 + i**2)) elif e.is_Number and abs(e) != 1: # handle the Float case: (2.0 + 4*x)**e -> 2.**e*(1 + 2.0*x)**e c, m = zip(*[i.as_coeff_Mul() for i in self.args]) big = 0 float = False s = dict() for i in c: float = float or i.is_Float if abs(i) >= big: big = 1.0 * abs(i) s[i] = -1 if i < 0 else 1 if float and big and big != 1: addpow = Add(*[(s[c[i]] if abs(c[i]) == big else c[i] / big) * m[i] for i in range(len(c))])**e return big**e * addpow
def test_Abs_rewrite(): x = Symbol('x', real=True) a = Abs(x).rewrite(Heaviside).expand() assert a == x * Heaviside(x) - x * Heaviside(-x) for i in [-2, -1, 0, 1, 2]: assert a.subs(x, i) == abs(i) y = Symbol('y') assert Abs(y).rewrite(Heaviside) == Abs(y) x, y = Symbol('x', real=True), Symbol('y') assert Abs(x).rewrite(Piecewise) == Piecewise((x, x >= 0), (-x, True)) assert Abs(y).rewrite(Piecewise) == Abs(y) assert Abs(y).rewrite(sign) == y / sign(y) i = Symbol('i', imaginary=True) assert abs(i).rewrite(Piecewise) == Piecewise((I * i, I * i >= 0), (-I * i, True)) assert Abs(y).rewrite(conjugate) == sqrt(y * conjugate(y)) assert Abs(i).rewrite(conjugate) == sqrt(-i**2) # == -I*i y = Symbol('y', extended_real=True) assert (Abs(exp(-I*x)-exp(-I*y))**2).rewrite(conjugate) == \ -exp(I*x)*exp(-I*y) + 2 - exp(-I*x)*exp(I*y)
def _intersect(self, other): from sympy.functions.elementary.integers import ceiling, floor from sympy.functions.elementary.complexes import sign if other is S.Naturals: return self._intersect(Interval(1, S.Infinity)) if other is S.Integers: return self if other.is_Interval: if not all(i.is_number for i in other.args[:2]): return # In case of null Range, return an EmptySet. if self.size == 0: return S.EmptySet # trim down to self's size, and represent # as a Range with step 1. start = ceiling(max(other.inf, self.inf)) if start not in other: start += 1 end = floor(min(other.sup, self.sup)) if end not in other: end -= 1 return self.intersect(Range(start, end + 1)) if isinstance(other, Range): from sympy.solvers.diophantine import diop_linear from sympy.core.numbers import ilcm # non-overlap quick exits if not other: return S.EmptySet if not self: return S.EmptySet if other.sup < self.inf: return S.EmptySet if other.inf > self.sup: return S.EmptySet # work with finite end at the start r1 = self if r1.start.is_infinite: r1 = r1.reversed r2 = other if r2.start.is_infinite: r2 = r2.reversed # this equation represents the values of the Range; # it's a linear equation eq = lambda r, i: r.start + i * r.step # we want to know when the two equations might # have integer solutions so we use the diophantine # solver a, b = diop_linear(eq(r1, Dummy()) - eq(r2, Dummy())) # check for no solution no_solution = a is None and b is None if no_solution: return S.EmptySet # there is a solution # ------------------- # find the coincident point, c a0 = a.as_coeff_Add()[0] c = eq(r1, a0) # find the first point, if possible, in each range # since c may not be that point def _first_finite_point(r1, c): if c == r1.start: return c # st is the signed step we need to take to # get from c to r1.start st = sign(r1.start - c) * step # use Range to calculate the first point: # we want to get as close as possible to # r1.start; the Range will not be null since # it will at least contain c s1 = Range(c, r1.start + st, st)[-1] if s1 == r1.start: pass else: # if we didn't hit r1.start then, if the # sign of st didn't match the sign of r1.step # we are off by one and s1 is not in r1 if sign(r1.step) != sign(st): s1 -= st if s1 not in r1: return return s1 # calculate the step size of the new Range step = abs(ilcm(r1.step, r2.step)) s1 = _first_finite_point(r1, c) if s1 is None: return S.EmptySet s2 = _first_finite_point(r2, c) if s2 is None: return S.EmptySet # replace the corresponding start or stop in # the original Ranges with these points; the # result must have at least one point since # we know that s1 and s2 are in the Ranges def _updated_range(r, first): st = sign(r.step) * step if r.start.is_finite: rv = Range(first, r.stop, st) else: rv = Range(r.start, first + st, st) return rv r1 = _updated_range(self, s1) r2 = _updated_range(other, s2) # work with them both in the increasing direction if sign(r1.step) < 0: r1 = r1.reversed if sign(r2.step) < 0: r2 = r2.reversed # return clipped Range with positive step; it # can't be empty at this point start = max(r1.start, r2.start) stop = min(r1.stop, r2.stop) return Range(start, stop, step) else: return
def test_issue_4099(): a = Symbol('a') assert limit(a/x, x, 0) == oo*sign(a) assert limit(-a/x, x, 0) == -oo*sign(a) assert limit(-a*x, x, oo) == -oo*sign(a) assert limit(a*x, x, oo) == oo*sign(a)
def _eval_rewrite_as_sign(self, arg): if arg.is_real: return (sign(arg) + 1) / 2
def test_sympy__functions__elementary__complexes__sign(): from sympy.functions.elementary.complexes import sign assert _test_args(sign(x))
def test_issue_18118(): assert limit(sign(sin(x)), x, 0, "-") == -1 assert limit(sign(sin(x)), x, 0, "+") == 1
def doit(self, **hints): """Evaluates the limit. Parameters ========== deep : bool, optional (default: True) Invoke the ``doit`` method of the expressions involved before taking the limit. hints : optional keyword arguments To be passed to ``doit`` methods; only used if deep is True. """ e, z, z0, dir = self.args if z0 is S.ComplexInfinity: raise NotImplementedError("Limits at complex " "infinity are not implemented") if hints.get('deep', True): e = e.doit(**hints) z = z.doit(**hints) z0 = z0.doit(**hints) if e == z: return z0 if not e.has(z): return e if z0 is S.NaN: return S.NaN if e.has(*_illegal): return self if e.is_Order: return Order(limit(e.expr, z, z0), *e.args[1:]) cdir = 0 if str(dir) == "+": cdir = 1 elif str(dir) == "-": cdir = -1 def set_signs(expr): if not expr.args: return expr newargs = tuple(set_signs(arg) for arg in expr.args) if newargs != expr.args: expr = expr.func(*newargs) abs_flag = isinstance(expr, Abs) sign_flag = isinstance(expr, sign) if abs_flag or sign_flag: sig = limit(expr.args[0], z, z0, dir) if sig.is_zero: sig = limit(1 / expr.args[0], z, z0, dir) if sig.is_extended_real: if (sig < 0) == True: return -expr.args[0] if abs_flag else S.NegativeOne elif (sig > 0) == True: return expr.args[0] if abs_flag else S.One return expr if e.has(Float): # Convert floats like 0.5 to exact SymPy numbers like S.Half, to # prevent rounding errors which can lead to unexpected execution # of conditional blocks that work on comparisons # Also see comments in https://github.com/sympy/sympy/issues/19453 from sympy.simplify.simplify import nsimplify e = nsimplify(e) e = set_signs(e) if e.is_meromorphic(z, z0): if abs(z0) is S.Infinity: newe = e.subs(z, 1 / z) # cdir changes sign as oo- should become 0+ cdir = -cdir else: newe = e.subs(z, z + z0) try: coeff, ex = newe.leadterm(z, cdir=cdir) except ValueError: pass else: if ex > 0: return S.Zero elif ex == 0: return coeff if cdir == 1 or not (int(ex) & 1): return S.Infinity * sign(coeff) elif cdir == -1: return S.NegativeInfinity * sign(coeff) else: return S.ComplexInfinity if abs(z0) is S.Infinity: if e.is_Mul: e = factor_terms(e) newe = e.subs(z, 1 / z) # cdir changes sign as oo- should become 0+ cdir = -cdir else: newe = e.subs(z, z + z0) try: coeff, ex = newe.leadterm(z, cdir=cdir) except (ValueError, NotImplementedError, PoleError): # The NotImplementedError catching is for custom functions from sympy.simplify.powsimp import powsimp e = powsimp(e) if e.is_Pow: r = self.pow_heuristics(e) if r is not None: return r else: if isinstance(coeff, AccumBounds) and ex == S.Zero: return coeff if coeff.has(S.Infinity, S.NegativeInfinity, S.ComplexInfinity, S.NaN): return self if not coeff.has(z): if ex.is_positive: return S.Zero elif ex == 0: return coeff elif ex.is_negative: if ex.is_integer: if cdir == 1 or ex.is_even: return S.Infinity * sign(coeff) elif cdir == -1: return S.NegativeInfinity * sign(coeff) else: return S.ComplexInfinity else: if cdir == 1: return S.Infinity * sign(coeff) elif cdir == -1: return S.Infinity * sign(coeff) * S.NegativeOne**ex else: return S.ComplexInfinity # gruntz fails on factorials but works with the gamma function # If no factorial term is present, e should remain unchanged. # factorial is defined to be zero for negative inputs (which # differs from gamma) so only rewrite for positive z0. if z0.is_extended_positive: e = e.rewrite(factorial, gamma) l = None try: if str(dir) == '+-': r = gruntz(e, z, z0, '+') l = gruntz(e, z, z0, '-') if l != r: raise ValueError( "The limit does not exist since " "left hand limit = %s and right hand limit = %s" % (l, r)) else: r = gruntz(e, z, z0, dir) if r is S.NaN or l is S.NaN: raise PoleError() except (PoleError, ValueError): if l is not None: raise r = heuristics(e, z, z0, dir) if r is None: return self return r
def _eval_rewrite_as_sign(self, arg): if arg.is_real: return (sign(arg)+1)/2
def _intersect(self, other): from sympy.functions.elementary.integers import ceiling, floor from sympy.functions.elementary.complexes import sign if other is S.Naturals: return self._intersect(Interval(1, S.Infinity)) if other is S.Integers: return self if other.is_Interval: if not all(i.is_number for i in other.args[:2]): return # In case of null Range, return an EmptySet. if self.size == 0: return S.EmptySet # trim down to self's size, and represent # as a Range with step 1. start = ceiling(max(other.inf, self.inf)) if start not in other: start += 1 end = floor(min(other.sup, self.sup)) if end not in other: end -= 1 return self.intersect(Range(start, end + 1)) if isinstance(other, Range): from sympy.solvers.diophantine import diop_linear from sympy.core.numbers import ilcm # non-overlap quick exits if not other: return S.EmptySet if not self: return S.EmptySet if other.sup < self.inf: return S.EmptySet if other.inf > self.sup: return S.EmptySet # work with finite end at the start r1 = self if r1.start.is_infinite: r1 = r1.reversed r2 = other if r2.start.is_infinite: r2 = r2.reversed # this equation represents the values of the Range; # it's a linear equation eq = lambda r, i: r.start + i*r.step # we want to know when the two equations might # have integer solutions so we use the diophantine # solver a, b = diop_linear(eq(r1, Dummy()) - eq(r2, Dummy())) # check for no solution no_solution = a is None and b is None if no_solution: return S.EmptySet # there is a solution # ------------------- # find the coincident point, c a0 = a.as_coeff_Add()[0] c = eq(r1, a0) # find the first point, if possible, in each range # since c may not be that point def _first_finite_point(r1, c): if c == r1.start: return c # st is the signed step we need to take to # get from c to r1.start st = sign(r1.start - c)*step # use Range to calculate the first point: # we want to get as close as possible to # r1.start; the Range will not be null since # it will at least contain c s1 = Range(c, r1.start + st, st)[-1] if s1 == r1.start: pass else: # if we didn't hit r1.start then, if the # sign of st didn't match the sign of r1.step # we are off by one and s1 is not in r1 if sign(r1.step) != sign(st): s1 -= st if s1 not in r1: return return s1 # calculate the step size of the new Range step = abs(ilcm(r1.step, r2.step)) s1 = _first_finite_point(r1, c) if s1 is None: return S.EmptySet s2 = _first_finite_point(r2, c) if s2 is None: return S.EmptySet # replace the corresponding start or stop in # the original Ranges with these points; the # result must have at least one point since # we know that s1 and s2 are in the Ranges def _updated_range(r, first): st = sign(r.step)*step if r.start.is_finite: rv = Range(first, r.stop, st) else: rv = Range(r.start, first + st, st) return rv r1 = _updated_range(self, s1) r2 = _updated_range(other, s2) # work with them both in the increasing direction if sign(r1.step) < 0: r1 = r1.reversed if sign(r2.step) < 0: r2 = r2.reversed # return clipped Range with positive step; it # can't be empty at this point start = max(r1.start, r2.start) stop = min(r1.stop, r2.stop) return Range(start, stop, step) else: return
def test_sign(): x = Symbol('x', real = True) assert refine(sign(x), Q.positive(x)) == 1 assert refine(sign(x), Q.negative(x)) == -1 assert refine(sign(x), Q.zero(x)) == 0 assert refine(sign(x), True) == sign(x) assert refine(sign(Abs(x)), Q.nonzero(x)) == 1 x = Symbol('x', imaginary=True) assert refine(sign(x), Q.positive(im(x))) == S.ImaginaryUnit assert refine(sign(x), Q.negative(im(x))) == -S.ImaginaryUnit assert refine(sign(x), True) == sign(x) x = Symbol('x', complex=True) assert refine(sign(x), Q.zero(x)) == 0
def test_issue_5740(): assert limit(log(x)*z - log(2*x)*y, x, 0) == oo*sign(y - z)
def _upper_hessenberg_decomposition(A): """Converts a matrix into Hessenberg matrix H Returns 2 matrices H, P s.t. $P H P^{T} = A$, where H is an upper hessenberg matrix and P is an orthogonal matrix Examples ======== >>> from sympy import Matrix >>> A = Matrix([ ... [1,2,3], ... [-3,5,6], ... [4,-8,9], ... ]) >>> H, P = A.upper_hessenberg_decomposition() >>> H Matrix([ [1, 6/5, 17/5], [5, 213/25, -134/25], [0, 216/25, 137/25]]) >>> P Matrix([ [1, 0, 0], [0, -3/5, 4/5], [0, 4/5, 3/5]]) >>> P * H * P.H == A True References ========== .. [#] https://mathworld.wolfram.com/HessenbergDecomposition.html """ M = A.as_mutable() if not M.is_square: raise NonSquareMatrixError("Matrix must be square.") n = M.cols P = M.eye(n) H = M for j in range(n - 2): u = H[j + 1:, j] if u[1:, :].is_zero_matrix: continue if sign(u[0]) != 0: u[0] = u[0] + sign(u[0]) * u.norm() else: u[0] = u[0] + u.norm() v = u / u.norm() H[j + 1:, :] = H[j + 1:, :] - 2 * v * (v.H * H[j + 1:, :]) H[:, j + 1:] = H[:, j + 1:] - (H[:, j + 1:] * (2 * v)) * v.H P[:, j + 1:] = P[:, j + 1:] - (P[:, j + 1:] * (2 * v)) * v.H return H, P