Files
blackroad-operating-system/packs/research-lab/math/lucidia_math_lab/prime_explorer.py
Alexa Louise 0108860bff feat: Add Research Lab pack with paralleled math modules
Create comprehensive research-lab pack structure with mathematical
and quantum computing modules from blackroad-prism-console:

Math Modules:
- hilbert_core.py: Hilbert space symbolic reasoning
- collatz/: Distributed Collatz conjecture verification
- linmath/: Linear mathematics C library
- lucidia_math_forge/: Symbolic proof engine
- lucidia_math_lab/: Experimental mathematics

Quantum Modules:
- lucidia_quantum/: Quantum core
- quantum_engine/: Circuit simulation

Experiments:
- br_math/: Gödel gap, quantum experiments

Includes pack.yaml manifest and comprehensive README.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 23:49:03 -06:00

99 lines
2.6 KiB
Python

"""Prime pattern exploration and visualization utilities."""
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
from typing import Tuple
import matplotlib.pyplot as plt
import numpy as np
import sympy as sp
@dataclass
class PrimeVisualizer:
output_dir: Path
def save_fig(self, fig: plt.Figure, name: str) -> None:
self.output_dir.mkdir(parents=True, exist_ok=True)
png = self.output_dir / f"{name}.png"
svg = self.output_dir / f"{name}.svg"
fig.savefig(png)
fig.savefig(svg)
plt.close(fig)
def ulam_spiral(size: int) -> Tuple[np.ndarray, np.ndarray]:
"""Generate an Ulam spiral and mask of prime numbers."""
grid = np.zeros((size, size), dtype=int)
x = y = size // 2
dx, dy = 0, -1
for n in range(1, size * size + 1):
if -size // 2 <= x < size // 2 and -size // 2 <= y < size // 2:
grid[y + size // 2, x + size // 2] = n
if x == y or (x < 0 and x == -y) or (x > 0 and x == 1 - y):
dx, dy = -dy, dx
x, y = x + dx, y + dy
prime_mask = np.vectorize(sp.isprime)(grid)
return grid, prime_mask
def plot_ulam(grid: np.ndarray, mask: np.ndarray) -> plt.Figure:
fig, ax = plt.subplots()
ax.imshow(mask, cmap="Greys")
ax.set_xticks([])
ax.set_yticks([])
return fig
def residue_grid(mod: int, size: int = 100) -> np.ndarray:
"""Compute a modular residue grid.
Parameters
----------
mod:
The modulus used for the residue computation.
size:
Total number of integers to include. ``size`` must be a perfect
square so that the numbers can be reshaped into a square grid.
Raises
------
ValueError
If ``size`` is not a perfect square.
"""
numbers = np.arange(1, size + 1)
side = int(np.sqrt(size))
if side * side != size:
raise ValueError("size must be a perfect square")
return numbers.reshape(side, side) % mod
def plot_residue(grid: np.ndarray) -> plt.Figure:
fig, ax = plt.subplots()
ax.imshow(grid, cmap="viridis")
ax.set_xticks([])
ax.set_yticks([])
return fig
def fourier_prime_gaps(limit: int) -> Tuple[np.ndarray, np.ndarray]:
"""Return prime gaps and their Fourier transform magnitude."""
primes = list(sp.primerange(2, limit))
gaps = np.diff(primes)
fft = np.abs(np.fft.fft(gaps))
return gaps, fft
def plot_fourier(gaps: np.ndarray, fft: np.ndarray) -> plt.Figure:
fig, ax = plt.subplots(2, 1, figsize=(6, 6))
ax[0].plot(gaps)
ax[0].set_title("Prime gaps")
ax[1].plot(fft)
ax[1].set_title("FFT magnitude")
return fig