def _Sqrt(x): return Pow(x, S.Half)
def test_nested_substitution(): # Substitution within a substitution. e = Add(Pow(w * x + y, 2), sqrt(w * x + y)) substs, reduced = cse([e]) assert substs == [(x0, w * x + y)] assert reduced == [sqrt(x0) + x0**2]
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 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 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 _eval_rewrite_as_besselj(self, z, **kwargs): 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, **kwargs): 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 test_issue_22689(): assert str(Mul(Pow(x,-2, evaluate=False), Pow(3,-1,evaluate=False), evaluate=False)) == "1/(x**2*3)"
def _create_evalf_table(): global evalf_table from sympy.functions.combinatorial.numbers import bernoulli from sympy.concrete.products import Product from sympy.concrete.summations import Sum from sympy.core.add import Add from sympy.core.mul import Mul from sympy.core.numbers import Exp1, Float, Half, ImaginaryUnit, Integer, NaN, NegativeOne, One, Pi, Rational, Zero from sympy.core.power import Pow from sympy.core.symbol import Dummy, Symbol from sympy.functions.elementary.complexes import Abs, im, re from sympy.functions.elementary.exponential import exp, log from sympy.functions.elementary.integers import ceiling, floor from sympy.functions.elementary.piecewise import Piecewise from sympy.functions.elementary.trigonometric import atan, cos, sin from sympy.integrals.integrals import Integral evalf_table = { Symbol: evalf_symbol, Dummy: evalf_symbol, Float: lambda x, prec, options: (x._mpf_, None, prec, None), Rational: lambda x, prec, options: (from_rational(x.p, x.q, prec), None, prec, None), Integer: lambda x, prec, options: (from_int(x.p, prec), None, prec, None), Zero: lambda x, prec, options: (None, None, prec, None), One: lambda x, prec, options: (fone, None, prec, None), Half: lambda x, prec, options: (fhalf, None, prec, None), Pi: lambda x, prec, options: (mpf_pi(prec), None, prec, None), Exp1: lambda x, prec, options: (mpf_e(prec), None, prec, None), ImaginaryUnit: lambda x, prec, options: (None, fone, None, prec), NegativeOne: lambda x, prec, options: (fnone, None, prec, None), NaN: lambda x, prec, options: (fnan, None, prec, None), exp: lambda x, prec, options: evalf_pow( Pow(S.Exp1, x.args[0], evaluate=False), prec, options), cos: evalf_trig, sin: evalf_trig, Add: evalf_add, Mul: evalf_mul, Pow: evalf_pow, log: evalf_log, atan: evalf_atan, Abs: evalf_abs, re: evalf_re, im: evalf_im, floor: evalf_floor, ceiling: evalf_ceiling, Integral: evalf_integral, Sum: evalf_sum, Product: evalf_prod, Piecewise: evalf_piecewise, bernoulli: evalf_bernoulli, }
def _integer_basis(poly): """Compute coefficient basis for a polynomial over integers. Returns the integer ``div`` such that substituting ``x = div*y`` ``p(x) = m*q(y)`` where the coefficients of ``q`` are smaller than those of ``p``. For example ``x**5 + 512*x + 1024 = 0`` with ``div = 4`` becomes ``y**5 + 2*y + 1 = 0`` Returns the integer ``div`` or ``None`` if there is no possible scaling. Examples ======== >>> from sympy.polys import Poly >>> from sympy.abc import x >>> from sympy.polys.polyroots import _integer_basis >>> p = Poly(x**5 + 512*x + 1024, x, domain='ZZ') >>> _integer_basis(p) 4 """ monoms, coeffs = list(zip(*poly.terms())) monoms, = list(zip(*monoms)) coeffs = list(map(abs, coeffs)) if coeffs[0] < coeffs[-1]: coeffs = list(reversed(coeffs)) n = monoms[0] monoms = [n - i for i in reversed(monoms)] else: return None monoms = monoms[:-1] coeffs = coeffs[:-1] # Special case for two-term polynominals if len(monoms) == 1: r = Pow(coeffs[0], S.One / monoms[0]) if r.is_Integer: return int(r) else: return None divs = reversed(divisors(gcd_list(coeffs))[1:]) try: div = next(divs) except StopIteration: return None while True: for monom, coeff in zip(monoms, coeffs): if coeff % div**monom != 0: try: div = next(divs) except StopIteration: return None else: break else: return div
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 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 _hypot(x, y): return sqrt(Pow(x, 2) + Pow(y, 2))
def _Cbrt(x): return Pow(x, Rational(1, 3))
def _eval_rewrite_as_Pow(self, arg, **kwargs): if arg.is_Mul: logs = [a for a in arg.args if isinstance(a, log) and len(a.args) == 1] if logs: return Pow(logs[0].args[0], arg.coeff(logs[0]))
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_as_leading_term(self, x, logx=None, cdir=0): if len(self.args) == 1: arg = self.args[0] arg0 = arg.subs(x, 0).cancel() if not arg0.is_zero: return self.func(arg0) return arg.as_leading_term(x) 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=None): r""" 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`` 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 ====== ====== ======= ======= Notes ===== 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. If ``verbose`` is set to ``True``, detailed progress is printed. See Also ======== smoothness, smoothness_p, divisors """ 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 if -1 in factordict: factordict.pop(-1) args = [S.NegativeOne] else: args = [] args.extend([ Pow(*i, **{'evaluate': False}) for i in sorted(factordict.items()) ]) return Mul(*args, **{'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 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 _eval_rewrite_as_besselj(self, z, **kwargs): 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): """The square root function sqrt(x) -> Returns the principal square root of x. The parameter evaluate determines if the expression should be evaluated. If None, its value is taken from global_evaluate 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, evaluate=evaluate)
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)
def __div__(self, other): return self * Pow(other, -1)
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 _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 test_core_power(): x = Symbol("x") for c in (Pow, Pow(x, 4)): check(c)
def test_complex(): a = Symbol("a", real=True) b = Symbol("b", real=True) e = (a + I * b) * (a - I * b) assert e.expand() == a**2 + b**2 assert sqrt(I) == Pow(I, S.Half)
# Optimization procedures for turning A**(-1) * x into MatrixSolve(A, x) def _matinv_predicate(expr): # TODO: We should be able to support more than 2 elements if expr.is_MatMul and len(expr.args) == 2: left, right = expr.args if left.is_Inverse and right.shape[1] == 1: inv_arg = left.arg if isinstance(inv_arg, MatrixSymbol): return bool(ask(Q.fullrank(left.arg))) return False def _matinv_transform(expr): left, right = expr.args inv_arg = left.arg return MatrixSolve(inv_arg, right) matinv_opt = ReplaceOptim(_matinv_predicate, _matinv_transform) logaddexp_opt = ReplaceOptim(log(exp(_v)+exp(_w)), logaddexp(_v, _w)) logaddexp2_opt = ReplaceOptim(log(Pow(2, _v)+Pow(2, _w)), logaddexp2(_v, _w)*log(2)) # Collections of optimizations: optims_c99 = (expm1_opt, log1p_opt, exp2_opt, log2_opt, log2const_opt) optims_numpy = (logaddexp_opt, logaddexp2_opt) optims_scipy = (cosm1_opt,)
def test_dim_simplify_pow(): assert Pow(L, 2) == L**2
left, right = expr.args if left.is_Inverse and right.shape[1] == 1: inv_arg = left.arg if isinstance(inv_arg, MatrixSymbol): return bool(ask(Q.fullrank(left.arg))) return False def _matinv_transform(expr): left, right = expr.args inv_arg = left.arg return MatrixSolve(inv_arg, right) matinv_opt = ReplaceOptim(_matinv_predicate, _matinv_transform) logaddexp_opt = ReplaceOptim(log(exp(_v) + exp(_w)), logaddexp(_v, _w)) logaddexp2_opt = ReplaceOptim(log(Pow(2, _v) + Pow(2, _w)), logaddexp2(_v, _w) * log(2)) # Collections of optimizations: optims_c99 = (expm1_opt, log1p_opt, exp2_opt, log2_opt, log2const_opt) optims_numpy = optims_c99 + ( logaddexp_opt, logaddexp2_opt, ) + sinc_opts optims_scipy = (cosm1_opt, )
def _exp2(x): return Pow(_Two, x)