Skip to content

Commit

Permalink
feat: port Analysis.Fourier.FourierTransform (#4927)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ruben-VandeVelde committed Jun 9, 2023
1 parent 0a81ec1 commit 708e990
Show file tree
Hide file tree
Showing 2 changed files with 282 additions and 0 deletions.
1 change: 1 addition & 0 deletions Mathlib.lean
Expand Up @@ -562,6 +562,7 @@ import Mathlib.Analysis.Convex.StrictConvexBetween
import Mathlib.Analysis.Convex.StrictConvexSpace
import Mathlib.Analysis.Convex.Topology
import Mathlib.Analysis.Convex.Uniform
import Mathlib.Analysis.Fourier.FourierTransform
import Mathlib.Analysis.Hofer
import Mathlib.Analysis.InnerProductSpace.Adjoint
import Mathlib.Analysis.InnerProductSpace.Basic
Expand Down
281 changes: 281 additions & 0 deletions Mathlib/Analysis/Fourier/FourierTransform.lean
@@ -0,0 +1,281 @@
/-
Copyright (c) 2023 David Loeffler. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Loeffler
! This file was ported from Lean 3 source module analysis.fourier.fourier_transform
! leanprover-community/mathlib commit fd5edc43dc4f10b85abfe544b88f82cf13c5f844
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathlib.Analysis.Complex.Circle
import Mathlib.MeasureTheory.Group.Integration
import Mathlib.MeasureTheory.Measure.Haar.OfBasis

/-!
# The Fourier transform
We set up the Fourier transform for complex-valued functions on finite-dimensional spaces.
## Design choices
In namespace `VectorFourier`, we define the Fourier integral in the following context:
* `π•œ` is a commutative ring.
* `V` and `W` are `π•œ`-modules.
* `e` is a unitary additive character of `π•œ`, i.e. a homomorphism `(Multiplicative π•œ) β†’* circle`.
* `ΞΌ` is a measure on `V`.
* `L` is a `π•œ`-bilinear form `V Γ— W β†’ π•œ`.
* `E` is a complete normed `β„‚`-vector space.
With these definitions, we define `fourierIntegral` to be the map from functions `V β†’ E` to
functions `W β†’ E` that sends `f` to
`Ξ» w, ∫ v in V, e [-L v w] β€’ f v βˆ‚ΞΌ`,
where `e [x]` is notational sugar for `(e (Multiplicative.ofAdd x) : β„‚)` (available in locale
`fourier_transform`). This includes the cases `W` is the dual of `V` and `L` is the canonical
pairing, or `W = V` and `L` is a bilinear form (e.g. an inner product).
In namespace `fourier`, we consider the more familiar special case when `V = W = π•œ` and `L` is the
multiplication map (but still allowing `π•œ` to be an arbitrary ring equipped with a measure).
The most familiar case of all is when `V = W = π•œ = ℝ`, `L` is multiplication, `ΞΌ` is volume, and
`e` is `Real.fourierChar`, i.e. the character `Ξ» x, exp ((2 * Ο€ * x) * I)`. The Fourier integral
in this case is defined as `Real.fourierIntegral`.
## Main results
At present the only nontrivial lemma we prove is `fourierIntegral_continuous`, stating that the
Fourier transform of an integrable function is continuous (under mild assumptions).
-/


noncomputable section

local notation "π•Š" => circle

open MeasureTheory Filter

open scoped Topology

-- To avoid messing around with multiplicative vs. additive characters, we make a notation.
scoped[FourierTransform] notation e "[" x "]" => (e (Multiplicative.ofAdd x) : β„‚)

open FourierTransform

/-! ## Fourier theory for functions on general vector spaces -/


namespace VectorFourier

variable {π•œ : Type _} [CommRing π•œ] {V : Type _} [AddCommGroup V] [Module π•œ V] [MeasurableSpace V]
{W : Type _} [AddCommGroup W] [Module π•œ W] {E : Type _} [NormedAddCommGroup E] [NormedSpace β„‚ E]

section Defs

variable [CompleteSpace E]

/-- The Fourier transform integral for `f : V β†’ E`, with respect to a bilinear form `L : V Γ— W β†’ π•œ`
and an additive character `e`. -/
def fourierIntegral (e : Multiplicative π•œ β†’* π•Š) (ΞΌ : Measure V) (L : V β†’β‚—[π•œ] W β†’β‚—[π•œ] π•œ) (f : V β†’ E)
(w : W) : E :=
∫ v, e[-L v w] β€’ f v βˆ‚ΞΌ
#align vector_fourier.fourier_integral VectorFourier.fourierIntegral

theorem fourierIntegral_smul_const (e : Multiplicative π•œ β†’* π•Š) (ΞΌ : Measure V)
(L : V β†’β‚—[π•œ] W β†’β‚—[π•œ] π•œ) (f : V β†’ E) (r : β„‚) :
fourierIntegral e ΞΌ L (r β€’ f) = r β€’ fourierIntegral e ΞΌ L f := by
ext1 w
-- Porting note: was
-- simp only [Pi.smul_apply, fourierIntegral, smul_comm _ r, integral_smul]
simp only [Pi.smul_apply, fourierIntegral, ← integral_smul]
congr; funext
rw [smul_comm]
#align vector_fourier.fourier_integral_smul_const VectorFourier.fourierIntegral_smul_const

/-- The uniform norm of the Fourier integral of `f` is bounded by the `LΒΉ` norm of `f`. -/
theorem norm_fourierIntegral_le_integral_norm (e : Multiplicative π•œ β†’* π•Š) (ΞΌ : Measure V)
(L : V β†’β‚—[π•œ] W β†’β‚—[π•œ] π•œ) (f : V β†’ E) (w : W) :
β€–fourierIntegral e ΞΌ L f wβ€– ≀ ∫ v : V, β€–f vβ€– βˆ‚ΞΌ := by
refine' (norm_integral_le_integral_norm _).trans (le_of_eq _)
simp_rw [norm_smul, Complex.norm_eq_abs, abs_coe_circle, one_mul]
#align vector_fourier.norm_fourier_integral_le_integral_norm VectorFourier.norm_fourierIntegral_le_integral_norm

/-- The Fourier integral converts right-translation into scalar multiplication by a phase factor.-/
theorem fourierIntegral_comp_add_right [MeasurableAdd V] (e : Multiplicative π•œ β†’* π•Š) (ΞΌ : Measure V)
[ΞΌ.IsAddRightInvariant] (L : V β†’β‚—[π•œ] W β†’β‚—[π•œ] π•œ) (f : V β†’ E) (vβ‚€ : V) :
fourierIntegral e ΞΌ L (f ∘ fun v => v + vβ‚€) =
fun w => e[L vβ‚€ w] β€’ fourierIntegral e ΞΌ L f w := by
ext1 w
dsimp only [fourierIntegral, Function.comp_apply]
conv in L _ => rw [← add_sub_cancel v vβ‚€]
rw [integral_add_right_eq_self fun v : V => e[-L (v - vβ‚€) w] β€’ f v]
dsimp only
rw [← integral_smul]
congr 1 with v
rw [← smul_assoc, smul_eq_mul, ← Submonoid.coe_mul, ← e.map_mul, ← ofAdd_add, ←
LinearMap.neg_apply, ← sub_eq_add_neg, ← LinearMap.sub_apply, LinearMap.map_sub, neg_sub]
#align vector_fourier.fourier_integral_comp_add_right VectorFourier.fourierIntegral_comp_add_right

end Defs

section Continuous

/- In this section we assume π•œ, V, W have topologies, and L, e are continuous (but f needn't be).
This is used to ensure that `e [-L v w]` is (ae strongly) measurable. We could get away with
imposing only a measurable-space structure on π•œ (it doesn't have to be the Borel sigma-algebra of
a topology); but it seems hard to imagine cases where this extra generality would be useful, and
allowing it would complicate matters in the most important use cases.
-/
variable [TopologicalSpace π•œ] [TopologicalRing π•œ] [TopologicalSpace V] [BorelSpace V]
[TopologicalSpace W] {e : Multiplicative π•œ β†’* π•Š} {ΞΌ : Measure V} {L : V β†’β‚—[π•œ] W β†’β‚—[π•œ] π•œ}

/-- For any `w`, the Fourier integral is convergent iff `f` is integrable. -/
theorem fourier_integral_convergent_iff (he : Continuous e)
(hL : Continuous fun p : V Γ— W => L p.1 p.2) {f : V β†’ E} (w : W) :
Integrable f ΞΌ ↔ Integrable (fun v : V => e[-L v w] β€’ f v) ΞΌ := by
-- first prove one-way implication
have aux :
βˆ€ {g : V β†’ E} (_ : Integrable g ΞΌ) (x : W), Integrable (fun v : V => e[-L v x] β€’ g v) ΞΌ := by
intro g hg x
have c : Continuous fun v => e[-L v x] := by
refine' (continuous_induced_rng.mp he).comp (continuous_ofAdd.comp (Continuous.neg _))
exact hL.comp (continuous_prod_mk.mpr ⟨continuous_id, continuous_const⟩)
rw [← integrable_norm_iff (c.aestronglyMeasurable.smul hg.1)]
convert hg.norm using 2
rw [norm_smul, Complex.norm_eq_abs, abs_coe_circle, one_mul]
-- then use it for both directions
refine' ⟨fun hf => aux hf w, fun hf => _⟩
convert aux hf (-w)
rw [← smul_assoc, smul_eq_mul, ← Submonoid.coe_mul, ← MonoidHom.map_mul, ← ofAdd_add,
LinearMap.map_neg, neg_neg, ← sub_eq_add_neg, sub_self, ofAdd_zero, MonoidHom.map_one,
Submonoid.coe_one, one_smul]
#align vector_fourier.fourier_integral_convergent_iff VectorFourier.fourier_integral_convergent_iff

variable [CompleteSpace E]

theorem fourierIntegral_add (he : Continuous e) (hL : Continuous fun p : V Γ— W => L p.1 p.2)
{f g : V β†’ E} (hf : Integrable f ΞΌ) (hg : Integrable g ΞΌ) :
fourierIntegral e ΞΌ L f + fourierIntegral e ΞΌ L g = fourierIntegral e ΞΌ L (f + g) := by
ext1 w
dsimp only [Pi.add_apply, fourierIntegral]
simp_rw [smul_add]
rw [integral_add]
Β· exact (fourier_integral_convergent_iff he hL w).mp hf
Β· exact (fourier_integral_convergent_iff he hL w).mp hg
#align vector_fourier.fourier_integral_add VectorFourier.fourierIntegral_add

/-- The Fourier integral of an `L^1` function is a continuous function. -/
theorem fourierIntegral_continuous [TopologicalSpace.FirstCountableTopology W] (he : Continuous e)
(hL : Continuous fun p : V Γ— W => L p.1 p.2) {f : V β†’ E} (hf : Integrable f ΞΌ) :
Continuous (fourierIntegral e ΞΌ L f) := by
apply continuous_of_dominated
Β· exact fun w => ((fourier_integral_convergent_iff he hL w).mp hf).1
Β· refine' fun w => ae_of_all _ fun v => _
Β· exact fun v => β€–f vβ€–
Β· rw [norm_smul, Complex.norm_eq_abs, abs_coe_circle, one_mul]
Β· exact hf.norm
Β· rw [continuous_induced_rng] at he
refine' ae_of_all _ fun v => (he.comp (continuous_ofAdd.comp _)).smul continuous_const
refine' (hL.comp (continuous_prod_mk.mpr ⟨continuous_const, continuous_id⟩)).neg
#align vector_fourier.fourier_integral_continuous VectorFourier.fourierIntegral_continuous

end Continuous

end VectorFourier

/-! ## Fourier theory for functions on `π•œ` -/


namespace Fourier

variable {π•œ : Type _} [CommRing π•œ] [MeasurableSpace π•œ] {E : Type _} [NormedAddCommGroup E]
[NormedSpace β„‚ E]

section Defs

variable [CompleteSpace E]

/-- The Fourier transform integral for `f : π•œ β†’ E`, with respect to the measure `ΞΌ` and additive
character `e`. -/
def fourierIntegral (e : Multiplicative π•œ β†’* π•Š) (ΞΌ : Measure π•œ) (f : π•œ β†’ E) (w : π•œ) : E :=
VectorFourier.fourierIntegral e ΞΌ (LinearMap.mul π•œ π•œ) f w
#align fourier.fourier_integral Fourier.fourierIntegral

theorem fourierIntegral_def (e : Multiplicative π•œ β†’* π•Š) (ΞΌ : Measure π•œ) (f : π•œ β†’ E) (w : π•œ) :
fourierIntegral e ΞΌ f w = ∫ v : π•œ, e[-(v * w)] β€’ f v βˆ‚ΞΌ :=
rfl
#align fourier.fourier_integral_def Fourier.fourierIntegral_def

theorem fourierIntegral_smul_const (e : Multiplicative π•œ β†’* π•Š) (ΞΌ : Measure π•œ) (f : π•œ β†’ E) (r : β„‚) :
fourierIntegral e ΞΌ (r β€’ f) = r β€’ fourierIntegral e ΞΌ f :=
VectorFourier.fourierIntegral_smul_const _ _ _ _ _
#align fourier.fourier_integral_smul_const Fourier.fourierIntegral_smul_const

/-- The uniform norm of the Fourier transform of `f` is bounded by the `LΒΉ` norm of `f`. -/
theorem norm_fourierIntegral_le_integral_norm (e : Multiplicative π•œ β†’* π•Š) (ΞΌ : Measure π•œ)
(f : π•œ β†’ E) (w : π•œ) : β€–fourierIntegral e ΞΌ f wβ€– ≀ ∫ x : π•œ, β€–f xβ€– βˆ‚ΞΌ :=
VectorFourier.norm_fourierIntegral_le_integral_norm _ _ _ _ _
#align fourier.norm_fourier_integral_le_integral_norm Fourier.norm_fourierIntegral_le_integral_norm

/-- The Fourier transform converts right-translation into scalar multiplication by a phase factor.-/
theorem fourierIntegral_comp_add_right [MeasurableAdd π•œ] (e : Multiplicative π•œ β†’* π•Š) (ΞΌ : Measure π•œ)
[ΞΌ.IsAddRightInvariant] (f : π•œ β†’ E) (vβ‚€ : π•œ) :
fourierIntegral e ΞΌ (f ∘ fun v => v + vβ‚€) = fun w => e[vβ‚€ * w] β€’ fourierIntegral e ΞΌ f w :=
VectorFourier.fourierIntegral_comp_add_right _ _ _ _ _
#align fourier.fourier_integral_comp_add_right Fourier.fourierIntegral_comp_add_right

end Defs

end Fourier

open scoped Real

namespace Real

/-- The standard additive character of `ℝ`, given by `Ξ» x, exp (2 * Ο€ * x * I)`. -/
def fourierChar : Multiplicative ℝ β†’* π•Š where
toFun z := expMapCircle (2 * Ο€ * Multiplicative.toAdd z)
map_one' := by simp only; rw [toAdd_one, MulZeroClass.mul_zero, expMapCircle_zero]
map_mul' x y := by simp only; rw [toAdd_mul, mul_add, expMapCircle_add]
#align real.fourier_char Real.fourierChar

theorem fourierChar_apply (x : ℝ) : Real.fourierChar[x] = Complex.exp (↑(2 * Ο€ * x) * Complex.I) :=
by rfl
#align real.fourier_char_apply Real.fourierChar_apply

@[continuity]
theorem continuous_fourierChar : Continuous Real.fourierChar :=
(map_continuous expMapCircle).comp (continuous_const.mul continuous_toAdd)
#align real.continuous_fourier_char Real.continuous_fourierChar

variable {E : Type _} [NormedAddCommGroup E] [CompleteSpace E] [NormedSpace β„‚ E]

theorem vector_fourierIntegral_eq_integral_exp_smul {V : Type _} [AddCommGroup V] [Module ℝ V]
[MeasurableSpace V] {W : Type _} [AddCommGroup W] [Module ℝ W] (L : V β†’β‚—[ℝ] W β†’β‚—[ℝ] ℝ)
(ΞΌ : Measure V) (f : V β†’ E) (w : W) :
VectorFourier.fourierIntegral fourierChar ΞΌ L f w =
∫ v : V, Complex.exp (↑(-2 * Ο€ * L v w) * Complex.I) β€’ f v βˆ‚ΞΌ :=
by simp_rw [VectorFourier.fourierIntegral, Real.fourierChar_apply, mul_neg, neg_mul]
#align real.vector_fourier_integral_eq_integral_exp_smul Real.vector_fourierIntegral_eq_integral_exp_smul

/-- The Fourier integral for `f : ℝ β†’ E`, with respect to the standard additive character and
measure on `ℝ`. -/
def fourierIntegral (f : ℝ β†’ E) (w : ℝ) :=
Fourier.fourierIntegral fourierChar volume f w
#align real.fourier_integral Real.fourierIntegral

theorem fourierIntegral_def (f : ℝ β†’ E) (w : ℝ) :
fourierIntegral f w = ∫ v : ℝ, fourierChar[-(v * w)] β€’ f v :=
rfl
#align real.fourier_integral_def Real.fourierIntegral_def

scoped[FourierTransform] notation "𝓕" => Real.fourierIntegral

theorem fourierIntegral_eq_integral_exp_smul {E : Type _} [NormedAddCommGroup E] [CompleteSpace E]
[NormedSpace β„‚ E] (f : ℝ β†’ E) (w : ℝ) :
𝓕 f w = ∫ v : ℝ, Complex.exp (↑(-2 * Ο€ * v * w) * Complex.I) β€’ f v := by
simp_rw [fourierIntegral_def, Real.fourierChar_apply, mul_neg, neg_mul, mul_assoc]
#align real.fourier_integral_eq_integral_exp_smul Real.fourierIntegral_eq_integral_exp_smul

end Real

0 comments on commit 708e990

Please sign in to comment.