Theory Abstract_Descent
theory Abstract_Descent
imports "HOL-Analysis.Analysis"
begin
section ‹Abstract descent and telescoping lemmas›
text ‹
This theory contains abstract sequence and finite-sum lemmas used in descent
analyses. These results are independent of gradients, projections, and
particular optimization algorithms.
›
subsection ‹Finite-sum telescoping›
text ‹
If each local progress term is bounded by the decrease of a potential, then
the sum of all progress terms is bounded by the total decrease of the
potential.
›
lemma sum_progress_le_initial_gap:
fixes a c :: "nat ⇒ real"
assumes step: "⋀n. n < N ⟹ c n ≤ a n - a (Suc n)"
shows "sum c {..<N} ≤ a 0 - a N"
using step
proof (induction N)
case 0
show ?case by simp
next
case (Suc N)
have IH: "sum c {..<N} ≤ a 0 - a N"
proof (rule Suc.IH)
fix n
assume n_lt: "n < N"
then show "c n ≤ a n - a (Suc n)"
using Suc.prems by simp
qed
have last: "c N ≤ a N - a (Suc N)"
using Suc.prems by simp
have "sum c {..<Suc N} = sum c {..<N} + c N"
by simp
also have "... ≤ (a 0 - a N) + (a N - a (Suc N))"
using IH last by linarith
also have "... = a 0 - a (Suc N)"
by simp
finally show ?case .
qed
text ‹
A version in which the terminal value of the potential is replaced by a lower
bound.
›
lemma sum_progress_le_initial_minus_lower_bound:
fixes a c :: "nat ⇒ real"
assumes step: "⋀n. n < N ⟹ c n ≤ a n - a (Suc n)"
assumes lower: "B ≤ a N"
shows "sum c {..<N} ≤ a 0 - B"
proof -
have "sum c {..<N} ≤ a 0 - a N"
using step by (rule sum_progress_le_initial_gap)
also have "... ≤ a 0 - B"
using lower by linarith
finally show ?thesis .
qed
subsection ‹Average bounds›
text ‹
If a finite sum is bounded above, then at least one term is bounded by the
corresponding average.
›
lemma exists_le_average_of_sum_bound:
fixes a :: "nat ⇒ real"
assumes N_pos: "N > 0"
assumes nonneg: "⋀n. n < N ⟹ 0 ≤ a n"
assumes sum_bound: "sum a {..<N} ≤ B"
shows "∃n<N. a n ≤ B / real N"
proof (rule ccontr)
assume not_exists: "¬ (∃n<N. a n ≤ B / real N)"
have gt: "⋀n. n < N ⟹ B / real N < a n"
proof -
fix n
assume n_lt: "n < N"
have "¬ a n ≤ B / real N"
using not_exists n_lt by auto
then show "B / real N < a n"
by simp
qed
have const_sum: "sum (λn. B / real N) {..<N} = B"
using N_pos by simp
have strict_sum: "sum (λn. B / real N) {..<N} < sum a {..<N}"
using N_pos gt by (intro sum_strict_mono) auto
have "B < sum a {..<N}"
using const_sum strict_sum by simp
then show False
using sum_bound by linarith
qed
lemma exists_le_average_of_nonnegative_sum:
fixes a :: "nat ⇒ real"
assumes N_pos: "N > 0"
assumes nonneg: "⋀n. n < N ⟹ 0 ≤ a n"
shows "∃n<N. a n ≤ sum a {..<N} / real N"
proof -
have sum_bound: "sum a {..<N} ≤ sum a {..<N}"
by simp
show ?thesis
using exists_le_average_of_sum_bound[OF N_pos nonneg sum_bound] .
qed
subsection ‹Linear recurrences›
text ‹
A one-step linear recurrence can be iterated to obtain a geometric bound.
›
lemma sequence_linear_rate_from_step:
fixes a :: "nat ⇒ real"
assumes q_nonneg: "0 ≤ q"
assumes step: "⋀n. a (Suc n) ≤ q * a n"
shows "a n ≤ q ^ n * a 0"
proof (induction n)
case 0
show ?case by simp
next
case (Suc n)
have "a (Suc n) ≤ q * a n"
by (rule step)
also have "... ≤ q * (q ^ n * a 0)"
proof (rule mult_left_mono)
show "a n ≤ q ^ n * a 0"
using Suc.IH .
show "0 ≤ q"
using q_nonneg .
qed
also have "... = q ^ Suc n * a 0"
by (simp add: algebra_simps)
finally show ?case .
qed
end