Re: [eigen] Passing Eigen::Map types to functions that take Eigen types |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: "eigen@xxxxxxxxxxxxxxxxxxx" <eigen@xxxxxxxxxxxxxxxxxxx>
- Subject: Re: [eigen] Passing Eigen::Map types to functions that take Eigen types
- From: "Wood, Tobias" <tobias.wood@xxxxxxxxx>
- Date: Wed, 1 Jul 2015 20:54:51 +0000
- Accept-language: en-GB, en-US
- Authentication-results: lists.tuxfamily.org; dkim=none (message not signed) header.d=none;
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:23
- Thread-index: AQHQs/kOneJblFR3i0GskikLn/kO5Z3GisY6gAA56YCAAFIxsQ==
- Thread-topic: [eigen] Passing Eigen::Map types to functions that take Eigen types
I replied in haste and missed part of your e-mail, apologies. Christoph's suggestion is the correct one. Would redefining your methods really be more work than trying to subclass MatrixXd?
My point about raw pointers was a general one, not specific to your example code. Your use-case is sensible.
Good luck,
Toby
________________________________________
From: Martin Felis <martin.felis@xxxxxxxxxxxxxxxxxxxxx>
Sent: 01 July 2015 16:55
To: eigen@xxxxxxxxxxxxxxxxxxx
Subject: Re: [eigen] Passing Eigen::Map types to functions that take Eigen types
On 01.07.2015 14:32, Wood, Tobias wrote:
> Hello Martin,
>
> Your do_work_ptr definition should look like this:
>
> void do_work_ptr (double* ptr, int rows, int cols) {
> Eigen::Map<Eigen::MatrixXd> mat_data(ptr, rows, cols);
> do_work (mat_data);
> }
>
> Your original version was instructing Eigen to first create a map around the pointer, and then copy the elements to a new Matrix. The above version only creates the map.
Thanks for your reply. Making mat_data of type Eigen::Map does not work
as it cannot be passed by reference as a Eigen::MatrixXd&.
E.g. using
void do_work (Eigen::MatrixXd& mat) {
Eigen::Matrix2d mask;
mask << 10., -15., -20., 30.;
mat.block<2,2>(0,0) = mask;
}
void do_work_ref (Eigen::Ref<Eigen::MatrixXd> mat) {
Eigen::Matrix2d mask;
mask << 10., -15., -20., 30.;
mat.block<2,2>(0,0) = mask;
}
void do_work_ptr (double* ptr) {
Eigen::Map<Eigen::MatrixXd> mat_data (ptr, 2, 3);
do_work (mat_data);
}
will give the following error:
invalid initialization of reference of type ‘Eigen::MatrixXd& {aka
Eigen::Matrix<double, -1, -1>&}’ from expression of type
‘Eigen::Map<Eigen::Matrix<double, -1, -1>, 0, Eigen::Stride<0, 0> >’
do_work (data_map);
Replacing do_work with do_work_ref as suggested by Christoph Hertzberg
does work. This would still mean I have to change my library code.
Would it be possible to subclass MatrixXd to take a pointer and use that
instead of creating a new one?
> However, I wonder why you are not using Eigen for the data storage inside your library? The do_work_ptr approach you have described is prone to memory leaks if you are not careful. Eigen has a .data() method that will return a pointer to the underlying array if you ever need it.
I am already using Eigen for the data storage inside my library, however
some functions in my library fill (possibly huge) matrices that I pass
as references to it.
My motivation on providing API that use raw pointers is to expose my
code to scripting languages. With a bit of luck you can actually get
access to the raw data for the data types in the scripting languages and
it would be a shame if I wouldn't use it and create copies of it.
Im not sure I understand your comment, though. How can
do_work_ptr(double* ptr) leak memory? Of course the caller has to ensure
that the data in ptr must be cleared, but as it belongs to the scripting
language I do not have to care about it.
Thanks again!
Martin
--
mail : martin.felis@xxxxxxxxxxxxxxxxxxxxx
phone : +49 6221 544983
office: IWR | Speyerer Str 6 | Room 319 | 69115 Heidelberg | Germany