Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

Questions re. ippsCrossCorrLagMax_32f64f

siddy
Beginner
323 Views
Hi everyone,
Thanks for helping me so far!
Although have used the above mentioned function, I still feel I have not yet grasped the
exact workings of it, in relation to the input arguments.
I am trying to find the cross correlation of 2 ipps vectors. The vectors may result in both a positive
or a negative lag, which I do not know apriori. Since I was not sure if the function actually returned negative lags (as per my matlab prototype), I did the following:
//---------------------------------------------------------------------------------------------------------------------
st = ippsCrossCorrLagMax_32f64f(smoothCol1, smoothCol2, nSamples, nSamples/2, &max, &maxIndx1);

st = ippsCrossCorrLagMax_32f64f(smoothCol2, smoothCol1, nSamples, nSamples/2, &max, &maxIndx2);

// -----------------------------------------------------------------------------------
if(maxIndx1 > maxIndx2){

Lag = ((double)maxIndx1);
}
else{

Lag = -((double)maxIndx2)/;
}

//std::cout << "Lag : " << Lag << std::endl;
return Lag;
//------------------------------------------------------------------------------------------------------------------------

I did this, because i was not able to specify the origin of the relative shifts to somewhere in the middle of the vector, in a clean way.
Is the logic correct? Or am I doing superflous correlations, and it is, by some trick, possible to get
the negative lags? Maybe my terminology is contaminated by what Matlab is doing, but to me, negative lag is that the maximum correlation occurs for shifts to the left of origin, and positive to the right. In my matlab prototype, negative lags are returned without any extra logic.


Thanks again for all the help,
Sid.
0 Kudos
1 Solution
igorastakhov
New Contributor II
323 Views
Sid,

CrossCorr is symmetrical operation - so it doesn't matter what vector is the first and what is the second and lowLag parameter is just defines the starting point of crosscorr - in other words playing with lowLag and dstLen you can obtaing any part of the full cross-correlation of two vectors (that will occur if lowLag = src1Len-1 and dstLen = src1Len+src2Len-1. Below is a comment on internal realization - think it will be helpful for final understanding and looking for a correspondence with MatLab:

// Let us examine two variants of cross-correlation:

// a) srcLen1 > srcLen2, for example

// pSrc1 = y0,y1,y2,y3,y4,y5,y6,y7,y8 ( srcLen1 = 9 )

// pSrc2 = x0,x1,x2,x3,x4 ( srcLen2 = 5 )

// lowLag = -8 ( full cross-correlation )

// Output will be as below: _

// x0*y8 \

// x0*y7+x1*y8 | this part has length = first ( see function ),

// x0*y6+x1*y7+x2*y8 | ownFirstTriangle function is used;

// x0*y5+x1*y6+x2*y7+x3*y8 _/

// x0*y4+x1*y5+x2*y6+x3*y7+x4*y8 \

// x0*y3+x1*y4+x2*y5+x3*y6+x4*y7 | this part has length = filter ( see function ),

// x0*y2+x1*y3+x2*y4+x3*y5+x4*y6 | ownBackFilter function is used;

// x0*y1+x1*y2+x2*y3+x3*y4+x4*y5_/

// x0*y0+x1*y1+x2*y2+x3*y3+x4*y4 \

// x1*y0+x2*y1+x3*y2+x4*y3 | this part has length = last ( see function ),

// x2*y0+x3*y1+x4*y2 | ownLastTriangle function is used,

// x3*y0+x4*y1 | note: this part starts from lag = 0;

// x4*y0 _/

//

// b) srcLen1 < srcLen2, for example

// pSrc1 = y0,y1,y2,y3,y4 ( srcLen1 = 5 )

// pSrc2 = x0,x1,x2,x3,x4,x5,x6,x7,x8 ( srcLen2 = 9 )

// lowLag = -4 ( full cross-correlation )

// Output will be as below: _

// x0*y4 \

// x0*y3+x1*y4 | this part has length = first ( see function ),

// x0*y2+x1*y3+x2*y4 | ownFirstTriangle function is used;

// x0*y1+x1*y2+x2*y3+x3*y4 _/

