Definitionandbasicpropertiesofthetworeal-valuedbranchesoftheLambertWfunction,
*) section‹The Lambert $W$ Function on the reals› theory Lambert_W imports
Complex_Main "HOL-Library.FuncSet" "HOL-Real_Asymp.Real_Asymp" begin
(*<*) text‹Some lemmas about asymptotic equivalence:›
lemma asymp_equiv_sandwich': fixes f :: "'a ==> real" assumes"∧c'. c' ∈ {l<..<c} ==> eventually (λx. f x ≥ c' * g x) F" assumes"∧c'. c' ∈ {c<..<u} ==> eventually (λx. f x ≤ c' * g x) F" assumes"l < c""c < u"and [simp]: "c ≠ 0" shows"f ∼[F] (λx. c * g x)" proof - have"(λx. f x - c * g x) ∈ o[F](g)" proof (rule landau_o.smallI) fix e :: real assume e: "e > 0"
define C1 where"C1 = min (c + e) ((c + u) / 2)" have C1: "C1 ∈ {c<..<u}""C1 - c ≤ e" using e assms by (auto simp: C1_def min_def)
define C2 where"C2 = max (c - e) ((c + l) / 2)" have C2: "C2 ∈ {l<..<c}""c - C2 ≤ e" using e assms by (auto simp: C2_def max_def field_simps)
show"eventually (λx. norm (f x - c * g x) ≤ e * norm (g x)) F" using assms(2)[OF C1(1)] assms(1)[OF C2(1)] proof eventually_elim case (elim x) show ?case proof (cases "f x ≥ c * g x") case True hence"norm (f x - c * g x) = f x - c * g x" by simp alsohave"…≤ (C1 - c) * g x" using elim by (simp add: algebra_simps) alsohave"…≤ (C1 - c) * norm (g x)" using C1 by (intro mult_left_mono) auto alsohave"…≤ e * norm (g x)" using C1 elim by (intro mult_right_mono) auto finallyshow ?thesis using elim by simp next case False hence"norm (f x - c * g x) = c * g x - f x" by simp alsohave"…≤ (c - C2) * g x" using elim by (simp add: algebra_simps) alsohave"…≤ (c - C2) * norm (g x)" using C2 by (intro mult_left_mono) auto alsohave"…≤ e * norm (g x)" using C2 elim by (intro mult_right_mono) auto finallyshow ?thesis using elim by simp qed qed qed alsohave"g ∈ O[F](λx. c * g x)" by simp finallyshow ?thesis unfolding asymp_equiv_altdef by blast qed
lemma asymp_equiv_sandwich'': fixes f :: "'a ==> real" assumes"∧c'. c' ∈ {l<..<1} ==> eventually (λx. f x ≥ c' * g x) F" assumes"∧c'. c' ∈ {1<..<u} ==> eventually (λx. f x ≤ c' * g x) F" assumes"l < 1""1 < u" shows"f ∼[F] (g)" using asymp_equiv_sandwich'[of l 1 g f F u] assms by simp (*>*)
subsection‹Properties of the function $x\mapsto x e^{x}$›
lemma exp_times_self_gt: assumes"x ≠ -1" shows"x * exp x > -exp (-1::real)" proof -
define f where"f = (λx::real. x * exp x)"
define f' where"f' = (λx::real. (x + 1) * exp x)" have"(f has_field_derivative f' x) (at x)"for x by (auto simp: f_def f'_def intro!: derivative_eq_intros simp: algebra_simps)
define l r where"l = min x (-1)"and"r = max x (-1)"
have"∃z. z > l ∧ z < r ∧ f r - f l = (r - l) * f' z" unfolding f_def f'_def l_def r_def using assms by (intro MVT2) (auto intro!: derivative_eq_intros simp: algebra_simps) thenobtain z where z: "z ∈ {l<..<r}""f r - f l = (r - l) * f' z" by auto from z have"f x = f (-1) + (x + 1) * f' z" using assms by (cases "x ≥ -1") (auto simp: l_def r_def max_def min_def algebra_simps) moreoverhave"sgn ((x + 1) * f' z) = 1" using z assms by (cases x "(-1) :: real" rule: linorder_cases; cases z "(-1) :: real" rule: linorder_cases)
(auto simp: f'_def sgn_mult l_def r_def) hence"(x + 1) * f' z > 0"using sgn_greater by fastforce ultimatelyshow ?thesis by (simp add: f_def) qed
lemma exp_times_self_ge: "x * exp x ≥ -exp (-1::real)" using exp_times_self_gt[of x] by (cases "x = -1") auto
lemma exp_times_self_strict_mono: assumes"x ≥ -1""x < (y :: real)" shows"x * exp x < y * exp y" using assms(2) proof (rule DERIV_pos_imp_increasing_open) fix t assume t: "x < t""t < y" have"((λx. x * exp x) has_real_derivative (t + 1) * exp t) (at t)" by (auto intro!: derivative_eq_intros simp: algebra_simps) moreoverhave"(t + 1) * exp t > 0" using t assms by (intro mult_pos_pos) auto ultimatelyshow"∃y. ((λa. a * exp a) has_real_derivative y) (at t) ∧ 0 < y"by blast qed (auto intro!: continuous_intros)
lemma exp_times_self_strict_antimono: assumes"y ≤ -1""x < (y :: real)" shows"x * exp x > y * exp y" proof - have"-x * exp x < -y * exp y" using assms(2) proof (rule DERIV_pos_imp_increasing_open) fix t assume t: "x < t""t < y" have"((λx. -x * exp x) has_real_derivative (-(t + 1)) * exp t) (at t)" by (auto intro!: derivative_eq_intros simp: algebra_simps) moreoverhave"(-(t + 1)) * exp t > 0" using t assms by (intro mult_pos_pos) auto ultimatelyshow"∃y. ((λa. -a * exp a) has_real_derivative y) (at t) ∧ 0 < y"by blast qed (auto intro!: continuous_intros) thus ?thesis by simp qed
lemma exp_times_self_mono: assumes"x ≥ -1""x ≤ (y :: real)" shows"x * exp x ≤ y * exp y" using exp_times_self_strict_mono[of x y] assms by (cases "x = y") auto
lemma exp_times_self_antimono: assumes"y ≤ -1""x ≤ (y :: real)" shows"x * exp x ≥ y * exp y" using exp_times_self_strict_antimono[of y x] assms by (cases "x = y") auto
lemma exp_times_self_inj: "inj_on (λx::real. x * exp x) {-1..}" proof fix x y :: real assume"x ∈ {-1..}""y ∈ {-1..}""x * exp x = y * exp y" thus"x = y" using exp_times_self_strict_mono[of x y] exp_times_self_strict_mono[of y x] by (cases x y rule: linorder_cases) auto qed
lemma exp_times_self_inj': "inj_on (λx::real. x * exp x) {..-1}" proof fix x y :: real assume"x ∈ {..-1}""y ∈ {..-1}""x * exp x = y * exp y" thus"x = y" using exp_times_self_strict_antimono[of x y] exp_times_self_strict_antimono[of y x] by (cases x y rule: linorder_cases) auto qed
subsection‹Definition›
text‹
The following are the two branches $W_0(x)$ and $W_{-1}(x)$ of the Lambert $W$ function on the
real numbers. These are the inverse functions of the function $x\mapsto xe^x$, i.\,e.\
we have $W(x)e^{W(x)} = x$ for both branches wherever they are defined. The two branches
meet at the point $x = -\frac{1}{e}$.
$W_0(x)$ is the principal branch, whose domain is $[-\frac{1}{e}; \infty)$ and whose
range is $[-1; \infty)$.
$W_{-1}(x)$ has the domain $[-\frac{1}{e}; 0)$ and the range $(-\infty;-1]$.
Figure~\ref{fig:lambertw} shows plots of these two branches for illustration. ›
text‹
definecolor{myblue}{HTML}{3869b1}
definecolor{myred}{HTML}{cc2428}
begin{figure}
begin{center}
begin{tikzpicture} \begin{axis}[
xmin=-0.5, xmax=6.6, ymin=-3.8, ymax=1.5, axis lines=middle, ytick = {-3, -2, -1, 1}, xtick = {1,...,10}, yticklabel pos = right,
yticklabel style={right,xshift=1mm},
extra x tick style={tick label style={above,yshift=1mm}},
extra x ticks={-0.367879441},
extra x tick labels={$-\frac{1}{e}$},
width=\textwidth, height=0.8\textwidth,
xlabel={$x$}, tick style={thin,black}
] \addplot [color=black, line width=0.5pt, densely dashed, mark=none,domain=-5:0,samples=200] ({-exp(-1)}, {x}); \addplot [color=myblue, line width=1pt, mark=none,domain=-1:1.5,samples=200] ({x*exp(x)}, {x}); \addplot [color=myred, line width=1pt, mark=none,domain=-5:-1,samples=200] ({x*exp(x)}, {x}); \end{axis}
end{tikzpicture}
end{center}
caption{The two real branches of the Lambert $W$ function: $W_0$ (blue) and $W_{-1}$ (red).}
label{fig:lambertw}
end{figure} ›
definition Lambert_W :: "real ==> real"where "Lambert_W x = (if x < -exp(-1) then -1 else (THE w. w ≥ -1 ∧ w * exp w = x))"
definition Lambert_W' :: "real ==> real"where "Lambert_W' x = (if x ∈ {-exp(-1)..<0} then (THE w. w ≤ -1 ∧ w * exp w = x) else -1)"
lemma Lambert_W_ex1: assumes"(x::real) ≥ -exp (-1)" shows"∃!w. w ≥ -1 ∧ w * exp w = x" proof (rule ex_ex1I) have"filterlim (λw::real. w * exp w) at_top at_top" by real_asymp hence"eventually (λw. w * exp w ≥ x) at_top" by (auto simp: filterlim_at_top) hence"eventually (λw. w ≥ 0 ∧ w * exp w ≥ x) at_top" by (intro eventually_conj eventually_ge_at_top) thenobtain w' where w': "w' * exp w' ≥ x""w' ≥ 0" by (auto simp: eventually_at_top_linorder) from w' assms have"∃w. -1 ≤ w ∧ w ≤ w' ∧ w * exp w = x" by (intro IVT' continuous_intros) auto thus"∃w. w ≥ -1 ∧ w * exp w = x"by blast next fix w w' :: real assume ww': "w ≥ -1 ∧ w * exp w = x""w' ≥ -1 ∧ w' * exp w' = x" hence"w * exp w = w' * exp w'"by simp thus"w = w'" using exp_times_self_strict_mono[of w w'] exp_times_self_strict_mono[of w' w] ww' by (cases w w' rule: linorder_cases) auto qed
lemma Lambert_W'_ex1: assumes"(x::real) ∈ {-exp (-1)..<0}" shows"∃!w. w ≤ -1 ∧ w * exp w = x" proof (rule ex_ex1I) have"eventually (λw. x ≤ w * exp w) at_bot" using assms by real_asymp hence"eventually (λw. w ≤ -1 ∧ w * exp w ≥ x) at_bot" by (intro eventually_conj eventually_le_at_bot) thenobtain w' where w': "w' * exp w' ≥ x""w' ≤ -1" by (auto simp: eventually_at_bot_linorder)
from w' assms have"∃w. w' ≤ w ∧ w ≤ -1 ∧ w * exp w = x" by (intro IVT2' continuous_intros) auto thus"∃w. w ≤ -1 ∧ w * exp w = x"by blast next fix w w' :: real assume ww': "w ≤ -1 ∧ w * exp w = x""w' ≤ -1 ∧ w' * exp w' = x" hence"w * exp w = w' * exp w'"by simp thus"w = w'" using exp_times_self_strict_antimono[of w w'] exp_times_self_strict_antimono[of w' w] ww' by (cases w w' rule: linorder_cases) auto qed
lemma Lambert_W_times_exp_self: assumes"x ≥ -exp (-1)" shows"Lambert_W x * exp (Lambert_W x) = x" using theI'[OF Lambert_W_ex1[OF assms]] assms by (auto simp: Lambert_W_def)
lemma Lambert_W_times_exp_self': assumes"x ≥ -exp (-1)" shows"exp (Lambert_W x) * Lambert_W x = x" using Lambert_W_times_exp_self[of x] assms by (simp add: mult_ac)
lemma Lambert_W'_times_exp_self: assumes"x ∈ {-exp (-1)..<0}" shows"Lambert_W' x * exp (Lambert_W' x) = x" using theI'[OF Lambert_W'_ex1[OF assms]] assms by (auto simp: Lambert_W'_def)
lemma Lambert_W'_times_exp_self': assumes"x ∈ {-exp (-1)..<0}" shows"exp (Lambert_W' x) * Lambert_W' x = x" using Lambert_W'_times_exp_self[of x] assms by (simp add: mult_ac)
lemma Lambert_W_ge: "Lambert_W x ≥ -1" using theI'[OF Lambert_W_ex1[of x]] by (auto simp: Lambert_W_def)
lemma Lambert_W'_le: "Lambert_W' x ≤ -1" using theI'[OF Lambert_W'_ex1[of x]] by (auto simp: Lambert_W'_def)
lemma Lambert_W_eqI: assumes"w ≥ -1""w * exp w = x" shows"Lambert_W x = w" proof - from assms exp_times_self_ge[of w] have"x ≥ -exp (-1)" by (cases "x ≥ -exp (-1)") auto from Lambert_W_ex1[OF this] Lambert_W_times_exp_self[OF this] Lambert_W_ge[of x] assms show ?thesis by metis qed
lemma Lambert_W'_eqI: assumes"w ≤ -1""w * exp w = x" shows"Lambert_W' x = w" proof - from assms exp_times_self_ge[of w] have"x ≥ -exp (-1)" by (cases "x ≥ -exp (-1)") auto moreoverfrom assms have"w * exp w < 0" by (intro mult_neg_pos) auto ultimatelyhave"x ∈ {-exp (-1)..<0}" using assms by auto
from Lambert_W'_ex1[OF this(1)] Lambert_W'_times_exp_self[OF this(1)] Lambert_W'_le assms show ?thesis by metis qed
text‹
$W_0(x)$ and $W_{-1}(x)$ together fully cover all solutions of $we^w = x$: › lemma exp_times_self_eqD: assumes"w * exp w = x" shows"x ≥ -exp (-1)"and"w = Lambert_W x ∨ x < 0 ∧ w = Lambert_W' x" proof - from assms show"x ≥ -exp (-1)" using exp_times_self_ge[of w] by auto show"w = Lambert_W x ∨ x < 0 ∧ w = Lambert_W' x" proof (cases "w ≥ -1") case True hence"Lambert_W x = w" using assms by (intro Lambert_W_eqI) auto thus ?thesis by auto next case False from False have"w * exp w < 0" by (intro mult_neg_pos) auto from False have"Lambert_W' x = w" using assms by (intro Lambert_W'_eqI) auto thus ?thesis using assms ‹w * exp w < 0›by auto qed qed
theorem exp_times_self_eq_iff: "w * exp w = x ⟷ x ≥ -exp (-1) ∧ (w = Lambert_W x ∨ x < 0 ∧ w = Lambert_W' x)" using exp_times_self_eqD[of w x] by (auto simp: Lambert_W_times_exp_self Lambert_W'_times_exp_self)
lemma Lambert_W_exp_times_self [simp]: "x ≥ -1 ==> Lambert_W (x * exp x) = x" by (rule Lambert_W_eqI) auto
lemma Lambert_W_exp_times_self' [simp]: "x ≥ -1 ==> Lambert_W (exp x * x) = x" by (rule Lambert_W_eqI) auto
lemma Lambert_W'_exp_times_self [simp]: "x ≤ -1 ==> Lambert_W' (x * exp x) = x" by (rule Lambert_W'_eqI) auto
lemma Lambert_W'_exp_times_self' [simp]: "x ≤ -1 ==> Lambert_W' (exp x * x) = x" by (rule Lambert_W'_eqI) auto
lemma Lambert_W_times_ln_self': assumes"x ≥ exp (-1)" shows"Lambert_W (ln x * x) = ln x" using Lambert_W_times_ln_self[OF assms] by (simp add: mult.commute)
lemma Lambert_W_eq_minus_exp_minus1 [simp]: "Lambert_W (-exp (-1)) = -1" by (rule Lambert_W_eqI) auto
lemma Lambert_W'_eq_minus_exp_minus1 [simp]: "Lambert_W' (-exp (-1)) = -1" by (rule Lambert_W'_eqI) auto
lemma Lambert_W_0 [simp]: "Lambert_W 0 = 0" by (rule Lambert_W_eqI) auto
subsection‹Monotonicity properties›
lemma Lambert_W_strict_mono: assumes"x ≥ -exp(-1)""x < y" shows"Lambert_W x < Lambert_W y" proof (rule ccontr) assume"¬(Lambert_W x < Lambert_W y)" hence"Lambert_W x * exp (Lambert_W x) ≥ Lambert_W y * exp (Lambert_W y)" by (intro exp_times_self_mono) (auto simp: Lambert_W_ge) hence"x ≥ y" using assms by (simp add: Lambert_W_times_exp_self) with assms show False by simp qed
lemma Lambert_W_mono: assumes"x ≥ -exp(-1)""x ≤ y" shows"Lambert_W x ≤ Lambert_W y" using Lambert_W_strict_mono[of x y] assms by (cases "x = y") auto
lemma Lambert_W_eq_iff [simp]: "x ≥ -exp(-1) ==> y ≥ -exp(-1) ==> Lambert_W x = Lambert_W y ⟷ x = y" using Lambert_W_strict_mono[of x y] Lambert_W_strict_mono[of y x] by (cases x y rule: linorder_cases) auto
lemma Lambert_W_le_iff [simp]: "x ≥ -exp(-1) ==> y ≥ -exp(-1) ==> Lambert_W x ≤ Lambert_W y ⟷ x ≤ y" using Lambert_W_strict_mono[of x y] Lambert_W_strict_mono[of y x] by (cases x y rule: linorder_cases) auto
lemma Lambert_W_less_iff [simp]: "x ≥ -exp(-1) ==> y ≥ -exp(-1) ==> Lambert_W x < Lambert_W y ⟷ x < y" using Lambert_W_strict_mono[of x y] Lambert_W_strict_mono[of y x] by (cases x y rule: linorder_cases) auto
lemma Lambert_W_le_minus_one: assumes"x ≤ -exp(-1)" shows"Lambert_W x = -1" proof (cases "x = -exp(-1)") case False thus ?thesis using assms by (auto simp: Lambert_W_def) qed auto
lemma Lambert_W_pos_iff [simp]: "Lambert_W x > 0 ⟷ x > 0" proof (cases "x ≥ -exp (-1)") case True thus ?thesis using Lambert_W_less_iff[of 0 x] by (simp del: Lambert_W_less_iff) next case False hence"x < - exp(-1)"by auto alsohave"…≤ 0"by simp finallyshow ?thesis using False by (auto simp: Lambert_W_le_minus_one) qed
lemma Lambert_W_eq_0_iff [simp]: "Lambert_W x = 0 ⟷ x = 0" using Lambert_W_eq_iff[of x 0] by (cases "x ≥ -exp (-1)") (auto simp: Lambert_W_le_minus_one simp del: Lambert_W_eq_iff)
lemma Lambert_W_nonneg_iff [simp]: "Lambert_W x ≥ 0 ⟷ x ≥ 0" using Lambert_W_pos_iff[of x] by (cases "x = 0") (auto simp del: Lambert_W_pos_iff)
lemma Lambert_W_neg_iff [simp]: "Lambert_W x < 0 ⟷ x < 0" using Lambert_W_nonneg_iff[of x] by (auto simp del: Lambert_W_nonneg_iff)
lemma Lambert_W_nonpos_iff [simp]: "Lambert_W x ≤ 0 ⟷ x ≤ 0" using Lambert_W_pos_iff[of x] by (auto simp del: Lambert_W_pos_iff)
lemma Lambert_W_geI: assumes"y * exp y ≤ x" shows"Lambert_W x ≥ y" proof (cases "y ≥ -1") case False hence"y ≤ -1"by simp alsohave"-1 ≤ Lambert_W x"by (rule Lambert_W_ge) finallyshow ?thesis . next case True have"Lambert_W x ≥ Lambert_W (y * exp y)" using assms exp_times_self_ge[of y] by (intro Lambert_W_mono) auto thus ?thesis using assms True by simp qed
lemma Lambert_W_gtI: assumes"y * exp y < x" shows"Lambert_W x > y" proof (cases "y ≥ -1") case False hence"y < -1"by simp alsohave"-1 ≤ Lambert_W x"by (rule Lambert_W_ge) finallyshow ?thesis . next case True have"Lambert_W x > Lambert_W (y * exp y)" using assms exp_times_self_ge[of y] by (intro Lambert_W_strict_mono) auto thus ?thesis using assms True by simp qed
lemma Lambert_W_leI: assumes"y * exp y ≥ x""y ≥ -1""x ≥ -exp (-1)" shows"Lambert_W x ≤ y" proof - have"Lambert_W x ≤ Lambert_W (y * exp y)" using assms exp_times_self_ge[of y] by (intro Lambert_W_mono) auto thus ?thesis using assms by simp qed
lemma Lambert_W_lessI: assumes"y * exp y > x""y ≥ -1""x ≥ -exp (-1)" shows"Lambert_W x < y" proof - have"Lambert_W x < Lambert_W (y * exp y)" using assms exp_times_self_ge[of y] by (intro Lambert_W_strict_mono) auto thus ?thesis using assms by simp qed
lemma Lambert_W'_strict_antimono: assumes"-exp (-1) ≤ x""x < y""y < 0" shows"Lambert_W' x > Lambert_W' y" proof (rule ccontr) assume"¬(Lambert_W' x > Lambert_W' y)" hence"Lambert_W' x * exp (Lambert_W' x) ≥ Lambert_W' y * exp (Lambert_W' y)" using assms by (intro exp_times_self_antimono Lambert_W'_le) auto hence"x ≥ y" using assms by (simp add: Lambert_W'_times_exp_self) with assms show False by simp qed
lemma Lambert_W'_antimono: assumes"x ≥ -exp(-1)""x ≤ y""y < 0" shows"Lambert_W' x ≥ Lambert_W' y" using Lambert_W'_strict_antimono[of x y] assms by (cases "x = y") auto
lemma Lambert_W'_eq_iff [simp]: "x ∈ {-exp(-1)..<0} ==> y ∈ {-exp(-1)..<0} ==> Lambert_W' x = Lambert_W' y ⟷ x = y" using Lambert_W'_strict_antimono[of x y] Lambert_W'_strict_antimono[of y x] by (cases x y rule: linorder_cases) auto
lemma Lambert_W'_le_iff [simp]: "x ∈ {-exp(-1)..<0} ==> y ∈ {-exp(-1)..<0} ==> Lambert_W' x ≤ Lambert_W' y ⟷ x ≥ y" using Lambert_W'_strict_antimono[of x y] Lambert_W'_strict_antimono[of y x] by (cases x y rule: linorder_cases) auto
lemma Lambert_W'_less_iff [simp]: "x ∈ {-exp(-1)..<0} ==> y ∈ {-exp(-1)..<0} ==> Lambert_W' x < Lambert_W' y ⟷ x > y" using Lambert_W'_strict_antimono[of x y] Lambert_W'_strict_antimono[of y x] by (cases x y rule: linorder_cases) auto
lemma Lambert_W'_le_minus_one: assumes"x ≤ -exp(-1)" shows"Lambert_W' x = -1" proof (cases "x = -exp(-1)") case False thus ?thesis using assms by (auto simp: Lambert_W'_def) qed auto
lemma Lambert_W'_ge_zero: "x ≥ 0 ==> Lambert_W' x = -1" by (simp add: Lambert_W'_def)
lemma Lambert_W'_neg: "Lambert_W' x < 0" by (rule le_less_trans[OF Lambert_W'_le]) auto
lemma Lambert_W'_nz [simp]: "Lambert_W' x ≠ 0" using Lambert_W'_neg[of x] by simp
lemma Lambert_W'_geI: assumes"y * exp y ≥ x""y ≤ -1""x ≥ -exp(-1)" shows"Lambert_W' x ≥ y" proof - from assms have"y * exp y < 0" by (intro mult_neg_pos) auto hence"Lambert_W' x ≥ Lambert_W' (y * exp y)" using assms exp_times_self_ge[of y] by (intro Lambert_W'_antimono) auto thus ?thesis using assms by simp qed
lemma Lambert_W'_gtI: assumes"y * exp y > x""y ≤ -1""x ≥ -exp(-1)" shows"Lambert_W' x ≥ y" proof - from assms have"y * exp y < 0" by (intro mult_neg_pos) auto hence"Lambert_W' x > Lambert_W' (y * exp y)" using assms exp_times_self_ge[of y] by (intro Lambert_W'_strict_antimono) auto thus ?thesis using assms by simp qed
lemma Lambert_W'_leI: assumes"y * exp y ≤ x""x < 0" shows"Lambert_W' x ≤ y" proof (cases "y ≤ -1") case True have"Lambert_W' x ≤ Lambert_W' (y * exp y)" using assms exp_times_self_ge[of y] by (intro Lambert_W'_antimono) auto thus ?thesis using assms True by simp next case False have"Lambert_W' x ≤ -1" by (rule Lambert_W'_le) alsohave"… < y" using False by simp finallyshow ?thesis by simp qed
lemma Lambert_W'_lessI: assumes"y * exp y < x""x < 0" shows"Lambert_W' x < y" proof (cases "y ≤ -1") case True have"Lambert_W' x < Lambert_W' (y * exp y)" using assms exp_times_self_ge[of y] by (intro Lambert_W'_strict_antimono) auto thus ?thesis using assms True by simp next case False have"Lambert_W' x ≤ -1" by (rule Lambert_W'_le) alsohave"… < y" using False by simp finallyshow ?thesis by simp qed
lemma bij_betw_exp_times_self_atLeastAtMost: fixes a b :: real assumes"a ≥ -1""a ≤ b" shows"bij_betw (λx. x * exp x) {a..b} {a * exp a..b * exp b}" unfolding bij_betw_def proof show"inj_on (λx. x * exp x) {a..b}" by (rule inj_on_subset[OF exp_times_self_inj]) (use assms in auto) next show"(λx. x * exp x) ` {a..b} = {a * exp a..b * exp b}" proof safe fix x assume"x ∈ {a..b}" thus"x * exp x ∈ {a * exp a..b * exp b}" using assms by (auto intro!: exp_times_self_mono) next fix x assume x: "x ∈ {a * exp a..b * exp b}" have"(-1) * exp (-1) ≤ a * exp a" using assms by (intro exp_times_self_mono) auto alsohave"…≤ x"using x by simp finallyhave"x ≥ -exp (-1)"by simp
have"Lambert_W x ∈ {a..b}" using x ‹x ≥ -exp (-1)› assms by (auto intro!: Lambert_W_geI Lambert_W_leI) moreoverhave"Lambert_W x * exp (Lambert_W x) = x" using‹x ≥ -exp (-1)›by (simp add: Lambert_W_times_exp_self) ultimatelyshow"x ∈ (λx. x * exp x) ` {a..b}" unfolding image_iff by metis qed qed
lemma bij_betw_exp_times_self_atLeastAtMost': fixes a b :: real assumes"a ≤ b""b ≤ -1" shows"bij_betw (λx. x * exp x) {a..b} {b * exp b..a * exp a}" unfolding bij_betw_def proof show"inj_on (λx. x * exp x) {a..b}" by (rule inj_on_subset[OF exp_times_self_inj']) (use assms in auto) next show"(λx. x * exp x) ` {a..b} = {b * exp b..a * exp a}" proof safe fix x assume"x ∈ {a..b}" thus"x * exp x ∈ {b * exp b..a * exp a}" using assms by (auto intro!: exp_times_self_antimono) next fix x assume x: "x ∈ {b * exp b..a * exp a}" from assms have"a * exp a < 0" by (intro mult_neg_pos) auto with x have"x < 0"by auto have"(-1) * exp (-1) ≤ b * exp b" using assms by (intro exp_times_self_antimono) auto alsohave"…≤ x"using x by simp finallyhave"x ≥ -exp (-1)"by simp
have"Lambert_W' x ∈ {a..b}" using x ‹x ≥ -exp (-1)›‹x < 0› assms by (auto intro!: Lambert_W'_geI Lambert_W'_leI) moreoverhave"Lambert_W' x * exp (Lambert_W' x) = x" using‹x ≥ -exp (-1)›‹x < 0›by (auto simp: Lambert_W'_times_exp_self) ultimatelyshow"x ∈ (λx. x * exp x) ` {a..b}" unfolding image_iff by metis qed qed
lemma bij_betw_exp_times_self_atLeast: fixes a :: real assumes"a ≥ -1" shows"bij_betw (λx. x * exp x) {a..} {a * exp a..}" unfolding bij_betw_def proof show"inj_on (λx. x * exp x) {a..}" by (rule inj_on_subset[OF exp_times_self_inj]) (use assms in auto) next show"(λx. x * exp x) ` {a..} = {a * exp a..}" proof safe fix x assume"x ≥ a" thus"x * exp x ≥ a * exp a" using assms by (auto intro!: exp_times_self_mono) next fix x assume x: "x ≥ a * exp a" have"(-1) * exp (-1) ≤ a * exp a" using assms by (intro exp_times_self_mono) auto alsohave"…≤ x"using x by simp finallyhave"x ≥ -exp (-1)"by simp
have"Lambert_W x ∈ {a..}" using x ‹x ≥ -exp (-1)› assms by (auto intro!: Lambert_W_geI Lambert_W_leI) moreoverhave"Lambert_W x * exp (Lambert_W x) = x" using‹x ≥ -exp (-1)›by (simp add: Lambert_W_times_exp_self) ultimatelyshow"x ∈ (λx. x * exp x) ` {a..}" unfolding image_iff by metis qed qed
subsection‹Basic identities and bounds›
lemma Lambert_W_2_ln_2 [simp]: "Lambert_W (2 * ln 2) = ln 2" proof - have"-1 ≤ (0 :: real)" by simp alsohave"…≤ ln 2" by simp finallyhave"-1 ≤ (ln 2 :: real)" . thus ?thesis by (intro Lambert_W_eqI) auto qed
lemma Lambert_W_exp_1 [simp]: "Lambert_W (exp 1) = 1" by (rule Lambert_W_eqI) auto
lemma Lambert_W_neg_ln_over_self: assumes"x ∈ {exp (-1)..exp 1}" shows"Lambert_W (-ln x / x) = -ln x" proof - have"0 < (exp (-1) :: real)" by simp alsohave"…≤ x" using assms by simp finallyhave"x > 0" . from‹x > 0› assms have"ln x ≤ ln (exp 1)" by (subst ln_le_cancel_iff) auto alsohave"ln (exp 1) = (1 :: real)" by simp finallyhave"ln x ≤ 1" . show ?thesis using assms ‹x > 0›‹ln x ≤ 1› by (intro Lambert_W_eqI) (auto simp: exp_minus field_simps) qed
lemma Lambert_W'_neg_ln_over_self: assumes"x ≥ exp 1" shows"Lambert_W' (-ln x / x) = -ln x" proof (rule Lambert_W'_eqI) have"0 < (exp 1 :: real)" by simp alsohave"…≤ x" by fact finallyhave"x > 0" . from assms ‹x > 0›have"ln x ≥ ln (exp 1)" by (subst ln_le_cancel_iff) auto thus"-ln x ≤ -1"by simp show"-ln x * exp (-ln x) = -ln x / x" using‹x > 0›by (simp add: field_simps exp_minus) qed
lemma exp_Lambert_W: "x ≥ -exp (-1) ==> x ≠ 0 ==> exp (Lambert_W x) = x / Lambert_W x" using Lambert_W_times_exp_self[of x] by (auto simp add: divide_simps mult_ac)
lemma exp_Lambert_W': "x ∈ {-exp (-1)..<0} ==> exp (Lambert_W' x) = x / Lambert_W' x" using Lambert_W'_times_exp_self[of x] by (auto simp add: divide_simps mult_ac)
have"exp (ln (Lambert_W x)) = exp (ln x - Lambert_W x)" using assms x by (subst exp_diff) (auto simp: exp_Lambert_W) thus ?thesis by (subst (asm) exp_inj_iff) qed
lemma ln_minus_Lambert_W': assumes"x ∈ {-exp (-1)..<0}" shows"ln (-Lambert_W' x) = ln (-x) - Lambert_W' x" proof - have"exp (ln (-x) - Lambert_W' x) = -Lambert_W' x" using assms by (simp add: exp_diff exp_Lambert_W') alsohave"… = exp (ln (-Lambert_W' x))" using Lambert_W'_neg[of x] by simp finallyshow ?thesis by simp qed
lemma Lambert_W_plus_Lambert_W_eq: assumes"x > 0""y > 0" shows"Lambert_W x + Lambert_W y = Lambert_W (x * y * (1 / Lambert_W x + 1 / Lambert_W y))" proof (rule sym, rule Lambert_W_eqI) have"x > -exp(-1)""y > -exp (-1)" by (rule less_trans[OF _ assms(1)] less_trans[OF _ assms(2)], simp)+ with assms show"(Lambert_W x + Lambert_W y) * exp (Lambert_W x + Lambert_W y) = x * y * (1 / Lambert_W x + 1 / Lambert_W y)" by (auto simp: field_simps exp_add exp_Lambert_W) have"-1 ≤ (0 :: real)" by simp alsofrom assms have"…≤ Lambert_W x + Lambert_W y" by (intro add_nonneg_nonneg) auto finallyshow"…≥ -1" . qed
lemma Lambert_W'_plus_Lambert_W'_eq: assumes"x ∈ {-exp(-1)..<0}""y ∈ {-exp(-1)..<0}" shows"Lambert_W' x + Lambert_W' y = Lambert_W' (x * y * (1 / Lambert_W' x + 1 / Lambert_W' y))" proof (rule sym, rule Lambert_W'_eqI) from assms show"(Lambert_W' x + Lambert_W' y) * exp (Lambert_W' x + Lambert_W' y) = x * y * (1 / Lambert_W' x + 1 / Lambert_W' y)" by (auto simp: field_simps exp_add exp_Lambert_W') have"Lambert_W' x + Lambert_W' y ≤ -1 + -1" by (intro add_mono Lambert_W'_le) alsohave"…≤ -1"by simp finallyshow"Lambert_W' x + Lambert_W' y ≤ -1" . qed
lemma Lambert_W_gt_ln_minus_ln_ln: assumes"x > exp 1" shows"Lambert_W x > ln x - ln (ln x)" proof (rule Lambert_W_gtI) have"x > 1" by (rule less_trans[OF _ assms]) auto have"ln x > ln (exp 1)" by (subst ln_less_cancel_iff) (use‹x > 1› assms in auto) thus"(ln x - ln (ln x)) * exp (ln x - ln (ln x)) < x" using assms ‹x > 1›by (simp add: exp_diff field_simps) qed
lemma Lambert_W_less_ln: assumes"x > exp 1" shows"Lambert_W x < ln x" proof (rule Lambert_W_lessI) have"x > 0" by (rule less_trans[OF _ assms]) auto have"ln x > ln (exp 1)" by (subst ln_less_cancel_iff) (use‹x > 0› assms in auto) thus"x < ln x * exp (ln x)" using‹x > 0›by simp show"ln x ≥ -1" by (rule less_imp_le[OF le_less_trans[OF _ ‹ln x > _›]]) auto show"x ≥ -exp (-1)" by (rule less_imp_le[OF le_less_trans[OF _ ‹x > 0›]]) auto qed
subsection‹Limits, continuity, and differentiability›
lemma filterlim_Lambert_W_at_top [tendsto_intros]: "filterlim Lambert_W at_top at_top" unfolding filterlim_at_top proof fix C :: real have"eventually (λx. x ≥ C * exp C) at_top" by (rule eventually_ge_at_top) thus"eventually (λx. Lambert_W x ≥ C) at_top" proof eventually_elim case (elim x) thus ?case by (intro Lambert_W_geI) auto qed qed
lemma filterlim_Lambert_W_at_left_0 [tendsto_intros]: "filterlim Lambert_W' at_bot (at_left 0)" unfolding filterlim_at_bot proof fix C :: real
define C' where"C' = min C (-1)" have"C' < 0""C' ≤ C" by (simp_all add: C'_def) have"C' * exp C' < 0" using‹C' < 0›by (intro mult_neg_pos) auto hence"eventually (λx. x ≥ C' * exp C') (at_left 0)" by real_asymp moreoverhave"eventually (λx::real. x < 0) (at_left 0)" by real_asymp ultimatelyshow"eventually (λx. Lambert_W' x ≤ C) (at_left 0)" proof eventually_elim case (elim x) hence"Lambert_W' x ≤ C'" by (intro Lambert_W'_leI) auto alsohave"…≤ C"by fact finallyshow ?case . qed qed
lemma continuous_on_Lambert_W [continuous_intros]: "continuous_on {-exp (-1)..} Lambert_W" proof - have *: "continuous_on {-exp (-1)..b * exp b} Lambert_W"if"b ≥ 0"for b proof - have"continuous_on ((λx. x * exp x) ` {-1..b}) Lambert_W" by (rule continuous_on_inv) (auto intro!: continuous_intros) alsohave"(λx. x * exp x) ` {-1..b} = {-exp (-1)..b * exp b}" using bij_betw_exp_times_self_atLeastAtMost[of "-1" b] ‹b ≥ 0› by (simp add: bij_betw_def) finallyshow ?thesis . qed
have"continuous (at x) Lambert_W"if"x ≥ 0"for x proof - have x: "-exp (-1) < x" by (rule less_le_trans[OF _ that]) auto
define b where"b = Lambert_W x + 1" have"b ≥ 0" using Lambert_W_ge[of x] by (simp add: b_def) have"x = Lambert_W x * exp (Lambert_W x)" using that x by (subst Lambert_W_times_exp_self) auto alsohave"… < b * exp b" by (intro exp_times_self_strict_mono) (auto simp: b_def Lambert_W_ge) finallyhave"b * exp b > x" . have"continuous_on {-exp(-1)<..<b * exp b} Lambert_W" by (rule continuous_on_subset[OF *[of b]]) (use‹b ≥ 0›in auto) moreoverhave"x ∈ {-exp(-1)<..<b * exp b}" using‹b * exp b > x› x by auto ultimatelyshow"continuous (at x) Lambert_W" by (subst (asm) continuous_on_eq_continuous_at) auto qed hence"continuous_on {0..} Lambert_W" by (intro continuous_at_imp_continuous_on) auto moreoverhave"continuous_on {-exp (-1)..0} Lambert_W" using *[of 0] by simp ultimatelyhave"continuous_on ({-exp (-1)..0} ∪ {0..}) Lambert_W" by (intro continuous_on_closed_Un) auto alsohave"{-exp (-1)..0} ∪ {0..} = {-exp (-1::real)..}" using order.trans[of "-exp (-1)::real"0] by auto finallyshow ?thesis . qed
lemma continuous_on_Lambert_W_alt [continuous_intros]: assumes"continuous_on A f""∧x. x ∈ A ==> f x ≥ -exp (-1)" shows"continuous_on A (λx. Lambert_W (f x))" using continuous_on_compose2[OF continuous_on_Lambert_W assms(1)] assms by auto
lemma continuous_on_Lambert_W' [continuous_intros]: "continuous_on {-exp (-1)..<0} Lambert_W'" proof - have *: "continuous_on {-exp (-1)..-b * exp (-b)} Lambert_W'"if"b ≥ 1"for b proof - have"continuous_on ((λx. x * exp x) ` {-b..-1}) Lambert_W'" by (intro continuous_on_inv ballI) (auto intro!: continuous_intros) alsohave"(λx. x * exp x) ` {-b..-1} = {-exp (-1)..-b * exp (-b)}" using bij_betw_exp_times_self_atLeastAtMost'[of "-b""-1"] that by (simp add: bij_betw_def) finallyshow ?thesis . qed
have"continuous (at x) Lambert_W'"if"x > -exp (-1)""x < 0"for x proof -
define b where"b = Lambert_W x + 1" have"eventually (λb. -b * exp (-b) > x) at_top" using that by real_asymp hence"eventually (λb. b ≥ 1 ∧ -b * exp (-b) > x) at_top" by (intro eventually_conj eventually_ge_at_top) thenobtain b where b: "b ≥ 1""-b * exp (-b) > x" by (auto simp: eventually_at_top_linorder)
have"continuous_on {-exp(-1)<..<-b * exp (-b)} Lambert_W'" by (rule continuous_on_subset[OF *[of b]]) (use‹b ≥ 1›in auto) moreoverhave"x ∈ {-exp(-1)<..<-b * exp (-b)}" using b that by auto ultimatelyshow"continuous (at x) Lambert_W'" by (subst (asm) continuous_on_eq_continuous_at) auto qed hence **: "continuous_on {-exp (-1)<..<0} Lambert_W'" by (intro continuous_at_imp_continuous_on) auto
show ?thesis unfolding continuous_on_def proof fix x :: real assume x: "x ∈ {-exp(-1)..<0}" show"(Lambert_W' ---> Lambert_W' x) (at x within {-exp(-1)..<0})" proof (cases "x = -exp(-1)") case False hence"isCont Lambert_W' x" using x ** by (auto simp: continuous_on_eq_continuous_at) thus ?thesis using continuous_at filterlim_within_subset by blast next case True
define a :: real where"a = -2 * exp (-2)" have a: "a > -exp (-1)" using exp_times_self_strict_antimono[of "-1""-2"] by (auto simp: a_def) from True have"x ∈ {-exp (-1)..<a}" using a by (auto simp: a_def) have"continuous_on {-exp (-1)..<a} Lambert_W'" unfolding a_def by (rule continuous_on_subset[OF *[of 2]]) auto hence"(Lambert_W' ---> Lambert_W' x) (at x within {-exp (-1)..<a})" using‹x ∈ {-exp (-1)..<a}›by (auto simp: continuous_on_def) alsohave"at x within {-exp (-1)..<a} = at_right x" using a by (intro at_within_nhd[of _ "{..<a}"]) (auto simp: True) alsohave"… = at x within {-exp (-1)..<0}" using a by (intro at_within_nhd[of _ "{..<0}"]) (auto simp: True) finallyshow ?thesis . qed qed qed
lemma continuous_on_Lambert_W'_alt [continuous_intros]: assumes"continuous_on A f""∧x. x ∈ A ==> f x ∈ {-exp (-1)..<0}" shows"continuous_on A (λx. Lambert_W' (f x))" using continuous_on_compose2[OF continuous_on_Lambert_W' assms(1)] assms by (auto simp: subset_iff)
lemma tendsto_Lambert_W_1: assumes"(f ---> L) F""eventually (λx. f x ≥ -exp (-1)) F" shows"((λx. Lambert_W (f x)) ---> Lambert_W L) F" proof (cases "F = bot") case [simp]: False from tendsto_lowerbound[OF assms] have"L ≥ -exp (-1)"by simp thus ?thesis using continuous_on_tendsto_compose[OF continuous_on_Lambert_W assms(1)] assms(2) by simp qed auto
lemma tendsto_Lambert_W [tendsto_intros]: assumes"(f ---> L) F""eventually (λx. f x ≥ -exp (-1)) F ∨ L > -exp (-1)" shows"((λx. Lambert_W (f x)) ---> Lambert_W L) F" using assms(2) proof assume"L > -exp (-1)" from order_tendstoD(1)[OF assms(1) this] assms(1) show ?thesis by (intro tendsto_Lambert_W_1) (auto elim: eventually_mono) qed (use tendsto_Lambert_W_1[OF assms(1)] in auto)
lemma tendsto_Lambert_W'_1: assumes"(f ---> L) F""eventually (λx. f x ≥ -exp (-1)) F""L < 0" shows"((λx. Lambert_W' (f x)) ---> Lambert_W' L) F" proof (cases "F = bot") case [simp]: False from tendsto_lowerbound[OF assms(1,2)] have L_ge: "L ≥ -exp (-1)"by simp from order_tendstoD(2)[OF assms(1,3)] have ev: "eventually (λx. f x < 0) F" by auto with assms(2) have"eventually (λx. f x ∈ {-exp (-1)..<0}) F" by eventually_elim auto thus ?thesis using L_ge assms(3) by (intro continuous_on_tendsto_compose[OF continuous_on_Lambert_W' assms(1)]) auto qed auto
lemma tendsto_Lambert_W' [tendsto_intros]: assumes"(f ---> L) F""eventually (λx. f x ≥ -exp (-1)) F ∨ L > -exp (-1)""L < 0" shows"((λx. Lambert_W' (f x)) ---> Lambert_W' L) F" using assms(2) proof assume"L > -exp (-1)" from order_tendstoD(1)[OF assms(1) this] assms(1,3) show ?thesis by (intro tendsto_Lambert_W'_1) (auto elim: eventually_mono) qed (use tendsto_Lambert_W'_1[OF assms(1) _ assms(3)] in auto)
lemma continuous_Lambert_W [continuous_intros]: assumes"continuous F f""f (Lim F (λx. x)) > -exp (-1) ∨ eventually (λx. f x ≥ -exp (-1)) F" shows"continuous F (λx. Lambert_W (f x))" using assms unfolding continuous_def by (intro tendsto_Lambert_W) auto
lemma continuous_Lambert_W' [continuous_intros]: assumes"continuous F f""f (Lim F (λx. x)) > -exp (-1) ∨ eventually (λx. f x ≥ -exp (-1)) F" "f (Lim F (λx. x)) < 0" shows"continuous F (λx. Lambert_W' (f x))" using assms unfolding continuous_def by (intro tendsto_Lambert_W') auto
lemma has_field_derivative_Lambert_W [derivative_intros]: assumes x: "x > -exp (-1)" shows"(Lambert_W has_real_derivative inverse (x + exp (Lambert_W x))) (at x within A)" proof -
write Lambert_W (‹W›) from x have"W x > W (-exp (-1))" by (subst Lambert_W_less_iff) auto hence"W x > -1"by simp
note [derivative_intros] = DERIV_inverse_function[where g = Lambert_W] have"((λx. x * exp x) has_real_derivative (1 + W x) * exp (W x)) (at (W x))" by (auto intro!: derivative_eq_intros simp: algebra_simps) hence"(W has_real_derivative inverse ((1 + W x) * exp (W x))) (at x)" by (rule DERIV_inverse_function[where a = "-exp (-1)"and b = "x + 1"])
(use x ‹W x > -1›in‹auto simp: Lambert_W_times_exp_self Lim_ident_at
intro!: continuous_intros›) alsohave"(1 + W x) * exp (W x) = x + exp (W x)" using x by (simp add: algebra_simps Lambert_W_times_exp_self) finallyshow ?thesis by (rule has_field_derivative_at_within) qed
lemma has_field_derivative_Lambert_W_gen [derivative_intros]: assumes"(f has_real_derivative f') (at x within A)""f x > -exp (-1)" shows"((λx. Lambert_W (f x)) has_real_derivative (f' / (f x + exp (Lambert_W (f x))))) (at x within A)" using DERIV_chain2[OF has_field_derivative_Lambert_W[OF assms(2)] assms(1)] by (simp add: field_simps)
lemma has_field_derivative_Lambert_W' [derivative_intros]: assumes x: "x ∈ {-exp (-1)<..<0}" shows"(Lambert_W' has_real_derivative inverse (x + exp (Lambert_W' x))) (at x within A)" proof -
write Lambert_W' (‹W›) from x have"W x < W (-exp (-1))" by (subst Lambert_W'_less_iff) auto hence"W x < -1"by simp
note [derivative_intros] = DERIV_inverse_function[where g = Lambert_W] have"((λx. x * exp x) has_real_derivative (1 + W x) * exp (W x)) (at (W x))" by (auto intro!: derivative_eq_intros simp: algebra_simps) hence"(W has_real_derivative inverse ((1 + W x) * exp (W x))) (at x)" by (rule DERIV_inverse_function[where a = "-exp (-1)"and b = "0"])
(use x ‹W x < -1›in‹auto simp: Lambert_W'_times_exp_self Lim_ident_at
intro!: continuous_intros›) alsohave"(1 + W x) * exp (W x) = x + exp (W x)" using x by (simp add: algebra_simps Lambert_W'_times_exp_self) finallyshow ?thesis by (rule has_field_derivative_at_within) qed
lemma has_field_derivative_Lambert_W'_gen [derivative_intros]: assumes"(f has_real_derivative f') (at x within A)""f x ∈ {-exp (-1)<..<0}" shows"((λx. Lambert_W' (f x)) has_real_derivative (f' / (f x + exp (Lambert_W' (f x))))) (at x within A)" using DERIV_chain2[OF has_field_derivative_Lambert_W'[OF assms(2)] assms(1)] by (simp add: field_simps)
subsection‹Asymptotic expansion›
text‹
Lastly, we prove some more detailed asymptotic expansions of $W$ and $W'$ at their
singularities. First, we show that: \begin{align*}
W(x) &= \log x - \log\log x + o(\log\log x) &&\text{for}\ x\to\infty\\
W'(x) &= \log (-x) - \log (-\log (-x)) + o(\log (-\log (-x))) &&\text{for}\ x\to 0^{-} \end{align*} › theorem Lambert_W_asymp_equiv_at_top: "(λx. Lambert_W x - ln x) ∼[at_top] (λx. -ln (ln x))" proof - have"(λx. Lambert_W x - ln x) ∼[at_top] (λx. (-1) * ln (ln x))" proof (rule asymp_equiv_sandwich') fix c' :: real assume c': "c' ∈ {-2<..<-1}" have"eventually (λx. (ln x + c' * ln (ln x)) * exp (ln x + c' * ln (ln x)) ≤ x) at_top" "eventually (λx. ln x + c' * ln (ln x) ≥ -1) at_top" using c' by real_asymp+ thus"eventually (λx. Lambert_W x - ln x ≥ c' * ln (ln x)) at_top" proof eventually_elim case (elim x) hence"Lambert_W x ≥ ln x + c' * ln (ln x)" by (intro Lambert_W_geI) thus ?caseby simp qed next fix c' :: real assume c': "c' ∈ {-1<..<0}" have"eventually (λx. (ln x + c' * ln (ln x)) * exp (ln x + c' * ln (ln x)) ≥ x) at_top" "eventually (λx. ln x + c' * ln (ln x) ≥ -1) at_top" using c' by real_asymp+ thus"eventually (λx. Lambert_W x - ln x ≤ c' * ln (ln x)) at_top" using eventually_ge_at_top[of "-exp (-1)"] proof eventually_elim case (elim x) hence"Lambert_W x ≤ ln x + c' * ln (ln x)" by (intro Lambert_W_leI) thus ?caseby simp qed qed auto thus ?thesis by simp qed
lemma Lambert_W_asymp_equiv_at_top' [asymp_equiv_intros]: "Lambert_W ∼[at_top] ln" proof - have"(λx. Lambert_W x - ln x) ∈ Θ(λx. -ln (ln x))" by (intro asymp_equiv_imp_bigtheta Lambert_W_asymp_equiv_at_top) alsohave"(λx::real. -ln (ln x)) ∈ o(ln)" by real_asymp finallyshow ?thesis by (simp add: asymp_equiv_altdef) qed
theorem Lambert_W'_asymp_equiv_at_left_0: "(λx. Lambert_W' x - ln (-x)) ∼[at_left 0] (λx. -ln (-ln (-x)))" proof - have"(λx. Lambert_W' x - ln (-x)) ∼[at_left 0] (λx. (-1) * ln (-ln (-x)))" proof (rule asymp_equiv_sandwich') fix c' :: real assume c': "c' ∈ {-2<..<-1}" have"eventually (λx. x ≤ (ln (-x) + c' * ln (-ln (-x))) * exp (ln (-x) + c' * ln (-ln (-x)))) (at_left 0)" "eventually (λx::real. ln (-x) + c' * ln (-ln (-x)) ≤ -1) (at_left 0)" "eventually (λx::real. -exp (-1) ≤ x) (at_left 0)" using c' by real_asymp+ thus"eventually (λx. Lambert_W' x - ln (-x) ≥ c' * ln (-ln (-x))) (at_left 0)" proof eventually_elim case (elim x) hence"Lambert_W' x ≥ ln (-x) + c' * ln (-ln (-x))" by (intro Lambert_W'_geI) thus ?caseby simp qed next fix c' :: real assume c': "c' ∈ {-1<..<0}" have"eventually (λx. x ≥ (ln (-x) + c' * ln (-ln (-x))) * exp (ln (-x) + c' * ln (-ln (-x)))) (at_left 0)" using c' by real_asymp moreoverhave"eventually (λx::real. x < 0) (at_left 0)" by (auto simp: eventually_at intro: exI[of _ 1]) ultimatelyshow"eventually (λx. Lambert_W' x - ln (-x) ≤ c' * ln (-ln (-x))) (at_left 0)" proof eventually_elim case (elim x) hence"Lambert_W' x ≤ ln (-x) + c' * ln (-ln (-x))" by (intro Lambert_W'_leI) thus ?caseby simp qed qed auto thus ?thesis by simp qed
lemma Lambert_W'_asymp_equiv'_at_left_0 [asymp_equiv_intros]: "Lambert_W' ∼[at_left 0] (λx. ln (-x))" proof - have"(λx. Lambert_W' x - ln (-x)) ∈ Θ[at_left 0](λx. -ln (-ln (-x)))" by (intro asymp_equiv_imp_bigtheta Lambert_W'_asymp_equiv_at_left_0) alsohave"(λx::real. -ln (-ln (-x))) ∈ o[at_left 0](λx. ln (-x))" by real_asymp finallyshow ?thesis by (simp add: asymp_equiv_altdef) qed
text‹
Next, we look at the branching point $a := \tfrac{1}{e}$. Here, the asymptotic behaviour
is as follows: \begin{align*}
W(x) &= -1 + \sqrt{2e}(x - a)^{\frac{1}{2}} - \tfrac{2}{3}e(x-a) + o(x-a) &&\text{for} x\to a^+\\
W'(x) &= -1 - \sqrt{2e}(x - a)^{\frac{1}{2}} - \tfrac{2}{3}e(x-a) + o(x-a) &&\text{for} x\to a^+ \end{align*} › lemma sqrt_sqrt_mult: assumes"x ≥ (0 :: real)" shows"sqrt x * (sqrt x * y) = x * y" using assms by (subst mult.assoc [symmetric]) auto
theorem Lambert_W_asymp_equiv_at_right_minus_exp_minus1: defines"e ≡ exp 1" defines"a ≡ -exp (-1)" defines"C1 ≡ sqrt (2 * exp 1)" defines"f ≡ (λx. -1 + C1 * sqrt (x - a))" shows"(λx. Lambert_W x - f x) ∼[at_right a] (λx. -2/3 * e * (x - a))" proof -
define C :: "real ==> real"where"C = (λc. sqrt (2/e)/3 * (2*e+3*c))" have asymp_equiv: "(λx. (f x + c * (x - a)) * exp (f x + c * (x - a)) - x) ∼[at_right a] (λx. C c * (x - a) powr (3/2))"if"c ≠ -2/3 * e"for c proof - from that have"C c ≠ 0" by (auto simp: C_def e_def) have"(λx. (f x + c * (x - a)) * exp (f x + c * (x - a)) - x - C c * (x - a) powr (3/2)) ∈ o[at_right a](λx. (x - a) powr (3/2))" unfolding f_def a_def C_def C1_def e_def by (real_asymp simp: field_simps real_sqrt_mult real_sqrt_divide sqrt_sqrt_mult
exp_minus simp flip: sqrt_def) thus ?thesis using‹C c ≠ 0›by (intro smallo_imp_asymp_equiv) auto qed
show ?thesis proof (rule asymp_equiv_sandwich') fix c' :: real assume c': "c' ∈ {-e<..<-2/3*e}" hence neq: "c' ≠ -2/3 * e"by auto from c' have neg: "C c' < 0"unfolding C_def by (auto intro!: mult_pos_neg) hence"eventually (λx. C c' * (x - a) powr (3 / 2) < 0) (at_right a)" by real_asymp hence"eventually (λx. (f x + c' * (x - a)) * exp (f x + c' * (x - a)) - x < 0) (at_right a)" using asymp_equiv_eventually_neg_iff[OF asymp_equiv[OF neq]] by eventually_elim (use neg in auto) thus"eventually (λx. Lambert_W x - f x ≥ c' * (x - a)) (at_right a)" proof eventually_elim case (elim x) hence"Lambert_W x ≥ f x + c' * (x - a)" by (intro Lambert_W_geI) auto thus ?caseby simp qed next fix c' :: real assume c': "c' ∈ {-2/3*e<..<0}" hence neq: "c' ≠ -2/3 * e"by auto from c' have pos: "C c' > 0"unfolding C_def by auto hence"eventually (λx. C c' * (x - a) powr (3 / 2) > 0) (at_right a)" by real_asymp hence"eventually (λx. (f x + c' * (x - a)) * exp (f x + c' * (x - a)) - x > 0) (at_right a)" using asymp_equiv_eventually_pos_iff[OF asymp_equiv[OF neq]] by eventually_elim (use pos in auto) moreoverhave"eventually (λx. - 1 ≤ f x + c' * (x - a)) (at_right a)" "eventually (λx. x > a) (at_right a)" unfolding a_def f_def C1_def c' by real_asymp+ ultimatelyshow"eventually (λx. Lambert_W x - f x ≤ c' * (x - a)) (at_right a)" proof eventually_elim case (elim x) hence"Lambert_W x ≤ f x + c' * (x - a)" by (intro Lambert_W_leI) (auto simp: a_def) thus ?caseby simp qed qed (auto simp: e_def) qed
have asymp_equiv: "(λx. (f x + c * (x - a)) * exp (f x + c * (x - a)) - x) ∼[at_right a] (λx. C c * (x - a) powr (3/2))"if"c ≠ -2/3 * e"for c proof - from that have"C c ≠ 0" by (auto simp: C_def e_def) have"(λx. (f x + c * (x - a)) * exp (f x + c * (x - a)) - x - C c * (x - a) powr (3/2)) ∈ o[at_right a](λx. (x - a) powr (3/2))" unfolding f_def a_def C_def C1_def e_def by (real_asymp simp: field_simps real_sqrt_mult real_sqrt_divide sqrt_sqrt_mult
exp_minus simp flip: sqrt_def) thus ?thesis using‹C c ≠ 0›by (intro smallo_imp_asymp_equiv) auto qed
show ?thesis proof (rule asymp_equiv_sandwich') fix c' :: real assume c': "c' ∈ {-e<..<-2/3*e}" hence neq: "c' ≠ -2/3 * e"by auto from c' have pos: "C c' > 0"unfolding C_def by (auto intro!: mult_pos_neg) hence"eventually (λx. C c' * (x - a) powr (3 / 2) > 0) (at_right a)" by real_asymp hence"eventually (λx. (f x + c' * (x - a)) * exp (f x + c' * (x - a)) - x > 0) (at_right a)" using asymp_equiv_eventually_pos_iff[OF asymp_equiv[OF neq]] by eventually_elim (use pos in auto) moreoverhave"eventually (λx. x > a) (at_right a)" "eventually (λx. f x + c' * (x - a) ≤ -1) (at_right a)" unfolding a_def f_def C1_def c' by real_asymp+ ultimatelyshow"eventually (λx. Lambert_W' x - f x ≥ c' * (x - a)) (at_right a)" proof eventually_elim case (elim x) hence"Lambert_W' x ≥ f x + c' * (x - a)" by (intro Lambert_W'_geI) (auto simp: a_def) thus ?caseby simp qed next fix c' :: real assume c': "c' ∈ {-2/3*e<..<0}" hence neq: "c' ≠ -2/3 * e"by auto from c' have neg: "C c' < 0"unfolding C_def by auto hence"eventually (λx. C c' * (x - a) powr (3 / 2) < 0) (at_right a)" by real_asymp hence"eventually (λx. (f x + c' * (x - a)) * exp (f x + c' * (x - a)) - x < 0) (at_right a)" using asymp_equiv_eventually_neg_iff[OF asymp_equiv[OF neq]] by eventually_elim (use neg in auto) moreoverhave"eventually (λx. x < 0) (at_right a)" unfolding a_def by real_asymp ultimatelyshow"eventually (λx. Lambert_W' x - f x ≤ c' * (x - a)) (at_right a)" proof eventually_elim case (elim x) hence"Lambert_W' x ≤ f x + c' * (x - a)" by (intro Lambert_W'_leI) auto thus ?caseby simp qed qed (auto simp: e_def) qed
text‹
Lastly, just for fun, we derive a slightly more accurate expansion of $W_0(x)$ for $x\to\infty$: › theorem Lambert_W_asymp_equiv_at_top'': "(λx. Lambert_W x - ln x + ln (ln x)) ∼[at_top] (λx. ln (ln x) / ln x)" proof - have"(λx. Lambert_W x - ln x + ln (ln x)) ∼[at_top] (λx. 1 * (ln (ln x) / ln x))" proof (rule asymp_equiv_sandwich') fix c' :: real assume c': "c' ∈ {0<..<1}"
define a where"a = (λx::real. ln x - ln (ln x) + c' * (ln (ln x) / ln x))" have"eventually (λx. a x * exp (a x) ≤ x) at_top" using c' unfolding a_def by real_asymp+ thus"eventually (λx. Lambert_W x - ln x + ln (ln x) ≥ c' * (ln (ln x) / ln x)) at_top" proof eventually_elim case (elim x) hence"Lambert_W x ≥ a x" by (intro Lambert_W_geI) thus ?caseby (simp add: a_def) qed next fix c' :: real assume c': "c' ∈ {1<..<2}"
define a where"a = (λx::real. ln x - ln (ln x) + c' * (ln (ln x) / ln x))" have"eventually (λx. a x * exp (a x) ≥ x) at_top" "eventually (λx. a x ≥ -1) at_top" using c' unfolding a_def by real_asymp+ thus"eventually (λx. Lambert_W x - ln x + ln (ln x) ≤ c' * (ln (ln x) / ln x)) at_top" using eventually_ge_at_top[of "-exp (-1)"] proof eventually_elim case (elim x) hence"Lambert_W x ≤ a x" by (intro Lambert_W_leI) thus ?caseby (simp add: a_def) qed qed auto thus ?thesis by simp qed
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet am 2026-06-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.