File: Mathlib/Algebra/LinearRecurrence.lean

full_name: LinearRecurrence.coeffs
code: /-- A "linear recurrence relation" over a commutative semiring is given by its
  order `n` and `n` coefficients. -/
structure LinearRecurrence (α : Type*) [CommSemiring α] where
  order : ℕ
  coeffs : Fin order → α
goal: Fin self.order → α

full_name: LinearRecurrence
code: /-- A "linear recurrence relation" over a commutative semiring is given by its
  order `n` and `n` coefficients. -/
structure LinearRecurrence (α : Type*) [CommSemiring α] where
  order : ℕ
  coeffs : Fin order → α
goal: Type u_1

full_name: LinearRecurrence.order
code: /-- A "linear recurrence relation" over a commutative semiring is given by its
  order `n` and `n` coefficients. -/
structure LinearRecurrence (α : Type*) [CommSemiring α] where
  order : ℕ
  coeffs : Fin order → α
goal: ℕ

full_name: instInhabitedLinearRecurrence
code: instance (α : Type*) [CommSemiring α] : Inhabited (LinearRecurrence α) 
goal: Inhabited (LinearRecurrence α)

full_name: LinearRecurrence.IsSolution
code: /-- We say that a sequence `u` is solution of `LinearRecurrence order coeffs` when we have
  `u (n + order) = ∑ i : Fin order, coeffs i * u (n + i)` for any `n`. -/
def IsSolution (u : ℕ → α) 
goal: Prop

full_name: LinearRecurrence.mkSol
code: /-- A solution of a `LinearRecurrence` which satisfies certain initial conditions.
  We will prove this is the only such solution. -/
def mkSol (init : Fin E.order → α) : ℕ → α
  
goal: ℕ → α

full_name: LinearRecurrence.is_sol_mkSol
code: /-- `E.mkSol` indeed gives solutions to `E`. -/
theorem is_sol_mkSol (init : Fin E.order → α) : E.IsSolution (E.mkSol init) 
goal: E.IsSolution (E.mkSol init)

full_name: LinearRecurrence.mkSol_eq_init
code: /-- `E.mkSol init`'s first `E.order` terms are `init`. -/
theorem mkSol_eq_init (init : Fin E.order → α) : ∀ n : Fin E.order, E.mkSol init n = init n 
goal: E.mkSol init ↑n = init n

full_name: LinearRecurrence.eq_mk_of_is_sol_of_eq_init
code: /-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n 
goal: u n = E.mkSol init n

full_name: LinearRecurrence.eq_mk_of_is_sol_of_eq_init'
code: /-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `u = E.mkSol init`. This proves that `E.mkSol init` is the only solution
  of `E` whose first `E.order` values are given by `init`. -/
theorem eq_mk_of_is_sol_of_eq_init' {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : u = E.mkSol init 
goal: u = E.mkSol init

full_name: LinearRecurrence.solSpace
code: /-- The space of solutions of `E`, as a `Submodule` over `α` of the module `ℕ → α`. -/
def solSpace : Submodule α (ℕ → α) 
goal: Submodule α (ℕ → α)

full_name: LinearRecurrence.is_sol_iff_mem_solSpace
code: /-- Defining property of the solution space : `u` is a solution
  iff it belongs to the solution space. -/
theorem is_sol_iff_mem_solSpace (u : ℕ → α) : E.IsSolution u ↔ u ∈ E.solSpace 
goal: E.IsSolution u ↔ u ∈ E.solSpace

full_name: LinearRecurrence.toInit
code: /-- The function that maps a solution `u` of `E` to its first
  `E.order` terms as a `LinearEquiv`. -/
def toInit : E.solSpace ≃ₗ[α] Fin E.order → α 
goal: ↥E.solSpace ≃ₗ[α] Fin E.order → α

full_name: LinearRecurrence.sol_eq_of_eq_init
code: /-- Two solutions are equal iff they are equal on `range E.order`. -/
theorem sol_eq_of_eq_init (u v : ℕ → α) (hu : E.IsSolution u) (hv : E.IsSolution v) :
    u = v ↔ Set.EqOn u v ↑(range E.order) 
goal: u = v ↔ Set.EqOn u v ↑(Finset.range E.order)

full_name: LinearRecurrence.tupleSucc
code: /-- `E.tupleSucc` maps `![s₀, s₁, ..., sₙ]` to `![s₁, ..., sₙ, ∑ (E.coeffs i) * sᵢ]`,
  where `n := E.order`. -/
def tupleSucc : (Fin E.order → α) →ₗ[α] Fin E.order → α 
goal: (Fin E.order → α) →ₗ[α] Fin E.order → α

full_name: LinearRecurrence.solSpace_rank
code: /-- The dimension of `E.solSpace` is `E.order`. -/
theorem solSpace_rank : Module.rank α E.solSpace = E.order 
goal: Module.rank α ↥E.solSpace = ↑E.order

full_name: LinearRecurrence.charPoly
code: /-- The characteristic polynomial of `E` is
`X ^ E.order - ∑ i : Fin E.order, (E.coeffs i) * X ^ i`. -/
def charPoly : α[X] 
goal: α[X]

full_name: LinearRecurrence.geom_sol_iff_root_charPoly
code: /-- The geometric sequence `q^n` is a solution of `E` iff
  `q` is a root of `E`'s characteristic polynomial. -/
theorem geom_sol_iff_root_charPoly (q : α) :
    (E.IsSolution fun n ↦ q ^ n) ↔ E.charPoly.IsRoot q 
goal: (E.IsSolution fun n => q ^ n) ↔ E.charPoly.IsRoot q