// x0*y0+x1*y1+x2*y2+x3*y3+x4*y4 \ note: this part starts from lag = 0,

// x1*y0+x2*y1+x3*y2+x4*y3+x5*y4 | this part has length = filter ( see function ),

// x2*y0+x3*y1+x4*y2+x5*y3+x6*y4 | ownForwFilter function is used;

// x3*y0+x4*y1+x5*y2+x6*y3+x7*y4_/

// x4*y0+x5*y1+x6*y2+x7*y3+x8*y4 \

// x5*y0+x6*y1+x7*y2+x8*y3 | this part has length = last ( see function ),

// x6*y0+x7*y1+x8*y2 | ownLastTriangle function is used,

// x7*y0+x8*y1 |

// x8*y0 _/

//

// As one can see from (a) and (b) the functions ownFirstTriangle and ownLastTriangle

// are symmetrical, so the same algorithm can be implemented. The same words can be said

// about the functions ownBackFilter and ownForwFilter.

//

// For long enough vectors ( "net" dstLen > IPPSCROSSCORR_START_FFT_USE ) the algorithm

// with FFT is used instead of direct calculations:

// pSrc1 = y0,y1,y2,...,y[n-1], srcLen1 = n,

// pSrc2 = x0,x1,x2,...,x[k-1], srcLen2 = k;

// l = n + k - 1 - full cross-correlation length;

// the order of FFT would be "m" from inequality: l <= 2^m;

// the vectors for transform would be formed as below: ( zero padded )

// y = y0,y1,y2,...,y[n-1],0,0[n+1],...,0[l-1] "0" means zero here;

// x = 0[0],0[1],...,0[n-2],x0,x1,x2,...,x[k-1],0,0,...,0[l-1];

// Y = FFT( y );

// X = FFT( x );

// Z = Y~ * X; (~ means complex conjugate );

// pDst = FFT^(-1)( Z );

//


Guess you see now that there is no any reason to call it twice - you should use negative lowLag and you'll have the full cross-corr output for single call. As regarding IPPAPI macro - it's just a line from ipps.h file - all functions are defined in the same manner and after this macro application by the compiler you'll have the traditional C function definition: stdcall IppStatus ippsCrossCorr....

Regards,
Igor

View solution in original post

0 Kudos
4 Replies
Ying_H_Intel
Employee
323 Views
Hi Sid,

As you see in IPP manual, the function doen't support Negative lags, so it looks right, you have to compuate theone like you did.

Best Regards,
Ying
0 Kudos
igorastakhov
New Contributor II
323 Views
Hi Sid,

I think this is not the optimal approach - it's better to use
IPPAPI(IppStatus, ippsCrossCorr_32f, (const Ipp32f* pSrc1, int src1Len, const Ipp32f* pSrc2, int src2Len, Ipp32f* pDst, int dstLen, int lowLag))
function and then call(for cross-corr dst)

IPPAPI ( IppStatus, ippsMaxIndx_32f, ( const Ipp32f* pSrc, int len, Ipp32f* pMax, int* pIndx ))
it will be significantly faster than to perform 2 correlations

Regards,
Igor

0 Kudos
siddy
Beginner
323 Views
Thanks Igor. I will take your advice on this one. Just 2 quick questions:
1) Will I have to call this twice, once for positive, and once for negative lag? I think I will have to recalculate the lag with the signs based on the length of the vectors. Can you confirm this?
2) What does IPPAPI do? Does it make things more efficient that Ippstatus st = ipps<>..(...) type of
function call?

Thanks,
Sid.
0 Kudos
igorastakhov
New Contributor II
324 Views
Sid,

CrossCorr is symmetrical operation - so it doesn't matter what vector is the first and what is the second and lowLag parameter is just defines the starting point of crosscorr - in other words playing with lowLag and dstLen you can obtaing any part of the full cross-correlation of two vectors (that will occur if lowLag = src1Len-1 and dstLen = src1Len+src2Len-1. Below is a comment on internal realization - think it will be helpful for final understanding and looking for a correspondence with MatLab:

// Let us examine two variants of cross-correlation:

// a) srcLen1 > srcLen2, for example

