added old multithreaded prime calculation script
authorGeorgios Atheridis <atheridis@tutamail.com>
Tue, 2 Aug 2022 04:14:33 +0000 (07:14 +0300)
committerGeorgios Atheridis <atheridis@tutamail.com>
Tue, 2 Aug 2022 04:14:33 +0000 (07:14 +0300)
README.md [new file with mode: 0644]
calculating_primes.py [new file with mode: 0644]

diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..bdcdae1
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# Collection of random simple Python scripts
diff --git a/calculating_primes.py b/calculating_primes.py
new file mode 100644 (file)
index 0000000..97a2a22
--- /dev/null
@@ -0,0 +1,110 @@
+import numpy as np\r
+from math import sqrt, ceil, floor\r
+import concurrent.futures\r
+import os\r
+\r
+\r
+def sieve(limit):\r
+    """\r
+    Calculates prime numbers using the Sieve of Eratosthenes.\r
+\r
+    :param int limit: Choose the limit which primes are calculated. Exclusive.\r
+    :return np.array:\r
+    """\r
+    is_prime = np.ones(limit, dtype=bool)\r
+    for n in range(2, ceil(sqrt(limit))):\r
+        if is_prime[n]:\r
+            is_prime[n * n :: n] = 0\r
+    is_prime[0] = 0\r
+    is_prime[1] = 0\r
+\r
+    os.makedirs(f"primes{limit}", exist_ok=True)\r
+\r
+    np.save(f"primes{limit}/Prime_{limit}_0", np.packbits(is_prime))\r
+\r
+    return np.nonzero(is_prime)[0], is_prime\r
+\r
+\r
+def wrapper(limit, segment, primes, worker):\r
+    segment_range = [segment * worker, (1 + worker) * segment]\r
+    if segment_range[1] >= limit:\r
+        segment_range[1] = limit\r
+\r
+    is_prime_range = np.ones(segment, dtype=bool)\r
+\r
+    for i in range(len(primes)):\r
+        loLim = floor(segment_range[0] / primes[i]) * primes[i]\r
+\r
+        if loLim < segment_range[0]:\r
+            loLim += primes[i]\r
+\r
+        for j in range(loLim, segment_range[1], primes[i]):\r
+            is_prime_range[j - segment_range[0]] = 0\r
+\r
+    np.save(f"primes{segment}/Prime_{segment}_{worker}", np.packbits(is_prime_range))\r
+\r
+    # return is_prime_range, worker\r
+\r
+\r
+def segmented_sieve(limit):\r
+    """\r
+    Calculates prime numbers using the Sieve of Eratosthenes.\r
+    Uses less memory compared to sieve, but is a bit slower.\r
+\r
+    :param int limit: Choose the limit which primes are calculated. Exclusive.\r
+    :return:\r
+    """\r
+    segment = int(ceil(sqrt(limit)))\r
+    primes, is_prime = sieve(segment)\r
+\r
+    prime_list = []\r
+    prime_list.append((is_prime, 0))\r
+\r
+    with concurrent.futures.ProcessPoolExecutor(12) as executor:\r
+        results = []\r
+        worker = 0\r
+        while segment < limit:\r
+            worker += 1\r
+            results.append(\r
+                executor.submit(wrapper, limit, int(ceil(sqrt(limit))), primes, worker)\r
+            )\r
+            segment += int(ceil(sqrt(limit)))\r
+\r
+    return prime_list, int(ceil(sqrt(limit)))\r
+\r
+\r
+def get_primes(seg, code):\r
+    p = np.load(f"primes{seg}/Prime_{seg}_{code}.npy")\r
+    p = np.unpackbits(p, count=seg)\r
+    return np.nonzero(p)[0] + seg * code\r
+\r
+\r
+def is_prime(seg, n):\r
+    code = floor(n / seg)\r
+    pos = n % seg\r
+    primes = np.load(f"primes{seg}/Prime_{seg}_{code}.npy")\r
+    primes = np.unpackbits(primes, count=seg)\r
+    return primes[pos]\r
+\r
+\r
+if __name__ == "__main__":\r
+    l, seg = segmented_sieve(1_000_000)\r
+    print(get_primes(1000, 1))\r
+    # isprime = 0\r
+    # print(is_prime(31623 ,isprime))\r
+\r
+    # sums = 0\r
+    # lists = []\r
+    # count = 0\r
+    # for i in range(100000):\r
+    #     # if i % 1000 == 0:\r
+    #     #     print(f"i: {i}")\r
+    #     primes = get_primes(100000, i)\r
+    #     for prime in primes:\r
+    #         count += 1\r
+    #         if count % 10000000 == 0:\r
+    #             print(f"i: {int(count / 100000)}")\r
+    #         sums = sums + int(prime)*int(prime)\r
+    #         if sums % count == 0:\r
+    #             lists.append(count)\r
+    #             print(count)\r