Resurrecting a 2000 Year Old Thread

12 posts in this topic

czardas 1,116

Some time ago a question came up in General Help and Support about primes. I've always had a fascination with this apparently chaotic number sequence and thought this is a worthwhile challenge. Without reading up on the subject, I set about trying to figure out how I might approach the problem of testing for primality using AutoIt.

I started by writing a function which eliminated even numbers, and multiples of 3 and 5. Everything seemed fine at this point; but when I tried to scale up my idea, I took an interesting wrong turn. The approach I had adopted involved testing the primes in the range 7 to 31, and then incrementing them by steps of 30. I had calculated that this would produce a set of numbers guaranteed to include all higher primes. Testing for division using this smaller set of numbers would be faster than testing all the odd numbers ending 1, 3, 7 and 9.

At this stage the only thing that seemed obvious to me was - the more prime multiples I skip, the faster my function would run. Here's what I was thinking at the time: to scale this up I need to eliminate a few more prime multiples from a larger sequence and increment by much larger steps. All the numbers in the larger sequences will be made up exclusively of all the higher primes. BUT NOT WITH MY METHOD! This was a fatal oversight on my part.

For a while I was distracted away from coding and this bug went undetected. After a slightly embarrassing moment in the Chat forum I discovered that some prime factors were missing from my sequence ==> 3673. My error was very basic - I had made an assumption without any proof.

So there was a big flaw in my reasoning. My earlier assumption that the sequence in my function had to be comprised only of prime numbers was totally wrong. I imagine this may be the cause of amusement to some, but it also goes to show how easy it can be to overlook something fundamental like this. Always check your assumptions are correct and save yourself any future embarrassment!

Share this post

Link to post

Share on other sites

jchd 926

Welcome to the wonderland of arithmetic. Primes, their repartition, their fantastic properties have always fascinated countless people, mathematicians and laymen alltogether.

Simple as that may seem at first look, characterizing them in general is often far from trivial and many pitfalls are awaiting the unsuspecting amateur.

Every primality test, compositeness test, factoring program, younameit will start with a trial division step to remove small factors. As you have experienced, a loop step of 30 without further checking is not enough to guarantee scaling. Don't by shy: there's nothing wrong by being fooled by intuition. It just needs to be backed by a more in-depth analysis.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post

Link to post

Share on other sites

czardas 1,116

What an excellent and appropriate article jchd. This guy has obviously spent time studying the guitar and knows how demanding it can be. I very much appreciate your responce.

I posted my little story above in the hope that it may serve as an illustration to some younger readers who may be just starting out - I consider it to be an instructive mistake. By the time I sat down and wrote out the sequences, I already knew what I was looking for because I had eliminated all other possible causes for this error that I could think of. This was a valuable lesson - for me at least.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post

Link to post

Share on other sites

czardas 1,116

Less difficult than finding it in the first place and actually proving that the set of positive results it generates is exactly the set of primes.

Of course. Of the few basic (Euclidean) proofs I have read and managed to understand, I have always been struck by the beauty and rigor they contain. It is often an inspiration when the truth dawns on you.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post

Link to post

Share on other sites

czardas 1,116

It's good to have this info in one place, however there is some rather advanced stuff in some of the links posted here. Learning maths is a great asset to any would-be coder, but you don't have to be an expert in the subject to proceed. It is possible to understand how I made my mistake (described above) without necessarily understanding all the details. This is still of value to anyone learning to write code.

Knowing what pitfalls to avoid is just as relevant as learning how to write good code. There are some fantastic examples in this forum to follow, and we all learn things in different ways. Some people tend to visualize things more, and a group of people have photographic memories. I was led down the wrong path by false intuition. It was still a step towards my ultimate goal - albeit one which fell short of the target in the first instance.

Share this post

Link to post

Share on other sites

czardas 1,116

I have taken this a little further, but quickly hit limits with optimization as I expected. Well there are other methods as jchd has shown, but if you use any of these functions, make sure to read the descriptions carefully. I have added a couple of examples at the end of the code and a new function to return a random prime of a specified number of digits (between 1 to 15). Searching large ranges will be slow and greedy on RAM: use at your own risk. Don't forget to clear memory as shown in the examples.

;

