Boost logo

Boost Users :

From: speedsnaii (speedsnaii_at_[hidden])
Date: 2003-03-07 11:34:43


Hi Joerg,
 
> > If the constructor also would accept a row I could use it as a
> > parameter type for function calls when I want to express, that
> > only 'data' types are expected and 'expressions' are not wanted.
> > (Sorry for the sloppy formulation, I am not sure how to express
> > this more concise.)
>
> I hope, we'll be able to solve this, too.
>

Finally I found a solution that works with expressions, without the
burden of template parameter specification. I took up your suggestion
and blended it with boost::function. I would be glad if you could
have a look on it and perhaps comment.
=====================================================================
#include <iostream>
#include <boost/numeric/ublas/config.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/function.hpp>
using namespace boost::numeric::ublas;

// this is the class that implements the functor
// it also could be parameterized on more than one expression
// (this is what Joerg suggested)
template<class T, class E>
class func_impl {
public:
    func_impl(const vector_expression<E> &e) : e_ (e) {}
    T operator() (const T& x){
        // algorithm goes here ...
        return e_()(0)*x; // just for demonstration
    }
private:
const vector_expression<E> &e_;
};

// this is the user part of the functor
// the constructor is used to act as a generator for the
// implementation type.
template<class T>
class func : public boost::function1<T, T> {
public:
    template<class E>
    func(const vector_expression<E>& e)
        : boost::function1<T, T>(func_impl<T, E>(e)) {}
};

int main(int argc, char* argv[])
{
matrix<double> m (3,3);
vector<double> v (3);
func<double> f(m.row(0)); // notice: no need to know the type of m.row

    m(0,0) = 0.0; m(0,1) = 0.1; m(0,2) = 0.2;
    m(1,0) = 1.0; m(1,1) = 1.1; m(1,2) = 1.2;
    m(2,0) = 2.0; m(2,1) = 2.1; m(2,2) = 2.2;

    std::cout << f(1.0) << std::endl;
    // outputs: 0

    m(0,0) = 47.11; // change the referenced matrix
    std::cout << f(1.0) << std::endl;
    // outputs: 47.11

    // other argument types ...
    func<double> f1(m.column(2));
    std::cout << f1(1.0) << std::endl;
    // outputs: 0.2
    m(0,2) = 13;
    std::cout << f1(1.0) << std::endl;
    // outputs: 13

    // similar with vector ...
    func<double> f2(v);

    return 0;
}
=====================================================================

Of course this involves an indirection since I am using the
functiom.hpp from boost as base class. But I think this is not
avoidable in principle, since this is what a reference is all about,
isn't it?

Regards,
Roland


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net