Search code examples
matlabcellvectorizationcell-arraymulti-layer

Placing values(numbers) in a multilayers cell matrix in MATLAB


Assume Q is a matrix which has 3 cells and in each cell it has 2 other cells, means:

Q={ { [] [] } ; { [] [] }; { [] [] } }

Moreover, if we have "a" and "b" which they have 3 member each, and we would like to place

"a(1,1)" into "Q{1}{1}",

"b(1,1)" into "Q{1}{2}",

"a(2,1)" into "Q{2}{1}",

"b(2,1)" into "Q{2}{2}",

"a(3,1)" into "Q{3}{1}",

"b(3,1)" into "Q{3}{2}",

For example, if

a = [2; 3; 4];
b = [1; 5; 8] 

Then Q should be like

Q={{2 1}; 
   {3 5}; 
   {4 8}}

Please note that we need a vectorized code and not a for-loop code as I already have the latter one, as shown next -

for i=1:size(Q,2)

     Q{i}{1}=a(i,:)
     Q{i}{2}=b(i,:)

end

Thanks.


Solution

  • Code

    Q = mat2cell(num2cell([a b]),ones(1,numel(a)),2)
    

    Example

    Code with input and output display

    a = [2; 3; 4]; %// Inputs
    b = [1; 5; 8];
    
    Q = mat2cell(num2cell([a b]),ones(1,numel(a)),2); %// Output
    
    celldisp(Q) %// Display results
    

    Output on code run

    Q{1}{1} =
         2
    Q{1}{2} =
         1
    Q{2}{1} =
         3
    Q{2}{2} =
         5
    Q{3}{1} =
         4
    Q{3}{2} =
         8
    

    Benchmarking

    Function for loop method

    function out = loop1(a,b)
    
    out = cell(size(a,1),1); 
    for i=1:size(out,1) 
        out{i}{1}=a(i,:); 
        out{i}{2}=b(i,:);
    end
    
    return;
    

    Function for vectorized method

    function out = vec1(a,b)
    
    out = mat2cell(num2cell([a b]),ones(1,numel(a)),2);
    
    return;
    

    Benchmarking Code

    N_arr = [50 100 200 500 1000 2000 5000 10000 50000]; %// array elements for N
    
    timeall = zeros(2,numel(N_arr));
    for k1 = 1:numel(N_arr)
        
        N = N_arr(k1);
        a = randi(9,N,1);
        b = randi(9,N,1);
        
        f = @() loop1(a,b);
        timeall(1,k1) = timeit(f);
        clear f
        
        f = @() vec1(a,b);
        timeall(2,k1) = timeit(f);
        clear f
    end
    
    %// Graphical display of benchmark results
    figure,
    hold on
    plot(N_arr,timeall(1,:),'-ro')
    plot(N_arr,timeall(2,:),'-kx')
    legend('Loop Method','Vectorized Method')
    xlabel('Datasize (N) ->'),ylabel('Time(sec) ->')
    

    Results

    enter image description here

    Conclusions

    Looks like vectorized method is the way to go, as it's showing almost double the performance (in terms of runtime) as compared to the loop approach across a wide range of datasizes.