Convert to the dense representation: allocate degree + 1
coefficients and write each stored term into its slot, O(n) in the
degree whatever the term count. The one operation here whose cost is not
governed by the term count; no operation in this library is implemented
through it.
6.4. Conversions
The dense conversions are the boundary between the two representations
and the proof route for the multiplicative laws. toDense is the one
operation whose cost is governed by the degree.
Hex.SparsePoly.toDense.{u} {R : Type u} [Zero R] [DecidableEq R] (s : Hex.SparsePoly R) : Hex.DensePoly RHex.SparsePoly.toDense.{u} {R : Type u} [Zero R] [DecidableEq R] (s : Hex.SparsePoly R) : Hex.DensePoly R
Hex.SparsePoly.ofDense.{u} {R : Type u} [Zero R] [DecidableEq R] (p : Hex.DensePoly R) : Hex.SparsePoly RHex.SparsePoly.ofDense.{u} {R : Type u} [Zero R] [DecidableEq R] (p : Hex.DensePoly R) : Hex.SparsePoly R
Convert from the dense representation, keeping the nonzero coefficients with their indices.
Kernel-facing specification (an ordered List walk); compiled code uses
Hex.SparsePoly.ofDenseImpl, the value-equal array pass selected by
Hex.SparsePoly.ofDense_eq_impl.
Hex.SparsePoly.toDense_mul.{u} {S : Type u} [Lean.Grind.CommRing S] [DecidableEq S] (s t : Hex.SparsePoly S) : (s * t).toDense = s.toDense * t.toDenseHex.SparsePoly.toDense_mul.{u} {S : Type u} [Lean.Grind.CommRing S] [DecidableEq S] (s t : Hex.SparsePoly S) : (s * t).toDense = s.toDense * t.toDense
The conversion is multiplicative: the transported convolution. This
is where coeff_mul and the multiplicative ring laws come from.
Measured crossovers (recorded in the library SPEC): sparse addition
beats dense up to about t ≈ n/8 stored terms at degree n, sparse
multiplication up to about t ≈ n/4, and sparse evaluation stays ahead
to at least t ≈ n/6.