-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document how to write allocation-free code using iDynTree's data structures and iDynTree::toEigen #510
Comments
CC |
I think this pattern is quite nice to avoid having Eigen vectors as class members, especially in public headers (and to avoid the need to have However, reviewing #516 it is possible to see that on complex expressions, this can create enormous readability problems. See for example in https://github.com/robotology/idyntree/pull/516/files#diff-9b4797931af64cac6597368c06f44dbeR132 the following expression: iDynTree::toEigen(m_P) = iDynTree::toEigen(m_Phat) - (iDynTree::toEigen(m_K)*iDynTree::toEigen(m_S)*iDynTree::toEigen(m_K).transpose()); // P_k+1 = Phat_k+1 - K_k+1 S (K_k+1)^T The amount of Use using directives
toEigen(m_P) = toEigen(m_Phat) - toEigen(m_K)*toEigen(m_S)*toEigen(m_K).transpose()); // P_k+1 = Phat_k+1 - K_k+1 S (K_k+1)^T Using a shorter toEigen aliasThis is something that I think we should add in ei(m_P) = ei(m_Phat) - ei(m_K)*ei(m_S)*ei(m_K).transpose()); // P_k+1 = Phat_k+1 - K_k+1 S (K_k+1)^T any opinion on this @S-Dafarra @GiulioRomualdi @prashanthr05 ? Use local Eigen::Map objectsIf you have read carefully https://eigen.tuxfamily.org/dox/group__TutorialMapClass.html, you should know that local Eigen::Map<Eigen::MatrixXd> P(toEigen(m_P));
Eigen::Map<Eigen::MatrixXd> Phat(toEigen(m_Phat));
Eigen::Map<Eigen::MatrixXd> K(toEigen(m_K));
Eigen::Map<Eigen::MatrixXd> S(toEigen(m_S));
P = Phat - K*S*K.transpose()); // P_k+1 = Phat_k+1 - K_k+1 S (K_k+1)^T |
In my opinion, using local P = Phat - K*S*K.transpose()); // P_k+1 = Phat_k+1 - K_k+1 S (K_k+1)^T than this iDynTree::toEigen(m_P) = iDynTree::toEigen(m_Phat) - (iDynTree::toEigen(m_K)*iDynTree::toEigen(m_S)*iDynTree::toEigen(m_K).transpose()); // P_k+1 = Phat_k+1 - K_k+1 S (K_k+1)^T or this toEigen(m_P) = toEigen(m_Phat) - toEigen(m_K)*toEigen(m_S)*toEigen(m_K).transpose()); // P_k+1 = Phat_k+1 - K_k+1 S (K_k+1)^T The latter two pieces of code adds extra layers of complexity in reading the code. I have felt this personally when I was trying to read a piece of code as a newbie coder, although the differences are very minor. However, these can be used interchangeably depending on the complexity of the statement and depending on the need to add extra lines to the code. By using a shorter In the order of precedence, I would opt for,
|
I fully agree with @prashanthr05! |
Indeed. Actually @francesco-romano suggested that this is a perfect example of pattern where using
should work fine. |
Probably it's just a crazy idea. But why not redefine the basic operators (I e. + * -) to embed the Eigen map? |
It is not so crazy. You can actually define operator overloading in a separate namespace, so that operator would be overloaded only if you do |
cc @kouroshD |
cc @fjandrad |
Probably overloading some operators (by using a suitable namespace #510 (comment)) may be really useful also for supporting different types of object in templates class. ami-iit/bipedal-locomotion-framework#46 (comment) @traversaro do you think it is suitable? |
Yes, feel free to open a PR for that, thanks! |
Discussing with @prashanthr05 , it turns out that it is not clear why classes such as
iDynTree::VectorDynSize
oriDynTree::MatrixDynSize
do not implement the overload foroperator*
, and whyiDynTree::toEigen
(or some equivalent method for any existing matrix library) should be used instead. We should document that.In a nutshell, the point is that if A is a
iDynTree::MatrixDynSize
andb
andc
areiDynTree::VectorDynSize
of consistent size, any naive implementation ofiDynTree::MatrixDynSize::operator*
will result in a memory allocation for any code such as:while the equivalent code using
toEigen
is allocation-free:the reason for this are two:
iDynTree::toEigen
returnsEigen::Map
objects (see https://eigen.tuxfamily.org/dox/group__TutorialMapClass.html), so no memory is actually copied unless it is strictly necessary.The text was updated successfully, but these errors were encountered: