def test_plot_and_save_6(): if not matplotlib: skip("Matplotlib not the default backend") x = Symbol('x') with TemporaryDirectory(prefix='sympy_') as tmpdir: filename = 'test.png' ### # Test expressions that can not be translated to np and generate complex # results. ### p = plot(sin(x) + I*cos(x)) p.save(os.path.join(tmpdir, filename)) p = plot(sqrt(sqrt(-x))) p.save(os.path.join(tmpdir, filename)) p = plot(LambertW(x)) p.save(os.path.join(tmpdir, filename)) p = plot(sqrt(LambertW(x))) p.save(os.path.join(tmpdir, filename)) #Characteristic function of a StudentT distribution with nu=10 x1 = 5 * x**2 * exp_polar(-I*pi)/2 m1 = meijerg(((1 / 2,), ()), ((5, 0, 1 / 2), ()), x1) x2 = 5*x**2 * exp_polar(I*pi)/2 m2 = meijerg(((1/2,), ()), ((5, 0, 1/2), ()), x2) expr = (m1 + m2) / (48 * pi) p = plot(expr, (x, 1e-6, 1e-2)) p.save(os.path.join(tmpdir, filename))
def test_issue_5673(): e = LambertW(-1) assert e.is_comparable is False assert e.is_positive is not True e2 = 1 - 1 / (1 - exp(-1000)) assert e2.is_positive is not True e3 = -2 + exp(exp(LambertW(log(2))) * LambertW(log(2))) assert e3.is_nonzero is not True
def test_issue_7259(): assert series( LambertW(x), x) == x - x**2 + 3 * x**3 / 2 - 8 * x**4 / 3 + 125 * x**5 / 24 + O(x** 6) assert series(LambertW(x**2), x, n=8) == x**2 - x**4 + 3 * x**6 / 2 + O(x**8) assert series(LambertW(sin(x)), x, n=4) == x - x**2 + 4 * x**3 / 3 + O(x**4)
def test_pmint_WrightOmega(): if ON_TRAVIS: skip("Too slow for travis.") def omega(x): return LambertW(exp(x)) f = (1 + omega(x) * (2 + cos(omega(x)) * (x + omega(x)))) / (1 + omega(x)) / (x + omega(x)) g = log(x + LambertW(exp(x))) + sin(LambertW(exp(x))) assert heurisch(f, x) == g
def test_issue_16572(): if not matplotlib: skip("Matplotlib not the default backend") x = Symbol('x') p = plot(LambertW(x), show=False) # Random number of segments, probably more than 50, but we want to see # that there are segments generated, as opposed to when the bug was present assert len(p[0].get_data()[0]) >= 30
def _lambert(eq, x): """ Given an expression assumed to be in the form ``F(X, a..f) = a*log(b*X + c) + d*X + f = 0`` where X = g(x) and x = g^-1(X), return the Lambert solution if possible: ``x = g^-1(-c/b + (a/d)*W(d/(a*b)*exp(c*d/a/b)*exp(-f/a)))``. """ eq = _mexpand(expand_log(eq)) mainlog = _mostfunc(eq, log, x) if not mainlog: return [] # violated assumptions other = eq.subs(mainlog, 0) if isinstance(-other, log): eq = (eq - other).subs(mainlog, mainlog.args[0]) mainlog = mainlog.args[0] if not isinstance(mainlog, log): return [] # violated assumptions other = -(-other).args[0] eq += other if not x in other.free_symbols: return [] # violated assumptions d, f, X2 = _linab(other, x) logterm = collect(eq - other, mainlog) a = logterm.as_coefficient(mainlog) if a is None or x in a.free_symbols: return [] # violated assumptions logarg = mainlog.args[0] b, c, X1 = _linab(logarg, x) if X1 != X2: return [] # violated assumptions u = Dummy('rhs') sol = [] # check only real solutions: for k in [-1, 0]: l = LambertW(d / (a * b) * exp(c * d / a / b) * exp(-f / a), k) # if W's arg is between -1/e and 0 there is # a -1 branch real solution, too. if k and not l.is_real: continue rhs = -c / b + (a / d) * l solns = solve(X1 - u, x) for i, tmp in enumerate(solns): solns[i] = tmp.subs(u, rhs) sol.append(solns[i]) return sol
def _lambert(eq, x): """ Given an expression assumed to be in the form ``F(X, a..f) = a*log(b*X + c) + d*X + f = 0`` where X = g(x) and x = g^-1(X), return the Lambert solution if possible: ``x = g^-1(-c/b + (a/d)*W(d/(a*b)*exp(c*d/a/b)*exp(-f/a)))``. """ eq = _mexpand(expand_log(eq)) mainlog = _mostfunc(eq, log, x) if not mainlog: return [] # violated assumptions other = eq.subs(mainlog, 0) if (-other).func is log: eq = (eq - other).subs(mainlog, mainlog.args[0]) mainlog = mainlog.args[0] if mainlog.func is not log: return [] # violated assumptions other = -(-other).args[0] eq += other if not x in other.free_symbols: return [] # violated assumptions d, f, X2 = _linab(other, x) logterm = collect(eq - other, mainlog) a = logterm.as_coefficient(mainlog) if a is None or x in a.free_symbols: return [] # violated assumptions logarg = mainlog.args[0] b, c, X1 = _linab(logarg, x) if X1 != X2: return [] # violated assumptions u = Dummy('rhs') rhs = -c / b + (a / d) * LambertW( d / (a * b) * exp(c * d / a / b) * exp(-f / a)) # if W's arg is between -1/e and 0 there is a -1 branch solution, too. # Check here to see if exp(W(s)) appears and return s/W(s) instead? solns = solve(X1 - u, x) for i, tmp in enumerate(solns): solns[i] = tmp.subs(u, rhs) return solns
def test_sympy__functions__elementary__exponential__LambertW(): from sympy.functions.elementary.exponential import LambertW assert _test_args(LambertW(2))
def test_issue_18969(): a, b = symbols('a b', positive=True) assert limit(LambertW(a), a, b) == LambertW(b) assert limit(exp(LambertW(a)), a, b) == exp(LambertW(b))
def test_issue_12571(): assert limit(-LambertW(-log(x))/log(x), x, 1) == 1
def test_issue_10978(): assert LambertW(x).limit(x, 0) == 0
def omega(x): return LambertW(exp(x))
def test_pmint_LambertW(): f = LambertW(x) g = x * LambertW(x) - x + x / LambertW(x) assert heurisch(f, x) == g
def _lambert(eq, x, domain=S.Complexes): """ Given an expression assumed to be in the form ``F(X, a..f) = a*log(b*X + c) + d*X + f = 0`` where X = g(x) and x = g^-1(X), return the Lambert solution, ``x = g^-1(-c/b + (a/d)*W(d/(a*b)*exp(c*d/a/b)*exp(-f/a)))``. """ eq = _mexpand(expand_log(eq)) mainlog = _mostfunc(eq, log, x) if not mainlog: return [] # violated assumptions other = eq.subs(mainlog, 0) if isinstance(-other, log): eq = (eq - other).subs(mainlog, mainlog.args[0]) mainlog = mainlog.args[0] if not isinstance(mainlog, log): return [] # violated assumptions other = -(-other).args[0] eq += other if not x in other.free_symbols: return [] # violated assumptions d, f, X2 = _linab(other, x) logterm = collect(eq - other, mainlog) a = logterm.as_coefficient(mainlog) if a is None or x in a.free_symbols: return [] # violated assumptions logarg = mainlog.args[0] b, c, X1 = _linab(logarg, x) if X1 != X2: return [] # violated assumptions # invert the generator X1 so we have x(u) u = Dummy('rhs') xusolns = solve(X1 - u, x) # There are infinitely many branches for LambertW # but only branches for k = -1 and 0 might be real. The k = 0 # branch is real and the k = -1 branch is real if the LambertW argumen # in in range [-1/e, 0]. Since `solve` does not return infinite # solutions we will only include the -1 branch if it tests as real. # Otherwise, inclusion of any LambertW in the solution indicates to # the user that there are imaginary solutions corresponding to # different k values. lambert_real_branches = [-1, 0] sol = [] # solution of the given Lambert equation is like # sol = -c/b + (a/d)*LambertW(arg, k), # where arg = d/(a*b)*exp((c*d-b*f)/a/b) and k in lambert_real_branches. # Instead of considering the single arg, `d/(a*b)*exp((c*d-b*f)/a/b)`, # the individual `p` roots obtained when writing `exp((c*d-b*f)/a/b)` # as `exp(A/p) = exp(A)**(1/p)`, where `p` is an Integer, are used. # calculating args for LambertW num, den = ((c*d-b*f)/a/b).as_numer_denom() p, den = den.as_coeff_Mul() e = exp(num/den) t = Dummy('t') if p == 1: t = e args = [d/(a*b)*t] elif domain.is_subset(S.Reals): # print(l090) ind_ls = [d/(a*b)*t for t in roots(t**p - e, t).keys()] args = [] j = -1 for i in ind_ls: j += 1 if not isinstance(i,int): if not i.has(I): args.append(ind_ls[j]) elif isinstance(i,int): args.append(ind_ls[j]) else: args = [d/(a*b)*t for t in roots(t**p - e, t).keys()] if len(args) == 0: return S.EmptySet # calculating solutions from args for arg in args: for k in lambert_real_branches: w = LambertW(arg, k) if k and not w.is_real: continue rhs = -c/b + (a/d)*w for xu in xusolns: sol.append(xu.subs(u, rhs)) return sol
def test_lambertw(): k = Symbol('k') assert LambertW(x, 0) == LambertW(x) assert LambertW(x, 0, evaluate=False) != LambertW(x) assert LambertW(0) == 0 assert LambertW(E) == 1 assert LambertW(-1 / E) == -1 assert LambertW(-log(2) / 2) == -log(2) assert LambertW(oo) is oo assert LambertW(0, 1) is -oo assert LambertW(0, 42) is -oo assert LambertW(-pi / 2, -1) == -I * pi / 2 assert LambertW(-1 / E, -1) == -1 assert LambertW(-2 * exp(-2), -1) == -2 assert LambertW(2 * log(2)) == log(2) assert LambertW(-pi / 2) == I * pi / 2 assert LambertW(exp(1 + E)) == E assert LambertW( x**2).diff(x) == 2 * LambertW(x**2) / x / (1 + LambertW(x**2)) assert LambertW(x, k).diff(x) == LambertW(x, k) / x / (1 + LambertW(x, k)) assert LambertW(sqrt(2)).evalf(30).epsilon_eq( Float("0.701338383413663009202120278965", 30), 1e-29) assert re(LambertW(2, -1)).evalf().epsilon_eq(Float("-0.834310366631110")) assert LambertW(-1).is_real is False # issue 5215 assert LambertW(2, evaluate=False).is_real p = Symbol('p', positive=True) assert LambertW(p, evaluate=False).is_real assert LambertW(p - 1, evaluate=False).is_real is None assert LambertW(-p - 2 / S.Exp1, evaluate=False).is_real is False assert LambertW(S.Half, -1, evaluate=False).is_real is False assert LambertW(Rational(-1, 10), -1, evaluate=False).is_real assert LambertW(-10, -1, evaluate=False).is_real is False assert LambertW(-2, 2, evaluate=False).is_real is False assert LambertW(0, evaluate=False).is_algebraic na = Symbol('na', nonzero=True, algebraic=True) assert LambertW(na).is_algebraic is False assert LambertW(p).is_zero is False n = Symbol('n', negative=True) assert LambertW(n).is_zero is False