Search code examples
matlabmatrixsignal-processingcell-array

Aligning multiple arrays in a cell array by prepending/postpending NaNs


I am trying to align arrays within a cell-array while prepending/postpending NaNs to match the size of arrays like this for example:

%Setting up data
A = [0.01 0.02 0.03 0.01 0.60 0.90 -1.02];
B = [0.03 0.01 0.60 0.90];
C = [0.03 0.01 0.60 0.90 -1.02 0.03 -1.02];

CellABC = {A, B, C}; 

The expected output is this:

CellABC = {[0.01   0.02   0.03   0.01   0.60   0.90   -1.02  NaN   NaN ],...
            NaN    NaN    0.03   0.01   0.60   0.90   NaN    NaN   NaN ],... 
            NaN    NaN    0.03   0.01   0.60   0.90   -1.02  0.03  -1.02]};

This is just an example. In my actual data, I have a 1x100 cell-array containing arrays of sizes ranging from 1x400 to 1x1400.

I have tried this:

[~, idx] = max(cellfun(@numel, CellABC)); %index of maximum no. of entries in CellABC
for i=1:length(CellABC)
    [d1, d2] = findsignal(CellABC{idx},CellABC{i},'Metric','absolute');
    tmp = NaN(size(CellABC{idx}));   %initializing with NaNs
    tmp(d1:d2) = CellABC{i};    %saving the array as per indices of found values
    CellABC{i} = tmp;           %Updating the cell array
end

This will align the CellABC{2} correctly but the number of postpended NaNs is not correct. Also that does not give postpended NaNs at the end of CellABC{1} and prepended NaNs at the start of CellABC{3}. I understand the reason that findsignal function is not useful in this case since we don't have an array with the complete data to be use as the first input argument of findsignal. How could I make this work?

I have also looked into alignsignals function but it is only for two signals. I am unable to figure out how this could be implemented for 100 signals as in my case.

How could this problem be solved?


Solution

  • Its relatively simple for the example data, but you may need more than one template in multiple loops if the real data is too fragmented.

    A = [0.01 0.02 0.03 0.01 0.60 0.90 -1.02];
    B = [0.03 0.01 0.60 0.90];
    C = [0.03 0.01 0.60 0.90 -1.02 0.03 -1.02];
    
    CellABC = {A, B, C}; 
    
    % find longest anyway
    [~,I]=max(cellfun(@(x) numel(x),CellABC));
    % find lags and align in two pass
    % 1st pass
    lags=zeros(numel(CellABC),1);
    for idx=1:numel(CellABC)
        if idx==I, continue; end
        [r,lag]=xcorr(CellABC{I},CellABC{idx});
        [~,lagId]=max(r);
        lags(idx)=lag(lagId);
    end
    % 2nd pass 
    out=nan(numel(CellABC),max(arrayfun(@(x) numel(CellABC{x})+lags(x),1:numel(CellABC))));
    for idx=1:numel(CellABC)
       out(idx,lags(idx)+1:lags(idx)+numel(CellABC{idx}))=CellABC{idx}; 
    end
    
    
    
    out =
    
    0.0100    0.0200    0.0300    0.0100    0.6000    0.9000   -1.0200       NaN       NaN
       NaN       NaN    0.0300    0.0100    0.6000    0.9000       NaN       NaN       NaN
       NaN       NaN    0.0300    0.0100    0.6000    0.9000   -1.0200    0.0300   -1.0200