Are there any Conditional operators in vDSP?

Hi.

I want to implement the code below using vDSP.

for i in a.indices {
  a[i] = n[i] == 0.0 ? 0.0 : b[i] / n[i]
}

This code is slow. Are there any good implementation using Accelerate framework?

Replies

You could use vDSP_vdiv which will return inf when dividing by zero (that is, there won't be a runtime error). Or you could use vDSP_vcmprs to create copies of b and n where n isn't 0.

Thank you!

vDSP_vcmprs is what I need!

Sorry, I misunderstood.

What I need is masking nan values, not gathering non-nan values.

As you said, vDSP_vdiv returns nan(, not inf) when you divide by zero. And I cannot find any effective compare operations to mask nan. Are there any good functions?

What I am really doing is,

let numerators: [Float] = ...
let denominators: [Float] = ...
let divides = vDSP.divide(numerators, denominators)
let alternativesOfNAN: [Float] = ...

for i in divides {
    if divides[i].isNaN {
        divides[i] = alternativesOfNAN[i]    
    }
}

The last loop is quite slow compared with other parts using vDSP.

I might solve it by myself.

let numerators: [Float] = ...
let denominators: [Float] = ... // actually these are integers in my case

let denominatorsEpsilon = vDSP.add(Float.leastNonzeroMagnitude * 10000000, denominators) // (Float.leastNonzeroMagnitude * 10000000 is minimal number to avoid NaN when dividing.
let divides = vDSP.divide(numerators, denominatorsEpsilon)

let alternativesOfNAN: [Float] = ...

let denominatorsClip = vDSP.clip(denominators, to: 0...1) // denominatorsClip are 0 or 1 since denominators are integers
let result = vDSP.subtract(multiplication: (divides, denominatorsClip), multiplication: (alternativesOfNAN, vDSP.add(-1, denominatorsClip)))

I don't like this code since it is not precise and includes many unnecessary operations, but it is much faster than code checking isNaN.