#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 поэлементно с предоставленными вашими индексами.