; #FUNCTION# ====================================================================================================================; Name...........: _ClearDivisors; Description ...: Used to clear memory after calling _IsPrime() or _RandomPrime(); Syntax.........: _ClearDivisors(); Author ........: czardas; Comments ......; Call this function if you no longer need to use _IsPrime() or _RandomPrime() and want to clear memory.; ===============================================================================================================================Func_ClearDivisors()_IsPrime("",True)EndFunc;==> _ClearDivisors; #FUNCTION# ====================================================================================================================; Name...........: _IsPrime; Description ...: Tests a number for primality.; Syntax.........: _IsPrime($iInt [, _ClearDivisors = False]); Parameters ....: $iInt - The number to test; : $bClearDivisors - DO NOT USE THIS PARAMETER; Return values .: Success - Returns True, or False if not prime.; Failure - Returns False and sets @error to 1 if $iInt is not an integer or is out of range:; Author ........: czardas; Comments ......; This function is designed to be called multiple times but uses lots of memory.; ; It is advisable to use Sleep() after any batch processes to allow the CPU to cool off a little.; ; After using this function you should free memory by calling the function _ClearDivisors(); ===============================================================================================================================Func_IsPrime($iInt,$bClearDivisors=False)Static$aDivisors=__GetDivisors()If$bClearDivisorsThen$aDivisors=0ReturnElseIfNotIsArray($aDivisors)Then$aDivisors=__GetDivisors()EndIfIfNotIsInt($iInt)ThenReturnSetError(1,0,False); Only integers are allowed$iInt=Abs($iInt)If$iInt=2Or$iInt=3Or$iInt=5Or$iInt=7Or$iInt=11Or$iInt=13ThenReturnTrueIf$iInt<2OrNot(Mod($iInt,2)AndMod($iInt,3)AndMod($iInt,5)AndMod($iInt,7)AndMod($iInt,11)AndMod($iInt,13))ThenReturnFalseLocal$bPrime=True,$iRoot=Sqrt($iInt)IfIsInt($iRoot)ThenReturnFalse$iRoot=Floor($iRoot)For$i=0To5759For$j=$aDivisors[$i]To$iRootStep30030; 2 *3 *5 *7 *11 *13IfMod($iInt,$j)ThenContinueLoop; $j is not a factor$bPrime=FalseExitLoop2NextNextReturn$bPrimeEndFunc;==> _IsPrime; #FUNCTION# ====================================================================================================================; Name...........: _RandomPrime; Description ...: Returns a random prime number of between 1 and 15 digits in length (length must be specified).; Syntax.........: _RandomPrime($iDigits); Parameters ....: $iDigits - The number of digits in the random prime number; Return values .: Success - Returns a random prime number with the required number of digits.; Failure - Sets @error to 1 if $iDigits is not an integer or is out of range:; Author ........: czardas; Comments ......; This function is designed to be called multiple times but uses lots of memory.; ; It is advisable to use Sleep() after any batch processes to allow the CPU to cool off a little.; ; After using this function you should free memory by calling the function _ClearDivisors(); ===============================================================================================================================Func_RandomPrime($iDigits)IfNotIsInt($iDigits)Or$iDigits<1Or$iDigits>15ThenReturnSetError(1)$iDigits-=1Local$iNumber=Number(Random(1,9,1)&StringMid(Random(),3,$iDigits))Local$iStep=1-2*Random(0,1,1)Local$aRange[15][2]=[[2,7],[11,97],[101,997],[1009,9973],[10007,99991],[100003,999983],_[1000003,9999991],[10000019,99999989],[100000007,999999937],[1000000007,9999999967],_[10000000019,99999999977],[100000000003,999999999989],[1000000000039,9999999999971],_[10000000000037,99999999999973],[100000000000031,999999999999989]]If$iNumber>$aRange[$iDigits][1]And$iStep=1Then$iNumber=$aRange[$iDigits][0]ElseIf$iNumber<$aRange[$iDigits][0]And$iStep=-1Then$iNumber=$aRange[$iDigits][1]EndIfWhile1; Do not increase the size of the next loop.For$iNumber=$iNumberTo$iNumber+10*$iStepStep$iStepIf_IsPrime($iNumber)ThenExitLoop2NextSleep($iDigits+16); CPU needs to cool down.WEndReturn$iNumberEndFunc;==> _RandomPrime; #INTERNAL_USE_ONLY# ===========================================================================================================; Name...........: __GetDivisors; Description ...: Sieve to remove prime multiples from the number range 17 to 30045.; Syntax.........: __GetDivisors(); Return values .: Success - Returns an array of the remaining numbers within the range.; Author ........: czardas; Comments ......; This function is called internally by _IsPrime; ===============================================================================================================================Func__GetDivisors()Local$aPrimes[5]=[3,5,7,11,13],$aNumbers[15015],$iTempFor$i=0To15014$iTemp=$i*2+17; Produces odd numbers from 17 to 30045For$j=0To4IfNotMod($iTemp,$aPrimes[$j])ThenContinueLoop2; Skip multiples of 3, 5, 7, 11 and 13Next$aNumbers[$i]=$iTempNext$iTemp=0Local$aDivisors[5760]; Will only contain the factors that made it through the sieve.For$i=0To15014If$aNumbers[$i]Then$aDivisors[$iTemp]=$aNumbers[$i]$iTemp+=1EndIfNextReturn$aDivisorsEndFunc;==> __GetDivisors; ****************************************************************************************; EXAMPLE 1Global$iMax=0ConsoleWrite("Highest primes from 1 to 12 digits"&@LF)For$i=1To12$iMax&=9; $iMax now becomes a string.For$j=$iMaxto10^($i-1)Step-2; $iMax is still interpreted as a number here.If_IsPrime($j)ThenConsoleWrite($j&@LF)Sleep(50); The larger the search range, the more time the CPU needs to cool off.ExitLoopEndIfNextNext_ClearDivisors(); Free up memory; ****************************************************************************************; EXAMPLE 2ConsoleWrite(@LF&"Random primes from 1 to 15 digits"&@LF)For$i=1to15ConsoleWrite(_RandomPrime($i)&@LF)Sleep(10)Next_ClearDivisors(); Free up memory

Share this post

Link to post

Share on other sites

jchd 926

Not being picky, but I wanted to test: >my bignum implementation of _IsPrime (or its complement) favorably competes in both speed and memory usage over a large range of input values. We can even increase the number of iterations of Miller-Rabin to increase confidence on the result by a huge margin. 10 iterations provides probability 0.999999046325684, 15 iterations give 0.999999999068677, 20 iterations provide 0.999999999999091 and 25 iterations give 0.999999999999999

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post

Link to post

Share on other sites

czardas 1,116

Thanks jchd - your words mean a lot to me. I don't have a great deal of use for my function personally, but it might be possible to make use of it with music composition somehow - I'm not sure. I don't need it for encryption purposes and I imagine (my) 15 digit version would be too weak for this. I do like the method of cycling through a sequence - it's similar to generating rhythms.