Zulip Chat Archive

Stream: Is there code for X?

Topic: Integrability of log in a closed interval containing zero


Stefan Kebekus (Aug 12 2024 at 08:46):

Dear all,

I am stuck trying to compute very elementary integrals such as 01lnxdx\int_0^1 \ln x dx, and I cannot figure out what theorems of Mathlib would apply in this setting. Any help is greatly appreciated!

Best,

Stefan.

PS: I really want slightly more elaborate integrals of elementary complex analysis, such as 02πln(4sin2(θ/2))dθ\int_0^{2π} \ln (4*\sin^2 (θ/2)) dθ, but maybe I should start with the first case I cannot handle…

Johan Commelin (Aug 12 2024 at 15:09):

Hmm, there is docs#integral_log, but it seems that mathlib really doesn't like having 0 in the domain of integration of log.

Gareth Ma (Aug 12 2024 at 16:37):

Without looking into the actual Mathlib implementation of the details, you can always prove the Tendsto result instead, i.e. limε0ε1log(x)dx\lim_{\varepsilon \to 0} \int_{\varepsilon}^1 \log(x) \mathrm{d}x

Gareth Ma (Aug 12 2024 at 16:41):

@\Stefan, indeed it would be nice to have 0π/2log(sinx)dx\int_0^{\pi / 2} \log(\sin x) \mathrm{d}x in Mathlib (or other upper bounds), and 0π/4log(tanx)dx\int_0^{\pi / 4} \log(\tan x) \mathrm{d}x would be fun* to formalise too, IIRC it's not in Mathlib.

*My definition of fun is usually different from others. In this case it's from when I learned it for an integration competition(?) I wonder how hard would it be to formalise the typical proof, which is quite handwavy with series expansion everywhere..

Johan Commelin (Aug 12 2024 at 16:42):

Gareth Ma said:

Without looking into the actual Mathlib implementation of the details, you can always prove the Tendsto result instead, i.e. limε0ε1log(x)dx\lim_{\varepsilon \to 0} \int_{\varepsilon}^1 \log(x) \mathrm{d}x

Do we have the API to make this easy? I can't find it.

cc @Yury G. Kudryashov @Floris van Doorn @Sébastien Gouëzel

Gareth Ma (Aug 12 2024 at 17:07):

import Mathlib.Analysis.SpecialFunctions.Integrals

open scoped Interval Topology
open Real Filter MeasureTheory intervalIntegral

#check Function.rightLim
#check integral_log
example : Tendsto (fun ε :    x in ε..1, log x) (𝓝[>] 0) (𝓝 (-1)) := by
  -- if h holds, then we can `convert` and prove that the two functions are equal on ε > 0
  suffices h : Tendsto (fun ε :   -1 - ε * log ε + ε) (𝓝[>] 0) (𝓝 (-1)) by
    convert tendsto_nhdsWithin_congr ?_ h
    intro x hx
    rw [Set.mem_Ioi] at hx
    rw [integral_log_of_pos hx zero_lt_one]
    norm_num
    abel

  -- now we prove h holds! which should be simple limits
  -- I write out all the details but obviously they can be golfed
  have h1 : Tendsto (fun ε :   (-1 : )) (𝓝[>] 0) (𝓝 (-1)) :=
    tendsto_const_nhds -- (x := (-1 : ℝ)) (f := 𝓝[>] 0)
  have h2 : Tendsto (fun ε :   ε * log ε) (𝓝[>] 0) (𝓝 0) := by
    -- left as an exercise to the reader - jk
    -- I found this using https://leansearch.net
    -- Query: "x * log(x) -> 0 as x -> 0"
    have := tendsto_log_mul_rpow_nhds_zero zero_lt_one
    simp_rw [rpow_one, mul_comm] at this
    exact this
  have h3 : Tendsto (fun ε :   ε) (𝓝[>] 0) (𝓝 0) :=
    -- we don't need the [>] part of the filter
    tendsto_nhdsWithin_of_tendsto_nhds tendsto_id

  -- note the use of dot notation here
  convert (h1.sub h2).add h3 using 2
  norm_num

Gareth Ma (Aug 12 2024 at 17:07):

