From ab8ede08c7507ac439016e2028ec6228f12c675d Mon Sep 17 00:00:00 2001
From: marwan <>
Date: Thu, 14 Jun 2007 08:52:19 +0000
Subject: [PATCH] *** empty log message ***

---
 corrgram.m | 147 ++++++++++++++++++++++++++++++++
 migram.m   | 239 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 386 insertions(+)
 create mode 100644 corrgram.m
 create mode 100644 migram.m

diff --git a/corrgram.m b/corrgram.m
new file mode 100644
index 0000000..a30c962
--- /dev/null
+++ b/corrgram.m
@@ -0,0 +1,147 @@
+function [c_out, l_out, t_out] = corrgram(varargin)
+%CORRGRAM Calculate windowed cross correlation between two signals.
+%   C = CORRGRAM(A,B,MAXLAG,WINDOW,NOVERLAP) calculates the windowed cross   
+%   correlation between the signals in vector A and vector B. CORRGRAM splits  
+%   the signals into overlapping segments and forms the columns of C with 
+%   their cross correlation values up to maximum lag specified by scalar 
+%   MAXLAG. Each column of C contains the cross correlation function between 
+%   the short-term, time-localized signals A and B. Time increases linearly 
+%   across the columns of C, from left to right.  Lag increases linearly down 
+%   the rows, starting at -MAXLAG. If lengths of A and B differ, the shorter
+%   signal is filled with zeros. If N is the length of the signals, C is
+%   a matrix with 2*MAXLAG+1 rows and 
+%         k = fix((N-NOVERLAP)/(WINDOW-NOVERLAP)) 
+%   columns.
+%
+%   [C,L,T] = CORRGRAM(...) returns a column of lag L and one of time T
+%   at which the correlation coefficients are computed. L has length equal 
+%   to the number of rows of C, T has length k.
+%
+%   C = CORRGRAM(A,B) calculates windowed cross correlation using defeault
+%   settings; the defeaults are MAXLAG = floor(0.1*N), WINDOW = floor(0.1*N)
+%   and NOVERLAP = 0. You can tell CORRGRAM to use the defeault for any 
+%   parameter by leaving it off or using [] for that parameter, e.g. 
+%   CORRGRAM(A,B,[],1000).
+%
+%   CORRGRAM(A,B) with no output arguments plots the windowed cross 
+%   correlation using the current figure.
+%
+%   EXAMPLE:
+%       x = cos(0:.01:10*pi)';
+%       y = sin(0:.01:10*pi)' + .5 * randn(length(x),1);
+%       corrgram(x,y)
+%
+%   See also CORRCOEF, CORR, XCORR, MIGRAM.
+
+% Copyright (c) 2007 by AMRON
+% Norbert Marwan, Potsdam University, Germany
+% http://www.agnld.uni-potsdam.de
+%
+% $Date$
+% $Revision$
+
+
+error(nargchk(2,5,nargin))
+verbose = 0;
+
+x = varargin{1}; y = varargin{2};
+x = x(:); y = y(:);
+
+
+% check input and inital setting of parameters
+
+nx = length(x); ny = length(y);
+if nx < ny    % zero-pad x if it has length less than y
+    x(ny) = 0; nx = ny;
+end
+
+if ny < nx    % zero-pad y if it has length less than x
+    y(nx) = 0;
+end
+
+maxlag = floor(nx/10); 
+window = floor(nx/10);
+noverlap = 0;
+
+if length(varargin) > 2 & ~isempty(varargin{3})
+    maxlag = varargin{3};
+    if maxlag < 0, error('Requires positive integer value for maximum lag.'), end
+    if length(maxlag) > 1, error('Requires MAXLAG to be a scalar.'), end
+end
+
+if length(varargin) > 3 & ~isempty(varargin{4})
+    window = varargin{4};
+    if window < 0, error('Requires positive integer value for window length.'), end
+    if length(window) > 1, error('Requires WINDOW to be a scalar.'), end
+end
+
+if length(varargin) > 4 & ~isempty(varargin{5})
+    noverlap = varargin{5};
+    if noverlap < 0, error('Requires positive integer value for NOVERLAP.'), end
+    if length(noverlap) > 1, error('Requires NOVERLAP to be a scalar.'), end
+    if noverlap >= window, error('Requires NOVERLAP to be strictly less than the window length.'), end
+end
+
+
+% prepare time delayed signals
+X = buffer(x,maxlag+1,maxlag)';
+Y = fliplr(buffer(y,maxlag+1,maxlag)');
+
+% divide the delayed signals into overlapping windows
+% and compute the correlation coefficient
+cnt = 1;
+
+warning off
+C = zeros(2*maxlag+1, fix((nx-noverlap)/(window-noverlap)));
+if verbose, h = waitbar(0,'Compute cross correlation'); end
+
+% -MAXLAG:0
+[Yi dummy] = buffer(Y(:,1),window,noverlap,'nodelay'); 
+Yi = normalize(Yi);
+for i = 1:size(X,2), if verbose, waitbar(cnt/(2*size(X,2))), end
+    [Xi dummy] = buffer(X(:,i),window,noverlap,'nodelay');
+    Xi = normalize(Xi);
+    C(cnt,:) = mean(Xi .* Yi);
+    cnt = cnt + 1;
+end
+
+% 0:MAXLAG
+[Xi dummy] = buffer(X(:,end),window,noverlap,'nodelay');
+Xi = normalize(Xi);
+for i = 2:size(Y,2), if verbose, waitbar(cnt/(2*size(X,2))), end
+    [Yi dummy] = buffer(Y(:,i),window,noverlap,'nodelay');
+    Yi = normalize(Yi);
+    C(cnt,:) = mean(Xi .* Yi);
+    cnt = cnt + 1;
+end
+if verbose, delete(h), end
+
+warning on
+
+% create time scale for the windows
+t = (1:nx/size(Xi,2):nx)';
+l = (-maxlag:maxlag)';
+
+% display and output result
+if nargout == 0
+    newplot
+    imagesc(t, l, C)
+    xlabel('Time'), ylabel('Lag'), axis xy
+    title('Windowed cross correlation', 'fontweight', 'bold')
+    colorbar
+elseif nargout == 1,
+    c_out = C;
+elseif nargout == 2,
+    c_out = C;
+    l_out = l;
+elseif nargout == 3,
+    c_out = C;
+    l_out = l;
+    t_out = t;
+end
+
+
+function Y = normalize(X)
+    Y = X - repmat(mean(X), size(X,1), 1);
+    s = sqrt( sum(conj(Y) .* Y) / (size(Y,1) - 1) );
+    Y = Y ./ repmat(s, size(Y,1), 1);
diff --git a/migram.m b/migram.m
new file mode 100644
index 0000000..93d98a2
--- /dev/null
+++ b/migram.m
@@ -0,0 +1,239 @@
+function [c_out, l_out, t_out] = migram(varargin)
+%MIGRAM Calculate windowed mutual information between two signals.
+%   I = MIGRAM(A,B,MAXLAG,WINDOW,NOVERLAP) calculates the windowed mutual   
+%   information between the signals in vector A and vector B. MIGRAM splits  
+%   the signals into overlapping segments and forms the columns of I with 
+%   their mutual information values up to maximum lag specified by scalar 
+%   MAXLAG. Each column of I contains the mutual information function 
+%   between the short-term, time-localized signals A and B.  Time increases
+%   linearly across the columns of I, from left to right.  Lag increases 
+%   linearly down the rows, starting at -MAXLAG. If lengths of A and B 
+%   differ, the shorter signal is filled with zeros. If N is the length of 
+%   the signals, I is a matrix with 2*MAXLAG+1 rows and 
+%         k = fix((N-NOVERLAP)/(WINDOW-NOVERLAP)) 
+%   columns.
+%
+%   I = MIGRAM(A,B,MAXLAG,WINDOW,NOVERLAP,NBINS) calculates the mutual
+%   information based on histograms with the number of bins NBINS.
+%
+%   [I,L,T] = MIGRAM(...) returns a column of lag L and one of time T
+%   at which the mutual information is computed. L has length equal 
+%   to the number of rows of I, T has length k.
+%
+%   I = MIGRAM(A,B) calculates windowed mutual information using defeault
+%   settings; the defeaults are MAXLAG = floor(0.1*N), WINDOW = floor(0.1*N),
+%   NOVERLAP = 0 and NBINS = 10. You can tell CORRGRAM to use the defeault 
+%   for any parameter by leaving it off or using [] for that parameter, e.g. 
+%   MIGRAM(A,B,[],1000).
+%
+%   MIGRAM(A,B) with no output arguments plots the mutual information 
+%   using the current figure.
+%
+%   EXAMPLE:
+%       x = cos(0:.01:10*pi)';
+%       y = sin(0:.01:10*pi)' + .5 * randn(length(x),1);
+%       migram(x,y)
+%
+%   See also MI, CORRGRAM.
+
+% Copyright (c) 2007 by AMRON
+% Norbert Marwan, Potsdam University, Germany
+% http://www.agnld.uni-potsdam.de
+%
+% $Date$
+% $Revision$
+
+
+error(nargchk(2,6,nargin))
+verbose = 0;
+
+x = varargin{1}; y = varargin{2};
+x = x(:); y = y(:);
+
+
+% check input and inital setting of parameters
+
+nx = length(x); ny = length(y);
+if nx < ny    % zero-pad x if it has length less than y
+    x(ny) = 0; nx = ny;
+end
+
+if ny < nx    % zero-pad y if it has length less than x
+    y(nx) = 0;
+end
+
+maxlag = floor(nx/10); 
+window = floor(nx/10);
+noverlap = 0;
+nbins = 10;
+
+if length(varargin) > 2 & ~isempty(varargin{3})
+    maxlag = varargin{3};
+    if maxlag < 0, error('Requires positive integer value for maximum lag.'), end
+    if length(maxlag) > 1, error('Requires MAXLAG to be a scalar.'), end
+end
+
+if length(varargin) > 3 & ~isempty(varargin{4})
+    window = varargin{4};
+    if window <= 0, error('Requires positive integer value for window length.'), end
+    if length(window) > 1, error('Requires WINDOW to be a scalar.'), end
+end
+
+if length(varargin) > 4 & ~isempty(varargin{5})
+    noverlap = varargin{5};
+    if noverlap < 0, error('Requires positive integer value for NOVERLAP.'), end
+    if length(noverlap) > 1, error('Requires NOVERLAP to be a scalar.'), end
+    if noverlap >= window, error('Requires NOVERLAP to be strictly less than the window length.'), end
+end
+
+if length(varargin) > 5 & ~isempty(varargin{6})
+    noverlap = varargin{6};
+    if nbins <= 0, error('Requires positive integer value for NBINS.'), end
+    if length(nbins) > 1, error('Requires NBINS to be a scalar.'), end
+end
+
+
+
+% prepare time delayed signals
+X = buffer(x,maxlag+1,maxlag)';
+Y = fliplr(buffer(y,maxlag+1,maxlag)');
+
+% divide the delayed signals into overlapping windows
+% and compute the correlation coefficient
+cnt = 1;
+
+warning off
+C = zeros(2*maxlag+1, fix((nx-noverlap)/(window-noverlap)));
+if verbose, h = waitbar(0,'Compute mutual information'); end
+
+% -MAXLAG:0
+[Yi dummy] = buffer(Y(:,1),window,noverlap,'nodelay'); 
+Yi = normalize(Yi);
+if exist('accumarray','builtin') == 5
+    for i = 1:size(X,2), if verbose, waitbar(cnt/(2*size(X,2))), end
+        [Xi dummy] = buffer(X(:,i),window,noverlap,'nodelay');
+        C(cnt,:) = MI6(Xi, Yi, nbins);
+        cnt = cnt + 1;
+    end
+else
+    for i = 1:size(X,2), if verbose, waitbar(cnt/(2*size(X,2))), end
+        [Xi dummy] = buffer(X(:,i),window,noverlap,'nodelay');
+        C(cnt,:) = MI5(Xi, Yi, nbins);
+        cnt = cnt + 1;
+    end
+end
+
+% 0:MAXLAG
+[Xi dummy] = buffer(X(:,end),window,noverlap,'nodelay');
+Xi = normalize(Xi);
+if exist('accumarray','builtin') == 5
+    for i = 2:size(Y,2), if verbose, waitbar(cnt/(2*size(X,2))), end
+        [Yi dummy] = buffer(Y(:,i),window,noverlap,'nodelay');
+        C(cnt,:) = MI6(Xi, Yi, nbins);
+        cnt = cnt + 1;
+    end
+else
+    for i = 2:size(Y,2), if verbose, waitbar(cnt/(2*size(X,2))), end
+        [Yi dummy] = buffer(Y(:,i),window,noverlap,'nodelay');
+        C(cnt,:) = MI5(Xi, Yi, nbins);
+        cnt = cnt + 1;
+    end
+end
+
+if verbose, delete(h), end
+
+warning on
+
+% create time scale for the windows
+t = (1:nx/size(Xi,2):nx)';
+l = (-maxlag:maxlag)';
+
+% display and output result
+if nargout == 0
+    newplot
+    imagesc(t, l, C)
+    xlabel('Time'), ylabel('Lag'), axis xy
+    title('Windowed mutual information', 'fontweight', 'bold')
+    colorbar
+elseif nargout == 1,
+    c_out = C;
+elseif nargout == 2,
+    c_out = C;
+    l_out = l;
+elseif nargout == 3,
+    c_out = C;
+    t_out = t;
+    l_out = l;
+end
+
+
+% mutual information for Matlab version >= 6
+function Z = MI6(x, y, nbins)
+    
+    % normalise the data and replace the values with integers
+    % in the range [1 nbins]
+    x = x - repmat(min(x), size(x,1), 1); 
+    y = y - repmat(min(y), size(y,1), 1);
+    x = x ./ repmat(max(x) + eps, size(x,1), 1); 
+    y = y ./ repmat(max(y) + eps, size(y,1), 1);
+    
+    x = floor(x * nbins) + 1;
+    y = floor(y * nbins) + 1;
+    
+    % compute probabilities
+    Z = zeros(1,size(x,2));
+    for i = 1:size(x,2)
+    
+        Pxy = accumarray([x(:,i) y(:,i)] + 1, 1);
+        Px = sum(Pxy,1);
+        Py = sum(Pxy,2);
+
+        Pxy = Pxy / sum(Pxy(:));
+        Px = Px / sum(Px(:));
+        Py = Py / sum(Py(:));
+
+        % entropies
+        Ix = -sum((Px(Px ~= 0)) .* log(Px(Px ~= 0)));
+        Iy = -sum((Py(Py ~= 0)) .* log(Py(Py ~= 0)));
+        Ixy = -sum(Pxy(Pxy ~= 0) .* log(Pxy(Pxy ~= 0)));                                                                    
+        
+        % mutual information
+        Z(i) = Ix + Iy - Ixy;
+    end    
+    
+    
+% mutual information for Matlab version < 6
+function Z = MI5(x, y, nbins)   
+    
+    % normalise the data and replace the values with integers
+    % in the range [1 nbins]
+    x = x - repmat(min(x), size(x,1), 1); 
+    y = y - repmat(min(y), size(y,1), 1);
+    x = x ./ repmat(max(x) + eps, size(x,1), 1); 
+    y = y ./ repmat(max(y) + eps, size(y,1), 1);
+    
+    x = floor(x * nbins) + 1;
+    y = floor(y * nbins) + 1;
+    
+    % compute probabilities
+    Z = zeros(1,size(x,2));
+    for i = 1:size(x,2)
+    
+        Pxy = full(sparse(x(:,i) + 1, y(:,i) + 1, 1));
+        Px = sum(Pxy,1);
+        Py = sum(Pxy,2);
+
+        Pxy = Pxy / sum(Pxy(:));
+        Px = Px / sum(Px(:));
+        Py = Py / sum(Py(:));
+
+        % entropies
+        Ix = -sum((Px(Px ~= 0)) .* log(Px(Px ~= 0)));
+        Iy = -sum((Py(Py ~= 0)) .* log(Py(Py ~= 0)));
+        Ixy = -sum(Pxy(Pxy ~= 0) .* log(Pxy(Pxy ~= 0)));                                                                    
+        
+        % mutual information
+        Z(i) = Ix + Iy - Ixy;
+    end    
+    
+    
-- 
GitLab