Page MenuHomec4science

vector_checker.hpp
No OneTemporary

File Metadata

Created
Sun, Sep 1, 17:51

vector_checker.hpp

/* =============================================================================
Copyright (c) 2014 - 2016
F. Georget <fabieng@princeton.edu> Princeton University
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
============================================================================= */
#ifndef SPECMICP_UTILS_VECTORCHECKER_HPP
#define SPECMICP_UTILS_VECTORCHECKER_HPP
/*!
\file eigen/vector_checker.hpp
\brief Check vectors
The functions defined is this file allow to write friendly expressions to check
the values of a vector. This is an example of possible expressions :
\code{.cpp}
Vector x;
// Check that all values are between 0.0 and 10.0 and that at least one
// value is non zero
assert((is_bounded(x, 0.0, 10.0) && (any(x) > 0.0)));
// Check that all values are greater or equal that 10
// or that all values are between 0 and 10.
assert(((all(x) >= 10.0) || (all(x) >= 0.0) && (all(x) < 10.0)));
\endcode
*/
#include "specmicp_common/types.hpp"
#include <cmath>
#include <utility>
#include "vector_checker_expr.hpp"
namespace specmicp {
//! \namespace specmicp::vector_checker
//! \brief Check values in a vector
namespace vector_checker {
//! \namespace specmicp::vector_checker::expr
//! \brief Expressions used by the vector checker
//!
//! All classes in this namespace should not be used directly
//! \namespace specmicp::vector_checker::oper
//! \brief Operators used by the vector checker
//!
//! All classes in this namespace should not be used directly
// All, Any, and Bounded
// =====================
//! \brief Wrapper around a vector for creating a 'All' condition
template <typename ScalarT>
class All
{
public:
//! \brief Constructor
All(const VectorT<ScalarT>& vector):
m_vector(vector)
{}
//! \brief Return the vector
const VectorT<ScalarT>& operator() () const {return m_vector;}
private:
const VectorT<ScalarT>& m_vector; //!< Const ref to underlying vector
};
//! \brief Create a 'All' wrapper from a vector
template <typename ScalarT>
All<ScalarT> all(const VectorT<ScalarT>& vector)
{
return All<ScalarT>(vector);
}
//! \brief Wrapper around a vector to create a 'Any' condition
template <typename ScalarT>
class Any
{
public:
//! \brief Constructor
Any(const VectorT<ScalarT>& vector):
m_vector(vector)
{}
//! \brief Return the vector
const VectorT<ScalarT>& operator() () const {return m_vector;}
private:
const VectorT<ScalarT>& m_vector; //!< Const ref to underlying vector
};
//! \brief create a 'Any' wrapper
template <typename ScalarT>
Any<ScalarT> any(const VectorT<ScalarT>& vector)
{
return Any<ScalarT>(vector);
}
//! \brief create a 'Bounded' expression
template <typename ScalarT>
expr::BoundedExpr<ScalarT> is_bounded(
const VectorT<ScalarT>& vector,
ScalarT lower,
ScalarT upper
)
{
return expr::BoundedExpr<ScalarT>(vector, lower, upper);
}
// Logical Operators
// =================
//! \brief Evaluate the logical AND between two expressions
template <typename Derived0, typename Derived1>
expr::AndBoolExpr<Derived0, Derived1> operator&& (
expr::BaseBoolExpr<Derived0>&& child_0,
expr::BaseBoolExpr<Derived1>&& child_1)
{
return expr::AndBoolExpr<Derived0, Derived1>(
std::forward<expr::BaseBoolExpr<Derived0>>(child_0),
std::forward<expr::BaseBoolExpr<Derived1>>(child_1)
);
}
//! \brief Evaluate the logical AND between two expressions
template <typename Derived0, typename Derived1>
expr::OrBoolExpr<Derived0, Derived1> operator|| (
expr::BaseBoolExpr<Derived0>&& child_0,
expr::BaseBoolExpr<Derived1>&& child_1)
{
return expr::OrBoolExpr<Derived0, Derived1>(
std::forward<expr::BaseBoolExpr<Derived0>>(child_0),
std::forward<expr::BaseBoolExpr<Derived1>>(child_1)
);
}
// Comparison Operator
// ===================
//! \namespace specmicp::vector_checker::oper
//! \brief Namespace for the operators
#ifndef SPC_DOXYGEN_SHOULD_SKIP_THIS
// it's time to get a little ugly
// These macros defines the necessary overloading functions for the operators.
// It's easy and cheap.
// This one defines a tag for the operator 'op'
// 'name' is the name of the tag
#define make_tag_operator(name, op) \
namespace oper { \
struct name \
{ \
template <typename ScalarT> \
bool operator() (const ScalarT& lhs, const ScalarT& rhs) const { \
return (lhs op rhs); \
} \
}; \
}
// This one overloads the operator 'op'
// 'name' : Tag for the operator 'op'
// 'op' : the operator
// 'class_name' : All or Any
#define make_operator_overloading_class(name, op, class_name) \
template <typename ScalarT> \
expr::class_name ## Expr<oper::name, ScalarT> operator op ( \
class_name<ScalarT>&& lhs, \
ScalarT rhs \
) \
{ \
return expr::class_name ## Expr<oper::name, ScalarT>(lhs(), rhs); \
}
// Define the necessary overload for the operator 'op'
// Name is the tag name for the operator
#define make_operator(name, op) \
make_tag_operator(name, op) \
make_operator_overloading_class(name, op, All) \
make_operator_overloading_class(name, op, Any)
// Really defines the operator
make_operator(DifferentThan, !=)
make_operator(EqualTo, ==)
make_operator(GreaterThan, >)
make_operator(GreaterThanOrEqualTo, >=)
make_operator(LessThan, <)
make_operator(LessThanOrEqualTo, <=)
// we clean up
#undef make_operator
#undef make_operator_overloading_class
#undef make_tag_operator
#endif // SPC_DOXYGEN_SHOULD_SKIP_THIS
// special operator
namespace oper {
//! \brief Check if values are finite
struct IsFinite
{
//! \brief Return true if the value is finite
//!
//! \sa std::isfinite
template <typename ScalarT>
bool operator() (const ScalarT& lhs, const ScalarT& _) const {
return (std::isfinite(lhs));
}
};
} // end namespace oper
//! \brief check that all element of a vector is finite
template <typename ScalarT>
expr::AllExpr<oper::IsFinite, ScalarT> is_finite(const VectorT<ScalarT>& vector)
{
return expr::AllExpr<oper::IsFinite, ScalarT>(vector, 0.0);
}
//! \brief create a 'LowerBounded' expression
template <typename ScalarT>
expr::AllExpr<oper::GreaterThanOrEqualTo, ScalarT> is_lower_bounded(
const VectorT<ScalarT>& vector,
ScalarT lower
)
{
return expr::AllExpr<oper::GreaterThanOrEqualTo, ScalarT>(vector, lower);
}
//! \brief create a 'UpperBounded' expression
template <typename ScalarT>
expr::AllExpr<oper::LessThanOrEqualTo, ScalarT> is_upper_bounded(
const VectorT<ScalarT>& vector,
ScalarT upper
)
{
return expr::AllExpr<oper::LessThanOrEqualTo, ScalarT>(vector, upper);
}
} //end namespace vector_checker
} //end namespace specmicp
#endif // SPECMICP_UTILS_VECTORCHECKER_HPP

Event Timeline