use crate::{CausalMultiVector, CausalMultiVectorError, HilbertState, Metric, MultiVector};
use deep_causality_num::{Complex, FromPrimitive, RealField};
use std::fmt::{Display, Formatter};
#[derive(Debug, Clone, PartialEq)]
pub struct HopfState<R: RealField>(CausalMultiVector<R>);
impl<R: RealField> HopfState<R> {
pub fn new(data: Vec<R>) -> Result<Self, CausalMultiVectorError> {
let metric = Metric::Euclidean(3);
if data.len() != 8 {
return Err(CausalMultiVectorError::data_length_mismatch(8, data.len()));
}
let mv = CausalMultiVector::new(data, metric)?;
let normalized = mv.normalize();
Ok(Self(normalized))
}
pub fn from_spinor(alpha: Complex<R>, beta: Complex<R>) -> Self {
let mut data = vec![R::zero(); 8];
data[0] = alpha.re;
data[3] = alpha.im; data[5] = beta.im; data[6] = beta.re;
let mv = CausalMultiVector::new(data, Metric::Euclidean(3)).unwrap();
Self(mv.normalize())
}
pub fn as_inner(&self) -> &CausalMultiVector<R> {
&self.0
}
}
impl<R: RealField + FromPrimitive> HopfState<R> {
pub fn project(&self) -> CausalMultiVector<R> {
let mut z_data = vec![R::zero(); 8];
z_data[4] = R::one(); let sigma_3 = CausalMultiVector::new(z_data, Metric::Euclidean(3)).unwrap();
let r = &self.0;
let r_rev = r.reversion();
let temp = r.geometric_product(&sigma_3);
let vector = temp.geometric_product(&r_rev);
vector.grade_projection(1)
}
pub fn fiber_shift(&self, angle_rad: R) -> Self {
let mut bivec_data = vec![R::zero(); 8];
bivec_data[3] = R::one(); let generator = CausalMultiVector::new(bivec_data, Metric::Euclidean(3)).unwrap();
let half = R::from_f64(0.5).expect("R::from_f64(0.5) failed");
let half_angle = angle_rad * half;
let cos = half_angle.cos();
let sin = half_angle.sin();
let term_sin = generator * (-sin);
let term_cos = CausalMultiVector::scalar(cos, Metric::Euclidean(3));
let phase_rotor = term_cos + term_sin;
let new_mv = self.0.geometric_product(&phase_rotor);
Self(new_mv)
}
}
impl<R: RealField> TryFrom<&HilbertState<R>> for HopfState<R> {
type Error = CausalMultiVectorError;
fn try_from(quantum_state: &HilbertState<R>) -> Result<Self, Self::Error> {
let data = &quantum_state.as_inner().data;
if data.len() < 2 {
return Err(CausalMultiVectorError::dimension_mismatch(2, data.len()));
}
let alpha = data[0];
let beta = data[1];
Ok(HopfState::from_spinor(alpha, beta))
}
}
impl<R: RealField> TryFrom<HopfState<R>> for HilbertState<R> {
type Error = CausalMultiVectorError;
fn try_from(hopf: HopfState<R>) -> Result<Self, Self::Error> {
let d = hopf.as_inner().data();
let re_alpha = d[0]; let im_alpha = d[3]; let alpha = Complex::new(re_alpha, im_alpha);
let re_beta = d[6]; let im_beta = d[5]; let beta = Complex::new(re_beta, im_beta);
let mut q_data = vec![Complex::new(R::zero(), R::zero()); 1024];
q_data[0] = alpha;
q_data[1] = beta;
HilbertState::new_spin10(q_data)
}
}
impl<R: RealField + core::fmt::Debug> Display for HopfState<R> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "HopfState({:?})", self.0)
}
}