I want to do some operation with elements in a matrix, depending on the position of each element.
I know that by-default, Eigen matrix is column-major, so to loop over the matrix, the outer for-loop is for each column, and the inner for-loop is for each row. I have 4 kinds of expressions to be assigned to m(r,c)
, depending on the values of r
and c
. Some pseudo-code is shown below:
if c == some_c
if r == some_r
m(r,c) = some expression A
else
m(r,c) = some expression B
else
if r == some_r
m(r,c) = some expression C
else
m(r,c) = some expression D
I have also made detailed c++ codes below. I am not C++ expert, so I am not sure whether my code is elegant or not. Could you please let me know how to improve it? I would prefer using possible modern C++14 or C++17 features.
#include <Eigen/Dense>
using Matrix = Eigen::MatrixXd
void some_operation_on_matrix(Matrix& m, size_t some_r, size_t some_c)
{
for (size_t c = 0; c < m.cols(); c++) {
for (size_t r = 0; r < m.rows(); r++) {
if (c == some_c) {
if (r == some_r) {
// m(r,c) = some expression A
}
else {
// m(r,c) = some expression B
}
}
else {
if (r == some_r) {
// m(r,c) = some expression C
}
else {
// m(r,c) = some expression D
}
}
}
}
}
I would change the logic of your loop a bit
void some_operation_on_matrix(Matrix& m, size_t some_r, size_t some_c)
{
for (size_t c = 0; c < m.cols(); c++) {
if (c == some_c) {
for (size_t r = 0; r < m.rows(); r++) {
if (r == some_r) {
// m(r,c) = some expression A
}
else {
// m(r,c) = some expression B
}
}
else {
for (size_t r = 0; r < m.rows(); r++) {
if (r == some_r) {
// m(r,c) = some expression C
}
else {
// m(r,c) = some expression D
}
}
}
}
}
Thus, the if statement if (c == some_c)
has only to be evaluated for all m.cols
and not for all m.cols * m.rows
.
You can extract the second for loop in a function
void innerLoop(Matrix &m, const size_t some_r, std::function expression1, std::function expression2)
{
for (size_t r = 0; r < m.rows(); r++) {
if (r == some_r) {
m(r,c) = expression1(...);
}
else {
m(r,c) = expression2(...);
}
}
}
and
void some_operation_on_matrix(Matrix& m, size_t some_r, size_t some_c)
{
for (size_t c = 0; c < m.cols(); c++) {
if (c == some_c) {
innerLoop(m, some_r, expressionA, expressionB);
else {
innerLoop(m, some_r, expressionC, expressionC);
}
}
}