@Stefan Kebekus :) (I also just learned about the \nhds[>] notation, it's very cool!)

Sébastien Gouëzel (Aug 12 2024 at 17:18):

To avoid the limiting argument and working directly on the interval, I'd try to use docs#intervalIntegral.integral_eq_sub_of_hasDerivAt_of_tendsto, together with docs#intervalIntegral.intervalIntegrable_deriv_of_nonneg to check the integrability without bothering too much.

Gareth Ma (Aug 12 2024 at 17:58):

I don't think it works? xlog(x)xx\log(x) - x is not continuous at 00

Gareth Ma (Aug 12 2024 at 17:58):

Wait it is

Gareth Ma (Aug 12 2024 at 18:10):

I suggested my method above since I wasn't sure if the integral is integrable (in Mathlib?), but it works out. I also finished the proof for practice, because I'm also not familiar with measure theory things

example :  x in (0 : )..1, log x = -1 := by
  rw [integral_eq_sub_of_hasDerivAt_of_tendsto (f := fun x  x * log x - x) (fa := 0) (fb := -1)]
  · simp
  · simp
  · intro x hx
    norm_num at hx
    convert (hasDerivAt_mul_log hx.left.ne.symm).sub (hasDerivAt_id x) using 1
    norm_num
  · rw [ neg_neg log]
    apply IntervalIntegrable.neg
    apply intervalIntegrable_deriv_of_nonneg (g := fun x  -(x * log x - x))
    · exact (continuous_mul_log.continuousOn.sub continuous_id.continuousOn).neg
    · intro x hx
      norm_num at hx
      convert ((hasDerivAt_mul_log hx.left.ne.symm).sub (hasDerivAt_id x)).neg using 1
      norm_num
    · intro x hx
      norm_num at hx
      rw [Pi.neg_apply, Left.nonneg_neg_iff]
      exact (log_nonpos_iff hx.left).mpr hx.right.le
  · have := tendsto_log_mul_rpow_nhds_zero zero_lt_one
    simp_rw [rpow_one, mul_comm] at this
    -- tendsto_nhdsWithin_of_tendsto_nhds should be under Tendsto namespace
    convert this.sub (tendsto_nhdsWithin_of_tendsto_nhds tendsto_id)
    norm_num

Ruben Van de Velde (Aug 12 2024 at 19:02):

Can you generalise to 0..t?

Gareth Ma (Aug 12 2024 at 19:09):

Yes, I was just lazy

Gareth Ma (Aug 12 2024 at 19:13):

Oh actually no not directly, because the strategy I'm using (I didn't look at alternate paths) is the intervalIntegrable_deriv_of_nonneg suggested above, which requires f(x)0f'(x) \geq 0 to prove f(x)f'(x) is integrable on the interval. In the proof above I wrote it as (log(x))-(-\log(x)) then used Integrable.neg or whatever

Gareth Ma (Aug 12 2024 at 19:13):

But you can split it into two intervals. let me see

Gareth Ma (Aug 12 2024 at 19:33):

example {t : } (ht : 0 < t) :  x in (0 : )..t, log x = t * log t - t := by
  rw [ integral_add_adjacent_intervals (b := 1)]
  trans (-1) + (t * log t - t + 1)
  · congr
    · -- ∫ x in 0..1, log x = -1, same proof as before
      rw [integral_eq_sub_of_hasDerivAt_of_tendsto (f := fun x  x * log x - x) (fa := 0) (fb := -1)]
      · simp
      · simp
      · intro x hx
        norm_num at hx
        convert (hasDerivAt_mul_log hx.left.ne.symm).sub (hasDerivAt_id x) using 1
        norm_num
      · rw [ neg_neg log]
        apply IntervalIntegrable.neg
        apply intervalIntegrable_deriv_of_nonneg (g := fun x  -(x * log x - x))
        · exact (continuous_mul_log.continuousOn.sub continuous_id.continuousOn).neg
        · intro x hx
          norm_num at hx
          convert ((hasDerivAt_mul_log hx.left.ne.symm).sub (hasDerivAt_id x)).neg using 1
          norm_num
        · intro x hx
          norm_num at hx
          rw [Pi.neg_apply, Left.nonneg_neg_iff]
          exact (log_nonpos_iff hx.left).mpr hx.right.le
      · have := tendsto_log_mul_rpow_nhds_zero zero_lt_one
        simp_rw [rpow_one, mul_comm] at this
        -- tendsto_nhdsWithin_of_tendsto_nhds should be under Tendsto namespace
        convert this.sub (tendsto_nhdsWithin_of_tendsto_nhds tendsto_id)
        norm_num
      · rw [(by simp : -1 = 1 * log 1 - 1)]
        apply tendsto_nhdsWithin_of_tendsto_nhds
        exact (continuousAt_id.mul (continuousAt_log one_ne_zero)).sub continuousAt_id
    · -- ∫ x in 1..t, log x = t * log t + 1, just use integral_log_of_pos
      rw [integral_log_of_pos zero_lt_one ht]
      norm_num
  · abel
  · -- log is integrable on [[0, 1]]
    rw [ neg_neg log]
    apply IntervalIntegrable.neg
    apply intervalIntegrable_deriv_of_nonneg (g := fun x  -(x * log x - x))
    · exact (continuous_mul_log.continuousOn.sub continuous_id.continuousOn).neg
    · intro x hx
      norm_num at hx
      convert ((hasDerivAt_mul_log hx.left.ne.symm).sub (hasDerivAt_id x)).neg using 1
      norm_num
    · intro x hx
      norm_num at hx
      rw [Pi.neg_apply, Left.nonneg_neg_iff]
      exact (log_nonpos_iff hx.left).mpr hx.right.le
  · -- log is integrable on [[0, t]]
    simp [Set.mem_uIcc, ht]

