Regina 7.4 Calculation Engine
|
Represents a multivariate polynomial of the type used by arrow polynomials of links. More...
#include <maths/arrow.h>
Public Types | |
using | Coefficient = Integer |
The type of each coefficient of the polynomial. | |
using | DiagramSequence = LightweightSequence<size_t> |
The type used to represent a product of diagram variables. | |
Public Member Functions | |
Arrow ()=default | |
Creates the zero polynomial. | |
Arrow (const Arrow &)=default | |
Creates a new copy of the given polynomial. | |
Arrow (Arrow &&) noexcept=default | |
Moves the contents of the given polynomial to this new polynomial. | |
template<typename iterator , typename deref = decltype(*iterator())> | |
Arrow (iterator begin, iterator end) | |
Creates a new polynomial from the given collection of diagram sequences and non-zero Laurent polynomials in A. | |
Arrow (std::initializer_list< std::pair< DiagramSequence, Laurent< Integer > > > pairs) | |
Creates a new polynomial from a hard-coded collection of diagram sequences and non-zero Laurent polynomials in A. | |
Arrow (Laurent< Integer > laurent) | |
Creates the given Laurent polynomial in A. | |
void | init () |
Sets this to become the zero polynomial. | |
void | initDiagram (const DiagramSequence &d) |
Sets this to become the given product of diagram variables, using a deep copy. | |
void | initDiagram (DiagramSequence &&d) |
Sets this to become the given product of diagram variables, using a fast move operation. | |
bool | isZero () const |
Returns whether this is the zero polynomial. | |
const Laurent< Integer > & | operator[] (const DiagramSequence &d) const |
Returns the Laurent polynomial in A that is attached to the given product of diagram variables. | |
void | set (const DiagramSequence &d, const Laurent< Integer > &value) |
Changes the Laurent polynomial in A that is attached to the given product of diagram variables. | |
void | set (const DiagramSequence &d, Laurent< Integer > &&value) |
Changes the Laurent polynomial in A that is attached to the given product of diagram variables. | |
bool | operator== (const Arrow &rhs) const |
Tests whether this and the given polynomial are equal. | |
bool | operator== (const Laurent< Integer > &rhs) const |
Tests whether this is equal to the given Laurent polynomial in A. | |
std::strong_ordering | operator<=> (const Arrow &rhs) const |
Compares this against the given polynomial under a total ordering of all arrow polynomials. | |
Arrow & | operator= (const Arrow &)=default |
Sets this to be a copy of the given polynomial. | |
Arrow & | operator= (Arrow &&value) noexcept=default |
Moves the contents of the given polynomial to this polynomial. | |
Arrow & | operator= (Laurent< Integer > laurent) |
Sets this to be the given Laurent polynomial in A. | |
void | swap (Arrow &other) noexcept |
Swaps the contents of this and the given polynomial. | |
void | shift (long s) |
Multiplies this polynomial by A^s for some integer s. | |
void | scaleUp (long k) |
Multiplies all exponents of A in this polynomial by k for some integer k. | |
void | scaleDown (long k) |
Divides all exponents in this polynomial by k for some integer k. | |
void | negate () |
Negates this polynomial. | |
void | invertA () |
Replaces A with A^-1 in this polynomial. | |
void | multDiagram (size_t index) |
Multiplies this polynomial by the given diagram variable. | |
Laurent< Integer > | sumLaurent () const |
Returns the sum of all Laurent polynomials in A that are attached to each diagram sequence. | |
Arrow & | operator*= (const Integer &scalar) |
Multiplies this polynomial by the given integer constant. | |
Arrow & | operator*= (const Laurent< Integer > &laurent) |
Multiplies this arrow polynomial by the given Laurent polynomial in A . | |
Arrow & | operator+= (const Arrow &other) |
Adds the given polynomial to this. | |
Arrow & | operator-= (const Arrow &other) |
Subtracts the given polynomial from this. | |
Arrow & | operator*= (const Arrow &other) |
Multiplies this by the given polynomial. | |
void | writeTextShort (std::ostream &out, bool utf8=false) const |
Writes this polynomial to the given output stream. | |
void | tightEncode (std::ostream &out) const |
Writes the tight encoding of this polynomial to the given output stream. | |
void | writeTextLong (std::ostream &out) const |
A default implementation for detailed output. | |
std::string | str () const |
Returns a short text representation of this object. | |
std::string | utf8 () const |
Returns a short text representation of this object using unicode characters. | |
std::string | detail () const |
Returns a detailed text representation of this object. | |
std::string | tightEncoding () const |
Returns the tight encoding of this object. | |
size_t | hash () const |
Hashes this object to a non-negative integer, allowing it to be used for keys in hash tables. | |
Static Public Member Functions | |
static Arrow | tightDecode (std::istream &input) |
Reconstructs a polynomial from its given tight encoding. | |
static Arrow | tightDecoding (const std::string &enc) |
Reconstructs an object of type T from its given tight encoding. | |
Friends | |
Arrow | operator* (const Arrow &lhs, const Arrow &rhs) |
Multiplies the two given polynomials. | |
Represents a multivariate polynomial of the type used by arrow polynomials of links.
An arrow polynomial is a polynomial in the "ordinary variable" A
and a finite number of "diagram variables" K_1,K_2,...
. The ordinary variable may appear with any integer exponents, including negative exponents (as in a Laurent polynomial). The diagram variables may only appear with non-negative integer exponents (as in an ordinary polynomial). All of the variables commute, and all of the coefficients are integers.
This class is implemented as a collection of Laurent polynomials in A
, each attached to a different product of diagram variables (K_1)^(a_1) (K_2)^(a_2) ...
. We represent each such product of diagram variables by the sequence of non-negative integers a_1,a_2,...
, where the final integer is strictly positive; for the trivial product with no diagram variables at all we use the empty sequence. In the notes below we call such a sequence a diagram sequence.
This class implements C++ move semantics and adheres to the C++ Swappable requirement. It is designed to avoid deep copies wherever possible, even when passing or returning objects by value.
using regina::Arrow::Coefficient = Integer |
The type of each coefficient of the polynomial.
using regina::Arrow::DiagramSequence = LightweightSequence<size_t> |
The type used to represent a product of diagram variables.
|
default |
Creates the zero polynomial.
|
default |
Creates a new copy of the given polynomial.
This constructor induces a deep copy of the given polynomial.
|
defaultnoexcept |
Moves the contents of the given polynomial to this new polynomial.
This is a fast (constant time) operation.
The polynomial that was passed will no longer be usable.
|
inline |
Creates a new polynomial from the given collection of diagram sequences and non-zero Laurent polynomials in A.
The data should be presented as a collection of pairs of the form (seq, laurent)
, where seq
is a diagram sequence and laurent
is the associated Laurent polynomial in A
.
The pairs may be given in any order. An empty sequence will be treated as the zero polynomial.
Unlike the std::initializer_list constructor, zero Laurent polynomials are allowed (these will be silently ignored), and multiple pairs with the same diagram sequences are also allowed (these will be summed together).
This routine is targeted more towards Python users (since in C++ it is often easier to hard-code arrow polynomials using the std::initializer_list constructor). As an example, Python users can create the arrow polynomial A^-4 + (A^-6 - A^-10) K_1
using either of the expressions:
(seq, laurent)
, where seq is a python list of integers representing a diagram sequence, and where laurent is either (i) a Laurent polynomial, or (ii) a pair (minExp, coefficients)
which could be used to construct a Laurent polynomial. In the latter case, minExp would an integer, and coefficients would be a python list of integers.InvalidArgument | At least one of the given diagram sequences is non-empty and ends in zero. |
iterator | an iterator type which, when dereferenced, gives a std::pair of the form (seq, laurent) , where seq and laurent can be used to construct objects of types DiagramSequence and Laurent<Integer> respectively. |
deref | a dummy argument that should be ignored. This is present to ensure that iterator can be dereferenced. Once we support a greater subset of C++20, this will be enforced through concepts instead. |
begin | the beginning of the collection of pairs, as outlined above. |
end | a past-the-end iterator indicating the end of the collection of pairs. |
|
inline |
Creates a new polynomial from a hard-coded collection of diagram sequences and non-zero Laurent polynomials in A.
The data should be presented as a collection of pairs of the form (seq, laurent)
, where seq
is a diagram sequence and laurent
is the associated Laurent polynomial in A
.
The pairs may be given in any order. An empty sequence will be treated as the zero polynomial.
So, for example, you can create the arrow polynomial A^-4 + (A^-6 - A^-10) K_1
using the syntax:
InvalidArgument | Two of the given diagram sequences are identical, and/or one of the given diagram sequences is non-empty and ends in zero, and/or one of the given Laurent polynomials is zero. |
pairs | the diagram sequences and Laurent polynomials, as outlined above. |
|
inherited |
Returns a detailed text representation of this object.
This text may span many lines, and should provide the user with all the information they could want. It should be human-readable, should not contain extremely long lines (which cause problems for users reading the output in a terminal), and should end with a final newline. There are no restrictions on the underlying character set.
|
inlineinherited |
Hashes this object to a non-negative integer, allowing it to be used for keys in hash tables.
This hash function makes use of Regina's tight encodings. In particular, any two objects with the same tight encoding will have equal hashes. This implementation (and therefore the specific hash value for each object) is subject to change in future versions of Regina.
|
inline |
Sets this to become the zero polynomial.
|
inline |
Sets this to become the given product of diagram variables, using a deep copy.
If d is the sequence a_1,a_2,...
, then this polynomial will be set to (K_1)^(a_1) (K_2)^(a_2) ...
.
InvalidArgument | The given sequence of integers is non-empty and its last entry is zero. |
d | a sequence of integers representing some product of diagram variables. If this sequence is non-empty, then its last entry should be strictly positive. |
|
inline |
Sets this to become the given product of diagram variables, using a fast move operation.
This variant of initDiagram() will move the diagram sequence out of the argument d, which is very fast; however, like any move operation, it will render the original argument d unusable.
If d is the sequence a_1,a_2,...
, then this polynomial will be set to (K_1)^(a_1) (K_2)^(a_2) ...
.
InvalidArgument | The given sequence of integers is non-empty and its last entry is zero. |
d | a sequence of integers representing some product of diagram variables. If this sequence is non-empty, then its last entry should be strictly positive. |
|
inline |
Replaces A
with A^-1
in this polynomial.
This polynomial is changed directly.
Calling this routine is equivalent to calling scaleUp(-1)
.
|
inline |
Returns whether this is the zero polynomial.
true
if and only if this is the zero polynomial. void regina::Arrow::multDiagram | ( | size_t | index | ) |
Multiplies this polynomial by the given diagram variable.
Specifically, if the given index is i, then this polynomial will be multiplied by the diagram variable K_i
. Note that this requires i to be strictly positive.
InvalidArgument | The given index is zero. |
index | the index of the diagram variable to multiply by; this must be strictly positive. |
|
inline |
Negates this polynomial.
This polynomial is changed directly.
Multiplies this by the given polynomial.
other | the polynomial to multiply this by. |
Multiplies this polynomial by the given integer constant.
scalar | the scalar factor to multiply by. |
Adds the given polynomial to this.
other | the polynomial to add to this. |
Subtracts the given polynomial from this.
other | the polynomial to subtract from this. |
|
inline |
Compares this against the given polynomial under a total ordering of all arrow polynomials.
The particular total order that Regina uses is not important, and may change between Regina releases (though such changes should be very infrequent). The main purpose of this routine is to support algorithms that require a "canonical" choice of polynomial from amongst many alternatives.
This routine generates all of the usual comparison operators, including <
, <=
, >
, and >=
.
x <=> y
is not available, but the other comparison operators that it generates are available.rhs | the polynomial to compare with this. |
Moves the contents of the given polynomial to this polynomial.
This is a fast (constant time) operation.
The polynomial that was passed will no longer be usable.
Sets this to be a copy of the given polynomial.
This operator induces a deep copy of the given polynomial.
|
inline |
Tests whether this and the given polynomial are equal.
rhs | the polynomial to compare with this. |
true
if and only if this and the given polynomial are equal. const Laurent< Integer > & regina::Arrow::operator[] | ( | const DiagramSequence & | d | ) | const |
Returns the Laurent polynomial in A
that is attached to the given product of diagram variables.
arrow[a1, a2, ...]
. Moreover, in Python this operator can also set the attached Laurent polynomial: you can write arrow[a1, a2, ...] = ...
. However, when getting a coefficient this operator will return by value (to enforce constness), which means for example you cannot write something like arrow[a1, a2, ...].negate()
.InvalidArgument | The given sequence of integers is non-empty and its last entry is zero. |
d | a sequence of integers representing some product of diagram variables. If this sequence is non-empty, then its last entry should be strictly positive. |
|
inline |
Divides all exponents in this polynomial by k for some integer k.
This is equivalent to replacing the variable A
with A^(1/k)
.
Both positive and negative scaling factors k are allowed.
A
that appear in this polynomial with non-zero coefficients are multiples of k.FailedPrecondition | Either k is zero, or some exponent of A with a non-zero coefficient is not a multiple of k. |
k | the scaling factor to divide exponents by. |
|
inline |
Multiplies all exponents of A
in this polynomial by k for some integer k.
This is equivalent to replacing the variable A
with A^k
.
Both positive and negative scaling factors k are allowed.
k | the scaling factor to multiply exponents by. |
void regina::Arrow::set | ( | const DiagramSequence & | d, |
const Laurent< Integer > & | value ) |
Changes the Laurent polynomial in A
that is attached to the given product of diagram variables.
The new coefficient is allowed to be zero.
arrow.set(a1, a2, ...) = value
. In Python (but not C++), you can also set the attached Laurent polynomial directly using the syntax arrow[a1, a2, ...] = value
.InvalidArgument | The given sequence of integers is non-empty and its last entry is zero. |
d | a sequence of integers representing some product of diagram variables. If this sequence is non-empty, then its last entry should be strictly positive. |
value | the new Laurent polynomial that should be attached to the given product of diagram variables. |
void regina::Arrow::set | ( | const DiagramSequence & | d, |
Laurent< Integer > && | value ) |
Changes the Laurent polynomial in A
that is attached to the given product of diagram variables.
This variant of set() will move the Laurent polynomial out of the argument value, which is very fast; however, like any move operation, it will render the original argument value unusable.
The new coefficient is allowed to be zero.
arrow[a1, a2, ...] = value
.InvalidArgument | The given sequence of integers is non-empty and its last entry is zero. |
d | a sequence of integers representing some product of diagram variables. If this sequence is non-empty, then its last entry should be strictly positive. |
value | the new Laurent polynomial that should be attached to the given product of diagram variables. |
|
inline |
Multiplies this polynomial by A^s
for some integer s.
s | the power of A to multiply by. |
|
inherited |
Returns a short text representation of this object.
This text should be human-readable, should use plain ASCII characters where possible, and should not contain any newlines.
Within these limits, this short text ouptut should be as information-rich as possible, since in most cases this forms the basis for the Python __str__()
and __repr__()
functions.
__str__()
will use precisely this function, and for most classes the Python __repr__()
function will incorporate this into its output.
|
inlinenoexcept |
Swaps the contents of this and the given polynomial.
This is a fast (constant time) operation.
other | the polynomial whose contents should be swapped with this. |
|
static |
Reconstructs a polynomial from its given tight encoding.
See the page on tight encodings for details.
The tight encoding will be read from the given input stream. If the input stream contains leading whitespace then it will be treated as an invalid encoding (i.e., this routine will throw an exception). The input stream may contain further data: if this routine is successful then the input stream will be left positioned immediately after the encoding, without skipping any trailing whitespace.
InvalidInput | The given input stream does not begin with a tight encoding of an arrow polynomial. |
input | an input stream that begins with the tight encoding for an arrow polynomial. |
|
inlinestaticinherited |
Reconstructs an object of type T from its given tight encoding.
See the page on tight encodings for details.
The tight encoding should be given as a string. If this string contains leading whitespace or any trailing characters at all (including trailing whitespace), then it will be treated as an invalid encoding (i.e., this routine will throw an exception).
InvalidArgument | The given string is not a tight encoding of an object of type T. |
enc | the tight encoding for an object of type T. |
void regina::Arrow::tightEncode | ( | std::ostream & | out | ) | const |
Writes the tight encoding of this polynomial to the given output stream.
See the page on tight encodings for details.
out | the output stream to which the encoded string will be written. |
|
inlineinherited |
Returns the tight encoding of this object.
See the page on tight encodings for details.
FailedPrecondition | This may be thrown for some classes T if the object is in an invalid state. If this is possible, then a more detailed explanation of "invalid" can be found in the class documentation for T, under the member function T::tightEncode(). See FacetPairing::tightEncode() for an example of this. |
|
inherited |
Returns a short text representation of this object using unicode characters.
Like str(), this text should be human-readable, should not contain any newlines, and (within these constraints) should be as information-rich as is reasonable.
Unlike str(), this function may use unicode characters to make the output more pleasant to read. The string that is returned will be encoded in UTF-8.
|
inlineinherited |
A default implementation for detailed output.
This routine simply calls T::writeTextShort() and appends a final newline.
out | the output stream to which to write. |
void regina::Arrow::writeTextShort | ( | std::ostream & | out, |
bool | utf8 = false ) const |
Writes this polynomial to the given output stream.
If utf8 is passed as true
then unicode subscript and superscript characters will be used for diagram variables, exponents and the minus sign; these will be encoded using UTF-8. This will make the output nicer, but will require more complex fonts to be available on the user's machine.
out | the output stream to which to write. |
utf8 | true if unicode characters may be used. |
Multiplies the two given polynomials.
lhs | the first polynomial to multiply. |
rhs | the second polynomial to multiply. |