|
| 1 | +/- |
| 2 | +Copyright (c) 2026 Justus Springer. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Justus Springer |
| 5 | +-/ |
| 6 | +module |
| 7 | + |
| 8 | +public import Mathlib.Algebra.MvPolynomial.PDeriv |
| 9 | +public import Mathlib.RingTheory.MvPowerSeries.Inverse |
| 10 | +public import Mathlib.RingTheory.MvPowerSeries.Trunc |
| 11 | + |
| 12 | +/-! |
| 13 | +# Formal partial derivatives of multivariate power series |
| 14 | +
|
| 15 | +This file defines `MvPowerSeries.pderiv R i`, the formal partial derivative of a multivariate |
| 16 | +power series with respect to variable `i`, as a |
| 17 | +`Derivation R (MvPowerSeries σ R) (MvPowerSeries σ R)`. |
| 18 | +
|
| 19 | +See also `PowerSeries.derivative` for the univariate setting. |
| 20 | +
|
| 21 | +## Main definitions |
| 22 | +
|
| 23 | +- `MvPowerSeries.pderiv R i`: the formal partial derivative with respect to `i`, as a derivation. |
| 24 | +
|
| 25 | +## Main results |
| 26 | +
|
| 27 | +- `MvPowerSeries.coeff_pderiv`: coefficient formula |
| 28 | + `coeff n (pderiv R i f) = coeff (n + single i 1) f * (n i + 1)`. |
| 29 | +- `MvPowerSeries.pderiv_coe`: compatibility with `MvPolynomial.pderiv`. |
| 30 | +- `MvPowerSeries.trunc_pderiv`: truncation commutes with partial differentiation. |
| 31 | +- `MvPowerSeries.pderiv.ext`: a power series is determined by its constant term and its partial |
| 32 | + derivatives. |
| 33 | +- `MvPowerSeries.pderiv_pow`: power rule. |
| 34 | +- `MvPowerSeries.pderiv_inv`, `MvPowerSeries.pderiv_inv'`: derivative of an inverse. |
| 35 | +
|
| 36 | +-/ |
| 37 | + |
| 38 | +@[expose] public section |
| 39 | + |
| 40 | +namespace MvPowerSeries |
| 41 | + |
| 42 | +open MvPolynomial Finsupp |
| 43 | + |
| 44 | +variable {σ R : Type*} |
| 45 | + |
| 46 | +section Semiring |
| 47 | + |
| 48 | +variable [Semiring R] |
| 49 | + |
| 50 | +/-- The underlying function of the formal partial derivative with respect to variable `i`. |
| 51 | +This is packaged as a derivation in `MvPowerSeries.pderiv`. -/ |
| 52 | +noncomputable def pderivFun (i : σ) (f : MvPowerSeries σ R) : MvPowerSeries σ R := |
| 53 | + fun d ↦ coeff (d + single i 1) f * (d i + 1) |
| 54 | + |
| 55 | +theorem coeff_pderivFun {i : σ} (f : MvPowerSeries σ R) (d : σ →₀ ℕ) : |
| 56 | + coeff d (f.pderivFun i) = coeff (d + single i 1) f * (d i + 1) := by |
| 57 | + rfl |
| 58 | + |
| 59 | +theorem pderivFun_add {i : σ} (f g : MvPowerSeries σ R) : |
| 60 | + pderivFun i (f + g) = pderivFun i f + pderivFun i g := by |
| 61 | + ext |
| 62 | + rw [coeff_pderivFun, map_add, map_add, coeff_pderivFun, coeff_pderivFun, add_mul] |
| 63 | + |
| 64 | +theorem pderivFun_C {i : σ} (r : R) : pderivFun i (C r) = 0 := by |
| 65 | + ext n |
| 66 | + rw [coeff_pderivFun, coeff_add_single_C, zero_mul, (coeff n).map_zero] |
| 67 | + |
| 68 | +theorem pderivFun_one {i : σ} : pderivFun i (1 : MvPowerSeries σ R) = 0 := by |
| 69 | + rw [← map_one C, pderivFun_C (1 : R)] |
| 70 | + |
| 71 | +end Semiring |
| 72 | + |
| 73 | +section CommSemiring |
| 74 | + |
| 75 | +variable [CommSemiring R] |
| 76 | + |
| 77 | +private theorem pderivFun_coe {i : σ} (f : MvPolynomial σ R) : |
| 78 | + (f : MvPowerSeries σ R).pderivFun i = f.pderiv i := by |
| 79 | + ext |
| 80 | + rw [coeff_pderivFun, coeff_coe, coeff_coe, coeff_pderiv] |
| 81 | + |
| 82 | +private theorem trunc_pderivFun [DecidableEq σ] {i : σ} (f : MvPowerSeries σ R) (n : σ →₀ ℕ) : |
| 83 | + trunc R n (pderivFun i f) = pderiv i (trunc R (n + single i 1) f) := by |
| 84 | + ext |
| 85 | + rw [coeff_trunc] |
| 86 | + split_ifs with h |
| 87 | + · rw [coeff_pderivFun, coeff_pderiv, coeff_trunc, if_pos (add_lt_add_left h _)] |
| 88 | + · rw [coeff_pderiv, coeff_trunc, if_neg ((add_lt_add_iff_right _).not.mpr h), zero_mul] |
| 89 | + |
| 90 | +-- A special case of `pderivFun_mul`, used in its proof. |
| 91 | +private theorem pderivFun_coe_mul_coe {i : σ} (f g : MvPolynomial σ R) : |
| 92 | + pderivFun i (f * g : MvPowerSeries σ R) = f * pderiv i g + g * pderiv i f := by |
| 93 | + rw [← coe_mul, pderivFun_coe, pderiv_mul, add_comm, mul_comm _ g, ← coe_mul, ← coe_mul, |
| 94 | + MvPolynomial.coe_add] |
| 95 | + |
| 96 | +private theorem pderivFun_mul {i : σ} (f g : MvPowerSeries σ R) : |
| 97 | + pderivFun i (f * g) = f • g.pderivFun i + g • f.pderivFun i := by |
| 98 | + classical |
| 99 | + ext n |
| 100 | + have h₁ : n < n + single i 1 := lt_def.mpr ⟨self_le_add_right _ _, i, by simp⟩ |
| 101 | + have h₂ : n + single i 1 < n + single i 1 + single i 1 := |
| 102 | + lt_def.mpr ⟨self_le_add_right _ _, i, by simp⟩ |
| 103 | + have h₃ : n < n + single i 1 + single i 1 := lt_trans h₁ h₂ |
| 104 | + rw [coeff_pderivFun, map_add, ← coeff_trunc_mul_trunc_eq_coeff_mul _ _ _ h₂, smul_eq_mul, |
| 105 | + smul_eq_mul, ← coeff_trunc_mul_trunc_eq_coeff_mul₂ _ _ g (f.pderivFun i) h₃ h₁, |
| 106 | + ← coeff_trunc_mul_trunc_eq_coeff_mul₂ _ _ f (g.pderivFun i) h₃ h₁, trunc_pderivFun, |
| 107 | + trunc_pderivFun, ← coeff_coe, ← coeff_coe, ← coeff_coe, ← map_add, coe_mul, coe_mul, coe_mul, |
| 108 | + ← pderivFun_coe_mul_coe, coeff_pderivFun] |
| 109 | + |
| 110 | +private theorem pderivFun_smul {i : σ} (r : R) (f : MvPowerSeries σ R) : |
| 111 | + pderivFun i (r • f) = r • pderivFun i f := by |
| 112 | + rw [smul_eq_C_mul, smul_eq_C_mul, pderivFun_mul, pderivFun_C, smul_zero, add_zero, smul_eq_mul] |
| 113 | + |
| 114 | +variable (R) in |
| 115 | +/-- The formal partial derivative of a multivariate formal power series with respect to |
| 116 | +variable `i`, as an `R`-derivation on `MvPowerSeries σ R`. -/ |
| 117 | +@[no_expose] |
| 118 | +noncomputable def pderiv (i : σ) : Derivation R (MvPowerSeries σ R) (MvPowerSeries σ R) where |
| 119 | + toFun := pderivFun i |
| 120 | + map_add' := pderivFun_add |
| 121 | + map_smul' := pderivFun_smul |
| 122 | + map_one_eq_zero' := pderivFun_one |
| 123 | + leibniz' := pderivFun_mul |
| 124 | + |
| 125 | +@[simp] theorem pderiv_C {i : σ} {r : R} : pderiv R i (C r) = 0 := pderivFun_C r |
| 126 | + |
| 127 | +theorem pderiv_one {i : σ} : pderiv R i 1 = 0 := pderiv_C |
| 128 | + |
| 129 | +theorem coeff_pderiv {i : σ} (f : MvPowerSeries σ R) (n : σ →₀ ℕ) : |
| 130 | + coeff n (pderiv R i f) = coeff (n + single i 1) f * (n i + 1) := |
| 131 | + coeff_pderivFun f n |
| 132 | + |
| 133 | +theorem pderiv_coe {i : σ} (f : MvPolynomial σ R) : |
| 134 | + pderiv R i f = MvPolynomial.pderiv i f := pderivFun_coe f |
| 135 | + |
| 136 | +@[simp] |
| 137 | +theorem pderiv_X_self {i : σ} : pderiv R i (X i) = 1 := by |
| 138 | + classical |
| 139 | + ext n |
| 140 | + simp only [coeff_pderiv, coeff_X, boole_mul, add_eq_right, coeff_one] |
| 141 | + split_ifs <;> simp_all |
| 142 | + |
| 143 | +@[simp] |
| 144 | +theorem pderiv_X_of_ne {i j : σ} (h : j ≠ i) : pderiv R i (X j) = 0 := by |
| 145 | + classical |
| 146 | + ext n |
| 147 | + simpa only [coeff_pderiv, coeff_X, boole_mul, coeff_zero] using |
| 148 | + if_neg (ne_iff.mpr ⟨i, by grind [Finsupp.add_apply]⟩) |
| 149 | + |
| 150 | +theorem pderiv_X [DecidableEq σ] (i j : σ) : |
| 151 | + pderiv R i (X j) = Pi.single (M := fun _ => MvPowerSeries σ R) i 1 j := by |
| 152 | + by_cases h : i = j |
| 153 | + · subst h; simp only [pderiv_X_self, Pi.single_eq_same] |
| 154 | + · grind [pderiv_X_of_ne] |
| 155 | + |
| 156 | +theorem trunc_pderiv [DecidableEq σ] {i : σ} (f : MvPowerSeries σ R) (n : σ →₀ ℕ) : |
| 157 | + trunc R n (pderiv R i f) = MvPolynomial.pderiv i (trunc R (n + single i 1) f) := |
| 158 | + trunc_pderivFun .. |
| 159 | + |
| 160 | +/-- The partial derivative of `g^n` equals `n * g^(n-1) * g'`. -/ |
| 161 | +theorem pderiv_pow {i : σ} (g : MvPowerSeries σ R) (n : ℕ) : |
| 162 | + pderiv R i (g ^ n) = n * g ^ (n - 1) * pderiv R i g := by |
| 163 | + rw [Derivation.leibniz_pow, smul_eq_mul, nsmul_eq_mul, mul_assoc] |
| 164 | + |
| 165 | +end CommSemiring |
| 166 | + |
| 167 | +/-- If `f` and `g` have the same constant term and all partial derivatives, then they are equal. |
| 168 | +
|
| 169 | +The `CommRing` assumption is needed because the proof uses `smul_right_inj`, which requires |
| 170 | +cancellation of addition in `R`; `IsAddTorsionFree` alone does not suffice. -/ |
| 171 | +theorem pderiv.ext [CommRing R] [IsAddTorsionFree R] {f g : MvPowerSeries σ R} |
| 172 | + (hD : ∀ i, pderiv R i f = pderiv R i g) (hc : constantCoeff f = constantCoeff g) : f = g := by |
| 173 | + ext n |
| 174 | + by_cases h : n = 0 |
| 175 | + · rw [h, coeff_zero_eq_constantCoeff, hc] |
| 176 | + obtain ⟨i, hi : n i ≠ 0⟩ := ne_iff.mp h |
| 177 | + have : single i 1 ≤ n := fun j ↦ by |
| 178 | + by_cases hj : j = i <;> grind [single_eq_same, single_eq_of_ne] |
| 179 | + have e := congr(coeff (n - single i 1) $(hD i)) |
| 180 | + rwa [coeff_pderiv, coeff_pderiv, tsub_add_cancel_of_le this, coe_tsub, Pi.sub_apply, |
| 181 | + single_eq_same, Nat.cast_sub (Nat.one_le_iff_ne_zero.mpr hi), Nat.cast_one, sub_add_cancel, |
| 182 | + mul_comm, ← nsmul_eq_mul, mul_comm, ← nsmul_eq_mul, smul_right_inj hi] at e |
| 183 | + |
| 184 | +@[simp] |
| 185 | +theorem pderiv_inv {i : σ} [CommRing R] (f : (MvPowerSeries σ R)ˣ) : |
| 186 | + pderiv R i ↑f⁻¹ = -(↑f⁻¹ : MvPowerSeries σ R) ^ 2 * pderiv R i f := |
| 187 | + (pderiv R i).leibniz_of_mul_eq_one f.inv_mul |
| 188 | + |
| 189 | +@[simp] |
| 190 | +theorem pderiv_invOf {i : σ} [CommRing R] (f : MvPowerSeries σ R) [Invertible f] : |
| 191 | + pderiv R i ⅟f = -⅟f ^ 2 * pderiv R i f := |
| 192 | + (pderiv R i).leibniz_invOf f |
| 193 | + |
| 194 | +/- |
| 195 | +The following theorem is stated only in the case that `R` is a field. This is because |
| 196 | +there is currently no instance of `Inv (MvPowerSeries σ R)` for more general base rings `R`. |
| 197 | +-/ |
| 198 | + |
| 199 | +@[simp] |
| 200 | +theorem pderiv_inv' {i : σ} [Field R] (f : MvPowerSeries σ R) : |
| 201 | + pderiv R i f⁻¹ = -f⁻¹ ^ 2 * pderiv R i f := by |
| 202 | + by_cases h : constantCoeff f = 0 |
| 203 | + · suffices f⁻¹ = 0 by |
| 204 | + rw [this, pow_two, zero_mul, neg_zero, zero_mul, map_zero] |
| 205 | + rwa [MvPowerSeries.inv_eq_zero] |
| 206 | + apply Derivation.leibniz_of_mul_eq_one |
| 207 | + exact MvPowerSeries.inv_mul_cancel (h := h) |
| 208 | + |
| 209 | +end MvPowerSeries |
0 commit comments