File: Mathlib/RingTheory/Polynomial/Bernstein.lean

full_name: bernsteinPolynomial
code: /-- `bernsteinPolynomial R n ν` is `(choose n ν) * X^ν * (1 - X)^(n - ν)`.

Although the coefficients are integers, it is convenient to work over an arbitrary commutative ring.
-/
def bernsteinPolynomial (n ν : ℕ) : R[X] 
goal: R[X]

full_name: bernsteinPolynomial.eq_zero_of_lt
code: theorem eq_zero_of_lt {n ν : ℕ} (h : n < ν) : bernsteinPolynomial R n ν = 0 
goal: bernsteinPolynomial R n ν = 0

full_name: bernsteinPolynomial.map
code: @[simp]
theorem map (f : R →+* S) (n ν : ℕ) :
    (bernsteinPolynomial R n ν).map f = bernsteinPolynomial S n ν 
goal: Polynomial.map f (bernsteinPolynomial R n ν) = bernsteinPolynomial S n ν

full_name: bernsteinPolynomial.flip
code: theorem flip (n ν : ℕ) (h : ν ≤ n) :
    (bernsteinPolynomial R n ν).comp (1 - X) = bernsteinPolynomial R n (n - ν) 
goal: (bernsteinPolynomial R n ν).comp (1 - Polynomial.X) = bernsteinPolynomial R n (n - ν)

full_name: bernsteinPolynomial.flip'
code: theorem flip' (n ν : ℕ) (h : ν ≤ n) :
    bernsteinPolynomial R n ν = (bernsteinPolynomial R n (n - ν)).comp (1 - X) 
goal: bernsteinPolynomial R n ν = (bernsteinPolynomial R n (n - ν)).comp (1 - Polynomial.X)

full_name: bernsteinPolynomial.eval_at_0
code: theorem eval_at_0 (n ν : ℕ) : (bernsteinPolynomial R n ν).eval 0 = if ν = 0 then 1 else 0 
goal: Polynomial.eval 0 (bernsteinPolynomial R n ν) = if ν = 0 then 1 else 0

full_name: bernsteinPolynomial.eval_at_1
code: theorem eval_at_1 (n ν : ℕ) : (bernsteinPolynomial R n ν).eval 1 = if ν = n then 1 else 0 
goal: Polynomial.eval 1 (bernsteinPolynomial R n ν) = if ν = n then 1 else 0

full_name: bernsteinPolynomial.derivative_succ_aux
code: theorem derivative_succ_aux (n ν : ℕ) :
    Polynomial.derivative (bernsteinPolynomial R (n + 1) (ν + 1)) =
      (n + 1) * (bernsteinPolynomial R n ν - bernsteinPolynomial R n (ν + 1)) 
goal: Polynomial.derivative (bernsteinPolynomial R (n + 1) (ν + 1)) =
  (↑n + 1) * (bernsteinPolynomial R n ν - bernsteinPolynomial R n (ν + 1))

full_name: bernsteinPolynomial.derivative_succ
code: theorem derivative_succ (n ν : ℕ) : Polynomial.derivative (bernsteinPolynomial R n (ν + 1)) =
    n * (bernsteinPolynomial R (n - 1) ν - bernsteinPolynomial R (n - 1) (ν + 1)) 
goal: Polynomial.derivative (bernsteinPolynomial R n (ν + 1)) =
  ↑n * (bernsteinPolynomial R (n - 1) ν - bernsteinPolynomial R (n - 1) (ν + 1))

full_name: bernsteinPolynomial.derivative_zero
code: theorem derivative_zero (n : ℕ) :
    Polynomial.derivative (bernsteinPolynomial R n 0) = -n * bernsteinPolynomial R (n - 1) 0 
goal: Polynomial.derivative (bernsteinPolynomial R n 0) = -↑n * bernsteinPolynomial R (n - 1) 0

full_name: bernsteinPolynomial.iterate_derivative_at_0_eq_zero_of_lt
code: theorem iterate_derivative_at_0_eq_zero_of_lt (n : ℕ) {ν k : ℕ} :
    k < ν → (Polynomial.derivative^[k] (bernsteinPolynomial R n ν)).eval 0 = 0 
goal: k < ν → Polynomial.eval 0 ((⇑Polynomial.derivative)^[k] (bernsteinPolynomial R n ν)) = 0

full_name: bernsteinPolynomial.iterate_derivative_succ_at_0_eq_zero
code: @[simp]
theorem iterate_derivative_succ_at_0_eq_zero (n ν : ℕ) :
    (Polynomial.derivative^[ν] (bernsteinPolynomial R n (ν + 1))).eval 0 = 0 
goal: Polynomial.eval 0 ((⇑Polynomial.derivative)^[ν] (bernsteinPolynomial R n (ν + 1))) = 0

full_name: bernsteinPolynomial.iterate_derivative_at_0
code: @[simp]
theorem iterate_derivative_at_0 (n ν : ℕ) :
    (Polynomial.derivative^[ν] (bernsteinPolynomial R n ν)).eval 0 =
      (ascPochhammer R ν).eval ((n - (ν - 1) : ℕ) : R) 
