.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/number_theory/factorization/plot_01_pollard_rho.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_number_theory_factorization_plot_01_pollard_rho.py: Pollard's rho factorization =================================================== Pollard's rho method finds a prime factor :math:`p` of :math:`n` in roughly :math:`\sqrt p` steps, by waiting for a birthday-paradox collision in the sequence :math:`x \mapsto x^2 + 1 \bmod p`. This script factors the Fermat number :math:`F_6 = 2^{64}+1` and plots the step count against the smallest prime factor for a batch of semiprimes. .. GENERATED FROM PYTHON SOURCE LINES 13-18 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from mathematicskit.number_theory import is_prime_miller_rabin, pollard_rho .. GENERATED FROM PYTHON SOURCE LINES 19-21 The sixth Fermat number ----------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 21-25 .. code-block:: Python result = pollard_rho(2**64 + 1) print(f"2^64 + 1 = {result.factor} * {result.cofactor} ({result.iterations} iterations)") .. rst-class:: sphx-glr-script-out .. code-block:: none 2^64 + 1 = 274177 * 67280421310721 (808 iterations) .. GENERATED FROM PYTHON SOURCE LINES 26-28 Steps grow like the square root of the smallest factor ----------------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 28-58 .. code-block:: Python rng = np.random.default_rng(0) def random_prime(lo, hi): while True: n = int(rng.integers(lo, hi)) | 1 if is_prime_miller_rabin(n): return n small_factors, steps = [], [] for bits in range(8, 34, 2): for _ in range(6): p = random_prime(2 ** (bits - 1), 2**bits) q = random_prime(2**40, 2**41) r = pollard_rho(p * q) small_factors.append(min(r.factor, r.cofactor)) steps.append(r.iterations) small_factors, steps = np.array(small_factors), np.array(steps) fig, ax = plt.subplots() ax.loglog(small_factors, steps, "o", alpha=0.6, label="Pollard rho") ref = np.logspace(np.log10(small_factors.min()), np.log10(small_factors.max()), 50) ax.loglog(ref, np.sqrt(np.pi * ref / 2), "--", color="firebrick", label="sqrt(pi p / 2)") ax.set_xlabel("smallest prime factor p") ax.set_ylabel("iterations") ax.set_title("Rho finds p in about sqrt(p) steps") ax.legend() plt.show() .. image-sg:: /api/gallery/number_theory/factorization/images/sphx_glr_plot_01_pollard_rho_001.png :alt: Rho finds p in about sqrt(p) steps :srcset: /api/gallery/number_theory/factorization/images/sphx_glr_plot_01_pollard_rho_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.476 seconds) .. _sphx_glr_download_api_gallery_number_theory_factorization_plot_01_pollard_rho.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_01_pollard_rho.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_01_pollard_rho.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_01_pollard_rho.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_