Skip to main content

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.

GitHub stars PyPI version Python Versions License: MIT CI

๐Ÿ“ฆ 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


๐ŸŒŸ 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.

โญ Star this repo ยท Try the live demo

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

constraint_theory-1.0.1.tar.gz (545.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

constraint_theory-1.0.1-cp310-cp310-manylinux_2_35_x86_64.whl (372.8 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.35+ x86-64

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

Hashes for constraint_theory-1.0.1.tar.gz
Algorithm Hash digest
SHA256 0551b6875af5a3297113538e62cf2cbdb2d54269febdd6caa85935e082fddbac
MD5 a1ab50d6a2f9a428ae8b71788d22e2a3
BLAKE2b-256 bd8528a68bf7050c06675c790583f25a395667b251a4fe50858b80c87228c4cc

See more details on using hashes here.

File details

Details for the file constraint_theory-1.0.1-cp310-cp310-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for constraint_theory-1.0.1-cp310-cp310-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 052ee32d6babb6439442051aaca58b6fa09d99f14d8def6d658e3ed2bd1ba9fa
MD5 04a6ed53e1ded7cc9608d445e2a8cc26
BLAKE2b-256 53c43a9a321cdfcae4df8141c35c460662503061eaf6999982d1514cec45db98

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page