Re: [eigen] Being able to use Eigen::Map<Eigen::Matrix< ... > > everywhere you can use a Eigen::Matrix |

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

*To*: eigen <eigen@xxxxxxxxxxxxxxxxxxx>*Subject*: Re: [eigen] Being able to use Eigen::Map<Eigen::Matrix< ... > > everywhere you can use a Eigen::Matrix*From*: Gael Guennebaud <gael.guennebaud@xxxxxxxxx>*Date*: Tue, 19 Feb 2013 19:37:43 +0100*Dkim-signature*: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:mime-version:in-reply-to:references:from:date:message-id :subject:to:content-type; bh=RP3PuT9eGlux7NhM8xiDTGvguP8ZfV8aAa3uQvk2r38=; b=Nt8lm7T57/vkxfkNlq7108Ba1itlX5g+V4h+4279X1yLTjZEeBbdNR9pySb5/+kRy9 xW/S+SFh1DIgAEqiolFaZ8zZjiy2OMvaoN9SlbrP1NP3eDLF9neQqe+K84WP34QTtVW5 UUEiHkxozVBHw+iGaFhjXAr6loSY7bY7V9Baxk10B3Kn81o459IkVN5ksA9E8Zddtv0G LCJcTHoKPNRCovlBGvMuZTg6ZvX/lC1dWcbZRsYN0SnQjP/eG+UItVKUp7LrE2jrStdE Tk3+i4Wkgvwcut2DRu5D9RxIOryZdtDIt0bUQ3jjNEhwbCuNutODrLfQBv9i/9hiC46Q vIuA==

