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 linalg.h.
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.
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 comparators.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.
This class is defined in operations.h.
It is automatically included together with all top-level data structures.
This class is defined in IndexedSubset.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.
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.
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.
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.
compare objects applying conv<X,bool> to the difference.
The latter has specializations for float and double evaluating everything
within an +/- epsilon to false.
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:
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.
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.)
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.
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:
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.
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>());
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.
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:
Define argument_type, etc. as the exact iterator type the functor expects.
Define argument_type as <void and write the operator() as a
member template parameterized with input iterator type(s).
Make the functor a class template parameterized with input iterator type(s), and pass it to
the algorithms as an untyped template wrapped into one of the following classes:
template <template <typename> class Operation> class BuildUnaryIt;
template <template <typename, typename> class Operation> class BuildBinaryIt;
Whatever design you choose, this special interface will be automatically recognized in all
pseudo-container classes and
basic algorithms.
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:
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);
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> { };
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.
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.
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.
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.