@@ -11,27 +11,50 @@ import ZKLib.Data.Math.Operations
11
11
/-!
12
12
# Univariate Polynomials with Efficient Operations
13
13
14
- Note: this file was originally taken from Bolton Bailey, but has been heavily modified to fit our
15
- needs.
14
+ This file is based on various similar implementations. Credits:
15
+ - Bolton Bailey
16
+ - ...
16
17
-/
17
18
18
- section Polynomial
19
+ namespace Array
20
+
21
+ def trim {R : Type *} [DecidableEq R] (a : Array R) (y : R) : Array R :=
22
+ a.popWhile (fun x => x = y)
23
+
24
+ theorem trim_trim {R : Type *} [DecidableEq R] (a : Array R) (y : R) :
25
+ (a.trim y).trim y = a.trim y := by
26
+ simp [trim]
27
+ sorry
28
+
29
+ end Array
30
+
31
+ open Polynomial
19
32
20
33
/-- A type analogous to `Polynomial` that supports computable operations. This polynomial is
21
34
represented internally as an Array of coefficients.
22
35
23
36
For example the Array `#[1,2,3]` represents the polynomial `1 + 2x + 3x^2`. Two arrays may represent
24
37
the same polynomial via zero-padding, for example `#[1,2,3] = #[1,2,3,0,0,0,...]`.
25
38
-/
26
- structure UniPoly (R : Type _) [Semiring R] where
39
+ @[ext, specialize]
40
+ structure UniPoly (R : Type *) [Semiring R] where
27
41
mk::
28
42
coeffs : Array R
29
- -- h : coeffs last is non zero
30
43
deriving Inhabited, DecidableEq, Repr
31
44
45
+ @[ext, specialize]
46
+ structure UniPoly' (R : Type *) [Semiring R] [DecidableEq R] where
47
+ coeffs : Array R
48
+ hTrim : coeffs.trim 0 = coeffs
49
+ -- Alternatively (requires `Nontrivial R` as well)
50
+ -- hTrim' : coeffs.getLastD 1 ≠ 0
51
+ deriving Repr
52
+
32
53
namespace UniPoly
33
54
34
- variable {R : Type _} [Semiring R]
55
+ variable {R : Type *} [Semiring R]
56
+
57
+ instance [DecidableEq R] : Inhabited (UniPoly' R) := ⟨⟨#[], rfl⟩⟩
35
58
36
59
/-- Another way to access `coeffs` -/
37
60
def toArray (p : UniPoly R) : Array R := p.coeffs
@@ -189,20 +212,15 @@ instance [BEq R] [Field R] : Mod (UniPoly R) := ⟨UniPoly.mod⟩
189
212
to the left by one. -/
190
213
def divX (p : UniPoly R) : UniPoly R := ⟨p.coeffs.extract 1 p.size⟩
191
214
192
- theorem ext {p q : UniPoly R} (h : p.coeffs = q.coeffs) : p = q := by
193
- cases p; cases q; simp at h; rw [h]
194
-
195
215
@[simp] theorem zero_def : (0 : UniPoly R) = ⟨#[]⟩ := rfl
196
216
197
- theorem add_comm {p q : UniPoly R} : p + q = q + p := by
217
+ variable {p q r : UniPoly R}
218
+
219
+ theorem add_comm : p + q = q + p := by
198
220
simp only [instHAdd, Add.add, add, List.zipWith_toArray, mk.injEq, Array.mk.injEq]
199
221
exact List.zipWith_comm_of_comm _ (fun x y ↦ by change x + y = y + x; rw [_root_.add_comm]) _ _
200
222
201
- private lemma zipWith_const {α β : Type _} {f : α → β → β} {l₁ : List α} {l₂ : List β}
202
- (h₁ : l₁.length = l₂.length) (h₂ : ∀ a b, f a b = b) : l₁.zipWith f l₂ = l₂ := by
203
- induction' l₁ with hd tl ih generalizing l₂ <;> rcases l₂ <;> aesop
204
-
205
- @[simp] theorem zero_add {p : UniPoly R} : 0 + p = p := by
223
+ @[simp] theorem zero_add : 0 + p = p := by
206
224
simp [instHAdd, instAdd, add, List.matchSize]
207
225
refine UniPoly.ext (Array.ext' ?_)
208
226
simp only
@@ -212,12 +230,10 @@ private lemma zipWith_const {α β : Type _} {f : α → β → β} {l₁ : List
212
230
intros i h
213
231
change 0 + p.coeffs[i] = p.coeffs[i]
214
232
simp)]
215
- exact zipWith_const (by simp) (by simp)
233
+ exact List. zipWith_const (by simp) (by simp)
216
234
217
- @[simp] theorem add_assoc (p q r : UniPoly R) : p + q + r = p + (q + r) := by
235
+ theorem add_assoc : p + q + r = p + (q + r) := by
218
236
simp [instHAdd, instAdd, add, List.matchSize]
219
- -- refine Array.ext' ?_
220
- -- simp [ Array.toList_zipWith ]
221
237
sorry
222
238
223
239
-- TODO: define `SemiRing` structure on `UniPoly`
@@ -284,17 +300,20 @@ end Equiv
284
300
285
301
end UniPoly
286
302
303
+ namespace Lagrange
304
+
287
305
-- unique polynomial of degree n that has nodes at ω^i for i = 0, 1, ..., n-1
288
- def Lagrange. nodal' {F : Type } [Semiring F ] (n : ℕ) (ω : F ) : UniPoly F :=
289
- .mk (Array.range n |>.map (fun i => ω^i))
306
+ def nodal {R : Type * } [Semiring R ] (n : ℕ) (ω : R ) : UniPoly R := sorry
307
+ -- .mk (Array.range n |>.map (fun i => ω^i))
290
308
291
309
/--
292
310
This function produces the polynomial which is of degree n and is equal to r i at ω^i for i = 0, 1,
293
311
..., n-1.
294
312
-/
295
- def Lagrange.interpolate' {F : Type } [Semiring F] (n : ℕ) (ω : F) (r : Fin n → F) : UniPoly F :=
296
- -- .mk (Array.finRange n |>.map (fun i => r i))
297
- sorry
313
+ def interpolate {R : Type *} [Semiring R] (n : ℕ) (ω : R) (r : Vector R n) : UniPoly R := sorry
314
+ -- .mk (Array.finRange n |>.map (fun i => r[ i ] )) * nodal n ω
315
+
316
+ end Lagrange
298
317
299
318
section Tropical
300
319
/-- This section courtesy of Junyan Xu -/
@@ -345,6 +364,3 @@ noncomputable def Equiv.UniPoly.TropicallyBoundPolynomial {R : Type} [Semiring R
345
364
map_add' := by sorry
346
365
347
366
end Tropical
348
-
349
-
350
- end Polynomial
0 commit comments