Skip to content
Snippets Groups Projects
Commit 1918df6b authored by Dmitri Naumov's avatar Dmitri Naumov
Browse files

[ML] Eigen block matrix view CwiseNullaryOp

including tests.
parent 2ea25df3
No related branches found
No related tags found
No related merge requests found
/**
* \file
* \copyright
* Copyright (c) 2012-2023, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*/
#pragma once
#include <Eigen/Core>
namespace MathLib
{
template <int D, typename M>
class EigenBlockMatrixViewFunctor
{
public:
static constexpr int rows = M::RowsAtCompileTime == Eigen::Dynamic
? Eigen::Dynamic
: D * M::RowsAtCompileTime;
static constexpr int cols = M::ColsAtCompileTime == Eigen::Dynamic
? Eigen::Dynamic
: D * M::ColsAtCompileTime;
using Scalar = typename M::Scalar;
using Matrix = Eigen::Matrix<Scalar, rows, cols, Eigen::ColMajor>;
constexpr explicit EigenBlockMatrixViewFunctor(const M& matrix)
: matrix_(matrix){};
constexpr const Scalar operator()(Eigen::Index row, Eigen::Index col) const
{
if (row / matrix_.rows() != col / matrix_.cols())
{
return 0;
}
return matrix_(row % matrix_.rows(), col % matrix_.cols());
}
private:
const typename M::Nested& matrix_;
};
template <int D, typename M>
constexpr Eigen::CwiseNullaryOp<
EigenBlockMatrixViewFunctor<D, M>,
typename EigenBlockMatrixViewFunctor<D, M>::Matrix>
eigenBlockMatrixView(const Eigen::MatrixBase<M>& matrix)
{
using Matrix = typename EigenBlockMatrixViewFunctor<D, M>::Matrix;
return Matrix::NullaryExpr(
D * matrix.rows(), D * matrix.cols(),
EigenBlockMatrixViewFunctor<D, M>(matrix.derived()));
}
} // namespace MathLib
/**
* \file
* \copyright
* Copyright (c) 2012-2023, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*/
#include "MathLib/EigenBlockMatrixView.h"
#include <gtest/gtest.h>
#include <Eigen/Core>
TEST(MathLib_EigenBlockMatriView, 1by1)
{
Eigen::Matrix<double, 4, 4> expected =
Eigen::Vector4d::Constant(42).asDiagonal();
// fixed size
Eigen::Matrix<double, 1, 1> A{42};
ASSERT_EQ(expected, MathLib::eigenBlockMatrixView<4>(A));
// dynamic size
Eigen::MatrixXd B(1, 1);
B << 42;
ASSERT_TRUE(expected == MathLib::eigenBlockMatrixView<4>(B));
}
TEST(MathLib_EigenBlockMatriView, 1byN)
{
Eigen::Matrix<double, 6, 3> expected;
// clang-format off
expected << 1, 0, 0,
2, 0, 0,
0, 1, 0,
0, 2, 0,
0, 0, 1,
0, 0, 2;
// clang-format on
Eigen::Vector2d v{1, 2};
ASSERT_TRUE(expected == MathLib::eigenBlockMatrixView<3>(v));
// dynamic
Eigen::MatrixXd w(2, 1);
w << 1, 2;
ASSERT_TRUE(expected == MathLib::eigenBlockMatrixView<3>(w));
}
TEST(MathLib_EigenBlockMatriView, Nby1)
{
Eigen::Matrix<double, 3, 6> expected;
// clang-format off
expected << 1, 2, 0, 0, 0, 0,
0, 0, 1, 2, 0, 0,
0, 0, 0, 0, 1, 2;
// clang-format on
Eigen::RowVector2d v{1, 2};
ASSERT_TRUE(expected == MathLib::eigenBlockMatrixView<3>(v));
// dynamic
Eigen::MatrixXd w(1, 2);
w << 1, 2;
ASSERT_TRUE(expected == MathLib::eigenBlockMatrixView<3>(w));
}
TEST(MathLib_EigenBlockMatriView, NbyM)
{
Eigen::Matrix<double, 6, 6> expected;
// clang-format off
expected << 1, 2, 0, 0, 0, 0,
3, 4, 0, 0, 0, 0,
0, 0, 1, 2, 0, 0,
0, 0, 3, 4, 0, 0,
0, 0, 0, 0, 1, 2,
0, 0, 0, 0, 3, 4;
// clang-format on
Eigen::Matrix2d A;
A << 1, 2, 3, 4;
ASSERT_TRUE(expected == MathLib::eigenBlockMatrixView<3>(A));
// dynamic
Eigen::MatrixXd B(2, 2);
B << 1, 2, 3, 4;
ASSERT_TRUE(expected == MathLib::eigenBlockMatrixView<3>(B));
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment