Как добавить матрицу в цикл WHILE, вложенный в цикл PARFOR в MATLAB?

У меня есть код, который я использую для вычисления итераций, необходимых для сходимости последовательности Коллатца числа к единице:

nums = input('Enter a number: ');

iter = zeros(1, nums, 'uint16');

collatz = zeros(1, nums, 'uint64');
seqn = zeros(nums, 'uint64');

parfor ii = 1:nums    

    num = ii;
    collatz(ii) = num;
    % seqn(ii) = num;

    while num ~= 1

        % writes the maximum number reached
        if collatz(ii) < num
            collatz(ii) = num; 
        end

        if rem(num, 2) == 0
            num = num / 2;
        else
            num = 3 * num + 1;
        end

        % counts iterations needed to reduce each number to one
        iter(ii) = iter(ii) + 1;

        % records the sequence
        seqn(:, iter(ii)) = num;

    end
end

Короче говоря, он вычисляет последовательность Коллатца для каждого числа до num, записывает максимальное число в последовательности и записывает количество итераций, которые потребовались, чтобы уменьшить число до единицы.

С матрицей seqn я пытаюсь записать последовательность Коллатца для каждого числа, для которого я запускаю цикл.

Проблема здесь в том, что MATLAB не запустит этот цикл PARFOR из-за изменений, внесенных в seqn. Я не понимаю причину! Мне кажется, что то, что я делаю с iter, по сути то же самое, что я делаю с seqn, в том смысле, что оно выполняется внутри вложенного цикла WHILE и не зависит от предыдущих итераций.

Что я могу сделать, чтобы исправить это?


person Gallifreyan    schedule 02.04.2017    source источник


Ответы (1)


Я изменил ваш цикл while на цикл for и установил окончательное значение iter снаружи. кроме того, я устанавливаю только один элемент seqn вместо всего столбца, как вы. теперь Matlab позволяет вам запустить это, но я не уверен, что это то, что вы хотели, так что взгляните:

nums = input('Enter a number: ');

iter = zeros(1, nums, 'uint16');
maxitr = 1e6;
collatz = zeros(1, nums, 'uint64');
seqn = zeros(nums, 'uint64');

parfor ii = 1:nums

    num = ii;
    collatz(ii) = num;
    % seqn(ii) = num;

    for itr = 1:maxitr
        if num == 1
            break
        end
        % writes the maximum number reached
        if collatz(ii) < num
            collatz(ii) = num;
        end

        if rem(num, 2) == 0
            num = num / 2;
        else
            num = 3 * num + 1;
        end

        % records the sequence
        seqn(ii, itr) = num;
    end
    iter(ii) = itr - 1;
end
person user2999345    schedule 02.04.2017
comment
Отличная идея с циклом for вместо while! Сначала я отклонил его, потому что не знал, сколько итераций мне нужно будет сделать, но все данные (числа до 10 ^ 8) показывают, что 10 ^ 6 будет более чем достаточно. Я проверю это, когда у меня будет доступ к моей машине, и вернусь :) - person Gallifreyan; 02.04.2017
comment
... ааа, и мой ноутбук чуть не разбился :D Использование оперативной памяти достигло моего максимума (8 Гб) - с моей реализацией этого не происходит. Хотя причины не вижу. - person Gallifreyan; 02.04.2017
comment
О, это, наверное, предраспределение - uint32 и uint64 съедают слишком много оперативной памяти. - person Gallifreyan; 02.04.2017