Conditional (ternary) operator

Issue #267 resolved
Matthias Moulin created an issue

An interesting addition to Blaze is a function, Select, to represent the conditional (ternary)?: operator, which unfortunately could not be overloaded in C++, but naturally translates to SIMD intrinsics using a mask (with the difference that short circuiting is not possible). (Note that short circuiting is also not possible for overloads of operator && and ||, but that is never really a use case for an algebra library).

Select(V(bool), V(X), V(X));

Pseudocode:

result[i] = (V1[i] & mask[i])|(V2[i] & ~mask[i]);

Related intrinsics:

SSE: _mm_and_ps, _mm_andnot_ps, _mm_or_ps

ARM NEON: vbslq_f32

Comments (5)

  1. Klaus Iglberger

    Hi Matthias!

    Thanks creating this proposal. This indeed sounds like a reasonable and useful addition to Blaze. We will consider it for the next releases of Blaze. Thanks again,

    Best regards,

    Klaus!

  2. 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.7.

    The select() Operation

    The select() function performs a componentwise, conditional selection of elements. Given the three dense vectors cond, a, and b, in case an element in the cond vector evaluates to true, the according element of a is selected, in case the cond element evaluates to false, the according element of b is selected. The following example demonstrates the use of the select() function:

    blaze::DynamicVector<bool> cond{ true, false, true false };
    blaze::DynamicVector<int> a{ 1, -1, 1, -1 };
    blaze::DynamicVector<int> b{ -2, 2, -2, 2 };
    blaze::DynamicVector<int> c;
    // ... Resizing and initialization
    
    c = select( cond, a, b );  // Results in ( 1, 2, 1, 2 )
    

    Alternatively it is possible to use three dense matrices:

    blaze::DynamicMatrix<bool> cond{ { true, false }, { true false } };
    blaze::DynamicMatrix<int> A{ { 1, -1 }, { 1, -1 } };
    blaze::DynamicMatrix<int> B{ { -2, 2 }, { -2, 2 } };
    blaze::DynamicMatrix<int> C;
    // ... Resizing and initialization
    
    C = select( cond, A, B );  // Results in ( 1, 2 ) ( 1, 2 )
    
  3. Log in to comment