Examples
User documentation
The class degree is used to represent the values returned by the "deg"
function applied to power products and (multivariate) polynomials.
Recall that in general a degree is a value in ZZ^k; the value of k and
the way the degree is computed (equiv. weight matrix) are specified when
creating the PPOrdering object used for making the PPMonoid of the
polynomial ring -- see the function NewPolyRing (in SparsePolyRing).
If t1 and t2 are two power products then the degree of their product is
just the sum of their individual degrees; and naturally, if t1 divides
t2 then the degree of the quotient is the difference of their degrees.
The degree values are totally ordered using a lexicographic ordering.
Note that a degree may have negative components.
Constructors
A degree object may be created by using one of the following functions:
Operations
The following functions are available for objects of type degree:
d1 = d2-- assignmentcout << d-- print out the degreeGradingDim(d)-- get the number of the componentsd[k]-- get thek-th component of the degree (as aBigInt)SetComponent(d, k, n)-- sets thek-th component ofdton(integer)
Arithmetic
d1 + d2-- sumd1 - d2-- difference (there might be no PP with such a degree)d1 += d2-- equivalent tod1 = d1 + d2d1 -= d2-- equivalent tod1 = d1 - d2top(d1, d2)-- coordinate-by-coordinate maximum (a sort of "lcm")cmp(d1, d2)-- (int) result is <0, =0, >0 according asd1 <,=,> d2in lex orderFastCmp(d1, d2)-- same ascmp(d1,d2)but no compatibility check on the args
Queries
The usual comparison operators may be used for comparing degrees (using the lexicographic ordering).
d1 == d2andd1 != d2IsZero(d)-- return true iffdis the zero degreed1 < d2d1 <= d2d1 > d2d1 >= d2
Maintainer documentation
So far the implementation is very simple. The primary design choice was to
use C++ std::vector<>s for holding the values -- indeed a degree object is
just a "wrapped up" vector of values of type degree::ElementType. For a
first implementation this conveniently hides issues of memory management
etc. Since I do not expect huge numbers of degree objects to created and
destroyed, there seems little benefit in trying to use MemPools (except it
might be simpler to detect memory leaks...) I have preferred to make most
functions friends rather than members, mostly because I prefer the syntax
of normal function calls.
The CheckCompatible function is simple so I made it inline. Note the type
of the third argument: it is deliberately not (a reference to) a
std::string because I wanted to avoid calling a ctor for a std::string
unless an error is definitely to be signalled. I made it a private
static member function so that within it there is free access to
myCoords, the data member of a degree object; also the call
degree::CheckCompatible makes it clear that it is special to degrees.
As is generally done in CoCoALib the member function mySetComponent only uses
CoCoA_ASSERT for the index range check. In contrast, the non-member fn SetComponent
always performs a check on the index value. The member fn operator[] also
always performs a check on the index value because it is the only way to get
read access to the degree components. I used MachineInt as the type for
the index to avoid the nasty surprises C++ can spring with silent conversions
between various integer types.
In implementations of functions on degrees I have preferred to place the
lengths of the degree vectors in a const local variable: it seems cleaner
than calling repeatedly myCoords.size(), and might even be fractionally
faster.
operator<< no longer handles the case of one-dimensional
degrees specially so that the value is not printed inside parentheses.
Bugs, Shortcomings and other ideas
The implementation uses BigInts internally to hold the values of the degree
coordinates. The allows a smooth transition to examples with huge degrees
but could cause some run-time performance degradation. If many complaints
about lack of speed surface, I'll review the implementation.
Is public write-access to the components of a degree object desirable? Or is this a bug?
No special handling for the case of a grading over Z (i.e. k=1) other than for printing. Is this really a shortcoming?
Printing via operator<< is perhaps rather crude?
Is the special printing for k=1 really such a clever idea?
GradingDim(const degree&) seems a bit redundant,
but it is clearer than "dim" or "size"
Is use of MachineInt for the index values such a clever idea?