Skip to content

Commit

Permalink
Big integers (v4.0.0)
Browse files Browse the repository at this point in the history
  • Loading branch information
WrathfulSpatula committed Dec 26, 2024
1 parent 9c07709 commit 6554690
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 36 deletions.
1 change: 1 addition & 0 deletions Eratosthenes/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .eratosthenes import *
58 changes: 38 additions & 20 deletions src/prime_gen.cpp → Eratosthenes/_eratosthenes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,20 @@
// number under trial. Multiples of 2, 3, 5, 7, and 11 can
// be entirely skipped in loop enumeration.

#include "config.h"
#include "dispatchqueue.hpp"

#include <cmath>
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>

#if BIG_INT_BITS > 64
#include <boost/multiprecision/cpp_int.hpp>
#endif

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

namespace qimcifa {

#if BIG_INT_BITS < 33
typedef uint32_t BigInteger;
#elif BIG_INT_BITS < 65
typedef uint64_t BigInteger;
#else
typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<BIG_INT_BITS, BIG_INT_BITS,
boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>
BigInteger;
#endif
typedef typedef boost::multiprecision::cpp_int BigInteger;

inline BigInteger sqrt(const BigInteger& toTest)
{
Expand Down Expand Up @@ -248,6 +236,17 @@ std::vector<BigInteger> SieveOfEratosthenes(const BigInteger& n)
return knownPrimes;
}

std::vector<std::string> _SieveOfEratosthenes(const std::string& n) {
std::vector<BigInteger> v = SieveOfEratosthenes(BigInteger(n));
std::vector<std::string> toRet;
toRet.reserve(v.size());
for (const BigInteger& p : v) {
toRet.push_back(boost::lexical_cast<std::string>(p));
}

return toRet;
}

// Pardon the obvious "copy/pasta."
// I began to design a single method to switch off between these two,
// then I realized the execution time overhead of the implementation.
Expand Down Expand Up @@ -373,6 +372,10 @@ BigInteger CountPrimesTo(const BigInteger& n)
return count;
}

std::string _CountPrimesTo(const string& n) {
return boost::lexical_cast<std::string>(CountPrimesTo(BigInteger(n)));
}

std::vector<BigInteger> SegmentedSieveOfEratosthenes(BigInteger n)
{
// TODO: This should scale to the system.
Expand Down Expand Up @@ -466,7 +469,18 @@ std::vector<BigInteger> SegmentedSieveOfEratosthenes(BigInteger n)
return knownPrimes;
}

BigInteger SegmentedCountPrimesTo(BigInteger n)
std::vector<std::string> _SegmentedSieveOfEratosthenes(const std::string& n) {
std::vector<BigInteger> v = SegmentedSieveOfEratosthenes(BigInteger(n));
std::vector<std::string> toRet;
toRet.reserve(v.size());
for (const BigInteger& p : v) {
toRet.push_back(boost::lexical_cast<std::string>(p));
}

return toRet;
}

BigInteger SegmentedCountPrimesTo(const BigInteger& n)
{
// TODO: This should scale to the system.
// Assume the L1/L2 cache limit is 2048 KB.
Expand Down Expand Up @@ -578,14 +592,18 @@ BigInteger SegmentedCountPrimesTo(BigInteger n)

return count;
}

std::string _SegmentedCountPrimesTo(const std::string& n) {
return boost::lexical_cast<std::string>(SegmentedCountPrimesTo(BigInteger(n)));
}
} // namespace qimcifa

using namespace qimcifa;

PYBIND11_MODULE(eratosthenes, m) {
PYBIND11_MODULE(_eratosthenes, m) {
m.doc() = "pybind11 plugin to generate prime numbers";
m.def("count", &CountPrimesTo, "Counts the prime numbers between 1 and the value of its argument");
m.def("segmented_count", &SegmentedCountPrimesTo, "Counts the primes in capped space complexity");
m.def("sieve", &SieveOfEratosthenes, "Returns all primes up to the value of its argument (using Sieve of Eratosthenes)");
m.def("segmented_sieve", &SegmentedSieveOfEratosthenes, "Returns the primes in capped space complexity");
m.def("count", &_CountPrimesTo, "Counts the prime numbers between 1 and the value of its argument");
m.def("segmented_count", &_SegmentedCountPrimesTo, "Counts the primes in capped space complexity");
m.def("sieve", &_SieveOfEratosthenes, "Returns all primes up to the value of its argument (using Sieve of Eratosthenes)");
m.def("segmented_sieve", &_SegmentedSieveOfEratosthenes, "Returns the primes in capped space complexity");
}
File renamed without changes.
23 changes: 23 additions & 0 deletions Eratosthenes/eratosthenes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import _eratosthenes

def count(n):
return int(_eratosthenes._count(str(n)))

def segmented_count(n):
return int(_eratosthenes._segmented_count(str(n)))

def sieve(n):
v = _eratosthenes._sieve(str(n))
l = []
for p in v:
l.append(int(p))

return l

def segmented_sieve(n):
v = _eratosthenes._segmmented_sieve(str(n))
l = []
for p in v:
l.append(int(p))

return l
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

ext_modules = [
Extension(
'eratosthenes',
'_eratosthenes',
['src/prime_gen.cpp', "src/dispatchqueue.cpp"],
include_dirs=['src/include', 'pybind11/include'],
language='c++',
Expand All @@ -20,7 +20,7 @@

setup(
name='Eratosthenes',
version='3.0.13',
version='4.0.0',
author='Dan Strano',
author_email='[email protected]',
description='Fast prime generation for Python based on Sieve of Eratosthenes',
Expand Down
14 changes: 0 additions & 14 deletions src/include/config.h

This file was deleted.

0 comments on commit 6554690

Please sign in to comment.