Page 1 of 1
about []CT comparison tolerance
Posted: Mon Feb 07, 2011 1:21 pm
by giangiquario
Dyalog 12.1 Classic
I cannot understand the following result:
Can we always trust in []CT ?
Re: about []CT comparison tolerance
Posted: Tue Feb 08, 2011 9:27 am
by Geoff|Dyalog
Power to an integer right argument remembers its arguments and result. If on the next call the value of the right argument differs from the previous call by 1, 0, ¯1 the result is computed by multiplication/division from the previous result.
What is seen here is the difference between calculating the result by 90 multiplications compared with calculating the result by 22 divisions.
So the question is not really about comparison tolerance but about how much an APL can try to optimise its performance. The default value of ⎕CT is really there to mask such differences.
Re: about []CT comparison tolerance
Posted: Tue Feb 08, 2011 9:29 am
by Geoff|Dyalog
Sorry, that should have said "22 multiplications"
Re: about []CT comparison tolerance
Posted: Tue Feb 08, 2011 9:48 am
by Geoff|Dyalog
Incidentally, with version 13 I can do:
Dyalog APL/S-64 Version 13.0.7951
Unicode Edition
DEBUG Build
Pre-release Development Build
Tue Feb 8 09:36:28 2011
clear ws
⎕fr←1287
⎕pp←34
⎕dct←0
(⊃10*-⍳22)≡⊃10*-⍳90
1
⊃10*-⍳90
0.1
This is actually a demonstration of one of the advantages of decimal floating point over binary floating point. If the left argument to power had been a power of 2 rather than a power of 10 then binary would perform more in accordance with pure mathematics. However, a power of 10 is more common in code than a power of 2 and floating point hardware/software is only an approximation to pure mathematics.
Really about []CT comparison tolerance?
Posted: Tue Feb 08, 2011 1:02 pm
by uwejanza
Just to make sure that we are really talking about ⎕CT here:
What is the value of ⎕ML in your examples, guys?
You know that:
⎕ml←0
(⊃10*-⍳22)
0.1
⎕ml←1
(⊃10*-⍳22)
0.1
⎕ml←2
(⊃10*-⍳22)
0.1 0.01 0.001 0.0001 0.00001 0.000001 1E¯7 1E¯8 1E¯9 1E¯10 1E¯11 1E¯12 1E¯13 1E¯14 1E¯15 1E¯16 1E¯17
1E¯18 1E¯19 1E¯20 1E¯21 1E¯22
⎕ml←3
(⊃10*-⍳22)
0.1 0.01 0.001 0.0001 0.00001 0.000001 1E¯7 1E¯8 1E¯9 1E¯10 1E¯11 1E¯12 1E¯13 1E¯14 1E¯15 1E¯16 1E¯17
1E¯18 1E¯19 1E¯20 1E¯21 1E¯22
In cases 0 and 1 we are compariing he first values of two different series of numbers.
(⊃10*-⍳22)≡⊃10*-⍳90 must match.
In cases 2 and 3 we are comparing two different series as a whole.
(⊃10*-⍳22)≡⊃10*-⍳90 must not match, no matter what ⎕CT, because of the different numbers of elements.
Re: about []CT comparison tolerance
Posted: Wed Feb 09, 2011 5:33 pm
by giangiquario
The []ML is 0
Re: about []CT comparison tolerance
Posted: Fri Feb 25, 2011 2:09 pm
by uwejanza
First, let's look at some experimental results in Dyalog 12.1:
Code: Select all
⎕pp←17
⎕ml←0
⎕ct←0
⊃10*-⍳10
0.1
⊃10*-⍳11
0.09999999999999998
⊃10*-⍳51
0.10000000000000006
⊃10*-⍳1151
0.09999999999999992
If I got Goeff's post right, the interpreter should in any case first calculate the value of "10 to the power of the first element of the vector" of negative integers, which in any of the cases would be 10 to the power of -1. If afterwards the interpreter chooses to use this value as a base to multiply with or divide by some other value, this multiplication or division operation should not harm the base value calculated in the first place. But as we can see in the example above, the value is harmed.
There seem to be several algorithms involved in calculating the series of powers, depending of the length or value of the progression vector used as the right argument of the * function.
Geoff pointed out that decimal floating point numbers would cure such cases. I tend to agree for cases where the left argument of the * function is a product of 2s and 5s. I tend to doubt for all other integers.
Code: Select all
⊃9*-⍳7
0.1111111111111111
⊃9*-⍳11
0.11111111111111109
⊃9*-⍳51
0.11111111111111105
⊃9*-⍳1151
0.11111111111111097
Even with decimal floating point numbers implemented we may still need a little bit of tolerance in comparisons, with ⎕CT set to a value different to zero.
Uwe
Re: about []CT comparison tolerance
Posted: Mon Feb 28, 2011 9:43 am
by Geoff|Dyalog
I had to track this through a debugger to understand this. Dyalog APL's arithmetic functions change algorithm at 8 elements in the array. The first algorithm is to do the obvious. The second uses a vector approach (higher setup cost, lower per element cost). The first algorithm walks the array forward the second algorithm walks the array backwards. No good reason for the difference just the way the coder thought.
Now the scalar function (called by both methods) remembers its arguments and result. If, on the next call the left argument is the same and the right argument differs by +1, then the new result is derived from the previous result.
So in the
⊃10*-⍳11
case, the value is derived from successive multiplications following the initial derivation of
10*¯11
similarly for
⊃10*-⍳51
the value is derived from successive multiplications following the initial derivation of
10*¯51
Note the +1 difference is for true for v12.1. Current code for v13.0 also does ¯1 and 0 this way.