Gareth Ma (Aug 12 2024 at 19:35):

By the way, in the proof I showed that log(x)\log(x) is integrable on [0,1][0, 1] (closed), but intervalIntegrable_log only shows log(x)\log(x) is integrable on any interval [a,b][a, b] where 0∉[a,b]0 \not\in [a, b] (i.e. both positive or negative). So I think there can be some strengthening

  • When the measure is the volume measure!

Gareth Ma (Aug 12 2024 at 19:35):

I don't think it's in Mathlib

Gareth Ma (Aug 12 2024 at 19:53):

(deleted)

Gareth Ma (Aug 12 2024 at 19:54):

(deleted)

Stefan Kebekus (Aug 13 2024 at 06:41):

@Gareth Ma @Johan Commelin @Ruben Van de Velde @Sébastien Gouëzel Thanks again for your extremely generous help. Most likely, I would have been stuck for weeks.

Stefan Kebekus (Aug 13 2024 at 06:42):

@Gareth Ma Is it ok with you if I add your code to my Nevanlinna project? -- This is a project in the making, where I try to formalize the most basic theorems of Nevanlinna theory.

Johan Commelin (Aug 13 2024 at 06:59):

@Gareth Ma I agree that there can be some strengthening. The condition can be 0(a,b)0 \notin (a,b).

Johan Commelin (Aug 13 2024 at 07:00):

If you want to PR that strengthening to mathlib, that would be great. And maybe you can abstract some general "tools" from your proof into lemmas that can be useful in other places as well?

Johan Commelin (Aug 13 2024 at 07:01):

Because the original question by Stefan should ideally have a proof that is < 5 lines using mathlib.

Johan Commelin (Aug 13 2024 at 07:01):

(Preferably even a 1-liner, of course.)

Gareth Ma (Aug 13 2024 at 07:24):

Stefan Kebekus said:

Gareth Ma Is it ok with you if I add your code to my Nevanlinna project? -- This is a project in the making, where I try to formalize the most basic theorems of Nevanlinna theory.

Yes sure! I am already working on some other projects so I might not be too active, but (just like this thread) I can help with stuff here and there :)

Stefan Kebekus (Aug 13 2024 at 07:24):

@Gareth Ma Thanks!

Gareth Ma (Aug 13 2024 at 07:26):

Johan Commelin said:

Gareth Ma I agree that there can be some strengthening. The condition can be 0(a,b)0 \notin (a,b).

Actually you don't need any restrictions on [a,b][a, b] or (a,b)(a, b) at all. https://gist.github.com/grhkm21/a6ea62be3dad5b0eec0602025ffd7781 (I deleted it above, it's somewhere in the edit history)

The sorry can be filled in by copying the proof above, I tried by symmetry but can't find the API

Gareth Ma (Aug 13 2024 at 07:26):

So theorem intervalIntegrable_log' (a b : ℝ) : IntervalIntegrable log volume a b := by holds


Last updated: May 02 2025 at 03:31 UTC