Размещение значений (чисел) в многослойной матрице ячеек в MATLAB

Предположим, что Q - матрица, которая имеет 3 ячейки, и в каждой ячейке есть 2 другие ячейки, что означает:

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

Более того, если у нас есть "a" и "b", в каждом из которых по 3 члена, и мы хотели бы разместить

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

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

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

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

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

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

Например, если

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

Тогда Q должен быть как

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

Обратите внимание, что нам нужен векторизованный код, а не код цикла for, так как последний у меня уже есть, как показано ниже:

for i=1:size(Q,2)

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

end

Спасибо.


person Iman    schedule 16.07.2014    source источник
comment
А в чем проблема с вашей петлей?   -  person Dan    schedule 16.07.2014
comment
Я очистил ваш Q (сохранив его структуру идентичной тому, как он был у вас), и это противоречит вашему циклу, в котором есть ячейки в ячейках. Есть ли причина иметь внутренние матрицы в виде ячеек? то есть могут ли эти скаляры когда-либо не быть скалярами? А также почему бы просто не Q = [a,b] забыть о ячейках?   -  person Dan    schedule 16.07.2014
comment
Как насчет этого - Q = mat2cell([a b].',2,ones(1,numel(a))).'?   -  person Divakar    schedule 16.07.2014
comment
@Dan Есть причина поместить каждого члена в матрицу подъячейки в каждую суперячейку, поскольку я только что упростил матрицы Q, a, b. На самом деле Q и другие матрицы в моем коде содержат миллиарды чисел, и каждая подъячейка представляет собой другую характеристику. Более того, я хотел бы написать его в строке, а не в цикле, так как это может быть очень дорого и занимать много времени для таких огромных данных. Кстати, спасибо за внимание.   -  person Iman    schedule 16.07.2014
comment
@Divakar Большое спасибо. Это выглядит очень хорошо. Мне было интересно, не могли бы вы сообщить мне, как я могу разделить каждый элемент a и b на отдельные ячейки. Например: Q={{2}{1};{3}{5};{4}{8}}   -  person Iman    schedule 16.07.2014
comment
@Iman Может быть, это - mat2cell([a b].',[1 1],ones(1,numel(a))).'   -  person Divakar    schedule 16.07.2014
comment
@Iman Вы пытались предварительно выделить Q?   -  person Dan    schedule 16.07.2014
comment
@Divakar Ты потрясающий человек! Это тот! Если бы вы могли написать свое решение как ответ, я могу отметить его как окончательный ответ.   -  person Iman    schedule 16.07.2014
comment
@ Дэн Да, я сделал. Но все равно эта строка должна быть быстрее, чем цикл. Не уверен на 100%, я применю его к своим данным и дам вам знать. Еще раз спасибо.   -  person Iman    schedule 16.07.2014
comment
@Dan Я применил его для 100000 чисел. Цикл был быстрее строки: a=(1:100000)'; b=(1:100000)'; tic Q=cell(size(a,1),1); for i=1:size(Q,1) Q{i}{1}=a(i,:); Q{i}{2}=b(i,:); end toc Elapsed time is 0.372703 seconds. tic Q=mat2cell(mat2cell([a b].',[1 1],ones(1,numel(a))).',ones(1,size(a,1)).'); toc Elapsed time is 0.717828 seconds.   -  person Iman    schedule 16.07.2014
comment
@Iman Ознакомьтесь с изменениями в моем решении, включая бенчмаркинг.   -  person Divakar    schedule 17.07.2014
comment
@Divakar Вау... Выглядит потрясающе. Спасибо, приятель   -  person Iman    schedule 17.07.2014


Ответы (1)


Код

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

Пример

Код с отображением ввода и вывода

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

Q = mat2cell(num2cell([a b]),ones(1,numel(a)),2); %// Output

celldisp(Q) %// Display results

Вывод при запуске кода

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

Сравнительный анализ

Функция для метода цикла

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 out = vec1(a,b)

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

return;

Код сравнительного анализа

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) ->')

Результаты

введите здесь описание изображения

Выводы

Похоже, векторизованный метод — это то, что нужно, поскольку он показывает почти удвоенную производительность (с точки зрения времени выполнения) по сравнению с циклическим подходом в широком диапазоне размеров данных.

person Divakar    schedule 16.07.2014
comment
Это выглядит великолепно. Мне просто интересно, как мы можем поместить каждый массив в ячейку? Я имею в виду, что вместо Q = {{2}{1};{3}{5};{4}{8}} получается Q = {{{2}{1}};{{3}{5}};{{4}{8}}} - person Iman; 16.07.2014
comment
@ Иман, я не уверен, как бы ты получил или хотя бы изобразил - Q = {{{2}{1}};{{3}{5}};{{4}{8}}}? Хотя бы объясните, что это такое? - person Divakar; 16.07.2014
comment
Возможно, дополнительные пояснения будут полезны. Мне нужно Q в форме Q={ {{}{}}; {{}{}}; {{}{}} }. Вот почему она называется многослойной ячейкой-матрицей. Он должен иметь 2 разные глубины. - person Iman; 16.07.2014
comment
@Iman Посмотрите, работает ли это - mat2cell(mat2cell([a b],ones(1,numel(a)),[1 1]),[1 1 1],2)? - person Divakar; 16.07.2014
comment
Точно! Это то, что я только что пришел написать. Q=mat2cell(mat2cell([a b].',[1 1],ones(1,numel(a))).',ones(1,size(Q,1)).') Спасибо миллион ;) - person Iman; 16.07.2014
comment
Да, это здорово. Я ценю это. Я только что обновил ваш ответ, если он вам подходит. - person Iman; 16.07.2014