Registered Member
|
Hi!
I'm trying to create an Eigen object with array semantics (need it only for a storage passed by const ref to a code that expects an Eigen::ArrayXXd) that is a view of the contents of multiple vectors. Basically, in the attached code I'd like for Eigen::ArrayXXd X to refer to the contents of a bunch of vectors (here -- three of them with Eigen::VectorXd type, but in real app. a bit more (and a bit larger, but still all of the same length)). Because of the large size of the data, I'd like to avoid allocating any additional memory for X (i.e., I only want it to be a view, not a copy), to avoid allocation and copying overhead. The intention is in the comment -- but only to some extent (including that the code right now won't compile, since data mem.-fun. only returns an r-value) since I'd like to avoid X assuming the ownership of the memory of vectors a, b, c. After I pass it to a code (that won't modify it, but will read only), I'm happy to discard X. // Well, as a last-resort scenario I'd be also fine with discarding a, b, c -- so even _move_ would be preferable to _copy_ for me. I understand that the way I've written it now (the uncommented part) I'm performing a _copy_ of the contents of a, b, c into consecutive columns of X, and I presume there's no copy-on-write optimization for this? Any ideas on how to create a read-only view instead? In the docs I was only able to find information on TriangularView /* http://eigen.tuxfamily.org/dox/QuickRefPage.html */ (which isn't what I want at all) and Eigen::Map /* http://eigen.tuxfamily.org/dox/classEigen_1_1Map.html */ (which seems to be able to take only one pointer to one object containing one piece of data -- while I need multiple ones).
Intended output:
|
Moderator
|
to do so you would have to write your own expression that would basically store a std::vector<Map<...> >, and your function should be templatized to accept any kind of array objects.
|
Registered Member
|
Ah, that's an interesting solution, thanks.
A question -- does Eigen::Map have value-semantics or reference-semantics? And if value, is it lightweight or fat? Basically, I'm wondering if I shouldn't still use std::vector<Eigen::Map<...>*> instead of std::vector<Eigen::Map<...>> if I want to avoid all the overheads that I can? Or, perhaps, boost::ptr_vector<Eigen::Map<...>>; incidentally, is it safe to use Eigen::Map with Boost.Pointer Containers, http://www.boost.org/doc/libs/release/l ... ainer.html? Completely alternatively, would either std::vector<Eigen::VectorXd*> or boost::ptr_vector<Eigen::VectorXd> be a better idea for this application than the Eigen::Map approach -- and if so, which one and why? |
Moderator
|
A Map<VectorXd> object only stores a pointer plus an integer (size), so it is very lightweight though the size information will be duplicated many times. Also note that Map<>::operator= copies the values, not the pointers, just like any Eigen's object, so a std::vector<Map<>> could work but some care has to be taken. For instance, one could implement a setInnerVector(i, vec) method with overloads for VectorXd and MapBase objects. The Map elements stored in the std::vector<Map<>> would be initialized with the placement new mechanism:
new (&m_innerVectors[i]) Map<...>(data,size); hope that helps. |
Registered Member
|
ggael, thanks for the reply, I'm still not sure how to insert eigen-maps into std-vectors.
For
neither
nor
work. Both error out with:
An attempt to use placement new on
either by
or
results with
|
Moderator
|
here is a working example:
|
Registered Member
|
Thanks! This worked!
I've done a mini-benchmark and data-initialization step (basically, setting up the pointers) was much faster -- while initialization took roughly 0.070 s for the copy (that was still faster than I expected, I guess you must have done a pretty good job vectorizing the copy operation on Eigen data-structures?), it took (within measurement & display precision) only "0 s" for the map. Traversal took 0.021..0.025 s for both. In case anyone wants to look at the code, I've left it on Ideone.com's pastebin. http://www.ideone.com/ZswrI copy: 0.077 s // initialization Array X.sum(): -434.035 0.021 s // traversal 0.073 s Array X.sum(): -434.035 0.021 s 0.065 s Array X.sum(): -434.035 0.025 s http://www.ideone.com/63iYj map: 0 s // initialization Array X.sum(): -434.035 0.021 s // traversal 0 s Array X.sum(): -434.035 0.021 s 0 s Array X.sum(): -434.035 0.021 s |
Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]