Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit c30131f

Browse files
committed
feat(data/polynomial/{derivative, iterated_deriv}): reduce assumptions (#13368)
1 parent 761801f commit c30131f

File tree

2 files changed

+80
-90
lines changed

2 files changed

+80
-90
lines changed

src/data/polynomial/derivative.lean

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -109,27 +109,25 @@ derivative.to_add_monoid_hom.iterate_map_add _ _ _
109109
derivative (∑ b in s, f b) = ∑ b in s, derivative (f b) :=
110110
derivative.map_sum
111111

112-
@[simp] lemma derivative_smul (r : R) (p : R[X]) : derivative (r • p) = r • derivative p :=
113-
derivative.map_smul _ _
114-
115-
@[simp] lemma iterate_derivative_smul (r : R) (p : R[X]) (k : ℕ) :
116-
derivative^[k] (r • p) = r • (derivative^[k] p) :=
112+
@[simp] lemma derivative_smul {S : Type*} [monoid S]
113+
[distrib_mul_action S R] [is_scalar_tower S R R]
114+
(s : S) (p : R[X]) : derivative (s • p) = s • derivative p :=
115+
derivative.map_smul_of_tower s p
116+
117+
@[simp] lemma iterate_derivative_smul {S : Type*} [monoid S]
118+
[distrib_mul_action S R] [is_scalar_tower S R R]
119+
(s : S) (p : R[X]) (k : ℕ) :
120+
derivative^[k] (s • p) = s • (derivative^[k] p) :=
117121
begin
118122
induction k with k ih generalizing p,
119123
{ simp, },
120124
{ simp [ih], },
121125
end
122126

123-
/- We can't use `derivative_mul` here because
124-
we want to prove this statement also for noncommutative rings.-/
125-
@[simp]
126-
lemma derivative_C_mul (a : R) (p : R[X]) : derivative (C a * p) = C a * derivative p :=
127-
by convert derivative_smul a p; apply C_mul'
128-
129127
@[simp]
130128
lemma iterate_derivative_C_mul (a : R) (p : R[X]) (k : ℕ) :
131129
derivative^[k] (C a * p) = C a * (derivative^[k] p) :=
132-
by convert iterate_derivative_smul a p k; apply C_mul'
130+
by simp_rw [← smul_eq_C_mul, iterate_derivative_smul]
133131

134132
theorem of_mem_support_derivative {p : R[X]} {n : ℕ} (h : n ∈ p.derivative.support) :
135133
n + 1 ∈ p.support :=
@@ -197,42 +195,42 @@ begin
197195
exact hf h2
198196
end
199197

200-
end semiring
201-
202-
section comm_semiring
203-
variables [comm_semiring R]
204-
205-
lemma derivative_eval (p : R[X]) (x : R) :
206-
p.derivative.eval x = p.sum (λ n a, (a * n)*x^(n-1)) :=
207-
by simp only [derivative_apply, eval_sum, eval_pow, eval_C, eval_X, eval_nat_cast, eval_mul]
208-
209198
@[simp] lemma derivative_mul {f g : R[X]} :
210199
derivative (f * g) = derivative f * g + f * derivative g :=
211-
calc derivative (f * g) = f.sum (λn a, g.sum (λm b, C ((a * b) * (n + m : ℕ)) * X^((n + m) - 1))) :
200+
calc derivative (f * g) = f.sum (λn a, g.sum (λm b, (n + m) • (C (a * b) * X^((n + m) - 1)))) :
212201
begin
213202
rw mul_eq_sum_sum,
214203
transitivity, exact derivative_sum,
215204
transitivity, { apply finset.sum_congr rfl, assume x hx, exact derivative_sum },
216205
apply finset.sum_congr rfl, assume n hn, apply finset.sum_congr rfl, assume m hm,
217206
transitivity,
218207
{ apply congr_arg, exact monomial_eq_C_mul_X },
219-
exact derivative_C_mul_X_pow _ _
208+
dsimp, rw [← smul_mul_assoc, smul_C, nsmul_eq_mul'], exact derivative_C_mul_X_pow _ _
220209
end
221210
... = f.sum (λn a, g.sum (λm b,
222-
(C (a * n) * X^(n - 1)) * (C b * X^m) + (C a * X^n) * (C (b * m) * X^(m - 1)))) :
211+
(n • (C a * X^(n - 1))) * (C b * X^m) + (C a * X^n) * (m • (C b * X^(m - 1))))) :
223212
sum_congr rfl $ assume n hn, sum_congr rfl $ assume m hm,
224-
by simp only [nat.cast_add, mul_add, add_mul, C_add, C_mul];
225-
cases n; simp only [nat.succ_sub_succ, pow_zero];
226-
cases m; simp only [nat.cast_zero, C_0, nat.succ_sub_succ, zero_mul, mul_zero, nat.add_succ,
227-
tsub_zero, pow_zero, pow_add, one_mul, pow_succ, mul_comm, mul_left_comm]
213+
by cases n; cases m; simp_rw [add_smul, mul_smul_comm, smul_mul_assoc,
214+
X_pow_mul_assoc, ← mul_assoc, ← C_mul, mul_assoc, ← pow_add];
215+
simp only [nat.add_succ, nat.succ_add, nat.succ_sub_one, zero_smul, add_comm]
228216
... = derivative f * g + f * derivative g :
229217
begin
230218
conv { to_rhs, congr,
231219
{ rw [← sum_C_mul_X_eq g] },
232220
{ rw [← sum_C_mul_X_eq f] } },
233-
simp only [sum, sum_add_distrib, finset.mul_sum, finset.sum_mul, derivative_apply]
221+
simp only [sum, sum_add_distrib, finset.mul_sum, finset.sum_mul, derivative_apply],
222+
simp_rw [← smul_mul_assoc, smul_C, nsmul_eq_mul'],
234223
end
235224

225+
end semiring
226+
227+
section comm_semiring
228+
variables [comm_semiring R]
229+
230+
lemma derivative_eval (p : R[X]) (x : R) :
231+
p.derivative.eval x = p.sum (λ n a, (a * n)*x^(n-1)) :=
232+
by simp only [derivative_apply, eval_sum, eval_pow, eval_C, eval_X, eval_nat_cast, eval_mul]
233+
236234
theorem derivative_pow_succ (p : R[X]) (n : ℕ) :
237235
(p ^ (n + 1)).derivative = (n + 1) * (p ^ n) * p.derivative :=
238236
nat.rec_on n (by rw [pow_one, nat.cast_zero, zero_add, one_mul, pow_zero, one_mul]) $ λ n ih,

src/data/polynomial/iterated_deriv.lean

Lines changed: 53 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ begin
4949
{ simp only [iterated_deriv_succ, ih, derivative_add] }
5050
end
5151

52-
@[simp] lemma iterated_deriv_smul : iterated_deriv (r • p) n = r • iterated_deriv p n :=
52+
@[simp] lemma iterated_deriv_smul {S : Type*} [monoid S]
53+
[distrib_mul_action S R] [is_scalar_tower S R R]
54+
(s : S) : iterated_deriv (s • p) n = s • iterated_deriv p n :=
5355
begin
5456
induction n with n ih,
5557
{ simp only [iterated_deriv_zero_right] },
@@ -96,120 +98,110 @@ begin
9698
rw eq1, exact iterated_deriv_C _ _ h,
9799
end
98100

99-
end semiring
100-
101-
section ring
102-
variables [ring R] (p q : R[X]) (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 :
112-
iterated_deriv (p - q) n = iterated_deriv p n - iterated_deriv q n :=
113-
by rw [sub_eq_add_neg, iterated_deriv_add, iterated_deriv_neg, ←sub_eq_add_neg]
114-
115-
116-
end ring
117-
118-
section comm_semiring
119-
variable [comm_semiring R]
120-
variables (f p q : R[X]) (n k : ℕ)
121-
122101
lemma coeff_iterated_deriv_as_prod_Ico :
123-
∀ m : ℕ, (iterated_deriv f k).coeff m = (∏ i in Ico m.succ (m + k.succ), i) * (f.coeff (m+k)) :=
102+
∀ m : ℕ, (iterated_deriv f k).coeff m = (∏ i in Ico m.succ (m + k.succ), i) (f.coeff (m+k)) :=
124103
begin
125104
induction k with k ih,
126-
{ simp only [add_zero, forall_const, one_mul, Ico_self, eq_self_iff_true,
105+
{ simp only [add_zero, forall_const, one_smul, Ico_self, eq_self_iff_true,
127106
iterated_deriv_zero_right, prod_empty] },
128-
{ intro m, rw [iterated_deriv_succ, coeff_derivative, ih (m+1), mul_right_comm],
107+
{ intro m, rw [iterated_deriv_succ, coeff_derivative, ih (m+1), ← nat.cast_add_one,
108+
← nsmul_eq_mul', smul_smul, mul_comm],
129109
apply congr_arg2,
130110
{ have set_eq : (Ico m.succ (m + k.succ.succ)) = (Ico (m + 1).succ (m + 1 + k.succ)) ∪ {m+1},
131-
{ rw [union_comm, ←insert_eq, Ico_insert_succ_left, add_succ, add_succ, add_succ _ k,
132-
←succ_eq_add_one, succ_add],
133-
rw succ_eq_add_one,
134-
linarith },
135-
rw [set_eq, prod_union],
136-
apply congr_arg2,
137-
{ refl },
138-
{ simp only [prod_singleton], norm_cast },
111+
{ simp_rw [← Ico_succ_singleton, union_comm, succ_eq_add_one, add_comm (k + 1), add_assoc],
112+
rw [Ico_union_Ico_eq_Ico]; simp_rw [add_le_add_iff_left, le_add_self], },
113+
rw [set_eq, prod_union, prod_singleton],
139114
{ rw [disjoint_singleton_right, mem_Ico],
140115
exact λ h, (nat.lt_succ_self _).not_le h.1 } },
141116
{ exact congr_arg _ (succ_add m k) } },
142117
end
143118

144119
lemma coeff_iterated_deriv_as_prod_range :
145-
∀ m : ℕ, (iterated_deriv f k).coeff m = f.coeff (m + k) * (∏ i in range k, (m + k - i)) :=
120+
∀ m : ℕ, (iterated_deriv f k).coeff m = (∏ i in range k, (m + k - i)) • f.coeff (m + k) :=
146121
begin
147122
induction k with k ih,
148123
{ simp },
149124
intro m,
150125
calc (f.iterated_deriv k.succ).coeff m
151-
= f.coeff (m + k.succ) * (∏ i in range k, (m + k.succ - i)) * (m + 1) :
126+
= (∏ i in range k, (m + k.succ - i)) • f.coeff (m + k.succ) * (m + 1) :
152127
by rw [iterated_deriv_succ, coeff_derivative, ih m.succ, succ_add, add_succ]
153-
... = f.coeff (m + k.succ) * (∏ i in range k, (m + k.succ - i)) * (m + 1) :
154-
by push_cast
155-
... = f.coeff (m + k.succ) * (∏ i in range k.succ, (m + k.succ - i)) :
156-
by rw [prod_range_succ, add_tsub_assoc_of_le k.le_succ, succ_sub le_rfl, tsub_self, mul_assoc]
128+
... = ((∏ i in range k, (m + k.succ - i)) * (m + 1)) • f.coeff (m + k.succ) :
129+
by rw [← nat.cast_add_one, ← nsmul_eq_mul', smul_smul, mul_comm]
130+
... = (∏ i in range k.succ, (m + k.succ - i)) • f.coeff (m + k.succ) :
131+
by rw [prod_range_succ, add_tsub_assoc_of_le k.le_succ, succ_sub le_rfl, tsub_self]
157132
end
158133

159134
lemma iterated_deriv_eq_zero_of_nat_degree_lt (h : f.nat_degree < n) : iterated_deriv f n = 0 :=
160135
begin
161136
ext m,
162-
rw [coeff_iterated_deriv_as_prod_range, coeff_zero, coeff_eq_zero_of_nat_degree_lt, zero_mul],
137+
rw [coeff_iterated_deriv_as_prod_range, coeff_zero, coeff_eq_zero_of_nat_degree_lt, smul_zero],
163138
linarith
164139
end
165140

166141
lemma iterated_deriv_mul :
167142
iterated_deriv (p * q) n =
168143
∑ k in range n.succ,
169-
(C (n.choose k : R)) * iterated_deriv p (n - k) * iterated_deriv q k :=
144+
n.choose k • (iterated_deriv p (n - k) * iterated_deriv q k) :=
170145
begin
171146
induction n with n IH,
172147
{ simp },
173148

174149
calc (p * q).iterated_deriv n.succ
175150
= (∑ (k : ℕ) in range n.succ,
176-
C ↑(n.choose k) * p.iterated_deriv (n - k) * q.iterated_deriv k).derivative :
151+
(n.choose k) • (p.iterated_deriv (n - k) * q.iterated_deriv k)).derivative :
177152
by rw [iterated_deriv_succ, IH]
178153
... = ∑ (k : ℕ) in range n.succ,
179-
C ↑(n.choose k) * p.iterated_deriv (n - k + 1) * q.iterated_deriv k +
154+
(n.choose k) • (p.iterated_deriv (n - k + 1) * q.iterated_deriv k) +
180155
∑ (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]
156+
(n.choose k) • (p.iterated_deriv (n - k) * q.iterated_deriv (k + 1)) :
157+
by simp_rw [derivative_sum, derivative_smul, derivative_mul, iterated_deriv_succ, smul_add,
158+
sum_add_distrib]
184159
... = (∑ (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) +
160+
(n.choose k.succ) • (p.iterated_deriv (n - k) * q.iterated_deriv (k + 1)) +
161+
1 • (p.iterated_deriv n.succ * q.iterated_deriv 0)) +
187162
∑ (k : ℕ) in range n.succ,
188-
C ↑(n.choose k) * p.iterated_deriv (n - k) * q.iterated_deriv (k + 1) : _
163+
(n.choose k) • (p.iterated_deriv (n - k) * q.iterated_deriv (k + 1)) : _
189164
... = ∑ (k : ℕ) in range n.succ,
190-
C ↑(n.choose k) * p.iterated_deriv (n - k) * q.iterated_deriv (k + 1) +
165+
(n.choose k) • (p.iterated_deriv (n - k) * q.iterated_deriv (k + 1)) +
191166
∑ (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
167+
(n.choose k.succ) • (p.iterated_deriv (n - k) * q.iterated_deriv (k + 1)) +
168+
1 • (p.iterated_deriv n.succ * q.iterated_deriv 0) :
169+
by rw [add_comm, add_assoc]
195170
... = ∑ (i : ℕ) in range n.succ,
196-
C ↑((n+1).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]
171+
((n+1).choose (i+1)) • (p.iterated_deriv (n + 1 - (i+1)) * q.iterated_deriv (i+1)) +
172+
1 • (p.iterated_deriv n.succ * q.iterated_deriv 0) :
173+
by simp_rw [choose_succ_succ, succ_sub_succ, add_smul, sum_add_distrib]
199174
... = ∑ (k : ℕ) in range n.succ.succ,
200-
C ↑(n.succ.choose k) * p.iterated_deriv (n.succ - k) * q.iterated_deriv k :
175+
(n.succ.choose k) • (p.iterated_deriv (n.succ - k) * q.iterated_deriv k) :
201176
by rw [sum_range_succ' _ n.succ, choose_zero_right, tsub_zero],
202177

203178
congr,
204179
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, add_zero],
180+
{ rw [sum_range_succ, nat.choose_succ_self, zero_smul, add_zero],
206181
refine sum_congr rfl (λ k hk, _),
207182
rw mem_range at hk,
208183
congr,
209184
rw [tsub_add_eq_add_tsub (nat.succ_le_of_lt hk), nat.succ_sub_succ] },
210185
{ rw [choose_zero_right, tsub_zero] },
211186
end
212187

213-
end comm_semiring
188+
end semiring
189+
190+
section ring
191+
variables [ring R] (p q : R[X]) (n : ℕ)
192+
193+
@[simp] lemma iterated_deriv_neg : iterated_deriv (-p) n = - iterated_deriv p n :=
194+
begin
195+
induction n with n ih,
196+
{ simp only [iterated_deriv_zero_right] },
197+
{ simp only [iterated_deriv_succ, ih, derivative_neg] }
198+
end
199+
200+
@[simp] lemma iterated_deriv_sub :
201+
iterated_deriv (p - q) n = iterated_deriv p n - iterated_deriv q n :=
202+
by rw [sub_eq_add_neg, iterated_deriv_add, iterated_deriv_neg, ←sub_eq_add_neg]
203+
204+
205+
end ring
214206

215207
end polynomial

0 commit comments

Comments
 (0)