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

Commit 7691821

Browse files
committed
feat(data/polynomial/derivative): reduce assumptions (#14338)
The only changes here are to relax typeclass assumptions. Specifically these changes relax `comm_semiring` to `semiring` in: * polynomial.derivative_eval * polynomial.derivative_map * polynomial.iterate_derivative_map * polynomial.iterate_derivative_cast_nat_mul and relax `ring` to `semiring` as well as `char_zero` + `no_zero_divisors` to `no_zero_smul_divisors ℕ` in: * polynomial.mem_support_derivative * polynomial.degree_derivative_eq
1 parent 39184f4 commit 7691821

File tree

1 file changed

+58
-61
lines changed

1 file changed

+58
-61
lines changed

src/data/polynomial/derivative.lean

Lines changed: 58 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -222,15 +222,69 @@ calc derivative (f * g) = f.sum (λn a, g.sum (λm b, (n + m) • (C (a * b) * X
222222
simp_rw [← smul_mul_assoc, smul_C, nsmul_eq_mul'],
223223
end
224224

225+
lemma derivative_eval (p : R[X]) (x : R) :
226+
p.derivative.eval x = p.sum (λ n a, (a * n)*x^(n-1)) :=
227+
by simp_rw [derivative_apply, eval_sum, eval_mul_X_pow, eval_C]
228+
229+
@[simp]
230+
theorem derivative_map [semiring S] (p : R[X]) (f : R →+* S) :
231+
(p.map f).derivative = p.derivative.map f :=
232+
begin
233+
let n := max p.nat_degree ((map f p).nat_degree),
234+
rw [derivative_apply, derivative_apply],
235+
rw [sum_over_range' _ _ (n + 1) ((le_max_left _ _).trans_lt (lt_add_one _))],
236+
rw [sum_over_range' _ _ (n + 1) ((le_max_right _ _).trans_lt (lt_add_one _))],
237+
simp only [polynomial.map_sum, polynomial.map_mul, polynomial.map_C, map_mul, coeff_map,
238+
map_nat_cast, polynomial.map_nat_cast, polynomial.map_pow, map_X],
239+
all_goals { intro n, rw [zero_mul, C_0, zero_mul], }
240+
end
241+
242+
@[simp]
243+
theorem iterate_derivative_map [semiring S] (p : R[X]) (f : R →+* S) (k : ℕ):
244+
polynomial.derivative^[k] (p.map f) = (polynomial.derivative^[k] p).map f :=
245+
begin
246+
induction k with k ih generalizing p,
247+
{ simp, },
248+
{ simp only [ih, function.iterate_succ, polynomial.derivative_map, function.comp_app], },
249+
end
250+
251+
@[simp] lemma iterate_derivative_cast_nat_mul {n k : ℕ} {f : R[X]} :
252+
derivative^[k] (n * f) = n * (derivative^[k] f) :=
253+
by induction k with k ih generalizing f; simp*
254+
255+
lemma mem_support_derivative [no_zero_smul_divisors ℕ R]
256+
(p : R[X]) (n : ℕ) :
257+
n ∈ (derivative p).support ↔ n + 1 ∈ p.support :=
258+
suffices ¬p.coeff (n + 1) * (n + 1 : ℕ) = 0 ↔ coeff p (n + 1) ≠ 0,
259+
by simpa only [mem_support_iff, coeff_derivative, ne.def],
260+
by { rw [← nsmul_eq_mul', smul_eq_zero], simp only [nat.succ_ne_zero, false_or] }
261+
262+
@[simp] lemma degree_derivative_eq [no_zero_smul_divisors ℕ R]
263+
(p : R[X]) (hp : 0 < nat_degree p) :
264+
degree (derivative p) = (nat_degree p - 1 : ℕ) :=
265+
begin
266+
have h0 : p ≠ 0,
267+
{ contrapose! hp,
268+
simp [hp] },
269+
apply le_antisymm,
270+
{ rw derivative_apply,
271+
apply le_trans (degree_sum_le _ _) (sup_le (λ n hn, _)),
272+
apply le_trans (degree_C_mul_X_pow_le _ _) (with_bot.coe_le_coe.2 (tsub_le_tsub_right _ _)),
273+
apply le_nat_degree_of_mem_supp _ hn },
274+
{ refine le_sup _,
275+
rw [mem_support_derivative, tsub_add_cancel_of_le, mem_support_iff],
276+
{ show ¬ leading_coeff p = 0,
277+
rw [leading_coeff_eq_zero],
278+
assume h, rw [h, nat_degree_zero] at hp,
279+
exact lt_irrefl 0 (lt_of_le_of_lt (zero_le _) hp), },
280+
exact hp }
281+
end
282+
225283
end semiring
226284

227285
section comm_semiring
228286
variables [comm_semiring R]
229287

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-
234288
theorem derivative_pow_succ (p : R[X]) (n : ℕ) :
235289
(p ^ (n + 1)).derivative = (n + 1) * (p ^ n) * p.derivative :=
236290
nat.rec_on n (by rw [pow_one, nat.cast_zero, zero_add, one_mul, pow_zero, one_mul]) $ λ n ih,
@@ -255,28 +309,6 @@ begin
255309
simp only [mul_assoc], }
256310
end
257311

258-
@[simp]
259-
theorem derivative_map [comm_semiring S] (p : R[X]) (f : R →+* S) :
260-
(p.map f).derivative = p.derivative.map f :=
261-
polynomial.induction_on p
262-
(λ r, by rw [map_C, derivative_C, derivative_C, polynomial.map_zero])
263-
(λ p q ihp ihq, by rw [polynomial.map_add, derivative_add, ihp, ihq, derivative_add,
264-
polynomial.map_add])
265-
(λ n r ih, by rw [polynomial.map_mul, polynomial.map_C, polynomial.map_pow, polynomial.map_X,
266-
derivative_mul, derivative_pow_succ, derivative_C, zero_mul, zero_add, derivative_X, mul_one,
267-
derivative_mul, derivative_pow_succ, derivative_C, zero_mul, zero_add, derivative_X, mul_one,
268-
polynomial.map_mul, polynomial.map_C, polynomial.map_mul, polynomial.map_pow,
269-
polynomial.map_add, polynomial.map_nat_cast, polynomial.map_one, polynomial.map_X])
270-
271-
@[simp]
272-
theorem iterate_derivative_map [comm_semiring S] (p : R[X]) (f : R →+* S) (k : ℕ):
273-
polynomial.derivative^[k] (p.map f) = (polynomial.derivative^[k] p).map f :=
274-
begin
275-
induction k with k ih generalizing p,
276-
{ simp, },
277-
{ simp [ih], },
278-
end
279-
280312
/-- Chain rule for formal derivative of polynomials. -/
281313
theorem derivative_eval₂_C (p q : R[X]) :
282314
(p.eval₂ C q).derivative = p.derivative.eval₂ C q * q.derivative :=
@@ -305,10 +337,6 @@ begin
305337
{ simp [hij] }
306338
end
307339

308-
@[simp] lemma iterate_derivative_cast_nat_mul {n k : ℕ} {f : R[X]} :
309-
derivative^[k] (n * f) = n * (derivative^[k] f) :=
310-
by induction k with k ih generalizing f; simp*
311-
312340
end comm_semiring
313341

314342
section ring
@@ -358,36 +386,5 @@ end
358386

359387
end comm_ring
360388

361-
section no_zero_divisors
362-
variables [ring R] [no_zero_divisors R]
363-
364-
lemma mem_support_derivative [char_zero R] (p : R[X]) (n : ℕ) :
365-
n ∈ (derivative p).support ↔ n + 1 ∈ p.support :=
366-
suffices (¬(coeff p (n + 1) = 0 ∨ ((n + 1:ℕ) : R) = 0)) ↔ coeff p (n + 1) ≠ 0,
367-
by simpa only [mem_support_iff, coeff_derivative, ne.def, mul_eq_zero],
368-
by { rw [nat.cast_eq_zero], simp only [nat.succ_ne_zero, or_false] }
369-
370-
@[simp] lemma degree_derivative_eq [char_zero R] (p : R[X]) (hp : 0 < nat_degree p) :
371-
degree (derivative p) = (nat_degree p - 1 : ℕ) :=
372-
begin
373-
have h0 : p ≠ 0,
374-
{ contrapose! hp,
375-
simp [hp] },
376-
apply le_antisymm,
377-
{ rw derivative_apply,
378-
apply le_trans (degree_sum_le _ _) (sup_le (λ n hn, _)),
379-
apply le_trans (degree_C_mul_X_pow_le _ _) (with_bot.coe_le_coe.2 (tsub_le_tsub_right _ _)),
380-
apply le_nat_degree_of_mem_supp _ hn },
381-
{ refine le_sup _,
382-
rw [mem_support_derivative, tsub_add_cancel_of_le, mem_support_iff],
383-
{ show ¬ leading_coeff p = 0,
384-
rw [leading_coeff_eq_zero],
385-
assume h, rw [h, nat_degree_zero] at hp,
386-
exact lt_irrefl 0 (lt_of_le_of_lt (zero_le _) hp), },
387-
exact hp }
388-
end
389-
390-
end no_zero_divisors
391-
392389
end derivative
393390
end polynomial

0 commit comments

Comments
 (0)