views:

103

answers:

2
+1  A: 

Define your own type (trivial), give it an iterator and const_interator (trivial), and BOOST_FOREACH will work with it.

http://beta.boost.org/doc/libs/1_39_0/doc/html/foreach.html

glowcoder
This means I'm reinventing the wheel and I would also have to provide code for subranging / transforming / etc. Possible, but I believe better alternatives exist.
HardCoder1986
You're not reinventing the wheel. You're making an iterator. This should be a trivial exercise for a competent developer. If it's not trivial, then it's good exercise to make you a more competent developer. Either way, you win.
glowcoder
You skipped step one: define your own type. If there is a widely used 2d-array library that suits his needs, then that is the precise definition of reinventing the wheel.
Dennis Zickefoose
@Dennis it's at this point that he needs to take a step back to examine why he needs to iterate over them in the first place. At the point where you need to do a 1 dimensional operation on a 2 dimensional array, it's time to separate things into classes to manage the behavior properly.
glowcoder
But that doesn't change the fact that rolling a custom container when an existing container provides the functionality you need is foolish. And non-trivial.
Dennis Zickefoose
It changes everything. Sure, he can use a one-off solution for the issue of iteration and subranging. But think about what his objects represent. Chances are, there is some kind of model that the objects in those arrays are trying to emulate. His solution should use that model. If it internally uses that existing behavior, that's merely an implementation question. Although, iterators in 2d arrays are trivial for a competent developer (see my first comment).
glowcoder
A: 

hello.

I do the following (array_type is container/iterator range concept)

ublas::matrix<douple> A;
foreach (double & element, A.data()) {

however, this will not work for slices. your best solution is to write iterator of them .

here is an example of using multi array to provide storage of custom class. Perhaps you could do the same?:

template<size_t N, typename T>
struct tensor_array : boost::multi_array_ref<T,N> {
    typedef boost::multi_array_ref<T,N> base_type;

    typedef T value_type;
    typedef T& reference;
    typedef const T& const_reference;

    tensor_array() : base_type(NULL, extents())
    {
        // std::cout << "create" << std::endl;
    }
    template<class A>
    tensor_array(const A &dims)
        : base_type(NULL, extents())
    {
        //std::cout << "create" << std::endl;
        resize(dims);
    }

    template<typename U>
    void resize(const U (&dims)[N]) {
        boost::array<U,N> dims_;
        std::copy(dims, dims + N, dims_.begin());
        resize(dims_);
    }

    template<typename U>
    void resize(const boost::array<U,N> &dims) {
        size_t size = 1;
        boost::array<size_t,N> shape;
        for (size_t i = 0; i < N; ++i)  {
            size *= dims[i];
            shape[N-(i+1)] = dims[i];
        }
        data_.clear();
        data_.resize(size, 0);
        // update base_type parent
        set_base_ptr(&data_[0]);
        this->num_elements_ = size;
        reshape(shape);
    }

    size_t size() const { return data_.size(); }
    size_t size(size_t i) const { return this->shape()[N-(i+1)]; }
    tensor_array& fill(const T &value) {
        std::fill(data_.begin(), data_.end(), value);
        return *this;
    }
private:
    typedef boost::detail::multi_array::extent_gen<N> extents;
    std::vector<T> data_;
};
aaa
Yeah, I know. I mean like the whole idea seems wrong to me - to use `ublas::matrix` as a plain 2d container for elements. That's why I'm looking for something similiar and with the same functionality in terms of iterating / subranging.
HardCoder1986
@Hard maybe you could hide matrix inside custom class and control what features you expose?although, I see nothing wrong with using matrix just a storage.
aaa