.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/number_theory/quadratic_residues/plot_01_quadratic_reciprocity.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_quadratic_residues_plot_01_quadratic_reciprocity.py: The law of quadratic reciprocity =================================================== For distinct odd primes :math:`p, q`, :math:`\left(\frac{p}{q}\right)\left(\frac{q}{p}\right) = (-1)^{\frac{p-1}{2}\frac{q-1}{2}}`: whether :math:`p` is a square mod :math:`q` is tied to whether :math:`q` is a square mod :math:`p`. The plot tabulates the Legendre symbol for odd primes below 100; reflecting in the diagonal flips the sign exactly when both primes are :math:`3 \bmod 4`. .. GENERATED FROM PYTHON SOURCE LINES 15-20 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from mathematicskit.number_theory import jacobi_symbol, legendre_symbol, sieve_of_eratosthenes, sqrt_mod .. GENERATED FROM PYTHON SOURCE LINES 21-23 Tabulate (p/q) and check reciprocity ----------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 23-31 .. code-block:: Python primes = [int(p) for p in sieve_of_eratosthenes(100)[1:]] table = np.array([[legendre_symbol(p, q) if p != q else 0 for p in primes] for q in primes]) sign = np.array([[-1 if p % 4 == 3 and q % 4 == 3 else 1 for p in primes] for q in primes]) off_diagonal = ~np.eye(len(primes), dtype=bool) holds = bool(np.all((table * table.T == sign)[off_diagonal])) print("quadratic reciprocity holds for all pairs below 100:", holds) .. rst-class:: sphx-glr-script-out .. code-block:: none quadratic reciprocity holds for all pairs below 100: True .. GENERATED FROM PYTHON SOURCE LINES 32-34 Reciprocity lets the Jacobi symbol be computed without factoring, and Tonelli-Shanks then produces the square root itself. .. GENERATED FROM PYTHON SOURCE LINES 34-48 .. code-block:: Python print(f"(1001 / 9907) = {jacobi_symbol(1001, 9907)}") x = sqrt_mod(10, 13) print(f"sqrt(10) mod 13 = {x} (check: {x}^2 mod 13 = {x * x % 13})") fig, ax = plt.subplots(figsize=(6, 5)) im = ax.imshow(table, cmap="coolwarm", vmin=-1, vmax=1) ax.set_xticks(range(len(primes)), primes, fontsize=6, rotation=90) ax.set_yticks(range(len(primes)), primes, fontsize=6) ax.set_xlabel("p") ax.set_ylabel("q") ax.set_title("Legendre symbol (p / q)") fig.colorbar(im, ax=ax, ticks=[-1, 0, 1]) plt.show() .. image-sg:: /api/gallery/number_theory/quadratic_residues/images/sphx_glr_plot_01_quadratic_reciprocity_001.png :alt: Legendre symbol (p / q) :srcset: /api/gallery/number_theory/quadratic_residues/images/sphx_glr_plot_01_quadratic_reciprocity_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none (1001 / 9907) = -1 sqrt(10) mod 13 = 6 (check: 6^2 mod 13 = 10) .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.046 seconds) .. _sphx_glr_download_api_gallery_number_theory_quadratic_residues_plot_01_quadratic_reciprocity.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_quadratic_reciprocity.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_01_quadratic_reciprocity.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_01_quadratic_reciprocity.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_