""" DEPRECATED: Legacy Float HDV Implementation ============================================ This module is DEPRECATED and will be removed in a future version. Use `binary_hdv.BinaryHDV` instead for all new code. Migration notes: - HDV(dimension=N) -> BinaryHDV.random(dimension=N) - hdv.bind(other) -> hdv.xor_bind(other) - hdv.unbind(other) -> hdv.xor_bind(other) # XOR is self-inverse - hdv.cosine_similarity(other) -> hdv.similarity(other) - hdv.permute(shift) -> hdv.permute(shift) This module is kept temporarily for backward compatibility. """ import warnings import numpy as np from dataclasses import dataclass from typing import Optional from .exceptions import DimensionMismatchError @dataclass class HDV: """Holographic Distributed Representation""" vector: Optional[np.ndarray] = None # 10,000-dimensional vector dimension: int = 10000 id: str = None def __post_init__(self): # Emit deprecation warning on instantiation so tests can catch it warnings.warn( "src.core.hdv.HDV is deprecated. Use src.core.binary_hdv.BinaryHDV instead. " "This module will be removed in a future version.", DeprecationWarning, stacklevel=2 ) if self.vector is None: # Initialize with random bipolar vector self.vector = np.random.choice( [-1, 1], size=self.dimension ) elif self.vector.shape[0] != self.dimension: raise DimensionMismatchError( expected=self.dimension, actual=self.vector.shape[0], operation="HDV initialization" ) def __add__(self, other: 'HDV') -> 'HDV': """Superposition: v_A + v_B contains both""" warnings.warn( "HDV.__add__() is deprecated. Use binary_hdv.majority_bundle() instead.", DeprecationWarning, stacklevel=2 ) if self.dimension != other.dimension: raise DimensionMismatchError( expected=self.dimension, actual=other.dimension, operation="superposition" ) return HDV( vector=self.vector + other.vector, dimension=self.dimension ) def __xor__(self, other: 'HDV') -> 'HDV': """Binding: v_A ⊗ v_B (HRR circular convolution) (Deprecated: Use .bind() instead)""" warnings.warn( "HDV.__xor__() is deprecated. Use BinaryHDV.xor_bind() instead.", DeprecationWarning, stacklevel=2 ) return self.bind(other) def bind(self, other: 'HDV') -> 'HDV': """Binding: v_A ⊗ v_B (HRR circular convolution)""" warnings.warn( "HDV.bind() is deprecated. Use BinaryHDV.xor_bind() instead.", DeprecationWarning, stacklevel=2 ) if self.dimension != other.dimension: raise DimensionMismatchError( expected=self.dimension, actual=other.dimension, operation="binding" ) return HDV( vector=self.fft_convolution(self.vector, other.vector), dimension=self.dimension ) def unbind(self, other: 'HDV') -> 'HDV': """Unbinding: v_AB ⊗ v_A* (Approximate inverse)""" warnings.warn( "HDV.unbind() is deprecated. Use BinaryHDV.xor_bind() instead (XOR is self-inverse).", DeprecationWarning, stacklevel=2 ) if self.dimension != other.dimension: raise DimensionMismatchError( expected=self.dimension, actual=other.dimension, operation="unbinding" ) # Unbinding is convolution with involution inv = self.involution(other.vector) return HDV( vector=self.fft_convolution(self.vector, inv), dimension=self.dimension ).normalize() def involution(self, a: np.ndarray) -> np.ndarray: """Involution for HRR: a_i* = a_{(-i mod N)}""" res = np.zeros_like(a) res[0] = a[0] res[1:] = a[:0:-1] return res def permute(self, shift: int = 1) -> 'HDV': """Permutation for sequence/role representation""" warnings.warn( "HDV.permute() is deprecated. Use BinaryHDV.permute() instead.", DeprecationWarning, stacklevel=2 ) return HDV( vector=np.roll(self.vector, shift), dimension=self.dimension ) def cosine_similarity(self, other: 'HDV') -> float: """Measure semantic similarity""" warnings.warn( "HDV.cosine_similarity() is deprecated. Use BinaryHDV.similarity() instead.", DeprecationWarning, stacklevel=2 ) norm_a = np.linalg.norm(self.vector) norm_b = np.linalg.norm(other.vector) if norm_a == 0 or norm_b == 0: return 0.0 return np.dot(self.vector, other.vector) / (norm_a * norm_b) def normalize(self) -> 'HDV': """Binarize for cleaner superposition""" warnings.warn( "HDV.normalize() is deprecated. BinaryHDV vectors are already binary.", DeprecationWarning, stacklevel=2 ) # np.sign returns 0 for 0, we want to avoid 0s in bipolar vectors generally, # but for superposition result it's standard to threshold. # If 0, we can map to 1 or -1, or keep 0 (tertiary). # For strict bipolar, we usually map >=0 to 1, <0 to -1. v = np.sign(self.vector) v[v == 0] = 1 # Handle zero case deterministically return HDV( vector=v.astype(int), dimension=self.dimension ) @staticmethod def fft_convolution(a: np.ndarray, b: np.ndarray) -> np.ndarray: """Circular convolution via FFT (HRR binding)""" warnings.warn( "HDV.fft_convolution() is deprecated. BinaryHDV uses XOR binding instead.", DeprecationWarning, stacklevel=2 ) fft_a = np.fft.fft(a) fft_b = np.fft.fft(b) fft_result = fft_a * fft_b return np.real(np.fft.ifft(fft_result))