Special Functions · Lean source
CoupledNormalization.lean
Selected results recorded Coverage and evidence
Compiler/replay evidence is reported for a subset or bounded block. No whole-work coverage is implied.
This viewer reads the retained source; it does not run Lean or assign new claim mappings.
Local imports (1)
CoupledNormalization.lean297 lines
Original source path
lean/CoupledNormalization.leanSkip declarations and read code
1 import CoupledEvaluation
2 import Mathlib.Data.Nat.Choose.Basic
3
4 /-!
5 # Factorial normalization of the coupled derivative recurrence
6
7 The mathematical recurrence underlying `coupled_odd_derivatives` is defined
8 over exact rationals. Its order-(2n+1) arrays, divided by (2n+1)!, equal the
9 ordinary Taylor recurrence at every index, for arbitrary rational scales.
10 Finite inclusive prefixes therefore yield the certified polynomials.
11
12 This is a mathematical recurrence and finite-array specification. It does
13 not certify a Python interpreter, Fraction, mutation, guards or exceptions.
14 -/
15
16 set_option autoImplicit false
17 set_option maxHeartbeats 2500000
18
19 noncomputable section
20
21 namespace Komorebi.SpecialFunctions.Coupled.Scales
22
23 def oddFactorial (n : ℕ) : ℚ := ((2*n+1).factorial : ℚ)
24
25 theorem oddFactorial_ne_zero (n : ℕ) : oddFactorial n ≠ 0 := by
26 unfold oddFactorial
27 exact_mod_cast Nat.factorial_ne_zero (2*n+1)
28
29 theorem oddFactorial_zero : oddFactorial 0 = 1 := by
30 norm_num [oddFactorial]
31
32 theorem oddFactorial_succ (n : ℕ) :
33 oddFactorial (n+1) = (2*(n : ℚ)+3) * ((2*n+2).factorial : ℚ) := by
34 have he : 2*(n+1)+1 = (2*n+2)+1 := by omega
35 rw [oddFactorial, he, Nat.factorial_succ]
36 push_cast
37 ring
38
39 theorem binomial_factorial_product (n i : ℕ) (hi : i ≤ n) :
40 ((2*n+2).choose (2*i+1) : ℚ) * oddFactorial i * oddFactorial (n-i) =
41 ((2*n+2).factorial : ℚ) := by
42 have h := Nat.choose_mul_factorial_mul_factorial (show 2*i+1 ≤ 2*n+2 by omega)
43 have he : 2*n+2-(2*i+1) = 2*(n-i)+1 := by omega
44 rw [he] at h
45 unfold oddFactorial
46 exact_mod_cast h
47
48 theorem binomial_factorial_quotient (n i : ℕ) (hi : i ≤ n) :
49 ((2*n+2).choose (2*i+1) : ℚ) / oddFactorial (n+1) =
50 1 / ((2*(n : ℚ)+3) * oddFactorial i * oddFactorial (n-i)) := by
51 have h := binomial_factorial_product n i hi
52 have hf := oddFactorial_succ n
53 have hn : (2*(n : ℚ)+3) ≠ 0 := by positivity
54 apply (div_eq_div_iff (oddFactorial_ne_zero (n+1))
55 (mul_ne_zero (mul_ne_zero hn (oddFactorial_ne_zero i)) (oddFactorial_ne_zero (n-i)))).mpr
56 calc
57 _ = (2*(n : ℚ)+3) *
58 (((2*n+2).choose (2*i+1) : ℚ) * oddFactorial i * oddFactorial (n-i)) := by ring
59 _ = _ := by rw [h, hf]; ring
60
61 def derivativeRow (q r : ℚ) (c : ℕ → ℚ × ℚ) (n : ℕ) : ℚ :=
62 ∑ i : Fin (n+1), ((2*n+2).choose (2*i.val+1) : ℚ) *
63 (c i.val).1 * (c (n-i.val)).2 * q^(2*i.val+1) * r^(2*(n-i.val)+1)
64
65 def RationalScales.derivativeNext (p : RationalScales) (c : ℕ → ℚ × ℚ) (n : ℕ) : ℚ × ℚ :=
66 (derivativeRow p.q p.r c n, derivativeRow p.a p.b c n)
67
68 def RationalScales.derivatives (p : RationalScales) : ℕ → ℚ × ℚ
69 | 0 => (1, 1)
70 | n+1 =>
71 ((∑ i : Fin (n+1), ((2*n+2).choose (2*i.val+1) : ℚ) *
72 (p.derivatives i.val).1 * (p.derivatives (n-i.val)).2 *
73 p.q^(2*i.val+1) * p.r^(2*(n-i.val)+1)),
74 (∑ i : Fin (n+1), ((2*n+2).choose (2*i.val+1) : ℚ) *
75 (p.derivatives i.val).1 * (p.derivatives (n-i.val)).2 *
76 p.a^(2*i.val+1) * p.b^(2*(n-i.val)+1)))
77 termination_by n => n
78 decreasing_by all_goals omega
79
80 theorem rational_derivatives_zero (p : RationalScales) : p.derivatives 0 = (1,1) := by
81 rw [RationalScales.derivatives.eq_def]
82
83 theorem rational_derivatives_succ (p : RationalScales) (n : ℕ) :
84 p.derivatives (n+1) = p.derivativeNext p.derivatives n := by
85 rw [RationalScales.derivatives.eq_def]
86 rfl
87
88 def RationalScales.IsDerivativeSolution (p : RationalScales) (c : ℕ → ℚ × ℚ) : Prop :=
89 c 0 = (1,1) ∧ ∀ n, c (n+1) = p.derivativeNext c n
90
91 theorem rational_derivatives_solution (p : RationalScales) :
92 p.IsDerivativeSolution p.derivatives :=
93 ⟨rational_derivatives_zero p, rational_derivatives_succ p⟩
94
95 theorem derivative_solution_unique (p : RationalScales) {c d : ℕ → ℚ × ℚ}
96 (hc : p.IsDerivativeSolution c) (hd : p.IsDerivativeSolution d) : c = d := by
97 funext n
98 induction n using Nat.strong_induction_on with
99 | h n ih =>
100 cases n with
101 | zero => exact hc.1.trans hd.1.symm
102 | succ n =>
103 rw [hc.2 n, hd.2 n]
104 apply Prod.ext
105 all_goals
106 simp only [RationalScales.derivativeNext, derivativeRow]
107 apply Finset.sum_congr rfl
108 intro i _
109 have hi : i.val < n+1 := i.isLt
110 have hj : n-i.val < n+1 := by omega
111 simp only [ih i.val hi, ih (n-i.val) hj]
112
113 theorem derivativeRow_factorialScale (q r : ℚ) (c : ℕ → ℚ × ℚ) (n : ℕ) :
114 derivativeRow q r (fun k => (oddFactorial k * (c k).1, oddFactorial k * (c k).2)) n =
115 ((2*n+2).factorial : ℚ) *
116 ∑ i : Fin (n+1), q^(2*i.val+1) * r^(2*(n-i.val)+1) * (c i.val).1 * (c (n-i.val)).2 := by
117 rw [derivativeRow, Finset.mul_sum]
118 apply Finset.sum_congr rfl
119 intro i _
120 have hi : i.val ≤ n := by omega
121 have h := binomial_factorial_product n i.val hi
122 dsimp only
123 calc
124 _ = (((2*n+2).choose (2*i.val+1) : ℚ) * oddFactorial i.val * oddFactorial (n-i.val)) *
125 (q^(2*i.val+1) * r^(2*(n-i.val)+1) * (c i.val).1 * (c (n-i.val)).2) := by ring
126 _ = _ := by rw [h]
127
128 theorem factorial_scaled_coefficients_solution (p : RationalScales) :
129 p.IsDerivativeSolution
130 (fun n => (oddFactorial n * (p.coefficients n).1, oddFactorial n * (p.coefficients n).2)) := by
131 constructor
132 · dsimp only
133 have hz : p.coefficients 0 = (1,1) := by rw [RationalScales.coefficients.eq_def]
134 rw [hz, oddFactorial_zero]
135 norm_num
136 · intro n
137 dsimp only
138 have hn : (2*(n : ℚ)+3) ≠ 0 := by positivity
139 have hc := RationalScales.coefficients.eq_def p (n+1)
140 rw [hc]
141 apply Prod.ext
142 all_goals
143 simp only [RationalScales.derivativeNext, derivativeRow_factorialScale,
144 oddFactorial_succ]
145 field_simp [hn]
146
147 theorem rational_derivatives_factorial (p : RationalScales) (n : ℕ) :
148 p.derivatives n =
149 (oddFactorial n * (p.coefficients n).1, oddFactorial n * (p.coefficients n).2) :=
150 congrFun (derivative_solution_unique p (rational_derivatives_solution p)
151 (factorial_scaled_coefficients_solution p)) n
152
153 theorem derivativeNext_congr (p : RationalScales) {c d : ℕ → ℚ × ℚ} (n : ℕ)
154 (h : ∀ j, j ≤ n → c j = d j) : p.derivativeNext c n = p.derivativeNext d n := by
155 apply Prod.ext
156 all_goals
157 simp only [RationalScales.derivativeNext, derivativeRow]
158 apply Finset.sum_congr rfl
159 intro i _
160 rw [h i.val (by omega), h (n-i.val) (Nat.sub_le _ _)]
161
162 /-- Paired-array append model; both rows use only entries already stored. -/
163 def RationalScales.derivativeArray (p : RationalScales) : ℕ → List (ℚ × ℚ)
164 | 0 => [(1,1)]
165 | n+1 =>
166 let prior := p.derivativeArray n
167 prior ++ [p.derivativeNext (fun k => (prior[k]?).getD (0,0)) n]
168
169 theorem derivative_array_eq (p : RationalScales) (last : ℕ) :
170 p.derivativeArray last = List.ofFn (fun i : Fin (last+1) => p.derivatives i.val) := by
171 induction last with
172 | zero => simp [RationalScales.derivativeArray, List.ofFn_succ, rational_derivatives_zero]
173 | succ n ih =>
174 rw [RationalScales.derivativeArray, ih]
175 have hnext : p.derivativeNext
176 (fun k => ((List.ofFn (fun i : Fin (n+1) => p.derivatives i.val))[k]?).getD (0,0)) n =
177 p.derivatives (n+1) := by
178 rw [rational_derivatives_succ]
179 apply derivativeNext_congr
180 intro j hj
181 simp only [List.getElem?_ofFn, dite_eq_left (show j < n+1 by omega), Option.getD_some]
182 rw [hnext]
183 exact (List.ofFn_succ_last (f := fun j : Fin (n+1+1) => p.derivatives j.val)).symm
184
185 theorem derivative_array_length (p : RationalScales) (last : ℕ) :
186 (p.derivativeArray last).length = last+1 := by
187 rw [derivative_array_eq, List.length_ofFn]
188
189 theorem derivative_array_entry (p : RationalScales) (last n : ℕ) (hn : n ≤ last) :
190 (p.derivativeArray last)[n]? = some (p.derivatives n) := by
191 rw [derivative_array_eq]
192 simp only [List.getElem?_ofFn, dite_eq_left (show n < last+1 by omega)]
193
194 def RationalScales.derivativeComponent (p : RationalScales) (i : Fin 2) (n : ℕ) : ℚ :=
195 ![(p.derivatives n).1, (p.derivatives n).2] i
196
197 theorem derivative_component_factorial (p : RationalScales) (i : Fin 2) (n : ℕ) :
198 p.derivativeComponent i n = oddFactorial n * p.componentCoefficient i n := by
199 fin_cases i <;> simp [RationalScales.derivativeComponent, RationalScales.componentCoefficient,
200 rational_derivatives_factorial]
201
202 theorem derivative_component_normalized (p : RationalScales) (i : Fin 2) (n : ℕ) :
203 p.derivativeComponent i n / oddFactorial n = p.componentCoefficient i n := by
204 rw [derivative_component_factorial]
205 exact mul_div_cancel_left₀ _ (oddFactorial_ne_zero n)
206
207 theorem derivative_normalized_cast (p : RationalScales) (i : Fin 2) (n : ℕ) :
208 ((p.derivativeComponent i n / oddFactorial n : ℚ) : ℝ) =
209 p.toReal.componentCoefficient i n := by
210 rw [derivative_component_normalized, rational_component_coefficient_cast]
211
212 def RationalScales.ordinaryArray (p : RationalScales) (i : Fin 2) (last : ℕ) : List ℚ :=
213 (p.derivativeArray last).mapIdx (fun n c => ![c.1, c.2] i / oddFactorial n)
214
215 theorem ordinary_array_eq (p : RationalScales) (i : Fin 2) (last : ℕ) :
216 p.ordinaryArray i last = List.ofFn (fun n : Fin (last+1) => p.componentCoefficient i n.val) := by
217 rw [RationalScales.ordinaryArray, derivative_array_eq]
218 apply List.ext_getElem
219 · simp
220 · intro n hn hm
221 simp only [List.getElem_mapIdx, List.getElem_ofFn]
222 exact derivative_component_normalized p i n
223
224 theorem ordinary_array_length (p : RationalScales) (i : Fin 2) (last : ℕ) :
225 (p.ordinaryArray i last).length = last+1 := by
226 rw [ordinary_array_eq, List.length_ofFn]
227
228 theorem ordinary_array_entry (p : RationalScales) (i : Fin 2) (last n : ℕ) (hn : n ≤ last) :
229 (p.ordinaryArray i last)[n]? = some (p.componentCoefficient i n) := by
230 rw [ordinary_array_eq]
231 simp only [List.getElem?_ofFn, dite_eq_left (show n < last+1 by omega)]
232
233 def RationalScales.derivativePolynomial (p : RationalScales) (i : Fin 2) (N : ℕ) (x : ℚ) : ℚ :=
234 ∑ n ∈ Finset.range (N+1), (p.derivativeComponent i n / oddFactorial n) * x^(2*n+1)
235
236 theorem derivative_polynomial_eq (p : RationalScales) (i : Fin 2) (N : ℕ) (x : ℚ) :
237 p.derivativePolynomial i N x = p.polynomial i N x := by
238 simp only [RationalScales.derivativePolynomial, RationalScales.polynomial,
239 derivative_component_normalized]
240
241 def RationalScales.arrayPolynomial (p : RationalScales) (i : Fin 2) (N : ℕ) (x : ℚ) : ℚ :=
242 ((p.ordinaryArray i N).mapIdx (fun n c => c*x^(2*n+1))).sum
243
244 theorem array_polynomial_eq (p : RationalScales) (i : Fin 2) (N : ℕ) (x : ℚ) :
245 p.arrayPolynomial i N x = p.polynomial i N x := by
246 have hlist : (p.ordinaryArray i N).mapIdx (fun n c => c*x^(2*n+1)) =
247 List.ofFn (fun n : Fin (N+1) => p.componentCoefficient i n.val * x^(2*n.val+1)) := by
248 rw [ordinary_array_eq]
249 apply List.ext_getElem
250 · simp
251 · intro n hn hm
252 simp only [List.getElem_mapIdx, List.getElem_ofFn]
253 rw [RationalScales.arrayPolynomial, hlist, Fin.sum_ofFn, RationalScales.polynomial,
254 Finset.sum_range]
255
256 theorem array_polynomial_cast (p : RationalScales) (i : Fin 2) (N : ℕ) (x : ℚ) :
257 (p.arrayPolynomial i N x : ℝ) = p.toReal.realOddPolynomial i N (x : ℝ) := by
258 rw [array_polynomial_eq, rational_polynomial_cast]
259
260 theorem derivative_polynomial_cast (p : RationalScales) (i : Fin 2) (N : ℕ) (x : ℚ) :
261 (p.derivativePolynomial i N x : ℝ) = p.toReal.realOddPolynomial i N (x : ℝ) := by
262 rw [derivative_polynomial_eq, rational_polynomial_cast]
263
264 theorem derivative_endpoint_enclosure (p : RationalScales) (hs : p.toReal.positive)
265 (hc : p.toReal.q < 1 ∧ p.toReal.r < 1 ∧ p.toReal.a < 1 ∧ p.toReal.b < 1)
266 (x S : ℚ) (hx : 0 ≤ x) (hxS : x < S) (fuel : ℕ) (ht : p.maxScale^fuel*S < 1)
267 (N : ℕ) (i : Fin 2) :
268 (p.derivativePolynomial i N x : ℝ) ≤ p.toReal.realComponent i (x : ℝ) ∧
269 p.toReal.realComponent i (x : ℝ) ≤
270 ((p.derivativePolynomial i N x + rationalDiskMajorant p.maxScale fuel S *
271 (x/S)^(2*N+3) : ℚ) : ℝ) := by
272 rw [derivative_polynomial_eq]
273 exact rational_endpoint_enclosure p hs hc x S hx hxS fuel ht N i
274
275 theorem array_endpoint_enclosure (p : RationalScales) (hs : p.toReal.positive)
276 (hc : p.toReal.q < 1 ∧ p.toReal.r < 1 ∧ p.toReal.a < 1 ∧ p.toReal.b < 1)
277 (x S : ℚ) (hx : 0 ≤ x) (hxS : x < S) (fuel : ℕ) (ht : p.maxScale^fuel*S < 1)
278 (N : ℕ) (i : Fin 2) :
279 (p.arrayPolynomial i N x : ℝ) ≤ p.toReal.realComponent i (x : ℝ) ∧
280 p.toReal.realComponent i (x : ℝ) ≤
281 ((p.arrayPolynomial i N x + rationalDiskMajorant p.maxScale fuel S *
282 (x/S)^(2*N+3) : ℚ) : ℝ) := by
283 rw [array_polynomial_eq]
284 exact rational_endpoint_enclosure p hs hc x S hx hxS fuel ht N i
285
286 theorem rational_derivatives_one (p : RationalScales) :
287 p.derivatives 1 = (2*p.q*p.r, 2*p.a*p.b) := by
288 rw [rational_derivatives_succ]
289 simp [RationalScales.derivativeNext, derivativeRow, rational_derivatives_zero]
290
291 theorem derivative_normalization_first (p : RationalScales) :
292 p.derivativeComponent 0 1 / oddFactorial 1 = p.q*p.r/3 ∧
293 p.derivativeComponent 1 1 / oddFactorial 1 = p.a*p.b/3 := by
294 simp [RationalScales.derivativeComponent, rational_derivatives_one, oddFactorial]
295 constructor <;> ring
296
297 end Komorebi.SpecialFunctions.Coupled.Scales
Original file and source record
This copy matches the recorded source file. Its publication here does not change the work’s review status.
SHA-256: 907fd0fa37a59dff472088a2afa6cc4f9bb22663ce9d153378560cfdeaa549f8