Is argmax() and argmin() missing for vector operations?

Issue #256 resolved
Johannes Czech created an issue

Hello Klaus Iglberger,

thank your for creating this amazing library!

I was wondering if there is a.argmax() and .argmin() function for Vector Operations.

I could only see a solution with .min() and .max() in combination with .find() or iterating through the vector manually,

but this seems only to work with the CompressedVector type and is presumable not an ideal approach.

[https://bitbucket.org/blaze-lib/blaze/wiki/Vector](https://bitbucket.org/blaze-lib/blaze/wiki/Vector) Operations#!min-max

https://bitbucket.org/blaze-lib/blaze/wiki/Vector Operations#!element-lookup

Best regards,

~Johannes Czech

Comments (12)

  1. Johannes Czech reporter

    I created the following method for resolving this issue:

    template< typename VT  // Type of the dense vector
            , bool TF >    // Transpose flag
    inline decltype(auto) argmax( const DynamicVector<VT,TF>& dv ) {
        size_t idx = 0;      // set the first index as the hypothesis for the armgax index
        VT cur_max = dv[0];  // initialize the current maximum value
    
        // iterate through the vector and update idx and cur_max accordingly
        for( size_t i=1UL; i<dv.size(); ++i ) {
            if (dv[i] > cur_max) {
                idx = i;
                cur_max = dv[i];
            }
        }
        return idx;
    }
    

    and tested it against the Xtensor 0.20.8 and Eigen library 3.3.7 on an identical 80 element float vector for 1e7 iterations:

    I'm a bit surprised that this implementation is faster on my system than Eigen's eigen_vec.maxCoeff(&index) as well as XTensor's xt::argmax(xtensor_vec) even when using blaze::DynamicVector instead of blaze::StaticVector:

    argmax xtensor 4
    argmax blaze_vec 4
    argmax eigen_vec 4
    
    Elapsed time xtensor: 1042ms
    Elapsed time blaze: 886ms
    Elapsed time eigen: 909ms
    

    This functionality might also be useful for others and I propose to include this method or an improved version of it to the blaze library.

  2. Klaus Iglberger

    Hi Johannes!

    Thanks a lot for the proposal. This indeed sounds like a reasonable addition to Blaze.

    Based on your example we assume you have the following algorithmic details in mind:

    • Performs a linear search and returns the index of the first smallest (argmin()) or first largest (argmax()) element;
    • Returns 0 in case of an empty vector.

    We will try to integrate these two functions into Blaze as soon as possible. Thanks again for the proposal,

    Best regards,

    Klaus!

  3. Johannes Czech reporter

    Based on your example we assume you have the following algorithmic details in mind:

    + Performs a linear search and returns the index of the first smallest (argmin()) or first largest (argmax()) element;

    + Returns 0 in case of an empty vector.

    Thanks, that’s exactly what I had in mind.

  4. Klaus Iglberger

    Summary

    The feature has been implemented, tested, optimized, and documented as required. It is immediately available via cloning the Blaze repository and will be officially released in Blaze 3.6.

    Argmin

    The argmin() function returns the index of the first smallest element of the given dense vector. argmin() can only be used for element types that support the smaller-than relationship. In case the given vector currently has a size of 0, the returned index is 0.

    blaze::DynamicVector<int> a{ 1, -2, 3, 0 };
    const size_t minindex = argmin( a );  // Results in 1
    

    Argmax

    The argmax() function returns the index of the first largest element of the given dense vector. argmax() can only be used for element types that support the smaller-than relationship. In case the given vector currently has a size of 0, the returned index is 0.

    blaze::DynamicVector<int> a{ 1, -2, 3, 0 };
    const size_t maxindex = argmax( a );  // Results in 2
    
  5. Log in to comment