def _eval_subs(self, old, new): # keep processing of power-like args centralized in Pow if old.is_Pow: # handle (exp(3*log(x))).subs(x**2, z) -> z**(3/2) old = exp(old.exp * log(old.base)) elif old is S.Exp1 and new.is_Function: old = exp if old.func is exp or old is S.Exp1: f = lambda a: Pow(*a.as_base_exp(), evaluate=False) if (a.is_Pow or a.func is exp) else a return Pow._eval_subs(f(self), f(old), new) if old is exp and not new.is_Function: return new ** self.exp._subs(old, new) return Function._eval_subs(self, old, new)
def _eval_power(self, other): """exp(arg)**e -> exp(arg*e) if assumptions allow it. """ b, e = self.as_base_exp() return Pow._eval_power(Pow(b, e, evaluate=False), other)
class LambertW(Function): r""" The Lambert W function `W(z)` is defined as the inverse function of `w \exp(w)` [1]_. Explanation =========== In other words, the value of `W(z)` is such that `z = W(z) \exp(W(z))` for any complex number `z`. The Lambert W function is a multivalued function with infinitely many branches `W_k(z)`, indexed by `k \in \mathbb{Z}`. Each branch gives a different solution `w` of the equation `z = w \exp(w)`. The Lambert W function has two partially real branches: the principal branch (`k = 0`) is real for real `z > -1/e`, and the `k = -1` branch is real for `-1/e < z < 0`. All branches except `k = 0` have a logarithmic singularity at `z = 0`. Examples ======== >>> from sympy import LambertW >>> LambertW(1.2) 0.635564016364870 >>> LambertW(1.2, -1).n() -1.34747534407696 - 4.41624341514535*I >>> LambertW(-1).is_real False References ========== .. [1] https://en.wikipedia.org/wiki/Lambert_W_function """ _singularities = (-Pow(S.Exp1, -1, evaluate=False), S.ComplexInfinity) @classmethod def eval(cls, x, k=None): if k == S.Zero: return cls(x) elif k is None: k = S.Zero if k.is_zero: if x.is_zero: return S.Zero if x is S.Exp1: return S.One if x == -1 / S.Exp1: return S.NegativeOne if x == -log(2) / 2: return -log(2) if x == 2 * log(2): return log(2) if x == -S.Pi / 2: return S.ImaginaryUnit * S.Pi / 2 if x == exp(1 + S.Exp1): return S.Exp1 if x is S.Infinity: return S.Infinity if x.is_zero: return S.Zero if fuzzy_not(k.is_zero): if x.is_zero: return S.NegativeInfinity if k is S.NegativeOne: if x == -S.Pi / 2: return -S.ImaginaryUnit * S.Pi / 2 elif x == -1 / S.Exp1: return S.NegativeOne elif x == -2 * exp(-2): return -Integer(2) def fdiff(self, argindex=1): """ Return the first derivative of this function. """ x = self.args[0] if len(self.args) == 1: if argindex == 1: return LambertW(x) / (x * (1 + LambertW(x))) else: k = self.args[1] if argindex == 1: return LambertW(x, k) / (x * (1 + LambertW(x, k))) raise ArgumentIndexError(self, argindex) def _eval_is_extended_real(self): x = self.args[0] if len(self.args) == 1: k = S.Zero else: k = self.args[1] if k.is_zero: if (x + 1 / S.Exp1).is_positive: return True elif (x + 1 / S.Exp1).is_nonpositive: return False elif (k + 1).is_zero: if x.is_negative and (x + 1 / S.Exp1).is_positive: return True elif x.is_nonpositive or (x + 1 / S.Exp1).is_nonnegative: return False elif fuzzy_not(k.is_zero) and fuzzy_not((k + 1).is_zero): if x.is_extended_real: return False def _eval_is_finite(self): return self.args[0].is_finite def _eval_is_algebraic(self): s = self.func(*self.args) if s.func == self.func: if fuzzy_not(self.args[0].is_zero) and self.args[0].is_algebraic: return False else: return s.is_algebraic def _eval_nseries(self, x, n, logx, cdir=0): if len(self.args) == 1: from sympy import Order, ceiling, expand_multinomial arg = self.args[0].nseries(x, n=n, logx=logx) lt = arg.compute_leading_term(x, logx=logx) lte = 1 if lt.is_Pow: lte = lt.exp if ceiling(n / lte) >= 1: s = Add(*[(-S.One)**(k - 1) * Integer(k)**(k - 2) / factorial(k - 1) * arg**k for k in range(1, ceiling(n / lte))]) s = expand_multinomial(s) else: s = S.Zero return s + Order(x**n, x) return super()._eval_nseries(x, n, logx) def _eval_is_zero(self): x = self.args[0] if len(self.args) == 1: k = S.Zero else: k = self.args[1] if x.is_zero and k.is_zero: return True
def factorint(n, limit=None, use_trial=True, use_rho=True, use_pm1=True, verbose=False, visual=False): """ Given a positive integer ``n``, ``factorint(n)`` returns a dict containing the prime factors of ``n`` as keys and their respective multiplicities as values. For example: >>> from sympy.ntheory import factorint >>> factorint(2000) # 2000 = (2**4) * (5**3) {2: 4, 5: 3} >>> factorint(65537) # This number is prime {65537: 1} For input less than 2, factorint behaves as follows: - ``factorint(1)`` returns the empty factorization, ``{}`` - ``factorint(0)`` returns ``{0:1}`` - ``factorint(-n)`` adds ``-1:1`` to the factors and then factors ``n`` Algorithm ========= The function switches between multiple algorithms. Trial division quickly finds small factors (of the order 1-5 digits), and finds all large factors if given enough time. The Pollard rho and p-1 algorithms are used to find large factors ahead of time; they will often find factors of the order of 10 digits within a few seconds: >>> factors = factorint(12345678910111213141516) >>> for base, exp in sorted(factors.items()): ... print base, exp ... 2 2 2507191691 1 1231026625769 1 Any of these methods can optionally be disabled with the following boolean parameters: - ``use_trial``: Toggle use of trial division - ``use_rho``: Toggle use of Pollard's rho method - ``use_pm1``: Toggle use of Pollard's p-1 method ``factorint`` also periodically checks if the remaining part is a prime number or a perfect power, and in those cases stops. Partial Factorization ===================== If ``limit`` (> 2) is specified, the search is stopped after performing trial division up to (and including) the limit (or taking a corresponding number of rho/p-1 steps). This is useful if one has a large number and only is interested in finding small factors (if any). Note that setting a limit does not prevent larger factors from being found early; it simply means that the largest factor may be composite. This number, for example, has two small factors and a huge semi-prime factor that cannot be reduced easily: >>> from sympy.ntheory import isprime >>> a = 1407633717262338957430697921446883 >>> f = factorint(a, limit=10000) >>> f == {991: 1, 202916782076162456022877024859L: 1, 7: 1} True >>> isprime(max(f)) False Visual Factorization ==================== If ``visual`` is set to ``True``, then it will return a visual factorization of the integer. For example: >>> from sympy import pprint >>> pprint(factorint(4200, visual=True)) 3 1 2 1 2 *3 *5 *7 Note that this is achieved by using the evaluate=False flag in Mul and Pow. If you do other manipulations with an expression where evaluate=False, it may evaluate. Therefore, you should use the visual option only for visualization, and use the normal dictionary returned by visual=False if you want to perform operations on the factors. If you find that you want one from the other but you do not want to run expensive factorint again, you can easily switch between the two forms using the following list comprehensions: >>> from sympy import Mul, Pow >>> regular = factorint(1764); regular {2: 2, 3: 2, 7: 2} >>> pprint(Mul(*[Pow(*i, **{'evaluate':False}) for i in regular.items()], ... **{'evaluate':False})) 2 2 2 2 *3 *7 >>> visual = factorint(1764, visual=True); pprint(visual) 2 2 2 2 *3 *7 >>> dict([i.args for i in visual.args]) {2: 2, 3: 2, 7: 2} Miscellaneous Options ===================== If ``verbose`` is set to ``True``, detailed progress is printed. """ if visual: factordict = factorint(n, limit=limit, use_trial=use_trial, use_rho=use_rho, use_pm1=use_pm1, verbose=verbose, visual=False) if factordict == {}: return S.One return Mul( *[Pow(*i, **{'evaluate': False}) for i in factordict.items()], **{'evaluate': False}) assert use_trial or use_rho or use_pm1 n = int(n) if not n: return {0: 1} if n < 0: n = -n factors = {-1: 1} else: factors = {} # Power of two t = trailing(n) if t: factors[2] = t n >>= t if n == 1: return factors low, high = 3, 250 # It is sufficient to perform trial division up to sqrt(n) try: # add 1 to sqrt in case there is round off; add 1 overall to make # sure that the limit is included limit = iff(limit, lambda: max(limit, low), lambda: int(n**0.5) + 1) + 1 except OverflowError: limit = 1e1000 # Setting to True here forces _check_termination if first round of # trial division fails found_trial_previous = True if verbose and n < 1e300: print "Factoring", n while 1: try: high_ = min(high, limit) # Trial division if use_trial: if verbose: print trial_msg % (low, high_) ps = sieve.primerange(low, high_) n, found_trial = _trial(factors, n, ps, verbose) else: found_trial = False if high > limit: factors[n] = 1 raise StopIteration # Only used advanced (and more expensive) methods as long as # trial division fails to locate small factors if not found_trial: if found_trial_previous: _check_termination(factors, n, verbose) # Pollard p-1 if use_pm1 and not found_trial: B = int(high_**0.7) if verbose: print(pm1_msg % (high_, high_)) ps = factorint(pollard_pm1(n, B=high_, seed=high_) or 1, \ limit=limit-1, verbose=verbose) n, found_pm1 = _trial(factors, n, ps, verbose) if found_pm1: _check_termination(factors, n, verbose) # Pollard rho if use_rho and not found_trial: max_steps = int(high_**0.7) if verbose: print(rho_msg % (1, max_steps, high_)) ps = factorint(pollard_rho(n, retries=1, max_steps=max_steps, \ seed=high_) or 1, limit=limit-1, verbose=verbose) n, found_rho = _trial(factors, n, ps, verbose) if found_rho: _check_termination(factors, n, verbose) except StopIteration: return factors found_trial_previous = found_trial low, high = high, high * 2
def _Sqrt(x): return Pow(x, S.Half)
def _hypot(x, y): return sqrt(Pow(x, 2) + Pow(y, 2))
def _eval_rewrite_as_besselj(self, z): tt = Rational(2, 3) a = tt * Pow(-z, Rational(3, 2)) if re(z).is_negative: return -z / sqrt(3) * (besselj(-tt, a) + besselj(tt, a))
def GeneralizedMultivariateLogGammaOmega(syms, omega, v, lamda, mu): """ Extends GeneralizedMultivariateLogGamma. Parameters ========== syms: list/tuple/set of symbols For identifying each component omega: A square matrix Every element of square matrix must be absolute value of square root of correlation coefficient v: Positive real number lamda: List of positive real numbers mu: List of positive real numbers Returns ======= RandomSymbol Examples ======== >>> from sympy.stats import density >>> from sympy.stats.joint_rv_types import GeneralizedMultivariateLogGammaOmega >>> from sympy import Matrix, symbols, S >>> omega = Matrix([[1, S.Half, S.Half], [S.Half, 1, S.Half], [S.Half, S.Half, 1]]) >>> v = 1 >>> l, mu = [1, 1, 1], [1, 1, 1] >>> G = GeneralizedMultivariateLogGammaOmega('G', omega, v, l, mu) >>> y = symbols('y_1:4', positive=True) >>> density(G)(y[0], y[1], y[2]) sqrt(2)*Sum((1 - sqrt(2)/2)**n*exp((n + 1)*(y_1 + y_2 + y_3) - exp(y_1) - exp(y_2) - exp(y_3))/gamma(n + 1)**3, (n, 0, oo))/2 References ========== .. [1] https://en.wikipedia.org/wiki/Generalized_multivariate_log-gamma_distribution .. [2] https://www.researchgate.net/publication/234137346_On_a_multivariate_log-gamma_distribution_and_the_use_of_the_distribution_in_the_Bayesian_analysis Notes ===== If the GeneralizedMultivariateLogGammaOmega is too long to type use, `from sympy.stats.joint_rv_types import GeneralizedMultivariateLogGammaOmega as GMVLGO` """ _value_check((omega.is_square, isinstance(omega, Matrix)), "omega must be a" " square matrix") for val in omega.values(): _value_check((val >= 0, val <= 1), "all values in matrix must be between 0 and 1(both inclusive).") _value_check(omega.diagonal().equals(ones(1, omega.shape[0])), "all the elements of diagonal should be 1.") _value_check((omega.shape[0] == len(lamda), len(lamda) == len(mu)), "lamda, mu should be of same length and omega should " " be of shape (length of lamda, length of mu)") _value_check(len(lamda) > 1,"the distribution should have at least" " two random variables.") delta = Pow(Rational(omega.det()), Rational(1, len(lamda) - 1)) return GeneralizedMultivariateLogGamma(syms, delta, v, lamda, mu)
def _eval_rewrite_as_besselj(self, z): ot = Rational(1, 3) tt = Rational(2, 3) a = Pow(-z, Rational(3, 2)) if re(z).is_negative: return sqrt(-z / 3) * (besselj(-ot, tt * a) - besselj(ot, tt * a))
def _eval_rewrite_as_besselj(self, z): tt = Rational(2, 3) a = Pow(-z, Rational(3, 2)) if re(z).is_negative: return z / 3 * (besselj(-tt, tt * a) - besselj(tt, tt * a))
def sqrt(arg, evaluate=None): """Returns the principal square root. Parameters ========== 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 sqrt, Symbol, S >>> x = Symbol('x') >>> sqrt(x) sqrt(x) >>> sqrt(x)**2 x Note that sqrt(x**2) does not simplify to x. >>> sqrt(x**2) sqrt(x**2) This is because the two are not equal to each other in general. For example, consider x == -1: >>> from sympy import Eq >>> Eq(sqrt(x**2), x).subs(x, -1) False This is because sqrt computes the principal square root, so the square may put the argument in a different branch. This identity does hold if x is positive: >>> y = Symbol('y', positive=True) >>> sqrt(y**2) y You can force this simplification by using the powdenest() function with the force option set to True: >>> from sympy import powdenest >>> sqrt(x**2) sqrt(x**2) >>> powdenest(sqrt(x**2), force=True) x To get both branches of the square root you can use the rootof function: >>> from sympy import rootof >>> [rootof(x**2-3,i) for i in (0,1)] [-sqrt(3), sqrt(3)] Although ``sqrt`` is printed, there is no ``sqrt`` function so looking for ``sqrt`` in an expression will fail: >>> from sympy.utilities.misc import func_name >>> func_name(sqrt(x)) 'Pow' >>> sqrt(x).has(sqrt) Traceback (most recent call last): ... sympy.core.sympify.SympifyError: SympifyError: <function sqrt at 0x10e8900d0> To find ``sqrt`` look for ``Pow`` with an exponent of ``1/2``: >>> (x + 1/sqrt(x)).find(lambda i: i.is_Pow and abs(i.exp) is S.Half) {1/sqrt(x)} See Also ======== sympy.polys.rootoftools.rootof, root, real_root References ========== .. [1] https://en.wikipedia.org/wiki/Square_root .. [2] https://en.wikipedia.org/wiki/Principal_value """ # arg = sympify(arg) is handled by Pow return Pow(arg, S.Half, evaluate=evaluate)
def root(arg, n, k=0, evaluate=None): r"""Returns the *k*-th *n*-th root of ``arg``. Parameters ========== k : int, optional Should be an integer in $\{0, 1, ..., n-1\}$. Defaults to the principal root if $0$. 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, Rational >>> from sympy.abc import x, n >>> root(x, 2) sqrt(x) >>> root(x, 3) x**(1/3) >>> root(x, n) x**(1/n) >>> root(x, -Rational(2, 3)) x**(-3/2) To get the k-th n-th root, specify k: >>> root(-2, 3, 2) -(-1)**(2/3)*2**(1/3) To get all n n-th roots you can use the rootof function. The following examples show the roots of unity for n equal 2, 3 and 4: >>> from sympy import rootof >>> [rootof(x**2 - 1, i) for i in range(2)] [-1, 1] >>> [rootof(x**3 - 1,i) for i in range(3)] [1, -1/2 - sqrt(3)*I/2, -1/2 + sqrt(3)*I/2] >>> [rootof(x**4 - 1,i) for i in range(4)] [-1, 1, -I, I] SymPy, like other symbolic algebra systems, returns the complex root of negative numbers. This is the principal root and differs from the text-book result that one might be expecting. For example, the cube root of -8 does not come back as -2: >>> root(-8, 3) 2*(-1)**(1/3) The real_root function can be used to either make the principal result real (or simply to return the real root directly): >>> from sympy import real_root >>> real_root(_) -2 >>> real_root(-32, 5) -2 Alternatively, the n//2-th n-th root of a negative number can be computed with root: >>> root(-32, 5, 5//2) -2 See Also ======== sympy.polys.rootoftools.rootof sympy.core.power.integer_nthroot sqrt, real_root References ========== * https://en.wikipedia.org/wiki/Square_root * https://en.wikipedia.org/wiki/Real_root * https://en.wikipedia.org/wiki/Root_of_unity * https://en.wikipedia.org/wiki/Principal_value * http://mathworld.wolfram.com/CubeRoot.html """ n = sympify(n) if k: return Mul(Pow(arg, S.One / n, evaluate=evaluate), S.NegativeOne**(2 * k / n), evaluate=evaluate) return Pow(arg, 1 / n, evaluate=evaluate)
def _print_Pow(self, expr, rational=False): # XXX Workaround for negative integer power error from sympy.core.power import Pow if expr.exp.is_integer and expr.exp.is_negative: expr = Pow(expr.base, expr.exp.evalf(), evaluate=False) return self._hprint_Pow(expr, rational=rational, sqrt='numpy.sqrt')
def eval(cls, arg): from sympy.calculus import AccumBounds from sympy.sets.setexpr import SetExpr from sympy.matrices.matrices import MatrixBase from sympy import im, logcombine, re if isinstance(arg, MatrixBase): return arg.exp() elif global_parameters.exp_is_pow: return Pow(S.Exp1, arg) elif arg.is_Number: if arg is S.NaN: return S.NaN elif arg.is_zero: return S.One elif arg is S.One: return S.Exp1 elif arg is S.Infinity: return S.Infinity elif arg is S.NegativeInfinity: return S.Zero elif arg is S.ComplexInfinity: return S.NaN elif isinstance(arg, log): return arg.args[0] elif isinstance(arg, AccumBounds): return AccumBounds(exp(arg.min), exp(arg.max)) elif isinstance(arg, SetExpr): return arg._eval_func(cls) elif arg.is_Mul: coeff = arg.as_coefficient(S.Pi * S.ImaginaryUnit) if coeff: if (2 * coeff).is_integer: if coeff.is_even: return S.One elif coeff.is_odd: return S.NegativeOne elif (coeff + S.Half).is_even: return -S.ImaginaryUnit elif (coeff + S.Half).is_odd: return S.ImaginaryUnit elif coeff.is_Rational: ncoeff = coeff % 2 # restrict to [0, 2pi) if ncoeff > 1: # restrict to (-pi, pi] ncoeff -= 2 if ncoeff != coeff: return cls(ncoeff * S.Pi * S.ImaginaryUnit) # Warning: code in risch.py will be very sensitive to changes # in this (see DifferentialExtension). # look for a single log factor coeff, terms = arg.as_coeff_Mul() # but it can't be multiplied by oo if coeff in [S.NegativeInfinity, S.Infinity]: if terms.is_number: if coeff is S.NegativeInfinity: terms = -terms if re(terms).is_zero and terms is not S.Zero: return S.NaN if re(terms).is_positive and im(terms) is not S.Zero: return S.ComplexInfinity if re(terms).is_negative: return S.Zero return None coeffs, log_term = [coeff], None for term in Mul.make_args(terms): term_ = logcombine(term) if isinstance(term_, log): if log_term is None: log_term = term_.args[0] else: return None elif term.is_comparable: coeffs.append(term) else: return None return log_term**Mul(*coeffs) if log_term else None elif arg.is_Add: out = [] add = [] argchanged = False for a in arg.args: if a is S.One: add.append(a) continue newa = cls(a) if isinstance(newa, cls): if newa.args[0] != a: add.append(newa.args[0]) argchanged = True else: add.append(a) else: out.append(newa) if out or argchanged: return Mul(*out) * cls(Add(*add), evaluate=False) if arg.is_zero: return S.One
def test_big_expr(): f = Function('f') x = symbols('x') e1 = Dagger( AntiCommutator( Operator('A') + Operator('B'), Pow(DifferentialOperator(Derivative(f(x), x), f(x)), 3)) * TensorProduct(Jz**2, Operator('A') + Operator('B'))) * (JzBra(1, 0) + JzBra( 1, 1)) * (JzKet(0, 0) + JzKet(1, -1)) e2 = Commutator(Jz**2, Operator('A') + Operator('B')) * AntiCommutator( Dagger(Operator('C') * Operator('D')), Operator('E').inv()**2) * Dagger(Commutator(Jz, J2)) e3 = Wigner3j(1, 2, 3, 4, 5, 6) * TensorProduct( Commutator( Operator('A') + Dagger(Operator('B')), Operator('C') + Operator('D')), Jz - J2) * Dagger( OuterProduct(Dagger(JzBra(1, 1)), JzBra( 1, 0))) * TensorProduct( JzKetCoupled(1, 1, (1, 1)) + JzKetCoupled(1, 0, (1, 1)), JzKetCoupled(1, -1, (1, 1))) e4 = (ComplexSpace(1) * ComplexSpace(2) + FockSpace()**2) * (L2(Interval(0, oo)) + HilbertSpace()) assert str( e1 ) == '(Jz**2)x(Dagger(A) + Dagger(B))*{Dagger(DifferentialOperator(Derivative(f(x), x),f(x)))**3,Dagger(A) + Dagger(B)}*(<1,0| + <1,1|)*(|0,0> + |1,-1>)' ascii_str = \ """\ / 3 \\ \n\ |/ +\\ | \n\ 2 / + +\\ <| /d \\ | + +> \n\ /J \\ x \\A + B /*||DifferentialOperator|--(f(x)),f(x)| | ,A + B |*(<1,0| + <1,1|)*(|0,0> + |1,-1>)\n\ \\ z/ \\\\ \\dx / / / \ """ ucode_str = \ """\ ⎧ 3 ⎫ \n\ ⎪⎛ †⎞ ⎪ \n\ 2 ⎛ † †⎞ ⎨⎜ ⎛d ⎞ ⎟ † †⎬ \n\ ⎛J ⎞ ⨂ ⎝A + B ⎠⋅⎪⎜DifferentialOperator⎜──(f(x)),f(x)⎟ ⎟ ,A + B ⎪⋅(⟨1,0❘ + ⟨1,1❘)⋅(❘0,0⟩ + ❘1,-1⟩)\n\ ⎝ z⎠ ⎩⎝ ⎝dx ⎠ ⎠ ⎭ \ """ assert pretty(e1) == ascii_str assert upretty(e1) == ucode_str assert latex(e1) == \ r'{J_z^{2}}\otimes \left({A^{\dagger} + B^{\dagger}}\right) \left\{\left(DifferentialOperator\left(\frac{d}{d x} f{\left(x \right)},f{\left(x \right)}\right)^{\dagger}\right)^{3},A^{\dagger} + B^{\dagger}\right\} \left({\left\langle 1,0\right|} + {\left\langle 1,1\right|}\right) \left({\left|0,0\right\rangle } + {\left|1,-1\right\rangle }\right)' sT( e1, "Mul(TensorProduct(Pow(JzOp(Symbol('J')), Integer(2)), Add(Dagger(Operator(Symbol('A'))), Dagger(Operator(Symbol('B'))))), AntiCommutator(Pow(Dagger(DifferentialOperator(Derivative(Function('f')(Symbol('x')), Tuple(Symbol('x'), Integer(1))),Function('f')(Symbol('x')))), Integer(3)),Add(Dagger(Operator(Symbol('A'))), Dagger(Operator(Symbol('B'))))), Add(JzBra(Integer(1),Integer(0)), JzBra(Integer(1),Integer(1))), Add(JzKet(Integer(0),Integer(0)), JzKet(Integer(1),Integer(-1))))" ) assert str(e2) == '[Jz**2,A + B]*{E**(-2),Dagger(D)*Dagger(C)}*[J2,Jz]' ascii_str = \ """\ [ 2 ] / -2 + +\\ [ 2 ]\n\ [/J \\ ,A + B]*<E ,D *C >*[J ,J ]\n\ [\\ z/ ] \\ / [ z]\ """ ucode_str = \ """\ ⎡ 2 ⎤ ⎧ -2 † †⎫ ⎡ 2 ⎤\n\ ⎢⎛J ⎞ ,A + B⎥⋅⎨E ,D ⋅C ⎬⋅⎢J ,J ⎥\n\ ⎣⎝ z⎠ ⎦ ⎩ ⎭ ⎣ z⎦\ """ assert pretty(e2) == ascii_str assert upretty(e2) == ucode_str assert latex(e2) == \ r'\left[J_z^{2},A + B\right] \left\{E^{-2},D^{\dagger} C^{\dagger}\right\} \left[J^2,J_z\right]' sT( e2, "Mul(Commutator(Pow(JzOp(Symbol('J')), Integer(2)),Add(Operator(Symbol('A')), Operator(Symbol('B')))), AntiCommutator(Pow(Operator(Symbol('E')), Integer(-2)),Mul(Dagger(Operator(Symbol('D'))), Dagger(Operator(Symbol('C'))))), Commutator(J2Op(Symbol('J')),JzOp(Symbol('J'))))" ) assert str(e3) == \ "Wigner3j(1, 2, 3, 4, 5, 6)*[Dagger(B) + A,C + D]x(-J2 + Jz)*|1,0><1,1|*(|1,0,j1=1,j2=1> + |1,1,j1=1,j2=1>)x|1,-1,j1=1,j2=1>" ascii_str = \ """\ [ + ] / 2 \\ \n\ /1 3 5\\*[B + A,C + D]x |- J + J |*|1,0><1,1|*(|1,0,j1=1,j2=1> + |1,1,j1=1,j2=1>)x |1,-1,j1=1,j2=1>\n\ | | \\ z/ \n\ \\2 4 6/ \ """ ucode_str = \ """\ ⎡ † ⎤ ⎛ 2 ⎞ \n\ ⎛1 3 5⎞⋅⎣B + A,C + D⎦⨂ ⎜- J + J ⎟⋅❘1,0⟩⟨1,1❘⋅(❘1,0,j₁=1,j₂=1⟩ + ❘1,1,j₁=1,j₂=1⟩)⨂ ❘1,-1,j₁=1,j₂=1⟩\n\ ⎜ ⎟ ⎝ z⎠ \n\ ⎝2 4 6⎠ \ """ assert pretty(e3) == ascii_str assert upretty(e3) == ucode_str assert latex(e3) == \ r'\left(\begin{array}{ccc} 1 & 3 & 5 \\ 2 & 4 & 6 \end{array}\right) {\left[B^{\dagger} + A,C + D\right]}\otimes \left({- J^2 + J_z}\right) {\left|1,0\right\rangle }{\left\langle 1,1\right|} \left({{\left|1,0,j_{1}=1,j_{2}=1\right\rangle } + {\left|1,1,j_{1}=1,j_{2}=1\right\rangle }}\right)\otimes {{\left|1,-1,j_{1}=1,j_{2}=1\right\rangle }}' sT( e3, "Mul(Wigner3j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6)), TensorProduct(Commutator(Add(Dagger(Operator(Symbol('B'))), Operator(Symbol('A'))),Add(Operator(Symbol('C')), Operator(Symbol('D')))), Add(Mul(Integer(-1), J2Op(Symbol('J'))), JzOp(Symbol('J')))), OuterProduct(JzKet(Integer(1),Integer(0)),JzBra(Integer(1),Integer(1))), TensorProduct(Add(JzKetCoupled(Integer(1),Integer(0),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1)))), JzKetCoupled(Integer(1),Integer(1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))), JzKetCoupled(Integer(1),Integer(-1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))))" ) assert str(e4) == '(C(1)*C(2)+F**2)*(L2(Interval(0, oo))+H)' ascii_str = \ """\ // 1 2\\ x2\\ / 2 \\\n\ \\\\C x C / + F / x \\L + H/\ """ ucode_str = \ """\ ⎛⎛ 1 2⎞ ⨂2⎞ ⎛ 2 ⎞\n\ ⎝⎝C ⨂ C ⎠ ⊕ F ⎠ ⨂ ⎝L ⊕ H⎠\ """ assert pretty(e4) == ascii_str assert upretty(e4) == ucode_str assert latex(e4) == \ r'\left(\left(\mathcal{C}^{1}\otimes \mathcal{C}^{2}\right)\oplus {\mathcal{F}}^{\otimes 2}\right)\otimes \left({\mathcal{L}^2}\left( \left[0, \infty\right) \right)\oplus \mathcal{H}\right)' sT( e4, "TensorProductHilbertSpace((DirectSumHilbertSpace(TensorProductHilbertSpace(ComplexSpace(Integer(1)),ComplexSpace(Integer(2))),TensorPowerHilbertSpace(FockSpace(),Integer(2)))),(DirectSumHilbertSpace(L2(Interval(Integer(0), oo, false, true)),HilbertSpace())))" )
def _eval_subs(self, old, new): from sympy.core.power import Pow if old.is_Pow: return Pow(self, S.One, evaluate=False)._eval_subs(old, new)
def eval(cls, arg): from sympy.simplify.simplify import signsimp from sympy.core.function import expand_mul from sympy.core.power import Pow if hasattr(arg, "_eval_Abs"): obj = arg._eval_Abs() if obj is not None: return obj if not isinstance(arg, Expr): raise TypeError("Bad argument type for Abs(): %s" % type(arg)) # handle what we can arg = signsimp(arg, evaluate=False) n, d = arg.as_numer_denom() if d.free_symbols and not n.free_symbols: return cls(n) / cls(d) if arg.is_Mul: known = [] unk = [] for t in arg.args: if t.is_Pow and t.exp.is_integer and t.exp.is_negative: bnew = cls(t.base) if isinstance(bnew, cls): unk.append(t) else: known.append(Pow(bnew, t.exp)) else: tnew = cls(t) if isinstance(tnew, cls): unk.append(t) else: known.append(tnew) known = Mul(*known) unk = cls(Mul(*unk), evaluate=False) if unk else S.One return known * unk if arg is S.NaN: return S.NaN if arg is S.ComplexInfinity: return S.Infinity if arg.is_Pow: base, exponent = arg.as_base_exp() if base.is_extended_real: if exponent.is_integer: if exponent.is_even: return arg if base is S.NegativeOne: return S.One return Abs(base)**exponent if base.is_extended_nonnegative: return base**re(exponent) if base.is_extended_negative: return (-base)**re(exponent) * exp(-S.Pi * im(exponent)) return elif not base.has(Symbol): # complex base # express base**exponent as exp(exponent*log(base)) a, b = log(base).as_real_imag() z = a + I * b return exp(re(exponent * z)) if isinstance(arg, exp): return exp(re(arg.args[0])) if isinstance(arg, AppliedUndef): return if arg.is_Add and arg.has(S.Infinity, S.NegativeInfinity): if any(a.is_infinite for a in arg.as_real_imag()): return S.Infinity if arg.is_zero: return S.Zero if arg.is_extended_nonnegative: return arg if arg.is_extended_nonpositive: return -arg if arg.is_imaginary: arg2 = -S.ImaginaryUnit * arg if arg2.is_extended_nonnegative: return arg2 # reject result if all new conjugates are just wrappers around # an expression that was already in the arg conj = signsimp(arg.conjugate(), evaluate=False) new_conj = conj.atoms(conjugate) - arg.atoms(conjugate) if new_conj and all(arg.has(i.args[0]) for i in new_conj): return if arg != conj and arg != -conj: ignore = arg.atoms(Abs) abs_free_arg = arg.xreplace({i: Dummy(real=True) for i in ignore}) unk = [ a for a in abs_free_arg.free_symbols if a.is_extended_real is None ] if not unk or not all(conj.has(conjugate(u)) for u in unk): return sqrt(expand_mul(arg * conj))
def _exp2(x): return Pow(_Two, x)
def root(arg, n, k=0): """root(x, n, k) -> Returns the k-th n-th root of x, defaulting to the principle root (k=0). Examples ======== >>> from sympy import root, Rational >>> from sympy.abc import x, n >>> root(x, 2) sqrt(x) >>> root(x, 3) x**(1/3) >>> root(x, n) x**(1/n) >>> root(x, -Rational(2, 3)) x**(-3/2) To get the k-th n-th root, specify k: >>> root(-2, 3, 2) -(-1)**(2/3)*2**(1/3) To get all n n-th roots you can use the rootof function. The following examples show the roots of unity for n equal 2, 3 and 4: >>> from sympy import rootof, I >>> [rootof(x**2 - 1, i) for i in range(2)] [-1, 1] >>> [rootof(x**3 - 1,i) for i in range(3)] [1, -1/2 - sqrt(3)*I/2, -1/2 + sqrt(3)*I/2] >>> [rootof(x**4 - 1,i) for i in range(4)] [-1, 1, -I, I] SymPy, like other symbolic algebra systems, returns the complex root of negative numbers. This is the principal root and differs from the text-book result that one might be expecting. For example, the cube root of -8 does not come back as -2: >>> root(-8, 3) 2*(-1)**(1/3) The real_root function can be used to either make the principle result real (or simply to return the real root directly): >>> from sympy import real_root >>> real_root(_) -2 >>> real_root(-32, 5) -2 Alternatively, the n//2-th n-th root of a negative number can be computed with root: >>> root(-32, 5, 5//2) -2 See Also ======== sympy.polys.rootoftools.rootof sympy.core.power.integer_nthroot sqrt, real_root References ========== * http://en.wikipedia.org/wiki/Square_root * http://en.wikipedia.org/wiki/Real_root * http://en.wikipedia.org/wiki/Root_of_unity * http://en.wikipedia.org/wiki/Principal_value * http://mathworld.wolfram.com/CubeRoot.html """ n = sympify(n) if k: return Pow(arg, S.One / n) * S.NegativeOne**(2 * k / n) return Pow(arg, 1 / n)
def _Cbrt(x): return Pow(x, Rational(1, 3))
def sqrt(arg): """The square root function sqrt(x) -> Returns the principal square root of x. Examples ======== >>> from sympy import sqrt, Symbol >>> x = Symbol('x') >>> sqrt(x) sqrt(x) >>> sqrt(x)**2 x Note that sqrt(x**2) does not simplify to x. >>> sqrt(x**2) sqrt(x**2) This is because the two are not equal to each other in general. For example, consider x == -1: >>> from sympy import Eq >>> Eq(sqrt(x**2), x).subs(x, -1) False This is because sqrt computes the principal square root, so the square may put the argument in a different branch. This identity does hold if x is positive: >>> y = Symbol('y', positive=True) >>> sqrt(y**2) y You can force this simplification by using the powdenest() function with the force option set to True: >>> from sympy import powdenest >>> sqrt(x**2) sqrt(x**2) >>> powdenest(sqrt(x**2), force=True) x To get both branches of the square root you can use the rootof function: >>> from sympy import rootof >>> [rootof(x**2-3,i) for i in (0,1)] [-sqrt(3), sqrt(3)] See Also ======== sympy.polys.rootoftools.rootof, root, real_root References ========== .. [1] http://en.wikipedia.org/wiki/Square_root .. [2] http://en.wikipedia.org/wiki/Principal_value """ # arg = sympify(arg) is handled by Pow return Pow(arg, S.Half)
def test_core_power(): x = Symbol("x") for c in (Pow, Pow(x, 4)): check(c)
def factorint(n, limit=None, use_trial=True, use_rho=True, use_pm1=True, verbose=False, visual=None): """ Given a positive integer ``n``, ``factorint(n)`` returns a dict containing the prime factors of ``n`` as keys and their respective multiplicities as values. For example: >>> from sympy.ntheory import factorint >>> factorint(2000) # 2000 = (2**4) * (5**3) {2: 4, 5: 3} >>> factorint(65537) # This number is prime {65537: 1} For input less than 2, factorint behaves as follows: - ``factorint(1)`` returns the empty factorization, ``{}`` - ``factorint(0)`` returns ``{0:1}`` - ``factorint(-n)`` adds ``-1:1`` to the factors and then factors ``n`` Algorithm ========= The function switches between multiple algorithms. Trial division quickly finds small factors (of the order 1-5 digits), and finds all large factors if given enough time. The Pollard rho and p-1 algorithms are used to find large factors ahead of time; they will often find factors of the order of 10 digits within a few seconds: >>> factors = factorint(12345678910111213141516) >>> for base, exp in sorted(factors.items()): ... print base, exp ... 2 2 2507191691 1 1231026625769 1 Any of these methods can optionally be disabled with the following boolean parameters: - ``use_trial``: Toggle use of trial division - ``use_rho``: Toggle use of Pollard's rho method - ``use_pm1``: Toggle use of Pollard's p-1 method ``factorint`` also periodically checks if the remaining part is a prime number or a perfect power, and in those cases stops. Partial Factorization ===================== If ``limit`` (> 3) is specified, the search is stopped after performing trial division up to (and including) the limit (or taking a corresponding number of rho/p-1 steps). This is useful if one has a large number and only is interested in finding small factors (if any). Note that setting a limit does not prevent larger factors from being found early; it simply means that the largest factor may be composite. Since checking for perfect power is relatively cheap, it is done regardless of the limit setting. This number, for example, has two small factors and a huge semi-prime factor that cannot be reduced easily: >>> from sympy.ntheory import isprime >>> a = 1407633717262338957430697921446883 >>> f = factorint(a, limit=10000) >>> f == {991: 1, 202916782076162456022877024859L: 1, 7: 1} True >>> isprime(max(f)) False This number has a small factor and a residual perfect power whose base is greater than the limit: >>> factorint(3*101**7, limit=5) {3: 1, 101: 7} Visual Factorization ==================== If ``visual`` is set to ``True``, then it will return a visual factorization of the integer. For example: >>> from sympy import pprint >>> pprint(factorint(4200, visual=True)) 3 1 2 1 2 *3 *5 *7 Note that this is achieved by using the evaluate=False flag in Mul and Pow. If you do other manipulations with an expression where evaluate=False, it may evaluate. Therefore, you should use the visual option only for visualization, and use the normal dictionary returned by visual=False if you want to perform operations on the factors. You can easily switch between the two forms by sending them back to factorint: >>> from sympy import Mul, Pow >>> regular = factorint(1764); regular {2: 2, 3: 2, 7: 2} >>> pprint(factorint(regular)) 2 2 2 2 *3 *7 >>> visual = factorint(1764, visual=True); pprint(visual) 2 2 2 2 *3 *7 >>> print factorint(visual) {2: 2, 3: 2, 7: 2} If you want to send a number to be factored in a partially factored form you can do so with a dictionary or unevaluated expression: >>> factorint(factorint({4: 2, 12: 3})) # twice to toggle to dict form {2: 10, 3: 3} >>> factorint(Mul(4, 12, **dict(evaluate=False))) {2: 4, 3: 1} The table of the output logic is: _______________________________ | | visual= | |input + -----+--------+------+ | | True | False | other| +------+------+--------+------+ |dict | mul | dict | mul | |n | mul | dict | dict | |mul | mul | dict | dict | +------+------+--------+------+ Miscellaneous Options ===================== If ``verbose`` is set to ``True``, detailed progress is printed. """ factordict = {} if visual and not isinstance(n, Mul) and not isinstance(n, dict): factordict = factorint(n, limit=limit, use_trial=use_trial, use_rho=use_rho, use_pm1=use_pm1, verbose=verbose, visual=False) elif isinstance(n, Mul): factordict = dict([(int(k), int(v)) for k, v in n.as_powers_dict().items()]) elif isinstance(n, dict): factordict = n if factordict and (isinstance(n, Mul) or isinstance(n, dict)): # check it for k in factordict.keys(): if isprime(k): continue e = factordict.pop(k) d = factorint(k, limit=limit, use_trial=use_trial, use_rho=use_rho, use_pm1=use_pm1, verbose=verbose, visual=False) for k, v in d.items(): if k in factordict: factordict[k] += v * e else: factordict[k] = v * e if visual or (type(n) is dict and visual is not True and visual is not False): if factordict == {}: return S.One return Mul( *[ Pow(*i, **{'evaluate': False}) for i in sorted(factordict.items()) ], **{'evaluate': False}) elif isinstance(n, dict) or isinstance(n, Mul): return factordict assert use_trial or use_rho or use_pm1 n = int(n) if limit: limit = int(limit) # special cases if n < 0: factors = factorint(-n, limit=limit, use_trial=use_trial, use_rho=use_rho, use_pm1=use_pm1, verbose=verbose, visual=False) factors[-1] = 1 return factors if limit: if limit < 2: if n == 1: return {} return {n: 1} elif n < 10: # doing this we are assured of getting a limit > 2 # when we have to compute it later return [{ 0: 1 }, {}, { 2: 1 }, { 3: 1 }, { 2: 2 }, { 5: 1 }, { 2: 1, 3: 1 }, { 7: 1 }, { 2: 3 }, { 3: 2 }][n] factors = {} # do simplistic factorization if verbose: sn = str(n) if len(sn) > 50: print 'Factoring %s' % sn[:5] + \ '..(%i other digits)..' % (len(sn) - 10) + sn[-5:] else: print 'Factoring', n if use_trial: # this is the preliminary factorization for small factors small = 2**15 fail_max = 600 small = min(small, limit or small) if verbose: print trial_int_msg % (2, small, fail_max) n, next_p = _factorint_small(factors, n, small, fail_max) else: next_p = 2 if factors and verbose: for k in sorted(factors): print factor_msg % (k, factors[k]) if next_p == 0: if n > 1: factors[int(n)] = 1 if verbose: print complete_msg return factors # continue with more advanced factorization methods # first check if the simplistic run didn't finish # because of the limit and check for a perfect # power before exiting try: if limit and next_p > limit: if verbose: print 'Exceeded limit:', limit _check_termination(factors, n, limit, use_trial, use_rho, use_pm1, verbose) if n > 1: factors[int(n)] = 1 return factors else: # Before quitting (or continuing on)... # ...do a Fermat test since it's so easy and we need the # square root anyway. Finding 2 factors is easy if they are # "close enough." This is the big root equivalent of dividing by # 2, 3, 5. sqrt_n = integer_nthroot(n, 2)[0] a = sqrt_n + 1 a2 = a**2 b2 = a2 - n for i in range(3): b, fermat = integer_nthroot(b2, 2) if fermat: break b2 += 2 * a + 1 # equiv to (a+1)**2 - n a += 1 if fermat: if verbose: print fermat_msg if limit: limit -= 1 for r in [a - b, a + b]: facs = factorint(r, limit=limit, use_trial=use_trial, use_rho=use_rho, use_pm1=use_pm1, verbose=verbose) factors.update(facs) raise StopIteration # ...see if factorization can be terminated _check_termination(factors, n, limit, use_trial, use_rho, use_pm1, verbose) except StopIteration: if verbose: print complete_msg return factors # these are the limits for trial division which will # be attempted in parallel with pollard methods low, high = next_p, 2 * next_p limit = limit or sqrt_n # add 1 to make sure limit is reached in primerange calls limit += 1 while 1: try: high_ = high if limit < high_: high_ = limit # Trial division if use_trial: if verbose: print trial_msg % (low, high_) ps = sieve.primerange(low, high_) n, found_trial = _trial(factors, n, ps, verbose) if found_trial: _check_termination(factors, n, limit, use_trial, use_rho, use_pm1, verbose) else: found_trial = False if high > limit: if verbose: print 'Exceeded limit:', limit if n > 1: factors[int(n)] = 1 raise StopIteration # Only used advanced methods when no small factors were found if not found_trial: if (use_pm1 or use_rho): high_root = max(int(math.log(high_**0.7)), low, 3) # Pollard p-1 if use_pm1: if verbose: print(pm1_msg % (high_root, high_)) c = pollard_pm1(n, B=high_root, seed=high_) if c: # factor it and let _trial do the update ps = factorint(c, limit=limit - 1, use_trial=use_trial, use_rho=use_rho, use_pm1=use_pm1, verbose=verbose) n, _ = _trial(factors, n, ps, verbose=False) _check_termination(factors, n, limit, use_trial, use_rho, use_pm1, verbose) # Pollard rho if use_rho: max_steps = high_root if verbose: print(rho_msg % (1, max_steps, high_)) c = pollard_rho(n, retries=1, max_steps=max_steps, \ seed=high_) if c: # factor it and let _trial do the update ps = factorint(c, limit=limit - 1, use_trial=use_trial, use_rho=use_rho, use_pm1=use_pm1, verbose=verbose) n, _ = _trial(factors, n, ps, verbose=False) _check_termination(factors, n, limit, use_trial, use_rho, use_pm1, verbose) except StopIteration: if verbose: print complete_msg return factors low, high = high, high * 2
def area_tria(x1, x2, x3, y1, y2, y3, z1, z2, z3): a = sympy.sqrt(Pow(x2 - x1, 2) + Pow(y2 - y1, 2) + Pow(z2 - z1, 2)) b = sympy.sqrt(Pow(x3 - x1, 2) + Pow(y3 - y1, 2) + Pow(z3 - z1, 2)) c = sympy.sqrt(Pow(x3 - x2, 2) + Pow(y3 - y2, 2) + Pow(z3 - z2, 2)) p = (a + b + c) / 2. return sympy.sqrt(p * (p - a) * (p - b) * (p - c))