%% Prime Factorizations
% This example shows how to use some elementary functions on sym objects using the Symbolic Math Toolbox™.
%
% The built-in integer types of MATLAB are suitable for integers smaller than 2^64. However, we want to carry out statistical investigations on prime factorizations of larger integers. To do this, we use symbolic integers because their size is unlimited. Investigate the integers between N_0+1 and N_0 + 100, where N_0 = 3*10^{23}. The built-in data types cannot store such values exactly. Thus, wrap the innermost number with sym to use symbolic representation in the calculations. This avoids rounding or overflow errors:

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

%
% In arithmetical operations, symbolic numbers can be combined with doubles, and the conversion takes place before the operation. Thus, the following definition cannot cause rounding errors:

A = N0 + (1:100);

%
% Compute the prime factorizations of the elements of A using factor. The number of prime factors differs. Arrays cannot contain vectors of different lengths, but cell arrays can. To avoid memory re-allocations, initialize the cell array first, then compute the factorizations in a loop:

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

%
% A more efficient approach is to use arrayfun. Setting UniformOutput to false returns the result as a cell array.

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

%
% For example, the first prime factorizations are:

Bcell{1:5}

%
% Obtain the largest prime factor using max. Note that if the output consists of sym objects, the option  UniformOutput always has to be set to false even if the output is uniform.

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

%
% For example, the first maximal prime factors are:

Mcell{1:5}

%
% Convert the cell array to a symbolic vector, and investigate the ratio of the lengths of the largest prime factor and the number as a whole. You can apply arithmetical operations elementwise to symbolic vectors, in the same way as for doubles. Note that most statistical functions require their arguments to be double-precision numbers.

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

%
% In the same way, now investigate the distribution of the number of prime factors. Here, the result contains uniform numeric data. Therefore, you do not need to set UniformOutput to false.

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

%
% The interval under investigation contains two prime numbers:

A(omega == 1)

%
% We check that the maximal prime factors are about equally often in the residue classes 1 and 3 modulo 4. Note that equations of sym objects are symbolic objects themselves and not logical values; we have to convert them before we can sum them:

sum(logical(mod(M, 4) == 1))
sum(logical(mod(M, 4) == 3))

%
% Copyright 2015-2016 The MathWorks, Inc.
%