Skip to content
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

Implement the MatrixView class #734

Merged
merged 17 commits into from
Sep 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
28306d7
Implement MatrixView class
GiulioRomualdi Sep 9, 2020
abd7f9d
Add MatrixView to the set of the headers in the core CMakeLists file
GiulioRomualdi Sep 9, 2020
de39dbd
Implement MatrixDynSize assignement operator for MatrixView objects
GiulioRomualdi Sep 9, 2020
17ae047
Add typedef in MatrixDynSize and MatrixFixSize to make them compatibl…
GiulioRomualdi Sep 9, 2020
e4b9ace
Extend the MatrixDynSize test with the MatrixView class
GiulioRomualdi Sep 9, 2020
9038b94
Implement the toEigen method for the MatrixView class
GiulioRomualdi Sep 9, 2020
2813702
Extend the EigenHelpersUnitTest with tests related to MatrixView
GiulioRomualdi Sep 9, 2020
abc9e97
Implement unit tests for MatrixView class
GiulioRomualdi Sep 9, 2020
44694c9
Enable the compilation of the MatrixViewUnitTest
GiulioRomualdi Sep 9, 2020
c173e11
Fix typos in EigenHelpers.h
GiulioRomualdi Sep 9, 2020
d766d55
Introduce the MatrixViewInternal namespace to avoid possible name col…
GiulioRomualdi Sep 9, 2020
67f2589
Use std::ptrdiff_t instead of unsigned int as index type in MatrixVie…
GiulioRomualdi Sep 9, 2020
c4fe388
Add a test for checking the possible errors when a ColMajor MatrixVie…
GiulioRomualdi Sep 9, 2020
ab3af17
Fix style in EigenHelpers.h file
GiulioRomualdi Sep 10, 2020
7bcf16f
Add a comment describing the trick used to build an Eigen::Map from a…
GiulioRomualdi Sep 10, 2020
f07abf2
Update CHANGELOG.md
GiulioRomualdi Sep 10, 2020
5ebd210
Merge branch 'devel' into feature/add_matrix_view
GiulioRomualdi Sep 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- When used in Python, new iDynTree objects can be constructed from generic iterable objects and NumPy arrays (`*.FromPython`),
and existing objects can be converted to NumPy arrays (`*.toNumPy`) (https://github.com/robotology/idyntree/pull/726).
- iDynTree Python bindings can now be installed with `pip3 install git+https://github.com/robotology/idyntree.git` (https://github.com/robotology/idyntree/pull/733).
- Implement the MatrixView class (https://github.com/robotology/idyntree/pull/734)

### Fixed
- Fixed bug in `yarprobotstatepublisher` that caused segmentation fault each time an unknown joint name was read from the input joint states topic (https://github.com/robotology/idyntree/pull/719)
Expand Down
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ set(IDYNTREE_CORE_EXP_HEADERS include/iDynTree/Core/Axis.h
include/iDynTree/Core/CubicSpline.h
include/iDynTree/Core/Span.h
include/iDynTree/Core/SO3Utils.h
include/iDynTree/Core/MatrixView.h
# Deprecated headers
include/iDynTree/Core/AngularForceVector3.h
include/iDynTree/Core/AngularMotionVector3.h
Expand Down
99 changes: 99 additions & 0 deletions src/core/include/iDynTree/Core/EigenHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,105 @@ inline Eigen::Map<Eigen::VectorXd> toEigen(iDynTree::Span<double> vec)
{
return Eigen::Map<Eigen::VectorXd>(vec.data(),vec.size());
}

inline Eigen::Map<const Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>,
0,
Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>
toEigen(const MatrixView<const double>& mat)
{
using MatrixRowMajor = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;

// This is a trick required to see a ColMajor matrix as a RowMajor matrix.
//
// Given the following matrix
// _ _ _
// / \ _____ | 1 2 3 4 5 |
// / _ \ |_____| | |
// / ___ \ |_____| | |
// /_/ \_\ |_ 6 7 8 9 10 _|
//
// If the matrix is stored as RowMajor matrix there will be a vector v_row in which
// the elements are saved
// v_row = [1 2 3 4 5 6 7 8 9 10]
//
// If the matrix is stored as ColMajor matrix there will be a vector v_col in which
// the elements are saved
// v_col = [1 6 2 7 3 8 4 9 5 10]
//
// Our goal here is to build a RowMajor Matrix (independently it is RowMajor/ColMajor)
// starting from the raw vactor (v_row, v_col)
//
// From the Eigen documentation https://eigen.tuxfamily.org/dox/classEigen_1_1Stride.html
// The inner stride is the pointer increment between two consecutive entries within a given row of a row-major matrix.
// The outer stride is the pointer increment between two consecutive rows of a row-major matrix.
//
// Starting from v_row we can build a RowMajor matrix by choosing the following pair of strides
// - inner_stride = 1
// - outer_stride = 5 = number of columns of A
//
// Starting from v_col we can build a RowMajor matrix by choosing the following pair of strides
// - inner_stride = 2 = number of rows of A
// - outer_stride = 1

const int innerStride = (mat.storageOrder() == StorageOrder::ColMajor) ? mat.rows() : 1;
const int outerStride = (mat.storageOrder() == StorageOrder::ColMajor) ? 1 : mat.cols();
Copy link
Contributor

@prashanthr05 prashanthr05 Sep 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read here that it is not always safe to use ternary operators with Eigen expressions.

Copy link
Contributor

@prashanthr05 prashanthr05 Sep 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, my bad, here mat is a MatrixView type!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that it is not safe when an Eigen type is on the left side. In this case should be fine as only int are involved.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay, understood.

Copy link
Member Author

@GiulioRomualdi GiulioRomualdi Sep 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the operator is called on int so it shouldn't be a problem, please correct me if I'm mistaken.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that it is not safe when an Eigen type is on the left side. In this case should be fine as only int are involved.

Ops I missed the message


return Eigen::Map<const MatrixRowMajor, 0, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>(
mat.data(),
mat.rows(),
mat.cols(),
Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>(outerStride, innerStride));
}

inline Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>,
0,
Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>
toEigen(const MatrixView<double>& mat)
{
using MatrixRowMajor = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;

// This is a trick required to see a ColMajor matrix as a RowMajor matrix.
//
// Given the following matrix
// _ _ _
// / \ _____ | 1 2 3 4 5 |
// / _ \ |_____| | |
// / ___ \ |_____| | |
// /_/ \_\ |_ 6 7 8 9 10 _|
//
// If the matrix is stored as RowMajor matrix there will be a vector v_row in which
// the elements are saved as
// v_row = [1 2 3 4 5 6 7 8 9 10]
//
// If the matrix is stored as ColMajor matrix there will be a vector v_col in which
// the elements are saved as
// v_col = [1 6 2 7 3 8 4 9 5 10]
//
// Our goal here is to build a RowMajor Matrix (independently it is RowMajor/ColMajor)
// starting from the raw vactor (v_row, v_col)
//
// From the Eigen documentation https://eigen.tuxfamily.org/dox/classEigen_1_1Stride.html
// The inner stride is the pointer increment between two consecutive entries within a given row of a row-major matrix.
// The outer stride is the pointer increment between two consecutive rows of a row-major matrix.
//
// Starting from v_row we can build a RowMajor matrix by choosing the following pair of strides
// - inner_stride = 1
// - outer_stride = 5 = number of columns of A
//
// Starting from v_col we can build a RowMajor matrix by choosing the following pair of strides
// - inner_stride = 2 = number of rows of A
// - outer_stride = 1

const int innerStride = (mat.storageOrder() == StorageOrder::ColMajor) ? mat.rows() : 1;
const int outerStride = (mat.storageOrder() == StorageOrder::ColMajor) ? 1 : mat.cols();

return Eigen::Map<MatrixRowMajor, 0, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>(
mat.data(),
mat.rows(),
mat.cols(),
Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>(outerStride, innerStride));
}

#endif

inline Eigen::Map<const Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> > toEigen(const MatrixDynSize & mat)
Expand Down
19 changes: 19 additions & 0 deletions src/core/include/iDynTree/Core/MatrixDynSize.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#include <string>

#include <iDynTree/Core/MatrixView.h>

namespace iDynTree
{
/**
Expand Down Expand Up @@ -105,6 +107,15 @@ namespace iDynTree
*/
MatrixDynSize& operator=(const MatrixDynSize& other);

/**
* Assignment operator
*
* @param other the object to copy into self
*
* @return *this
*/
MatrixDynSize& operator=(const MatrixView<const double>& other);

/**
* Denstructor
*
Expand Down Expand Up @@ -209,6 +220,14 @@ namespace iDynTree
void fillColMajorBuffer(double * colMajorBuf) const;


#if !defined(SWIG_VERSION) || SWIG_VERSION >= 0x030000
/** Typedefs to enable make_matrix_view.
*/
///@{
typedef double value_type;
///@}
#endif

/** @name Output helpers.
* Output helpers.
*/
Expand Down
8 changes: 8 additions & 0 deletions src/core/include/iDynTree/Core/MatrixFixSize.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,14 @@ namespace iDynTree
*/
void fillColMajorBuffer(double * colMajorBuf) const;

#if !defined(SWIG_VERSION) || SWIG_VERSION >= 0x030000
/** Typedefs to enable make_matrix_view.
*/
///@{
typedef double value_type;
///@}
#endif


/** @name Output helpers.
* Output helpers.
Expand Down
Loading