def _eval_rewrite_as_besseli(self, z): ot = Rational(1, 3) tt = Rational(2, 3) a = C.Pow(z, Rational(3, 2)) if re(z).is_positive: return ot*sqrt(z) * (besseli(-ot, tt*a) - besseli(ot, tt*a)) else: return ot*(C.Pow(a, ot)*besseli(-ot, tt*a) - z*C.Pow(a, -ot)*besseli(ot, tt*a))
def _eval_rewrite_as_Sum(self, arg): if arg.is_even: k = C.Dummy("k", integer=True) j = C.Dummy("j", integer=True) n = self.args[0] / 2 Em = (S.ImaginaryUnit * C.Sum( C.Sum( C.binomial(k, j) * ((-1)**j * (k - 2*j)**(2*n + 1)) / (2**k*S.ImaginaryUnit**k * k), (j, 0, k)), (k, 1, 2*n + 1))) return Em
def _show_NT_np_p2(max_p): '''[n>=p**2]: NT(n,p**2) = C(n,p**2) - [p\n]C(n/p,p) [n>=p]: NT(n*p,p**2) = C(n*p,p**2) - C(n,p) ''' for p in primes(max_p): f = C(n * p, p**2) - C(n, p) g = f.factor() print('NT(n*p, {p}**2) = {f}'.format(p=p, f=g))
def _eval_rewrite_as_besseli(self, z): ot = Rational(1, 3) tt = Rational(2, 3) a = C.Pow(z, Rational(3, 2)) if re(z).is_positive: return sqrt(z)/sqrt(3) * (besseli(-ot, tt*a) + besseli(ot, tt*a)) else: b = C.Pow(a, ot) c = C.Pow(a, -ot) return sqrt(ot)*(b*besseli(-ot, tt*a) + z*c*besseli(ot, tt*a))
def ufuncify(args, expr, **kwargs): """ Generates a binary ufunc-like lambda function for numpy arrays ``args`` Either a Symbol or a tuple of symbols. Specifies the argument sequence for the ufunc-like function. ``expr`` A SymPy expression that defines the element wise operation ``kwargs`` Optional keyword arguments are forwarded to autowrap(). The returned function can only act on one array at a time, as only the first argument accept arrays as input. .. Note:: a *proper* numpy ufunc is required to support broadcasting, type casting and more. The function returned here, may not qualify for numpy's definition of a ufunc. That why we use the term ufunc-like. References ========== [1] http://docs.scipy.org/doc/numpy/reference/ufuncs.html Examples ======== >>> from sympy.utilities.autowrap import ufuncify >>> from sympy.abc import x, y >>> import numpy as np >>> f = ufuncify([x, y], y + x**2) >>> f([1, 2, 3], 2) [ 3. 6. 11.] >>> a = f(np.arange(5), 3) >>> isinstance(a, np.ndarray) True >>> print a [ 3. 4. 7. 12. 19.] """ y = C.IndexedBase(C.Dummy('y')) x = C.IndexedBase(C.Dummy('x')) m = C.Dummy('m', integer=True) i = C.Dummy('i', integer=True) i = C.Idx(i, m) l = C.Lambda(args, expr) f = implemented_function('f', l) if isinstance(args, C.Symbol): args = [args] else: args = list(args) # ensure correct order of arguments kwargs['args'] = [y, x] + args[1:] + [m] # first argument accepts an array args[0] = x[i] return autowrap(C.Equality(y[i], f(*args)), **kwargs)
def _eval_rewrite_as_besseli(self, z): ot = Rational(1, 3) tt = Rational(2, 3) a = tt * C.Pow(z, Rational(3, 2)) if re(z).is_positive: return z/sqrt(3) * (besseli(-tt, a) + besseli(tt, a)) else: a = C.Pow(z, Rational(3, 2)) b = C.Pow(a, tt) c = C.Pow(a, -tt) return sqrt(ot) * (b*besseli(-tt, tt*a) + z**2*c*besseli(tt, tt*a))
def taylor_term(n, x, *previous_terms): if n < 0: return S.Zero else: x = sympify(x) if len(previous_terms) > 1: p = previous_terms[-1] return (3**(S(1)/3)*x * Abs(sin(2*pi*(n + S.One)/S(3))) * C.factorial((n - S.One)/S(3)) / ((n + S.One) * Abs(cos(2*pi*(n + S.Half)/S(3))) * C.factorial((n - 2)/S(3))) * p) else: return (S.One/(root(3, 6)*pi) * gamma((n + S.One)/S(3)) * Abs(sin(2*pi*(n + S.One)/S(3))) / C.factorial(n) * (root(3, 3)*x)**n)
def taylor_term(n, x, *previous_terms): if n < 0: return S.Zero else: x = sympify(x) if len(previous_terms) > 1: p = previous_terms[-1] return ((3**(S(1)/3)*x)**(-n)*(3**(S(1)/3)*x)**(n + 1)*sin(pi*(2*n/3 + S(4)/3))*C.factorial(n) * gamma(n/3 + S(2)/3)/(sin(pi*(2*n/3 + S(2)/3))*C.factorial(n + 1)*gamma(n/3 + S(1)/3)) * p) else: return (S.One/(3**(S(2)/3)*pi) * gamma((n+S.One)/S(3)) * sin(2*pi*(n+S.One)/S(3)) / C.factorial(n) * (root(3, 3)*x)**n)
def Zlm(l, m, th, ph): from sympy import simplify if m > 0: zz = C.NegativeOne()**m*(Ylm(l, m, th, ph) + Ylm_c(l, m, th, ph))/sqrt(2) elif m == 0: return Ylm(l, m, th, ph) else: zz = C.NegativeOne()**m*(Ylm(l, -m, th, ph) - Ylm_c(l, -m, th, ph))/(I*sqrt(2)) zz = zz.expand(complex=True) zz = simplify(zz) return zz
def _calc_bernoulli(n): s = 0 a = int(C.binomial(n+3, n-6)) for j in xrange(1, n//6+1): s += a * bernoulli(n - 6*j) # Avoid computing each binomial coefficient from scratch a *= _product(n-6 - 6*j + 1, n-6*j) a //= _product(6*j+4, 6*j+9) if n % 6 == 4: s = -Rational(n+3, 6) - s else: s = Rational(n+3, 3) - s return s / C.binomial(n+3, n)
def _calc_bernoulli(n): s = 0 a = int(C.Binomial(n + 3, n - 6)) for j in xrange(1, n // 6 + 1): s += a * bernoulli(n - 6 * j) # Avoid computing each binomial coefficient from scratch a *= _product(n - 6 - 6 * j + 1, n - 6 * j) a //= _product(6 * j + 4, 6 * j + 9) if n % 6 == 4: s = -Rational(n + 3, 6) - s else: s = Rational(n + 3, 3) - s return s / C.Binomial(n + 3, n)
def calc_B(m, base): assert m >= 0 L = m + 1 Cs = [C(m, j) for j in range(L)] B = [[c * (i + base)**(m - j) for j, c in zip(range(L), Cs)] for i in range(L)] return Matrix(B)
def test_subfactorial(): assert all(subfactorial(i) == ans for i, ans in enumerate( [1, 0, 1, 2, 9, 44, 265, 1854, 14833, 133496])) assert subfactorial(oo) == oo x = Symbol('x') assert subfactorial(x).rewrite(C.uppergamma) == \ C.uppergamma(x + 1, -1)/S.Exp1 tt = Symbol('tt', integer=True, nonnegative=True) tf = Symbol('tf', integer=True, nonnegative=False) tn = Symbol('tf', integer=True) ft = Symbol('ft', integer=False, nonnegative=True) ff = Symbol('ff', integer=False, nonnegative=False) fn = Symbol('ff', integer=False) nt = Symbol('nt', nonnegative=True) nf = Symbol('nf', nonnegative=False) nn = Symbol('nf') assert subfactorial(tt).is_integer assert subfactorial(tf).is_integer is None assert subfactorial(tn).is_integer is None assert subfactorial(ft).is_integer is None assert subfactorial(ff).is_integer is None assert subfactorial(fn).is_integer is None assert subfactorial(nt).is_integer is None assert subfactorial(nf).is_integer is None assert subfactorial(nn).is_integer is None
def _print_Pow(self, expr): base = self._print(expr.base) if ('_' in base or '^' in base) and 'cdot' not in base: mode = True else: mode = False # Treat x**Rational(1,n) as special case if expr.exp.is_Rational and abs(expr.exp.p) == 1 and expr.exp.q != 1: expq = expr.exp.q if expq == 2: tex = r"\sqrt{%s}" % base elif self._settings['itex']: tex = r"\root{%d}{%s}" % (expq, base) else: tex = r"\sqrt[%d]{%s}" % (expq, base) if expr.exp.is_negative: return r"\frac{1}{%s}" % tex else: return tex elif self._settings['fold_frac_powers'] \ and expr.exp.is_Rational \ and expr.exp.q != 1: base, p, q = self._print(expr.base), expr.exp.p, expr.exp.q if mode: return r"{\lp %s \rp}^{%s/%s}" % (base, p, q) else: return r"%s^{%s/%s}" % (base, p, q) elif expr.exp.is_Rational and expr.exp.is_negative and expr.base.is_Function: # Things like 1/x return r"\frac{%s}{%s}" % \ (1, self._print(C.Pow(expr.base, -expr.exp))) else: if expr.base.is_Function: return self._print(expr.base, self._print(expr.exp)) else: if expr.is_commutative and expr.exp == -1: """ solves issue 4129 As Mul always simplify 1/x to x**-1 The objective is achieved with this hack first we get the latex for -1 * expr, which is a Mul expression """ tex = self._print(S.NegativeOne * expr).strip() # the result comes with a minus and a space, so we remove if tex[:1] == "-": return tex[1:].strip() if self._needs_brackets(expr.base): tex = r"\left(%s\right)^{%s}" else: if mode: tex = r"{\lp %s \rp}^{%s}" else: tex = r"%s^{%s}" return tex % (self._print(expr.base), self._print(expr.exp))
def choose_without_period(n, k): r'''NT n k = sum Mu d * C(n/d, k/d) {d\gcd(n,k)} for [(n,k)!=(0,0)] NT 0 0 = 1 ''' if (n, k) == (0, 0): return 1 return sum(Mu_d * C(n // d, k // d) for Mu_d, d in iter_Mu(gcd(n, k)))
def _eval_rewrite_as_Sum(self, arg): if arg.is_even: k = C.Dummy("k", integer=True) j = C.Dummy("j", integer=True) n = self.args[0] / 2 Em = (S.ImaginaryUnit * C.Sum( C.Sum( C.binomial(k,j) * ((-1)**j * (k-2*j)**(2*n+1)) / (2**k*S.ImaginaryUnit**k * k), (j,0,k)), (k, 1, 2*n+1))) return Em
def ufuncify(args, expr, **kwargs): """Generates a binary ufunc-like lambda function for numpy arrays ``args`` Either a Symbol or a tuple of symbols. Specifies the argument sequence for the ufunc-like function. ``expr`` A Sympy expression that defines the element wise operation ``kwargs`` Optional keyword arguments are forwarded to autowrap(). The returned function can only act on one array at a time, as only the first argument accept arrays as input. .. Note:: a *proper* numpy ufunc is required to support broadcasting, type casting and more. The function returned here, may not qualify for numpy's definition of a ufunc. That why we use the term ufunc-like. See http://docs.scipy.org/doc/numpy/reference/ufuncs.html :Examples: >>> from sympy.utilities.autowrap import ufuncify >>> from sympy.abc import x, y, z >>> f = ufuncify([x, y], y + x**2) # doctest: +SKIP >>> f([1, 2, 3], 2) # doctest: +SKIP [2. 5. 10.] """ y = C.IndexedBase(C.Dummy('y')) x = C.IndexedBase(C.Dummy('x')) m = C.Dummy('m', integer=True) i = C.Dummy('i', integer=True) i = C.Idx(i, m) l = C.Lambda(args, expr) f = implemented_function('f', l) if isinstance(args, C.Symbol): args = [args] else: args = list(args) # first argument accepts an array args[0] = x[i] return autowrap(C.Equality(y[i], f(*args)), **kwargs)
def full(self): # remove unused commands self.clean() # evalf for command in self.commands: command.expr = mypowsimp(mycollectsimp(command.expr.evalf())) command.expr = command.expr.subs(C.Real(-1.0), -1) command.expr = command.expr.subs(C.Real(-2.0), -2) # substitute as much as possible while self.autosub(level=0): pass while self.autosub(level=1): pass # substitute back temporary variables that are used only once self.singles() # mypowsimp for command in self.commands: command.expr = mypowsimp(command.expr) command.expr = command.expr.subs(C.Real(-1.0), -1) command.expr = command.expr.subs(C.Real(-2.0), -2)
def mypowsimp(expr): def find_double_pow(expr): for sub in preorder_traversal(expr): if isinstance(sub, C.Pow) and isinstance(sub.base, C.Pow): return sub while True: sub = find_double_pow(expr) if sub is None: break expr = expr.subs(sub, C.Pow(sub.base.base, sub.exp*sub.base.exp)) return expr
def Pow(expr, assumptions): """ Real**Integer -> Real Positive**Real -> Real Real**(Integer/Even) -> Real if base is nonnegative Real**(Integer/Odd) -> Real Imaginary**(Integer/Even) -> Real Imaginary**(Integer/Odd) -> not Real Imaginary**Real -> ? since Real could be 0 (giving real) or 1 (giving imaginary) b**Imaginary -> Real if log(b) is imaginary and b != 0 and exponent != integer multiple of I*pi/log(b) Real**Real -> ? e.g. sqrt(-1) is imaginary and sqrt(2) is not """ if expr.is_number: return AskRealHandler._number(expr, assumptions) if expr.base.func == C.exp: if ask(Q.imaginary(expr.base.args[0]), assumptions): if ask(Q.imaginary(expr.exp), assumptions): return True # If the i = (exp's arg)/(I*pi) is an integer or half-integer # multiple of I*pi then 2*i will be an integer. In addition, # exp(i*I*pi) = (-1)**i so the overall realness of the expr # can be determined by replacing exp(i*I*pi) with (-1)**i. i = expr.base.args[0] / I / pi if ask(Q.integer(2 * i), assumptions): return ask(Q.real(((-1)**i)**expr.exp), assumptions) return if ask(Q.imaginary(expr.base), assumptions): if ask(Q.integer(expr.exp), assumptions): odd = ask(Q.odd(expr.exp), assumptions) if odd is not None: return not odd return if ask(Q.imaginary(expr.exp), assumptions): imlog = ask(Q.imaginary(C.log(expr.base)), assumptions) if imlog is not None: # I**i -> real, log(I) is imag; # (2*I)**i -> complex, log(2*I) is not imag return imlog if ask(Q.real(expr.base), assumptions): if ask(Q.real(expr.exp), assumptions): if expr.exp.is_Rational and \ ask(Q.even(expr.exp.q), assumptions): return ask(Q.positive(expr.base), assumptions) elif ask(Q.integer(expr.exp), assumptions): return True elif ask(Q.positive(expr.base), assumptions): return True elif ask(Q.negative(expr.base), assumptions): return False
def Pow(expr, assumptions): """ Real**Integer -> Real Positive**Real -> Real Real**(Integer/Even) -> Real if base is nonnegative Real**(Integer/Odd) -> Real Imaginary**(Integer/Even) -> Real Imaginary**(Integer/Odd) -> not Real Imaginary**Real -> ? since Real could be 0 (giving real) or 1 (giving imaginary) b**Imaginary -> Real if log(b) is imaginary and b != 0 and exponent != integer multiple of I*pi/log(b) Real**Real -> ? e.g. sqrt(-1) is imaginary and sqrt(2) is not """ if expr.is_number: return AskRealHandler._number(expr, assumptions) if expr.base.func == C.exp: if ask(Q.imaginary(expr.base.args[0]), assumptions): if ask(Q.imaginary(expr.exp), assumptions): return True # If the i = (exp's arg)/(I*pi) is an integer or half-integer # multiple of I*pi then 2*i will be an integer. In addition, # exp(i*I*pi) = (-1)**i so the overall realness of the expr # can be determined by replacing exp(i*I*pi) with (-1)**i. i = expr.base.args[0]/I/pi if ask(Q.integer(2*i), assumptions): return ask(Q.real(((-1)**i)**expr.exp), assumptions) return if ask(Q.imaginary(expr.base), assumptions): if ask(Q.integer(expr.exp), assumptions): odd = ask(Q.odd(expr.exp), assumptions) if odd is not None: return not odd return if ask(Q.imaginary(expr.exp), assumptions): imlog = ask(Q.imaginary(C.log(expr.base)), assumptions) if imlog is not None: # I**i -> real, log(I) is imag; # (2*I)**i -> complex, log(2*I) is not imag return imlog if ask(Q.real(expr.base), assumptions): if ask(Q.real(expr.exp), assumptions): if expr.exp.is_Rational and \ ask(Q.even(expr.exp.q), assumptions): return ask(Q.positive(expr.base), assumptions) elif ask(Q.integer(expr.exp), assumptions): return True elif ask(Q.positive(expr.base), assumptions): return True elif ask(Q.negative(expr.base), assumptions): return False
def test_curve(): s = Symbol('s') z = Symbol('z') # this curve is independent of the indicated parameter C = Curve([2*s, s**2], (z, 0, 2)) assert C.parameter == z assert C.functions == (2*s, s**2) assert C.arbitrary_point() == Point(2*s, s**2) assert C.arbitrary_point(z) == Point(2*s, s**2) # this is how it is normally used C = Curve([2*s, s**2], (s, 0, 2)) assert C.parameter == s assert C.functions == (2*s, s**2) t = Symbol('t') assert C.arbitrary_point() != Point(2*t, t**2) # the t returned as assumptions t = Symbol('t', real=True) # now t has the same assumptions so the test passes assert C.arbitrary_point() == Point(2*t, t**2) assert C.arbitrary_point(z) == Point(2*z, z**2) assert C.arbitrary_point(C.parameter) == Point(2*s, s**2) raises(ValueError, 'Curve((s, s + t), (s, 1, 2)).arbitrary_point()') raises(ValueError, 'Curve((s, s + t), (t, 1, 2)).arbitrary_point(s)')
def test_curve(): s = Symbol("s") z = Symbol("z") # this curve is independent of the indicated parameter C = Curve([2 * s, s ** 2], (z, 0, 2)) assert C.parameter == z assert C.functions == (2 * s, s ** 2) assert C.arbitrary_point() == Point(2 * s, s ** 2) assert C.arbitrary_point(z) == Point(2 * s, s ** 2) # this is how it is normally used C = Curve([2 * s, s ** 2], (s, 0, 2)) assert C.parameter == s assert C.functions == (2 * s, s ** 2) t = Symbol("t") assert C.arbitrary_point() != Point(2 * t, t ** 2) # the t returned as assumptions t = Symbol("t", real=True) # now t has the same assumptions so the test passes assert C.arbitrary_point() == Point(2 * t, t ** 2) assert C.arbitrary_point(z) == Point(2 * z, z ** 2) assert C.arbitrary_point(C.parameter) == Point(2 * s, s ** 2) raises(ValueError, "Curve((s, s + t), (s, 1, 2)).arbitrary_point()") raises(ValueError, "Curve((s, s + t), (t, 1, 2)).arbitrary_point(s)")
def canonize(cls, n, sym=None): if n.is_Number: if n.is_Integer and n.is_nonnegative: if n is S.Zero: return S.One elif n is S.One: if sym is None: return -S.Half else: return sym - S.Half # Bernoulli numbers elif sym is None: if n.is_odd: return S.Zero n = int(n) # Use mpmath for enormous Bernoulli numbers if n > 500: p, q = bernfrac(n) return Rational(int(p), q) case = n % 6 highest_cached = cls._highest[case] if n <= highest_cached: return cls._cache[n] # To avoid excessive recursion when, say, bernoulli(1000) is # requested, calculate and cache the entire sequence ... B_988, # B_994, B_1000 in increasing order for i in xrange(highest_cached + 6, n + 6, 6): b = cls._calc_bernoulli(i) cls._cache[i] = b cls._highest[case] = i return b # Bernoulli polynomials else: n, result = int(n), [] for k in xrange(n + 1): result.append(C.Binomial(n, k) * cls(k) * sym**(n - k)) return C.Add(*result) else: raise ValueError("Bernoulli numbers are defined only" " for nonnegative integer indices.")
def eval(cls, n, m=None): if m is None: m = S.One if n == oo: return C.zeta(m) if n.is_Integer and n.is_nonnegative and m.is_Integer: if n == 0: return S.Zero if not m in cls._functions: @recurrence_memo([0]) def f(n, prev): return prev[-1] + S.One / n**m cls._functions[m] = f return cls._functions[m](int(n))
def Pow(expr, assumptions): """ Imaginary**Odd -> Imaginary Imaginary**Even -> Real b**Imaginary -> !Imaginary if exponent is an integer multiple of I*pi/log(b) Imaginary**Real -> ? Positive**Real -> Real Negative**Integer -> Real Negative**(Integer/2) -> Imaginary Negative**Real -> not Imaginary if exponent is not Rational """ if expr.is_number: return AskImaginaryHandler._number(expr, assumptions) if expr.base.func == C.exp: if ask(Q.imaginary(expr.base.args[0]), assumptions): if ask(Q.imaginary(expr.exp), assumptions): return False i = expr.base.args[0] / I / pi if ask(Q.integer(2 * i), assumptions): return ask(Q.imaginary(((-1)**i)**expr.exp), assumptions) if ask(Q.imaginary(expr.base), assumptions): if ask(Q.integer(expr.exp), assumptions): odd = ask(Q.odd(expr.exp), assumptions) if odd is not None: return odd return if ask(Q.imaginary(expr.exp), assumptions): imlog = ask(Q.imaginary(C.log(expr.base)), assumptions) if imlog is not None: return False # I**i -> real; (2*I)**i -> complex ==> not imaginary if ask(Q.real(expr.base) & Q.real(expr.exp), assumptions): if ask(Q.positive(expr.base), assumptions): return False else: rat = ask(Q.rational(expr.exp), assumptions) if not rat: return rat if ask(Q.integer(expr.exp), assumptions): return False else: half = ask(Q.integer(2 * expr.exp), assumptions) if half: return ask(Q.negative(expr.base), assumptions) return half
def Pow(expr, assumptions): """ Imaginary**Odd -> Imaginary Imaginary**Even -> Real b**Imaginary -> !Imaginary if exponent is an integer multiple of I*pi/log(b) Imaginary**Real -> ? Positive**Real -> Real Negative**Integer -> Real Negative**(Integer/2) -> Imaginary Negative**Real -> not Imaginary if exponent is not Rational """ if expr.is_number: return AskImaginaryHandler._number(expr, assumptions) if expr.base.func == C.exp: if ask(Q.imaginary(expr.base.args[0]), assumptions): if ask(Q.imaginary(expr.exp), assumptions): return False i = expr.base.args[0]/I/pi if ask(Q.integer(2*i), assumptions): return ask(Q.imaginary(((-1)**i)**expr.exp), assumptions) if ask(Q.imaginary(expr.base), assumptions): if ask(Q.integer(expr.exp), assumptions): odd = ask(Q.odd(expr.exp), assumptions) if odd is not None: return odd return if ask(Q.imaginary(expr.exp), assumptions): imlog = ask(Q.imaginary(C.log(expr.base)), assumptions) if imlog is not None: return False # I**i -> real; (2*I)**i -> complex ==> not imaginary if ask(Q.real(expr.base) & Q.real(expr.exp), assumptions): if ask(Q.positive(expr.base), assumptions): return False else: rat = ask(Q.rational(expr.exp), assumptions) if not rat: return rat if ask(Q.integer(expr.exp), assumptions): return False else: half = ask(Q.integer(2*expr.exp), assumptions) if half: return ask(Q.negative(expr.base), assumptions) return half
def Pow(expr, assumptions): """ Imaginary**integer/odd -> Imaginary Imaginary**integer/even -> Real if integer % 2 == 0 b**Imaginary -> !Imaginary if exponent is an integer multiple of I*pi/log(b) Imaginary**Real -> ? Negative**even root -> Imaginary Negative**odd root -> Real Negative**Real -> Imaginary Real**Integer -> Real Real**Positive -> Real """ if expr.is_number: return AskImaginaryHandler._number(expr, assumptions) if expr.base.func == C.exp: if ask(Q.imaginary(expr.base.args[0]), assumptions): if ask(Q.imaginary(expr.exp), assumptions): return False i = expr.base.args[0] / I / pi if ask(Q.integer(2 * i), assumptions): return ask(Q.imaginary(((-1)**i)**expr.exp), assumptions) if ask(Q.imaginary(expr.base), assumptions): if ask(Q.integer(expr.exp), assumptions): odd = ask(Q.odd(expr.exp), assumptions) if odd is not None: return odd return if ask(Q.imaginary(expr.exp), assumptions): imlog = ask(Q.imaginary(C.log(expr.base)), assumptions) if imlog is not None: return False # I**i -> real; (2*I)**i -> complex ==> not imaginary if ask(Q.real(expr.base), assumptions): if ask(Q.real(expr.exp), assumptions): if ask( Q.rational(expr.exp) & Q.even(denom(expr.exp)), assumptions): return ask(Q.negative(expr.base), assumptions) elif ask(Q.integer(expr.exp), assumptions): return False elif ask(Q.positive(expr.base), assumptions): return False elif ask(Q.negative(expr.base), assumptions): return True
def Pow(expr, assumptions): """ Imaginary**integer/odd -> Imaginary Imaginary**integer/even -> Real if integer % 2 == 0 b**Imaginary -> !Imaginary if exponent is an integer multiple of I*pi/log(b) Imaginary**Real -> ? Negative**even root -> Imaginary Negative**odd root -> Real Negative**Real -> Imaginary Real**Integer -> Real Real**Positive -> Real """ if expr.is_number: return AskImaginaryHandler._number(expr, assumptions) if expr.base.func == C.exp: if ask(Q.imaginary(expr.base.args[0]), assumptions): if ask(Q.imaginary(expr.exp), assumptions): return False i = expr.base.args[0]/I/pi if ask(Q.integer(2*i), assumptions): return ask(Q.imaginary(((-1)**i)**expr.exp), assumptions) if ask(Q.imaginary(expr.base), assumptions): if ask(Q.integer(expr.exp), assumptions): odd = ask(Q.odd(expr.exp), assumptions) if odd is not None: return odd return if ask(Q.imaginary(expr.exp), assumptions): imlog = ask(Q.imaginary(C.log(expr.base)), assumptions) if imlog is not None: return False # I**i -> real; (2*I)**i -> complex ==> not imaginary if ask(Q.real(expr.base), assumptions): if ask(Q.real(expr.exp), assumptions): if ask(Q.rational(expr.exp) & Q.even(denom(expr.exp)), assumptions): return ask(Q.negative(expr.base), assumptions) elif ask(Q.integer(expr.exp), assumptions): return False elif ask(Q.positive(expr.base), assumptions): return False elif ask(Q.negative(expr.base), assumptions): return True
def test_subfactorial(): assert all( subfactorial(i) == ans for i, ans in enumerate([1, 0, 1, 2, 9, 44, 265, 1854, 14833, 133496])) assert subfactorial(oo) == oo x = Symbol('x') assert subfactorial(x).rewrite(C.uppergamma) == \ C.uppergamma(x + 1, -1)/S.Exp1 tt = Symbol('tt', integer=True, nonnegative=True) tf = Symbol('tf', integer=True, nonnegative=False) tn = Symbol('tf', integer=True) ft = Symbol('ft', integer=False, nonnegative=True) ff = Symbol('ff', integer=False, nonnegative=False) fn = Symbol('ff', integer=False) nt = Symbol('nt', nonnegative=True) nf = Symbol('nf', nonnegative=False) nn = Symbol('nf') te = Symbol('te', even=True, nonnegative=True) to = Symbol('to', odd=True, nonnegative=True) assert subfactorial(tt).is_integer assert subfactorial(tf).is_integer is None assert subfactorial(tn).is_integer is None assert subfactorial(ft).is_integer is None assert subfactorial(ff).is_integer is None assert subfactorial(fn).is_integer is None assert subfactorial(nt).is_integer is None assert subfactorial(nf).is_integer is None assert subfactorial(nn).is_integer is None assert subfactorial(tt).is_nonnegative assert subfactorial(tf).is_nonnegative is None assert subfactorial(tn).is_nonnegative is None assert subfactorial(ft).is_nonnegative is None assert subfactorial(ff).is_nonnegative is None assert subfactorial(fn).is_nonnegative is None assert subfactorial(nt).is_nonnegative is None assert subfactorial(nf).is_nonnegative is None assert subfactorial(nn).is_nonnegative is None assert subfactorial(tt).is_even is None assert subfactorial(tt).is_odd is None assert subfactorial(te).is_odd is True assert subfactorial(to).is_even is True
def Ylm(l, m, theta, phi): """ Spherical harmonics Ylm. Examples: >>> from sympy import symbols, Ylm >>> theta, phi = symbols("theta phi") >>> Ylm(0, 0, theta, phi) 1/(2*sqrt(pi)) >>> Ylm(1, -1, theta, phi) sqrt(6)*exp(-I*phi)*sin(theta)/(4*sqrt(pi)) >>> Ylm(1, 0, theta, phi) sqrt(3)*cos(theta)/(2*sqrt(pi)) """ l, m, theta, phi = [sympify(x) for x in (l, m, theta, phi)] factorial = C.factorial return sqrt((2*l+1)/(4*pi) * factorial(l-m)/factorial(l+m)) * \ Plmcos(l, m, theta) * C.exp(I*m*phi)
def Ylm(l, m, theta, phi): """ Spherical harmonics Ylm. Examples: >>> from sympy import symbols, Ylm >>> theta, phi = symbols("theta phi") >>> Ylm(0, 0, theta, phi) 1/(2*pi**(1/2)) >>> Ylm(1, -1, theta, phi) 6**(1/2)*exp(-I*phi)*sin(theta)/(4*pi**(1/2)) >>> Ylm(1, 0, theta, phi) 3**(1/2)*cos(theta)/(2*pi**(1/2)) """ l, m, theta, phi = [sympify(x) for x in (l, m, theta, phi)] factorial = C.Factorial return sqrt((2*l+1)/(4*pi) * factorial(l-m)/factorial(l+m)) * \ Plmcos(l, m, theta) * C.exp(I*m*phi)
def eval(cls, n, sym=None): if n.is_Number: if n.is_Integer and n.is_nonnegative: if n is S.Zero: return S.One elif n is S.One: if sym is None: return -S.Half else: return sym - S.Half # Bernoulli numbers elif sym is None: if n.is_odd: return S.Zero n = int(n) # Use mpmath for enormous Bernoulli numbers if n > 500: p, q = bernfrac(n) return Rational(int(p), int(q)) case = n % 6 highest_cached = cls._highest[case] if n <= highest_cached: return cls._cache[n] # To avoid excessive recursion when, say, bernoulli(1000) is # requested, calculate and cache the entire sequence ... B_988, # B_994, B_1000 in increasing order for i in xrange(highest_cached + 6, n + 6, 6): b = cls._calc_bernoulli(i) cls._cache[i] = b cls._highest[case] = i return b # Bernoulli polynomials else: n, result = int(n), [] for k in xrange(n + 1): result.append(C.binomial(n, k)*cls(k)*sym**(n - k)) return Add(*result) else: raise ValueError("Bernoulli numbers are defined only" " for nonnegative integer indices.")
def _minpoly_sin(ex, x): """ Returns the minimal polynomial of ``sin(ex)`` see http://mathworld.wolfram.com/TrigonometryAngles.html """ from sympy.functions.combinatorial.factorials import binomial c, a = ex.args[0].as_coeff_Mul() if a is pi: if c.is_rational: n = c.q q = sympify(n) if q.is_prime: # for a = pi*p/q with q odd prime, using chebyshevt # write sin(q*a) = mp(sin(a))*sin(a); # the roots of mp(x) are sin(pi*p/q) for p = 1,..., q - 1 a = dup_chebyshevt(n, ZZ) return Add(*[x**(n - i - 1) * a[i] for i in range(n)]) if c.p == 1: if q == 9: return 64 * x**6 - 96 * x**4 + 36 * x**2 - 3 if n % 2 == 1: # for a = pi*p/q with q odd, use # sin(q*a) = 0 to see that the minimal polynomial must be # a factor of dup_chebyshevt(n, ZZ) a = dup_chebyshevt(n, ZZ) a = [x**(n - i) * a[i] for i in range(n + 1)] r = Add(*a) _, factors = factor_list(r) res = _choose_factor(factors, x, ex) return res expr = ((1 - C.cos(2 * c * pi)) / 2)**S.Half res = _minpoly_compose(expr, x, QQ) return res raise NotAlgebraic("%s doesn't seem to be an algebraic element" % ex)
def _minpoly_sin(ex, x): """ Returns the minimal polynomial of ``sin(ex)`` see http://mathworld.wolfram.com/TrigonometryAngles.html """ from sympy.functions.combinatorial.factorials import binomial c, a = ex.args[0].as_coeff_Mul() if a is pi: if c.is_rational: n = c.q q = sympify(n) if q.is_prime: # for a = pi*p/q with q odd prime, using chebyshevt # write sin(q*a) = mp(sin(a))*sin(a); # the roots of mp(x) are sin(pi*p/q) for p = 1,..., q - 1 a = dup_chebyshevt(n, ZZ) return Add(*[x**(n - i - 1)*a[i] for i in range(n)]) if c.p == 1: if q == 9: return 64*x**6 - 96*x**4 + 36*x**2 - 3 if n % 2 == 1: # for a = pi*p/q with q odd, use # sin(q*a) = 0 to see that the minimal polynomial must be # a factor of dup_chebyshevt(n, ZZ) a = dup_chebyshevt(n, ZZ) a = [x**(n - i)*a[i] for i in range(n + 1)] r = Add(*a) _, factors = factor_list(r) res = _choose_factor(factors, x, ex) return res expr = ((1 - C.cos(2*c*pi))/2)**S.Half res = _minpoly_compose(expr, x, QQ) return res raise NotAlgebraic("%s doesn't seem to be an algebraic element" % ex)
def test_line(): p1 = Point(0, 0) p2 = Point(1, 1) p3 = Point(x1, x1) p4 = Point(y1, y1) p5 = Point(x1, 1 + x1) p6 = Point(1, 0) p7 = Point(0, 1) p8 = Point(2, 0) p9 = Point(2, 1) l1 = Line(p1, p2) l2 = Line(p3, p4) l3 = Line(p3, p5) l4 = Line(p1, p6) l5 = Line(p1, p7) l6 = Line(p8, p9) l7 = Line(p2, p9) raises(ValueError, lambda: Line(Point(0, 0), Point(0, 0))) # Basic stuff assert Line((1, 1), slope=1) == Line((1, 1), (2, 2)) assert Line((1, 1), slope=oo) == Line((1, 1), (1, 2)) assert Line((1, 1), slope=-oo) == Line((1, 1), (1, 2)) raises(ValueError, lambda: Line((1, 1), 1)) assert Line(p1, p2) == Line(p2, p1) assert l1 == l2 assert l1 != l3 assert l1.slope == 1 assert l1.length == oo assert l3.slope == oo assert l4.slope == 0 assert l4.coefficients == (0, 1, 0) assert l4.equation(x=x, y=y) == y assert l5.slope == oo assert l5.coefficients == (1, 0, 0) assert l5.equation() == x assert l6.equation() == x - 2 assert l7.equation() == y - 1 assert p1 in l1 # is p1 on the line l1? assert p1 not in l3 assert Line((-x, x), (-x + 1, x - 1)).coefficients == (1, 1, 0) assert simplify(l1.equation()) in (x - y, y - x) assert simplify(l3.equation()) in (x - x1, x1 - x) assert Line(p1, p2).scale(2, 1) == Line(p1, p9) assert l2.arbitrary_point() in l2 for ind in xrange(0, 5): assert l3.random_point() in l3 # Orthogonality p1_1 = Point(-x1, x1) l1_1 = Line(p1, p1_1) assert l1.perpendicular_line(p1) == l1_1 assert Line.is_perpendicular(l1, l1_1) assert Line.is_perpendicular(l1, l2) == False p = l1.random_point() assert l1.perpendicular_segment(p) == p # Parallelity p2_1 = Point(-2 * x1, 0) l2_1 = Line(p3, p5) assert l2.parallel_line(p1_1) == Line(p2_1, p1_1) assert l2_1.parallel_line(p1) == Line(p1, Point(0, 2)) assert Line.is_parallel(l1, l2) assert Line.is_parallel(l2, l3) == False assert Line.is_parallel(l2, l2.parallel_line(p1_1)) assert Line.is_parallel(l2_1, l2_1.parallel_line(p1)) # Intersection assert intersection(l1, p1) == [p1] assert intersection(l1, p5) == [] assert intersection(l1, l2) in [[l1], [l2]] assert intersection(l1, l1.parallel_line(p5)) == [] # Concurrency l3_1 = Line(Point(5, x1), Point(-Rational(3, 5), x1)) assert Line.is_concurrent(l1) == False assert Line.is_concurrent(l1, l3) assert Line.is_concurrent(l1, l3, l3_1) assert Line.is_concurrent(l1, l1_1, l3) == False # Projection assert l2.projection(p4) == p4 assert l1.projection(p1_1) == p1 assert l3.projection(p2) == Point(x1, 1) raises(GeometryError, lambda: Line(Point(0, 0), Point(1, 0)).projection(Circle(Point(0, 0), 1))) # Finding angles l1_1 = Line(p1, Point(5, 0)) assert feq(Line.angle_between(l1, l1_1).evalf(), pi.evalf() / 4) # Testing Rays and Segments (very similar to Lines) assert Ray((1, 1), angle=pi / 4) == Ray((1, 1), (2, 2)) assert Ray((1, 1), angle=pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=-pi / 2) == Ray((1, 1), (1, 0)) assert Ray((1, 1), angle=-3 * pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=5 * pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=5.0 * pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=pi) == Ray((1, 1), (0, 1)) assert Ray((1, 1), angle=3.0 * pi) == Ray((1, 1), (0, 1)) assert Ray((1, 1), angle=4.0 * pi) == Ray((1, 1), (2, 1)) assert Ray((1, 1), angle=0) == Ray((1, 1), (2, 1)) # XXX don't know why this fails without str assert str(Ray((1, 1), angle=4.2 * pi)) == str(Ray(Point(1, 1), Point(2, 1 + C.tan(0.2 * pi)))) assert Ray((1, 1), angle=5) == Ray((1, 1), (2, 1 + C.tan(5))) raises(ValueError, lambda: Ray((1, 1), 1)) r1 = Ray(p1, Point(-1, 5)) r2 = Ray(p1, Point(-1, 1)) r3 = Ray(p3, p5) r4 = Ray(p1, p2) r5 = Ray(p2, p1) r6 = Ray(Point(0, 1), Point(1, 2)) r7 = Ray(Point(0.5, 0.5), Point(1, 1)) assert l1.projection(r1) == Ray(p1, p2) assert l1.projection(r2) == p1 assert r3 != r1 t = Symbol("t", real=True) assert Ray((1, 1), angle=pi / 4).arbitrary_point() == Point(1 / (1 - t), 1 / (1 - t)) s1 = Segment(p1, p2) s2 = Segment(p1, p1_1) assert s1.midpoint == Point(Rational(1, 2), Rational(1, 2)) assert s2.length == sqrt(2 * (x1 ** 2)) assert s1.perpendicular_bisector() == Line(Point(0, 1), Point(1, 0)) assert Segment((1, 1), (2, 3)).arbitrary_point() == Point(1 + t, 1 + 2 * t) # intersections assert s1.intersection(Line(p6, p9)) == [] s3 = Segment(Point(0.25, 0.25), Point(0.5, 0.5)) assert s1.intersection(s3) == [s1] assert s3.intersection(s1) == [s3] assert r4.intersection(s3) == [s3] assert r4.intersection(Segment(Point(2, 3), Point(3, 4))) == [] assert r4.intersection(Segment(Point(-1, -1), Point(0.5, 0.5))) == [Segment(p1, Point(0.5, 0.5))] s3 = Segment(Point(1, 1), Point(2, 2)) assert s1.intersection(s3) == [Point(1, 1)] s3 = Segment(Point(0.5, 0.5), Point(1.5, 1.5)) assert s1.intersection(s3) == [Segment(Point(0.5, 0.5), p2)] assert s1.intersection(Segment(Point(4, 4), Point(5, 5))) == [] assert s1.intersection(Segment(Point(-1, -1), p1)) == [p1] assert s1.intersection(Segment(Point(-1, -1), Point(0.5, 0.5))) == [Segment(p1, Point(0.5, 0.5))] assert r4.intersection(r5) == [s1] assert r5.intersection(r6) == [] assert r4.intersection(r7) == r7.intersection(r4) == [r7] # Segment contains a, b = symbols("a,b") s = Segment((0, a), (0, b)) assert Point(0, (a + b) / 2) in s s = Segment((a, 0), (b, 0)) assert Point((a + b) / 2, 0) in s raises(Undecidable, lambda: Point(2 * a, 0) in s) # Testing distance from a Segment to an object s1 = Segment(Point(0, 0), Point(1, 1)) s2 = Segment(Point(half, half), Point(1, 0)) pt1 = Point(0, 0) pt2 = Point(Rational(3) / 2, Rational(3) / 2) assert s1.distance(pt1) == 0 assert s2.distance(pt1) == 2 ** (half) / 2 assert s2.distance(pt2) == 2 ** (half) # Special cases of projection and intersection r1 = Ray(Point(1, 1), Point(2, 2)) r2 = Ray(Point(2, 2), Point(0, 0)) r3 = Ray(Point(1, 1), Point(-1, -1)) r4 = Ray(Point(0, 4), Point(-1, -5)) r5 = Ray(Point(2, 2), Point(3, 3)) assert intersection(r1, r2) == [Segment(Point(1, 1), Point(2, 2))] assert intersection(r1, r3) == [Point(1, 1)] assert r1.projection(r3) == Point(1, 1) assert r1.projection(r4) == Segment(Point(1, 1), Point(2, 2)) r5 = Ray(Point(0, 0), Point(0, 1)) r6 = Ray(Point(0, 0), Point(0, 2)) assert r5 in r6 assert r6 in r5 s1 = Segment(Point(0, 0), Point(2, 2)) s2 = Segment(Point(-1, 5), Point(-5, -10)) s3 = Segment(Point(0, 4), Point(-2, 2)) assert intersection(r1, s1) == [Segment(Point(1, 1), Point(2, 2))] assert r1.projection(s2) == Segment(Point(1, 1), Point(2, 2)) assert s3.projection(r1) == Segment(Point(0, 4), Point(-1, 3)) l1 = Line(Point(0, 0), Point(3, 4)) r1 = Ray(Point(0, 0), Point(3, 4)) s1 = Segment(Point(0, 0), Point(3, 4)) assert intersection(l1, l1) == [l1] assert intersection(l1, r1) == [r1] assert intersection(l1, s1) == [s1] assert intersection(r1, l1) == [r1] assert intersection(s1, l1) == [s1] entity1 = Segment(Point(-10, 10), Point(10, 10)) entity2 = Segment(Point(-5, -5), Point(-5, 5)) assert intersection(entity1, entity2) == [] r1 = Ray(p1, Point(0, 1)) r2 = Ray(Point(0, 1), p1) r3 = Ray(p1, p2) r4 = Ray(p2, p1) s1 = Segment(p1, Point(0, 1)) assert Line(r1.source, r1.random_point()).slope == r1.slope assert Line(r2.source, r2.random_point()).slope == r2.slope assert Segment(Point(0, -1), s1.random_point()).slope == s1.slope p_r3 = r3.random_point() p_r4 = r4.random_point() assert p_r3.x >= p1.x and p_r3.y >= p1.y assert p_r4.x <= p2.x and p_r4.y <= p2.y p10 = Point(2000, 2000) s1 = Segment(p1, p10) p_s1 = s1.random_point() assert p1.x <= p_s1.x and p_s1.x <= p10.x and p1.y <= p_s1.y and p_s1.y <= p10.y s2 = Segment(p10, p1) assert hash(s1) == hash(s2) p11 = p10.scale(2, 2) assert s1.is_similar(Segment(p10, p11)) assert s1.is_similar(r1) == False assert (r1 in s1) == False assert Segment(p1, p2) in s1 assert s1.plot_interval() == [t, 0, 1] assert s1 in Line(p1, p10) assert Line(p1, p10) == Line(p10, p1) assert Line(p1, p10) != p1 assert Line(p1, p10).plot_interval() == [t, -5, 5] assert Ray((0, 0), angle=pi / 4).plot_interval() == [t, 0, 5 * sqrt(2) / (1 + 5 * sqrt(2))]
def _eval_rewrite_as_hyper(self,n): return C.hyper([1-n,-n],[2],1)
def _eval_rewrite_as_gamma(self,n): # The gamma function allows to generalize Catalan numbers to complex n return 4**n*C.gamma(n + S.Half)/(C.gamma(S.Half)*C.gamma(n+2))
def _eval_rewrite_as_binomial(self,n): return C.binomial(2*n,n)/(n + 1)
def fdiff(self, argindex=1): n = self.args[0] return catalan(n)*(C.polygamma(0,n+Rational(1,2))-C.polygamma(0,n+2)+C.log(4))
def eval(cls, n, evaluate=True): if n.is_Integer and n.is_nonnegative: return 4**n*C.gamma(n + S.Half)/(C.gamma(S.Half)*C.gamma(n+2))
def Ylm(l, m, theta, phi): l, m, theta, phi = [sympify(x) for x in (l, m, theta, phi)] factorial = C.Factorial return sqrt((2 * l + 1) / (4 * pi) * factorial(l - m) / factorial(l + m)) * Plmcos(l, m, theta) * C.exp(I * m * phi)
def test_ellipse(): p1 = Point(0, 0) p2 = Point(1, 1) p4 = Point(0, 1) e1 = Ellipse(p1, 1, 1) e2 = Ellipse(p2, half, 1) e3 = Ellipse(p1, y1, y1) c1 = Circle(p1, 1) c2 = Circle(p2, 1) c3 = Circle(Point(sqrt(2), sqrt(2)), 1) # Test creation with three points cen, rad = Point(3 * half, 2), 5 * half assert Circle(Point(0, 0), Point(3, 0), Point(0, 4)) == Circle(cen, rad) raises(GeometryError, "Circle(Point(0,0), Point(1,1), Point(2,2))") raises(ValueError, "Ellipse(None, None, None, 1)") raises(GeometryError, "Circle(Point(0,0))") # Basic Stuff assert Ellipse(None, 1, 1).center == Point(0, 0) assert e1 == c1 assert e1 != e2 assert p4 in e1 assert p2 not in e2 assert e1.area == pi assert e2.area == pi / 2 assert e3.area == pi * (y1**2) assert c1.area == e1.area assert c1.circumference == e1.circumference assert e3.circumference == 2 * pi * y1 assert e1.plot_interval() == e2.plot_interval() == [t, -pi, pi] assert e1.plot_interval(x) == e2.plot_interval(x) == [x, -pi, pi] assert Ellipse(None, 1, None, 1).circumference == 2 * pi assert c1.minor == 1 # Private Functions assert hash(c1) == hash(Circle(Point(1, 0), Point(0, 1), Point(0, -1))) assert c1 in e1 assert (Line(p1, p2) in e1) == False assert e1.__cmp__(e1) == 0 assert e1.__cmp__(Point(0, 0)) > 0 # Encloses assert e1.encloses(Segment(Point(-0.5, -0.5), Point(0.5, 0.5))) == True assert e1.encloses(Line(p1, p2)) == False assert e1.encloses(Ray(p1, p2)) == False assert e1.encloses(e1) == False assert e1.encloses( Polygon(Point(-0.5, -0.5), Point(-0.5, 0.5), Point(0.5, 0.5))) == True assert e1.encloses(RegularPolygon(p1, 0.5, 3)) == True assert e1.encloses(RegularPolygon(p1, 5, 3)) == False assert e1.encloses(RegularPolygon(p2, 5, 3)) == False # with generic symbols, the hradius is assumed to contain the major radius M = Symbol('M') m = Symbol('m') c = Ellipse(p1, M, m).circumference _x = c.atoms(Dummy).pop() assert c == \ 4*M*C.Integral(sqrt((1 - _x**2*(M**2 - m**2)/M**2)/(1 - _x**2)), (_x, 0, 1)) assert e2.arbitrary_point() in e2 # Foci f1, f2 = Point(sqrt(12), 0), Point(-sqrt(12), 0) ef = Ellipse(Point(0, 0), 4, 2) assert ef.foci in [(f1, f2), (f2, f1)] # Tangents v = sqrt(2) / 2 p1_1 = Point(v, v) p1_2 = p2 + Point(half, 0) p1_3 = p2 + Point(0, 1) assert e1.tangent_lines(p4) == c1.tangent_lines(p4) assert e2.tangent_lines(p1_2) == [Line(p1_2, p2 + Point(half, 1))] assert e2.tangent_lines(p1_3) == [Line(p1_3, p2 + Point(half, 1))] assert c1.tangent_lines(p1_1) == [Line(p1_1, Point(0, sqrt(2)))] assert c1.tangent_lines(p1) == [] assert e2.is_tangent(Line(p1_2, p2 + Point(half, 1))) assert e2.is_tangent(Line(p1_3, p2 + Point(half, 1))) assert c1.is_tangent(Line(p1_1, Point(0, sqrt(2)))) assert e1.is_tangent(Line(Point(0, 0), Point(1, 1))) == False assert c1.is_tangent(e1) == False assert c1.is_tangent(Ellipse(Point(2, 0), 1, 1)) == True assert c1.is_tangent(Polygon(Point(1, 1), Point(1, -1), Point(2, 0))) == True assert c1.is_tangent(Polygon(Point(1, 1), Point(1, 0), Point(2, 0))) == False assert Ellipse(Point(5, 5), 2, 1).tangent_lines(Point(0, 0)) == \ [Line(Point(0, 0), Point(S(77)/25, S(132)/25)), Line(Point(0, 0), Point(S(33)/5, S(22)/5))] assert Ellipse(Point(5, 5), 2, 1).tangent_lines(Point(3, 4)) == \ [Line(Point(3, 4), Point(4, 4)), Line(Point(3, 4), Point(3, 5))] assert Circle(Point(5, 5), 2).tangent_lines(Point(3, 3)) == \ [Line(Point(3, 3), Point(4, 3)), Line(Point(3, 3), Point(3, 4))] assert Circle(Point(5, 5), 2).tangent_lines(Point(5 - 2*sqrt(2), 5)) == \ [Line(Point(5 - 2*sqrt(2), 5), Point(5 - sqrt(2), 5 - sqrt(2))), Line(Point(5 - 2*sqrt(2), 5), Point(5 - sqrt(2), 5 + sqrt(2))),] # Properties major = 3 minor = 1 e4 = Ellipse(p2, minor, major) assert e4.focus_distance == sqrt(major**2 - minor**2) ecc = e4.focus_distance / major assert e4.eccentricity == ecc assert e4.periapsis == major * (1 - ecc) assert e4.apoapsis == major * (1 + ecc) # independent of orientation e4 = Ellipse(p2, major, minor) assert e4.focus_distance == sqrt(major**2 - minor**2) ecc = e4.focus_distance / major assert e4.eccentricity == ecc assert e4.periapsis == major * (1 - ecc) assert e4.apoapsis == major * (1 + ecc) # Intersection l1 = Line(Point(1, -5), Point(1, 5)) l2 = Line(Point(-5, -1), Point(5, -1)) l3 = Line(Point(-1, -1), Point(1, 1)) l4 = Line(Point(-10, 0), Point(0, 10)) pts_c1_l3 = [ Point(sqrt(2) / 2, sqrt(2) / 2), Point(-sqrt(2) / 2, -sqrt(2) / 2) ] assert intersection(e2, l4) == [] assert intersection(c1, Point(1, 0)) == [Point(1, 0)] assert intersection(c1, l1) == [Point(1, 0)] assert intersection(c1, l2) == [Point(0, -1)] assert intersection(c1, l3) in [pts_c1_l3, [pts_c1_l3[1], pts_c1_l3[0]]] assert intersection(c1, c2) in [[(1, 0), (0, 1)], [(0, 1), (1, 0)]] assert intersection(c1, c3) == [(sqrt(2) / 2, sqrt(2) / 2)] assert e1.intersection(l1) == [Point(1, 0)] assert e2.intersection(l4) == [] assert e1.intersection(Circle(Point(0, 2), 1)) == [Point(0, 1)] assert e1.intersection(Circle(Point(5, 0), 1)) == [] assert e1.intersection(Ellipse(Point(2, 0), 1, 1)) == [Point(1, 0)] assert e1.intersection(Ellipse( Point(5, 0), 1, 1, )) == [] assert e1.intersection(Point(2, 0)) == [] assert e1.intersection(e1) == e1 # some special case intersections csmall = Circle(p1, 3) cbig = Circle(p1, 5) cout = Circle(Point(5, 5), 1) # one circle inside of another assert csmall.intersection(cbig) == [] # separate circles assert csmall.intersection(cout) == [] # coincident circles assert csmall.intersection(csmall) == csmall v = sqrt(2) t1 = Triangle(Point(0, v), Point(0, -v), Point(v, 0)) points = intersection(t1, c1) assert len(points) == 4 assert Point(0, 1) in points assert Point(0, -1) in points assert Point(v / 2, v / 2) in points assert Point(v / 2, -v / 2) in points circ = Circle(Point(0, 0), 5) elip = Ellipse(Point(0, 0), 5, 20) assert intersection(circ, elip) in \ [[Point(5, 0), Point(-5, 0)], [Point(-5, 0), Point(5, 0)]] assert elip.tangent_lines(Point(0, 0)) == [] elip = Ellipse(Point(0, 0), 3, 2) assert elip.tangent_lines(Point(3, 0)) == [Line(Point(3, 0), Point(3, -12))] e1 = Ellipse(Point(0, 0), 5, 10) e2 = Ellipse(Point(2, 1), 4, 8) a = S(53) / 17 c = 2 * sqrt(3991) / 17 ans = [Point(a - c / 8, a / 2 + c), Point(a + c / 8, a / 2 - c)] assert e1.intersection(e2) == ans e2 = Ellipse(Point(x, y), 4, 8) ans = list(reversed(ans)) assert [p.subs({x: 2, y: 1}) for p in e1.intersection(e2)] == ans # Combinations of above assert e3.is_tangent(e3.tangent_lines(p1 + Point(y1, 0))[0]) e = Ellipse((1, 2), 3, 2) assert e.tangent_lines(Point(10, 0)) == \ [Line(Point(10, 0), Point(1, 0)), Line(Point(10, 0), Point(S(14)/5, S(18)/5))] # encloses_point e = Ellipse((0, 0), 1, 2) assert e.encloses_point(e.center) assert e.encloses_point(e.center + Point(0, e.vradius - Rational(1, 10))) assert e.encloses_point(e.center + Point(e.hradius - Rational(1, 10), 0)) assert e.encloses_point(e.center + Point(e.hradius, 0)) is False assert e.encloses_point(e.center + Point(e.hradius + Rational(1, 10), 0)) is False e = Ellipse((0, 0), 2, 1) assert e.encloses_point(e.center) assert e.encloses_point(e.center + Point(0, e.vradius - Rational(1, 10))) assert e.encloses_point(e.center + Point(e.hradius - Rational(1, 10), 0)) assert e.encloses_point(e.center + Point(e.hradius, 0)) is False assert e.encloses_point(e.center + Point(e.hradius + Rational(1, 10), 0)) is False assert c1.encloses_point(Point(1, 0)) is False assert c1.encloses_point(Point(0.3, 0.4)) is True
def test_line(): p1 = Point(0, 0) p2 = Point(1, 1) p3 = Point(x1, x1) p4 = Point(y1, y1) p5 = Point(x1, 1 + x1) p6 = Point(1, 0) p7 = Point(0, 1) p8 = Point(2, 0) p9 = Point(2, 1) l1 = Line(p1, p2) l2 = Line(p3, p4) l3 = Line(p3, p5) l4 = Line(p1, p6) l5 = Line(p1, p7) l6 = Line(p8, p9) l7 = Line(p2, p9) raises(ValueError, 'Line(Point(0, 0), Point(0, 0))') # Basic stuff assert Line((1, 1), slope=1) == Line((1, 1), (2, 2)) assert Line((1, 1), slope=oo) == Line((1, 1), (1, 2)) assert Line((1, 1), slope=-oo) == Line((1, 1), (1, 2)) raises(ValueError, 'Line((1, 1), 1)') assert Line(p1, p2) == Line(p2, p1) assert l1 == l2 assert l1 != l3 assert l1.slope == 1 assert l1.length == oo assert l3.slope == oo assert l4.slope == 0 assert l4.coefficients == (0, 1, 0) assert l4.equation(x=x, y=y) == y assert l5.slope == oo assert l5.coefficients == (1, 0, 0) assert l5.equation() == x assert l6.equation() == x - 2 assert l7.equation() == y - 1 assert p1 in l1 # is p1 on the line l1? assert p1 not in l3 assert simplify(l1.equation()) in (x - y, y - x) assert simplify(l3.equation()) in (x - x1, x1 - x) assert Line(p1, p2).scale(2, 1) == Line(p1, p9) assert l2.arbitrary_point() in l2 for ind in xrange(0, 5): assert l3.random_point() in l3 # Orthogonality p1_1 = Point(-x1, x1) l1_1 = Line(p1, p1_1) assert l1.perpendicular_line(p1) == l1_1 assert Line.is_perpendicular(l1, l1_1) assert Line.is_perpendicular(l1, l2) == False p = l1.random_point() assert l1.perpendicular_segment(p) == p # Parallelity p2_1 = Point(-2 * x1, 0) l2_1 = Line(p3, p5) assert l2.parallel_line(p1_1) == Line(p2_1, p1_1) assert l2_1.parallel_line(p1) == Line(p1, Point(0, 2)) assert Line.is_parallel(l1, l2) assert Line.is_parallel(l2, l3) == False assert Line.is_parallel(l2, l2.parallel_line(p1_1)) assert Line.is_parallel(l2_1, l2_1.parallel_line(p1)) # Intersection assert intersection(l1, p1) == [p1] assert intersection(l1, p5) == [] assert intersection(l1, l2) in [[l1], [l2]] assert intersection(l1, l1.parallel_line(p5)) == [] # Concurrency l3_1 = Line(Point(5, x1), Point(-Rational(3, 5), x1)) assert Line.is_concurrent(l1) == False assert Line.is_concurrent(l1, l3) assert Line.is_concurrent(l1, l3, l3_1) assert Line.is_concurrent(l1, l1_1, l3) == False # Projection assert l2.projection(p4) == p4 assert l1.projection(p1_1) == p1 assert l3.projection(p2) == Point(x1, 1) raises( GeometryError, 'Line(Point(0, 0), Point(1, 0)).projection(Circle(Point(0, 0), 1))') # Finding angles l1_1 = Line(p1, Point(5, 0)) assert feq(Line.angle_between(l1, l1_1).evalf(), pi.evalf() / 4) # Testing Rays and Segments (very similar to Lines) assert Ray((1, 1), angle=pi / 4) == Ray((1, 1), (2, 2)) assert Ray((1, 1), angle=pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=-pi / 2) == Ray((1, 1), (1, 0)) assert Ray((1, 1), angle=-3 * pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=5 * pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=5.0 * pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=pi) == Ray((1, 1), (0, 1)) assert Ray((1, 1), angle=3.0 * pi) == Ray((1, 1), (0, 1)) assert Ray((1, 1), angle=4.0 * pi) == Ray((1, 1), (2, 1)) assert Ray((1, 1), angle=0) == Ray((1, 1), (2, 1)) # XXX don't know why this fails without str assert str(Ray( (1, 1), angle=4.2 * pi)) == str(Ray(Point(1, 1), Point(2, 1 + C.tan(0.2 * pi)))) assert Ray((1, 1), angle=5) == Ray((1, 1), (2, 1 + C.tan(5))) raises(ValueError, 'Ray((1, 1), 1)') r1 = Ray(p1, Point(-1, 5)) r2 = Ray(p1, Point(-1, 1)) r3 = Ray(p3, p5) r4 = Ray(p1, p2) r5 = Ray(p2, p1) r6 = Ray(Point(0, 1), Point(1, 2)) r7 = Ray(Point(0.5, 0.5), Point(1, 1)) assert l1.projection(r1) == Ray(p1, p2) assert l1.projection(r2) == p1 assert r3 != r1 t = Symbol('t', real=True) assert Ray( (1, 1), angle=pi / 4).arbitrary_point() == Point(1 / (1 - t), 1 / (1 - t)) s1 = Segment(p1, p2) s2 = Segment(p1, p1_1) assert s1.midpoint == Point(Rational(1, 2), Rational(1, 2)) assert s2.length == sqrt(2 * (x1**2)) assert s1.perpendicular_bisector() == Line(Point(0, 1), Point(1, 0)) assert Segment((1, 1), (2, 3)).arbitrary_point() == Point(1 + t, 1 + 2 * t) # intersections assert s1.intersection(Line(p6, p9)) == [] s3 = Segment(Point(0.25, 0.25), Point(0.5, 0.5)) assert s1.intersection(s3) == [s1] assert s3.intersection(s1) == [s3] assert r4.intersection(s3) == [s3] assert r4.intersection(Segment(Point(2, 3), Point(3, 4))) == [] assert r4.intersection(Segment(Point(-1, -1), Point( 0.5, 0.5))) == [Segment(p1, Point(0.5, 0.5))] s3 = Segment(Point(1, 1), Point(2, 2)) assert s1.intersection(s3) == [Point(1, 1)] s3 = Segment(Point(0.5, 0.5), Point(1.5, 1.5)) assert s1.intersection(s3) == [Segment(Point(0.5, 0.5), p2)] assert s1.intersection(Segment(Point(4, 4), Point(5, 5))) == [] assert s1.intersection(Segment(Point(-1, -1), p1)) == [p1] assert s1.intersection(Segment(Point(-1, -1), Point( 0.5, 0.5))) == [Segment(p1, Point(0.5, 0.5))] assert r4.intersection(r5) == [s1] assert r5.intersection(r6) == [] assert r4.intersection(r7) == r7.intersection(r4) == [r7] # Segment contains a, b = symbols('a,b') s = Segment((0, a), (0, b)) assert Point(0, (a + b) / 2) in s s = Segment((a, 0), (b, 0)) assert Point((a + b) / 2, 0) in s raises(Undecidable, "Point(2*a, 0) in s") # Testing distance from a Segment to an object s1 = Segment(Point(0, 0), Point(1, 1)) s2 = Segment(Point(half, half), Point(1, 0)) pt1 = Point(0, 0) pt2 = Point(Rational(3) / 2, Rational(3) / 2) assert s1.distance(pt1) == 0 assert s2.distance(pt1) == 2**(half) / 2 assert s2.distance(pt2) == 2**(half) # Special cases of projection and intersection r1 = Ray(Point(1, 1), Point(2, 2)) r2 = Ray(Point(2, 2), Point(0, 0)) r3 = Ray(Point(1, 1), Point(-1, -1)) r4 = Ray(Point(0, 4), Point(-1, -5)) r5 = Ray(Point(2, 2), Point(3, 3)) assert intersection(r1, r2) == [Segment(Point(1, 1), Point(2, 2))] assert intersection(r1, r3) == [Point(1, 1)] assert r1.projection(r3) == Point(1, 1) assert r1.projection(r4) == Segment(Point(1, 1), Point(2, 2)) r5 = Ray(Point(0, 0), Point(0, 1)) r6 = Ray(Point(0, 0), Point(0, 2)) assert r5 in r6 assert r6 in r5 s1 = Segment(Point(0, 0), Point(2, 2)) s2 = Segment(Point(-1, 5), Point(-5, -10)) s3 = Segment(Point(0, 4), Point(-2, 2)) assert intersection(r1, s1) == [Segment(Point(1, 1), Point(2, 2))] assert r1.projection(s2) == Segment(Point(1, 1), Point(2, 2)) assert s3.projection(r1) == Segment(Point(0, 4), Point(-1, 3)) l1 = Line(Point(0, 0), Point(3, 4)) r1 = Ray(Point(0, 0), Point(3, 4)) s1 = Segment(Point(0, 0), Point(3, 4)) assert intersection(l1, l1) == [l1] assert intersection(l1, r1) == [r1] assert intersection(l1, s1) == [s1] assert intersection(r1, l1) == [r1] assert intersection(s1, l1) == [s1] entity1 = Segment(Point(-10, 10), Point(10, 10)) entity2 = Segment(Point(-5, -5), Point(-5, 5)) assert intersection(entity1, entity2) == [] r1 = Ray(p1, Point(0, 1)) r2 = Ray(Point(0, 1), p1) r3 = Ray(p1, p2) r4 = Ray(p2, p1) s1 = Segment(p1, Point(0, 1)) assert Line(r1.source, r1.random_point()).slope == r1.slope assert Line(r2.source, r2.random_point()).slope == r2.slope assert Segment(Point(0, -1), s1.random_point()).slope == s1.slope p_r3 = r3.random_point() p_r4 = r4.random_point() assert p_r3.x >= p1.x and p_r3.y >= p1.y assert p_r4.x <= p2.x and p_r4.y <= p2.y p10 = Point(2000, 2000) s1 = Segment(p1, p10) p_s1 = s1.random_point() assert p1.x <= p_s1.x and p_s1.x <= p10.x and p1.y <= p_s1.y and p_s1.y <= p10.y s2 = Segment(p10, p1) assert hash(s1) == hash(s2) p11 = p10.scale(2, 2) assert s1.is_similar(Segment(p10, p11)) assert s1.is_similar(r1) == False assert (r1 in s1) == False assert Segment(p1, p2) in s1 assert s1.plot_interval() == [t, 0, 1] assert s1 in Line(p1, p10) assert Line(p1, p10) == Line(p10, p1) assert Line(p1, p10) != p1 assert Line(p1, p10).plot_interval() == [t, -5, 5]
def test_order_oo(): from sympy import C x = Symbol('x', positive=True, finite=True) assert C.Order(x)*oo != C.Order(1, x) assert limit(oo/(x**2 - 4), x, oo) == oo
def Ylm(l, m, theta, phi): l, m, theta, phi = [sympify(x) for x in (l, m, theta, phi)] factorial = C.Factorial return sqrt((2*l+1)/(4*pi) * factorial(l-m)/factorial(l+m)) * \ Plmcos(l, m, theta) * C.exp(I*m*phi)
def test_line(): p1 = Point(0, 0) p2 = Point(1, 1) p3 = Point(x1, x1) p4 = Point(y1, y1) p5 = Point(x1, 1 + x1) p6 = Point(1, 0) p7 = Point(0, 1) p8 = Point(2, 0) p9 = Point(2, 1) l1 = Line(p1, p2) l2 = Line(p3, p4) l3 = Line(p3, p5) l4 = Line(p1, p6) l5 = Line(p1, p7) l6 = Line(p8, p9) l7 = Line(p2, p9) # Basic stuff assert Line((1, 1), slope=1) == Line((1, 1), (2, 2)) assert Line((1, 1), slope=oo) == Line((1, 1), (1, 2)) assert Line((1, 1), slope=-oo) == Line((1, 1), (1, 2)) raises(ValueError, "Line((1, 1), 1)") assert Line(p1, p2) == Line(p2, p1) assert l1 == l2 assert l1 != l3 assert l1.slope == 1 assert l3.slope == oo assert l4.slope == 0 assert l4.coefficients == (0, 1, 0) assert l4.equation(x=x, y=y) == y assert l5.slope == oo assert l5.coefficients == (1, 0, 0) assert l5.equation() == x assert l6.equation() == x - 2 assert l7.equation() == y - 1 assert p1 in l1 # is p1 on the line l1? assert p1 not in l3 assert simplify(l1.equation()) in (x - y, y - x) assert simplify(l3.equation()) in (x - x1, x1 - x) assert l2.arbitrary_point() in l2 for ind in xrange(0, 5): assert l3.random_point() in l3 # Orthogonality p1_1 = Point(-x1, x1) l1_1 = Line(p1, p1_1) assert l1.perpendicular_line(p1) == l1_1 assert Line.is_perpendicular(l1, l1_1) assert Line.is_perpendicular(l1, l2) == False # Parallelity p2_1 = Point(-2 * x1, 0) l2_1 = Line(p3, p5) assert l2.parallel_line(p1_1) == Line(p2_1, p1_1) assert l2_1.parallel_line(p1) == Line(p1, Point(0, 2)) assert Line.is_parallel(l1, l2) assert Line.is_parallel(l2, l3) == False assert Line.is_parallel(l2, l2.parallel_line(p1_1)) assert Line.is_parallel(l2_1, l2_1.parallel_line(p1)) # Intersection assert intersection(l1, p1) == [p1] assert intersection(l1, p5) == [] assert intersection(l1, l2) in [[l1], [l2]] assert intersection(l1, l1.parallel_line(p5)) == [] # Concurrency l3_1 = Line(Point(5, x1), Point(-Rational(3, 5), x1)) assert Line.is_concurrent(l1, l3) assert Line.is_concurrent(l1, l3, l3_1) assert Line.is_concurrent(l1, l1_1, l3) == False # Projection assert l2.projection(p4) == p4 assert l1.projection(p1_1) == p1 assert l3.projection(p2) == Point(x1, 1) # Finding angles l1_1 = Line(p1, Point(5, 0)) assert feq(Line.angle_between(l1, l1_1).evalf(), pi.evalf() / 4) # Testing Rays and Segments (very similar to Lines) assert Ray((1, 1), angle=pi / 4) == Ray((1, 1), (2, 2)) assert Ray((1, 1), angle=pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=-pi / 2) == Ray((1, 1), (1, 0)) assert Ray((1, 1), angle=-3 * pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=5 * pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=5.0 * pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=pi) == Ray((1, 1), (0, 1)) assert Ray((1, 1), angle=3.0 * pi) == Ray((1, 1), (0, 1)) assert Ray((1, 1), angle=4.0 * pi) == Ray((1, 1), (2, 1)) assert Ray((1, 1), angle=0) == Ray((1, 1), (2, 1)) # XXX don't know why this fails without str assert str(Ray((1, 1), angle=4.2 * pi)) == str(Ray(Point(1, 1), Point(2, 1 + C.tan(0.2 * pi)))) assert Ray((1, 1), angle=5) == Ray((1, 1), (2, 1 + C.tan(5))) raises(ValueError, "Ray((1, 1), 1)") r1 = Ray(p1, Point(-1, 5)) r2 = Ray(p1, Point(-1, 1)) r3 = Ray(p3, p5) assert l1.projection(r1) == Ray(p1, p2) assert l1.projection(r2) == p1 assert r3 != r1 t = Symbol("t", real=True) assert Ray((1, 1), angle=pi / 4).arbitrary_point() == Point(1 / (1 - t), 1 / (1 - t)) s1 = Segment(p1, p2) s2 = Segment(p1, p1_1) assert s1.midpoint == Point(Rational(1, 2), Rational(1, 2)) assert s2.length == sqrt(2 * (x1 ** 2)) assert s1.perpendicular_bisector() == Line(Point(0, 1), Point(1, 0)) assert Segment((1, 1), (2, 3)).arbitrary_point() == Point(1 + t, 1 + 2 * t) # Segment contains a, b = symbols("a,b") s = Segment((0, a), (0, b)) assert Point(0, (a + b) / 2) in s s = Segment((a, 0), (b, 0)) assert Point((a + b) / 2, 0) in s assert (Point(2 * a, 0) in s) is False # XXX should be None? # Testing distance from a Segment to an object s1 = Segment(Point(0, 0), Point(1, 1)) s2 = Segment(Point(half, half), Point(1, 0)) pt1 = Point(0, 0) pt2 = Point(Rational(3) / 2, Rational(3) / 2) assert s1.distance(pt1) == 0 assert s2.distance(pt1) == 2 ** (half) / 2 assert s2.distance(pt2) == 2 ** (half) # Special cases of projection and intersection r1 = Ray(Point(1, 1), Point(2, 2)) r2 = Ray(Point(2, 2), Point(0, 0)) r3 = Ray(Point(1, 1), Point(-1, -1)) r4 = Ray(Point(0, 4), Point(-1, -5)) assert intersection(r1, r2) == [Segment(Point(1, 1), Point(2, 2))] assert intersection(r1, r3) == [Point(1, 1)] assert r1.projection(r3) == Point(1, 1) assert r1.projection(r4) == Segment(Point(1, 1), Point(2, 2)) r5 = Ray(Point(0, 0), Point(0, 1)) r6 = Ray(Point(0, 0), Point(0, 2)) assert r5 in r6 assert r6 in r5 s1 = Segment(Point(0, 0), Point(2, 2)) s2 = Segment(Point(-1, 5), Point(-5, -10)) s3 = Segment(Point(0, 4), Point(-2, 2)) assert intersection(r1, s1) == [Segment(Point(1, 1), Point(2, 2))] assert r1.projection(s2) == Segment(Point(1, 1), Point(2, 2)) assert s3.projection(r1) == Segment(Point(0, 4), Point(-1, 3)) l1 = Line(Point(0, 0), Point(3, 4)) r1 = Ray(Point(0, 0), Point(3, 4)) s1 = Segment(Point(0, 0), Point(3, 4)) assert intersection(l1, l1) == [l1] assert intersection(l1, r1) == [r1] assert intersection(l1, s1) == [s1] assert intersection(r1, l1) == [r1] assert intersection(s1, l1) == [s1] entity1 = Segment(Point(-10, 10), Point(10, 10)) entity2 = Segment(Point(-5, -5), Point(-5, 5)) assert intersection(entity1, entity2) == []
def test_ellipse(): p1 = Point(0, 0) p2 = Point(1, 1) p3 = Point(x1, x2) p4 = Point(0, 1) p5 = Point(-1, 0) e1 = Ellipse(p1, 1, 1) e2 = Ellipse(p2, half, 1) e3 = Ellipse(p1, y1, y1) c1 = Circle(p1, 1) c2 = Circle(p2, 1) c3 = Circle(Point(sqrt(2), sqrt(2)), 1) # Test creation with three points cen, rad = Point(3 * half, 2), 5 * half assert Circle(Point(0, 0), Point(3, 0), Point(0, 4)) == Circle(cen, rad) raises(GeometryError, "Circle(Point(0,0), Point(1,1), Point(2,2))") # Basic Stuff assert e1 == c1 assert e1 != e2 assert p4 in e1 assert p2 not in e2 assert e1.area == pi assert e2.area == pi / 2 assert e3.area == pi * (y1**2) assert c1.area == e1.area assert c1.circumference == e1.circumference assert e3.circumference == 2 * pi * y1 a = Symbol('a') b = Symbol('b') e5 = Ellipse(p1, a, b) assert e5.circumference == 4*a*C.Integral(((1 - x**2*Abs(b**2 - a**2)/a**2)/(1 - x**2))**(S(1)/2),\ (x, 0, 1)) assert e2.arbitrary_point() in e2 # Foci f1, f2 = Point(sqrt(12), 0), Point(-sqrt(12), 0) ef = Ellipse(Point(0, 0), 4, 2) assert ef.foci in [(f1, f2), (f2, f1)] # Tangents v = sqrt(2) / 2 p1_1 = Point(v, v) p1_2 = p2 + Point(half, 0) p1_3 = p2 + Point(0, 1) assert e1.tangent_line(p4) == c1.tangent_line(p4) assert e2.tangent_line(p1_2) == Line(p1_2, p2 + Point(half, 1)) assert e2.tangent_line(p1_3) == Line(p1_3, p2 + Point(half, 1)) assert c1.tangent_line(p1_1) == Line(p1_1, Point(0, sqrt(2))) assert e2.is_tangent(Line(p1_2, p2 + Point(half, 1))) assert e2.is_tangent(Line(p1_3, p2 + Point(half, 1))) assert c1.is_tangent(Line(p1_1, Point(0, sqrt(2)))) assert e1.is_tangent(Line(Point(0, 0), Point(1, 1))) == False # Intersection l1 = Line(Point(1, -5), Point(1, 5)) l2 = Line(Point(-5, -1), Point(5, -1)) l3 = Line(Point(-1, -1), Point(1, 1)) l4 = Line(Point(-10, 0), Point(0, 10)) pts_c1_l3 = [ Point(sqrt(2) / 2, sqrt(2) / 2), Point(-sqrt(2) / 2, -sqrt(2) / 2) ] assert intersection(e2, l4) == [] assert intersection(c1, Point(1, 0)) == [Point(1, 0)] assert intersection(c1, l1) == [Point(1, 0)] assert intersection(c1, l2) == [Point(0, -1)] assert intersection(c1, l3) in [pts_c1_l3, [pts_c1_l3[1], pts_c1_l3[0]]] assert intersection(c1, c2) in [[(1, 0), (0, 1)], [(0, 1), (1, 0)]] assert intersection(c1, c3) == [(sqrt(2) / 2, sqrt(2) / 2)] # some special case intersections csmall = Circle(p1, 3) cbig = Circle(p1, 5) cout = Circle(Point(5, 5), 1) # one circle inside of another assert csmall.intersection(cbig) == [] # separate circles assert csmall.intersection(cout) == [] # coincident circles assert csmall.intersection(csmall) == csmall v = sqrt(2) t1 = Triangle(Point(0, v), Point(0, -v), Point(v, 0)) points = intersection(t1, c1) assert len(points) == 4 assert Point(0, 1) in points assert Point(0, -1) in points assert Point(v / 2, v / 2) in points assert Point(v / 2, -v / 2) in points e1 = Circle(Point(0, 0), 5) e2 = Ellipse(Point(0, 0), 5, 20) assert intersection(e1, e2) in \ [[Point(5, 0), Point(-5, 0)], [Point(-5, 0), Point(5, 0)]] # FAILING ELLIPSE INTERSECTION GOES HERE # Combinations of above assert e3.is_tangent(e3.tangent_line(p1 + Point(y1, 0))) major = 3 minor = 1 e4 = Ellipse(p2, major, minor) assert e4.focus_distance == sqrt(abs(major**2 - minor**2)) ecc = e4.focus_distance / major assert e4.eccentricity == ecc assert e4.periapsis == major * (1 - ecc) assert e4.apoapsis == major * (1 + ecc)