/usr/include/boost/accumulators/numeric/functional
Edit: /usr/include/boost/accumulators/numeric/functional/valarray.hpp (15612B)
///////////////////////////////////////////////////////////////////////////////
/// \file valarray.hpp
///
// Copyright 2005 Eric Niebler. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_NUMERIC_FUNCTIONAL_VALARRAY_HPP_EAN_12_12_2005
#define BOOST_NUMERIC_FUNCTIONAL_VALARRAY_HPP_EAN_12_12_2005
#ifdef BOOST_NUMERIC_FUNCTIONAL_HPP_INCLUDED
# error Include this file before boost/accumulators/numeric/functional.hpp
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace boost { namespace numeric
{
namespace operators
{
namespace acc_detail
{
template
struct make_valarray
{
typedef std::valarray type;
};
}
///////////////////////////////////////////////////////////////////////////////
// Handle valarray / Right where Right is a scalar and Right != Left.
template
typename lazy_enable_if<
mpl::and_, mpl::not_ > >
, acc_detail::make_valarray >
>::type
operator /(std::valarray const &left, Right const &right)
{
typedef typename functional::divides::result_type value_type;
std::valarray result(left.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::divides(left[i], right);
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Handle valarray * Right where Right is a scalar and Right != Left.
template
typename lazy_enable_if<
mpl::and_, mpl::not_ > >
, acc_detail::make_valarray >
>::type
operator *(std::valarray const &left, Right const &right)
{
typedef typename functional::multiplies::result_type value_type;
std::valarray result(left.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::multiplies(left[i], right);
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Handle valarray + valarray where Right != Left.
template
typename lazy_disable_if<
is_same
, acc_detail::make_valarray >
>::type
operator +(std::valarray const &left, std::valarray const &right)
{
typedef typename functional::plus::result_type value_type;
std::valarray result(left.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::plus(left[i], right[i]);
}
return result;
}
}
namespace functional
{
struct std_valarray_tag;
template
struct tag >
{
typedef std_valarray_tag type;
};
#ifdef __GLIBCXX__
template
struct tag >
{
typedef std_valarray_tag type;
};
#endif
/// INTERNAL ONLY
///
// This is necessary because the GCC stdlib uses expression templates, and
// typeof(som-valarray-expression) is not an instance of std::valarray
#define BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(Name, Op) \
template \
struct Name \
{ \
typedef Left first_argument_type; \
typedef Right second_argument_type; \
typedef typename Left::value_type left_value_type; \
typedef typename Right::value_type right_value_type; \
typedef \
std::valarray< \
typename Name::result_type \
> \
result_type; \
result_type \
operator ()(Left &left, Right &right) const \
{ \
return numeric::promote >(left) \
Op numeric::promote >(right); \
} \
}; \
template \
struct Name \
{ \
typedef Left first_argument_type; \
typedef Right second_argument_type; \
typedef typename Left::value_type left_value_type; \
typedef \
std::valarray< \
typename Name::result_type \
> \
result_type; \
result_type \
operator ()(Left &left, Right &right) const \
{ \
return numeric::promote >(left) Op right;\
} \
}; \
template \
struct Name \
{ \
typedef Left first_argument_type; \
typedef Right second_argument_type; \
typedef typename Right::value_type right_value_type; \
typedef \
std::valarray< \
typename Name::result_type \
> \
result_type; \
result_type \
operator ()(Left &left, Right &right) const \
{ \
return left Op numeric::promote >(right);\
} \
};
BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(plus, +)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(minus, -)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(multiplies, *)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(divides, /)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(modulus, %)
#undef BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP
///////////////////////////////////////////////////////////////////////////////
// element-wise min of std::valarray
template
struct min_assign
{
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const
{
BOOST_ASSERT(left.size() == right.size());
for(std::size_t i = 0, size = left.size(); i != size; ++i)
{
if(numeric::less(right[i], left[i]))
{
left[i] = right[i];
}
}
}
};
///////////////////////////////////////////////////////////////////////////////
// element-wise max of std::valarray
template
struct max_assign
{
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const
{
BOOST_ASSERT(left.size() == right.size());
for(std::size_t i = 0, size = left.size(); i != size; ++i)
{
if(numeric::greater(right[i], left[i]))
{
left[i] = right[i];
}
}
}
};
// partial specialization of numeric::fdiv<> for std::valarray.
template
struct fdiv
: mpl::if_<
are_integral
, divides
, divides
>::type
{};
// promote
template
struct promote
{
typedef From argument_type;
typedef To result_type;
To operator ()(From &arr) const
{
typename remove_const::type res(arr.size());
for(std::size_t i = 0, size = arr.size(); i != size; ++i)
{
res[i] = numeric::promote(arr[i]);
}
return res;
}
};
template
struct promote
{
typedef ToFrom argument_type;
typedef ToFrom result_type;
ToFrom &operator ()(ToFrom &tofrom) const
{
return tofrom;
}
};
// for "promoting" a std::valarray to a bool, useful for
// comparing 2 valarrays for equality:
// if(numeric::promote(a == b))
template
struct promote
{
typedef From argument_type;
typedef bool result_type;
bool operator ()(From &arr) const
{
BOOST_MPL_ASSERT((is_same));
for(std::size_t i = 0, size = arr.size(); i != size; ++i)
{
if(!arr[i])
{
return false;
}
}
return true;
}
};
template
struct promote
: promote
{};
///////////////////////////////////////////////////////////////////////////////
// functional::as_min
template
struct as_min
{
typedef T argument_type;
typedef typename remove_const::type result_type;
typename remove_const::type operator ()(T &arr) const
{
return 0 == arr.size()
? T()
: T(numeric::as_min(arr[0]), arr.size());
}
};
///////////////////////////////////////////////////////////////////////////////
// functional::as_max
template
struct as_max
{
typedef T argument_type;
typedef typename remove_const::type result_type;
typename remove_const::type operator ()(T &arr) const
{
return 0 == arr.size()
? T()
: T(numeric::as_max(arr[0]), arr.size());
}
};
///////////////////////////////////////////////////////////////////////////////
// functional::as_zero
template
struct as_zero
{
typedef T argument_type;
typedef typename remove_const::type result_type;
typename remove_const::type operator ()(T &arr) const
{
return 0 == arr.size()
? T()
: T(numeric::as_zero(arr[0]), arr.size());
}
};
///////////////////////////////////////////////////////////////////////////////
// functional::as_one
template
struct as_one
{
typedef T argument_type;
typedef typename remove_const::type result_type;
typename remove_const::type operator ()(T &arr) const
{
return 0 == arr.size()
? T()
: T(numeric::as_one(arr[0]), arr.size());
}
};
} // namespace functional
}} // namespace boost::numeric
#endif