Skip Menu |

This queue is for tickets about the Math-Prime-FastSieve CPAN distribution.

Report information
The Basics
Id: 87042
Status: rejected
Priority: 0/
Queue: Math-Prime-FastSieve

People
Owner: Nobody in particular
Requestors: jimm [...] renewalcomputerservices.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: several bugs
Date: Fri, 19 Jul 2013 02:01:31 -0700
To: bug-Math-Prime-FastSieve [...] rt.cpan.org
From: Renewal Computer Services <jimm [...] renewalcomputerservices.com>
nth_prime(1) gives the first prime, 1, not the first prime in the list as specified in the manual. to fix, the prime number of the lower bound must be added to this number. this would mean you would also need to add another method, one which provides the so I would suggest 3 functions in this interface: - nth_prime(index) which takes a 1-based index into the list of primes starting with 1 and returns the nth prime of all the primes starting with 1. - nth_prime_in_list(index) which takes a 1-based index into the list of primes within the bounds of the generated list such as by ranged_primes() and returns the nth prime of that list. - list_count(index) which returns a count the list of primes within the bounds of the generated list such as by ranged_primes(). - sieve_count() which returns a count the of the list of primes starting with 1. - since most people working with primes want to work with huge numbers, I would highly suggest that Math::BigInt should be used in this module as a requirement. -- Renewal Computer Services <http://RenewalComputerServices.com> Jim Michaels, Owner 1303 NE 87th Ave <http://www.mapquest.com/maps/1303+NE+87th+Ave+Vancouver+WA+98664-1959/> (87th Ave & 13th St), Vancouver, WA, 98664-1959 USA, 1-360-521-2060 Cell 1-10pm Serving Vancouver, WA DIY Computer Repair Info: Jesusnjim.com <http://Jesusnjim.com> jimm@RenewalComputerServices.com <mailto:jimm@RenewalComputerServices.com> jmichae3@yahoo.com <mailto:jmichae3@yahoo.com>
RT-Send-CC: dana [...] acm.org
Thanks for the report. I need to seek clarification... On Fri Jul 19 02:01:43 2013, jimm@renewalcomputerservices.com wrote: Show quoted text
> > nth_prime(1) gives the first prime, 1, not the first prime in the list > as specified in the manual.
perl -MMath::Prime::FastSieve -E 'say Math::Prime::FastSieve::Sieve->new(20)->nth_prime(1)' This code should yield '2', as 2 is the first prime number. And when I run it, it does. Can you provide sample code where this method misbehaves? <snip> Show quoted text
> - since most people working with primes want to work with huge numbers, > I would highly suggest that Math::BigInt should be used in this module > as a requirement.
Math::Prime::FastSieve attempts to hold the entire sieve in memory as a bit vector. This is pretty fast for sieves that don't take you into swap memory. But once they begin to get into swap, you're much better off with a segmented sieve. Dana Jacobsen's Math::Prime::Util is probably what you're looking for when you get into sieves that are big enough for "BigInt" semantics.
My reading of the documentation seems pretty clear that nth_prime returns the absolute nth prime or 0 (if the nth prime is past the sieve range). I've had no luck reproducing a result of 1 on various perl versions on Linux, Cygwin, and Windows, and there's nothing in the code that would make me think that would be output. nth_prime(1) returns either 2 or 0 (if initialized with 0, undef, negative, etc.). The lower bound for the sieve is always 2 (the first prime). I think perhaps you're getting the functionality of ranged_primes(lower, upper) confused with the sieving. The sieve in this module is always from 2 to N. Then the methods give fast answers within that range. Regarding Math::BigInt, this should be a non-issue with 64-bit Perl with this module. I could see the case on a 32-bit Perl where it is restricted to (I believe) ~2 billion, but I suspect that isn't what you're talking about. While it might be inefficient, some of the functions you're asking for could be done by indexing into the ranged_primes return. Methods on $sieve: # Return the absolute nth prime: $sieve->nth_prime($index) # Returns the 4th prime in the list (sorry, 0 based) $sieve->ranged_primes(5, 16)->[3] # Returns the count for the entire sieve $sieve->sieve_count() # Returns the count in this range scalar @{$sieve->ranged_primes(5,16)} You may want to look at Math::Prime::Util (and Math::Prime::Util::GMP) which has better support for ranged operations and big numbers. It will happily give you primes between 10**18 and 10**18+n, or 10**101 to 10**101+n, etc. It also does efficient ranged prime counts.
RT-Send-CC: dana [...] acm.org
I'm rejecting this ticket because it seems to be based on a misunderstanding of how Math::Prime::FastSieve works. Furthermore, neither I nor Dana were able to come up with a situation that provides anything but correct results for nth_prime. The code involved is simple enough, and the existing test suite already tests nth_prime(1), which was the specific example mentioned in the ticket. If there is a test case that demonstrates bad behavior, please do let me know.
Subject: Re: [rt.cpan.org #87042] several bugs
Date: Fri, 26 Jul 2013 16:10:46 -0700
To: bug-Math-Prime-FastSieve [...] rt.cpan.org
From: Renewal Computer Services <jimm [...] renewalcomputerservices.com>
On 7/19/2013 10:52 PM, David J. Oswald via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=87042 > > > Thanks for the report. I need to seek clarification... > > On Fri Jul 19 02:01:43 2013, jimm@renewalcomputerservices.com wrote:
>> nth_prime(1) gives the first prime, 1, not the first prime in the list >> as specified in the manual.
> perl -MMath::Prime::FastSieve -E 'say Math::Prime::FastSieve::Sieve->new(20)->nth_prime(1)' > > This code should yield '2', as 2 is the first prime number. And when I run it, it does. Can you provide sample code where this method misbehaves? > > <snip> >
>> - since most people working with primes want to work with huge numbers, >> I would highly suggest that Math::BigInt should be used in this module >> as a requirement.
> Math::Prime::FastSieve attempts to hold the entire sieve in memory as a bit vector. This is pretty fast for sieves that don't take you into swap memory. But once they begin to get into swap, you're much better off with a segmented sieve. Dana Jacobsen's Math::Prime::Util is probably what you're looking for when you get into sieves that are big enough for "BigInt" semantics. > > > >
perl -MMath::Prime::FastSieve -E 'say Math::Prime::FastSieve::Sieve->new(20)->nth_prime(1)' does yield 2. actually, 1 is the first prime number from what little I remember in college 20 years ago. but typically with sieves it's ignored since it's not easily calculable and typically requires an if test and specifically adding this to the list of primes manually. I would also suggest, if possible, use int64_t or uint64_t in <stdint.h> if this is compatible as a data type with Perl. at least then you will have 64-bit numbers instead of just 32-bit. boost has bigint types of numbers. as for perl data structures, you should be using dynamic_bitset for your data type if you are using gcc. it would reduce your memory requirements by a factor of 8. or maybe even 32. you can always translate the bits into a bool through your interface. the data structure is more densely packed and probably doesn't waste bits. http://gcc.gnu.org/onlinedocs/gcc-4.7.1/libstdc++/api/a00910.html#a6043959b046b04a92027e355ce16562b -- Renewal Computer Services <http://RenewalComputerServices.com> Jim Michaels, Owner 1303 NE 87th Ave <http://www.mapquest.com/maps/1303+NE+87th+Ave+Vancouver+WA+98664-1959/> (87th Ave & 13th St), Vancouver, WA, 98664-1959 USA, 1-360-521-2060 Cell 1-10pm Serving Vancouver, WA DIY Computer Repair Info: Jesusnjim.com <http://Jesusnjim.com> jimm@RenewalComputerServices.com <mailto:jimm@RenewalComputerServices.com> jmichae3@yahoo.com <mailto:jmichae3@yahoo.com>
Subject: Re: [rt.cpan.org #87042] several bugs
Date: Fri, 26 Jul 2013 16:18:49 -0700
To: bug-Math-Prime-FastSieve [...] rt.cpan.org
From: Renewal Computer Services <jimm [...] renewalcomputerservices.com>
On 7/22/2013 5:13 PM, David J. Oswald via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=87042 > > > I'm rejecting this ticket because it seems to be based on a misunderstanding of how Math::Prime::FastSieve works. Furthermore, neither I nor Dana were able to come up with a situation that provides anything but correct results for nth_prime. The code involved is simple enough, and the existing test suite already tests nth_prime(1), which was the specific example mentioned in the ticket. > > If there is a test case that demonstrates bad behavior, please do let me know. > >
I am just going by the specs in the pm. ranged_prime's lower bound is supposed to work, but it doesn't, gives me 3 all the time for lower bound. here is my code, twin-primes.pl, you feed it with commandline args 10000 500 and it should give you the range 99500..10500 but it gives me 3..10500. #!/usr/bin/perl #twinprimes.pl #Abstract: generate twin primes, and the differences, showing maximum difference for the set #Author: Jim Michaels #Created: 7/18/2013 #program arguments: # positive integer center # positive integer offset, less than center above #I originally did this with C++, but it was too slow with sieve of Eratosthenes. this had a fast sieve and it already had range capability. use Math::BigInt; # ---------- The simple interface: ---------- use Math::Prime::FastSieve qw( primes ); sub help { die("twinprimes.pl - generate list of twin primes with differences\n" . "usage:\n" . " twinprimes.pl center offset\n" . " perl twinprimes.pl center offset\n" . "options:\n" . " center: positive integer which twin primes center around\n" . " offset: positive integer which is subtracted from the offset and added to the center to provide upper and lower bounds.\n" . "\n" . "This program generates twin primes in the style of primesieve as far as format, but goes 2 steps further:\n" . "- this handles BigInt for infinite precision math\n" . "- it uses Perl's very flexible number formatting (handles hexadecimal, octal, etc)\n" . "- shows the difference between twin primes\n" . "- shows the maximum and minimum difference at the end, and the count\n" . "By Jim Michaels, 7/18/2013\n" ); } if (2 != $#ARGV+1) { #provide help, user provided invalid quantity of arguments help(); } # Obtain an reference to an array containing all primes less than or # equal to 5 Million. #my $aref = primes( 5_000_000 ); my ($center, $offset, $i, $max_difference, $min_difference, $difference, $old_i, $upper_bound, $lower_bound,$twin_prine_count,$offset); my @twinprimes = (); $center=$ARGV[0]; $offset=$ARGV[1]; $upper_bound = $center+$offset+2; $lower_bound = $center-$offset; # ---------- The object (far more flexible) interface. ---------- # Create a new sieve and flag all primes less or equal to n. my $sieve = Math::Prime::FastSieve::Sieve->new( $upper_bound ); # Obtain a ref to an array containing all primes <= 5 Million. #my $aref = $sieve->primes( 5_000_000 ); # Obtain a ref to an array containing all primes >= 5, and <= 16. my $aref = $sieve->ranged_primes( $lower_bound, $upper_bound); my $num_found = $sieve->count_sieve(); $twin_prime_count=0; $old_i = -1; $difference = 0; for ($i=1; $i < $num_found - 1; $i++) { if ($sieve->nth_prime($i)+2==$sieve->nth_prime($i+1)) { $twin_prime_count++; print "(" . $sieve->nth_prime($i) . ", " . $sieve->nth_prime($i+1) . ") index=" . $twin_prime_count; #if (-1 != $old_i) { $difference = $i-$old_i; $min_difference = min($min_difference,$difference); $max_difference = max($max_difference,$difference); print " difference=" . $difference; #} else { # $min_difference = $difference; # $max_difference = $difference; #} print "\n"; $old_i = $i; } } print "\n"; print "center=" . $center . "\n"; print "offset=" . $offset . "\n\n"; print "lower bound=" . $lower_bound . "\n"; print "upper bound=" . $upper_bound . "\n"; print "min difference=" . $min_difference . "\n"; print "max difference=" . $max_difference . "\n"; print "count=" . $num_found . "\n"; print "\n"; sub min { my($mn,$i); if ($#_+1 < 1) { return 0; } $mn=$_[0]; for ($i=0; $i <= $#_; $i++) { #if (0 == $i) { # $mn=$_[$i]; #} if ($_[$i] < $mn) { $mn=$_[$i]; } } return $mn; } sub max { my($mx,$i); if ($#_+1 < 1) { return 0; } $mx=$_[0]; for ($i=0; $i <= $#_; $i++) { #if (0 == $i) { # $mx=$_[$i]; #} if ($_[$i] > $mx) { $mx=$_[$i]; } } return $mx; } -- Renewal Computer Services <http://RenewalComputerServices.com> Jim Michaels, Owner 1303 NE 87th Ave <http://www.mapquest.com/maps/1303+NE+87th+Ave+Vancouver+WA+98664-1959/> (87th Ave & 13th St), Vancouver, WA, 98664-1959 USA, 1-360-521-2060 Cell 1-10pm Serving Vancouver, WA DIY Computer Repair Info: Jesusnjim.com <http://Jesusnjim.com> jimm@RenewalComputerServices.com <mailto:jimm@RenewalComputerServices.com> jmichae3@yahoo.com <mailto:jmichae3@yahoo.com>

Message body is not shown because it is too large.

Subject: Re: [rt.cpan.org #87042] several bugs
Date: Fri, 26 Jul 2013 19:27:14 -0700
To: bug-Math-Prime-FastSieve [...] rt.cpan.org
From: Renewal Computer Services <jimm [...] renewalcomputerservices.com>
On 7/20/2013 12:06 AM, Dana Jacobsen via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=87042 > > > My reading of the documentation seems pretty clear that nth_prime returns the absolute nth prime or 0 (if the nth prime is past the sieve range). I've had no luck reproducing a result of 1 on various perl versions on Linux, Cygwin, and Windows, and there's nothing in the code that would make me think that would be output. nth_prime(1) returns either 2 or 0 (if initialized with 0, undef, negative, etc.). The lower bound for the sieve is always 2 (the first prime). > > I think perhaps you're getting the functionality of ranged_primes(lower, upper) confused with the sieving. The sieve in this module is always from 2 to N. Then the methods give fast answers within that range. > > Regarding Math::BigInt, this should be a non-issue with 64-bit Perl with this module. I could see the case on a 32-bit Perl where it is restricted to (I believe) ~2 billion, but I suspect that isn't what you're talking about. > > While it might be inefficient, some of the functions you're asking for could be done by indexing into the ranged_primes return. Methods on $sieve: > > # Return the absolute nth prime: > $sieve->nth_prime($index) > # Returns the 4th prime in the list (sorry, 0 based) > $sieve->ranged_primes(5, 16)->[3] > # Returns the count for the entire sieve > $sieve->sieve_count() > # Returns the count in this range > scalar @{$sieve->ranged_primes(5,16)} > > You may want to look at Math::Prime::Util (and Math::Prime::Util::GMP) which has better support for ranged operations and big numbers. It will happily give you primes between 10**18 and 10**18+n, or 10**101 to 10**101+n, etc. It also does efficient ranged prime counts. > >
when I try to get the $aref or @aref list from ranged_primes() I get various useless results: size of scalar(@aref)=1 $#aref=0 when I should be getting much larger numbers. the list from this function and probably primes also is inaccessible. it appears it is only accessible through the API via nth_prime(). if this is intended, there needs to be some forwards/backwards index lookup functionality to make ranged_primes() usable. apparently, it does the whole set of prime numbers regardless of the lower bounds I set. this may be by design due to sieve algorithm I figure. Specifically, some sort of functions that: - looks up the index of a prime number in the list that augments nth_prime(). it should return failure if it's not found. - looks up the specific prime number of an index in the list that augments nth_prime(). it should return failure if it's not in list. in other words, some lookup functionality. otherwise, it's possible that range_primes() should be deleted entirely if we cannot access the list of it at all anyway and no functionality to access that list is going to be provided. otherwise, I would be spending my time re-generating the list of primes in order to find out what the primes were in that list, and that would basically be rewriting your code. according to the pm file: SV* Sieve::ranged_primes( long lower, long upper ) upper and lower appears to be a prime number. when I run my twin-primes.pl code as you see in the bug report, I get for center 10000 offset +/-500, which gives me: (3, 5) index=1 difference=3 (5, 7) index=2 difference=1 (11, 13) index=3 difference=2 (17, 19) index=4 difference=2 (29, 31) index=5 difference=3 (41, 43) index=6 difference=3 (59, 61) index=7 difference=4 (71, 73) index=8 difference=3 (101, 103) index=9 difference=6 (107, 109) index=10 difference=2 ... (9857, 9859) index=204 difference=12 (9929, 9931) index=205 difference=8 (10007, 10009) index=206 difference=6 (10037, 10039) index=207 difference=2 (10067, 10069) index=208 difference=3 (10091, 10093) index=209 difference=3 (10139, 10141) index=210 difference=6 (10271, 10273) index=211 difference=16 (10301, 10303) index=212 difference=3 (10331, 10333) index=213 difference=4 (10427, 10429) index=214 difference=8 (10457, 10459) index=215 difference=4 center=10000 offset=500 lower bound=9500 upper bound=10502 min difference= max difference=24 count=1285 this starts at 3, for a prime number, not 9500 which is consistent with nth_prime(). no list access API function is provided, and so far, I have been unable by any method I have tried to access this array/list returned by ranged_primes(). a list access method/function in the API needed to be provided, please. it looks like std::vector<bool>, and I should hope that somehow this translates well to Perl, but apparently this does not. try it for yourself. use Math::Prime::FastSieve qw( primes ); my $sieve = Math::Prime::FastSieve::Sieve->new(10000); my @aref = $sieve->ranged_primes( 9500, 10500); print "size of aref=scalar:" . scalar(@aref) . " \$\#:" . $#aref . "\n"; for ($i=0; $i <= $#aref; $i++) { printf $aref[$i] . "\n"; } my $aref2 = $sieve->ranged_primes( 9500, 10500); print "size of aref=scalar:" . scalar(@aref2) . " \$\#:" . $#aref2 . "\n"; for ($i=0; $i <= scalar(@aref2); $i++) { printf $aref2[$i] . "\n"; } -----Documentation: - I believe the ranged_primes() example to be wrong, my $aref = returned from ranged_primes should be my @aref = if it really is a standard perl list. - undocumented structures etc. I don't know what's in these structures or data types or macros. so I don't know how to access the elements in $aref in the examples. I would like to see an example that walks the list and prints out the primes for a ranged prime, because what I have doesn't work, and it's only based on best-guess, not enough info. the undocumented structure information is critical to accessing the list. specifically: newRV_noinc AV newAV newSVuv av_push newSVuv actual source code is not provided, so I can't tell what's in the structures. I think I said before that it would be a good idea to use int64_t. If I remember right, Perl without Math::BigInt handles 64-bit numbers. so it would be good to: - use this as your integer number type in all functions (and translate as such for return types) - use this instead of bool? perl doesn't have bool to my knowledge. I really like having the ranged_primes functionality (mainly because I don't have to write it myself). I was just hoping to get it working. I was also hoping for some enhancements in addition to the bug report on ranged_primes(). -- Renewal Computer Services <http://RenewalComputerServices.com> Jim Michaels, Owner 1303 NE 87th Ave <http://www.mapquest.com/maps/1303+NE+87th+Ave+Vancouver+WA+98664-1959/> (87th Ave & 13th St), Vancouver, WA, 98664-1959 USA, 1-360-521-2060 Cell 1-10pm Serving Vancouver, WA DIY Computer Repair Info: Jesusnjim.com <http://Jesusnjim.com> jimm@RenewalComputerServices.com <mailto:jimm@RenewalComputerServices.com> jmichae3@yahoo.com <mailto:jmichae3@yahoo.com>

Message body is not shown because it is too large.

Subject: Re: [rt.cpan.org #87042] several bugs
Date: Fri, 26 Jul 2013 20:07:06 -0700
To: bug-Math-Prime-FastSieve [...] rt.cpan.org
From: Renewal Computer Services <jimm [...] renewalcomputerservices.com>
On 7/22/2013 5:13 PM, David J. Oswald via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=87042 > > > I'm rejecting this ticket because it seems to be based on a misunderstanding of how Math::Prime::FastSieve works. Furthermore, neither I nor Dana were able to come up with a situation that provides anything but correct results for nth_prime. The code involved is simple enough, and the existing test suite already tests nth_prime(1), which was the specific example mentioned in the ticket. > > If there is a test case that demonstrates bad behavior, please do let me know. > >
you may use these examples for ranged_prime(), ranged_primes works fine. the problem with me was I did not know how to dereference an array. the expansion of the size of the integer would still be useful for whoever uses this library. so, - there IS a way to access the array that is returned. - lookup functions would be nice, but are not required. maybe perl already provides these. use Math::Prime::FastSieve qw( primes ); my $sieve = Math::Prime::FastSieve::Sieve->new(10500); #print list of primes between 9500 and 10500 my $aref = $sieve->ranged_primes( 9500, 10500); for ($i=0; $i <= $#{$aref}; $i++) { printf $$aref[$i] . ","; } printf "\n"; #print list of twin primes between 9500 and 10500 my $twin_prime_count=0; my $old_i = -1; my $difference = 0; my $aref = $sieve->ranged_primes( $lower_bound, $upper_bound); my $num_found = $#{$aref} + 1; for ($i=0; $i < $num_found - 1; $i++) { if ($$aref[$i]+2==$$aref[$i+1]) {#twin prime? $twin_prime_count++; print "(" . $$aref[$i] . ", " . $$aref[$i+1] . ")\n"; if (-1 != $old_i) { $difference = $i-$old_i; $min_difference = min($min_difference,$difference); $max_difference = max($max_difference,$difference); } $old_i = $i; } } print "lower bound=" . $lower_bound . "\n"; print "upper bound=" . $upper_bound . "\n"; print "min difference=" . $min_difference . "\n"; print "max difference=" . $max_difference . "\n"; print "count=" . $twin_prime_count . "\n"; sub min { my($mn,$i); if ($#_+1 < 1) { return 0; } $mn=int($_[0]); for ($i=0; $i <= $#_; $i++) { #if (0 == $i) { # $mn=$_[$i]; #} if (int($_[$i]) < $mn) { $mn=int($_[$i]); } } return $mn; } sub max { my($mx,$i); if ($#_+1 < 1) { return 0; } $mx=int($_[0]); for ($i=0; $i <= $#_; $i++) { #if (0 == $i) { # $mx=$_[$i]; #} if (int($_[$i]) > $mx) { $mx=int($_[$i]); } } return $mx; } -- Renewal Computer Services <http://RenewalComputerServices.com> Jim Michaels, Owner 1303 NE 87th Ave <http://www.mapquest.com/maps/1303+NE+87th+Ave+Vancouver+WA+98664-1959/> (87th Ave & 13th St), Vancouver, WA, 98664-1959 USA, 1-360-521-2060 Cell 1-10pm Serving Vancouver, WA DIY Computer Repair Info: Jesusnjim.com <http://Jesusnjim.com> jimm@RenewalComputerServices.com <mailto:jimm@RenewalComputerServices.com> jmichae3@yahoo.com <mailto:jmichae3@yahoo.com>
RT-Send-CC: dana [...] acm.org
On Fri Jul 26 16:12:10 2013, jimm@renewalcomputerservices.com wrote: Show quoted text
> perl -MMath::Prime::FastSieve -E 'say > Math::Prime::FastSieve::Sieve->new(20)->nth_prime(1)' > does yield 2. > > actually, 1 is the first prime number from what little I remember in > college 20 years ago. but typically with sieves it's ignored since > it's not easily calculable and typically requires an if test and > specifically adding this to the list of primes manually.
http://en.wikipedia.org/wiki/Prime_numbers#Primality_of_one Apparently the last "professional mathematician to call 1 prime" died in 1941. I'm not a professional mathematician, but I'll trust that since nobody else has stepped up to take is place in that niche the concept has been laid to rest as well. Show quoted text
> I would also suggest, if possible, use int64_t or uint64_t in > <stdint.h> > if this is compatible as a data type with Perl. at least then you will > have 64-bit numbers instead of just 32-bit. boost has bigint types of > numbers.
We're not going to support Math::BigInt, or BigInt. If you need that, use Math::Prime::Util, which, because it offers a segmented sieve, is a much better fit for truly huge integers. We do, however, already support 64-bit integers, and would gain nothing aside from a possible reduction of portability if we specifically used int64_t or uint64_t (that would make the module inaccessible to users of 32-bit builds of Perl). As a case in point: We can safely assert that 5_000_000_000 (5 billion) is outside the range of even an unsigned 32-bit integer. So consider this code: use Math::Prime::FastSieve; my $sieve = Math::Prime::FastSieve::Sieve->new(5_000_000_000); my $primes_ref = $sieve->ranged_primes( 4_999_999_500, 5_000_000_000 ); print scalar @{$primes_ref}, "\n"; print "$_\n" for @{$primes_ref}; The output on a 64-bit Perl build will be: 21 4999999547 4999999573 4999999607 4999999621 4999999643 4999999679 4999999717 4999999729 4999999751 4999999759 4999999789 4999999799 4999999801 4999999811 4999999817 4999999859 4999999861 4999999867 4999999883 4999999903 4999999937 Clearly, 4_999_999_937 is out of the range that could be expressed in 32 bits. Because we're using a 64 bit Perl, and because we're compiling using the machine's native long, which should in almost all cases on a 64 bit machine be a 64 bit container, we get 64 bit semantics. But I do want to point out that this test code, on my reasonably fast machine, takes 24 seconds to run. Math::Prime::Util offers a segmented sieve, where you could specify a range from 4_999_999_500 to 5_000_000_000, and the sieve would only be built for that specific range. Instead of taking 24 seconds to run, it would take a small fraction of a second. If you need primes in the 64-bit range and beyond, you probably should be using Math::Prime::Util, not Math::Prime::FastSieve. Show quoted text
> > as for perl data structures, you should be using dynamic_bitset for > your data type if you are using gcc. it would reduce your memory > requirements by a factor of 8. or maybe even 32. you can always > translate the bits into a bool through your interface. the data > structure is more densely packed and probably doesn't waste bits. > http://gcc.gnu.org/onlinedocs/gcc- > 4.7.1/libstdc++/api/a00910.html#a6043959b046b04a92027e355ce16562b
I'm currently holding the sieve in a vector<bool>, which, although it's a much maligned contaner, doesn't consume 8-bits per bool, it consumes one bit per bool, plus a little meta-data that is constant regardless of container size. A vector<bool> is a dynamic bit vector, essentially. The "bool" specialization of the std::vector template is considered a 2nd class citizen among the STL container classes, but the way we're using it doesn't touch any of the areas considered deficient. Specifically using a GCC feature would either add code complexity (preprocessor directives to use some code for GCC, and other code for everyone else), or diminish portability, which is against the design objective. If you're suggesting that instead of an array-ref I should be passing back a bit-vector directly to Perl, that goes against the design philosophy of this module. The concept is for the sieve to be encapsulated within the C++ code, and for the "prime" characteristics to be available by querying the sieve through accessors. If I wanted to expose the sieve directly to Perl, I give the Sieve object an accessor that returns a Bit::Vector object. But I don't see that feature as being useful enough to justify the extra dependency. Please remember that Math::Prime::FastSieve was designed as a simple, fast prime sieve, and also as a proof of concept demonstrating that Inline::CPP can be used as a dependency for a CPAN module. If M::P::FastSieve wanted to be Math::Prime::Util, it could be rewritten, but then it would cease to be a simple example of Inline::CPP at work. ...and Math::Prime::Util already exists.
RT-Send-CC: dana [...] acm.org
On Fri Jul 26 16:18:59 2013, jimm@renewalcomputerservices.com wrote: Show quoted text
> my $aref = $sieve->ranged_primes( $lower_bound, $upper_bound);
The code you posted takes $sieve->ranged_primes() return value into the scalar value $aref, and then never uses $aref again. It would be impossible to make any kind of determination whether or not ranged_primes() is working properly if its return value is never used for anything. The test suite tests the range_primes() method with nine different ranges, some of them intentionally illegal for the sieve size used in the test, and in each case, the output is as expected/documented. See t/03sieve_object.t lines 39 through 66. If you can show a test in the form of: use Math::Prime::FastSieve; my $sieve_size = ***some integer***; my $min = *** some integer within the sieve ***; my $max = *** some integer within the sieve ***; my $sieve = Math::Prime::FastSieve::Sieve->new( $sieve_size ); my $range_aref = $sieve->ranged_primes( $min, $max ); print "$_\n" for @{$range_aref}; ...where the output is anything other than what it should be, you will have found a bug. If you can demonstrate some other documented use of the module that causes ranged_primes to misbehave, that would also be a bug. But calling ranged_primes and not using its return value... that's not a Math::Prime::FastSieve bug.
On Fri Jul 26 20:07:15 2013, jimm@renewalcomputerservices.com wrote: Show quoted text
> you may use these examples for ranged_prime(), ranged_primes works > fine. the problem with me was I did not know how to dereference an > array. the expansion of the size of the integer would still be > useful for whoever uses this library. so,
So rejecting the RT ticket was the correct thing to do. ranged_primes works as documented. Show quoted text
> use Math::Prime::FastSieve qw( primes ); > my $sieve = Math::Prime::FastSieve::Sieve->new(10500); > #print list of primes between 9500 and 10500 > my $aref = $sieve->ranged_primes( 9500, 10500); > for ($i=0; $i <= $#{$aref}; $i++) { > printf $$aref[$i] . ","; > } > printf "\n";
That's just proof that you can program C in Perl. ;) You may use this example... it's more Perlish. # print list of primes between 9500 and 10500 my $aref = $sieve->ranged_primes( 9500, 10500 ); print "$_\n" for @{$aref}; ...or... print "$_\n" for @{ $sieve->ranged_primes( 9500, 10500 ) }; ...or even... say for @{ $sieve->ranged_primes( 9500, 10500 ) }; ...or... { local $" = "\n"; print "@{$sieve->ranged_primes(9500,10500)}\n"; }
If I may add my two cents, On Fri Jul 26 19:12:10 2013, jimm@renewalcomputerservices.com wrote: Show quoted text
> actually, 1 is the first prime number [...]
David gave the link to Wikipedia, but for good measure: - Apostol 1976 "A prime number is a number greater than 1 whose only divisors are 1 and the number itself." - Hardy and Wright 6th edition 2008, "A number p is said to be prime if (i) p > 1, (ii) p has no positive divisors except 1 and p." ... "It is important to observe that 1 is not reckoned as a prime." - Crandall and Pomerance 2nd edition 2010, "The number 1 is considered neither prime nor composite". If 1 is considered prime, then most functions dealing with primes end up having to have special cases added to them. It isn't just sieving, it's basically any algorithm that wants a prime or factors that would have to have "p > 1" added to them. Show quoted text
> I would also suggest, if possible, use int64_t or uint64_t in > <stdint.h> > if this is compatible as a data type with Perl. at least then you will > have 64-bit numbers instead of just 32-bit. boost has bigint types of > numbers.
What I found from my code was that using UV/IV types saved me a lot of trouble. That's the integer type Perl is compiled for, and saves me from having to deal with the portability issues around different types and compilers. If they're on a 32-bit machine where "unsigned long" is 32-bit but using a 64-bit Perl, then we'll be 64-bit. I'm testing this with Math::Prime::FastSieve right now, as I have such a platform, and ... (queue Jeopardy theme, as this is a really slow Atom netbook) ... Indeed, prints the wrong answer. UV is an unsigned long long here. Show quoted text
> as for perl data structures, you should be using dynamic_bitset for > your data type if you are using gcc. it would reduce your memory > requirements by a factor of 8. or maybe even 32. you can always > translate the bits into a bool through your interface. the data > structure is more densely packed and probably doesn't waste bits. > http://gcc.gnu.org/onlinedocs/gcc- > 4.7.1/libstdc++/api/a00910.html#a6043959b046b04a92027e355ce16562b
If I remember right, I made a version of Math::Prime::FastSieve that used bit twiddling, just like I would with C, and it didn't change much. gcc seems able to figure out the std::vector<bool> pretty well and generate the right code. It's definitely not using a character or word per entry.
If you want really big ranges, you can use Math::Prime::Util's primes(begin,end) function, where they can be bigints (but for 64-bit values there isn't any real need). I use the same "return an array reference" for that function, since David showed me it really saved time with large ranges. However in simple scripts I'll often just use: my @primes = @{primes($begin,$end)}; so I don't worry about it. Noting that this probably uses twice the memory as leaving it in an array reference, but with ranges of 1000 it's completely irrelevant. It's meaningful when the list is many millions of numbers. If you just want twin primes without writing any code, MPU comes with a primes.pl program that will output twins, triplets, quadruplets, cousins, sexy, safe, Sophia Germain, Lucas, Fibonacci, Lucky, etc. (and combinations), taking an expression as arguments. E.g. primes.pl --twin 10**27-5000 10**27+5000 For differences, you could decorate it with something like: primes.pl --twin 10**27-5000 10**27+5000 | perl -Mbigint -nE '$n = 0+$_; say "$n diff: ", $last ? $n-$last : 0; $last = $n;' If you want to write it yourself, I recommend (1) look at List::Util for min, max, etc. (2) look at the examples/twin_primes.pl program in the latest Math::Prime::Util. It includes a twin primes iterator, which may or may not be of any interest. You may also find that simple next_prime, is_prime, etc. may work for your needs, and then use prime_precalc to speed them up if the endpoint is reasonable (e.g. under a few billion). Lastly, if you're in some sort of reasonable range, then primesieve will be the fastest solution. It has a faster sieve than ... well, anything. But at some point you're too big for a sieve to be an effective solution (you can debate at what point past 2^64 this occurs). Most of them just plain don't support operation on anything more than 64-bits (I'm not sure anything does other than perhaps TOS's private code). At this point you're *way* past the point of Math::Prime::FastSieve or Math::Prime::XS or Math::Big. You're left with Math::Primality, Math::Prime::Util (pure Perl), and Math::Prime::Util::GMP. Or skip Perl and write your own GMP code or use David Cleaver's mpz_prp code. I think Math::Prime::Util::GMP is the best solution (or use the GMP code from it), but I'm biased.