|
| 1 | +/- |
| 2 | +Copyright (c) 2025 Vasily Ilin. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Vasily Ilin |
| 5 | +-/ |
| 6 | +import Mathlib.Topology.Algebra.Order.Floor |
| 7 | +import Mathlib.Analysis.Calculus.Deriv.Add |
| 8 | +import Mathlib.Analysis.Calculus.Deriv.Mul |
| 9 | + |
| 10 | +/-! |
| 11 | +# Piecewise linear and constant interpolation on regular grids |
| 12 | +
|
| 13 | +Given a sequence of values `y` and slopes `c` on a regular grid with step size `h > 0` |
| 14 | +starting at `a`, this file defines: |
| 15 | +
|
| 16 | +* `piecewiseLinear y c h a t`: the piecewise linear interpolation, equal to |
| 17 | + `y n + (t - (a + n * h)) • c n` on `[a + n * h, a + (n + 1) * h)`. |
| 18 | +* `piecewiseConst c h a t`: the piecewise constant function taking value `c n` on |
| 19 | + `[a + n * h, a + (n + 1) * h)`. |
| 20 | +
|
| 21 | +## Main results |
| 22 | +
|
| 23 | +* `piecewiseConst_eq_on_Ico`: `piecewiseConst c h a t = c n` on the `n`-th cell. |
| 24 | +* `piecewiseLinear_apply_grid`: `piecewiseLinear y c h a (a + n * h) = y n`. |
| 25 | +* `piecewiseLinear_eq_on_Ico`: evaluation on the `n`-th cell. |
| 26 | +* `piecewiseLinear_continuousOn`: continuity on `[a, ∞)` when `y (n+1) = y n + h • c n`. |
| 27 | +* `piecewiseLinear_hasDerivWithinAt`: the right derivative of the piecewise linear function |
| 28 | + is the piecewise constant slope. |
| 29 | +
|
| 30 | +## References |
| 31 | +
|
| 32 | +* [Vilin97/forward_euler](https://github.com/Vilin97/forward_euler) — a formal proof of |
| 33 | + convergence of the forward Euler method, where these definitions are used. |
| 34 | +-/ |
| 35 | + |
| 36 | +open Set |
| 37 | + |
| 38 | +variable {α : Type*} [Field α] [LinearOrder α] [FloorSemiring α] [IsStrictOrderedRing α] |
| 39 | + |
| 40 | +/-- The piecewise linear interpolation of a sequence `y` with slopes `c` on a regular grid |
| 41 | +with step size `h` starting at `a`. On `[a + n * h, a + (n + 1) * h)`, the value is |
| 42 | +`y n + (t - (a + n * h)) • c n`. -/ |
| 43 | +noncomputable def piecewiseLinear {E : Type*} [AddCommGroup E] [Module α E] |
| 44 | + (y : ℕ → E) (c : ℕ → E) (h : α) (a : α) (t : α) : E := |
| 45 | + let n := ⌊(t - a) / h⌋₊ |
| 46 | + y n + (t - (a + n * h)) • c n |
| 47 | + |
| 48 | +/-- The piecewise constant function taking value `c n` on `[a + n * h, a + (n + 1) * h)`. -/ |
| 49 | +noncomputable def piecewiseConst {E : Type*} (c : ℕ → E) (h : α) (a : α) (t : α) : E := |
| 50 | + c ⌊(t - a) / h⌋₊ |
| 51 | + |
| 52 | +/-- The piecewise constant function equals `c n` on `[a + n * h, a + (n + 1) * h)`. -/ |
| 53 | +theorem piecewiseConst_eq_on_Ico {E : Type*} {c : ℕ → E} {h : α} {a : α} |
| 54 | + (hh : 0 < h) {n : ℕ} {t : α} |
| 55 | + (ht : t ∈ Ico (a + n * h) (a + (n + 1) * h)) : |
| 56 | + piecewiseConst c h a t = c n := by |
| 57 | + simp [piecewiseConst, Nat.floor_div_eq_of_mem_Ico hh ht] |
| 58 | + |
| 59 | +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] |
| 60 | + {y : ℕ → E} {c : ℕ → E} {h : ℝ} {a : ℝ} |
| 61 | + |
| 62 | +/-- The piecewise linear interpolation at a grid point `a + n * h` equals `y n`. -/ |
| 63 | +theorem piecewiseLinear_apply_grid (hh : 0 < h) (a : ℝ) (n : ℕ) : |
| 64 | + piecewiseLinear y c h a (a + n * h) = y n := by |
| 65 | + simp [piecewiseLinear, hh.ne'] |
| 66 | + |
| 67 | +/-- The piecewise linear interpolation equals `y n + (t - (a + n * h)) • c n` |
| 68 | +on `[a + n * h, a + (n + 1) * h)`. -/ |
| 69 | +theorem piecewiseLinear_eq_on_Ico (hh : 0 < h) {n : ℕ} {t : ℝ} |
| 70 | + (ht : t ∈ Ico (a + n * h) (a + (n + 1) * h)) : |
| 71 | + piecewiseLinear y c h a t = y n + (t - (a + n * h)) • c n := by |
| 72 | + simp [piecewiseLinear, Nat.floor_div_eq_of_mem_Ico hh ht] |
| 73 | + |
| 74 | +/-- A piecewise linear function whose grid values satisfy `y (n + 1) = y n + h • c n` |
| 75 | +is continuous on `[a, ∞)`. -/ |
| 76 | +theorem piecewiseLinear_continuousOn (hh : 0 < h) |
| 77 | + (hstep : ∀ n, y (n + 1) = y n + h • c n) : |
| 78 | + ContinuousOn (piecewiseLinear y c h a) (Ici a) := by |
| 79 | + apply ContinuousOn.of_Icc_grid hh; intro n |
| 80 | + apply (show ContinuousOn (fun t => y n + (t - (a + n * h)) • c n) _ by fun_prop).congr |
| 81 | + intro t ht; rcases eq_or_lt_of_le ht.2 with rfl | h_lt |
| 82 | + · norm_cast |
| 83 | + rw [piecewiseLinear_apply_grid hh a (n + 1), hstep] |
| 84 | + module |
| 85 | + · exact piecewiseLinear_eq_on_Ico hh ⟨ht.1, h_lt⟩ |
| 86 | + |
| 87 | +/-- The right derivative of a piecewise linear function is the piecewise constant slope. -/ |
| 88 | +theorem piecewiseLinear_hasDerivWithinAt (hh : 0 < h) {t : ℝ} (hat : a ≤ t) : |
| 89 | + HasDerivWithinAt (piecewiseLinear y c h a) |
| 90 | + (piecewiseConst c h a t) (Ici t) t := by |
| 91 | + set n := ⌊(t - a) / h⌋₊; set tn := a + n * h |
| 92 | + obtain ⟨h1, h2⟩ := mem_Ico_Nat_floor_div hh hat |
| 93 | + simp only [piecewiseConst] |
| 94 | + exact hasDerivWithinAt_Ioi_iff_Ici.mp |
| 95 | + (((hasDerivAt_id t |>.sub_const tn |>.smul_const (c n) |
| 96 | + |>.const_add (y n)).hasDerivWithinAt.congr_of_eventuallyEq (by |
| 97 | + filter_upwards [Ioo_mem_nhdsGT h2] with x hx |
| 98 | + exact piecewiseLinear_eq_on_Ico hh ⟨h1.trans hx.1.le, hx.2⟩) |
| 99 | + (by simp [piecewiseLinear, n, tn])).congr_deriv (one_smul _ _)) |
0 commit comments