ERROR: Primitive ‘_SimpleNumberSeries’ failed

Dear users,

I made the following code to present the difference in bit-depths and the problem of quantisation errors:

~bitDepthTester = { |numDiv|
	var	min = -1;
	var max = 1;
	var step = (max - min) / (numDiv);
	var a =	(min, (min + step)..max);
	a.plot(minval: -1, maxval: 1).plotMode_(\levels);

~bitDepthTester.(2 ** 1)
~bitDepthTester.(2 ** 2)
~bitDepthTester.(2 ** 4)
~bitDepthTester.(2 ** 8)
~bitDepthTester.(2 ** 16)
~bitDepthTester.(2 ** 24)
~bitDepthTester.(2 ** 32)

The calculation of evaluating ~bitDepthTester.(2 ** 24) need extremely long. It is much longer than expected, but sclang calculates it.

The problem here is the last line:
~bitDepthTester.(2 ** 32)
It returns the following error:

ERROR: Primitive ‘_SimpleNumberSeries’ failed.

Moreover, I have realised that 2 ** 26 is the maximum value that sclang can calculate.

As far as I know, the Float class of sclang deals with real numbers as 64-bit Floating point numbers. Moreover, sclang can calculate the following lines:

-1 + (2 ** 32).reciprocal
(2 ** 32).reciprocal
1 - (2 ** 32).reciprocal

However, why does my code ~bitDepthTester return the error when putting the argument value greater than 2 ** 26?

Showing only the first four examples is enough to understand how bit-depth is related to digitising analogue values. Still, I am curious about the error and the limitation of Float.

I really appreciate any help you can provide!

The problem is that your example creates an Array of size numDiv: (-1,2/numDiv … 1) !!

you’d have to perform 4 billion additions (or mutiplications).

If you build the Array using Array.series you can make an array of that size (although it would take 5 minutes on my system and I haven’t waited to see if it works - it doesn’t;t throw an error though)

I think the limitation is on the shorthand notation (1…(2**32))

1 Like

ps. if you want to work with large collections it helps to delay computation. interval does this for arithmetic series, but you can write many kinds of such things…

Interval(-1, 1, 1e-9).size == 2e9; // 2000000000 places between -1 and 1

Interval(-1, 1, 1e-9).at(1e9) == 0; // lookup value at 1000000001th place

1 Like

Thank you for your kind answers!
The following is the maximum size or the smallest step for each way:

a = Interval(-1, 1, (2 ** 29.999999999).reciprocal)
a.size // 2147483647

b = Interval(-1, 1, (2 ** 26 - 3).reciprocal).asArray
b.size // 134217723

c = {var size = 2 ** 26.99999999-3; Array.series(size, -1, 1, size.reciprocal) }.()
c.size // 134217724

The maximal size of the series created by Interval is the maximal number that the class Integer produces. It does make sense. However, the maximal number of Array is much smaller than it.

I do not understand why the maximal number of .asArray cannot produce an array of size 134217724 but 134217723, even though Array can create an array of size 134217724? Why is the maximal size made by .asArray one size smaller than the maximal size produced by Array?