use crate::{CausalMultiVector, CausalMultiVectorError, Metric};
use deep_causality_algebra::RealField;
use deep_causality_num::Zero;
use deep_causality_num_complex::Complex;
use deep_causality_tensor::CausalTensor;
use std::fmt::{Display, Formatter};
pub const KET_COLUMN: usize = 0;
#[derive(Debug, Clone, PartialEq)]
pub struct HilbertState<R: RealField> {
mv: CausalMultiVector<Complex<R>>,
}
impl<R: RealField> HilbertState<R> {
pub fn new_spin10(data: Vec<Complex<R>>) -> Result<Self, CausalMultiVectorError> {
let metric = Metric::NonEuclidean(10);
let mv = CausalMultiVector::new(data, metric)?;
Ok(Self { mv })
}
pub fn new(data: Vec<Complex<R>>, metric: Metric) -> Result<Self, CausalMultiVectorError> {
let mv = CausalMultiVector::new(data, metric)?;
Ok(Self { mv })
}
pub fn new_unchecked(data: Vec<Complex<R>>, metric: Metric) -> Self {
let mv = CausalMultiVector::unchecked(data, metric);
Self { mv }
}
pub fn from_multivector(mv: CausalMultiVector<Complex<R>>) -> Self {
Self { mv }
}
pub fn into_inner(self) -> CausalMultiVector<Complex<R>> {
self.mv
}
pub fn as_inner(&self) -> &CausalMultiVector<Complex<R>> {
&self.mv
}
pub fn mv(&self) -> &CausalMultiVector<Complex<R>> {
&self.mv
}
}
impl<R: RealField + Default> HilbertState<R> {
pub fn to_ket(&self) -> Result<CausalTensor<Complex<R>>, CausalMultiVectorError> {
let metric = self.mv.metric();
let n = metric.dimension();
if !n.is_multiple_of(2) {
return Err(CausalMultiVectorError::dimension_mismatch(n + 1, n));
}
let half = n / 2;
if half >= usize::BITS as usize {
return Err(CausalMultiVectorError::dimension_mismatch(n, n));
}
let d = 1usize << half;
if d.checked_mul(d).is_none() {
return Err(CausalMultiVectorError::dimension_mismatch(n, n));
}
let m = self.mv.to_matrix();
let slice = m.as_slice();
let mut d_r = R::zero();
for _ in 0..d {
d_r += R::one();
}
let inv_sqrt_d = R::one() / d_r.sqrt();
let col: Vec<Complex<R>> = (0..d)
.map(|i| {
let c = slice[i * d + KET_COLUMN];
Complex::new(c.re * inv_sqrt_d, c.im * inv_sqrt_d)
})
.collect();
Ok(CausalTensor::from_slice(&col, &[d, 1]))
}
pub fn from_ket(
ket: &CausalTensor<Complex<R>>,
metric: Metric,
) -> Result<Self, CausalMultiVectorError> {
let n = metric.dimension();
if !n.is_multiple_of(2) {
return Err(CausalMultiVectorError::dimension_mismatch(n + 1, n));
}
let half = n / 2;
if half >= usize::BITS as usize {
return Err(CausalMultiVectorError::dimension_mismatch(n, n));
}
let d = 1usize << half;
if d.checked_mul(d).is_none() {
return Err(CausalMultiVectorError::dimension_mismatch(n, n));
}
let shape = ket.shape();
if !(shape == [d] || shape == [d, 1]) {
return Err(CausalMultiVectorError::data_length_mismatch(
d,
ket.as_slice().len(),
));
}
let mut d_r = R::zero();
for _ in 0..d {
d_r += R::one();
}
let sqrt_d = d_r.sqrt();
let mut data = vec![Complex::zero(); d * d];
for (i, c) in ket.as_slice().iter().enumerate() {
data[i * d + KET_COLUMN] = Complex::new(c.re * sqrt_d, c.im * sqrt_d);
}
let matrix = CausalTensor::from_slice(&data, &[d, d]);
Ok(Self {
mv: CausalMultiVector::from_matrix(matrix, metric),
})
}
}
impl<R: RealField> Default for HilbertState<R> {
fn default() -> Self {
let metric = Metric::Euclidean(0);
let data = vec![Complex::zero()];
let mv = CausalMultiVector::new(data.clone(), metric)
.unwrap_or(CausalMultiVector::unchecked(data, metric));
Self { mv }
}
}
impl<R: RealField> core::ops::Add for HilbertState<R> {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self {
mv: self.mv + rhs.mv,
}
}
}
impl<R: RealField> core::ops::Mul<Complex<R>> for HilbertState<R> {
type Output = Self;
fn mul(self, rhs: Complex<R>) -> Self::Output {
Self { mv: self.mv * rhs }
}
}
impl<R: RealField + core::fmt::Debug> Display for HilbertState<R> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.mv)
}
}