@@ -7,6 +7,7 @@ import analysis.calculus.specific_functions
7
7
import analysis.calculus.series
8
8
import analysis.convolution
9
9
import data.set.pointwise.support
10
+ import measure_theory.measure.haar_lebesgue
10
11
11
12
/-!
12
13
# Bump functions in finite-dimensional vector spaces
@@ -194,3 +195,376 @@ begin
194
195
end
195
196
196
197
end
198
+
199
+ section
200
+
201
+ namespace exists_cont_diff_bump_base
202
+
203
+ /-- An auxiliary function to construct partitions of unity on finite-dimensional real vector spaces.
204
+ It is the characteristic function of the closed unit ball. -/
205
+ def φ : E → ℝ := (closed_ball (0 : E) 1 ).indicator (λ y, (1 : ℝ))
206
+
207
+ variables [normed_space ℝ E] [finite_dimensional ℝ E]
208
+
209
+ section helper_definitions
210
+
211
+ variable (E)
212
+ lemma u_exists : ∃ u : E → ℝ, cont_diff ℝ ⊤ u ∧
213
+ (∀ x, u x ∈ Icc (0 : ℝ) 1 ) ∧ (support u = ball 0 1 ) ∧ (∀ x, u (-x) = u x) :=
214
+ begin
215
+ have A : is_open (ball (0 : E) 1 ), from is_open_ball,
216
+ obtain ⟨f, f_support, f_smooth, f_range⟩ :
217
+ ∃ (f : E → ℝ), f.support = ball (0 : E) 1 ∧ cont_diff ℝ ⊤ f ∧ set.range f ⊆ set.Icc 0 1 ,
218
+ from A.exists_smooth_support_eq,
219
+ have B : ∀ x, f x ∈ Icc (0 : ℝ) 1 := λ x, f_range (mem_range_self x),
220
+ refine ⟨λ x, (f x + f (-x)) / 2 , _, _, _, _⟩,
221
+ { exact (f_smooth.add (f_smooth.comp cont_diff_neg)).div_const },
222
+ { assume x,
223
+ split,
224
+ { linarith [(B x).1 , (B (-x)).1 ] },
225
+ { linarith [(B x).2 , (B (-x)).2 ] } },
226
+ { refine support_eq_iff.2 ⟨λ x hx, _, λ x hx, _⟩,
227
+ { apply ne_of_gt,
228
+ have : 0 < f x,
229
+ { apply lt_of_le_of_ne (B x).1 (ne.symm _),
230
+ rwa ← f_support at hx },
231
+ linarith [(B (-x)).1 ] },
232
+ { have I1 : x ∉ support f, by rwa f_support,
233
+ have I2 : -x ∉ support f,
234
+ { rw f_support,
235
+ simp only at hx,
236
+ simpa using hx },
237
+ simp only [mem_support, not_not] at I1 I2,
238
+ simp only [I1, I2, add_zero, zero_div] } },
239
+ { assume x, simp only [add_comm, neg_neg] }
240
+ end
241
+
242
+ variable {E}
243
+
244
+ /-- An auxiliary function to construct partitions of unity on finite-dimensional real vector spaces,
245
+ which is smooth, symmetric, and with support equal to the unit ball. -/
246
+ def u (x : E) : ℝ := classical.some (u_exists E) x
247
+
248
+ variable (E)
249
+ lemma u_smooth : cont_diff ℝ ⊤ (u : E → ℝ) := (classical.some_spec (u_exists E)).1
250
+
251
+ lemma u_continuous : continuous (u : E → ℝ) := (u_smooth E).continuous
252
+
253
+ lemma u_support : support (u : E → ℝ) = ball 0 1 := (classical.some_spec (u_exists E)).2 .2 .1
254
+
255
+ lemma u_compact_support : has_compact_support (u : E → ℝ) :=
256
+ begin
257
+ rw [has_compact_support_def, u_support, closure_ball (0 : E) one_ne_zero],
258
+ exact is_compact_closed_ball _ _,
259
+ end
260
+ variable {E}
261
+
262
+ lemma u_nonneg (x : E) : 0 ≤ u x := ((classical.some_spec (u_exists E)).2 .1 x).1
263
+
264
+ lemma u_le_one (x : E) : u x ≤ 1 := ((classical.some_spec (u_exists E)).2 .1 x).2
265
+
266
+ lemma u_neg (x : E) : u (-x) = u x := (classical.some_spec (u_exists E)).2 .2 .2 x
267
+
268
+ variables [measurable_space E] [borel_space E]
269
+
270
+ local notation `μ ` := measure_theory.measure.add_haar
271
+
272
+ variable (E)
273
+ lemma u_int_pos : 0 < ∫ (x : E), u x ∂μ :=
274
+ begin
275
+ refine (integral_pos_iff_support_of_nonneg u_nonneg _).mpr _,
276
+ { exact (u_continuous E).integrable_of_has_compact_support (u_compact_support E) },
277
+ { rw u_support, exact measure_ball_pos _ _ zero_lt_one }
278
+ end
279
+ variable {E}
280
+
281
+ /-- An auxiliary function to construct partitions of unity on finite-dimensional real vector spaces,
282
+ which is smooth, symmetric, with support equal to the ball of radius `D` and integral `1`. -/
283
+ def W (D : ℝ) (x : E) : ℝ := ((∫ (x : E), u x ∂μ) * |D|^(finrank ℝ E))⁻¹ • u (D⁻¹ • x)
284
+
285
+ lemma W_def (D : ℝ) :
286
+ (W D : E → ℝ) = λ x, ((∫ (x : E), u x ∂μ) * |D|^(finrank ℝ E))⁻¹ • u (D⁻¹ • x) :=
287
+ by { ext1 x, refl }
288
+
289
+ lemma W_nonneg (D : ℝ) (x : E) : 0 ≤ W D x :=
290
+ begin
291
+ apply mul_nonneg _ (u_nonneg _),
292
+ apply inv_nonneg.2 ,
293
+ apply mul_nonneg (u_int_pos E).le,
294
+ apply pow_nonneg (abs_nonneg D)
295
+ end
296
+
297
+ lemma W_mul_φ_nonneg (D : ℝ) (x y : E) : 0 ≤ W D y * φ (x - y) :=
298
+ mul_nonneg (W_nonneg D y) (indicator_nonneg (by simp only [zero_le_one, implies_true_iff]) _)
299
+
300
+ variable (E)
301
+
302
+ lemma W_integral {D : ℝ} (Dpos : 0 < D) : ∫ (x : E), W D x ∂μ = 1 :=
303
+ begin
304
+ simp_rw [W, integral_smul],
305
+ rw [integral_comp_inv_smul_of_nonneg μ (u : E → ℝ) Dpos.le,
306
+ abs_of_nonneg Dpos.le, mul_comm],
307
+ field_simp [Dpos.ne', (u_int_pos E).ne'],
308
+ end
309
+
310
+ lemma W_support {D : ℝ} (Dpos : 0 < D) : support (W D : E → ℝ) = ball 0 D :=
311
+ begin
312
+ have B : D • ball (0 : E) 1 = ball 0 D,
313
+ by rw [smul_unit_ball Dpos.ne', real.norm_of_nonneg Dpos.le],
314
+ have C : D ^ finrank ℝ E ≠ 0 , from pow_ne_zero _ Dpos.ne',
315
+ simp only [W_def, algebra.id.smul_eq_mul, support_mul, support_inv, univ_inter,
316
+ support_comp_inv_smul₀ Dpos.ne', u_support, B, support_const (u_int_pos E).ne',
317
+ support_const C, abs_of_nonneg Dpos.le],
318
+ end
319
+
320
+ lemma W_compact_support {D : ℝ} (Dpos : 0 < D) : has_compact_support (W D : E → ℝ) :=
321
+ begin
322
+ rw [has_compact_support_def, W_support E Dpos, closure_ball (0 : E) Dpos.ne'],
323
+ exact is_compact_closed_ball _ _,
324
+ end
325
+ variable {E}
326
+
327
+ /-- An auxiliary function to construct partitions of unity on finite-dimensional real vector spaces.
328
+ It is the convolution between a smooth function of integral `1` supported in the ball of radius `D`,
329
+ with the indicator function of the closed unit ball. Therefore, it is smooth, equal to `1` on the
330
+ ball of radius `1 - D`, with support equal to the ball of radius `1 + D`. -/
331
+ def Y (D : ℝ) : E → ℝ := W D ⋆[lsmul ℝ ℝ, μ] φ
332
+
333
+ lemma Y_neg (D : ℝ) (x : E) : Y D (-x) = Y D x :=
334
+ begin
335
+ apply convolution_neg_of_neg_eq,
336
+ { apply eventually_of_forall (λ x, _),
337
+ simp only [W_def, u_neg, smul_neg, algebra.id.smul_eq_mul, mul_eq_mul_left_iff,
338
+ eq_self_iff_true, true_or], },
339
+ { apply eventually_of_forall (λ x, _),
340
+ simp only [φ, indicator, mem_closed_ball_zero_iff, norm_neg] },
341
+ end
342
+
343
+ lemma Y_eq_one_of_mem_closed_ball {D : ℝ} {x : E} (Dpos : 0 < D)
344
+ (hx : x ∈ closed_ball (0 : E) (1 - D)) : Y D x = 1 :=
345
+ begin
346
+ change (W D ⋆[lsmul ℝ ℝ, μ] φ) x = 1 ,
347
+ have B : ∀ (y : E), y ∈ ball x D → φ y = 1 ,
348
+ { have C : ball x D ⊆ ball 0 1 ,
349
+ { apply ball_subset_ball',
350
+ simp only [mem_closed_ball] at hx,
351
+ linarith only [hx] },
352
+ assume y hy,
353
+ simp only [φ, indicator, mem_closed_ball, ite_eq_left_iff, not_le, zero_ne_one],
354
+ assume h'y,
355
+ linarith only [mem_ball.1 (C hy), h'y] },
356
+ have Bx : φ x = 1 , from B _ (mem_ball_self Dpos),
357
+ have B' : ∀ y, y ∈ ball x D → φ y = φ x, by { rw Bx, exact B },
358
+ rw convolution_eq_right' _ (le_of_eq (W_support E Dpos)) B',
359
+ simp only [lsmul_apply, algebra.id.smul_eq_mul, integral_mul_right, W_integral E Dpos, Bx,
360
+ one_mul],
361
+ end
362
+
363
+ lemma Y_eq_zero_of_not_mem_ball {D : ℝ} {x : E} (Dpos : 0 < D)
364
+ (hx : x ∉ ball (0 : E) (1 + D)) : Y D x = 0 :=
365
+ begin
366
+ change (W D ⋆[lsmul ℝ ℝ, μ] φ) x = 0 ,
367
+ have B : ∀ y, y ∈ ball x D → φ y = 0 ,
368
+ { assume y hy,
369
+ simp only [φ, indicator, mem_closed_ball_zero_iff, ite_eq_right_iff, one_ne_zero],
370
+ assume h'y,
371
+ have C : ball y D ⊆ ball 0 (1 +D),
372
+ { apply ball_subset_ball',
373
+ rw ← dist_zero_right at h'y,
374
+ linarith only [h'y] },
375
+ exact hx (C (mem_ball_comm.1 hy)) },
376
+ have Bx : φ x = 0 , from B _ (mem_ball_self Dpos),
377
+ have B' : ∀ y, y ∈ ball x D → φ y = φ x, by { rw Bx, exact B },
378
+ rw convolution_eq_right' _ (le_of_eq (W_support E Dpos)) B',
379
+ simp only [lsmul_apply, algebra.id.smul_eq_mul, Bx, mul_zero, integral_const]
380
+ end
381
+
382
+ lemma Y_nonneg (D : ℝ) (x : E) : 0 ≤ Y D x :=
383
+ integral_nonneg (W_mul_φ_nonneg D x)
384
+
385
+ lemma Y_le_one {D : ℝ} (x : E) (Dpos : 0 < D) : Y D x ≤ 1 :=
386
+ begin
387
+ have A : (W D ⋆[lsmul ℝ ℝ, μ] φ) x ≤ (W D ⋆[lsmul ℝ ℝ, μ] 1 ) x,
388
+ { apply convolution_mono_right_of_nonneg _ (W_nonneg D)
389
+ (indicator_le_self' (λ x hx, zero_le_one)) (λ x, zero_le_one),
390
+ refine (has_compact_support.convolution_exists_left _ (W_compact_support E Dpos) _
391
+ (locally_integrable_const (1 : ℝ)) x).integrable,
392
+ exact continuous_const.mul ((u_continuous E).comp (continuous_id.const_smul _)) },
393
+ have B : (W D ⋆[lsmul ℝ ℝ, μ] (λ y, (1 : ℝ))) x = 1 ,
394
+ by simp only [convolution, continuous_linear_map.map_smul, mul_inv_rev, coe_smul', mul_one,
395
+ lsmul_apply, algebra.id.smul_eq_mul, integral_mul_left, W_integral E Dpos, pi.smul_apply],
396
+ exact A.trans (le_of_eq B)
397
+ end
398
+
399
+ lemma Y_pos_of_mem_ball {D : ℝ} {x : E} (Dpos : 0 < D) (D_lt_one : D < 1 )
400
+ (hx : x ∈ ball (0 : E) (1 + D)) : 0 < Y D x :=
401
+ begin
402
+ simp only [mem_ball_zero_iff] at hx,
403
+ refine (integral_pos_iff_support_of_nonneg (W_mul_φ_nonneg D x) _).2 _,
404
+ { have F_comp : has_compact_support (W D),
405
+ from W_compact_support E Dpos,
406
+ have B : locally_integrable (φ : E → ℝ) μ,
407
+ from (locally_integrable_const _).indicator measurable_set_closed_ball,
408
+ have C : continuous (W D : E → ℝ),
409
+ from continuous_const.mul ((u_continuous E).comp (continuous_id.const_smul _)),
410
+ exact (has_compact_support.convolution_exists_left (lsmul ℝ ℝ : ℝ →L[ℝ] ℝ →L[ℝ] ℝ)
411
+ F_comp C B x).integrable },
412
+ { set z := (D / (1 + D)) • x with hz,
413
+ have B : 0 < 1 + D, by linarith,
414
+ have C : ball z (D * (1 + D- ‖x‖) / (1 + D)) ⊆ support (λ (y : E), W D y * φ (x - y)),
415
+ { assume y hy,
416
+ simp only [support_mul, W_support E Dpos],
417
+ simp only [φ, mem_inter_iff, mem_support, ne.def, indicator_apply_eq_zero,
418
+ mem_closed_ball_zero_iff, one_ne_zero, not_forall, not_false_iff, exists_prop, and_true],
419
+ split,
420
+ { apply ball_subset_ball' _ hy,
421
+ simp only [z, norm_smul, abs_of_nonneg Dpos.le, abs_of_nonneg B.le, dist_zero_right,
422
+ real.norm_eq_abs, abs_div],
423
+ simp only [div_le_iff B] with field_simps,
424
+ ring_nf },
425
+ { have ID : ‖D / (1 + D) - 1 ‖ = 1 / (1 + D),
426
+ { rw real.norm_of_nonpos,
427
+ { simp only [B.ne', ne.def, not_false_iff, mul_one, neg_sub, add_tsub_cancel_right]
428
+ with field_simps},
429
+ { simp only [B.ne', ne.def, not_false_iff, mul_one] with field_simps,
430
+ apply div_nonpos_of_nonpos_of_nonneg _ B.le,
431
+ linarith only, } },
432
+ rw ← mem_closed_ball_iff_norm',
433
+ apply closed_ball_subset_closed_ball' _ (ball_subset_closed_ball hy),
434
+ rw [← one_smul ℝ x, dist_eq_norm, hz, ← sub_smul, one_smul, norm_smul, ID],
435
+ simp only [-one_div, -mul_eq_zero, B.ne', div_le_iff B] with field_simps,
436
+ simp only [mem_ball_zero_iff] at hx,
437
+ nlinarith only [hx, D_lt_one] } },
438
+ apply lt_of_lt_of_le _ (measure_mono C),
439
+ apply measure_ball_pos,
440
+ exact div_pos (mul_pos Dpos (by linarith only [hx])) B }
441
+ end
442
+
443
+ variable (E)
444
+
445
+ lemma Y_smooth : cont_diff_on ℝ ⊤ (uncurry Y) ((Ioo (0 : ℝ) 1 ) ×ˢ (univ : set E)) :=
446
+ begin
447
+ have hs : is_open (Ioo (0 : ℝ) (1 : ℝ)), from is_open_Ioo,
448
+ have hk : is_compact (closed_ball (0 : E) 1 ), from proper_space.is_compact_closed_ball _ _,
449
+ refine cont_diff_on_convolution_left_with_param (lsmul ℝ ℝ) hs hk _ _ _,
450
+ { rintros p x hp hx,
451
+ simp only [W, mul_inv_rev, algebra.id.smul_eq_mul, mul_eq_zero, inv_eq_zero],
452
+ right,
453
+ contrapose! hx,
454
+ have : p⁻¹ • x ∈ support u, from mem_support.2 hx,
455
+ simp only [u_support, norm_smul, mem_ball_zero_iff, real.norm_eq_abs, abs_inv,
456
+ abs_of_nonneg hp.1 .le, ← div_eq_inv_mul, div_lt_one hp.1 ] at this ,
457
+ rw mem_closed_ball_zero_iff,
458
+ exact this.le.trans hp.2 .le },
459
+ { exact (locally_integrable_const _).indicator measurable_set_closed_ball },
460
+ { apply cont_diff_on.mul,
461
+ { refine (cont_diff_on_const.mul _).inv
462
+ (λ x hx, ne_of_gt (mul_pos (u_int_pos E) (pow_pos (abs_pos_of_pos hx.1 .1 ) _))),
463
+ apply cont_diff_on.pow,
464
+ simp_rw [← real.norm_eq_abs],
465
+ apply @cont_diff_on.norm ℝ,
466
+ { exact cont_diff_on_fst },
467
+ { assume x hx, exact ne_of_gt hx.1 .1 } },
468
+ { apply (u_smooth E).comp_cont_diff_on,
469
+ exact cont_diff_on.smul (cont_diff_on_fst.inv (λ x hx, ne_of_gt hx.1 .1 )) cont_diff_on_snd } },
470
+ end
471
+
472
+ lemma Y_support {D : ℝ} (Dpos : 0 < D) (D_lt_one : D < 1 ) :
473
+ support (Y D : E → ℝ) = ball (0 : E) (1 + D) :=
474
+ support_eq_iff.2 ⟨λ x hx, (Y_pos_of_mem_ball Dpos D_lt_one hx).ne',
475
+ λ x hx, Y_eq_zero_of_not_mem_ball Dpos hx⟩
476
+
477
+ variable {E}
478
+
479
+ end helper_definitions
480
+
481
+ /-- The base function from which one will construct a family of bump functions. One could
482
+ add more properties if they are useful and satisfied in the examples of inner product spaces
483
+ and finite dimensional vector spaces, notably derivative norm control in terms of `R - 1`.
484
+ TODO: move to the right file and use this to refactor bump functions in general. -/
485
+ @[nolint has_nonempty_instance]
486
+ structure _root_.cont_diff_bump_base (E : Type *) [normed_add_comm_group E] [normed_space ℝ E] :=
487
+ (to_fun : ℝ → E → ℝ)
488
+ (mem_Icc : ∀ (R : ℝ) (x : E), to_fun R x ∈ Icc (0 : ℝ) 1 )
489
+ (symmetric : ∀ (R : ℝ) (x : E), to_fun R (-x) = to_fun R x)
490
+ (smooth : cont_diff_on ℝ ⊤ (uncurry to_fun) ((Ioi (1 : ℝ)) ×ˢ (univ : set E)))
491
+ (eq_one : ∀ (R : ℝ) (hR : 1 < R) (x : E) (hx : ‖x‖ ≤ 1 ), to_fun R x = 1 )
492
+ (support : ∀ (R : ℝ) (hR : 1 < R), support (to_fun R) = metric.ball (0 : E) R)
493
+
494
+ /-- A class registering that a real vector space admits bump functions. This will be instantiated
495
+ first for inner product spaces, and then for finite-dimensional normed spaces.
496
+ We use a specific class instead of `nonempty (cont_diff_bump_base E)` for performance reasons. -/
497
+ class _root_.has_cont_diff_bump (E : Type *) [normed_add_comm_group E] [normed_space ℝ E] : Prop :=
498
+ (out : nonempty (cont_diff_bump_base E))
499
+
500
+ @[priority 100 ]
501
+ instance {E : Type *} [normed_add_comm_group E] [normed_space ℝ E] [finite_dimensional ℝ E] :
502
+ has_cont_diff_bump E :=
503
+ begin
504
+ refine ⟨⟨_⟩⟩,
505
+ borelize E,
506
+ have IR : ∀ (R : ℝ), 1 < R → 0 < (R - 1 ) / (R + 1 ),
507
+ { assume R hR, apply div_pos; linarith },
508
+ exact
509
+ { to_fun := λ R x, if 1 < R then Y ((R - 1 ) / (R + 1 )) (((R + 1 ) / 2 )⁻¹ • x) else 0 ,
510
+ mem_Icc := λ R x, begin
511
+ split_ifs,
512
+ { refine ⟨Y_nonneg _ _, Y_le_one _ (IR R h)⟩ },
513
+ { simp only [pi.zero_apply, left_mem_Icc, zero_le_one] }
514
+ end ,
515
+ symmetric := λ R x, begin
516
+ split_ifs,
517
+ { simp only [Y_neg, smul_neg] },
518
+ { refl },
519
+ end ,
520
+ smooth := begin
521
+ suffices : cont_diff_on ℝ ⊤
522
+ ((uncurry Y) ∘ (λ (p : ℝ × E), ((p.1 - 1 ) / (p.1 + 1 ), ((p.1 + 1 )/2 )⁻¹ • p.2 )))
523
+ (Ioi 1 ×ˢ univ),
524
+ { apply this.congr,
525
+ rintros ⟨R, x⟩ ⟨(hR : 1 < R), hx⟩,
526
+ simp only [hR, uncurry_apply_pair, if_true, comp_app], },
527
+ apply (Y_smooth E).comp,
528
+ { apply cont_diff_on.prod,
529
+ { refine (cont_diff_on_fst.sub cont_diff_on_const).div
530
+ (cont_diff_on_fst.add cont_diff_on_const) _,
531
+ rintros ⟨R, x⟩ ⟨(hR : 1 < R), hx⟩,
532
+ apply ne_of_gt,
533
+ dsimp only,
534
+ linarith, },
535
+ { apply cont_diff_on.smul _ cont_diff_on_snd,
536
+ refine (cont_diff_on_fst.add cont_diff_on_const).div_const.inv _,
537
+ rintros ⟨R, x⟩ ⟨(hR : 1 < R), hx⟩,
538
+ apply ne_of_gt,
539
+ dsimp only,
540
+ linarith } },
541
+ { rintros ⟨R, x⟩ ⟨(hR : 1 < R), hx⟩,
542
+ have A : 0 < (R - 1 ) / (R + 1 ), by { apply div_pos; linarith },
543
+ have B : (R - 1 ) / (R + 1 ) < 1 , by { apply (div_lt_one _ ).2 ; linarith },
544
+ simp only [mem_preimage, prod_mk_mem_set_prod_eq, mem_Ioo, mem_univ, and_true, A, B] }
545
+ end ,
546
+ eq_one := λ R hR x hx, begin
547
+ have A : 0 < R + 1 , by linarith,
548
+ simp only [hR, if_true],
549
+ apply Y_eq_one_of_mem_closed_ball (IR R hR),
550
+ simp only [norm_smul, inv_div, mem_closed_ball_zero_iff, real.norm_eq_abs, abs_div,
551
+ abs_two, abs_of_nonneg A.le],
552
+ calc 2 / (R + 1 ) * ‖x‖ ≤ 2 / (R + 1 ) * 1 :
553
+ mul_le_mul_of_nonneg_left hx (div_nonneg zero_le_two A.le)
554
+ ... = 1 - (R - 1 ) / (R + 1 ) : by { field_simp [A.ne'], ring }
555
+ end ,
556
+ support := λ R hR, begin
557
+ have A : 0 < (R + 1 ) / 2 , by linarith,
558
+ have A' : 0 < R + 1 , by linarith,
559
+ have C : (R - 1 ) / (R + 1 ) < 1 , by { apply (div_lt_one _ ).2 ; linarith },
560
+ simp only [hR, if_true, support_comp_inv_smul₀ A.ne', Y_support _ (IR R hR) C,
561
+ smul_ball A.ne', real.norm_of_nonneg A.le, smul_zero],
562
+ congr' 1 ,
563
+ field_simp [A'.ne'],
564
+ ring,
565
+ end },
566
+ end
567
+
568
+ end exists_cont_diff_bump_base
569
+
570
+ end
0 commit comments