Эффективная итерация в ячейке

#matlab #iteration #cell

#matlab #итерация #ячейка

Вопрос:

Как мне эффективно выполнять итерацию в ячейке?

У меня есть такая ячейка:

 H{i,j} = 

{1} {2} {3} {4} ...
{5} {6} {7} {8} ...
....
  

Фактический размер составляет ~ 300 * 300, всего ~ 1000 непустых элементов.

 for i = 1 : numel(H)
    if isempty(H{i}), continue, end
    for j = 1 : numel(H)
        if i==j || isempty(H{j}), continue, end
            COMPLEX_OPERATION(H{i}, H{J});
        end
    end
end
  

Это двухуровневая (простите за мой английский) итерация для одной ячейки.

Этот код оказался неэффективным.

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

Слишком много времени тратится впустую на итерации.

Я пытаюсь найти эффективный способ выполнить эту итерацию.

Одним из возможных решений является использование cellfun(@COMPLEX_OPERATION), но я не уверен, как выполнить этот двойной цикл с помощью cellfun.

Другое возможное решение — сначала удалить пустые ячейки. Однако я не уверен, решит ли это проблему в значительной степени.

Комментарии:

1. Вы перебираете свои данные, и только если оба элемента ( H{i} и H{j} ) не пусты, которые вы хотите сделать COMPLEX_OPERATION() , все остальные разы вы ничего не хотите делать. Но вы не хотите этого делать COMPLEX_OPERATION(H{i}, H{i}); . Как насчет выполнения COMPLEX_OPERATION(H{i}, H{j}); , а позже COMPLEX_OPERATION(H{j}, H{i}); вы хотите сделать и то, и другое?

2. Неясно, как вы храните свои данные. Возможно, это неэффективный способ для начала. Решение того, как вы его храните, решит большинство ваших текущих и будущих проблем. Если каждая ячейка имеет скаляр, то нет причин вообще использовать массивы ячеек.

3. Я согласен. Вы не должны использовать массивы ячеек для отдельных значений. Кроме того, вы не должны использовать i j переменные and, поскольку они используются для представления комплексных чисел.

Ответ №1:

Это также должно быть интересно. Используйте двойной вызов cellfun, чтобы получить все комбинации. Просто измените C1 C2 на свою complex_function

 %simulation
H=cell(300,300);
indx=randperm(numel(H));
[H{indx(1:1000)}]=deal(1);

%code you want
empty_H=cellfun(@isempty, H);
non_empty_H=H(~empty_H);
all_combinations=cellfun(@(C2) (cellfun(@(C1) C1 C2, non_empty_H, 'UniformOutput', false)), non_empty_H, 'UniformOutput', false);
  

Комментарии:

1. Просто обратите внимание, что это создаст на 1000 комбинаций больше (i == j), чем вам требуется (в отличие от циклов for). Тем не менее, это может улучшиться благодаря использованию cellfun. При необходимости вы можете легко удалить это во внутреннем cellfun с потерей интерпретации комбинаций

Ответ №2:

Почему вы не можете просто сделать

 ind = ~cellfun(@isempty, H).* ~eye(size(H))

ind =

   0   1
   0   0

[r,c] = find(ind==1);
cellfun(@(H,r,c) (whatever_your_complex_function_does), H{[find(ind==1)].'}, cell2mat(r,[1 1]),cell2mat(c,[1 1]);
  

Более подробное объяснение…

 H ={[],[1 2]; [] [3 4]}



ind = cellfun(@isempty, H)

ind =

   1   0
   1   0
  

Это ваши пустые индексы. Мы инвертируем их в конце.

Затем найдите те, где i=j . Затем мы исключим их в конце.

Создайте идентификационную матрицу, представляющую i=j .

 I = eye(size(ind))

I =   

   1   0
   0   1
  

Затем умножьте их на ind. Мы используем ~I , чтобы получить те, где i~=j и (~ind) чтобы получить непустые элементы.

 (~ind).*~I

ans =

0   1
0   0
  

Теперь у вас есть индексы, где H не пусто и i~=j .

Получите индексы для них.

 [r,c] = find(ind==1);
  

Затем вы создаете анонимную функцию, которая принимает значения H , соответствующие этим индексам, и применяет ее по элементам к H . H , r и c будет использоваться в качестве входных данных для анонимной функции, где вы можете использовать ее как H{r} или H{c}

 cellfun(@(H,r,c) (whatever_your_complex_function_does), H{[find(ind==1)].'}, cell2mat(r,[1 1]),cell2mat(c,[1 1]);
  

Комментарии:

1. Я думаю, он хочет COMPLEX_OPERATION сопоставить каждый элемент с каждым другим элементом (кроме того же). Таким образом, имея 1000 непустые элементы, у него было бы 1000000 приведений COMPLEX_OPERATION . Может ли он решить это с cellfun(@COMPLEX_OPERATION, H{indH}, H{indH}) помощью? Будет COMPLEX_OPERATION ли это применяться к n-му элементу с n-м элементом или к n-му элементу с каждым другим элементом?

2. Обновлено, чтобы отразить это. Спасибо.

3. Не совсем так, как говорит @TheMinion. COMPLEX_OPERATION не выполняется 1 000 000 раз, если я был прав.

4. Боюсь, мой вопрос немного вводит в заблуждение. На самом деле я с нетерпением жду выполнения двойного цикла вместо итерации между одной ячейкой, как предлагает @TheMinion. (Его право на эту часть.)

5. @SolessChong Я не уверен, что вы подразумеваете под двойным циклом, но я обновил свой ответ до того, что, по моему мнению, будет отражать ваш псевдокод. Существует только один вызов cellfun , который применяет вашу COMPLEX_FUNCTION поэлементно с предоставленными вашими индексами.