goal: Polynomial.eval 0 ((⇑Polynomial.derivative)^[ν] (bernsteinPolynomial R n ν)) =
  Polynomial.eval (↑(n - (ν - 1))) (ascPochhammer R ν)

full_name: bernsteinPolynomial.iterate_derivative_at_0_ne_zero
code: theorem iterate_derivative_at_0_ne_zero [CharZero R] (n ν : ℕ) (h : ν ≤ n) :
    (Polynomial.derivative^[ν] (bernsteinPolynomial R n ν)).eval 0 ≠ 0 
goal: Polynomial.eval 0 ((⇑Polynomial.derivative)^[ν] (bernsteinPolynomial R n ν)) ≠ 0

full_name: bernsteinPolynomial.iterate_derivative_at_1_eq_zero_of_lt
code: theorem iterate_derivative_at_1_eq_zero_of_lt (n : ℕ) {ν k : ℕ} :
    k < n - ν → (Polynomial.derivative^[k] (bernsteinPolynomial R n ν)).eval 1 = 0 
goal: k < n - ν → Polynomial.eval 1 ((⇑Polynomial.derivative)^[k] (bernsteinPolynomial R n ν)) = 0

full_name: bernsteinPolynomial.iterate_derivative_at_1
code: @[simp]
theorem iterate_derivative_at_1 (n ν : ℕ) (h : ν ≤ n) :
    (Polynomial.derivative^[n - ν] (bernsteinPolynomial R n ν)).eval 1 =
      (-1) ^ (n - ν) * (ascPochhammer R (n - ν)).eval (ν + 1 : R) 
goal: Polynomial.eval 1 ((⇑Polynomial.derivative)^[n - ν] (bernsteinPolynomial R n ν)) =
  (-1) ^ (n - ν) * Polynomial.eval (↑ν + 1) (ascPochhammer R (n - ν))

full_name: bernsteinPolynomial.iterate_derivative_at_1_ne_zero
code: theorem iterate_derivative_at_1_ne_zero [CharZero R] (n ν : ℕ) (h : ν ≤ n) :
    (Polynomial.derivative^[n - ν] (bernsteinPolynomial R n ν)).eval 1 ≠ 0 
goal: Polynomial.eval 1 ((⇑Polynomial.derivative)^[n - ν] (bernsteinPolynomial R n ν)) ≠ 0

full_name: bernsteinPolynomial.linearIndependent_aux
code: theorem linearIndependent_aux (n k : ℕ) (h : k ≤ n + 1) :
    LinearIndependent ℚ fun ν : Fin k => bernsteinPolynomial ℚ n ν 
goal: LinearIndependent ℚ fun ν => bernsteinPolynomial ℚ n ↑ν

full_name: bernsteinPolynomial.linearIndependent
code: /-- The Bernstein polynomials are linearly independent.

We prove by induction that the collection of `bernsteinPolynomial n ν` for `ν = 0, ..., k`
are linearly independent.
The inductive step relies on the observation that the `(n-k)`-th derivative, evaluated at 1,
annihilates `bernsteinPolynomial n ν` for `ν < k`, but has a nonzero value at `ν = k`.
-/
theorem linearIndependent (n : ℕ) :
    LinearIndependent ℚ fun ν : Fin (n + 1) => bernsteinPolynomial ℚ n ν 
goal: LinearIndependent ℚ fun ν => bernsteinPolynomial ℚ n ↑ν

full_name: bernsteinPolynomial.sum
code: theorem sum (n : ℕ) : (∑ ν ∈ Finset.range (n + 1), bernsteinPolynomial R n ν) = 1 
goal: ∑ ν ∈ Finset.range (n + 1), bernsteinPolynomial R n ν = 1

full_name: bernsteinPolynomial.sum_smul
code: theorem sum_smul (n : ℕ) :
    (∑ ν ∈ Finset.range (n + 1), ν • bernsteinPolynomial R n ν) = n • X 
goal: ∑ ν ∈ Finset.range (n + 1), ν • bernsteinPolynomial R n ν = n • Polynomial.X

full_name: bernsteinPolynomial.sum_mul_smul
code: theorem sum_mul_smul (n : ℕ) :
    (∑ ν ∈ Finset.range (n + 1), (ν * (ν - 1)) • bernsteinPolynomial R n ν) =
      (n * (n - 1)) • X ^ 2 
goal: ∑ ν ∈ Finset.range (n + 1), (ν * (ν - 1)) • bernsteinPolynomial R n ν = (n * (n - 1)) • Polynomial.X ^ 2

full_name: bernsteinPolynomial.variance
code: /-- A certain linear combination of the previous three identities,
which we'll want later.
-/
theorem variance (n : ℕ) :
    (∑ ν ∈ Finset.range (n + 1), (n • Polynomial.X - (ν : R[X])) ^ 2 * bernsteinPolynomial R n ν) =
      n • Polynomial.X * ((1 : R[X]) - Polynomial.X) 
goal: ∑ ν ∈ Finset.range (n + 1), (n • Polynomial.X - ↑ν) ^ 2 * bernsteinPolynomial R n ν =
  n • Polynomial.X * (1 - Polynomial.X)