2012-06-06 15 views
7

Ho bisogno di eseguire l'autocorrelazione di un array (vettore) ma ho difficoltà a trovare il modo corretto per farlo. Credo di aver bisogno del metodo "vDSP_conv" da Accelerate Framework, ma non posso seguire come installarlo correttamente. La cosa che mi distoglie di più è la necessità di 2 ingressi. Forse ho la funzione sbagliata, ma non sono riuscito a trovarne uno che funzionasse su un singolo vettore.Eseguire autocorrelazione con vDSP_conv da Apple Accelerate Framework

La documentazione può essere trovata here

copiati dal sito

vDSP_conv

esegue sia correlazione o la convoluzione su due vettori; singola precisione .

vuoto vDSP_conv (const float __vDSP_signal [], vDSP_Stride __vDSP_signalStride, float const __vDSP_filter [], vDSP_Stride __vDSP_strideFilter, float __vDSP_result [], vDSP_Stride __vDSP_strideResult, vDSP_Length __vDSP_lenResult, vDSP_Length __vDSP_lenFilter);

Parametri

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

Per un esempio, si supponga di disporre di un array di float x = [1.0, 2.0, 3.0, 4.0, 5.0]. Come prenderei l'autocorrelazione di quello?

L'output dovrebbe essere qualcosa di simile a float y = [5.0, 14.0, 26.0, 40.0, 55.0, 40.0, 26.0, 14.0, 5.0] //generated using Matlab's xcorr(x) function

risposta

4

eseguendo autocorrelazione significa semplicemente si prende la correlazione incrociata di un vettore con se stessa. Non c'è niente di speciale in questo.

così nel tuo caso, fare:

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

controllo un codice di esempio per maggiori dettagli: (che fa un convoluzione)

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

EDIT: Questo rasenta ridicolo, ma si è necessario compensare il valore x con uno specifico numero di zeri, che è semplicemente pazzesco.

il seguente è un codice di lavoro, è sufficiente impostare il filtro per il valore di x che desideri, e sarà mettere il resto in posizione corretta:

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); 
+0

Ho appena provato questo con il mio esempio. Ma emette dati leggermente errati. Che cosa sto facendo di sbagliato? x = da 1 a 5 e il risultato è la dimensione 9 (5 * 2 -1) vDSP_conv (x, 1, x, 1, result, 1, 9, 5); -> uscite -> 55.0, 40.0, 26.0, 14.0, 5.0, 0.0, 0.0, 0.0, 294.0 – MrHappyAsthma

+0

Penso di aver fatto un errore, potrebbe essere necessario eseguire il pad x con gli zeri ... Non ho il mio Mac di fronte di me, ma sembra che l'input dovrebbe essere più lungo dell'output (che è a dir poco strano) – Rasman

+0

Blah: P che puzza. Ill cercherò di giocarci. Se ti imbatti in un modo per risolverlo di sicuro, per favore pubblica: D – MrHappyAsthma