Source code for mercurial.branches.isomorphism

"""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