The way we handle this in Eigen is through static assertions. If you can use c++11 features (e.g., -std=c++11 with gcc), then you can for instance do in the body of your function: static_assert(NumTraits<typename Db::Scalar>::IsInteger, "the second argument of fit_params must hold integers"); See http://en.cppreference.com/w/cpp/language/static_assert. Without c++11 you have to implement some workarounds. For instance, you might have a look at the our StaticAssert.h file in src/Core/utils and adapt a copy of it for your own use, or even use boost enable_if (http://www.boost.org/doc/libs/1_53_0/libs/utility/enable_if.html). And to complete Jitse answer, in the devel branch we have a tradeoff between fully generic templated functions, and functions limited to Matrix<> object via the Ref<> class which can accept any Matrix, Block, Map and the likes of the a given scalar type: http://eigen.tuxfamily.org/dox-devel/classEigen_1_1Ref.html. cheers, Gael On Tue, Feb 19, 2013 at 3:02 PM, Malcolm Reynolds <malcolm.reynolds@xxxxxxxxx> wrote: > Now that I'm running through the code changes necessary to implement this - > assuming my current functions are templated on the datatype of the matrix, > how can I change them to use MatrixBase, but still make sure the type is > correct? > > Eg: > > template<typename T> > class Foo { > public: > inline void fit_params(const Matrix<T, Dynamic, Dynamic> & input_data, > const Matrix<long, Dynamic, Dynamic> & > valid_indices) { > > // stuff > } > }; > > I want to make sure that the first argument is a matrix of whatever type the > class is instantiated with, and the second matrix contains types which are > valid for indexing. I can see that the function can be written as > > template<typename T> > class Foo { > public: > template<typename Da, typename Db> > inline void fit_params(const MatrixBase<Da> & input_data, > const MatrixBase<Db> & valid_indices) { > > // stuff > } > }; > > in order to get the efficiency advantages of MatrixBase, but now I can't > specify that the second argument must have a scalar type suitable for > indexing. Is there a way around this? > > Thanks again! > > > On Tue, Feb 19, 2013 at 1:08 PM, Malcolm Reynolds > <malcolm.reynolds@xxxxxxxxx> wrote: >> >> Hi Jitse, >> >> Thanks for your quick answer - excellent explanation. The way that C++ can >> implicitly create temporary objects is definitely something I need to read >> up more on. One final question, why do you recommend I use MatrixBase rather >> than the more general DenseBase or EigenBase? Will using the more general >> template types infer a performance hit? >> >> The only suggestion I would have for the documentation is maybe adding >> some note to the "Mapping external arrays" section of >> http://eigen.tuxfamily.org/dox-devel/group__QuickRefPage.html as that is the >> main page I was using for reference. A little note there saying "to use Maps >> in place of Matrices, please see considerations in <link>", with the link >> pointing to the TopicFunctionTakingEigenTypes.html page, would be a good >> idea I think. >> >> Thanks again! >> >> Malcolm >> >> >> On Tue, Feb 19, 2013 at 10:30 AM, Jitse Niesen <jitse@xxxxxxxxxxxxxxxxx> >> wrote: >>> >>> On Mon, 18 Feb 2013, Malcolm Reynolds wrote: >>> >>>> First post to this list, apologise if this is something really obvious >>>> but >>>> I'm having a bit of trouble using Eigen::Map. As I understand, it allows >>>> me >>>> to declare an Eigen matrix which reuses some memory already allocated >>>> (in my >>>> cases I'm gettin the data pointer from Numpy matrices), and then use >>>> this >>>> value everywhere I can use a regular Eigen matrix? >>> >>> >>> All Eigen functions are written such that a Map can be used in the same >>> way as a regular Eigen matrix. If you write your own functions, you may need >>> to do something extra if you want your own functions to accept a Map instead >>> of a regular matrix. This is explained at >>> >>> http://eigen.tuxfamily.org/dox-devel/TopicFunctionTakingEigenTypes.html >>> >>> >>>> I have a function which I'd already written with the signature >>>> >>>> predict(const MatrixXd & features, MatrixXd * const labels_out) >>>> >>>> following the good practice (afaik) of using const refs for parameters >>>> that >>>> don't need to be modified, and pointers otherwise. Anyway I'd like to >>>> pass >>>> in Eigen::Maps for both arguments of this function, as I'm writing a >>>> python >>>> interface for my library. [...] >>> >>> >>> You are calling this function like: >>> >>> Map<MatrixXd> mapFeatures = ...; >>> Map<MatrixXd> mapLabels = ...; >>> predict(mapFeatures, &mapLabels); >>> >>> For the first argument, the compiler converts the Map<MatrixXd> into a >>> MatrixXd by introducing a temporary object, so it is as if you had written: >>> >>> MatrixXd tempObject(mapFeatures); >>> predict(tempObject, &mapLabels); >>> >>> This does what you want, but it induces a performance penalty because >>> when tempObject is constructed, all the data from mapFeatures is copied into >>> the matrix tempObject. >>> >>> However, this does not work for the second argument. If the compiler were >>> to introduce another temporary object and pass that as the second argument, >>> then predict() would change the data in the temporary object and not in >>> mapLabels. >>> >>> The solution is to have predict() accept arguments of the template type >>> MatrixBase, as explained in the link I included above. If you still have >>> questions after reading that, do not hesitate to ask. Any suggestions on how >>> we can improve the explanations would be very welcome. >>> >>> Good luck, >>> Jitse >>> >>> >> >

**References**:**[eigen] Being able to use Eigen::Map<Eigen::Matrix< ... > > everywhere you can use a Eigen::Matrix***From:*Malcolm Reynolds

**Re: [eigen] Being able to use Eigen::Map<Eigen::Matrix< ... > > everywhere you can use a Eigen::Matrix***From:*Jitse Niesen

**Re: [eigen] Being able to use Eigen::Map<Eigen::Matrix< ... > > everywhere you can use a Eigen::Matrix***From:*Malcolm Reynolds

*From:*Malcolm Reynolds

**Messages sorted by:**[ date | thread ]- Prev by Date:
- Next by Date:
**[eigen] Re: New EIGEN_INITIALIZE_MATRICES_BY_NAN option** - Previous by thread:
- Next by thread:
**[eigen] Re: New EIGEN_INITIALIZE_MATRICES_BY_NAN option**

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