Re: [eigen] Best practices for accessing named regions within a larger array?

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


> I'm not sure to understand your issue. Do you have a concrete example
> of the "error-prone boilerplate" you are talking about?

Sure.  A trimmed down version that compiles is attached.

In practice I've got maybe four times the number of named regions.
The example::ncols, example::offset, and accessor methods (spelled out
here) can be generated using a single Boost.Preprocessor sequence and
some auxiliary macros.  That cure is about as bad as the disease,
however.  Tag-types and some Boost.MPL could accomplish the same but
would also be ugly looking.

- Rhys
#include <Eigen/Core>

// Contiguous storage for several related quantities.  Each quantity is kept in
// one or more columns.  Keeping them in one memory allocation is advantageous
// for memory overhead, memory locality, and for enforcing rows() consistency.
class example
{
private:

    struct ncols { enum {
        rho            = 1,
        rhou           = 3,
        rhoe           = 1,
        sym_rho_grad_u = 6
        // etc.
    };
    private: ncols();
    };

    struct offset { enum {
        rho            = 0,
        rhou           = rho  + ncols::rho,
        rhoe           = rhou + ncols::rhou,
        sym_rho_grad_u = rhoe + ncols::rhoe
        // etc.
    };
    private: offset();
    };

public:

    typedef Eigen::Array<double, Eigen::Dynamic, offset::sym_rho_grad_u + ncols::sym_rho_grad_u> storage_type;

    storage_type storage;

    storage_type::NColsBlockXpr<ncols::rho>::Type rho() {
        return storage.middleCols<ncols::rho>(offset::rho);
    }

    storage_type::NColsBlockXpr<ncols::rhou>::Type rhou() {
        return storage.middleCols<ncols::rhou>(offset::rhou);
    }

    storage_type::NColsBlockXpr<ncols::rhoe>::Type rhoe() {
        return storage.middleCols<ncols::rhoe>(offset::rhoe);
    }

    storage_type::NColsBlockXpr<ncols::sym_rho_grad_u>::Type sym_rho_grad_u() {
        return storage.middleCols<ncols::sym_rho_grad_u>(offset::sym_rho_grad_u);
    }

    // etc

    storage_type::ConstNColsBlockXpr<ncols::rho>::Type rho() const {
        return storage.middleCols<ncols::rho>(offset::rho);
    }

    storage_type::ConstNColsBlockXpr<ncols::rhou>::Type rhou() const {
        return storage.middleCols<ncols::rhou>(offset::rhou);
    }

    storage_type::ConstNColsBlockXpr<ncols::rhoe>::Type rhoe() const {
        return storage.middleCols<ncols::rhoe>(offset::rhoe);
    }

    storage_type::ConstNColsBlockXpr<ncols::sym_rho_grad_u>::Type sym_rho_grad_u() const {
        return storage.middleCols<ncols::sym_rho_grad_u>(offset::sym_rho_grad_u);
    }

    // etc
};

int main(int argc, char *argv[])
{
    example e;
    e.storage.resize(5, example::storage_type::ColsAtCompileTime);
    e.rho().fill(1);
    // etc

    return 0;
}


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/