Repository navigation
Expand file tree
/
Copy pathConvexFunction.lean
More file actions
494 lines (451 loc) · 22.3 KB
/
Copy pathConvexFunction.lean
File metadata and controls
494 lines (451 loc) · 22.3 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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
/-
Copyright (c) 2023 Chenyi Li, Ziyu Wang, Zaiwen Wen. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chenyi Li, Ziyu Wang, Penghao Yu, Zhipeng Cao, Shengyang Xu, Zaiwen Wen
-/
import Mathlib.Analysis.Convex.Function
import Mathlib.Analysis.Calculus.MeanValue
import Optlib.Differential.Calculation
import Optlib.Differential.Lemmas
set_option linter.unusedVariables false
/-!
# ConvexFunction
## Main results
This file mainly concentrates on the differentiable convex function and its properties.
The main theorem is given as:
Let f be a smooth function defined on a convex set s. Then the following statement is equivalent
(a) f is convex on s.
(b) (first order condition) f(y) ≥ f(x) + ∇ f(x)^T (y-x) ∀ x, y ∈ s.
(c) (monotonic of gradient) (∇ f(x) - ∇ f(y))^T (x-y) ≥ 0 ∀ x, y ∈ s.
Besides we also proof the corresponding properties for strict convex function.
-/
open InnerProductSpace
noncomputable section
section FirstOrderCondition
variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
variable {f : E → ℝ} {f' : E → (E →L[ℝ] ℝ)} {x y x': E} {s : Set E}
private lemma point_proportion {a b: ℝ} (_ : 0 ≤ a) (_ : 0 ≤ b) (sumab: a + b = 1)
(hpoint : x' = a • x + b • y) : x - x' = b • (x - y) := by
calc
x - x' = x - (a • x + b • y):= by rw [hpoint]
_ = x - a • x - b • y:= sub_add_eq_sub_sub x (a • x) (b • y)
_ = (1 : ℝ) • x - a • x - b • y:= by rw[one_smul]
_ = (1 - a) • x - b • y := by rw[sub_smul 1 a]
_ = b • x - b • y := by rw [← sumab]; ring_nf
_ = b • (x - y) := Eq.symm (smul_sub b x y)
/-
The first order condition for a convex function
-/
theorem Convex_first_order_condition {s : Set E}
(h : HasFDerivAt f (f' x) x) (hf : ConvexOn ℝ s f) (xs : x ∈ s) :
∀ y ∈ s, f x + f' x (y - x) ≤ f y := by
have h₁ : ∀ ε > (0 : ℝ), ∃ δ > (0 : ℝ), ∀ (x' : E), ‖x - x'‖ ≤ δ
→ ‖f x' - f x - (f' x) (x' - x)‖ ≤ ε * ‖x - x'‖:= by
apply HasFDeriv_Convergence h
intro y ys
by_cases h₂ : y = x
rw [h₂, sub_self, ContinuousLinearMap.map_zero (f' x), add_zero]
have h₃ : 0 < ‖x - y‖ := by
rw [norm_sub_pos_iff, Ne]
exact Iff.mpr ne_comm h₂
by_contra H
push_neg at H
rw [ConvexOn] at hf
rcases hf with ⟨ _, cxf⟩
specialize cxf xs ys
let ε := f x + (f' x) (y - x) - f y
have epos : 0 < ε := Iff.mpr sub_pos H
have lnmp: ∀ c : ℝ , f' x (c • (y - x)) = c * (f' x (y - x)) := by
intro c; rw [map_smul, smul_eq_mul]
let e1 := ε / (2 * ‖x - y‖)
have e1pos : 0 < e1 := div_pos (by linarith) (by linarith)
specialize h₁ e1 e1pos
rcases h₁ with ⟨δ , dpos, converge⟩
let b1 := δ / ‖x - y‖
have b1pos: 0 < b1 := div_pos dpos h₃
let b := min b1 (1 : ℝ)
let a := 1 - b
have sum_a_b : a + b = 1:= sub_add_cancel 1 b
have b_nonneg: 0 ≤ b := le_min (LT.lt.le b1pos) zero_le_one
have a_nonneg : 0 ≤ a := by
have h1: 0 + b ≤ a + b := by
rw [zero_add, sum_a_b]
exact min_le_right b1 1
apply (add_le_add_iff_right b).mp h1
specialize cxf a_nonneg b_nonneg sum_a_b
let x' := a • x + b • y
have x'rfl : x' = a • x + b • y := rfl
have h1 : ‖x - x'‖ = ‖b • (x - y)‖ := by
congr; apply point_proportion a_nonneg b_nonneg sum_a_b x'rfl
have h2 : ‖b • (x - y)‖ = b * ‖x - y‖ := by
rw [norm_smul, Real.norm_of_nonneg b_nonneg]
have x1nbhd: ‖x - x'‖ ≤ δ := by
rw[h1, h2]
have h3: b * ‖x - y‖ ≤ b1 * ‖x - y‖:= by
rw [mul_le_mul_right]
apply min_le_left
exact h₃
have h4: b1 * ‖x - y‖ = δ := by
simp [b1]
rw [div_mul_cancel₀]
apply ne_of_gt h₃
rw[← h4]
apply h3
specialize converge x' x1nbhd
have H1: f x + (f' x) (x' - x) - e1 * ‖x - x'‖ ≤ f x':= by
have l1: f x + (f' x) (x' - x) - f x' ≤ ‖f x' - f x - (f' x) (x' - x)‖:= by
rw [Real.norm_eq_abs]
have : f x + (f' x) (x' - x) - f x' = -(f x' - f x - (f' x) (x' - x)) := by
ring
rw [this]
apply neg_le_abs
have _: f x + (f' x) (x' - x) - f x'≤ e1 * ‖x - x'‖ := by
apply le_trans l1 converge
linarith
have H3: f y = f x + (f' x) (y - x) - ε := by simp only [ε, map_sub, sub_sub_cancel]
have l4: e1 * ‖x - x'‖ = ε * b / 2 := by
rw[h1, h2]
calc
e1 * (b * ‖x - y‖) = ε / (2 * ‖x - y‖) * (b * ‖x - y‖):= by rfl
_ = ((ε / 2) / ‖x - y‖) *(b * ‖x - y‖):= by ring
_ = ((ε / 2) / ‖x - y‖) * ‖x - y‖ * b := by rw[mul_comm b, mul_assoc]
_ = (ε / 2) * b := by rw [div_mul_cancel₀]; apply ne_of_gt h₃
_ = ε * b / 2 := by ring
rw [l4] at H1; rw [smul_eq_mul, smul_eq_mul] at cxf
have H4: a * f x + b * f y = f x + b * (f' x) (y - x) - b * ε := by rw [H3]; ring
have l5: b * (f' x) (y - x) = (f' x) (x' - x) := by
rw [← neg_sub x x',point_proportion a_nonneg b_nonneg sum_a_b x'rfl, smul_sub]
rw [neg_sub, ← smul_sub, lnmp b]
rw [l5] at H4; rw [H4] at cxf
have _ : f x + (f' x) (x' - x) - ε * b / 2 ≤ f x + (f' x) (x' - x) - b * ε := le_trans H1 cxf
have blt: 0 < b := by positivity
have H11: ε ≤ 0 := nonpos_of_mul_nonpos_left (by linarith) blt
linarith
theorem Convex_first_order_condition_inverse {f : E → ℝ} {f' : E → (E →L[ℝ] ℝ)}
{s : Set E} (h : ∀ x ∈ s, HasFDerivAt f (f' x) x) (h₁: Convex ℝ s)
(h₂ : ∀ (x : E), x ∈ s → ∀ (y : E), y ∈ s → f x + f' x (y - x) ≤ f y) : ConvexOn ℝ s f := by
rw [ConvexOn]; constructor
apply h₁; intro x xs y ys a b anonneg bnonneg sumab
let x' := a • x + b • y
have x'rfl : x' = a • x + b • y := rfl
have x'rfl_comm : x' = b • y + a • x := by rw [add_comm]
have sumba : b + a = 1 := by rw [add_comm]; exact sumab
specialize h x'
have x1s: x' ∈ s:= by
rw [convex_iff_segment_subset] at h₁
specialize h₁ xs ys
rw [segment_subset_iff] at h₁
exact h₁ a b anonneg bnonneg sumab
have H1: f x' + f' x' (x - x') ≤ f x := h₂ x' x1s x xs
have H2: f x' + f' x' (y - x') ≤ f y := h₂ x' x1s y ys
have lnmp: ∀ c: ℝ , f' x' (c • (y - x)) = c * (f' x' (y - x)) := by
intro c; rw [map_smul]; rfl
have H: a • (f x' + (f' x') (x - x')) + b • (f x' + (f' x') (y - x')) = f x' := by
have l1: a • (f x' + (f' x') (x - x')) + b • (f x' + (f' x') (y - x'))
= (a + b) • f x' + a • (f' x') (x - x')+ b • (f' x') (y - x'):= by
rw [smul_add, smul_add, ← add_assoc, add_assoc (a • f x'),
add_comm (a • (f' x') (x - x')), ← add_assoc, add_smul]
have l2: b • (f' x') (y - x') = (a * b) * (f' x') (y - x):= by
rw [point_proportion bnonneg anonneg sumba x'rfl_comm, lnmp a]
calc
_ = b * (a * (f' x') (y - x)):= by rfl
_ = b * a * (f' x') (y - x):= by rw [mul_assoc]
_ = (a * b) * (f' x') (y - x):= by simp[mul_comm]
have l3_1: x - x' = (- b) • (y - x):= by
rw [point_proportion anonneg bnonneg sumab x'rfl]
rw [smul_sub, neg_smul, smul_sub]; simp
have l3: a • (f' x') (x - x') = - (a * b) * (f' x') (y - x):= by
rw [l3_1, lnmp (- b)]
simp [mul_neg, mul_assoc, map_sub, neg_mul]
rw [l1, sumab, one_smul, l2, l3]
simp only [map_sub, neg_mul, neg_add_cancel_right]
have h1: a • (f x' + (f' x') (x - x')) ≤ a • f x := mul_le_mul_of_nonneg_left H1 anonneg
have h2: b • (f x' + (f' x') (y - x')) ≤ b • f y := mul_le_mul_of_nonneg_left H2 bnonneg
have H3: a • (f x' + (f' x') (x - x')) + b • (f x' + (f' x') (y - x')) ≤ a • f x + b • f y
:= add_le_add h1 h2
rw [H] at H3
apply H3
theorem Convex_first_order_condition_iff (h₁ : Convex ℝ s) (h : ∀ x ∈ s, HasFDerivAt f (f' x) x) :
ConvexOn ℝ s f ↔ ∀ x ∈ s, ∀ y ∈ s, f x + f' x (y - x) ≤ f y :=
⟨fun h₂ x xs ↦ Convex_first_order_condition (h x xs) h₂ xs,
Convex_first_order_condition_inverse h h₁⟩
theorem Convex_monotone_gradient (hfun: ConvexOn ℝ s f) (h : ∀ x ∈ s , HasFDerivAt f (f' x) x) :
∀ x ∈ s, ∀ y ∈ s, (f' x - f' y) (x - y) ≥ 0 := by
intro x hx y hy
have h₁ : f x + f' x (y - x) ≤ f y := Convex_first_order_condition (h x hx) hfun hx y hy
have h₂ : f y + f' y (x - y) ≤ f x := Convex_first_order_condition (h y hy) hfun hy x hx
have h₃ : f x + f' x (y - x) + (f y + f' y (x - y)) ≤ f y + f x := add_le_add h₁ h₂
rw [add_assoc, ← le_sub_iff_add_le', ← add_sub, sub_self, add_zero] at h₃
rw [add_comm, add_assoc, ← le_sub_iff_add_le', sub_self] at h₃
simp only [map_sub] at h₃
simp only [map_sub, ContinuousLinearMap.coe_sub', Pi.sub_apply]
linarith
end FirstOrderCondition
/-
The corresponding theorems for gradient.
-/
section FirstOrderCondition_Gradient
open Set InnerProductSpace
variable {E : Type*} [NormedAddCommGroup E] [InnerProductSpace ℝ E] [CompleteSpace E]
variable {f : E → ℝ} {f' : E → E} {s : Set E} {x : E}
theorem Convex_first_order_condition' (h : HasGradientAt f (f' x) x) (hf : ConvexOn ℝ s f)
(xs : x ∈ s) : ∀ (y : E), y ∈ s → f x + inner (f' x) (y - x) ≤ f y := by
show ∀ (y : E), y ∈ s → f x + (toDual ℝ E) (f' x) (y - x) ≤ f y
apply Convex_first_order_condition _ hf xs
apply h
theorem Convex_first_order_condition_inverse' (h : ∀ x ∈ s , HasGradientAt f (f' x) x)
(h₁ : Convex ℝ s) (h₂ : ∀ x : E, x ∈ s → ∀ y : E, y ∈ s → f x + inner (f' x) (y - x) ≤ f y) :
ConvexOn ℝ s f := by
apply Convex_first_order_condition_inverse
intro x; specialize h x
rw [hasGradientAt_iff_hasFDerivAt] at h
apply h; apply h₁; apply h₂
theorem Convex_first_order_condition_iff' (h₁ : Convex ℝ s) (h : ∀ x ∈ s, HasGradientAt f (f' x) x) :
ConvexOn ℝ s f ↔ ∀ x ∈ s, ∀ y ∈ s, f x + inner (f' x) (y - x) ≤ f y :=
⟨fun h₂ x xs ↦ Convex_first_order_condition' (h x xs) h₂ xs,
Convex_first_order_condition_inverse' h h₁⟩
theorem Convex_monotone_gradient' (hfun: ConvexOn ℝ s f) (h : ∀ x ∈ s, HasGradientAt f (f' x) x) :
∀ x ∈ s, ∀ y ∈ s, inner (f' x - f' y) (x - y) ≥ (0 : ℝ) := by
let g := fun x ↦ (toDual ℝ E) (f' x)
have h' : ∀ x ∈ s, HasFDerivAt f (g x) x := h
have equiv : ∀ x y : E, inner (f' x - f' y) (x - y) = (g x - g y) (x - y) := by
intro x y
rw [← InnerProductSpace.toDual_apply]
simp only [map_sub, ContinuousLinearMap.coe_sub', Pi.sub_apply, toDual_apply, g]
intro x hx y hy
rw [equiv]
exact Convex_monotone_gradient hfun h' x hx y hy
theorem monotone_gradient_convex' (h₁ : Convex ℝ s) (hf : ∀ x ∈ s, HasGradientAt f (f' x) x)
(mono: ∀ x ∈ s, ∀ y ∈ s, inner (f' x - f' y) (x - y) ≥ (0 : ℝ)) : ConvexOn ℝ s f := by
apply Convex_first_order_condition_inverse' hf h₁
intro x xs y ys
let g := fun t : ℝ ↦ f (x + t • (y - x))
let g' := fun t : ℝ ↦ (inner (f' (x + t • (y - x))) (y - x) : ℝ)
have h1 : ∀ r ∈ Icc 0 1, HasDerivAt g (g' r) r := by
let h := fun r : ℝ ↦ (x + r • (y - x))
have : g = f ∘ h := rfl
rw [this]; intro t ht
have : inner (f' (x + t • (y - x))) (y - x) = toDual ℝ E (f' (x + t • (y - x))) (y - x) := rfl
simp [g']; rw [this]; apply HasFDerivAt.comp_hasDerivAt
· apply hasGradientAt_iff_hasFDerivAt.mp
have : x + t • (y - x) ∈ s := by
apply Convex.add_smul_sub_mem h₁ xs ys; simp; simp at ht; rcases ht with ⟨ht1, ht2⟩
constructor <;> linarith
exact hf (x + t • (y - x)) this
· have ht: HasDerivAt (fun r : ℝ ↦ r) 1 t := hasDerivAt_id' t
have : HasDerivAt (fun r : ℝ ↦ r • (y - x)) ((1 : ℝ) • (y - x)) t := by
exact HasDerivAt.smul_const ht (y - x)
rw [one_smul] at this; exact HasDerivAt.const_add x this
have e1 : f x = g 0 := by simp [g]
have e2 : f y = g 1 := by simp [g]
have e3 : inner (f' x) (y - x) = g' 0 := by simp [g']
rw [e1, e2, e3]
have mono' : ∀ t ∈ Ioo 0 1, g' t ≥ g' 0 := by
intro t ht;
simp [g']; rw [← sub_nonneg, ← inner_sub_left]
rcases ht with ⟨ht1, ht2⟩
have hh: inner (f' (x + t • (y - x)) - f' x) (x + t • (y - x) - x) ≥ (0 : ℝ) := by
apply mono (x + t • (y - x)) _ x xs
have e4 : x + t • (y - x) = (1 - t) • x + t • y := by
rw [smul_sub, add_sub, sub_smul, one_smul, add_sub_right_comm]
rw [e4]
apply convex_iff_forall_pos.mp h₁ xs ys (by linarith) (by linarith) (by norm_num)
rw [add_sub_cancel_left, inner_smul_right] at hh
exact (mul_nonneg_iff_of_pos_left ht1).mp hh
have h2 : ∃ c ∈ Set.Ioo 0 1, g' c = (g 1 - g 0) / (1 - 0) := by
apply exists_hasDerivAt_eq_slope
· linarith
· have : ∀ x ∈ Icc 0 1, HasDerivAt g (g' x) x := by
intro x hx
exact (h1 x hx)
exact HasDerivAt.continuousOn this
· intro x hx
have : x ∈ Icc 0 1 := by simp at hx; simp; constructor <;> linarith
exact h1 x this
rcases h2 with ⟨c, ⟨⟨hc1,hc2⟩,hc3⟩⟩
rw [sub_zero, div_one] at hc3; rw [← le_sub_iff_add_le', ← hc3]
apply mono' c
simp; constructor; linarith; linarith
theorem monotone_gradient_iff_convex' (h₁ : Convex ℝ s) (hf : ∀ x ∈ s, HasGradientAt f (f' x) x):
ConvexOn ℝ s f ↔ ∀ x ∈ s, ∀ y ∈ s, inner (f' x - f' y) (x - y) ≥ (0 : ℝ) :=
⟨fun h ↦ Convex_monotone_gradient' h hf, fun h ↦ monotone_gradient_convex' h₁ hf h⟩
theorem monotone_gradient_convex {f' : E → (E →L[ℝ] ℝ)} (h₁ : Convex ℝ s)
(hf : ∀ x ∈ s, HasFDerivAt f (f' x) x)
(mono : ∀ x ∈ s, ∀ y ∈ s, (f' x - f' y) (x - y) ≥ 0) : ConvexOn ℝ s f := by
let g := fun x ↦ ((toDual ℝ E).symm (f' x))
have h' : ∀ x ∈ s, HasGradientAt f (g x) x := by
intro x' hx'
exact HasFDerivAt.hasGradientAt (hf x' hx')
have equiv : ∀ x y : E, inner (g x - g y) (x - y) = (f' x - f' y) (x - y) := by
intro x y
rw [← InnerProductSpace.toDual_apply]; simp [g]
have mono' : ∀ x ∈ s, ∀ y ∈ s, inner (g x - g y) (x - y) ≥ (0 : ℝ) := by
intro x hx y hy
specialize mono x hx y hy
rw [equiv]; exact mono
exact monotone_gradient_convex' h₁ h' mono'
theorem montone_gradient_iff_convex {f' : E → (E →L[ℝ] ℝ)}
(h₁ : Convex ℝ s) (hf : ∀ x ∈ s, HasFDerivAt f (f' x) x):
ConvexOn ℝ s f ↔ ∀ x ∈ s, ∀ y ∈ s, (f' x - f' y) (x - y) ≥ (0 : ℝ) :=
⟨fun h ↦ Convex_monotone_gradient h hf, fun h ↦ monotone_gradient_convex h₁ hf h⟩
end FirstOrderCondition_Gradient
section strict
/-
The corresponding theorems for a strict convex function, that is the
monotonic gradient of a strict convex function ↔
(monotonic of gradient) (∇ f(x) - ∇ f(y))^T (x-y) ≥ 0 ∀ x, y ∈ s.
-/
variable {E : Type*} [NormedAddCommGroup E] [InnerProductSpace ℝ E] [CompleteSpace E]
variable {f : E → ℝ} {f' : E → E} {s : Set E}
theorem monotone_gradient_strict_convex (hs : Convex ℝ s)
(hf : ∀ x ∈ s, HasGradientAt f (f' x) x)
(mono: ∀ x ∈ s, ∀ y ∈ s, x ≠ y → inner (f' x - f' y) (x - y) > (0 : ℝ)) :
StrictConvexOn ℝ s f := by
rw [StrictConvexOn]; use hs
intro x xin y yin xney a b apos bpos absum1
by_contra h₀; push_neg at h₀
have anneg : 0 ≤ a := by linarith
have bnneg : 0 ≤ b := by linarith
have mono' : ∀ x ∈ s, ∀ y ∈ s, inner (f' x - f' y) (x - y) ≥ (0 : ℝ) := by
intro x xin y yin
by_cases h : x = y
· rw [h]; simp
· linarith [mono x xin y yin h]
have convf : ConvexOn ℝ s f := by
apply monotone_gradient_convex' hs hf mono'
rw [ConvexOn] at convf
rcases convf with ⟨_, convf⟩
have eq : f (a • x + b • y) ≤ a • f x + b • f y := by apply convf xin yin anneg bnneg absum1
have eq2 : f (a • x + b • y) = a • f x + b • f y := by linarith
let z : E := a • x + b • y
have zin : z ∈ s := by
simp [z]
have : a = 1 - b := by linarith
rw [this, sub_smul, add_comm_sub, ← smul_sub]; simp
apply Convex.add_smul_sub_mem hs xin yin; simp; use bnneg; linarith
have eq1 : ∃ c : ℝ, c ∈ Set.Ioo 0 1 ∧ inner (f' (x + c • (z - x))) (z - x) = f z - f x := by
apply lagrange hs hf x xin z zin
have eq2 : ∃ c : ℝ, c ∈ Set.Ioo 0 1 ∧ inner (f' (z + c • (y - z))) (y - z) = f y - f z := by
apply lagrange hs hf z zin y yin
rcases eq1 with ⟨c, cin, e1⟩
rcases eq2 with ⟨d, din, e2⟩
have eq3 : b * inner (f' (z + d • (y - z))) (y - z) -
a * inner (f' (x + c • (z - x))) (z - x) = 0 := by
rw [e1, e2]; simp [z]; ring_nf; rw [add_comm, ← add_assoc]
simp at eq2; rw [← eq2]; nth_rw 1 [← mul_one (f (a • x + b • y))]; rw [← absum1]; ring_nf
rw [← inner_smul_right, ← inner_smul_right] at eq3
have this1 : b • (y - z) = a • b • (y - x) := by
simp [z]; nth_rw 1 [← one_smul ℝ y]; rw [← absum1, add_smul]; simp; rw [← smul_sub, smul_comm]
have this2 : a • (z - x) = a • b • (y - x) := by
simp [z]; nth_rw 2 [← one_smul ℝ x]; rw [← absum1, add_smul]; simp; rw [← smul_sub, smul_comm]
rw [this1, this2, ← inner_sub_left, inner_smul_right, inner_smul_right, ← mul_assoc] at eq3
have eq0 : inner (f' (z + d • (y - z)) - f' (x + c • (z - x))) (y - x) = (0 : ℝ) := by
contrapose! eq3
rw [mul_ne_zero_iff]
constructor
· rw [mul_ne_zero_iff]; constructor <;> linarith
· exact eq3
have zeq : z = x + b • (y - x) := by
nth_rw 1 [← one_smul ℝ x]; rw [← absum1, add_smul, smul_sub]; simp
let u : E := z + d • (y - z)
let v : E := x + c • (z - x)
have ueq : u = x + (b + d) • (y - x) - d • b • (y - x) := by
show z + d • (y - z) = x + (b + d) • (y - x) - d • b • (y - x); rw [zeq]
rw [add_assoc, ← add_sub, add_left_cancel_iff]
rw [add_smul, ← add_sub, add_left_cancel_iff]
rw [← sub_sub, smul_sub]
have veq : v = x + c • b • (y - x) := by
show x + c • (z - x) = x + c • b • (y - x)
rw [zeq, add_left_cancel_iff]; simp
have usubv : u - v = (b + d - d * b - c * b) • (y - x) := by
rw [ueq, veq, ← smul_assoc, ← smul_assoc, ← sub_sub]; simp
rw [← add_sub, ← sub_smul (b + d) (d * b)]; simp; rw [← sub_smul]
have eeq0 : inner (f' u - f' v) (u - v) = (0 : ℝ) := by
show inner (f' (z + d • (y - z)) - f' (x + c • (z - x))) (u - v) = (0 : ℝ)
rw [usubv, inner_smul_right, eq0]; simp
have coefne0 : b + d - d * b - c * b > 0 := by
nth_rw 1 [← mul_one d]; rw [← absum1]; simp; ring_nf
simp at cin; simp at din
rcases cin with ⟨_, cl1⟩; rcases din with ⟨dpos, _⟩
calc
c * b < b := by rw [mul_lt_iff_lt_one_left]; apply cl1; linarith
_ < b + d * a := by
have : 0 < d * a := by apply mul_pos dpos apos
linarith
have neq0 : inner (f' u - f' v) (u - v) > (0 : ℝ) := by
have uin : u ∈ s := by
show z + d • (y - z) ∈ s
apply Convex.add_smul_sub_mem hs zin yin; simp; simp at din
rcases din with ⟨dpos, dl1⟩; constructor <;> linarith
have vin : v ∈ s := by
show x + c • (z - x) ∈ s
apply Convex.add_smul_sub_mem hs xin zin; simp; simp at cin
rcases cin with ⟨cpos, cl1⟩; constructor <;> linarith
apply mono u uin v vin
by_contra h
have : u - v = 0 := by rw [h]; simp
rw [usubv, smul_eq_zero] at this;
contrapose! this
constructor
· linarith
· rw [sub_ne_zero]; symm; exact xney
linarith
theorem strict_convex_monotone_gradient (hf : ∀ x ∈ s, HasGradientAt f (f' x) x)
(h₁ : StrictConvexOn ℝ s f ) :
∀ x ∈ s, ∀ y ∈ s, x ≠ y → inner (f' x - f' y) (x - y) > (0 : ℝ) := by
intro x xin y yin xney
have convf : ConvexOn ℝ s f := by apply StrictConvexOn.convexOn h₁
rw [StrictConvexOn] at h₁
rcases h₁ with ⟨hs, fsconv⟩
have : inner (f' x - f' y) (x - y) ≥ (0 : ℝ) := by
apply Convex_monotone_gradient' convf hf x xin y yin
by_contra h0; push_neg at h0
have eq : inner (f' x - f' y) (x - y) = (0 : ℝ) := by linarith
have eq1 : f x + inner (f' x) (y - x) ≤ f y := by
apply Convex_first_order_condition' (hf x xin) convf xin y yin
have eq2 : f y + inner (f' y) (x - y) ≤ f x := by
apply Convex_first_order_condition' (hf y yin) convf yin x xin
have eq2' : f y ≤ f x + inner (f' x) (y - x) := by
rw [← add_zero (inner (f' x) (y - x)), ← eq, inner_sub_left, add_sub, ← inner_add_right]
simp; apply eq2
have eq3 : f y - f x = inner (f' x) (y - x) := by linarith
have extc : ∃ c : ℝ, c ∈ Set.Ioo 0 1 ∧ inner (f' (x + c • (y - x))) (y - x) = f y - f x := by
apply lagrange hs hf x xin y yin
rcases extc with ⟨c, cin, e1⟩
let z : E := x + c • (y - x)
have zin : z ∈ s := by
apply Convex.add_smul_sub_mem hs xin yin; simp; simp at cin; rcases cin with ⟨cpos, cl1⟩
constructor <;> linarith
simp at cin; rcases cin with ⟨cpos, cl1⟩
have eq0 : inner (f' z - f' x) (z - x) = (0 : ℝ) := by
simp [z]; rw [inner_smul_right, inner_sub_left, ← eq3, e1]; simp
have eq4 : f x + inner (f' x) (z - x) ≤ f z := by
apply Convex_first_order_condition' (hf x xin) convf xin z zin
have eq5 : f z + inner (f' z) (x - z) ≤ f x := by
apply Convex_first_order_condition' (hf z zin) convf zin x xin
have eq5' : f z ≤ f x + inner (f' x) (z - x) := by
rw [← add_zero (inner (f' x) (z - x)), ← eq0, inner_sub_left]
rw [add_sub, add_comm (inner (f' x) (z - x))]
rw [← add_sub, ← inner_sub_right, sub_self, inner_zero_right, add_zero]
rw [← sub_neg_eq_add, ← inner_neg_right, neg_sub]; linarith
have eq6 : f z = inner (f' x) (z - x) + f x := by linarith
have f1 : f z = (1 - c) • f x + c • f y := by
rw [eq6]; simp [z]; rw [inner_smul_right, ← eq3]; ring_nf
have f2 : f z < (1 - c) • f x + c • f y := by
simp
let d : ℝ := 1 - c
have : x + c • (y - x) = d • x + c • y := by
simp [d]; rw [smul_sub, sub_smul, one_smul, add_sub, add_sub_right_comm]
have cdsum1 : d + c = 1 := by simp [d]
have dpos : 0 < d := by linarith
simp [z]; rw [this]
apply fsconv xin yin xney dpos cpos cdsum1
linarith
theorem strict_convex_iff_monotone_gradient
(hs: Convex ℝ s) (h : ∀ x ∈ s, HasGradientAt f (f' x) x) :
(∀ x ∈ s, ∀ y ∈ s, x ≠ y → inner (f' x - f' y) (x - y) > (0 : ℝ))
↔ StrictConvexOn ℝ s f := by
constructor
exact monotone_gradient_strict_convex hs h
exact strict_convex_monotone_gradient h
end strict