|
| 1 | +/- |
| 2 | +Copyright (c) 2020 Jujian Zhang. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Jujian Zhang |
| 5 | +-/ |
| 6 | + |
| 7 | +import data.polynomial.derivative |
| 8 | +import logic.function.iterate |
| 9 | +import tactic.ring |
| 10 | +import tactic.linarith |
| 11 | + |
| 12 | +/-! |
| 13 | +# Theory of iterated derivative |
| 14 | +We define and prove some lemmas about iterated (formal) derivative for polynomials over a semiring. |
| 15 | +-/ |
| 16 | + |
| 17 | +noncomputable theory |
| 18 | + |
| 19 | +open finset nat polynomial |
| 20 | +open_locale big_operators |
| 21 | + |
| 22 | +namespace polynomial |
| 23 | +universes u |
| 24 | +variable {R : Type u} |
| 25 | + |
| 26 | +section semiring |
| 27 | + |
| 28 | +variables [semiring R] (r : R) (f p q : polynomial R) (n k : ℕ) |
| 29 | + |
| 30 | +/-- `iterated_deriv f n` is the `n`-th formal derivative of the polynomial `f` -/ |
| 31 | +def iterated_deriv : polynomial R := derivative ^[n] f |
| 32 | + |
| 33 | +@[simp] lemma iterated_deriv_zero_right : iterated_deriv f 0 = f := rfl |
| 34 | + |
| 35 | +lemma iterated_deriv_succ : iterated_deriv f (n + 1) = (iterated_deriv f n).derivative := |
| 36 | +by rw [iterated_deriv, iterated_deriv, function.iterate_succ'] |
| 37 | + |
| 38 | +@[simp] lemma iterated_deriv_zero_left : iterated_deriv (0 : polynomial R) n = 0 := |
| 39 | +begin |
| 40 | + induction n with n hn, |
| 41 | + { exact iterated_deriv_zero_right _ }, |
| 42 | + { rw [iterated_deriv_succ, hn, derivative_zero] }, |
| 43 | +end |
| 44 | + |
| 45 | +@[simp] lemma iterated_deriv_add : iterated_deriv (p + q) n = iterated_deriv p n + iterated_deriv q n := |
| 46 | +begin |
| 47 | + induction n with n ih, |
| 48 | + { simp only [iterated_deriv_zero_right], }, |
| 49 | + { simp only [iterated_deriv_succ, ih, derivative_add] } |
| 50 | +end |
| 51 | + |
| 52 | +@[simp] lemma iterated_deriv_smul : iterated_deriv (r • p) n = r • iterated_deriv p n := |
| 53 | +begin |
| 54 | + induction n with n ih, |
| 55 | + { simp only [iterated_deriv_zero_right] }, |
| 56 | + { simp only [iterated_deriv_succ, ih, derivative_smul] } |
| 57 | +end |
| 58 | + |
| 59 | +@[simp] lemma iterated_deriv_X_zero : iterated_deriv (X : polynomial R) 0 = X := |
| 60 | +by simp only [iterated_deriv_zero_right] |
| 61 | + |
| 62 | +@[simp] lemma iterated_deriv_X_one : iterated_deriv (X : polynomial R) 1 = 1 := |
| 63 | +by simp only [iterated_deriv, derivative_X, function.iterate_one] |
| 64 | + |
| 65 | +@[simp] lemma iterated_deriv_X (h : 1 < n) : iterated_deriv (X : polynomial R) n = 0 := |
| 66 | +begin |
| 67 | + induction n with n ih, |
| 68 | + { exfalso, exact not_lt_zero 1 h}, |
| 69 | + { simp only [iterated_deriv_succ], |
| 70 | + by_cases H : n = 1, |
| 71 | + { rw H, simp only [iterated_deriv_X_one, derivative_one] }, |
| 72 | + { replace h : 1 < n := array.push_back_idx h (ne.symm H), |
| 73 | + rw ih h, simp only [derivative_zero] } } |
| 74 | +end |
| 75 | + |
| 76 | + |
| 77 | +@[simp] lemma iterated_deriv_C_zero : iterated_deriv (C r) 0 = C r := |
| 78 | + by simp only [iterated_deriv_zero_right] |
| 79 | + |
| 80 | +@[simp] lemma iterated_deriv_C (h : 0 < n) : iterated_deriv (C r) n = 0 := |
| 81 | +begin |
| 82 | + induction n with n ih, |
| 83 | + { exfalso, exact nat.lt_asymm h h }, |
| 84 | + { by_cases H : n = 0, |
| 85 | + { rw [iterated_deriv_succ, H], simp only [iterated_deriv_C_zero, derivative_C]}, |
| 86 | + { replace h : 0 < n := nat.pos_of_ne_zero H, |
| 87 | + rw [iterated_deriv_succ, ih h], simp only [derivative_zero] } } |
| 88 | +end |
| 89 | + |
| 90 | +@[simp] lemma iterated_deriv_one_zero : iterated_deriv (1 : polynomial R) 0 = 1 := |
| 91 | +by simp only [iterated_deriv_zero_right] |
| 92 | + |
| 93 | +@[simp] lemma iterated_deriv_one : 0 < n → iterated_deriv (1 : polynomial R) n = 0 := λ h, |
| 94 | +begin |
| 95 | + have eq1 : (1 : polynomial R) = C 1 := by simp only [ring_hom.map_one], |
| 96 | + rw eq1, exact iterated_deriv_C _ _ h, |
| 97 | +end |
| 98 | + |
| 99 | +end semiring |
| 100 | + |
| 101 | +section ring |
| 102 | +variables [ring R] (p q : polynomial R) (n : ℕ) |
| 103 | + |
| 104 | +@[simp] lemma iterated_deriv_neg : iterated_deriv (-p) n = - iterated_deriv p n := |
| 105 | +begin |
| 106 | + induction n with n ih, |
| 107 | + { simp only [iterated_deriv_zero_right] }, |
| 108 | + { simp only [iterated_deriv_succ, ih, derivative_neg] } |
| 109 | +end |
| 110 | + |
| 111 | +@[simp] lemma iterated_deriv_sub : iterated_deriv (p - q) n = iterated_deriv p n - iterated_deriv q n := |
| 112 | +by rw [sub_eq_add_neg, iterated_deriv_add, iterated_deriv_neg, ←sub_eq_add_neg] |
| 113 | + |
| 114 | + |
| 115 | +end ring |
| 116 | + |
| 117 | +section comm_semiring |
| 118 | +variable [comm_semiring R] |
| 119 | +variables (f p q : polynomial R) (n k : ℕ) |
| 120 | + |
| 121 | +lemma coeff_iterated_deriv_as_prod_Ico : |
| 122 | + ∀ m : ℕ, (iterated_deriv f k).coeff m = (∏ i in Ico m.succ (m + k.succ), i) * (f.coeff (m+k)) := |
| 123 | +begin |
| 124 | + induction k with k ih, |
| 125 | + { simp only [add_zero, forall_const, one_mul, Ico.self_eq_empty, eq_self_iff_true, |
| 126 | + iterated_deriv_zero_right, prod_empty] }, |
| 127 | + { intro m, rw [iterated_deriv_succ, coeff_derivative, ih (m+1), mul_right_comm], |
| 128 | + apply congr_arg2, |
| 129 | + { have set_eq : (Ico m.succ (m + k.succ.succ)) = (Ico (m + 1).succ (m + 1 + k.succ)) ∪ {m+1}, |
| 130 | + { rw [union_comm, ←insert_eq, Ico.insert_succ_bot, add_succ, add_succ, add_succ _ k, |
| 131 | + ←succ_eq_add_one, succ_add], |
| 132 | + rw succ_eq_add_one, |
| 133 | + linarith }, |
| 134 | + rw [set_eq, prod_union], |
| 135 | + apply congr_arg2, |
| 136 | + { refl }, |
| 137 | + { simp only [prod_singleton], norm_cast }, |
| 138 | + { simp only [succ_pos', disjoint_singleton, and_true, lt_add_iff_pos_right, not_le, Ico.mem], |
| 139 | + exact lt_add_one (m + 1) } }, |
| 140 | + { exact congr_arg _ (succ_add m k) } }, |
| 141 | +end |
| 142 | + |
| 143 | +lemma coeff_iterated_deriv_as_prod_range : |
| 144 | + ∀ m : ℕ, (iterated_deriv f k).coeff m = f.coeff (m + k) * (∏ i in finset.range k, ↑(m + k - i)) := |
| 145 | +begin |
| 146 | + induction k with k ih, |
| 147 | + { simp }, |
| 148 | + |
| 149 | + intro m, |
| 150 | + calc (f.iterated_deriv k.succ).coeff m |
| 151 | + = f.coeff (m + k.succ) * (∏ i in finset.range k, ↑(m + k.succ - i)) * (m + 1) : |
| 152 | + by rw [iterated_deriv_succ, coeff_derivative, ih m.succ, succ_add, add_succ] |
| 153 | + ... = f.coeff (m + k.succ) * (↑(m + 1) * (∏ (i : ℕ) in range k, ↑(m + k.succ - i))) : |
| 154 | + by { push_cast, ring } |
| 155 | + ... = f.coeff (m + k.succ) * (∏ (i : ℕ) in range k.succ, ↑(m + k.succ - i)) : |
| 156 | + by { rw [prod_range_succ, nat.add_sub_assoc (le_succ k), nat.succ_sub le_rfl, nat.sub_self] } |
| 157 | +end |
| 158 | + |
| 159 | +lemma iterated_deriv_eq_zero_of_nat_degree_lt (h : f.nat_degree < n) : iterated_deriv f n = 0 := |
| 160 | +begin |
| 161 | + ext m, |
| 162 | + rw [coeff_iterated_deriv_as_prod_range, coeff_zero, coeff_eq_zero_of_nat_degree_lt, zero_mul], |
| 163 | + linarith |
| 164 | +end |
| 165 | + |
| 166 | +lemma iterated_deriv_mul : |
| 167 | + iterated_deriv (p * q) n = |
| 168 | + ∑ k in range n.succ, |
| 169 | + (C (n.choose k : R)) * iterated_deriv p (n - k) * iterated_deriv q k := |
| 170 | +begin |
| 171 | + induction n with n IH, |
| 172 | + { simp }, |
| 173 | + |
| 174 | + calc (p * q).iterated_deriv n.succ |
| 175 | + = (∑ (k : ℕ) in range n.succ, |
| 176 | + C ↑(n.choose k) * p.iterated_deriv (n - k) * q.iterated_deriv k).derivative : |
| 177 | + by rw [iterated_deriv_succ, IH] |
| 178 | + ... = ∑ (k : ℕ) in range n.succ, |
| 179 | + C ↑(n.choose k) * p.iterated_deriv (n - k + 1) * q.iterated_deriv k + |
| 180 | + ∑ (k : ℕ) in range n.succ, |
| 181 | + C ↑(n.choose k) * p.iterated_deriv (n - k) * q.iterated_deriv (k + 1) : |
| 182 | + by simp_rw [derivative_sum, derivative_mul, derivative_C, zero_mul, zero_add, |
| 183 | + iterated_deriv_succ, sum_add_distrib] |
| 184 | + ... = (∑ (k : ℕ) in range n.succ, |
| 185 | + C ↑(n.choose k.succ) * p.iterated_deriv (n - k) * q.iterated_deriv (k + 1) + |
| 186 | + C ↑1 * p.iterated_deriv n.succ * q.iterated_deriv 0) + |
| 187 | + ∑ (k : ℕ) in range n.succ, |
| 188 | + C ↑(n.choose k) * p.iterated_deriv (n - k) * q.iterated_deriv (k + 1) : _ |
| 189 | + ... = ∑ (k : ℕ) in range n.succ, |
| 190 | + C ↑(n.choose k) * p.iterated_deriv (n - k) * q.iterated_deriv (k + 1) + |
| 191 | + ∑ (k : ℕ) in range n.succ, |
| 192 | + C ↑(n.choose k.succ) * p.iterated_deriv (n - k) * q.iterated_deriv (k + 1) + |
| 193 | + C ↑1 * p.iterated_deriv n.succ * q.iterated_deriv 0 : |
| 194 | + by ring |
| 195 | + ... = ∑ (i : ℕ) in range n.succ, |
| 196 | + C ↑(n.succ.choose (i + 1)) * p.iterated_deriv (n + 1 - (i + 1)) * q.iterated_deriv (i + 1) + |
| 197 | + C ↑1 * p.iterated_deriv n.succ * q.iterated_deriv 0 : |
| 198 | + by simp_rw [choose_succ_succ, succ_sub_succ, cast_add, C.map_add, add_mul, sum_add_distrib] |
| 199 | + ... = ∑ (k : ℕ) in range n.succ.succ, |
| 200 | + C ↑(n.succ.choose k) * p.iterated_deriv (n.succ - k) * q.iterated_deriv k : |
| 201 | + by rw [sum_range_succ' _ n.succ, choose_zero_right, nat.sub_zero], |
| 202 | + |
| 203 | + congr, |
| 204 | + refine (sum_range_succ' _ _).trans (congr_arg2 (+) _ _), |
| 205 | + { rw [sum_range_succ, nat.choose_succ_self, cast_zero, C.map_zero, zero_mul, zero_mul, zero_add], |
| 206 | + refine sum_congr rfl (λ k hk, _), |
| 207 | + rw mem_range at hk, |
| 208 | + congr, |
| 209 | + rw [← nat.sub_add_comm (nat.succ_le_of_lt hk), nat.succ_sub_succ] }, |
| 210 | + { rw [choose_zero_right, nat.sub_zero] }, |
| 211 | +end |
| 212 | + |
| 213 | +end comm_semiring |
| 214 | + |
| 215 | +end polynomial |
0 commit comments