Laurent polynomials #
We introduce Laurent polynomials over a semiring R
. Mathematically, they are expressions of the
form
$$ \sum_{i \in \mathbb{Z}} a_i T ^ i $$
where the sum extends over a finite subset of ℤ
. Thus, negative exponents are allowed. The
coefficients come from the semiring R
and the variable T
commutes with everything.
Since we are going to convert back and forth between polynomials and Laurent polynomials, we
decided to maintain some distinction by using the symbol T
, rather than X
, as the variable for
Laurent polynomials.
Notation #
The symbol R[T;T⁻¹]
stands for LaurentPolynomial R
. We also define
C : R →+* R[T;T⁻¹]
the inclusion of constant polynomials, analogous to the one forR[X]
;T : ℤ → R[T;T⁻¹]
the sequence of powers of the variableT
.
Implementation notes #
We define Laurent polynomials as AddMonoidAlgebra R ℤ
.
Thus, they are essentially Finsupp
s ℤ →₀ R
.
This choice differs from the current irreducible design of Polynomial
, that instead shields away
the implementation via Finsupp
s. It is closer to the original definition of polynomials.
As a consequence, LaurentPolynomial
plays well with polynomials, but there is a little roughness
in establishing the API, since the Finsupp
implementation of R[X]
is well-shielded.
Unlike the case of polynomials, I felt that the exponent notation was not too easy to use, as only
natural exponents would be allowed. Moreover, in the end, it seems likely that we should aim to
perform computations on exponents in ℤ
anyway and separating this via the symbol T
seems
convenient.
I made a heavy use of simp
lemmas, aiming to bring Laurent polynomials to the form C a * T n
.
Any comments or suggestions for improvements is greatly appreciated!
Future work #
Lots is missing!
-- (Riccardo) add inclusion into Laurent series.
-- (Riccardo) giving a morphism (as R
-alg, so in the commutative case)
from R[T,T⁻¹]
to S
is the same as choosing a unit of S
.
-- A "better" definition of trunc
would be as an R
-linear map. This works:
-- -- def trunc : R[T;T⁻¹] →[R] R[X] := -- refine (?_ : R[ℕ] →[R] R[X]).comp ?_ -- · exact ⟨(toFinsuppIso R).symm, by simp⟩ -- · refine ⟨fun r ↦ comapDomain _ r -- (Set.injOn_of_injective (fun _ _ ↦ Int.ofNat.inj) _), ?_⟩ -- exact fun r f ↦ comapDomain_smul .. --
-- but it would make sense to bundle the maps better, for a smoother user experience.
-- I (DT) did not have the strength to embark on this (possibly short!) journey, after getting to
-- this stage of the Laurent process!
-- This would likely involve adding a comapDomain
analogue of
-- AddMonoidAlgebra.mapDomainAlgHom
and an R
-linear version of
-- Polynomial.toFinsuppIso
.
-- Add degree, int_degree, int_trailing_degree, leading_coeff, trailing_coeff,...
.
The semiring of Laurent polynomials with coefficients in the semiring R
.
We denote it by R[T;T⁻¹]
.
The ring homomorphism C : R →+* R[T;T⁻¹]
includes R
as the constant polynomials.
Equations
Instances For
Equations
- LaurentPolynomial.«term_[T;T⁻¹]» = Lean.ParserDescr.trailingNode `LaurentPolynomial.«term_[T;T⁻¹]» 9000 0 (Lean.ParserDescr.symbol "[T;T⁻¹]")
Instances For
The ring homomorphism, taking a polynomial with coefficients in R
to a Laurent polynomial
with coefficients in R
.
Equations
- Polynomial.toLaurent = (AddMonoidAlgebra.mapDomainRingHom R Int.ofNatHom).comp ↑(Polynomial.toFinsuppIso R)
Instances For
This is not a simp lemma, as it is usually preferable to use the lemmas about C
and X
instead.
The R
-algebra map, taking a polynomial with coefficients in R
to a Laurent polynomial
with coefficients in R
.
Equations
- Polynomial.toLaurentAlg = (AddMonoidAlgebra.mapDomainAlgHom R R Int.ofNatHom).comp ↑(Polynomial.toFinsuppIsoAlg R)
Instances For
When we have [CommSemiring R]
, the function C
is the same as algebraMap R R[T;T⁻¹]
.
(But note that C
is defined when R
is not necessarily commutative, in which case
algebraMap
is not available.)
The function n ↦ T ^ n
, implemented as a sequence ℤ → R[T;T⁻¹]
.
Using directly T ^ n
does not work, since we want the exponents to be of Type ℤ
and there
is no ℤ
-power defined on R[T;T⁻¹]
. Using that T
is a unit introduces extra coercions.
For these reasons, the definition of T
is as a sequence.
Equations
Instances For
Equations
- LaurentPolynomial.invertibleT n = { invOf := LaurentPolynomial.T (-n), invOf_mul_self := ⋯, mul_invOf_self := ⋯ }
To prove something about Laurent polynomials, it suffices to show that
- the condition is closed under taking sums, and
- it holds for monomials.
trunc : R[T;T⁻¹] →+ R[X]
maps a Laurent polynomial f
to the polynomial whose terms of
nonnegative degree coincide with the ones of f
. The terms of negative degree of f
"vanish".
trunc
is a left-inverse to Polynomial.toLaurent
.
Equations
- LaurentPolynomial.trunc = (Polynomial.toFinsuppIso R).symm.toAddMonoidHom.comp (Finsupp.comapDomain.addMonoidHom ⋯)
Instances For
This is a version of exists_T_pow
stated as an induction principle.
Suppose that Q
is a statement about Laurent polynomials such that
Q
is true on ordinary polynomials;Q (f * T)
impliesQ f
; it follow thatQ
is true on all Laurent polynomials.
The support of a polynomial f
is a finset in ℕ
. The lemma toLaurent_support f
shows that the support of f.toLaurent
is the same finset, but viewed in ℤ
under the natural
inclusion ℕ ↪ ℤ
.
Equations
- LaurentPolynomial.instModulePolynomial = Module.compHom (LaurentPolynomial R) Polynomial.toLaurent
Equations
- LaurentPolynomial.algebraPolynomial R = Algebra.mk Polynomial.toLaurent ⋯ ⋯
The map which substitutes T ↦ T⁻¹
into a Laurent polynomial.
Equations
- LaurentPolynomial.invert = AddMonoidAlgebra.domCongr R R (AddEquiv.neg ℤ)
Instances For
Evaluate a Laurent polynomial at a unit, using scalar multiplication.
Equations
- f.smeval x = Finsupp.sum f fun (n : ℤ) (r : R) => r • ↑(x ^ n)
Instances For
Evaluation as an R
-linear map.
Equations
- LaurentPolynomial.leval R x = { toFun := fun (f : LaurentPolynomial R) => f.smeval x, map_add' := ⋯, map_smul' := ⋯ }