Main Content

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 N0+1 and N0+100, where N0=3*1023. 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)]);
Roundng error for doubles: -25165824
disp(['Overflow error for integers: ' char(3*uint64(10)^23 - N0)]);
Overflow error for integers: -299981553255926290448385

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)); 

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:

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)]

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:

ans = 2303316007278478583sym('2303316007278478583')
ans = 171805943sym(171805943)
ans = 549797184491917sym('549797184491917')
ans = 76910994983sym('76910994983')
ans = 3610146697sym(3610146697)

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');

Figure contains an axes. The axes with title Ratio of lengths of the largest prime factor and the number contains an object of type histogram.

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);
title('Number of prime factors');

Figure contains an axes. The axes with title Number of prime factors contains an object of type histogram.

The interval under investigation contains two prime numbers:

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

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))
ans = 49
sum(logical(mod(M, 4) == 3))
ans = 51