Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ makedocs(
"polynomial.md",
"ncpolynomial.md",
"mpolynomial.md",
"univpolynomial.md",
"universal_ring.md",
"laurent_polynomial.md",
"laurent_mpolynomial.md",
"series.md",
Expand Down
123 changes: 123 additions & 0 deletions docs/src/universal_ring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
```@meta
CurrentModule = AbstractAlgebra
CollapsedDocStrings = true
DocTestSetup = AbstractAlgebra.doctestsetup()
```

# Universal ring

AbstractAlgebra provides a module, implemented in `src/UniversalRing.jl` for
universal rings. They "universalize" rings which have a notion of generators (or
variables) and coefficients. The most important example of such a ring is a
multivariate polynomial ring. In contrast to the usual multivariate polynomial
ring, its universal pendant allows for variables to be added at any time.

Another example is the ring of multivariate Laurent polynomials.

The type of the universal ring is `UniversalRing{T, U}` where `T` is the type of
the elements of the underlying ring and `U` is the type of the coefficients. In
the case of multivariate polynomials `T` would be a subtype of `MPolyRingElem`
and `U` would be the type of the coefficients of the polynomials, for example
`BigInt`.

## Universal polynomial ring

To compensate for the fact that the number of variables may change, many of the
functions relax their restrictions on exponent vectors. For example, if one
creates a polynomial when the ring only has two variables, each exponent vector
would consist of two integers. Later, when the ring has more variable, these
exponent vectors will still be accepted. The exponent vectors are simply padded
out to the full number of variables behind the scenes.

The universal polynomial ring behaves exactly like a multivariate polynomial
ring with the few differences noted above.

The only functionality not implemented is the ability to do `divrem` by an
ideal of polynomials.

The universal polynomial ring is very useful for doing symbolic manipulation.
However, it is important to understand that AbstractAlgebra is not a symbolic
system and the performance of the universal polynomial ring will closely match
that of a multivariate polynomial ring with the same number of variables.

The disadvantage of this approach to symbolic manipulation is that some
manipulations that would be offered by a symbolic system are not available,
as variables are not identified by their names alone in AbstractAlgebra, as
would be the case symbolically, but by objects.

The most powerful symbolic tools we offer are the generalized evaluation
functions, the multivariate coefficient functionality, the ability to
change coefficient ring and to map coefficients according to a supplied
function and the ability to convert a multivariate which happens to have
just one variable into a dense univariate polynomial.

Further facilities may be added in future to ease symbolic manipulations.

## Constructors

In order to construct universal polynomials in AbstractAlgebra, one must first
construct the universal polynomial ring itself. This is unique given a
coefficient ring.

The universal polynomial ring over a given coefficient ring `R` is constructed
with one of the following constructor functions.

```@docs
universal_polynomial_ring
```

Similarly, on can construct universal Laurent polynomial rings.

```@docs
universal_laurent_polynomial_ring
```

## Adding variables

There are two ways to add variables to a universal ring `S`.

```julia
gen(S::UniversalRing, var::VarName)
gens(S::UniversalRing, vars::Vector{VarName})
```

**Examples**

```jldoctest
julia> S = universal_polynomial_ring(ZZ)
Universal polynomial ring over Integers

julia> x = gen(S, :x)
x

julia> number_of_generators(S)
1

julia> y, z = gens(S, [:y, :z])
2-element Vector{UniversalRingElem{AbstractAlgebra.Generic.MPoly{BigInt}, BigInt}}:
y
z

julia> number_of_generators(S)
3
```

## Implement universal rings

To be able to use a ring as a base ring of an universal ring one has to
implement a few methods. In addition to the variable and coefficient related
methods like `gen`, `gens`, `symbols`, `coefficient_ring` there are the two
internal methods `_add_gens` and `_upgrade` used to extend the number of
variables.

```@docs
AbstractAlgebra._add_gens
AbstractAlgebra._upgrade
```

### Hashing

To be able to use subtypes of `UniversalRingElem` efficiently as keys of a
dictionary or similar applications, it is necessary to implement a custom `hash`
function. The results should not depend on the number of variables currently in
the parent. An example implementation can be found in `src/UnivPoly.jl`
101 changes: 0 additions & 101 deletions docs/src/univpolynomial.md

This file was deleted.

2 changes: 2 additions & 0 deletions src/AbstractAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ include("ResidueField.jl")
include("Fraction.jl")
include("TotalFraction.jl")
include("MPoly.jl")
include("UniversalLaurentPoly.jl")
include("UniversalRing.jl")
include("UnivPoly.jl")
include("FreeAssociativeAlgebra.jl")
include("LaurentMPoly.jl")
Expand Down
4 changes: 0 additions & 4 deletions src/AbstractTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ abstract type NCPolyRing{T} <: NCRing end

abstract type MPolyRing{T} <: Ring end

abstract type UniversalPolyRing{T} <: Ring end

abstract type LaurentPolyRing{T} <: Ring end

abstract type LaurentMPolyRing{T} <: Ring end
Expand Down Expand Up @@ -116,8 +114,6 @@ abstract type NCPolyRingElem{T} <: NCRingElem end

abstract type MPolyRingElem{T} <: RingElem end

abstract type UniversalPolyRingElem{T} <: RingElem end

abstract type LaurentPolyRingElem{T} <: RingElem end

abstract type LaurentMPolyRingElem{T} <: RingElem end
Expand Down
41 changes: 41 additions & 0 deletions src/ConcreteTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,44 @@ struct MatSpace{T <: NCRingElement} <: Module{T}
return new{T}(R, r, c)
end
end

###############################################################################
#
# Universal ring
#
###############################################################################

@attributes mutable struct UniversalRing{T <: RingElem, U <: RingElement} <: Ring
base_ring::Ring

function UniversalRing(R::Ring)
return new{elem_type(R), elem_type(coefficient_ring(R))}(R)
end
end

mutable struct UniversalRingElem{T <: RingElem, U <: RingElement} <: RingElem
data::T
parent::UniversalRing{T, U}
end

###############################################################################
#
# Universal polynomial ring
#
###############################################################################

struct UnivPolyCoeffs{T <: RingElem}
poly::T
end

struct UnivPolyExponentVectors{T <: RingElem}
poly::T
end

struct UnivPolyTerms{T <: RingElem}
poly::T
end

struct UnivPolyMonomials{T <: RingElem}
poly::T
end
4 changes: 4 additions & 0 deletions src/Deprecations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
@alias dense_poly_type poly_type
@alias dense_poly_ring_type poly_ring_type

const UniversalPolyRing{T} = UniversalRing{<:MPolyRingElem, T}
const UniversalPolyRingElem{T} = UniversalRingElem{<:MPolyRingElem, T}
const UnivPoly{T} = UniversalPolyRingElem{T}

###############################################################################
#
# Deprecated bindings
Expand Down
2 changes: 1 addition & 1 deletion src/Generic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ include("generic/NCPoly.jl")

include("generic/MPoly.jl")

include("generic/UnivPoly.jl")
include("generic/UniversalRing.jl")

include("generic/SparsePoly.jl")

Expand Down
Loading
Loading