// pSrc1 = y0,y1,y2,y3,y4,y5,y6,y7,y8 ( srcLen1 = 9 )

// pSrc2 = x0,x1,x2,x3,x4 ( srcLen2 = 5 )

// lowLag = -8 ( full cross-correlation )

// Output will be as below: _

// x0*y8 \

// x0*y7+x1*y8 | this part has length = first ( see function ),

// x0*y6+x1*y7+x2*y8 | ownFirstTriangle function is used;

// x0*y5+x1*y6+x2*y7+x3*y8 _/

// x0*y4+x1*y5+x2*y6+x3*y7+x4*y8 \

// x0*y3+x1*y4+x2*y5+x3*y6+x4*y7 | this part has length = filter ( see function ),

// x0*y2+x1*y3+x2*y4+x3*y5+x4*y6 | ownBackFilter function is used;

// x0*y1+x1*y2+x2*y3+x3*y4+x4*y5_/

// x0*y0+x1*y1+x2*y2+x3*y3+x4*y4 \

// x1*y0+x2*y1+x3*y2+x4*y3 | this part has length = last ( see function ),

// x2*y0+x3*y1+x4*y2 | ownLastTriangle function is used,

// x3*y0+x4*y1 | note: this part starts from lag = 0;

// x4*y0 _/

//

// b) srcLen1 < srcLen2, for example

// pSrc1 = y0,y1,y2,y3,y4 ( srcLen1 = 5 )

// pSrc2 = x0,x1,x2,x3,x4,x5,x6,x7,x8 ( srcLen2 = 9 )

// lowLag = -4 ( full cross-correlation )

// Output will be as below: _

// x0*y4 \

// x0*y3+x1*y4 | this part has length = first ( see function ),

// x0*y2+x1*y3+x2*y4 | ownFirstTriangle function is used;

// x0*y1+x1*y2+x2*y3+x3*y4 _/

// x0*y0+x1*y1+x2*y2+x3*y3+x4*y4 \ note: this part starts from lag = 0,

// x1*y0+x2*y1+x3*y2+x4*y3+x5*y4 | this part has length = filter ( see function ),

// x2*y0+x3*y1+x4*y2+x5*y3+x6*y4 | ownForwFilter function is used;

// x3*y0+x4*y1+x5*y2+x6*y3+x7*y4_/

// x4*y0+x5*y1+x6*y2+x7*y3+x8*y4 \

// x5*y0+x6*y1+x7*y2+x8*y3 | this part has length = last ( see function ),

// x6*y0+x7*y1+x8*y2 | ownLastTriangle function is used,

// x7*y0+x8*y1 |

// x8*y0 _/

//

// As one can see from (a) and (b) the functions ownFirstTriangle and ownLastTriangle

// are symmetrical, so the same algorithm can be implemented. The same words can be said

// about the functions ownBackFilter and ownForwFilter.

//

// For long enough vectors ( "net" dstLen > IPPSCROSSCORR_START_FFT_USE ) the algorithm

// with FFT is used instead of direct calculations:

// pSrc1 = y0,y1,y2,...,y[n-1], srcLen1 = n,

// pSrc2 = x0,x1,x2,...,x[k-1], srcLen2 = k;

// l = n + k - 1 - full cross-correlation length;

// the order of FFT would be "m" from inequality: l <= 2^m;

// the vectors for transform would be formed as below: ( zero padded )

// y = y0,y1,y2,...,y[n-1],0,0[n+1],...,0[l-1] "0" means zero here;

// x = 0[0],0[1],...,0[n-2],x0,x1,x2,...,x[k-1],0,0,...,0[l-1];

// Y = FFT( y );

// X = FFT( x );

// Z = Y~ * X; (~ means complex conjugate );

// pDst = FFT^(-1)( Z );

//


Guess you see now that there is no any reason to call it twice - you should use negative lowLag and you'll have the full cross-corr output for single call. As regarding IPPAPI macro - it's just a line from ipps.h file - all functions are defined in the same manner and after this macro application by the compiler you'll have the traditional C function definition: stdcall IppStatus ippsCrossCorr....

Regards,
Igor
0 Kudos
Reply