Matlab: как создавать бесконечно глубокие циклы for? - PullRequest
0 голосов
/ 31 октября 2011

Итак, нам дано немного w, и мы хотим что-то вроде такого псевдокода:

u = zeros(size(w));
for o=1:length(size(w))
 for i=1:size(w)(1), 
  for j=1:size(w)(2), 
...
    for k=1:size(w)(length(size(w))),
        u(i, j, ..., k )=1/(exp((-w(i,j, ..., k )))+25);
    end
...
  end
 end
end

возможно ли такое с Matlab и как это сделать?

Ответы [ 4 ]

5 голосов
/ 31 октября 2011

Вы можете использовать рекурсию - написать функцию, которая перебирает нужные переменные и каждый раз вызывает себя.

5 голосов
/ 31 октября 2011

Это, конечно, возможно, но также не рекомендуется, так как это очень не идиоматично.

Для простоты я предполагаю, что в вашем вопросе есть опечатка и что она должна сказать exp(-w(i,j,...)).

Тогда u можно рассчитать как

u = exp(-w);
1 голос
/ 31 октября 2011

@ Ответ Джонаса - лучший вариант, однако для кода общего назначения (тот, который @ Matrixized ответ @ Джонаса не применяется), вы можете использовать подход генерации кода, например:

fcode = fopen('manyForLoopsScript.m','w');
w = rand(2,3,4);
numLoops = length(size(w));
u = zeros(size(w));

% open the 'for' loops
for m = 1 : numLoops
    fprintf(fcode, 'for a%d = 1:size(w,%d)\n',m,m);
end

% the actuall 'stuff'
indStr = [];
for m = 1 : numLoops
    indStr = [indStr,sprintf('a%d,',m)];
end
indStr = indStr(1:end-1);
fprintf(fcode, ['u(' indStr ') = exp(-w(' indStr '));\n']);

% close the 'for' loops
for m = 1 : numLoops
    fprintf(fcode, 'end\n');
end
fclose(fcode);

manyForLoopsScript
0 голосов
/ 31 октября 2011

Один из вариантов - переписать функцию, которую вы хотите применить, для векторизации , чтобы она вычислялась поэлементно (так же, как встроенная функция EXP работает для скаляра/ вектор / матричный ввод):

u = 1./(exp(-w)+25);

В противном случае, если вы предпочитаете цикл for, все, что вам нужно сделать, это пересечь многомерную матрицу ввода, используя линейные индексы (в мажорном столбце), примените функцию к каждому элементу, затем RESHAPE результат вернется в ожидаемую форму:

u = zeros(numel(w),1);
for i=1:numel(w)
    u(i) = 1 ./ ( exp(-w(i)) + 25 );
end
u = reshape(u, size(w));

Это в основном то, что функции ARRAYFUN делают для вас:

u = arrayfun(@(x) 1./(exp(-x)+25), w);

В случае, если вам также необходим доступ к фактическим индексам при цикле по элементам матрицы, вы всегда можете получить их с помощью IND2SUB (который преобразует линейные индексы в индексы) или даже сгенерироватьвсе они с функциями, такими как MESHGRID и NDGRID ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...