10#ifndef THYRA_VECTOR_STD_OPS_HPP
11#define THYRA_VECTOR_STD_OPS_HPP
13#include "Thyra_VectorStdOps_decl.hpp"
14#include "Thyra_VectorSpaceBase.hpp"
15#include "Thyra_VectorBase.hpp"
16#include "RTOpPack_ROpGetElement.hpp"
17#include "RTOpPack_TOpSetElement.hpp"
18#include "RTOpPack_ROpMin.hpp"
19#include "RTOpPack_ROpMinIndex.hpp"
20#include "RTOpPack_ROpMinIndexGreaterThanBound.hpp"
21#include "RTOpPack_ROpMax.hpp"
22#include "RTOpPack_ROpMaxIndex.hpp"
23#include "RTOpPack_ROpMaxIndexLessThanBound.hpp"
24#include "RTOpPack_ROpSum.hpp"
25#include "RTOpPack_TOpAddScalar.hpp"
26#include "RTOpPack_TOpEleWiseDivide.hpp"
27#include "RTOpPack_TOpEleWiseProd.hpp"
28#include "RTOpPack_TOpPairWiseMax.hpp"
29#include "RTOpPack_TOpEleWiseConjProd.hpp"
30#include "RTOpPack_TOpEleWiseProdUpdate.hpp"
31#include "RTOpPack_TOpPairWiseMaxUpdate.hpp"
32#include "RTOpPack_TOpRandomize.hpp"
33#include "Teuchos_Assert.hpp"
34#include "Teuchos_Assert.hpp"
51 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
52 RTOpPack::ROpSum<Scalar> sum_op;
55 tuple(ptrInArg(v_rhs)),
58 return sum_op(*sum_targ);
97 return v_rhs2.
dot(v_rhs1);
101template<
class Scalar>
104 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
112 get_ele_targ.
ptr() );
113 return get_ele_op(*get_ele_targ);
120template<
class Scalar>
123 using Teuchos::tuple;
using Teuchos::null;
135template<
class Scalar>
138 v_lhs->assign(alpha);
142template<
class Scalar>
146 v_lhs->assign(v_rhs);
150template<
class Scalar>
153 using Teuchos::tuple;
using Teuchos::null;
157 tuple(v_lhs), null );
161template<
class Scalar>
168template<
class Scalar>
175template<
class Scalar>
182template<
class Scalar>
188 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
190 applyOp<Scalar>( ele_wise_prod_op, tuple(ptrInArg(v_rhs1),ptrInArg(v_rhs2)),
191 tuple(v_lhs), null );
194template<
class Scalar>
200 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
202 applyOp<Scalar>( pair_wise_max_op, tuple(ptrInArg(v_rhs1),ptrInArg(v_rhs2)),
203 tuple(v_lhs), null );
207template<
class Scalar>
213 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
215 applyOp<Scalar>( ele_wise_conj_prod_op, tuple(ptrInArg(v_rhs1),ptrInArg(v_rhs2)),
216 tuple(v_lhs), null );
220template<
class Scalar>
224 y->ele_wise_scale(x);
228template<
class Scalar>
239template<
class Scalar>
245 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
248 tuple(v_lhs), null );
252template<
class Scalar>
258 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
261 tuple(v_lhs), null );
266template<
class Scalar>
275template<
class Scalar>
282 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
284 applyOp<Scalar>( ele_wise_divide_op, tuple(ptrInArg(v_rhs1),ptrInArg(v_rhs2)),
285 tuple(v_lhs), null );
289template<
class Scalar>
297 y->linear_combination(alpha, x, beta);
301template<
class Scalar>
308template<
class Scalar>
323template<
class Scalar>
330template<
class Scalar>
337template<
class Scalar>
344template<
class Scalar>
351template<
class Scalar>
356 using Teuchos::tuple;
using Teuchos::ptrInArg;
362template<
class Scalar>
367 v_lhs->update(alpha, v_rhs);
371template<
class Scalar>
376 using Teuchos::tuple;
using Teuchos::ptrInArg;
384template<
class Scalar>
391template<
class Scalar>
398template<
class Scalar>
403 using Teuchos::tuple;
using Teuchos::ptrInArg;
406 tuple(ST::one(),ST::one()),
407 tuple(ptrInArg(x),ptrInArg(y)),
413template<
class Scalar>
418 using Teuchos::tuple;
using Teuchos::ptrInArg;
421 tuple(ST::one(),Scalar(-ST::one())),
422 tuple(ptrInArg(x),ptrInArg(y)),
428template<
class Scalar>
433 using Teuchos::tuple;
using Teuchos::ptrInArg;
436 tuple(alpha, ST::one()), tuple(ptrInArg(x),ptrInArg(y)),
442template<
class Scalar>
447 using Teuchos::tuple;
using Teuchos::ptrInArg;
450 tuple(ST::one(), alpha), tuple(ptrInArg(x),ptrInArg(y)),
456template<
class Scalar>
461 using Teuchos::tuple;
using Teuchos::ptrInArg;
464 tuple(alpha, beta), tuple(ptrInArg(x),ptrInArg(y)),
475template<
class Scalar>
477 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
478 RTOpPack::ROpMin<Scalar> min_op;
483 return min_op(*min_targ);
487template<
class Scalar>
492 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
499 *minEle = scalarIndex.
scalar;
500 *minIndex = scalarIndex.
index;
504template<
class Scalar>
509 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
516 *minEle = scalarIndex.
scalar;
517 *minIndex = scalarIndex.
index;
521template<
class Scalar>
524 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
525 RTOpPack::ROpMax<Scalar> max_op;
530 return max_op(*max_targ);
534template<
class Scalar>
539 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
546 *maxEle = scalarIndex.
scalar;
547 *maxIndex = scalarIndex.
index;
551template<
class Scalar>
556 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
563 *maxEle = scalarIndex.
scalar;
564 *maxIndex = scalarIndex.
index;
573#define THYRA_VECTOR_STD_OPS_INSTANT(SCALAR) \
575 template SCALAR sum( const VectorBase<SCALAR >& v_rhs ); \
577 template ScalarTraits<SCALAR >::magnitudeType \
578 norm_1( const VectorBase<SCALAR >& v_rhs ); \
580 template ScalarTraits<SCALAR >::magnitudeType \
581 norm_2( const VectorBase<SCALAR >& v_rhs ); \
583 template ScalarTraits<SCALAR >::magnitudeType \
584 norm_2( const VectorBase<SCALAR >& w, const VectorBase<SCALAR >& v ); \
586 template ScalarTraits<SCALAR >::magnitudeType \
587 norm_inf( const VectorBase<SCALAR >& v_rhs ); \
589 template SCALAR dot( const VectorBase<SCALAR >& v_rhs1, const VectorBase<SCALAR >& v_rhs2 ); \
591 template SCALAR get_ele( const VectorBase<SCALAR >& v, Ordinal i ); \
593 template void set_ele( Ordinal i, SCALAR alpha, const Ptr<VectorBase<SCALAR > > &v ); \
595 template void put_scalar( const SCALAR& alpha, const Ptr<VectorBase<SCALAR > > &v_lhs ); \
597 template void copy( const VectorBase<SCALAR >& v_rhs, \
598 const Ptr<VectorBase<SCALAR > > &v_lhs ); \
600 template void add_scalar( const SCALAR& alpha, const Ptr<VectorBase<SCALAR > > &v_lhs ); \
602 template void scale( const SCALAR& alpha, const Ptr<VectorBase<SCALAR > > &v_lhs ); \
604 template void abs( const VectorBase< SCALAR > &x, const Ptr<VectorBase< SCALAR > > &y ); \
606 template void reciprocal( const VectorBase< SCALAR > &x, const Ptr<VectorBase< SCALAR > > &y ); \
608 template void ele_wise_prod( \
609 const SCALAR& alpha, const VectorBase<SCALAR >& v_rhs1, \
610 const VectorBase<SCALAR >& v_rhs2, const Ptr<VectorBase<SCALAR > > &v_lhs \
613 template void ele_wise_conj_prod( \
614 const SCALAR& alpha, const VectorBase<SCALAR >& v_rhs1, \
615 const VectorBase<SCALAR >& v_rhs2, const Ptr<VectorBase<SCALAR > > &v_lhs \
618 template void ele_wise_scale( const VectorBase<SCALAR>& x, \
619 const Ptr<VectorBase<SCALAR> > &y ); \
621 template void Vp_StVtV( \
622 const Ptr<VectorBase<SCALAR > > &v_lhs, \
623 const SCALAR& alpha, const VectorBase<SCALAR >& v_rhs1, \
624 const VectorBase<SCALAR >& v_rhs2 \
627 template void ele_wise_prod_update( \
628 const SCALAR& alpha, const VectorBase<SCALAR >& v_rhs1, \
629 const Ptr<VectorBase<SCALAR > > &v_lhs \
632 template void Vt_StV( \
633 const Ptr<VectorBase<SCALAR > > &v_lhs, \
634 const SCALAR& alpha, const VectorBase<SCALAR >& x ); \
636 template void ele_wise_divide( \
637 const SCALAR& alpha, const VectorBase<SCALAR >& v_rhs1, \
638 const VectorBase<SCALAR >& v_rhs2, \
639 const Ptr<VectorBase<SCALAR > > &v_lhs \
642 template void linear_combination( \
643 const ArrayView<const SCALAR > &alpha, \
644 const ArrayView<const Ptr<const VectorBase<SCALAR > > > &x, \
645 const SCALAR &beta, \
646 const Ptr<VectorBase<SCALAR > > &y \
649 template void seed_randomize<SCALAR >( unsigned int s ); \
651 template void randomize( SCALAR l, SCALAR u, const Ptr<VectorBase<SCALAR > > &v ); \
653 template void assign( const Ptr<VectorBase<SCALAR > > &v_lhs, const SCALAR& alpha ); \
655 template void assign( const Ptr<VectorBase<SCALAR > > &v_lhs, const VectorBase<SCALAR >& v_rhs ); \
657 template void Vp_S( const Ptr<VectorBase<SCALAR > > &v_lhs, const SCALAR& alpha ); \
659 template void Vt_S( const Ptr<VectorBase<SCALAR > > &v_lhs, const SCALAR& alpha ); \
661 template void V_StV( const Ptr<VectorBase<SCALAR > > &y, const SCALAR& alpha, \
662 const VectorBase<SCALAR > &x \
665 template void Vp_StV( const Ptr<VectorBase<SCALAR > > &v_lhs, const SCALAR& alpha, \
666 const VectorBase<SCALAR >& v_rhs \
669 template void Vp_V( const Ptr<VectorBase<SCALAR > > &y, const VectorBase<SCALAR >& x, \
673 template void V_V( const Ptr<VectorBase<SCALAR > > &y, const VectorBase<SCALAR >& x ); \
675 template void V_S( const Ptr<VectorBase<SCALAR > > &y, const SCALAR& alpha ); \
677 template void V_VpV( const Ptr<VectorBase<SCALAR > > &z, const VectorBase<SCALAR >& x, \
678 const VectorBase<SCALAR >& y \
681 template void V_VmV( const Ptr<VectorBase<SCALAR > > &z, const VectorBase<SCALAR >& x, \
682 const VectorBase<SCALAR >& y \
685 template void V_StVpV( const Ptr<VectorBase<SCALAR > > &z, const SCALAR &alpha, \
686 const VectorBase<SCALAR >& x, const VectorBase<SCALAR >& y \
689 template void V_VpStV( const Ptr<VectorBase<SCALAR > > &z, \
690 const VectorBase<SCALAR >& x, \
691 const SCALAR &alpha, const VectorBase<SCALAR >& y ); \
693 template void V_StVpStV( const Ptr<VectorBase<SCALAR > > &z, const SCALAR &alpha, \
694 const VectorBase<SCALAR >& x, const SCALAR &beta, const VectorBase<SCALAR >& y \
699#define THYRA_VECTOR_STD_OPS_REAL_INSTANT(SCALAR) \
701 template SCALAR min( const VectorBase<SCALAR >& x ); \
703 template void pair_wise_max( \
704 const SCALAR& alpha, const VectorBase<SCALAR >& v_rhs1, \
705 const VectorBase<SCALAR >& v_rhs2, const Ptr<VectorBase<SCALAR > > &v_lhs \
708 template void pair_wise_max_update( \
709 const SCALAR& alpha, const VectorBase<SCALAR >& v_rhs1, \
710 const Ptr<VectorBase<SCALAR > > &v_lhs \
713 template void min( const VectorBase<SCALAR >& x, \
714 const Ptr<SCALAR > &minEle, const Ptr<Ordinal> &minIndex \
717 template void minGreaterThanBound( const VectorBase<SCALAR >& x, \
718 const SCALAR &bound, const Ptr<SCALAR > &minEle, const Ptr<Ordinal> &minIndex \
721 template SCALAR max( const VectorBase<SCALAR >& x ); \
723 template void max( const VectorBase<SCALAR >& x, \
724 const Ptr<SCALAR > &maxEle, const Ptr<Ordinal> &maxIndex \
727 template void maxLessThanBound( const VectorBase<SCALAR >& x, \
728 const SCALAR &bound, const Ptr<SCALAR > &maxEle, const Ptr<Ordinal> &maxIndex \
Teuchos::RCP< ReductTarget > reduct_obj_create() const
static void set_static_seed(const unsigned int static_seed)
RCP< const LinearOpBase< Scalar > > scale(const Scalar &scalar, const RCP< const LinearOpBase< Scalar > > &Op, const std::string &label="")
Build an implicit const scaled linear operator.
void assign(const Ptr< MultiVectorBase< Scalar > > &V, Scalar alpha)
V = alpha.
void randomize(Scalar l, Scalar u, const Ptr< MultiVectorBase< Scalar > > &V)
Generate a random multi-vector with elements uniformly distributed elements.
void V_VpV(const Ptr< MultiVectorBase< Scalar > > &Z, const MultiVectorBase< Scalar > &X, const MultiVectorBase< Scalar > &Y)
Z(i,j) = X(i,j) + Y(i,j), i = 0...Z->range()->dim()-1, j = 0...Z->domain()->dim()-1.
void Vt_S(const Ptr< MultiVectorBase< Scalar > > &Z, const Scalar &alpha)
Z(i,j) *= alpha, i = 0...Z->range()->dim()-1, j = 0...Z->domain()->dim()-1.
ScalarTraits< Scalar >::magnitudeType norm_1(const MultiVectorBase< Scalar > &V)
Take the induced matrix one norm of a multi-vector.
void V_VmV(const Ptr< MultiVectorBase< Scalar > > &Z, const MultiVectorBase< Scalar > &X, const MultiVectorBase< Scalar > &Y)
Z(i,j) = X(i,j) - Y(i,j), i = 0...Z->range()->dim()-1, j = 0...Z->domain()->dim()-1.
void linear_combination(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &X, const Scalar &beta, const Ptr< MultiVectorBase< Scalar > > &Y)
Y.col(j)(i) = beta*Y.col(j)(i) + sum( alpha[k]*X[k].col(j)(i), k=0...m-1 ), for i = 0....
void V_StVpV(const Ptr< MultiVectorBase< Scalar > > &Z, const Scalar &alpha, const MultiVectorBase< Scalar > &X, const MultiVectorBase< Scalar > &Y)
Z(i,j) = alpha*X(i,j) + Y(i), i = 0...z->space()->dim()-1, , j = 0...Z->domain()->dim()-1.
void Vp_V(const Ptr< MultiVectorBase< Scalar > > &Z, const MultiVectorBase< Scalar > &X)
Z(i,j) += X(i,j), i = 0...Z->range()->dim()-1, j = 0...Z->domain()->dim()-1.
void Vp_S(const Ptr< MultiVectorBase< Scalar > > &Z, const Scalar &alpha)
Z(i,j) += alpha, i = 0...Z->range()->dim()-1, j = 0...Z->domain()->dim()-1.
Abstract interface for finite-dimensional dense vectors.
void ele_wise_divide(const Scalar &alpha, const VectorBase< Scalar > &x, const VectorBase< Scalar > &v, const Ptr< VectorBase< Scalar > > &y)
Element-wise division update: y(i) += alpha * x(i) / v(i), i = 0...y->space()->dim()-1.
void scale(const Scalar &alpha, const Ptr< VectorBase< Scalar > > &y)
Scale all elements by a scalar: y(i) *= alpha, i = 0...y->space()->dim()-1.
void maxLessThanBound(const VectorBase< Scalar > &x, const Scalar &bound, const Ptr< Scalar > &maxEle, const Ptr< Ordinal > &maxIndex)
Max element less than bound and its index: Returns maxEle = x(k) and maxIndex = k such that x(k) >= x...
void abs(const VectorBase< Scalar > &x, const Ptr< VectorBase< Scalar > > &y)
Element-wise absolute value: y(i) = abs(x(i)), i = 0...y->space()->dim()-1.
void pair_wise_max_update(const Scalar &alpha, const VectorBase< Scalar > &x, const Ptr< VectorBase< Scalar > > &y)
Element-wise maximum update: y(i) = alpha * max(x(i), y(i)), i = 0...y->space()->dim()-1.
Teuchos::ScalarTraits< Scalar >::magnitudeType norm_1() const
One (1) norm: result = ||v||1.
void Vp_StV(const Ptr< VectorBase< Scalar > > &y, const Scalar &alpha, const VectorBase< Scalar > &x)
AXPY: y(i) = alpha * x(i) + y(i), i = 0...y->space()->dim()-1.
void V_VpStV(const Ptr< VectorBase< Scalar > > &z, const VectorBase< Scalar > &x, const Scalar &alpha, const VectorBase< Scalar > &y)
z(i) = x(i) + alpha*y(i), i = 0...z->space()->dim()-1.
void set_ele(Ordinal i, Scalar alpha, const Ptr< VectorBase< Scalar > > &v)
Set single element: v(i) = alpha.
Scalar dot(const VectorBase< Scalar > &x) const
Euclidean dot product: result = x^H * this.
Teuchos::ScalarTraits< Scalar >::magnitudeType norm_2(const VectorBase< Scalar > &v)
Euclidean (2) norm: result = ||v||2.
void ele_wise_scale(const VectorBase< Scalar > &x, const Ptr< VectorBase< Scalar > > &y)
Element-wise scaling: y(i) *= x(i), i = 0...y->space()->dim()-1.
void Vt_StV(const Ptr< VectorBase< Scalar > > &y, const Scalar &alpha, const VectorBase< Scalar > &x)
Element-wise product update: y(i) *= alpha * x(i), i = 0...y->space()->dim()-1.
Teuchos::ScalarTraits< Scalar >::magnitudeType norm_inf(const VectorBase< Scalar > &v_rhs)
Infinity norm: result = ||v||inf.
void V_StV(const Ptr< VectorBase< Scalar > > &y, const Scalar &alpha, const VectorBase< Scalar > &x)
Assign scaled vector: y(i) = alpha * x(i), i = 0...y->space()->dim()-1.
void linear_combination(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const VectorBase< Scalar > > > &x, const Scalar &beta)
Linear combination:
Scalar min(const VectorBase< Scalar > &x)
Min element: result = min{ x(i), i = 0...x.space()->dim()-1 } .
Scalar sum(const VectorBase< Scalar > &v)
Sum of vector elements: result = sum( v(i), i = 0...v.space()->dim()-1 ).
void ele_wise_prod_update(const Scalar &alpha, const VectorBase< Scalar > &x, const Ptr< VectorBase< Scalar > > &y)
Element-wise product update: y(i) *= alpha * x(i), i = 0...y->space()->dim()-1.
Scalar get_ele(const VectorBase< Scalar > &v, Ordinal i)
Get single element: result = v(i).
void seed_randomize(unsigned int s)
Seed the random number generator used in randomize().
void V_S(const Ptr< VectorBase< Scalar > > &y, const Scalar &alpha)
y(i) = alpha, i = 0...y->space()->dim()-1.
void pair_wise_max(const Scalar &alpha, const VectorBase< Scalar > &x, const VectorBase< Scalar > &v, const Ptr< VectorBase< Scalar > > &y)
Element-wise maximum: y(i) = alpha * max(x(i), v(i)), i = 0...y->space()->dim()-1.
void minGreaterThanBound(const VectorBase< Scalar > &x, const Scalar &bound, const Ptr< Scalar > &minEle, const Ptr< Ordinal > &minIndex)
Minimum element greater than some bound and its index: Returns minEle = x(k) and minIndex = k such th...
void V_V(const Ptr< VectorBase< Scalar > > &y, const VectorBase< Scalar > &x)
y(i) = x(i), i = 0...y->space()->dim()-1.
void put_scalar(const Scalar &alpha, const Ptr< VectorBase< Scalar > > &y)
Assign all elements to a scalar: y(i) = alpha, i = 0...y->space()->dim()-1.
void applyOp(const RTOpPack::RTOpT< Scalar > &op, const ArrayView< const Ptr< const VectorBase< Scalar > > > &vecs, const ArrayView< const Ptr< VectorBase< Scalar > > > &targ_vecs, const Ptr< RTOpPack::ReductTarget > &reduct_obj, const Ordinal global_offset) const
Calls applyOpImpl().
void ele_wise_conj_prod(const Scalar &alpha, const VectorBase< Scalar > &x, const VectorBase< Scalar > &v, const Ptr< VectorBase< Scalar > > &y)
Element-wise conjugate product update: y(i) += alpha * conj(x(i)) * v(i), i = 0......
void reciprocal(const VectorBase< Scalar > &x, const Ptr< VectorBase< Scalar > > &y)
Element-wise reciprocal: y(i) = 1/x(i), i = 0...y->space()->dim()-1.
void assign(const VectorBase< Scalar > &x)
Vector assignment:
void ele_wise_prod(const Scalar &alpha, const VectorBase< Scalar > &x, const VectorBase< Scalar > &v, const Ptr< VectorBase< Scalar > > &y)
Element-wise product update: y(i) += alpha * x(i) * v(i), i = 0...y->space()->dim()-1.
void Vp_StVtV(const Ptr< VectorBase< Scalar > > &y, const Scalar &alpha, const VectorBase< Scalar > &x, const VectorBase< Scalar > &v)
Element-wise product update: y(i) += alpha * x(i) * v(i), i = 0...y->space()->dim()-1.
Scalar dot(const VectorBase< Scalar > &x, const VectorBase< Scalar > &y)
Dot product: result = conj(x)'*y.
void copy(const VectorBase< Scalar > &x, const Ptr< VectorBase< Scalar > > &y)
Vector assignment: y(i) = x(i), i = 0...y->space()->dim()-1.
void V_StVpStV(const Ptr< VectorBase< Scalar > > &z, const Scalar &alpha, const VectorBase< Scalar > &x, const Scalar &beta, const VectorBase< Scalar > &y)
z(i) = alpha*x(i) + beta*y(i), i = 0...z->space()->dim()-1.
Scalar max(const VectorBase< Scalar > &x)
Max element: result = max{ x(i), i = 1...n } .
Teuchos::ScalarTraits< Scalar >::magnitudeType norm_2() const
Euclidean (2) norm: result = ||v||2.
virtual RCP< const VectorSpaceBase< Scalar > > space() const =0
Return a smart pointer to the vector space that this vector belongs to.
Teuchos::ScalarTraits< Scalar >::magnitudeType norm_inf() const
Infinity norm: result = ||v||inf.
void add_scalar(const Scalar &alpha, const Ptr< VectorBase< Scalar > > &y)
Add a scalar to all elements: y(i) += alpha, i = 0...y->space()->dim()-1.
#define TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(index, lower_inclusive, upper_exclusive)