|
Ublas : |
From: Gunter Winkler (guwi17_at_[hidden])
Date: 2006-11-15 04:00:26
On Tuesday 14 November 2006 17:52, Manoj Rajagopalan wrote:
> 1. Is there already a function in ublas that does something like this? I
> looked up the documentation and some of the ublas code but I couldn't
> locate anything but I feel such a requirement should be fairly common so
> I may have missed something.
I currently use this code:
namespace functor {
template <class T>
struct log
{
public:
typedef T value_type;
typedef T result_type;
static
result_type apply(const value_type& x)
{
return std::log(x);
}
};
template <class T>
struct maximum
{
public:
typedef T value_type;
typedef T result_type;
static
result_type apply(const value_type& x, const value_type& y)
{
return std::max(x, y);
}
static
result_type initial_value()
{
return (-std::numeric_limits<result_type>::max());
}
static
void update(result_type& t, const value_type& x)
{
if (x>t) t=x;
}
};
template <class T>
struct minimum
{
public:
typedef T value_type;
typedef T result_type;
static
result_type apply(const value_type& x, const value_type& y)
{
return std::min(x, y);
}
static
result_type initial_value()
{
return (std::numeric_limits<result_type>::max());
}
static
void update(result_type& t, const value_type& x)
{
if (x<t) t=x;
}
};
template <class T>
struct log_minimum
{
public:
typedef T value_type;
typedef T result_type;
static
result_type initial_value()
{
return std::log(std::numeric_limits<result_type>::max());
}
static
void update(result_type& t, const value_type& x)
{
if ( (x>0) && (std::log(x)<t) ) t = std::log(x);
}
};
}
// //////////// general vector to scalar expression /////////
// pitfalls:
// the result is OP::initial_value() for "empty" sparse vectors,
// zero elements that are not stored may be ignored
template<class T, class OP>
struct general_vector_scalar_unary:
public vector_scalar_unary_functor<T> {
typedef typename vector_scalar_unary_functor<T>::size_type size_type;
typedef typename vector_scalar_unary_functor<T>::difference_type difference_type;
typedef typename vector_scalar_unary_functor<T>::value_type value_type;
typedef typename vector_scalar_unary_functor<T>::result_type result_type;
// general case, access by index
template<class E>
static BOOST_UBLAS_INLINE
result_type apply (const vector_expression<E> &e) {
result_type t = OP::initial_value();
size_type size (e ().size ());
for (size_type i = 0; i < size; ++ i)
OP::update(t, e () (i));
return t;
}
// Dense case
template<class I>
static BOOST_UBLAS_INLINE
result_type apply (difference_type size, I it) {
result_type t = OP::initial_value();
while (-- size >= 0)
OP::update(t, *it), ++ it;
return t;
}
// Sparse case
template<class I>
static BOOST_UBLAS_INLINE
result_type apply (I it, const I &it_end) {
result_type t = OP::initial_value();
while (it != it_end)
OP::update(t, *it), ++ it;
return t;
}
};
// max v = max (v [i], i=1..N)
template<class E>
BOOST_UBLAS_INLINE
typename vector_scalar_unary_traits<E, general_vector_scalar_unary<typename E::value_type, functor::maximum<typename E::value_type> > >::result_type
max (const vector_expression<E> &e) {
typedef typename vector_scalar_unary_traits<E, general_vector_scalar_unary<typename E::value_type, functor::maximum<typename E::value_type> > >::expression_type expression_type;
return expression_type (e ());
}
// min v = min (v [i], i=1..N)
template<class E>
BOOST_UBLAS_INLINE
typename vector_scalar_unary_traits<E, general_vector_scalar_unary<typename E::value_type, functor::minimum<typename E::value_type> > >::result_type
min (const vector_expression<E> &e) {
typedef typename vector_scalar_unary_traits<E, general_vector_scalar_unary<typename E::value_type, functor::minimum<typename E::value_type> > >::expression_type expression_type;
return expression_type (e ());
}
// log_min v = min ( log(v [i]), i=1..N if v[i]>0 )
template<class E>
BOOST_UBLAS_INLINE
typename vector_scalar_unary_traits<E, general_vector_scalar_unary<typename E::value_type, functor::log_minimum<typename E::value_type> > >::result_type
log_min (const vector_expression<E> &e) {
typedef typename vector_scalar_unary_traits<E, general_vector_scalar_unary<typename E::value_type, functor::log_minimum<typename E::value_type> > >::expression_type expression_type;
return expression_type (e ());
}
// //////////// general vector unary expression /////////////
// (op v) [i] = op( v [i] )
template<class OP, class E>
BOOST_UBLAS_INLINE
typename vector_unary_traits<E, OP>::result_type
apply_to_all (const vector_expression<E> &e, const OP& op = OP()) {
typedef typename vector_unary_traits<E, OP>::expression_type expression_type;
return expression_type (e ());
}
--8x---------------------------
usage:
cout << apply_to_all<functor::log<double> >( pwc ) << endl;
HTH
Gunter