mirror of
https://github.com/allaunthefox/SilverSight.git
synced 2026-07-31 01:25:21 +00:00
Rust fixes: - Remove Q0_16 Not arm (was silently returning Bool(false) instead of type error) - Replace inline floor division with floor_div() calls in MulSatQ16/DivSatQ16 - Fix comment ranges for Q0_16 [-32767, 32767] and Q16_16 [-2147483647, 2147483647] Go fixes: - Add euclideanDiv() matching Lean Int.ediv (remainder ≥ 0) - Use euclideanDiv for MulSatQ16 and DivSatQ16 - Change Locals from []*Val to []Val (dangling pointer fix) - Step on halted state returns &s, nil (Lean returns Ok s) - OOB PC returns error instead of silent halt - Halt does not increment PC (Lean: PC unchanged) All Go tests pass (9/9)
180 lines
No EOL
5.7 KiB
Python
180 lines
No EOL
5.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
HopfDNA Fiber Analysis — Count exotic classes via S³ fiber structure
|
|
|
|
The 28 exotic spheres are NOT features of the S⁴ base.
|
|
They are TWISTS in the S³ FIBER over each base point.
|
|
|
|
For each S⁴ projection (base point), collect all DNA sequences
|
|
that map to it. Their fiber coordinates (the S³ = SU(2) element)
|
|
should show exactly 28 distinct twist patterns.
|
|
|
|
This is the correct topological approach: the 28 lives in the fiber.
|
|
"""
|
|
|
|
import math
|
|
import itertools
|
|
from collections import defaultdict
|
|
|
|
DNA_TO_Q = {
|
|
'A': (1, 0, 0, 0),
|
|
'C': (0, 1, 0, 0),
|
|
'G': (0, 0, 1, 0),
|
|
'T': (0, 0, 0, 1),
|
|
}
|
|
|
|
def quat_mul(a, b):
|
|
a1, a2, a3, a4 = a
|
|
b1, b2, b3, b4 = b
|
|
return (
|
|
a1*b1 - a2*b2 - a3*b3 - a4*b4,
|
|
a1*b2 + a2*b1 + a3*b4 - a4*b3,
|
|
a1*b3 - a2*b4 + a3*b1 + a4*b2,
|
|
a1*b4 + a2*b3 - a3*b2 + a4*b1,
|
|
)
|
|
|
|
def quat_conj(q):
|
|
return (q[0], -q[1], -q[2], -q[3])
|
|
|
|
def quat_norm_sq(q):
|
|
return q[0]**2 + q[1]**2 + q[2]**2 + q[3]**2
|
|
|
|
def quat_inv(q):
|
|
ns = quat_norm_sq(q)
|
|
if ns == 0: return None
|
|
c = quat_conj(q)
|
|
return tuple(x/ns for x in c)
|
|
|
|
def quat_div(a, b):
|
|
bi = quat_inv(b)
|
|
if bi is None: return None
|
|
return quat_mul(a, bi)
|
|
|
|
def dna_to_s7(seq):
|
|
def bases_to_quat(bases):
|
|
q = [0.0, 0.0, 0.0, 0.0]
|
|
for b in bases:
|
|
v = DNA_TO_Q[b]
|
|
q[0] += v[0]; q[1] += v[1]; q[2] += v[2]; q[3] += v[3]
|
|
return tuple(q)
|
|
q1 = bases_to_quat(seq[:4])
|
|
q2 = bases_to_quat(seq[4:])
|
|
n1 = quat_norm_sq(q1)
|
|
n2 = quat_norm_sq(q2)
|
|
total = n1 + n2
|
|
if total == 0: return ((1,0,0,0), (0,0,0,1))
|
|
scale = math.sqrt(total)
|
|
return (tuple(x/scale for x in q1), tuple(x/scale for x in q2))
|
|
|
|
def hopf_map(s7_point):
|
|
q1, q2 = s7_point
|
|
return quat_div(q1, q2)
|
|
|
|
def fiber_coordinate(s7_point):
|
|
"""
|
|
The FIBER coordinate of (q1, q2) ∈ S⁷ over base π(q1,q2) = q1/q2.
|
|
|
|
Two points (q1,q2) and (q1',q2') are in the same fiber iff
|
|
q1/q2 = q1'/q2', i.e., q1*q2⁻¹ = q1'*q2'⁻¹.
|
|
|
|
The fiber element is λ = q2/|q2| ∈ S³ (the phase of q2).
|
|
This is the SU(2) rotation that distinguishes exotic classes.
|
|
"""
|
|
q1, q2 = s7_point
|
|
n2 = math.sqrt(quat_norm_sq(q2))
|
|
if n2 < 1e-15:
|
|
return (1, 0, 0, 0) # identity at infinity
|
|
return tuple(x/n2 for x in q2)
|
|
|
|
def fiber_distance(a, b):
|
|
"""S³ = SU(2) distance: chordal distance on the 3-sphere."""
|
|
return math.sqrt(sum((a[i] - b[i])**2 for i in range(4)))
|
|
|
|
def s4_key(p, precision=4):
|
|
"""Canonical S⁴ key for grouping points in the same fiber."""
|
|
if p is None:
|
|
return None
|
|
if p[0] < 0:
|
|
return tuple(round(-x, precision) for x in p)
|
|
return tuple(round(x, precision) for x in p)
|
|
|
|
def main():
|
|
print("=" * 60)
|
|
print("HopfDNA Fiber Analysis — 28 exotic classes via S³ fiber")
|
|
print("=" * 60)
|
|
|
|
bases = ['A', 'C', 'G', 'T']
|
|
all_seqs = [''.join(p) for p in itertools.product(bases, repeat=8)]
|
|
print(f"\nTotal sequences: {len(all_seqs)}")
|
|
|
|
# Group sequences by S⁴ base point (fiber)
|
|
base_to_fibers = defaultdict(list)
|
|
for seq in all_seqs:
|
|
s7 = dna_to_s7(seq)
|
|
s4 = hopf_map(s7)
|
|
fiber = fiber_coordinate(s7)
|
|
key = s4_key(s4)
|
|
base_to_fibers[key].append(fiber)
|
|
|
|
print(f"Distinct S⁴ base points: {len(base_to_fibers)}")
|
|
|
|
# For each base point, count distinct fiber elements
|
|
total_fiber_elements = set()
|
|
base_fiber_counts = []
|
|
|
|
for base_key, fibers in base_to_fibers.items():
|
|
# Deduplicate fiber elements within this base point
|
|
unique_fibers = set()
|
|
for f in fibers:
|
|
# Round fiber coordinates
|
|
fr = tuple(round(x, 3) for x in f)
|
|
unique_fibers.add(fr)
|
|
base_fiber_counts.append(len(unique_fibers))
|
|
for uf in unique_fibers:
|
|
total_fiber_elements.add((base_key, uf))
|
|
|
|
print(f"\nFiber analysis:")
|
|
print(f" Total (base, fiber) pairs: {len(total_fiber_elements)}")
|
|
print(f" Avg fibers per base: {sum(base_fiber_counts)/len(base_fiber_counts):.1f}")
|
|
print(f" Max fibers per base: {max(base_fiber_counts)}")
|
|
print(f" Min fibers per base: {min(base_fiber_counts)}")
|
|
|
|
# Cluster ALL fiber elements globally
|
|
# The 28 exotic classes should appear as clusters in the fiber S³
|
|
all_fibers = list(total_fiber_elements)
|
|
fiber_points = [f for (_, f) in all_fibers]
|
|
|
|
print(f"\n Total distinct fiber elements: {len(fiber_points)}")
|
|
|
|
# Cluster fiber elements via single-linkage on S³
|
|
print(f"\n S³ fiber clustering (single-linkage):")
|
|
for eps in [0.5, 0.8, 1.0, 1.2, 1.3, 1.4, 1.41, 1.42, 1.5, 1.6, 1.8, 2.0]:
|
|
n = len(fiber_points)
|
|
parent = list(range(n))
|
|
def find(x):
|
|
while parent[x] != x:
|
|
parent[x] = parent[parent[x]]
|
|
x = parent[x]
|
|
return x
|
|
def union(x, y):
|
|
parent[find(x)] = find(y)
|
|
for i in range(min(n, 5000)): # subsample for speed
|
|
for j in range(i+1, min(n, 5000)):
|
|
d = fiber_distance(fiber_points[i], fiber_points[j])
|
|
if d < eps:
|
|
union(i, j)
|
|
comps = len(set(find(i) for i in range(min(n, 5000))))
|
|
marker = " ◄═══ 28" if comps == 28 else ""
|
|
print(f" eps={eps:.2f}: {comps} clusters{marker}")
|
|
|
|
# Also try: count distinct fiber elements per base,
|
|
# then look at the DISTRIBUTION of these counts
|
|
count_dist = Counter(base_fiber_counts)
|
|
print(f"\n Distribution of fiber counts per base:")
|
|
for count, freq in sorted(count_dist.items()):
|
|
print(f" {count} fibers: {freq} base points")
|
|
|
|
print(f"\n{'═' * 60}")
|
|
|
|
if __name__ == "__main__":
|
|
main() |