5.8 KiB
Operators
The classes used to build polynomials are (almost) fully compatible with respect to the following operators, that means that any two objects of these types can be combined if there is a directed path between them within the class hierarchy. The exception are shown and explained below. All the operators have the usual meaning.
- Comparison operators
operator==(lhs, rhs)
operator!=(lhs, rhs)
operator<(lhs, rhs)
operator<=(lhs, rhs)
operator>(lhs, rhs)
operator>=(lhs, rhs)
- Arithmetic operators
operator+(lhs, rhs)
operator+=(lhs, rhs)
operator-(lhs, rhs)
operator-(rhs)
operator-=(lhs, rhs)
operator*(lhs, rhs)
operator*=(lhs, rhs)
Comparison operators
All of these operators are defined for all combination of types. We use the following ordering:
- For two variables
x
andy
,x < y
if the id ofx
is smaller then the id ofy
. The id is generated automatically by the VariablePool. - For two monomials
a
andb
, we use a lexicographical ordering with total degree, that isa < b
if- the total degree of
a
is smaller than the total degree ofb
, or - the total degrees are the same and
- the exponent of some variable
v
ina
is greater than inb
and - the exponents of all variables smaller than
v
are the same ina
and inb
.
- the exponent of some variable
- The intuition is that the monomials are considered as a sorted product of plain variables.
- the total degree of
- For two terms
a
andb
,a < b
if- the monomial of
a
is smaller than the monomial ofb
, or - the monomials of
a
andb
are the same and the coefficient ofa
is smaller than the coefficient ofb
.
- the monomial of
- For two polynomials
a
andb
, we use a lexicographical ordering, that isa < b
ifterm(a,i) < term(b,i)
andterm(a,j) = term(b,j)
for allj=0, ..., i-1
, whereterm(a,0)
is the leading term ofa
, that is the largest term with respect to the term ordering.
Arithmetic operators
We now give a table for all (classes of) operators with the result type or a reason why it is not implemented for any combination of these types.
operator+(lhs, rhs)
, operator-(lhs, rhs)
-
C V M T MP C C MP MP MP MP V MP 1) 1) MP MP M MP 1) 1) MP MP T MP MP MP MP MP MP MP MP MP MP MP
operator-(lhs)
(unary minus)
-
C V M T MP - | C | 1) | 1) | T | MP
operator*(lhs, rhs)
-
C V M T MP C C T T T MP V T M M T MP M T M M T MP T T T T T MP MP MP MP MP MP MP
operator+=(rhs)
, operator-=(rhs)
+= | C | V | M | T | MP |
---|---|---|---|---|---|
C | C | 2) | 2) | 2) | 2) |
V | 2) | 2) | 2) | 2) | 2) |
M | 2) | 2) | 2) | 2) | 2) |
T | 2) | 2) | 2) | 2) | 2) |
MP | MP | MP | MP | MP | MP |
operator*=(rhs)
*= | C | V | M | T | MP |
---|---|---|---|---|---|
C | C | 3) | 3) | 3) | 3) |
V | 3) | 3) | 3) | 3) | 3) |
M | 3) | M | M | 3) | 3) |
T | T | T | T | T | 3) |
MP | MP | MP | MP | MP | MP |
-# A coefficient type is needed to construct the desired result type, but none can be extracted from the argument types. -# The type of the left hand side can not represent sums of these objects. -# The type of the left hand side can not represent products of these objects.
UnivariatePolynomial operators
Implementation
We follow a few rules when implementing these operators:
- Of the comparison operators, only
operator==
andoperator<
contain a real implementation. The others are implemented like this:operator!=(lhs, rhs)
:!(lhs == rhs)
operator<=(lhs, rhs)
:!(rhs < lhs)
operator>(lhs, rhs)
:rhs < lhs
operator>=(lhs, rhs)
:rhs <= lhs
- Of all
operator==
, only those wherelhs
is the most general type contain a real implementation. The others are implemented like this:operator==(lhs, rhs)
:rhs == lhs
- They are ordered like in the list above.
- Operators are implemented in the file of the most general type involved (either an argument or the return type).
- Operators are not implemented as friend methods. Those are usually only found by the compiler due to ADL, but as we need to declare
operator+(Term, Term) -> MultivariatePolynomial
next to the MultivariatePolynomial, this will not work. If a friend declaration is necessary, it will be done as a forward declaration. - Overloaded versions of the same operator are ordered in decreasing lexicographical order, like in this example:
operator(Term,Term)
operator(Term,Monomial)
operator(Term,Variable)
operator(Term,Coefficient)
operator(Monomial,Term)
operator(Variable,Term)
operator(Coefficient,Term)
- Other versions are below those.
Testing the operators
There are two stages for testing these operators: a syntactical check that these operators exist and have the correct signature and a semantical check that they actually work as expected.
Syntactical checks
The syntactical check for all operators specified here is done in tests/core/Test_Operators.cpp
.
We use boost::concept_check
to check the existence of the operators. There are the following concepts:
Comparison
: Checks for all comparison operators. (==
,!=
,<
,<=
,>
,>=
)Addition
: Checks for out-of-place addition operators. (+
,-
)UnaryMinus
: Checks for unary minus operators. (-
)Multiplication
: Checks for out-of-place multiplication operators. (*
)InplaceAddition
: Checks for all in-place addition operators. (+=
,-=
)InplaceMultiplication
: Checks for all in-place multiplication operators. (*=
)
Semantical checks
Semantical checking is done within the test for each class.