# Generic Laurent polynomials

Laurent polynomials are similar to polynomials but can have terms of negative degrees, and form a ring denoted by $R[x, x^{-1}]$ where R is the coefficient ring.

## Generic Laurent polynomial types

AbstractAlgebra.jl provides a generic implementation of Laurent polynomials, built in terms of regular polynomials in the file src/generic/LaurentPoly.jl.

The type LaurentPolyWrap{T, ...} <: LaurentPolyRingElem{T} implements generic Laurent polynomials by wrapping regular polynomials: a Laurent polynomial l wraps a polynomial p and an integer n such that $l = x^{-n} * p$.

The corresponding parent type is LaurentPolyWrapRing{T, ...} <: LaurentPolynomialRing{T}.

## Abstract types

Two abstract types LaurentPolyRingElem{T} and LaurentPolynomialRing{T} are defined to represent Laurent polynomials and rings thereof, parameterized on a base ring T.

## Laurent polynomials ring constructor

In order to instantiate Laurent polynomials, one must first construct the parent ring:

LaurentPolynomialRingType
LaurentPolynomialRing(R::Ring, s::Union{AbstractString, Char, Symbol})

Given a base ring R and string s specifying how the generator (variable) should be printed, return a tuple S, x representing the new Laurent polynomial ring $S = R[x, 1/x]$ and the generator $x$ of the ring.

Examples

julia> R, x = LaurentPolynomialRing(ZZ, "x")
(Univariate Laurent Polynomial Ring in x over Integers, x)

julia> 2x^-3 + x^2
x^2 + 2*x^-3

julia> rand(R, -3:3, -9:9)
-3*x^2 - 8*x + 4 + 3*x^-1 - 6*x^-2 + 9*x^-3
LaurentPolynomialRing(R::AbstractAlgebra.Ring, s::Vector{T}; cached::Bool = true) where T <: Union{String, Char, Symbol}

Given a base ring R and an array of strings s specifying how the generators (variables) should be printed, return a tuple T, (x1, x2, ...) representing the new ring $T = R[x1, 1/x1, x2, 1/x2, ...]$ and the generators $x1, x2, ...$ of the ring. By default the parent object T will depend only on R and x1, x2, ... and will be cached. Setting the optional argument cached to false will prevent the parent object T from being cached.

## Basic functionality

Laurent polynomials implement the ring interface, and some methods from the polynomial interface, for example:

julia> R, x = LaurentPolynomialRing(ZZ, "x")
(Univariate Laurent Polynomial Ring in x over Integers, x)

julia> var(R)
:x

julia> symbols(R)
1-element Vector{Symbol}:
:x

julia> nvars(R)
1

julia> f = x^-2 + 2x
2*x + x^-2

julia> coeff.(f, -2:2)
5-element Vector{BigInt}:
1
0
0
2
0

julia> set_coefficient!(f, 3, ZZ(5))
5*x^3 + 2*x + x^-2

julia> is_gen(f)
false

julia> shift_left(f,2)
5*x^5 + 2*x^3 + 1

julia> map_coefficients(x->2x, f)
10*x^3 + 4*x + 2*x^-2

julia> change_base_ring(RealField, f)
5.0*x^3 + 2.0*x + x^-2

(5, 1)