GNU Free Documentation License, Version 1.2

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 Z^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.

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.

A `degree`

object may be created by using one of the following functions:

`degree d1(k);`

-- create a new degree object with value (0,0,...,0), with k zeroes`wdeg(f)`

-- where f is a`RingElem`

belonging to a`PolyRing`

`wdeg(t)`

-- where t is a`PPMonoidElem`

(see`PPMonoid`

)

The following functions are available for objects of type degree:

`d1 = d2`

-- assignment, d1 must be non-const`cout << d`

-- print out the degree`GradingDim(d)`

-- get the number of the components`d[s]`

-- get the s-th component of the degree (as a BigInt) (for 0 <= s < k)`SetComponent(d, k, n)`

-- sets the k-th component of d to n (mach.int. or`BigInt`

)

`d1 + d2`

-- sum`d1 - d2`

-- difference (there might be no PP with such a degree)`d1 += d2`

-- equivalent to d1 = d1 + d2`d1 -= d2`

-- equivalent to d1 = d1 - d2`top(d1, d2)`

-- coordinate-by-coordinate maximum (a sort of "lcm")`cmp(d1, d2)`

-- (int) result is <0, =0, >0 according as d1 <,=,> d2

The six comparison operators may be used for comparing degrees (using the lexicographic ordering).

`IsZero(d)`

-- return true iff d is the zero degree

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 `MemPool`

s (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.

The implementation uses `BigInt`

s 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?