Python bindings for Constraint Theory - deterministic geometric snapping with O(log n) KD-tree lookup
Project description
Constraint Theory Python
Your floating-point drift ends here. Snap vectors to exact Pythagorean triples.
๐ฆ pip install constraint-theory | ๐ Live Demo | ๐ Full Docs
๐ฅ The Problem You Know
>>> import numpy as np
>>> v = np.array([3, 4]) / 5
>>> v[0] ** 2 + v[1] ** 2
0.9999999999999999 # "Close enough" for science?
Your physics simulation gives different results on laptop vs. cluster. Your tests flake. Your Monte Carlo won't reproduce.
โจ The Solution
>>> from constraint_theory import PythagoreanManifold
>>> manifold = PythagoreanManifold(200)
>>> manifold.snap(0.6, 0.8)
(0.6, 0.8, 0.0) # Exact. 3/5, 4/5. Zero noise.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ Input: (0.577, 0.816) โ noisy float โ
โ โ โ
โ KD-Tree: O(log n) lookup in Rust โ
โ โ โ
โ Output: (0.6, 0.8) โ exact Pythagorean triple โ
โ = (3/5, 4/5) โ stored as exact rationals โ
โ โ
โ Same result on EVERY machine. Cross-platform guaranteed. โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Install Now
Prerequisites: Python 3.8+
pip install constraint-theory
Try it now (30 seconds):
pip install constraint-theory
python -c "from constraint_theory import PythagoreanManifold; m = PythagoreanManifold(200); x, y, _ = m.snap(0.577, 0.816); print(f'Exact: ({x}, {y})')"
# Output: Exact: (0.6, 0.8)
โก Quick Start (30 Seconds)
from constraint_theory import PythagoreanManifold, generate_triples
# Create manifold (~1000 exact states)
manifold = PythagoreanManifold(density=200)
print(f"Manifold has {manifold.state_count} exact states")
# Output: Manifold has 1013 exact states
# Snap to nearest Pythagorean triple
x, y, noise = manifold.snap(0.577, 0.816)
print(f"Snapped: ({x:.4f}, {y:.4f}), noise: {noise:.6f}")
# Output: Snapped: (0.6000, 0.8000), noise: 0.0236
๐ Code Reduction: 63% Less Code
| Approach | Code | Reproducible | Speed |
|---|---|---|---|
| NumPy (normalize) | 156 chars | Platform-dependent | Fast |
| Constraint Theory | 58 chars | Exact everywhere | ~100ns |
NumPy Approach
# 156 characters - manual normalization
import numpy as np
def normalize(v):
mag = np.linalg.norm(v)
return v / mag
v = np.array([0.6, 0.8])
normalized = normalize(v) # Still floats, still drifts
Constraint Theory Approach
# 58 characters - exact by construction
from constraint_theory import PythagoreanManifold
manifold = PythagoreanManifold(200)
x, y, noise = manifold.snap(0.577, 0.816) # (0.6, 0.8, 0.0236)
๐ข NumPy Integration โ Drop-In Replacement for Normalization
Works seamlessly with your existing NumPy code. Replace v / np.linalg.norm(v) with exact snapping:
import numpy as np
from constraint_theory import PythagoreanManifold
manifold = PythagoreanManifold(200)
# Your old way: v / np.linalg.norm(v) โ floating-point drift
# Your new way: manifold.snap(x, y) โ exact everywhere
vector = np.array([0.577, 0.816])
sx, sy, noise = manifold.snap(vector[0], vector[1])
# Batch snap 10,000 vectors (SIMD optimized in Rust)
angles = np.random.uniform(0, 2 * np.pi, 10000)
vectors = np.column_stack([np.cos(angles), np.sin(angles)])
results = manifold.snap_batch(vectors)
# Convert results to NumPy arrays for analysis
snapped = np.array([[sx, sy] for sx, sy, _ in results])
noises = np.array([noise for _, _, noise in results])
print(f"Mean snapping noise: {noises.mean():.6f}")
print(f"Max snapping noise: {noises.max():.6f}")
# Verify exact unit norm
norms = np.linalg.norm(snapped, axis=1)
print(f"Max norm deviation from 1.0: {np.max(np.abs(norms - 1.0)):.2e}")
# Output: 0.00e+00 (exact!)
๐ Performance Comparison
| Operation | Constraint Theory | scipy.spatial.KDTree | Speedup |
|---|---|---|---|
| Single snap | ~100 ns | ~2 ฮผs | 20x |
| Batch 1,000 | ~74 ฮผs | ~1.5 ms | 20x |
| Batch 10,000 | ~740 ฮผs | ~15 ms | 20x |
| Metric | NumPy Normalize | Constraint Theory |
|---|---|---|
| Precision | Platform-dependent | Exact everywhere |
| Reproducibility | Requires seeding | Deterministic |
| Memory per vector | 16 bytes (2 floats) | 16 bytes (2 floats) |
| Cross-platform | May vary | Identical |
๐ฏ Use Cases
๐งญ Decision Tree: Is This For You?
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Do you use NumPy vectors? โ
โโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโ
โ YES โ
โโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโ
โ Need reproducible results across โ
โ laptop / server / cluster? โ
โโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโ
โ โ โ
โโโโโโผโโโโโ โโโโโโผโโโโโ โโโโโโผโโโโโ
โ YES โ โ NO โ โ MAYBE โ
โโโโโโฌโโโโโ โโโโโโฌโโโโโ โโโโโโฌโโโโโ
โ โ โ
โผ โผ โผ
โโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
โ โ USE โ โ โ Maybe โ โ ? Try โ
โ THIS! โ โ overkill โ โ demos โ
โโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
Machine Learning โ Reproducible Training
from constraint_theory import PythagoreanManifold
import numpy as np
manifold = PythagoreanManifold(500)
def augment_direction(dx, dy):
"""Deterministic data augmentation."""
sx, sy, _ = manifold.snap(dx, dy)
return sx, sy # Same augmentation, any machine, any run
# Paper reviewers can reproduce your exact training runs
Game Development โ Networked Physics
manifold = PythagoreanManifold(150)
def process_player_input(vx, vy):
dx, dy, _ = manifold.snap(vx, vy)
return dx, dy # All clients see identical physics
# No "rubber banding" from FP reconciliation
Scientific Computing โ Monte Carlo
import numpy as np
from constraint_theory import PythagoreanManifold
manifold = PythagoreanManifold(300)
# Snap 10,000 random directions to exact states
np.random.seed(42) # Seed for reproducibility
angles = np.random.uniform(0, 2 * np.pi, 10000)
directions = np.column_stack([np.cos(angles), np.sin(angles)])
results = manifold.snap_batch(directions)
snapped = np.array([[sx, sy] for sx, sy, _ in results])
# Reproducible on any HPC cluster
# Identical results on laptop, server, or cloud
๐ API Reference
PythagoreanManifold(density: int)
Create a manifold with specified density. Higher density = more exact states = finer resolution.
| Density | Approx States | Resolution |
|---|---|---|
| 50 | ~250 | 0.02 |
| 100 | ~500 | 0.01 |
| 200 | ~1000 | 0.005 |
| 500 | ~2500 | 0.002 |
| 1000 | ~5000 | 0.001 |
| Method | Returns | Description |
|---|---|---|
snap(x, y) |
(float, float, float) |
Snap single vector, returns (x, y, noise) |
snap_batch(vectors) |
List[(float, float, float)] |
Batch snap (SIMD optimized) |
state_count |
int |
Number of valid Pythagorean states |
generate_triples(max_c: int)
from constraint_theory import generate_triples
triples = generate_triples(50)
for a, b, c in triples[:5]:
print(f"{a}ยฒ + {b}ยฒ = {c}ยฒ")
# 3ยฒ + 4ยฒ = 5ยฒ
# 5ยฒ + 12ยฒ = 13ยฒ
# 8ยฒ + 15ยฒ = 17ยฒ
โ FAQ
What density should I use?
| Use Case | Recommended Density | Reasoning |
|---|---|---|
| Game physics | 100-200 | Fast lookups, sufficient precision |
| ML augmentation | 200-500 | Balance precision and speed |
| Scientific computing | 500-1000 | Maximum precision needed |
How accurate is the snapping?
Exact. The result is always a perfect Pythagorean triple where xยฒ + yยฒ = 1 exactly.
x, y, noise = manifold.snap(0.577, 0.816)
# x, y are EXACT - xยฒ + yยฒ = 1.0 perfectly
# noise = distance from input to snapped point
Is it thread-safe?
Yes! The Rust core uses immutable data structures.
from concurrent.futures import ThreadPoolExecutor
manifold = PythagoreanManifold(200)
def snap_many(vectors):
return [manifold.snap(x, y) for x, y in vectors]
# Safe for parallel use
with ThreadPoolExecutor(max_workers=8) as executor:
results = list(executor.map(snap_many, chunks))
๐ง Troubleshooting
Common Issues
ImportError: cannot import name 'PythagoreanManifold'
The Rust extension wasn't built or loaded correctly.
# Solution 1: Reinstall from PyPI
pip install --upgrade constraint-theory
# Solution 2: Build from source
git clone https://github.com/SuperInstance/constraint-theory-python
cd constraint-theory-python
pip install maturin
maturin develop --release
TypeError: PythagoreanManifold() takes no keyword arguments
You're using the wrong parameter name.
# WRONG - 'dimensions' doesn't exist
manifold = PythagoreanManifold(dimensions=2)
# CORRECT - use 'density' parameter
manifold = PythagoreanManifold(density=200)
ValueError: density must be positive
Density must be a positive integer.
# WRONG
manifold = PythagoreanManifold(0)
manifold = PythagoreanManifold(-100)
# CORRECT
manifold = PythagoreanManifold(200)
snap_batch() returns unexpected results
Ensure your input is the correct shape.
# WRONG - 1D array
vectors = np.array([0.6, 0.8, 0.707, 0.707])
results = manifold.snap_batch(vectors) # Error!
# CORRECT - Nx2 array
vectors = np.array([[0.6, 0.8], [0.707, 0.707]])
results = manifold.snap_batch(vectors) # Works!
Slow performance on first call
The first manifold creation is slower due to KD-tree construction.
# Solution: Create manifold once and reuse
manifold = PythagoreanManifold(200) # ~10-50ms
# Subsequent calls are fast
for _ in range(100000):
manifold.snap(0.577, 0.816) # ~100ns each
Getting Help
- ๐ API Reference
- ๐ Examples
- ๐ Report Issues
๐ Ecosystem
| Repo | What It Does | Key Features |
|---|---|---|
| constraint-theory-core | ๐ฆ Rust crate | ~100ns snap, SIMD batch, 82 tests |
| constraint-theory-python | ๐ This repo | NumPy integration, PyTorch compatible |
| constraint-theory-web | ๐ Interactive demos | 50 visualizations, zero setup |
| constraint-theory-research | ๐ Mathematical foundations | arXiv paper, proofs, open problems |
| constraint-ranch | ๐ฎ Gamified learning | Puzzle games, agent breeding |
| constraint-flow | ๐ผ Business automation | Exact financial calculations, workflow orchestration |
| constraint-theory-agent | ๐ค Implementation agent | Code audit, refactoring, expert explanations |
Core Rust Library Features
The Python bindings are powered by a Rust core that provides:
- O(log n) KD-tree lookup for nearest-neighbor search
- SIMD optimization for batch processing
- Zero-copy where possible for Python interop
- Thread-safe immutable data structures
See constraint-theory-core for the Rust API.
Web Visualizations
Explore the manifold interactively at constraint-theory-web.pages.dev:
- Visualize Pythagorean triple distribution on the unit circle
- Interactive snapping demonstrations
- Performance comparisons
- Real-time density adjustment
Research Background
This library implements the mathematical framework described in:
- "Deterministic Geometric Snapping via Pythagorean Manifolds" โ core algorithm
- "Cross-Platform Reproducibility in Scientific Computing" โ applications
- See constraint-theory-research for papers
๐ฆ Install from Source
git clone https://github.com/SuperInstance/constraint-theory-python
cd constraint-theory-python
pip install maturin
maturin develop --release
๐ค Contributing
Good First Issues ยท CONTRIBUTING.md
๐ License
MIT โ see LICENSE.
Stop debugging floating-point drift. Your competitors already did.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file constraint_theory-1.0.1.tar.gz.
File metadata
- Download URL: constraint_theory-1.0.1.tar.gz
- Upload date:
- Size: 545.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0551b6875af5a3297113538e62cf2cbdb2d54269febdd6caa85935e082fddbac
|
|
| MD5 |
a1ab50d6a2f9a428ae8b71788d22e2a3
|
|
| BLAKE2b-256 |
bd8528a68bf7050c06675c790583f25a395667b251a4fe50858b80c87228c4cc
|
File details
Details for the file constraint_theory-1.0.1-cp310-cp310-manylinux_2_35_x86_64.whl.
File metadata
- Download URL: constraint_theory-1.0.1-cp310-cp310-manylinux_2_35_x86_64.whl
- Upload date:
- Size: 372.8 kB
- Tags: CPython 3.10, manylinux: glibc 2.35+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
052ee32d6babb6439442051aaca58b6fa09d99f14d8def6d658e3ed2bd1ba9fa
|
|
| MD5 |
04a6ed53e1ded7cc9608d445e2a8cc26
|
|
| BLAKE2b-256 |
53c43a9a321cdfcae4df8141c35c460662503061eaf6999982d1514cec45db98
|