def _do_ellipse_intersection(self, o): """The intersection of two ellipses. Private helper method for `intersection`. """ seq = self.equation() variables = self.equation().atoms(C.Symbol) if len(variables) > 2: return None x, y = variables oeq = o.equation(x=x, y=y) # until the following line works... # result = solve([seq, oeq], [x, y]) # return [Point(*r) for r in result if im(r[0]).is_zero and im(r[1]).is_zero] # we do this: if self.center[0] == o.center[0] or self.center[1] == o.center[1]: result = solve_poly_system([seq, oeq], x, y) return [ Point(*r) for r in result if im(r[0]).is_zero and im(r[1]).is_zero ] raise NotImplementedError( "Off-axis Ellipse intersection not supported.")
def test_as_real_imag(): n = pi**1000 # the special code for working out the real # and complex parts of a power with Integer exponent # should not run if there is no imaginary part, hence # this should not hang assert n.as_real_imag() == (n, 0) # issue 6261 x = Symbol('x') assert sqrt(x).as_real_imag() == \ ((re(x)**2 + im(x)**2)**Rational(1, 4)*cos(atan2(im(x), re(x))/2), (re(x)**2 + im(x)**2)**Rational(1, 4)*sin(atan2(im(x), re(x))/2)) # issue 3853 a, b = symbols('a,b', real=True) assert ((1 + sqrt(a + b*I))/2).as_real_imag() == \ ( (a**2 + b**2)**Rational( 1, 4)*cos(atan2(b, a)/2)/2 + S.Half, (a**2 + b**2)**Rational(1, 4)*sin(atan2(b, a)/2)/2) assert sqrt(a**2).as_real_imag() == (sqrt(a**2), 0) i = symbols('i', imaginary=True) assert sqrt(i**2).as_real_imag() == (0, abs(i)) assert ((1 + I) / (1 - I)).as_real_imag() == (0, 1) assert ((1 + I)**3 / (1 - I)).as_real_imag() == (-2, 0)
def eval(cls, arg, H0=None): """ Returns a simplified form or a value of Heaviside depending on the argument passed by the Heaviside object. The ``eval()`` method is automatically called when the ``Heaviside`` class is about to be instantiated and it returns either some simplified instance or the unevaluated instance depending on the argument passed. In other words, ``eval()`` method is not needed to be called explicitly, it is being called and evaluated once the object is called. Examples ======== >>> from sympy import Heaviside, S >>> from sympy.abc import x >>> Heaviside(x) Heaviside(x) >>> Heaviside(19) 1 >>> Heaviside(0) Heaviside(0) >>> Heaviside(0, 1) 1 >>> Heaviside(-5) 0 >>> Heaviside(S.NaN) nan >>> Heaviside(x).eval(100) 1 >>> Heaviside(x - 100).subs(x, 5) 0 >>> Heaviside(x - 100).subs(x, 105) 1 """ H0 = sympify(H0) arg = sympify(arg) if arg.is_negative: return S.Zero elif arg.is_positive: return S.One elif arg.is_zero: return H0 elif arg is S.NaN: return S.NaN elif fuzzy_not(im(arg).is_zero): raise ValueError( "Function defined only for Real Values. Complex part: %s found in %s ." % (repr(im(arg)), repr(arg)))
def test_f_expand_complex(): x = Symbol('x', real=True) assert f(x).expand(complex=True) == I*im(f(x)) + re(f(x)) assert exp(x).expand(complex=True) == exp(x) assert exp(I*x).expand(complex=True) == cos(x) + I*sin(x) assert exp(z).expand(complex=True) == cos(im(z))*exp(re(z)) + \ I*sin(im(z))*exp(re(z))
def test_complex(): assert refine(re(1/(x + I*y)), Q.real(x) & Q.real(y)) == \ x/(x**2 + y**2) assert refine(im(1/(x + I*y)), Q.real(x) & Q.real(y)) == \ -y/(x**2 + y**2) assert refine(re((w + I*x) * (y + I*z)), Q.real(w) & Q.real(x) & Q.real(y) & Q.real(z)) == w*y - x*z assert refine(im((w + I*x) * (y + I*z)), Q.real(w) & Q.real(x) & Q.real(y) & Q.real(z)) == w*z + x*y
def eval(cls, arg): from sympy.functions.elementary.complexes import im v = cls._eval_number(arg) if v is not None: return v if arg.is_integer or arg.is_finite is False: return arg if arg.is_imaginary or (S.ImaginaryUnit*arg).is_real: i = im(arg) if not i.has(S.ImaginaryUnit): return cls(i)*S.ImaginaryUnit return cls(arg, evaluate=False) # Integral, numerical, symbolic part ipart = npart = spart = S.Zero # Extract integral (or complex integral) terms terms = Add.make_args(arg) for t in terms: if t.is_integer or (t.is_imaginary and im(t).is_integer): ipart += t elif t.has(Symbol): spart += t else: npart += t if not (npart or spart): return ipart # Evaluate npart numerically if independent of spart if npart and ( not spart or npart.is_real and (spart.is_imaginary or (S.ImaginaryUnit*spart).is_real) or npart.is_imaginary and spart.is_real): try: r, i = get_integer_part( npart, cls._dir, {}, return_ints=True) ipart += Integer(r) + Integer(i)*S.ImaginaryUnit npart = S.Zero except (PrecisionExhausted, NotImplementedError): pass spart += npart if not spart: return ipart elif spart.is_imaginary or (S.ImaginaryUnit*spart).is_real: return ipart + cls(im(spart), evaluate=False)*S.ImaginaryUnit elif isinstance(spart, (floor, ceiling)): return ipart + spart else: return ipart + cls(spart, evaluate=False)
def _do_ellipse_intersection(self, o): """The intersection of two ellipses. Private helper method for `intersection`. """ x = Dummy('x') y = Dummy('y') seq = self.equation(x, y) oeq = o.equation(x, y) result = solve([seq, oeq], [x, y]) return [Point(*r) for r in result if im(r[0]).is_zero is not False and im(r[1]).is_zero is not False]
def _do_ellipse_intersection(self, o): """The intersection of two ellipses. Private helper method for `intersection`. """ x = Dummy("x") y = Dummy("y") seq = self.equation(x, y) oeq = o.equation(x, y) result = solve([seq, oeq], [x, y]) return [Point(*r) for r in result if im(r[0]).is_zero and im(r[1]).is_zero]
def eval(cls, arg): arg = sympify(arg) if arg is S.NaN: return S.NaN elif fuzzy_not(im(arg).is_zero): raise ValueError( "Function defined only for Real Values. Complex part: %s found in %s ." % (repr(im(arg)), repr(arg))) elif arg.is_negative: return S.Zero elif arg.is_positive: return S.One
def test_diff_no_eval_derivative(): class My(Expr): def __new__(cls, x): return Expr.__new__(cls, x) # My doesn't have its own _eval_derivative method assert My(x).diff(x).func is Derivative assert My(x).diff(x, 3).func is Derivative assert re(x).diff(x, 2) == Derivative(re(x), (x, 2)) # issue 15518 assert diff(NDimArray([re(x), im(x)]), (x, 2)) == NDimArray( [Derivative(re(x), (x, 2)), Derivative(im(x), (x, 2))]) # it doesn't have y so it shouldn't need a method for this case assert My(x).diff(y) == 0
def test_derivatives_issue_4757(): x = Symbol('x', real=True) y = Symbol('y', imaginary=True) f = Function('f') assert re(f(x)).diff(x) == re(f(x).diff(x)) assert im(f(x)).diff(x) == im(f(x).diff(x)) assert re(f(y)).diff(y) == -I * im(f(y).diff(y)) assert im(f(y)).diff(y) == -I * re(f(y).diff(y)) assert Abs(f(x)).diff(x).subs(f(x), 1 + I * x).doit() == x / sqrt(1 + x**2) assert arg(f(x)).diff(x).subs(f(x), 1 + I * x**2).doit() == 2 * x / (1 + x**4) assert Abs(f(y)).diff(y).subs(f(y), 1 + y).doit() == -y / sqrt(1 - y**2) assert arg(f(y)).diff(y).subs(f(y), I + y**2).doit() == 2 * y / (1 + y**4)
def _eval_evalf(self, prec): """ Careful! any evalf of polar numbers is flaky """ i = im(self.args[0]) try: bad = (i <= -pi or i > pi) except TypeError: bad = True if bad: return self # cannot evalf for this argument res = exp(self.args[0])._eval_evalf(prec) if i > 0 and im(res) < 0: # i ~ pi, but exp(I*i) evaluated to argument slightly bigger than pi return re(res) return res
def test_zero_assumptions(): nr = Symbol('nonreal', real=False, finite=True) ni = Symbol('nonimaginary', imaginary=False) # imaginary implies not zero nzni = Symbol('nonzerononimaginary', zero=False, imaginary=False) assert re(nr).is_zero is None assert im(nr).is_zero is False assert re(ni).is_zero is None assert im(ni).is_zero is None assert re(nzni).is_zero is False assert im(nzni).is_zero is None
def eval(cls, nu, z): if z.is_zero: if nu.is_zero: return S.Infinity elif re(nu).is_zero == False: return S.ComplexInfinity elif re(nu).is_zero: return S.NaN if z.is_imaginary: if im(z) is S.Infinity or im(z) is S.NegativeInfinity: return S.Zero if nu.is_integer: if nu.could_extract_minus_sign(): return besselk(-nu, z)
def eval(cls, nu, z): if z.is_zero: if nu.is_zero: return S.Infinity elif re(nu).is_zero is False: return S.ComplexInfinity elif re(nu).is_zero: return S.NaN if z.is_imaginary: if im(z) is S.Infinity or im(z) is S.NegativeInfinity: return S.Zero if nu.is_integer: if nu.could_extract_minus_sign(): return besselk(-nu, z)
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 __new__(cls, *args, **kwargs): evaluate = kwargs.get('evaluate', global_evaluate[0]) if iterable(args[0]): if isinstance(args[0], Point) and not evaluate: return args[0] args = args[0] # unpack the arguments into a friendly Tuple # if we were already a Point, we're doing an excess # iteration, but we'll worry about efficiency later coords = Tuple(*args) if any(a.is_number and im(a) for a in coords): raise ValueError('Imaginary coordinates not permitted.') # Turn any Floats into rationals and simplify # any expressions before we instantiate if evaluate: coords = coords.xreplace( dict([(f, simplify(nsimplify(f, rational=True))) for f in coords.atoms(Float)])) if len(coords) == 2: return Point2D(coords, **kwargs) if len(coords) == 3: return Point3D(coords, **kwargs) return GeometryEntity.__new__(cls, *coords)
def test_evalf_with_zoo(): assert (1 / x).evalf(subs={x: 0}) == zoo # issue 8242 assert (-1 / x).evalf(subs={x: 0}) == zoo # PR 16150 assert (0**x).evalf(subs={x: -1}) == zoo # PR 16150 assert (0**x).evalf(subs={x: -1 + I}) == nan assert Mul(2, Pow(0, -1, evaluate=False), evaluate=False).evalf() == zoo # issue 21147 assert Mul(x, 1 / x, evaluate=False).evalf(subs={x: 0}) == Mul( x, 1 / x, evaluate=False).subs(x, 0) == nan assert Mul(1 / x, 1 / x, evaluate=False).evalf(subs={x: 0}) == zoo assert Mul(1 / x, Abs(1 / x), evaluate=False).evalf(subs={x: 0}) == zoo assert Abs(zoo, evaluate=False).evalf() == oo assert re(zoo, evaluate=False).evalf() == nan assert im(zoo, evaluate=False).evalf() == nan assert Add(zoo, zoo, evaluate=False).evalf() == nan assert Add(oo, zoo, evaluate=False).evalf() == nan assert Pow(zoo, -1, evaluate=False).evalf() == 0 assert Pow(zoo, Rational(-1, 3), evaluate=False).evalf() == 0 assert Pow(zoo, Rational(1, 3), evaluate=False).evalf() == zoo assert Pow(zoo, S.Half, evaluate=False).evalf() == zoo assert Pow(zoo, 2, evaluate=False).evalf() == zoo assert Pow(0, zoo, evaluate=False).evalf() == nan assert log(zoo, evaluate=False).evalf() == zoo assert zoo.evalf(chop=True) == zoo assert x.evalf(subs={x: zoo}) == zoo
def test_solve_trig(): from sympy.abc import n assert solveset_real(sin(x), x) == Union( imageset(Lambda(n, 2 * pi * n), S.Integers), imageset(Lambda(n, 2 * pi * n + pi), S.Integers) ) assert solveset_real(sin(x) - 1, x) == imageset(Lambda(n, 2 * pi * n + pi / 2), S.Integers) assert solveset_real(cos(x), x) == Union( imageset(Lambda(n, 2 * pi * n - pi / 2), S.Integers), imageset(Lambda(n, 2 * pi * n + pi / 2), S.Integers) ) assert solveset_real(sin(x) + cos(x), x) == Union( imageset(Lambda(n, 2 * n * pi - pi / 4), S.Integers), imageset(Lambda(n, 2 * n * pi + 3 * pi / 4), S.Integers) ) assert solveset_real(sin(x) ** 2 + cos(x) ** 2, x) == S.EmptySet assert solveset_complex(cos(x) - S.Half, x) == Union( imageset(Lambda(n, 2 * n * pi + pi / 3), S.Integers), imageset(Lambda(n, 2 * n * pi - pi / 3), S.Integers) ) y, a = symbols("y,a") assert solveset(sin(y + a) - sin(y), a, domain=S.Reals) == Union( imageset(Lambda(n, 2 * n * pi), S.Integers), imageset(Lambda(n, -I * (I * (2 * n * pi + arg(-exp(-2 * I * y))) + 2 * im(y))), S.Integers), )
def test_solve_sqrt_3(): R = Symbol("R") eq = sqrt(2) * R * sqrt(1 / (R + 1)) + (R + 1) * (sqrt(2) * sqrt(1 / (R + 1)) - 1) sol = solveset_complex(eq, R) assert sol == FiniteSet( *[ S(5) / 3 + 4 * sqrt(10) * cos(atan(3 * sqrt(111) / 251) / 3) / 3, -sqrt(10) * cos(atan(3 * sqrt(111) / 251) / 3) / 3 + 40 * re(1 / ((-S(1) / 2 - sqrt(3) * I / 2) * (S(251) / 27 + sqrt(111) * I / 9) ** (S(1) / 3))) / 9 + sqrt(30) * sin(atan(3 * sqrt(111) / 251) / 3) / 3 + S(5) / 3 + I * ( -sqrt(30) * cos(atan(3 * sqrt(111) / 251) / 3) / 3 - sqrt(10) * sin(atan(3 * sqrt(111) / 251) / 3) / 3 + 40 * im(1 / ((-S(1) / 2 - sqrt(3) * I / 2) * (S(251) / 27 + sqrt(111) * I / 9) ** (S(1) / 3))) / 9 ), ] ) # the number of real roots will depend on the value of m: for m=1 there are 4 # and for m=-1 there are none. eq = -sqrt((m - q) ** 2 + (-m / (2 * q) + S(1) / 2) ** 2) + sqrt( (-m ** 2 / 2 - sqrt(4 * m ** 4 - 4 * m ** 2 + 8 * m + 1) / 4 - S(1) / 4) ** 2 + (m ** 2 / 2 - m - sqrt(4 * m ** 4 - 4 * m ** 2 + 8 * m + 1) / 4 - S(1) / 4) ** 2 ) raises(NotImplementedError, lambda: solveset_real(eq, q))
def test_issue_9778(): assert solveset(x ** 3 + 1, x, S.Reals) == FiniteSet(-1) assert solveset(x ** (S(3) / 5) + 1, x, S.Reals) == S.EmptySet assert solveset(x ** 3 + y, x, S.Reals) == Intersection( Interval(-oo, oo), FiniteSet((-y) ** (S(1) / 3) * Piecewise((1, Ne(-im(y), 0)), ((-1) ** (S(2) / 3), -y < 0), (1, True))), )
def __new__(cls, *args, **kwargs): evaluate = kwargs.get('evaluate', global_evaluate[0]) if iterable(args[0]): if isinstance(args[0], Point) and not evaluate: return args[0] args = args[0] # unpack the arguments into a friendly Tuple # if we were already a Point, we're doing an excess # iteration, but we'll worry about efficiency later coords = Tuple(*args) if any(a.is_number and im(a) for a in coords): raise ValueError('Imaginary coordinates not permitted.') # Turn any Floats into rationals and simplify # any expressions before we instantiate if evaluate: coords = coords.xreplace(dict( [(f, simplify(nsimplify(f, rational=True))) for f in coords.atoms(Float)])) if len(coords) == 2: return Point2D(coords, **kwargs) if len(coords) == 3: return Point3D(coords, **kwargs) return GeometryEntity.__new__(cls, *coords)
def as_real_imag(self): """Returns a tuple of the real part of the input Matrix and it's imaginary part. >>> from sympy import Matrix, I >>> A = Matrix([[1+2*I, 3], [4+7*I, 5]]) >>> A.as_real_imag() (Matrix([ [1, 3], [4, 5]]), Matrix([ [2, 0], [7, 0]])) >>> from sympy.abc import x, y, z, w >>> B = Matrix([[x, y + x * I], [z + w * I, z]]) >>> B.as_real_imag() (Matrix([ [ re(x), re(y) - im(x)], [re(z) - im(w), re(z)]]), Matrix([ [ im(x), re(x) + im(y)], [re(w) + im(z), im(z)]])) """ from sympy.functions.elementary.complexes import re, im real_mat = self._new(self.rows, self.cols, lambda i, j: re(self[i, j])) im_mat = self._new(self.rows, self.cols, lambda i, j: im(self[i, j])) return (real_mat, im_mat)
def test_solve_sqrt_3(): R = Symbol('R') eq = sqrt(2) * R * sqrt(1 / (R + 1)) + (R + 1) * (sqrt(2) * sqrt(1 / (R + 1)) - 1) sol = solveset_complex(eq, R) assert sol == FiniteSet(*[ S(5) / 3 + 4 * sqrt(10) * cos(atan(3 * sqrt(111) / 251) / 3) / 3, -sqrt(10) * cos(atan(3 * sqrt(111) / 251) / 3) / 3 + 40 * re(1 / ((-S(1) / 2 - sqrt(3) * I / 2) * (S(251) / 27 + sqrt(111) * I / 9)**(S(1) / 3))) / 9 + sqrt(30) * sin(atan(3 * sqrt(111) / 251) / 3) / 3 + S(5) / 3 + I * (-sqrt(30) * cos(atan(3 * sqrt(111) / 251) / 3) / 3 - sqrt(10) * sin(atan(3 * sqrt(111) / 251) / 3) / 3 + 40 * im(1 / ( (-S(1) / 2 - sqrt(3) * I / 2) * (S(251) / 27 + sqrt(111) * I / 9)**(S(1) / 3))) / 9) ]) # the number of real roots will depend on the value of m: for m=1 there are 4 # and for m=-1 there are none. eq = -sqrt((m - q)**2 + (-m / (2 * q) + S(1) / 2)**2) + sqrt( (-m**2 / 2 - sqrt(4 * m**4 - 4 * m**2 + 8 * m + 1) / 4 - S(1) / 4)**2 + (m**2 / 2 - m - sqrt(4 * m**4 - 4 * m**2 + 8 * m + 1) / 4 - S(1) / 4)**2) unsolved_object = ConditionSet( q, Eq((-2 * sqrt(4 * q**2 * (m - q)**2 + (-m + q)**2) + sqrt( (-2 * m**2 - sqrt(4 * m**4 - 4 * m**2 + 8 * m + 1) - 1)**2 + (2 * m**2 - 4 * m - sqrt(4 * m**4 - 4 * m**2 + 8 * m + 1) - 1)**2) * Abs(q)) / Abs(q), 0), S.Reals) assert solveset_real(eq, q) == unsolved_object
def test_solve_sqrt_3(): R = Symbol('R') eq = sqrt(2) * R * sqrt(1 / (R + 1)) + (R + 1) * (sqrt(2) * sqrt(1 / (R + 1)) - 1) sol = solveset_complex(eq, R) assert sol == FiniteSet(*[ S(5) / 3 + 4 * sqrt(10) * cos(atan(3 * sqrt(111) / 251) / 3) / 3, -sqrt(10) * cos(atan(3 * sqrt(111) / 251) / 3) / 3 + 40 * re(1 / ((-S(1) / 2 - sqrt(3) * I / 2) * (S(251) / 27 + sqrt(111) * I / 9)**(S(1) / 3))) / 9 + sqrt(30) * sin(atan(3 * sqrt(111) / 251) / 3) / 3 + S(5) / 3 + I * (-sqrt(30) * cos(atan(3 * sqrt(111) / 251) / 3) / 3 - sqrt(10) * sin(atan(3 * sqrt(111) / 251) / 3) / 3 + 40 * im(1 / ( (-S(1) / 2 - sqrt(3) * I / 2) * (S(251) / 27 + sqrt(111) * I / 9)**(S(1) / 3))) / 9) ]) # the number of real roots will depend on the value of m: for m=1 there are 4 # and for m=-1 there are none. eq = -sqrt((m - q)**2 + (-m / (2 * q) + S(1) / 2)**2) + sqrt( (-m**2 / 2 - sqrt(4 * m**4 - 4 * m**2 + 8 * m + 1) / 4 - S(1) / 4)**2 + (m**2 / 2 - m - sqrt(4 * m**4 - 4 * m**2 + 8 * m + 1) / 4 - S(1) / 4)**2) raises(NotImplementedError, lambda: solveset_real(eq, q))
def eval(cls, arg): from sympy.calculus.accumulationbounds import AccumBounds def _eval(arg): if arg in (S.Infinity, S.NegativeInfinity): return AccumBounds(0, 1) if arg.is_integer: return S.Zero if arg.is_number: if arg is S.NaN: return S.NaN elif arg is S.ComplexInfinity: return S.NaN else: return arg - floor(arg) return cls(arg, evaluate=False) terms = Add.make_args(arg) real, imag = S.Zero, S.Zero for t in terms: # Two checks are needed for complex arguments # see issue-7649 for details if t.is_imaginary or (S.ImaginaryUnit * t).is_real: i = im(t) if not i.has(S.ImaginaryUnit): imag += i else: real += t else: real += t real = _eval(real) imag = _eval(imag) return real + S.ImaginaryUnit * imag
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 test_noncircularized_real_imaginary_parts(): # If this passes, lines numbered 3878-3882 (at the time of this commit) # of sympy/solvers/ode.py for nth_linear_constant_coeff_homogeneous # should be removed. y = sqrt(1+x) i, r = im(y), re(y) assert not (i.has(atan2) and r.has(atan2))
def test_quaternion_complex_real_addition(): a = symbols("a", complex=True) b = symbols("b", real=True) # This symbol is not complex: c = symbols("c", commutative=False) q = Quaternion(w, x, y, z) assert a + q == Quaternion(w + re(a), x + im(a), y, z) assert 1 + q == Quaternion(1 + w, x, y, z) assert I + q == Quaternion(w, 1 + x, y, z) assert b + q == Quaternion(w + b, x, y, z) raises(ValueError, lambda: c + q) raises(ValueError, lambda: q * c) raises(ValueError, lambda: c * q) assert -q == Quaternion(-w, -x, -y, -z) q1 = Quaternion(3 + 4*I, 2 + 5*I, 0, 7 + 8*I, real_field = False) q2 = Quaternion(1, 4, 7, 8) assert q1 + (2 + 3*I) == Quaternion(5 + 7*I, 2 + 5*I, 0, 7 + 8*I) assert q2 + (2 + 3*I) == Quaternion(3, 7, 7, 8) assert q1 * (2 + 3*I) == \ Quaternion((2 + 3*I)*(3 + 4*I), (2 + 3*I)*(2 + 5*I), 0, (2 + 3*I)*(7 + 8*I)) assert q2 * (2 + 3*I) == Quaternion(-10, 11, 38, -5) q1 = Quaternion(1, 2, 3, 4) q0 = Quaternion(0, 0, 0, 0) assert q1 + q0 == q1 assert q1 - q0 == q1 assert q1 - q1 == q0
def test_solve_trig(): from sympy.abc import n assert solveset_real(sin(x), x) == \ Union(imageset(Lambda(n, 2*pi*n), S.Integers), imageset(Lambda(n, 2*pi*n + pi), S.Integers)) assert solveset_real(sin(x) - 1, x) == \ imageset(Lambda(n, 2*pi*n + pi/2), S.Integers) assert solveset_real(cos(x), x) == \ Union(imageset(Lambda(n, 2*pi*n - pi/2), S.Integers), imageset(Lambda(n, 2*pi*n + pi/2), S.Integers)) assert solveset_real(sin(x) + cos(x), x) == \ Union(imageset(Lambda(n, 2*n*pi - pi/4), S.Integers), imageset(Lambda(n, 2*n*pi + 3*pi/4), S.Integers)) assert solveset_real(sin(x)**2 + cos(x)**2, x) == S.EmptySet assert solveset_complex(cos(x) - S.Half, x) == \ Union(imageset(Lambda(n, 2*n*pi + pi/3), S.Integers), imageset(Lambda(n, 2*n*pi - pi/3), S.Integers)) y, a = symbols('y,a') assert solveset(sin(y + a) - sin(y), a, domain=S.Reals) == \ Union(imageset(Lambda(n, 2*n*pi), S.Integers), imageset(Lambda(n, -I*(I*(2*n*pi +arg(-exp(-2*I*y))) + 2*im(y))), S.Integers))
def eval(cls, arg, k=0): """ Returns a simplified form or a value of DiracDelta depending on the argument passed by the DiracDelta object. The ``eval()`` method is automatically called when the ``DiracDelta`` class is about to be instantiated and it returns either some simplified instance or the unevaluated instance depending on the argument passed. In other words, ``eval()`` method is not needed to be called explicitly, it is being called and evaluated once the object is called. Examples ======== >>> from sympy import DiracDelta, S, Subs >>> from sympy.abc import x >>> DiracDelta(x) DiracDelta(x) >>> DiracDelta(x,1) DiracDelta(x, 1) >>> DiracDelta(1) 0 >>> DiracDelta(5,1) 0 >>> DiracDelta(0) DiracDelta(0) >>> DiracDelta(-1) 0 >>> DiracDelta(S.NaN) nan >>> DiracDelta(x).eval(1) 0 >>> DiracDelta(x - 100).subs(x, 5) 0 >>> DiracDelta(x - 100).subs(x, 100) DiracDelta(0) """ k = sympify(k) if not k.is_Integer or k.is_negative: raise ValueError("Error: the second argument of DiracDelta must be \ a non-negative integer, %s given instead." % (k,)) arg = sympify(arg) if arg is S.NaN: return S.NaN if arg.is_nonzero: return S.Zero if fuzzy_not(im(arg).is_zero): raise ValueError("Function defined only for Real Values. Complex part: %s found in %s ." % (repr(im(arg)), repr(arg)) )
def eval(cls, arg, k=0): """ Returns a simplified form or a value of DiracDelta depending on the argument passed by the DiracDelta object. The ``eval()`` method is automatically called when the ``DiracDelta`` class is about to be instantiated and it returns either some simplified instance or the unevaluated instance depending on the argument passed. In other words, ``eval()`` method is not needed to be called explicitly, it is being called and evaluated once the object is called. Examples ======== >>> from sympy import DiracDelta, S, Subs >>> from sympy.abc import x >>> DiracDelta(x) DiracDelta(x) >>> DiracDelta(x,1) DiracDelta(x, 1) >>> DiracDelta(1) 0 >>> DiracDelta(5,1) 0 >>> DiracDelta(0) DiracDelta(0) >>> DiracDelta(-1) 0 >>> DiracDelta(S.NaN) nan >>> DiracDelta(x).eval(1) 0 >>> DiracDelta(x - 100).subs(x, 5) 0 >>> DiracDelta(x - 100).subs(x, 100) DiracDelta(0) """ k = sympify(k) if not k.is_Integer or k.is_negative: raise ValueError("Error: the second argument of DiracDelta must be \ a non-negative integer, %s given instead." % (k,)) arg = sympify(arg) if arg is S.NaN: return S.NaN if arg.is_positive or arg.is_negative: return S.Zero if fuzzy_not(im(arg).is_zero): raise ValueError("Function defined only for Real Values. Complex part: %s found in %s ." % (repr(im(arg)), repr(arg)) )
def as_real_imag(self): real_matrices = [re(matrix) for matrix in self.blocks] real_matrices = Matrix(self.blockshape[0], self.blockshape[1], real_matrices) im_matrices = [im(matrix) for matrix in self.blocks] im_matrices = Matrix(self.blockshape[0], self.blockshape[1], im_matrices) return (real_matrices, im_matrices)
def test_evalf_default(): from sympy.functions.special.gamma_functions import polygamma assert type(sin(4.0)) == Float assert type(re(sin(I + 1.0))) == Float assert type(im(sin(I + 1.0))) == Float assert type(sin(4)) == sin assert type(polygamma(2.0, 4.0)) == Float assert type(sin(Rational(1, 4))) == sin
def test_im(): assert refine(im(x), Q.imaginary(x)) == -I*x assert refine(im(x), Q.real(x)) is S.Zero assert refine(im(x+y), Q.imaginary(x) & Q.imaginary(y)) == -I*x - I*y assert refine(im(x+y), Q.real(x) & Q.imaginary(y)) == -I*y assert refine(im(x*y), Q.imaginary(x) & Q.real(y)) == -I*x*y assert refine(im(x*y), Q.imaginary(x) & Q.imaginary(y)) == 0 assert refine(im(1/x), Q.imaginary(x)) == -I/x assert refine(im(x*y*z), Q.imaginary(x) & Q.imaginary(y) & Q.imaginary(z)) == -I*x*y*z
def eval(cls, arg, H0=None): """ Returns a simplified form or a value of Heaviside depending on the argument passed by the Heaviside object. The ``eval()`` method is automatically called when the ``Heaviside`` class is about to be instantiated and it returns either some simplified instance or the unevaluated instance depending on the argument passed. In other words, ``eval()`` method is not needed to be called explicitly, it is being called and evaluated once the object is called. Examples ======== >>> from sympy import Heaviside, S >>> from sympy.abc import x >>> Heaviside(x) Heaviside(x) >>> Heaviside(19) 1 >>> Heaviside(0) Heaviside(0) >>> Heaviside(0, 1) 1 >>> Heaviside(-5) 0 >>> Heaviside(S.NaN) nan >>> Heaviside(x).eval(100) 1 >>> Heaviside(x - 100).subs(x, 5) 0 >>> Heaviside(x - 100).subs(x, 105) 1 """ H0 = sympify(H0) arg = sympify(arg) if arg.is_negative: return S.Zero elif arg.is_positive: return S.One elif arg.is_zero: return H0 elif arg is S.NaN: return S.NaN elif fuzzy_not(im(arg).is_zero): raise ValueError("Function defined only for Real Values. Complex part: %s found in %s ." % (repr(im(arg)), repr(arg)) )
def test_erfi(): assert erfi(nan) is nan assert erfi(oo) is S.Infinity assert erfi(-oo) is S.NegativeInfinity assert erfi(0) is S.Zero assert erfi(I*oo) == I assert erfi(-I*oo) == -I assert erfi(-x) == -erfi(x) assert erfi(I*erfinv(x)) == I*x assert erfi(I*erfcinv(x)) == I*(1 - x) assert erfi(I*erf2inv(0, x)) == I*x assert erfi(I*erf2inv(0, x, evaluate=False)) == I*x # To cover code in erfi assert erfi(I).is_real is False assert erfi(0, evaluate=False).is_real assert erfi(0, evaluate=False).is_zero assert conjugate(erfi(z)) == erfi(conjugate(z)) assert erfi(x).as_leading_term(x) == 2*x/sqrt(pi) assert erfi(x*y).as_leading_term(y) == 2*x*y/sqrt(pi) assert (erfi(x*y)/erfi(y)).as_leading_term(y) == x assert erfi(1/x).as_leading_term(x) == erfi(1/x) assert erfi(z).rewrite('erf') == -I*erf(I*z) assert erfi(z).rewrite('erfc') == I*erfc(I*z) - I assert erfi(z).rewrite('fresnels') == (1 - I)*(fresnelc(z*(1 + I)/sqrt(pi)) - I*fresnels(z*(1 + I)/sqrt(pi))) assert erfi(z).rewrite('fresnelc') == (1 - I)*(fresnelc(z*(1 + I)/sqrt(pi)) - I*fresnels(z*(1 + I)/sqrt(pi))) assert erfi(z).rewrite('hyper') == 2*z*hyper([S.Half], [3*S.Half], z**2)/sqrt(pi) assert erfi(z).rewrite('meijerg') == z*meijerg([S.Half], [], [0], [Rational(-1, 2)], -z**2)/sqrt(pi) assert erfi(z).rewrite('uppergamma') == (sqrt(-z**2)/z*(uppergamma(S.Half, -z**2)/sqrt(S.Pi) - S.One)) assert erfi(z).rewrite('expint') == sqrt(-z**2)/z - z*expint(S.Half, -z**2)/sqrt(S.Pi) assert erfi(z).rewrite('tractable') == -I*(-_erfs(I*z)*exp(z**2) + 1) assert expand_func(erfi(I*z)) == I*erf(z) assert erfi(x).as_real_imag() == \ (erfi(re(x) - I*im(x))/2 + erfi(re(x) + I*im(x))/2, -I*(-erfi(re(x) - I*im(x)) + erfi(re(x) + I*im(x)))/2) assert erfi(x).as_real_imag(deep=False) == \ (erfi(re(x) - I*im(x))/2 + erfi(re(x) + I*im(x))/2, -I*(-erfi(re(x) - I*im(x)) + erfi(re(x) + I*im(x)))/2) assert erfi(w).as_real_imag() == (erfi(w), 0) assert erfi(w).as_real_imag(deep=False) == (erfi(w), 0) raises(ArgumentIndexError, lambda: erfi(x).fdiff(2))
def _do_ellipse_intersection(self, o): """ Find the intersection of two ellipses. """ seq = self.equation() variables = self.equation().atoms(C.Symbol) if len(variables) > 2: return None x, y = variables oeq = o.equation(x=x, y=y) # until the following line works... # result = solve([seq, oeq], [x, y]) # return [Point(*r) for r in result if im(r[0]).is_zero and im(r[1]).is_zero] # we do this: if self.center[0] == o.center[0] or self.center[1] == o.center[1]: result = solve_poly_system([seq, oeq], x, y) return [Point(*r) for r in result if im(r[0]).is_zero and im(r[1]).is_zero] raise NotImplementedError("Off-axis Ellipse intersection not supported.")
def eval(cls, arg): arg = sympify(arg) if arg is S.NaN: return S.NaN elif fuzzy_not(im(arg).is_zero): raise ValueError("Function defined only for Real Values. Complex part: %s found in %s ." % (repr(im(arg)), repr(arg)) ) elif arg.is_negative: return S.Zero elif arg.is_positive: return S.One
def add(self, other): """Adds quaternions. Parameters ========== other : Quaternion The quaternion to add to current (self) quaternion. Returns ======= Quaternion The resultant quaternion after adding self to other Examples ======== >>> from sympy import Quaternion >>> from sympy import symbols >>> q1 = Quaternion(1, 2, 3, 4) >>> q2 = Quaternion(5, 6, 7, 8) >>> q1.add(q2) 6 + 8*i + 10*j + 12*k >>> q1 + 5 6 + 2*i + 3*j + 4*k >>> x = symbols('x', real = True) >>> q1.add(x) (x + 1) + 2*i + 3*j + 4*k Quaternions over complex fields : >>> from sympy import Quaternion >>> from sympy import I >>> q3 = Quaternion(3 + 4*I, 2 + 5*I, 0, 7 + 8*I, real_field = False) >>> q3.add(2 + 3*I) (5 + 7*I) + (2 + 5*I)*i + 0*j + (7 + 8*I)*k """ q1 = self q2 = sympify(other) # If q2 is a number or a SymPy expression instead of a quaternion if not isinstance(q2, Quaternion): if q1.real_field and q2.is_complex: return Quaternion(re(q2) + q1.a, im(q2) + q1.b, q1.c, q1.d) elif q2.is_commutative: return Quaternion(q1.a + q2, q1.b, q1.c, q1.d) else: raise ValueError( "Only commutative expressions can be added with a Quaternion." ) return Quaternion(q1.a + q2.a, q1.b + q2.b, q1.c + q2.c, q1.d + q2.d)
def as_real_imag(self): """Returns tuple containing (real , imaginary) part of sparse matrix""" from sympy.functions.elementary.complexes import re, im real_smat = self.copy() im_smat = self.copy() for key, value in self._smat.items(): real_smat._smat[key] = re(value) im_smat._smat[key] = im(value) return (real_smat, im_smat)
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 eval(cls, nu, z): if z.is_zero: if nu.is_zero: return S.One elif (nu.is_integer and nu.is_zero is False) or re(nu).is_positive: return S.Zero elif re(nu).is_negative and not (nu.is_integer is True): return S.ComplexInfinity elif nu.is_imaginary: return S.NaN if z.is_imaginary: if im(z) is S.Infinity or im(z) is S.NegativeInfinity: return S.Zero if z.could_extract_minus_sign(): return (z) ** nu * (-z) ** (-nu) * besseli(nu, -z) if nu.is_integer: if nu.could_extract_minus_sign(): return besseli(-nu, z) newz = z.extract_multiplicatively(I) if newz: # NOTE we don't want to change the function if z==0 return I ** (-nu) * besselj(nu, -newz) # branch handling: from sympy import unpolarify, exp if nu.is_integer: newz = unpolarify(z) if newz != z: return besseli(nu, newz) else: newz, n = z.extract_branch_factor() if n != 0: return exp(2 * n * pi * nu * I) * besseli(nu, newz) nnu = unpolarify(nu) if nu != nnu: return besseli(nnu, z)
def test_solve_sqrt_3(): R = Symbol("R") eq = sqrt(2) * R * sqrt(1 / (R + 1)) + (R + 1) * (sqrt(2) * sqrt(1 / (R + 1)) - 1) sol = solveset_complex(eq, R) assert sol == FiniteSet( *[ S(5) / 3 + 4 * sqrt(10) * cos(atan(3 * sqrt(111) / 251) / 3) / 3, -sqrt(10) * cos(atan(3 * sqrt(111) / 251) / 3) / 3 + 40 * re(1 / ((-S(1) / 2 - sqrt(3) * I / 2) * (S(251) / 27 + sqrt(111) * I / 9) ** (S(1) / 3))) / 9 + sqrt(30) * sin(atan(3 * sqrt(111) / 251) / 3) / 3 + S(5) / 3 + I * ( -sqrt(30) * cos(atan(3 * sqrt(111) / 251) / 3) / 3 - sqrt(10) * sin(atan(3 * sqrt(111) / 251) / 3) / 3 + 40 * im(1 / ((-S(1) / 2 - sqrt(3) * I / 2) * (S(251) / 27 + sqrt(111) * I / 9) ** (S(1) / 3))) / 9 ), ] ) # the number of real roots will depend on the value of m: for m=1 there are 4 # and for m=-1 there are none. eq = -sqrt((m - q) ** 2 + (-m / (2 * q) + S(1) / 2) ** 2) + sqrt( (-m ** 2 / 2 - sqrt(4 * m ** 4 - 4 * m ** 2 + 8 * m + 1) / 4 - S(1) / 4) ** 2 + (m ** 2 / 2 - m - sqrt(4 * m ** 4 - 4 * m ** 2 + 8 * m + 1) / 4 - S(1) / 4) ** 2 ) unsolved_object = ConditionSet( q, Eq( ( -2 * sqrt(4 * q ** 2 * (m - q) ** 2 + (-m + q) ** 2) + sqrt( (-2 * m ** 2 - sqrt(4 * m ** 4 - 4 * m ** 2 + 8 * m + 1) - 1) ** 2 + (2 * m ** 2 - 4 * m - sqrt(4 * m ** 4 - 4 * m ** 2 + 8 * m + 1) - 1) ** 2 ) * Abs(q) ) / Abs(q), 0, ), S.Reals, ) assert solveset_real(eq, q) == unsolved_object
def __new__(cls, *args, **kwargs): eval = kwargs.get('evaluate', global_evaluate[0]) check = True if isinstance(args[0], Point): if not eval: return args[0] args = args[0].args check = False else: if iterable(args[0]): args = args[0] if len(args) != 2: raise ValueError( "Only two dimensional points currently supported") coords = Tuple(*args) if check: if any(a.is_number and im(a) for a in coords): raise ValueError('Imaginary args not permitted.') if eval: coords = coords.xreplace(dict( [(f, simplify(nsimplify(f, rational=True))) for f in coords.atoms(Float)])) return GeometryEntity.__new__(cls, *coords)
def get_integer_part(expr, no, options, return_ints=False): """ With no = 1, computes ceiling(expr) With no = -1, computes floor(expr) Note: this function either gives the exact result or signals failure. """ from sympy.functions.elementary.complexes import re, im # The expression is likely less than 2^30 or so assumed_size = 30 ire, iim, ire_acc, iim_acc = evalf(expr, assumed_size, options) # We now know the size, so we can calculate how much extra precision # (if any) is needed to get within the nearest integer if ire and iim: gap = max(fastlog(ire) - ire_acc, fastlog(iim) - iim_acc) elif ire: gap = fastlog(ire) - ire_acc elif iim: gap = fastlog(iim) - iim_acc else: # ... or maybe the expression was exactly zero return None, None, None, None margin = 10 if gap >= -margin: ire, iim, ire_acc, iim_acc = \ evalf(expr, margin + assumed_size + gap, options) # We can now easily find the nearest integer, but to find floor/ceil, we # must also calculate whether the difference to the nearest integer is # positive or negative (which may fail if very close). def calc_part(expr, nexpr): from sympy.core.add import Add nint = int(to_int(nexpr, rnd)) n, c, p, b = nexpr is_int = (p == 0) if not is_int: # if there are subs and they all contain integer re/im parts # then we can (hopefully) safely substitute them into the # expression s = options.get('subs', False) if s: doit = True from sympy.core.compatibility import as_int for v in s.values(): try: as_int(v) except ValueError: try: [as_int(i) for i in v.as_real_imag()] continue except (ValueError, AttributeError): doit = False break if doit: expr = expr.subs(s) expr = Add(expr, -nint, evaluate=False) x, _, x_acc, _ = evalf(expr, 10, options) try: check_target(expr, (x, None, x_acc, None), 3) except PrecisionExhausted: if not expr.equals(0): raise PrecisionExhausted x = fzero nint += int(no*(mpf_cmp(x or fzero, fzero) == no)) nint = from_int(nint) return nint, fastlog(nint) + 10 re_, im_, re_acc, im_acc = None, None, None, None if ire: re_, re_acc = calc_part(re(expr, evaluate=False), ire) if iim: im_, im_acc = calc_part(im(expr, evaluate=False), iim) if return_ints: return int(to_int(re_ or fzero)), int(to_int(im_ or fzero)) return re_, im_, re_acc, im_acc
def test_sympy__functions__elementary__complexes__im(): from sympy.functions.elementary.complexes import im assert _test_args(im(x))
def _cast_nocheck(self, value): from sympy.functions import re, im return ( super(ComplexType, self)._cast_nocheck(re(value)) + super(ComplexType, self)._cast_nocheck(im(value))*1j )
def _check(self, value): from sympy.functions import re, im super(ComplexType, self)._check(re(value)) super(ComplexType, self)._check(im(value))
def as_real_imag(self): return (re(Matrix(self)), im(Matrix(self)))
def eval(cls, variable, offset, exponent): """ Returns a simplified form or a value of Singularity Function depending on the argument passed by the object. The ``eval()`` method is automatically called when the ``SingularityFunction`` class is about to be instantiated and it returns either some simplified instance or the unevaluated instance depending on the argument passed. In other words, ``eval()`` method is not needed to be called explicitly, it is being called and evaluated once the object is called. Examples ======== >>> from sympy import SingularityFunction, Symbol, nan >>> from sympy.abc import x, a, n >>> SingularityFunction(x, a, n) SingularityFunction(x, a, n) >>> SingularityFunction(5, 3, 2) 4 >>> SingularityFunction(x, a, nan) nan >>> SingularityFunction(x, 3, 0).subs(x, 3) 1 >>> SingularityFunction(x, a, n).eval(3, 5, 1) 0 >>> SingularityFunction(x, a, n).eval(4, 1, 5) 243 >>> x = Symbol('x', positive = True) >>> a = Symbol('a', negative = True) >>> n = Symbol('n', nonnegative = True) >>> SingularityFunction(x, a, n) (-a + x)**n >>> x = Symbol('x', negative = True) >>> a = Symbol('a', positive = True) >>> SingularityFunction(x, a, n) 0 """ x = sympify(variable) a = sympify(offset) n = sympify(exponent) shift = (x - a) if fuzzy_not(im(shift).is_zero): raise ValueError("Singularity Functions are defined only for Real Numbers.") if fuzzy_not(im(n).is_zero): raise ValueError("Singularity Functions are not defined for imaginary exponents.") if shift is S.NaN or n is S.NaN: return S.NaN if (n + 2).is_negative: raise ValueError("Singularity Functions are not defined for exponents less than -2.") if shift.is_negative: return S.Zero if n.is_nonnegative and shift.is_nonnegative: return (x - a)**n if n == -1 or n == -2: if shift.is_negative or shift.is_positive: return S.Zero if shift.is_zero: return S.Infinity
def __new__(cls, *args, **kwargs): evaluate = kwargs.get('evaluate', global_evaluate[0]) on_morph = kwargs.get('on_morph', 'ignore') # unpack into coords coords = args[0] if len(args) == 1 else args # check args and handle quickly handle Point instances if isinstance(coords, Point): # even if we're mutating the dimension of a point, we # don't reevaluate its coordinates evaluate = False if len(coords) == kwargs.get('dim', len(coords)): return coords if not is_sequence(coords): raise TypeError(filldedent(''' Expecting sequence of coordinates, not `{}`''' .format(func_name(coords)))) # A point where only `dim` is specified is initialized # to zeros. if len(coords) == 0 and kwargs.get('dim', None): coords = (S.Zero,)*kwargs.get('dim') coords = Tuple(*coords) dim = kwargs.get('dim', len(coords)) if len(coords) < 2: raise ValueError(filldedent(''' Point requires 2 or more coordinates or keyword `dim` > 1.''')) if len(coords) != dim: message = ("Dimension of {} needs to be changed" "from {} to {}.").format(coords, len(coords), dim) if on_morph == 'ignore': pass elif on_morph == "error": raise ValueError(message) elif on_morph == 'warn': warnings.warn(message) else: raise ValueError(filldedent(''' on_morph value should be 'error', 'warn' or 'ignore'.''')) if any(i for i in coords[dim:]): raise ValueError('Nonzero coordinates cannot be removed.') if any(a.is_number and im(a) for a in coords): raise ValueError('Imaginary coordinates are not permitted.') if not all(isinstance(a, Expr) for a in coords): raise TypeError('Coordinates must be valid SymPy expressions.') # pad with zeros appropriately coords = coords[:dim] + (S.Zero,)*(dim - len(coords)) # Turn any Floats into rationals and simplify # any expressions before we instantiate if evaluate: coords = coords.xreplace(dict( [(f, simplify(nsimplify(f, rational=True))) for f in coords.atoms(Float)])) # return 2D or 3D instances if len(coords) == 2: kwargs['_nocheck'] = True return Point2D(*coords, **kwargs) elif len(coords) == 3: kwargs['_nocheck'] = True return Point3D(*coords, **kwargs) # the general Point return GeometryEntity.__new__(cls, *coords)