[eigen] Eigen Types as Parameters for Functions |

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

*To*: <eigen@xxxxxxxxxxxxxxxxxxx>*Subject*: [eigen] Eigen Types as Parameters for Functions*From*: Christian Seiler <christian@xxxxxxxx>*Date*: Thu, 26 Jan 2012 13:13:23 +0000

Hi, I'm a user and a fan of Eigen. However, there is one issue I frequently run into: I very often want to write functions that take Eigen types as parameters. Now, I've read <http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html>, and that has certain issues: First of all, these functions have to be defined as template functions, which means that they have to be defined

do that much, but I'd really prefer to put the function into a separate compilation unit if the code is a little more complex. (But for this to work with template functions, I'd have to explicitly instantiate all possible template variants in the compilation units, and there I'm definitely going to miss quite a few.) Also, having to play around with const_cast<> and template logic seems a bit excessive to me just to pass a simple matrix / vector as an argument, while at the same time being able to accept Block-type objects or direct expressions etc. Especially if the code is supposed to be shared with other people that are not as well-versed in the intricacies of C++ as I am, who may also need to modify the code later on. Therefore, I'd like to propose a solution that would make the life for me (and probably a lot of other people) easier. Rationale: In the end, the only real information about a matrix stored in memory that one needs are: - pointer to the first element - dimension - row/col major - strides (inner/outer) - alignment I propose adding a new class (name could be decided on later, for the purpose of this class, I'll use MatrixParameter, although I don't like the name particularily) that has the following properties: - subclass of MatrixBase, i.e. can be used inside the function like a Matrix object - has private members containing the above-mentioned bits of information (pointer to first element, dimension, ...) - can be implicitly converetd to from any compatible MatrixBase (i.e. foo(mat) and foo(mat.block(...)) can be used directly) This would allow one to create functions and/or methods that accept Eigen objects as parameters much more easily - and would even provide a stable binary ABI for libraries one wants to write, as long as the numerical type is specified. Examples of possible usage pattern: void veryComplicatedAlgorithm( Eigen::MatrixParameterXd result, Eigen::MatrixParameterXd orig ) { // do some very complicated calculation with orig // and store it in result } Matrix4d orig; orig << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16; MatrixXd result(2,2); veryComplicatedAlgorithm(result, orig.block(1,1,2,2)); double worksOnlyWithTwoByTwo(Eigen::MatrixParameter2d inp) { // or something... return inp(0,0) * inp(1,1) / (inp(0,1) + inp(1,0)); } Matrix4d foo = Matrix4d::Identity(); MatrixXd foo2 = MatrixXd::Identity(4, 4); double p = worksOnlyWithTwoByTwo(foo); // compile-time error double p2 = worksOnlyWithTwoByTwo(foo2); // run-time error // unless range-checking // disabled double p3 = worksOnlyWithTwoByTwo(foo.block(0, 0, 2, 2)); // works double p4 = worksOnlyWithTwoByTwo(foo2.block(0, 0, 2, 2)); // works void someWrapperAroundLegacyFortranCode( Eigen::MatrixParameterXd mat, Eigen::VectorParameterXd vec ) { // or something xxyyzz_(mat.size(), mat.data(), vec.data()); } Considerations: - The layout of the fields in the class should be fixed once and for all, this allows binary compatibility even when using a different version of Eigen for compiling both compilation units. ("once and for all" should mean something like "only change this if the major version of Eigen changes") - If the functions are not templated themselves, this fixes the scalar data type. I don't see this as a problem though, because that may be what people want. Also, this scheme still allows for declaring something along the lines of template<typename Scalar> void foo(Eigen::MatrixParameter<Scalar, ...> ...); if this is really wanted - Resizing of output matrices is not easily possible here. However, I don't think this is necessarily a problem, since most of the time the calling code will already know what the dimension of matrices used for output have to be. And if somebody really requires the ability to resize matrices, it should always be possible to use the current way of passing Eigen matrices. - Expressions such as foo(A * B) can be tricky. I propse that we define two classes: The second class could be prefixed with "Const" (e.g. MatrixConstParameter). There, any expression would be evaluated into a temporary before being passed to the function, while plain matrices and .block(...) would remain untouched. The non-"Const"-variant, on the other hand, would only accept plain matrices and .block(...) expressions, since only those can guarantee write acccess. (Ok, .transpose() would also work because one can just flip the RowMajor/ColMajor bit, but .adjoint() would already be problematic.) - The documentation should warn about memory management caveats here. Basically, since the classes proposed here are just wrappers for pointers, if the matrix pointed to falls out of scope or is deleted, and somebody stored a reference somewhere, this will lead to bugs. Unfortunately, disabling the copy constructor is not possible, since it is needed to be able to pass through arguments to other functions. I'd like to here your thoughts on this, and I'm offering to implement my proposal if you agree with the basic idea. Thanks, Christian

**Follow-Ups**:**Re: [eigen] Eigen Types as Parameters for Functions***From:*Benoit Jacob

**Re: [eigen] Eigen Types as Parameters for Functions***From:*Christoph Hertzberg

**Messages sorted by:**[ date | thread ]- Prev by Date:
**Re: [eigen] tf quotas reached again** - Next by Date:
**Re: [eigen] Eigen Types as Parameters for Functions** - Previous by thread:
**Re: [eigen] tf quotas reached again** - Next by thread:
**Re: [eigen] Eigen Types as Parameters for Functions**

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