get all the indexes by a condition

Issue #362 resolved
edward Miller created an issue

Hi

i am new to blaze and i am trying to get all the indexes from a vector with a condition

for example in python with numpy :

a = np.array([4, 5, 6, 2, 3, 4])

b = np.where(a==4)

#b will be [0,5]
print(b)

is there a similar implementation in blaze

i also know about std::find_if which can be used to find an element by a condition in a vector and can be used to find all the elements

for example :

std::vector<int> a = {4,5,6,2,3,4};

std::vector<int> b;

auto it = std::find_if(std::begin(a), std::end(a), [](int i){return i == 4;});
while (it != std::end(a)) {
    b.emplace_back(std::distance(std::begin(a), it));
    it = std::find_if(std::next(it), std::end(a), [](int i){return i == 4;});
    }
//b will be {0,5}

for (std::vector<int>::const_iterator i = b.begin(); i != b.end(); ++i)
    std::cout << *i << ' ';

my thanks

edward

Comments (3)

  1. Klaus Iglberger

    Hi Edward!

    Thanks for creating this issue. Unfortunately Blaze doesn’t have any operation that could be used for the purpose of selecting indices. The best option at this point is to implement this operation manually:

    template< typename VT, bool TF, typename Selector >
    decltype(auto) where( const blaze::DenseVector<VT,TF>& dv, Selector select )
    {
       const size_t N( size(dv) );
       blaze::DynamicVector<size_t,TF> res( N, 0UL );
       size_t j( 0UL );
    
       for( size_t i=0UL; i<N; ++i ) {
          if( select( (~dv)[i] ) ) res[j++] = i;
       }
    
       resize( res, j );
    
       return res;
    }
    
    int main()
    {
       const blaze::DynamicVector<int>    a{ 4, 5, 6, 2, 3, 4 };
       const blaze::DynamicVector<size_t> b( where( a, [](int v){ return v == 4; } ) );
    
       // Prints (0 5)
       std::cout << "\n b = " << trans(b) << "\n\n";
    }
    

    Note that this operation always returns a DynamicVector, because the number of resulting indices is unknown at compile time. As a consequence, this function will always allocate.

    We’ll see how we can provide a generic operation that can be used for this purpose. Thanks again for creating this issue,

    Best regards,

    Klaus!

  2. Log in to comment