Eigen boolean array slicing
Asked Answered
I

2

11

In MATLAB it is common to slice out values that satisfy some condition from a matrix/array (called logical indexing).

vec = [1 2 3 4 5];
condition = vec > 3;
vec(condition) = 3;

How do I do this in Eigen? So far I have:

Eigen::Matrix<bool, 1, 5> condition = vec.array() > 3;
Inspan answered 27/4, 2013 at 14:44 Comment(2)
dont have much experience with Eigen, but looks like you're looking for the select featurePermeance
Possible duplicate of Submatrices and indices using EigenCohort
C
0

As pointed out in the answer to an similar question here: Submatrices and indices using Eigen, libigl adds this functionality to Eigen.

igl::slice(A,indices,B);

Is equivalent to

B = A(indices)
Cohort answered 13/7, 2016 at 21:15 Comment(3)
while it may be useful, it doesn't answer the question here. OP asked for the equivalent of MATLAB's A(A>3)=3, not how to extract a submatrix... The solution I showed is basically an element-wise ternary operator equivalent to: m(i) = (m(i) > 3) ? 3 : m(i).Permeance
Browsing the docs, igl::slice_into, is a closer match, but as far as I can tell, it only works for a list of indices, not a vector of logicals... Even their MATLAB-to-eigen/igl conversion table suggests using Eigen::select: libigl.github.io/libigl/matlab-to-eigen.html (see the A(B == 0) = C(B==0) statement).Permeance
igl::slice_mask(vec,condition,output)Isidoro
P
16

Try this:

#include <iostream>
#include <Eigen/Dense>

int main()
{
    Eigen::MatrixXi m(1, 5);
    m << 1, 2, 3, 4, 5;
    m = (m.array() > 3).select(3, m);
    std::cout << m << std::endl;

    return 0;
}
Permeance answered 27/4, 2013 at 15:24 Comment(2)
@srsci: what do you mean? The example above is working fine, it's practically straight out of the documentation..Permeance
Actually, for the given problem (i.e., capping of the values) just m.cwiseMin(3) should work (and is usually faster).Groggery
C
0

As pointed out in the answer to an similar question here: Submatrices and indices using Eigen, libigl adds this functionality to Eigen.

igl::slice(A,indices,B);

Is equivalent to

B = A(indices)
Cohort answered 13/7, 2016 at 21:15 Comment(3)
while it may be useful, it doesn't answer the question here. OP asked for the equivalent of MATLAB's A(A>3)=3, not how to extract a submatrix... The solution I showed is basically an element-wise ternary operator equivalent to: m(i) = (m(i) > 3) ? 3 : m(i).Permeance
Browsing the docs, igl::slice_into, is a closer match, but as far as I can tell, it only works for a list of indices, not a vector of logicals... Even their MATLAB-to-eigen/igl conversion table suggests using Eigen::select: libigl.github.io/libigl/matlab-to-eigen.html (see the A(B == 0) = C(B==0) statement).Permeance
igl::slice_mask(vec,condition,output)Isidoro

© 2022 - 2024 — McMap. All rights reserved.