This class is defined in assoc.h. It is automatically included together with all associative containers (Map, SparseVector, IncidenceMatrix, etc).
This class is defined in linalg.h.
Either a functor class satisfying the extended requirements for binary operations, or an untyped template of such a class wrapped into BuildBinary or BuildBinaryIt (preferably expressed via the convenience typedef from namespace polymake::operations.
This class is defined in comparators.h. It is automatically included together with all top-level data structures.
This class is defined in ContainerChain.h. It is automatically included together with all matrix and vector classes.
This class is defined in operations.h. It is automatically included together with all top-level data structures.
enum cmp_value { cmp_lt=-1, cmp_eq=0, cmp_gt=1 };
is the return value of each comparator object. cmp_lt means that the left hand side operans is less than that on the right hand side, cmp_gt vice versa, and cmp_eq means equality.
Either a functor class satisfying the extended requirements for unary operations, or an untyped template of such a class wrapped into BuildUnary or BuildUnaryIt (preferably expressed via the convenience typedef from namespace polymake::operations.
If this is a reference, the functor object will contain a reference to the constant stored elsewhere. If it is a plain data type, the functor object will contain an own copy of the constant.
However, if the constant is a lazy evaluated expression, the functor object will store the result value computed during the functor construction, even in the reference case.
This class is defined in IndexedSubset.h. It is automatically included together with all top-level data structures.
This class is defined in GenericSet.h. It is automatically included together with all top-level data structures.

Prerequisits

using namespace polymake;

Overview

class polymorphic operator or function semantics besides the built-in operators
operations::neg -X arithmetic negation (vector, matrix)
operations::add X+Y addition (vector, matrix,) set union
operations::sub X-Y subtraction (vector, matrix,) set difference
operations::mul X*Y multiplication (all combinations of scalars, vectors, and matrices), set intersection
operations::square sqr(X) product of scalar, vector, or matrix with itself
operations::normalize X/=sqrt(sqr(X)) normalize a vector with floating-point coordinates
operations::tensor tensor_product(X,Y) tensor product of vectors
operations::div X/Y division (vector or matrix thru scalar), matrix rowwise concatenation
operations::mod X%Y
operations::bitwise_inv ~X set complement
operations::bitwise_or X|Y vector and matrix columnwise concatenation
operations::bitwise_and X&Y
operations::bitwise_xor X^Y symmetric set difference
operations::cmp X<=>Y compare objects arithmetically (scalar) or lexicographically (container), returning cmp_value. This functor (and other functionally interchangeable with it) is called thru this documentation a comparator. It can be expected to work more efficiently than two subsequent comparisons X<Y; X>Y; as practiced in STL code.
operations::cmp_epsilon compare objects applying conv<X,bool> to the difference. The latter has specializations for float and double evaluating everything within an +/- epsilon to false.
operations::positive X>0
operations::negative X<0
operations::logical_not !X compare with zero (scalar, vector, matrix). Relies upon conv<X,bool> .
operations::eq X==Y All comparison operators are based on cmp. Therefore it is necessary to specialize only the latter for each new data type.
operations::ne X!=Y
operations::lt X<Y
operations::le X<=Y
operations::gt X>Y
operations::ge X>=Y
operations::max std::max(X,Y)
operations::min std::min(X,Y)
operations::clear X() construct an object with its default container; reset an object to the default state (assignment version)
operations::concat concatenate(X,Y), X|Y concatenation (container, vector)
operations::slice select a subset (vector slice) using given element indices
operations::associative X[Y] find an element in an associative container (map)
operations::includes incl(Y,X)<1 true if XY

Interface

Functors are classes with special interface defined in STL. Briefly resembling, one functor class encodes a single operation, defined as operator(). Furthermore it must declare the type of the operation result as result_type and the types of the input parameter(s) as argument_type in case of a unary operation or as first_argument_type and second_argument_type in the binary case.

Functors in Polymake Template Library obey the same rules, but with slight modifications:

  1. In STL, all the typedef's mentioned above always refer to unqualified data types. Polymake functor may define them also as references and/or with const attribute:
    result_type
    is always the exact return type of operator(), with const and reference attributes if needed.
    argument_type, first_argument_type, second_argument_type
    if it is defined as a reference, it signals that the functor requires the argument passed to operator() be always a lvalue with suitable const qualification (that is, no temporary objects allowed.)
  2. If an operation has an assignment version (such as X+=Y), it is also accessible in the functor class as
    Left& assign(Left& X, const Right& Y);
    They always return the reference to their first argument, as the built-in assigment operators do.
  3. partial When performing a binary operation on elements of sparse containers (vectors, matrices, ...), it is useful to explicitly define the result in the situation when one operand is an implicitly given "zero". (It is much more efficient than creating a temporary zero and computing the result with the standard binary operator.)
    If the functor takes no precautions on this, the result is assumed to be zero too, and the computation is skipped at all. This is OK for multiplication or bitwise "and", but not for addition or concatenation. The functors like the latter overload the operator() with specializations looking like:
    template <typename Iterator> operator() (partial_left, first_argument_type x, Iterator y); template <typename Iterator> operator() (partial_right, Iterator x, second_argument_type y);
    partial_left and partial_right are empty tag classes and must be written verbatim.
    Iterator arguments point to the next explicit element in the sparse container (that is, after the gap); they can be safely ignored in the most cases.
  4. All functors defined in namespace pm::operations are class templates parameterized with types of input argument(s). In the most cases, these types can be automatically deduced from the context, which makes the explicit specification superfluous. (Moreover, in a nested expression involving function and class templates, it is not always easy to guess the input argument type right!)
    Unfortunately, the syntax rules of C++ do not allow to intermix classes with "naked" templates. Therefore there are two special classes introduced with the only aim to wrap the parameterless template:
    template <template <typename> class Operation> class BuildUnary; template <template <typename, typename> class Operation> class BuildBinary;

    In the most constructions taking a functor class as a class template parameter or function argument, it can be specified either as a normal class or as a functor template wrapped in BuildUnary or BuildBinary.

    For your convenience, for each functor defined in namespace pm::operations, the namespace polymake::operations defines a suitably wrapped typedef with the same name.

    Example:

    std::vector<int> V; int sum=accumulate(V, pm::operations::add<int,int>());

    and

    int sum=accumulate(V, operations::add());

    are effectively identical: both compute the sum of all vector elements.

    If the advantage of the untyped functor templates seems to you as not too much essential, try to sum the rows of a Matrix without using them.

  5. In some special cases it is more convenient to pass an iterator to the functor instead of data items it is pointing to. Most often such functors are used in pseudo-containers. There are three possibilities to build a functor with this kind of interface:
    Whatever design you choose, this special interface will be automatically recognized in all pseudo-container classes and basic algorithms.

Overloaded operations

A functor encoding an operation overloaded for various input types must be specialized for each input type (or pair in the binary case) that yields a different result type. If you need to define your own overloaded functors, you can use the discriminant mechanism shown in the following examples:

  1. Unary operation (here: negation)
    template <typename OpRef, typename Discr=typename object_traits<typename deref<OpRef>::type>::generic_tag> struct neg_impl;

    The first parameter is an input operand type; it can happen to be a reference (especially when instantiated via BuildUnary), therefore the pure data type must be first distilled using pm::deref.

    The discriminant Discr may belong to one of the following types (the list is not exhausting):

    is_scalar
    if an operand is a number (int, double, Rational, and so on);
    is_set
    if an operand is a GenericSet
    is_vector
    if an operand is a GenericVector
    is_matrix
    if an operand is a GenericMatrix
    is_incidence_matrix
    if an operand is a GenericIncidenceMatrix
  2. Binary operation (here: multiplication)
    template <typename LeftRef, typename RightRef, bool check=false, typename Discr=typename isomorphic<typename deref<LeftRef>::type, typename deref<RightRef>::type>::discriminant> struct mul_impl;

    Works similar to the unary case; the type isomorphic<...>::discriminant is always a cons pair of discriminant tags (from the list above) for the operands:

    cons<is_scalar, is_scalar>
    means multiplication of two numbers;
    cons<is_vector, is_scalar>
    multiplication of a vector with a scalar from right;
    cons<is_matrix, is_matrix>
    matrix multiplication;
    cons<is_set, is_set>
    set intersection.
    ... and so on

The additional template parameter Discr should be hidden in the auxiliary class implementing the operation (such as neg_impl or mul_impl,) so that the front class (neg or mul) can be used in conjuction with BuildUnary or BuildBinary wrappers. The relation between the classes is obvious:

template <typename LeftRef, typename RightRef> struct mul : public mul_impl<LeftRef,RightRef> { };

Compound operations

template <typename ConstantRef, typename Operation> struct operations::fix1;
The resulting operation is a unary operation, forwarding the arguments as the second operands to the given binary Operation. The first argument has a fixed value passed over to the constructor.
This class does essentially the same as the standard std::binder1st class, but implements the extended interface described above and can be used with untyped operation templates wrapped into BuildBinary or BuildBinaryIt.
template <typename ConstantRef, typename Operation> struct operations::fix2;
The same as above, fixing the second argument. Compare with the std::binder2nd class.
template <typename InnerOperation, typename OuterOperation> struct operations::composed11;
A composition of two unary operations. The arguments are forwarded to the InnerOperation, then the results are passed over to the OuterOperation.
This class does essentially the same as the standard unary_compose class, but implements the extended interface described above and can be used with untyped operation templates wrapped into BuildUnary or BuildUnaryIt.
Please note that the template parameter order is reversed compared to the standard class. Think of composed11 as of a pipe: InnerOperation | OuterOperation.
template <typename InnerOperation, typename OuterOperation> struct operations::composed21;
A composition of an (inner) binary and an (outer) unary operations. The arguments are forwarded to the InnerOperation, then the results are passed over to the OuterOperation.
This class does essentially the same as the standard binary_compose class, but implements the extended interface described above and can be used with untyped operation templates wrapped into BuildUnary or BuildUnaryIt. Besides this, it inherits the partial definedness of the inner binary operation.
Please note that the template parameter order is reversed compared to the standard class. Think of composed21 as of a pipe: InnerOperation | OuterOperation.
template <typename InnerOperation1, typename InnerOperation2, typename OuterOperation> class operations::composed12;
A composition of (inner) unary operations and an (outer) binary operation. The first argument is forwarded to the InnerOperation1, the second to the InnerOperation2, then the results are passed over to the OuterOperation.
There are specializations computing the following special cases more efficiently:
composed12<void, InnerOperation2, OuterOperation>
passes the first operand unchanged to the outer binary operation;
composed12<InnerOperation1, void, OuterOperation>
passes the second operand unchanged to the outer binary operation;
composed12<InnerOperation, OuterOperation, void>
applies the same inner unary operation to both operands. The functor object really contains only one inner functor.