summaryrefslogtreecommitdiff
path: root/macros/finddelay.sci
diff options
context:
space:
mode:
Diffstat (limited to 'macros/finddelay.sci')
-rw-r--r--macros/finddelay.sci187
1 files changed, 187 insertions, 0 deletions
diff --git a/macros/finddelay.sci b/macros/finddelay.sci
new file mode 100644
index 0000000..eb8e96a
--- /dev/null
+++ b/macros/finddelay.sci
@@ -0,0 +1,187 @@
+function d = finddelay(x,y,varargin)
+// This function returns the estimated delay between two input signals using crosscorrelation.
+// If signals are periodic, delay with least absolute value is returned.
+
+// Calling Sequence
+// D = FINDDELAY(X,Y)
+// D = FINDDELAY(...,MAXLAG)
+
+// Description
+// D = FINDDELAY(X,Y), returns estimated Delay D between X
+// and Y. D is positive implies Y is delayed with respect to X and vice versa.
+// If X, Y are matrices, then D is a row vector corresponding to delay between columns of X and Y
+
+// D = FINDDELAY(...,MAXLAG), uses MAXLAG as the maximum correlation
+// window size used to find the estimated delay(s) between X and Y:
+//
+// > If MAXLAG is an integer-valued scalar, and X and Y are row or column
+// vectors or matrices, the vector D of estimated delays is found by
+// cross-correlating (the columns of) X and Y over a range of lags
+// -MAXLAG:MAXLAG.
+// > If MAXLAG is an integer-valued row or column vector, and one input is vector
+// and another be matirx (let X is a row or column vector ,
+// and Y is a matrix) then the vector D of estimated delays is found by
+// cross-correlating X and column J of Y over a range of lags
+// -MAXLAG(J):MAXLAG(J), for J=1:Number of columns of Y.
+// > If MAXLAG is an integer-valued row or column vector, and X and Y are
+// both matrices. then vector D of estimated delays is found by
+// cross-correlating corresponding columns of X and Y over a range of lags
+// -MAXLAG(J):MAXLAG(J).
+//
+// By default, MAXLAG is equal to MAX(LX,LY)-1 for vectors,
+
+// Examples
+// X = [ 0 0 1 2 3 ];
+// Y = [ 0 0 0 1 2 3];
+// D = finddelay(X,Y,2)
+// disp(D)
+// X = [ 0 1 0 0 ; 1 0 2 1 ;0 0 0 2 ];
+// Y = [ 0 0 1 0 ;1 0 0 2 ; 0 0 0 0 ];
+// D = finddelay(X,Y)
+// disp(D)
+
+// See also
+// alignsignals
+
+// Authors
+// Pola Lakshmi Priyanka, IIT Bombay//
+
+
+//*************************************************************************************************************************************//
+
+
+// Check number of input arguments
+[out_a,inp_a]=argn(0)
+
+if inp_a<=1 | inp_a>3 then
+ error('comm:finddelay: Invalid number of input arguments')
+end
+
+if out_a>1 then
+ error('comm:finddelay: Invalid number of output arguments')
+end
+
+//Error Checking of input arguments
+if (~or(type(x)==[1 5 8]) | (isempty(x) ) | (ndims(x)>2) | ~or(type(y)==[1 5 8]) | (isempty(y) ) | (ndims(y)>2))
+ error('comm:finddelay:Input arguments must be numeric');
+end
+
+if isvector(x)
+ x = x';
+end
+
+if isvector(y)
+ y = y';
+end
+
+[row_x,col_x] = size(x);
+[row_y,col_y] = size(y);
+
+x = double(x);
+y = double(y);
+
+
+// Check if matrices are of compatible
+if ~isvector(x) & ~isvector(y)
+ if col_x~=col_y
+ error('comm:finddelay:When both inputs are matrices, they must have the same number of columns.')
+ end
+end
+
+// Check for maxlag
+if inp_a==3
+
+ if ( ndims(varargin(1))>2 | ~isreal(varargin(1)) | isempty(varargin(1)) | or(isnan(varargin(1))) | or(isinf(varargin(1))) | varargin(1) ~= ceil(varargin(1))),
+ error('comm:finddelay:Input argument 3 should be a finite integer vector')
+ end
+
+ if ( (isvector(x)) & (isvector(y)) & (length(varargin(1))>1) )
+ error('comm:finddelay: If x and y are both vectors, maxlag should be a scalar')
+ elseif ( (isvector(y)) & (length(varargin(1))>1) & (length(varargin(1))~=col_x) ),
+ error('comm:finddelay: If maxlag is a row/column vector, it should be of same length as the number of columns of X or Y');
+ elseif ( (isvector(x)) & (length(varargin(1))>1) & (length(varargin(1))~=col_y) ),
+ error('comm:finddelay: If maxlag is a row/column vector, it should be of same length as the number of columns of X or Y');
+ elseif ( (length(varargin(1))>1) & (length(varargin(1))~=col_x) & (length(varargin(1))~=col_y) ),
+ error('comm:finddelay: If X and Y are matrices, MAXLAG should be the same length as the number of columns of X and Y.');
+ else
+ if isempty(varargin(1))
+ maxlag = max(row_x,row_y)-1; //default value
+ else
+ maxlag = double(abs(varargin(1)));
+ end
+ end
+else
+ maxlag = max(row_x,row_y)-1;
+end
+
+
+max_col=max(col_x,col_y);
+
+if (length(maxlag)==1)
+ maxlag = repmat(maxlag,1,max_col);
+end
+
+if col_x<max_col
+ x = repmat(x,1,max_col);
+elseif col_y<max_col
+ y = repmat(y,1,max_col);
+end
+
+
+// Initialise cross-correlation matrix .
+maxlag_max = max(maxlag);
+c_normalized = zeros(2*maxlag_max+1,max_col);
+index_max = zeros(1,max_col);
+max_c = zeros(1,max_col);
+
+
+// Compute cross-correlation matrix:
+sq_x = abs(x).^2
+sq_y = abs(y).^2
+cxx0 = sum(sq_x,"r");
+cyy0 = sum(sq_y,"r");
+
+for i = 1:max_col
+ if ( (cxx0(i)==0) | (cyy0(i)==0) )
+ c_normalized(:,i) = zeros(2*maxlag_max+1,1);
+ else
+ c_normalized(maxlag_max-maxlag(i)+1:maxlag_max-maxlag(i)+2*maxlag(i)+1,i) ...
+ = abs(xcorr(x(:,i),y(:,i),maxlag(i)))/sqrt(cxx0(i)*cyy0(i));
+ end
+end
+
+// Find lowest positive or zero indices of lags (negative delays) giving the
+// largest absolute values of normalized cross-correlations.
+
+[max_pos,index_max_pos] = max(c_normalized(maxlag_max+1:$,:),"r");
+// Find lowest negative indices of lags (positive delays) giving the largest
+// absolute values of normalized cross-correlations.
+A=c_normalized(1:maxlag_max,:)
+[max_neg,index_max_neg] = max(A($:-1:1,:),"r");
+
+if isempty(max_neg)
+ index_max = maxlag_max + index_max_pos;
+else
+ for i=1:max_col
+ if max_pos(i)>max_neg(i)
+ index_max(i) = maxlag_max + index_max_pos(i);
+ max_c(i) = max_pos(i);
+ elseif max_pos(i)<max_neg(i)
+ index_max(i) = maxlag_max + 1 - index_max_neg(i);
+ max_c(i) = max_neg(i);
+ elseif max_pos(i)==max_neg(i)
+ if index_max_pos(i)<=index_max_neg(i)
+ index_max(i) = maxlag_max + index_max_pos(i);
+ max_c(i) = max_pos(i);
+ else
+ index_max(i) = maxlag_max + 1 - index_max_neg(i);
+ max_c(i) = max_neg(i);
+ end
+ end
+ end
+end
+
+// Subtract delays.
+d = (maxlag_max + 1) - index_max;
+
+endfunction