Hi all,
I am back to checking Squeak after quite a while and got latest trunk. I looked after one of my contributions Integer>>isPrime and I found my implementation of Algorithm P from Knuth's AOCP vol 2
substituted by an iteration of dividing self by all even numbers starting from 3 and (correctly) stopping at self sqrtFloor. This is IMHO a questionable/useless "improvement", not even looking to try to implement the Sieve of Eratostene...!
Again IMHO isPrime should be reverted back to what has been renamed isProbablyPrime Not being anymore used to contribute I just signal it here...
Hope it helps Bye
-- Enrico Spinielli "Do Androids dream of electric sheep?"— Philip K. Dick "Hear and forget; see and remember;do and understand."—Mitchel Resnick |
On Fri, Dec 18, 2009 at 05:25:45PM +0100, Enrico Spinielli wrote:
> Hi all, > I am back to checking Squeak after quite a while and got latest trunk. > I looked after one of my contributions Integer>>isPrime > and I found my implementation of Algorithm P from Knuth's AOCP vol 2 > substituted by an iteration of dividing self by all even numbers starting > from 3 > and (correctly) stopping at self sqrtFloor. > This is IMHO a questionable/useless "improvement", not even looking to try > to implement the Sieve of Eratostene...! > > Again IMHO isPrime should be reverted back to what has been renamed > isProbablyPrime > > Not being anymore used to contribute I just signal it here... > > Hope it helps > Bye > -- > Enrico Spinielli Enrico, Is this your original implementation? isPrime "See isProbablyPrimeWithK:andQ: for the algoritm description." | k q | self <= 1 ifTrue: [^self error: 'operation undefined']. self even ifTrue: [^self = 2]. k := 1. q := self - 1 bitShift: -1. [q odd] whileFalse: [q := q bitShift: -1. k := k + 1]. 25 timesRepeat: [(self isProbablyPrimeWithK: k andQ: q) ifFalse: [^false]]. ^true It was recently changed as follows: > Name: Kernel-ul.305 > Author: ul > Time: 25 November 2009, 2:55:43.339 am > UUID: a95be01c-d87c-154b-bdc6-c582dafad80b > Ancestors: Kernel-nice.304 > > - added Integer >> #sqrtFloor, which returns the floor of the square root of the receiver. > - renamed Integer >> #isPrime to #isProbablyPrime. > - added Integer >> #isPrime which is implemented as a deterministic primality test > - both #isPrime and #isProbablyPrime return false for receivers <= 1 instead of raising an error Is this a reasonable change? Dave |
In reply to this post by espin
On Fri, 18 Dec 2009, Enrico Spinielli wrote:
> Hi all, > I am back to checking Squeak after quite a while and got latest trunk. > I looked after one of my contributions Integer>>isPrime > and I found my implementation of Algorithm P from Knuth's AOCP vol 2 > substituted by an iteration of dividing self by all even numbers starting > from 3 > and (correctly) stopping at self sqrtFloor. > This is IMHO a questionable/useless "improvement", not even looking to try > to implement the Sieve of Eratostene...! What's the problem with the current #isPrime implementation? How could a sieve based primality test be faster? > > Again IMHO isPrime should be reverted back to what has been renamed > isProbablyPrime > Why? Levente > Not being anymore used to contribute I just signal it here... > > Hope it helps > Bye > -- > Enrico Spinielli > "Do Androids dream of electric sheep?"? Philip K. Dick > "Hear and forget; see and remember;do and understand."?Mitchel Resnick > |
In reply to this post by David T. Lewis
The original implementation is was has been renamed by ul to isProbablyPrime
Note that the probability is according to Knuth's words So 'probabilistic' in this case is very much deterministic! For accessible rationale about the algoritm (and a non probabilistic better one as well)
you can also see "<a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_1.2.6">1.2.6 Example: Testing for Primality" in SICP. A possible improvement could have been to keep a list of the first N
prime numbers (i.e. N=1000 or whatever integrer where gain in performance and or memory) and resort to the probabilistic test if self is greater than the bigger in the list.
The value of original algorithm is all research and reasoning that went into it from Knuth et al. (note the order of growth is log(n), where n is the integer under scrutiny) The problem with the new implementation is that it goes thru testing numbers which are
clearly not prime, 5, 15, 25, 35...just to mention multiples of 5. It can possibly be faster for small integers hence the above possible improvement suggestion...but for the rest it should be thrown away IMHO.
Primality testing is very important for modern electronic communications, i.e. encryption and as such it has to be reliable and performant for big integers. Hope this clarifies
Bye Enrico PS: the comment in the code was explicit enough to allow to research for the rationale about the algorithm...we should not fix what works (well) there are so many other fixes waiting... On Sat, Dec 19, 2009 at 12:56 AM, David T. Lewis <[hidden email]> wrote:
-- Enrico Spinielli "Do Androids dream of electric sheep?"— Philip K. Dick "Hear and forget; see and remember;do and understand."—Mitchel Resnick |
On Sat, Dec 19, 2009 at 02:58:16PM +0100, Enrico Spinielli wrote:
> The original implementation is was has been renamed by ul to isProbablyPrime > Note that the probability is according to Knuth's words > > ...less than (1/4)^25 that such a 25-time-in-a-row procedure gives the wrong > information about its input. This is less than one chance in a quadrillion; > [...] > It's much more likely that our computer has dropped a bit in its > calculations, > due to hardware malfunctions or cosmic radiation, than that Algorithm P has > repeatedly guessed wrong! > > So 'probabilistic' in this case is very much deterministic! Thanks for the background on this. It turns out that the new #isPrime works quite well for relatively small numbers: Time millisecondsToRun: [ r1 := (1 to: 200000) select: [:e | e isPrime]] ==> 1218 Time millisecondsToRun: [ r2 := (1 to: 200000) select: [:e | e isProbablyPrime]] ==> 188224 r1 = r2 ==> true However, things look considerably different if you are searching for larger primes: Time millisecondsToRun: [ r1 := (100000001000 to: 100000002000) select: [:e | e isPrime]] ==> 70652 Time millisecondsToRun: [ r2 := (100000001000 to: 100000002000) select: [:e | e isProbablyPrime]] ==> 1242 r1 = r2 ==> true r1 size ==> 41 So I think that the new #isProbablyPrime selector name may be misleading. Based on your explanation of the Knuth algorithm, the "probably" part is not the main issue (and it could be noted in the method comment anyway). However, the different performance characteristics would be very important for anyone using either of these methods. Suggestions anyone? Dave > For accessible rationale about the algoritm (and a non probabilistic better > one as well) > you can also see "1.2.6 Example: Testing for > Primality<<a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_1.2.6">http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_1.2.6>" > in SICP. > A possible improvement could have been to keep a list of the first N > prime numbers (i.e. N=1000 or whatever integrer where gain in performance > and or memory) and resort to the probabilistic test if self > is greater than the bigger in the list. > > The value of original algorithm is all research and reasoning that went into > it from > Knuth et al. (note the order of growth is log(n), where n is the integer > under scrutiny) > The problem with the new implementation is that it goes thru testing numbers > which are > clearly not prime, 5, 15, 25, 35...just to mention multiples of 5. > It can possibly be faster for small integers hence the above possible > improvement suggestion...but for the rest it should be thrown away IMHO. > > Primality testing is very important for modern electronic communications, > i.e. encryption > and as such it has to be reliable and performant for big integers. > > Hope this clarifies > Bye > Enrico > PS: the comment in the code was explicit enough to allow to research for > the rationale about the algorithm...we should not fix what works > (well) > there are so many other fixes waiting... > On Sat, Dec 19, 2009 at 12:56 AM, David T. Lewis <[hidden email]>wrote: > > > On Fri, Dec 18, 2009 at 05:25:45PM +0100, Enrico Spinielli wrote: > > > Hi all, > > > I am back to checking Squeak after quite a while and got latest trunk. > > > I looked after one of my contributions Integer>>isPrime > > > and I found my implementation of Algorithm P from Knuth's AOCP vol 2 > > > substituted by an iteration of dividing self by all even numbers starting > > > from 3 > > > and (correctly) stopping at self sqrtFloor. > > > This is IMHO a questionable/useless "improvement", not even looking to > > try > > > to implement the Sieve of Eratostene...! > > > > > > Again IMHO isPrime should be reverted back to what has been renamed > > > isProbablyPrime > > > > > > Not being anymore used to contribute I just signal it here... > > > > > > Hope it helps > > > Bye > > > -- > > > Enrico Spinielli > > > > Enrico, > > > > Is this your original implementation? > > > > > > isPrime > > "See isProbablyPrimeWithK:andQ: for the algoritm description." > > | k q | > > self <= 1 ifTrue: [^self error: 'operation undefined']. > > self even ifTrue: [^self = 2]. > > k := 1. > > > > q := self - 1 bitShift: -1. > > [q odd] whileFalse: > > [q := q bitShift: -1. > > k := k + 1]. > > > > 25 timesRepeat: [(self isProbablyPrimeWithK: k andQ: q) ifFalse: > > [^false]]. > > ^true > > > > It was recently changed as follows: > > > > > Name: Kernel-ul.305 > > > Author: ul > > > Time: 25 November 2009, 2:55:43.339 am > > > UUID: a95be01c-d87c-154b-bdc6-c582dafad80b > > > Ancestors: Kernel-nice.304 > > > > > > - added Integer >> #sqrtFloor, which returns the floor of the square root > > of the receiver. > > > - renamed Integer >> #isPrime to #isProbablyPrime. > > > - added Integer >> #isPrime which is implemented as a deterministic > > primality test > > > - both #isPrime and #isProbablyPrime return false for receivers <= 1 > > instead of raising an error > > > > Is this a reasonable change? > > > > Dave > > > > > > > > > -- > Enrico Spinielli > "Do Androids dream of electric sheep?"? Philip K. Dick > "Hear and forget; see and remember;do and understand."?Mitchel Resnick |
isLargeIntPrime for the Knuth version
isSmallIntPrime for the "determinitic" version isPrime self < 100000 "or the actual limit...maybe SmallInter maxVal 1073741823"
ifTrue: [^self isSmallIntPrime] ifFalse: [^self isLargeIntPrime] my 2 cents... :)
|
or simply
SmallInteger>>isPrime the current version LargePositiveInteger>>isPrime Knuth's version
Cédrick |
Again my point is:
If the answer is YES, then a fix (your proposal for example) is needed
if NOT leave what was there originally...double implementation is just making maintenance more difficult. Optimizing for the sake of it has never proved correct... My 2 cents...
Bye Enrico
On Sat, Dec 19, 2009 at 11:18 PM, Cédrick Béler <[hidden email]> wrote: or simply -- Enrico Spinielli "Do Androids dream of electric sheep?"— Philip K. Dick "Hear and forget; see and remember;do and understand."—Mitchel Resnick |
In reply to this post by espin
IMO, "probabilistic" should never be confused with "deterministic". I
also read that section of Knuth's book and, if anything, the feeling was that you could be pragmatic if you wanted to with really large numbers and use the probabilistic test. However, you never know for sure, so that's why he also discusses several deterministic tests. Note that if probabilistic tests were all that mattered, then why bother figuring out the AKS family of primality tests, right? The earlier versions of Knuth's books certainly could not assume that the complexity of checking an integer's primality was in P, because that was found with the AKS tests. So, if anything, the existence of deterministic tests in P should be taken into account when reading Knuth's books (particularly the editions before AKS was known). If anything, I'd rename isProbablyPrime to something like probabilisticPrimalityTestAlgorithmSuch. Andres. On 12/19/2009 5:58 AM, Enrico Spinielli wrote: > The original implementation is was has been renamed by ul to isProbablyPrime > Note that the probability is according to Knuth's words > > ...less than (1/4)^25 that such a 25-time-in-a-row procedure gives > the wrong > information about its input. This is less than one chance in a > quadrillion; [...] > It's much more likely that our computer has dropped a bit in its > calculations, > due to hardware malfunctions or cosmic radiation, than that > Algorithm P has > repeatedly guessed wrong! > > So 'probabilistic' in this case is very much deterministic! > For accessible rationale about the algoritm (and a non probabilistic > better one as well) > you can also see "1.2.6 Example: Testing for Primality > <<a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_1.2.6">http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_1.2.6>" > in SICP. > A possible improvement could have been to keep a list of the first N > prime numbers (i.e. N=1000 or whatever integrer where gain in performance > and or memory) and resort to the probabilistic test if self > is greater than the bigger in the list. > > The value of original algorithm is all research and reasoning that went > into it from > Knuth et al. (note the order of growth is log(n), where n is the integer > under scrutiny) > The problem with the new implementation is that it goes thru testing > numbers which are > clearly not prime, 5, 15, 25, 35...just to mention multiples of 5. > It can possibly be faster for small integers hence the above possible > improvement suggestion...but for the rest it should be thrown away IMHO. > > Primality testing is very important for modern electronic > communications, i.e. encryption > and as such it has to be reliable and performant for big integers. > > Hope this clarifies > Bye > Enrico > PS: the comment in the code was explicit enough to allow to research for > the rationale about the algorithm...we should not fix what works > (well) > there are so many other fixes waiting... > On Sat, Dec 19, 2009 at 12:56 AM, David T. Lewis <[hidden email] > <mailto:[hidden email]>> wrote: > > On Fri, Dec 18, 2009 at 05:25:45PM +0100, Enrico Spinielli wrote: > > Hi all, > > I am back to checking Squeak after quite a while and got latest > trunk. > > I looked after one of my contributions Integer>>isPrime > > and I found my implementation of Algorithm P from Knuth's AOCP vol 2 > > substituted by an iteration of dividing self by all even numbers > starting > > from 3 > > and (correctly) stopping at self sqrtFloor. > > This is IMHO a questionable/useless "improvement", not even > looking to try > > to implement the Sieve of Eratostene...! > > > > Again IMHO isPrime should be reverted back to what has been renamed > > isProbablyPrime > > > > Not being anymore used to contribute I just signal it here... > > > > Hope it helps > > Bye > > -- > > Enrico Spinielli > > Enrico, > > Is this your original implementation? > > > isPrime > "See isProbablyPrimeWithK:andQ: for the algoritm description." > | k q | > self <= 1 ifTrue: [^self error: 'operation undefined']. > self even ifTrue: [^self = 2]. > k := 1. > > q := self - 1 bitShift: -1. > [q odd] whileFalse: > [q := q bitShift: -1. > k := k + 1]. > > 25 timesRepeat: [(self isProbablyPrimeWithK: k andQ: q) > ifFalse: [^false]]. > ^true > > It was recently changed as follows: > > > Name: Kernel-ul.305 > > Author: ul > > Time: 25 November 2009, 2:55:43.339 am > > UUID: a95be01c-d87c-154b-bdc6-c582dafad80b > > Ancestors: Kernel-nice.304 > > > > - added Integer >> #sqrtFloor, which returns the floor of the > square root of the receiver. > > - renamed Integer >> #isPrime to #isProbablyPrime. > > - added Integer >> #isPrime which is implemented as a > deterministic primality test > > - both #isPrime and #isProbablyPrime return false for receivers > <= 1 instead of raising an error > > Is this a reasonable change? > > Dave > > > > > > -- > Enrico Spinielli > "Do Androids dream of electric sheep?"— Philip K. Dick > "Hear and forget; see and remember;do and understand."—Mitchel Resnick |
In reply to this post by espin
The problem I see is one of confusion. If you ask an integer isPrime,
then it would be reasonable to expect a deterministic answer, not a probabilistic one. On 12/20/2009 4:19 AM, Enrico Spinielli wrote: > Again my point is: > > was there a problem to solve? > Was it about performance? > > If the answer is YES, then a fix (your proposal for example) is needed > if NOT leave what was there originally...double implementation is just > making maintenance more difficult. > Optimizing for the sake of it has never proved correct... > > My 2 cents... > Bye > Enrico > > On Sat, Dec 19, 2009 at 11:18 PM, Cédrick Béler <[hidden email] > <mailto:[hidden email]>> wrote: > > or simply > > SmallInteger>>isPrime > the current version > > LargePositiveInteger>>isPrime > Knuth's version > > > -- > Cédrick > > > > > > > -- > Enrico Spinielli > "Do Androids dream of electric sheep?"— Philip K. Dick > "Hear and forget; see and remember;do and understand."—Mitchel Resnick |
In reply to this post by Andres Valloud-4
Hi,
I just reply with the words of SICP, footnote 47 in the link below: In testing primality of very large numbers chosen at random, the chance of stumbling upon a value that fools the Fermat test is less than the chance that cosmic radiation will cause the computer to make an error in carrying out a ``correct'' algorithm. Considering an algorithm to be inadequate for the first reason but not for the second illustrates the difference between mathematics and engineering. Bye Enrico On Thu, Dec 24, 2009 at 9:51 PM, Andres Valloud <[hidden email]> wrote: IMO, "probabilistic" should never be confused with "deterministic". I also read that section of Knuth's book and, if anything, the feeling was that you could be pragmatic if you wanted to with really large numbers and use the probabilistic test. However, you never know for sure, so that's why he also discusses several deterministic tests. -- Enrico Spinielli "Do Androids dream of electric sheep?"— Philip K. Dick "Hear and forget; see and remember;do and understand."—Mitchel Resnick |
Enrico Spinielli wrote:
> Hi, > I just reply with the words of SICP, footnote 47 in the link below: > In testing primality of very large numbers chosen at random, the > chance of stumbling upon a value that fools the Fermat test is less > than the chance that cosmic radiation will cause the computer to make > an error in carrying out a ``correct'' algorithm. Considering an > algorithm to be inadequate for the first reason but not for the second > illustrates the difference between mathematics and engineering. > > Bye > Enrico > Hi. That's assuming that you're testing very large numbers chosen at random. That's not always the case! And also assuming that the computer is not fail-proof. For example, a typical setup for critical applications is to have 3 computers do the same calculation, and vote on the correct result. A routine should not assume much about how it is going to be used. Instead, it should make clear its assumptions and limitations so callers will know. #isProbablyPrime or such, and a method comment with exactly the text you quote is the best. Cheers, Juan Vuletich |
>>>>> "Juan" == Juan Vuletich <[hidden email]> writes:
Juan> A routine should not assume much about how it is going to be Juan> used. Instead, it should make clear its assumptions and limitations so Juan> callers will know. #isProbablyPrime or such, and a method comment with Juan> exactly the text you quote is the best. Integer currently has both #isPrime (exact) and #isProbablyPrime (very likely correct for everything we care about). Just override #isPrime for LargePositiveInteger as ^self isProbablyPrime. That way, people who don't want to peer under the hood will get reasonable results, and those who do will know exactly what is happening, or can delete the definition in LargePositiveInteger if they don't mind slowing everyone down. :) -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <[hidden email]> <URL:http://www.stonehenge.com/merlyn/> Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion |
In reply to this post by Juan Vuletich-4
That is exactly the point. Testing for primality these days is for things like encryption
which works best for large integers. I think a lot of this thread is about a misunderstanding of 'probabilistic method'
in fact the probability is made so low that other factors, i.e. cosmic radiation, could factor in and mess things up, i.e. a bit of your computer memory...now I do not see any evidence that we try to avoid the effects of cosmic
radiation, then I do not see why we should dismiss the primality testing algorithm as 'non deterministic'... The suggestion for Randal is fine for me, as anything else you want to do,
even keep current isPrime Bye Enrico
On Tue, Dec 29, 2009 at 1:31 PM, Juan Vuletich <[hidden email]> wrote:
-- Enrico Spinielli "Do Androids dream of electric sheep?"— Philip K. Dick "Hear and forget; see and remember;do and understand."—Mitchel Resnick |
In reply to this post by Juan Vuletich-4
+1.
On 12/29/2009 4:31 AM, Juan Vuletich wrote: > Enrico Spinielli wrote: >> Hi, >> I just reply with the words of SICP, footnote 47 in the link below: >> In testing primality of very large numbers chosen at random, the >> chance of stumbling upon a value that fools the Fermat test is less >> than the chance that cosmic radiation will cause the computer to make >> an error in carrying out a ``correct'' algorithm. Considering an >> algorithm to be inadequate for the first reason but not for the second >> illustrates the difference between mathematics and engineering. >> >> Bye >> Enrico >> > > Hi. > > That's assuming that you're testing very large numbers chosen at random. > That's not always the case! And also assuming that the computer is not > fail-proof. For example, a typical setup for critical applications is to > have 3 computers do the same calculation, and vote on the correct result. > > A routine should not assume much about how it is going to be used. > Instead, it should make clear its assumptions and limitations so callers > will know. #isProbablyPrime or such, and a method comment with exactly > the text you quote is the best. > > Cheers, > Juan Vuletich > |
Free forum by Nabble | Edit this page |