forked from leanprover-community/mathlib4
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAverage.lean
More file actions
117 lines (88 loc) · 4.87 KB
/
Average.lean
File metadata and controls
117 lines (88 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/-
Copyright (c) 2023 Yury Kudryashov. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yury Kudryashov, Lua Viana Reis, Oliver Butterley
-/
module
public import Mathlib.Dynamics.BirkhoffSum.Basic
public import Mathlib.Algebra.Module.Basic
/-!
# Birkhoff average
In this file we define `birkhoffAverage f g n x` to be
$$
\frac{1}{n}\sum_{k=0}^{n-1}g(f^{[k]}(x)),
$$
where `f : α → α` is a self-map on some type `α`,
`g : α → M` is a function from `α` to a module over a division semiring `R`,
and `R` is used to formalize division by `n` as `(n : R)⁻¹ • _`.
While we need an auxiliary division semiring `R` to define `birkhoffAverage`,
the definition does not depend on the choice of `R`,
see `birkhoffAverage_congr_ring`.
-/
@[expose] public section
open Finset
section birkhoffAverage
variable (R : Type*) {α M : Type*} [DivisionSemiring R] [AddCommMonoid M] [Module R M]
/-- The average value of `g` on the first `n` points of the orbit of `x` under `f`,
i.e. the Birkhoff sum `∑ k ∈ Finset.range n, g (f^[k] x)` divided by `n`.
This average appears in many ergodic theorems
which say that `(birkhoffAverage R f g · x)`
converges to the "space average" `⨍ x, g x ∂μ` as `n → ∞`.
We use an auxiliary `[DivisionSemiring R]` to define division by `n`.
However, the definition does not depend on the choice of `R`,
see `birkhoffAverage_congr_ring`. -/
def birkhoffAverage (f : α → α) (g : α → M) (n : ℕ) (x : α) : M := (n : R)⁻¹ • birkhoffSum f g n x
theorem birkhoffAverage_zero (f : α → α) (g : α → M) (x : α) :
birkhoffAverage R f g 0 x = 0 := by simp [birkhoffAverage]
@[simp] theorem birkhoffAverage_zero' (f : α → α) (g : α → M) : birkhoffAverage R f g 0 = 0 :=
funext <| birkhoffAverage_zero _ _ _
theorem birkhoffAverage_one (f : α → α) (g : α → M) (x : α) :
birkhoffAverage R f g 1 x = g x := by simp [birkhoffAverage]
@[simp]
theorem birkhoffAverage_one' (f : α → α) (g : α → M) : birkhoffAverage R f g 1 = g :=
funext <| birkhoffAverage_one R f g
theorem map_birkhoffAverage (S : Type*) {F N : Type*}
[DivisionSemiring S] [AddCommMonoid N] [Module S N] [FunLike F M N]
[AddMonoidHomClass F M N] (g' : F) (f : α → α) (g : α → M) (n : ℕ) (x : α) :
g' (birkhoffAverage R f g n x) = birkhoffAverage S f (g' ∘ g) n x := by
simp only [birkhoffAverage, map_inv_natCast_smul g' R S, map_birkhoffSum]
theorem birkhoffAverage_congr_ring (S : Type*) [DivisionSemiring S] [Module S M]
(f : α → α) (g : α → M) (n : ℕ) (x : α) :
birkhoffAverage R f g n x = birkhoffAverage S f g n x :=
map_birkhoffAverage R S (AddMonoidHom.id M) f g n x
theorem birkhoffAverage_congr_ring' (S : Type*) [DivisionSemiring S] [Module S M] :
birkhoffAverage (α := α) (M := M) R = birkhoffAverage S := by
ext; apply birkhoffAverage_congr_ring
theorem Function.IsFixedPt.birkhoffAverage_eq {f : α → α} {x : α} (h : IsFixedPt f x)
(g : α → M) {n : ℕ} (hn : (n : R) ≠ 0) : birkhoffAverage R f g n x = g x := by
rw [birkhoffAverage, h.birkhoffSum_eq, ← Nat.cast_smul_eq_nsmul R, inv_smul_smul₀ hn]
lemma birkhoffAverage_add {f : α → α} {g g' : α → M} :
birkhoffAverage R f (g + g') = birkhoffAverage R f g + birkhoffAverage R f g' := by
funext _ x
simp [birkhoffAverage, birkhoffSum, sum_add_distrib, smul_add]
/-- If a function `g` is invariant under a function `f` (i.e., `g ∘ f = g`), then the Birkhoff
average of `g` over `f` for `n` iterations is equal to `g`. Requires that `0 < n`. -/
theorem birkhoffAverage_of_comp_eq {f : α → α} {g : α → M} (h : g ∘ f = g)
{n : ℕ} (hn : (n : R) ≠ 0) : birkhoffAverage R f g n = g := by
funext x
suffices (n : R)⁻¹ • n • g x = g x by simpa [birkhoffAverage, birkhoffSum_of_comp_eq h]
rw [← Nat.cast_smul_eq_nsmul (R := R), ← mul_smul, inv_mul_cancel₀ hn, one_smul]
end birkhoffAverage
section AddCommGroup
variable {R : Type*} {α M : Type*} [DivisionSemiring R] [AddCommGroup M] [Module R M]
lemma birkhoffAverage_neg {f : α → α} {g : α → M} :
birkhoffAverage R f (-g) = -birkhoffAverage R f g := by
funext _ x
simp [birkhoffAverage, birkhoffSum]
lemma birkhoffAverage_sub {f : α → α} {g g' : α → M} :
birkhoffAverage R f (g - g') = birkhoffAverage R f g - birkhoffAverage R f g' := by
funext _ x
simp [birkhoffAverage, birkhoffSum, smul_sub]
/-- Birkhoff average is "almost invariant" under `f`:
the difference between `birkhoffAverage R f g n (f x)` and `birkhoffAverage R f g n x`
is equal to `(n : R)⁻¹ • (g (f^[n] x) - g x)`. -/
theorem birkhoffAverage_apply_sub_birkhoffAverage (f : α → α) (g : α → M) (n : ℕ) (x : α) :
birkhoffAverage R f g n (f x) - birkhoffAverage R f g n x =
(n : R)⁻¹ • (g (f^[n] x) - g x) := by
simp only [birkhoffAverage, birkhoffSum_apply_sub_birkhoffSum, ← smul_sub]
end AddCommGroup