Why doesn't vDSP_maxv find the max value in the vector?

352 Views Asked by At

vDSP_maxv is not assigning the max value to output in the code below.

I expected the last line to print 2, but instead it prints something different each time, usually a very large or small number like 2.8026e-45

I've read this tutorial, the documentation, and the inline documentation in the header file for vDSP_maxv, but I don't see why the code below isn't producing the expected result.

Making numbers an UnsafePointer instead of an UnsafeMutablePointer didn't work, nor did a number of other things I've tried, so maybe I'm missing something fundamental.

import Accelerate

do {
    // INPUT - pointer pointing at: 0.0, 1.0, 2.0
    let count = 3
    let numbers = UnsafeMutablePointer<Float>
        .allocate(capacity: count)
    defer { numbers.deinitialize() }
    for i in 0..<count {
        (numbers+i).initialize(to: Float(i))
    }

    // OUTPUT
    var output = UnsafeMutablePointer<Float>
        .allocate(capacity: 1)

    // FIND MAX
    vDSP_maxv(
        numbers,
        MemoryLayout<Float>.stride,
        output,
        vDSP_Length(count)
    )
    print(output.pointee) // prints various numbers, none of which are expected
}
1

There are 1 best solutions below

0
On BEST ANSWER

You are mistaking the usage of the stride parameter to vDSP_maxv. You need to pass the number of elements consisting a single stride, not the number of bytes.

vDSP_maxv(::::)

*C = -INFINITY;
for (n = 0; n < N; ++n)
    if (*C < A[n*I])
        *C = A[n*I];

In the pseudo code above, I represents the stride parameter, and you see giving 4 (MemoryLayout<Float>.stride) to I would generate indexes exceeding the bound of A (your numbers).

Some other parts fixed to fit my preference, but the most important thing is the second parameter for vDSP_maxv:

import Accelerate

do {
    // INPUT - pointer pointing at: 0.0, 1.0, 2.0
    let numbers: [Float] = [0.0, 1.0, 2.0]

    // OUTPUT
    var output: Float = Float.nan

    // FIND MAX
    vDSP_maxv(
        numbers,
        1, //<- when you want to use all elements in `numbers` continuously, you need to pass `1`
        &output,
        vDSP_Length(numbers.count)
    )
    print(output) //-> 2.0
}