Главные факторизации

В этом примере показано, как использовать некоторые элементарные функции на sym объекты с помощью Symbolic Math Toolbox™.

Встроенные целочисленные типы MATLAB подходят для целых чисел, меньших, чем 2^64. Однако мы хотим выполнить статистические расследования на главных факторизациях больших целых чисел. Для этого мы используем символьные целые числа, потому что их размер неограничен. Исследуйте целые числа между N0+1 и N0+100, где N0=3*1023. Встроенные типы данных не могут сохранить такие значения точно. Таким образом перенесите самый внутренний номер с sym использовать символьное представление в вычислениях. Это старается не округляться или ошибки переполнения:

N0 = 3*sym(10)^23;
disp(['Roundng error for doubles: ' char(3*10^23 - N0)]);
Roundng error for doubles: -25165824
disp(['Overflow error for integers: ' char(3*uint64(10)^23 - N0)]);
Overflow error for integers: -299981553255926290448385

В арифметических операциях символьные числа могут быть объединены с, удваивается, и преобразование происходит перед операцией. Таким образом следующее определение не может вызвать погрешности округления:

A = N0 + (1:100);

Вычислите главные факторизации элементов A использование factor. Количество простых множителей отличается. Массивы не могут содержать векторы различных длин, но массивы ячеек могут. Чтобы избежать перераспределений памяти, инициализируйте массив ячеек сначала, затем вычислите факторизации в цикле:

Bcell = cell(1, 100);
for i=1:100
   Bcell{i} = factor(A(i)); 
end

Более эффективный подход должен использовать arrayfun. Установка UniformOutput к false возвращает результат как массив ячеек.

Bcell = arrayfun(@factor, A, 'UniformOutput', false);

Например, первые главные факторизации:

Bcell{1:5}
ans = (13432332303316007278478583)[sym (13), sym (43), sym (233), sym ('2303316007278478583')]
ans = (2171739911223244939171805943)[sym (2), sym (17), sym (173), sym (991), sym (1223), sym (244939), sym (171805943)]
ans = (311471392531549797184491917)[sym (3), sym (11), sym (47), sym (139), sym (2531), sym ('549797184491917')]
ans = (22330131295383776910994983)[sym (2), sym (2), sym (330131), sym (2953837), sym ('76910994983')]
ans = (5627126502668233610146697)[sym (5), sym (6271), sym (2650266823), sym (3610146697)]

Получите самый большой простой множитель с помощью max. Обратите внимание на то, что, если выход состоит из объектов sym, опция UniformOutput всегда должен устанавливаться в false даже если выход универсален.

Mcell = cellfun(@max, Bcell, 'UniformOutput', false);

Например, первые максимальные простые множители:

Mcell{1:5}
ans = 2303316007278478583sym ('2303316007278478583')
ans = 171805943sym (171805943)
ans = 549797184491917sym ('549797184491917')
ans = 76910994983sym ('76910994983')
ans = 3610146697sym (3610146697)

Преобразуйте массив ячеек в символьный вектор и исследуйте отношение длин самого большого простого множителя и номера в целом. Можно применить арифметические операции поэлементно к символьным векторам, таким же образом что касается удваивается. Обратите внимание на то, что большинство статистических функций требует, чтобы их аргументы были числами с двойной точностью.

M = [Mcell{:}];
histogram(double(log(M)./log(A)), 20);
title('Ratio of lengths of the largest prime factor and the number');

Таким же образом теперь исследуйте распределение количества простых множителей. Здесь, результат содержит универсальные числовые данные. Поэтому вы не должны устанавливать UniformOutput к false.

omega = cellfun(@numel, Bcell);
histogram(omega);
title('Number of prime factors');

Интервал под следствием содержит два простых числа:

A(omega == 1)
ans = (300000000000000000000037300000000000000000000049)[sym ('300000000000000000000037'), sym ('300000000000000000000049')]

Мы проверяем, что максимальные простые множители об одинаково часто в классах вычетов 1 и 3 по модулю 4. Обратите внимание на то, что уравнения объектов sym являются самими символьными объектами и не логическими значениями; мы должны преобразовать их, прежде чем мы сможем суммировать их:

sum(logical(mod(M, 4) == 1))
ans = 49
sum(logical(mod(M, 4) == 3))
ans = 51