"""Cross‑branch pattern mapping and isomorphism (Definition 2.7)."""
import numpy as np
[docs]
class IsomorphismMapper:
"""
Finds and applies structure‑preserving mappings between branch patterns.
"""
def __init__(self, similarity_threshold: float = 0.5):
self.similarity_threshold = similarity_threshold
[docs]
def compute_feature_matrix(self, pattern_state: np.ndarray) -> np.ndarray:
"""
Extract features for matching: use PCA-reduced representation.
"""
if pattern_state.ndim == 1:
pattern_state = pattern_state.reshape(-1, 1)
# Center and reduce dimension
centered = pattern_state - np.mean(pattern_state, axis=0)
if centered.shape[1] > 10:
from sklearn.decomposition import PCA
pca = PCA(n_components=10)
features = pca.fit_transform(centered)
else:
features = centered
return features
[docs]
def find_optimal_mapping(self, state_a: np.ndarray, state_b: np.ndarray) -> np.ndarray:
"""
Find linear mapping M that minimizes ||M·state_a - state_b||.
Returns M (matrix) and similarity score.
"""
# Flatten and ensure same length
a_flat = state_a.flatten()
b_flat = state_b.flatten()
n = min(len(a_flat), len(b_flat))
a_flat = a_flat[:n]
b_flat = b_flat[:n]
# Solve least squares: M * a = b -> M = b * a⁺
# For simplicity, assume diagonal scaling
# Compute optimal scaling factor per dimension
M = np.diag(np.clip(b_flat / (a_flat + 1e-12), -10, 10))
# Residual
residual = np.linalg.norm(M @ a_flat - b_flat)
similarity = 1.0 / (1.0 + residual)
return M, similarity
[docs]
def apply_mapping(self, source_pattern: np.ndarray, mapping: np.ndarray) -> np.ndarray:
"""Apply linear mapping to source pattern."""
flat = source_pattern.flatten()
if mapping.shape[0] != len(flat):
# Adjust mapping size
if mapping.shape[0] > len(flat):
mapping = mapping[: len(flat), : len(flat)]
else:
# Pad with identity
new_mapping = np.eye(len(flat))
new_mapping[: mapping.shape[0], : mapping.shape[0]] = mapping
mapping = new_mapping
transformed = mapping @ flat
return transformed.reshape(source_pattern.shape)
[docs]
def structural_similarity(self, pattern_a: np.ndarray, pattern_b: np.ndarray) -> float:
"""
Compute structural similarity (not just correlation) using feature matching.
"""
feat_a = self.compute_feature_matrix(pattern_a)
feat_b = self.compute_feature_matrix(pattern_b)
# Use cosine similarity of flattened features
if feat_a.size == 0 or feat_b.size == 0:
return 0.0
a_flat = feat_a.flatten()
b_flat = feat_b.flatten()
min_len = min(len(a_flat), len(b_flat))
a_flat = a_flat[:min_len]
b_flat = b_flat[:min_len]
dot = np.dot(a_flat, b_flat)
norm = np.linalg.norm(a_flat) * np.linalg.norm(b_flat)
return dot / (norm + 1e-12)
[docs]
def is_isomorphic(self, pattern_a: np.ndarray, pattern_b: np.ndarray) -> bool:
"""Return True if patterns are structurally isomorphic."""
sim = self.structural_similarity(pattern_a, pattern_b)
return sim >= self.similarity_threshold