Re: [eigen] Best practices for accessing named regions within a larger array? |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] Best practices for accessing named regions within a larger array?
- From: Rhys Ulerich <rhys.ulerich@xxxxxxxxx>
- Date: Sun, 4 Dec 2011 16:49:23 -0600
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; bh=+t38JDhmBM57ghgU5+W9NEhj8UbufMLZjJlGJr5sZgk=; b=T7kHmBHjUuf/AQKUAB5euZK8pD/2nEFOi0FXzauV16inMBqHXTeHkV8oROJ4IOLep2 x6uH+Y3WHWLq0ehMFVtXaw6lKHnNl1OfIMi7ub30X4C1GQ6X3RaWocfNvHVfITzxShr5 LuSm8Dcva/xZHkvIl51MtpXcT+SLCicUuAi1g=
> 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;
}