Perform autocorrelation using vDSP_conv from the Apple Accelerate Framework

I need to autocorrelate an array (vector), but it's hard for me to find the right way to do this. I believe that I need the "vDSP_conv" method from the Accelerate Framework, but I cannot follow its successful configuration. What throws me the most is the need for 2 inputs. Maybe I have the wrong function, but I could not find the one that worked on one vector.

The documentation can be found here.

Copied from site

vDSP_conv

Performs correlation or convolution on two vectors; One precision.

void vDSP_conv (const float __vDSP_signal [], vDSP_Stride __vDSP_signalStride, const float __vDSP_filter [], vDSP_Stride __vDSP_strideFilter, float __vDSP_result [], vDSP_Stride_ndult_ndult_ndult_ndult_ndult_ndult_ndult_ndult_eng

Options

__ vDSP_signal

Input vector A. The length of this vector must be at least __vDSP_lenResult + __vDSP_lenFilter - 1. 

__ vDSP_signalStride

 The stride through __vDSP_signal. 

__ vDSP_filter

 Input vector B. 

__ vDSP_strideFilter

 The stride through __vDSP_filter. 

__ vDSP_result

 Output vector C. 

__ vDSP_strideResult

 The stride through __vDSP_result. 

__ vDSP_lenResult

 The length of __vDSP_result. 

__ vDSP_lenFilter

 The length of __vDSP_filter. 

As an example, suppose you have an array float x = [1.0, 2.0, 3.0, 4.0, 5.0] . How can I take an autocorrelation of this?

The result should be something like float y = [5.0, 14.0, 26.0, 40.0, 55.0, 40.0, 26.0, 14.0, 5.0] //generated using Matlab xcorr(x) function

+7
source share
1 answer

doing autocorrelation simply means that you take the cross-correlation of one vector with yourself. This is not unusual.

so in your case do:

 vDSP_conv(x, 1, x, 1, result, 1, 2*len_X-1, len_X); 

check the sample code for more details: (which does the convolution)

http://disanji.net/iOS_Doc/#documentation/Performance/Conceptual/vDSP_Programming_Guide/SampleCode/SampleCode.html

EDIT: This borders on ridiculous, but you need to compensate for the value of x by a certain number of zeros, which is just crazy.

Below is the working code, just set the filter to the x value you want and it will put the rest in the correct position:

 float *signal, *filter, *result; int32_t signalStride, filterStride, resultStride; uint32_t lenSignal, filterLength, resultLength; uint32_t i; filterLength = 5; resultLength = filterLength*2 -1; lenSignal = ((filterLength + 3) & 0xFFFFFFFC) + resultLength; signalStride = filterStride = resultStride = 1; printf("\nConvolution ( resultLength = %d, " "filterLength = %d )\n\n", resultLength, filterLength); /* Allocate memory for the input operands and check its availability. */ signal = (float *) malloc(lenSignal * sizeof(float)); filter = (float *) malloc(filterLength * sizeof(float)); result = (float *) malloc(resultLength * sizeof(float)); for (i = 0; i < filterLength; i++) filter[i] = (float)(i+1); for (i = 0; i < resultLength; i++) if (i >=resultLength- filterLength) signal[i] = filter[i - filterLength+1]; /* Correlation. */ vDSP_conv(signal, signalStride, filter, filterStride, result, resultStride, resultLength, filterLength); printf("signal: "); for (i = 0; i < lenSignal; i++) printf("%2.1f ", signal[i]); printf("\n filter: "); for (i = 0; i < filterLength; i++) printf("%2.1f ", filter[i]); printf("\n result: "); for (i = 0; i < resultLength; i++) printf("%2.1f ", result[i]); /* Free allocated memory. */ free(signal); free(filter); free(result); 
+4
source

All Articles