#![allow(clippy::missing_const_for_fn)]
pub mod bloch;
pub mod density_bars;
pub mod husimi;
pub mod qsphere;
pub mod wigner;
#[cfg(feature = "python")]
use pyo3::prelude::*;
#[cfg(feature = "python")]
use scirs2_core::ndarray::Array1;
#[cfg(feature = "python")]
use scirs2_core::Complex64;
pub fn make_plotly_html(plotly_json: &str) -> String {
format!(
r#"<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>QuantRS2 Quantum State Visualization</title>
<script src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script>
<style>
body {{ margin: 0; padding: 10px; font-family: Arial, sans-serif; }}
#plot {{ width: 100%; height: calc(100vh - 20px); }}
</style>
</head>
<body>
<div id="plot"></div>
<script>
var figure = {json};
Plotly.newPlot('plot', figure.data, figure.layout, {{responsive: true}});
</script>
</body>
</html>"#,
json = plotly_json
)
}
#[cfg(feature = "python")]
#[pyclass(name = "QuantumState3DVisualizer")]
pub struct PyQuantumState3DVisualizer {
state: Array1<Complex64>,
n_qubits: usize,
}
#[cfg(feature = "python")]
#[pymethods]
impl PyQuantumState3DVisualizer {
#[new]
pub fn new(state_amplitudes: Vec<(f64, f64)>, n_qubits: usize) -> PyResult<Self> {
let expected = 1usize << n_qubits;
if state_amplitudes.len() != expected {
return Err(pyo3::exceptions::PyValueError::new_err(format!(
"state_amplitudes length {} does not match 2^{} = {}",
state_amplitudes.len(),
n_qubits,
expected
)));
}
let state: Array1<Complex64> = state_amplitudes
.into_iter()
.map(|(re, im)| Complex64::new(re, im))
.collect();
Ok(Self { state, n_qubits })
}
pub fn bloch_array_html(&self) -> PyResult<String> {
let json = bloch::bloch_array_plotly_json(&self.state, self.n_qubits)
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
Ok(make_plotly_html(&json))
}
pub fn qsphere_html(&self) -> PyResult<String> {
let json = qsphere::qsphere_plotly_json(&self.state, self.n_qubits)
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
Ok(make_plotly_html(&json))
}
pub fn wigner_html(&self) -> PyResult<String> {
let json = wigner::wigner_plotly_json(&self.state, self.n_qubits)
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
Ok(make_plotly_html(&json))
}
pub fn husimi_html(&self) -> PyResult<String> {
let json = husimi::husimi_plotly_json(&self.state, self.n_qubits)
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
Ok(make_plotly_html(&json))
}
pub fn density_bars_html(&self) -> PyResult<String> {
let json = density_bars::density_matrix_bars_plotly_json(&self.state, self.n_qubits)
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
Ok(make_plotly_html(&json))
}
pub fn __repr__(&self) -> String {
format!(
"QuantumState3DVisualizer(n_qubits={}, dim={})",
self.n_qubits,
self.state.len()
)
}
}