Main Content

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*1{0}^{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)]);
```

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

`ans = $$\left(\begin{array}{cccc}13& 43& 233& 2303316007278478583\end{array}\right)$$`

`ans = $$\left(\begin{array}{ccccccc}2& 17& 173& 991& 1223& 244939& 171805943\end{array}\right)$$`

`ans = $$\left(\begin{array}{cccccc}3& 11& 47& 139& 2531& 549797184491917\end{array}\right)$$`

`ans = $$\left(\begin{array}{ccccc}2& 2& 330131& 2953837& 76910994983\end{array}\right)$$`

`ans = $$\left(\begin{array}{cccc}5& 6271& 2650266823& 3610146697\end{array}\right)$$`

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}

`ans = $$2303316007278478583$$`

`ans = $$171805943$$`

`ans = $$549797184491917$$`

`ans = $$76910994983$$`

`ans = $$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');
```

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)

`ans = $$\left(\begin{array}{cc}300000000000000000000037& 300000000000000000000049\end{array}\right)$$`

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