qudit_inst/
target.rs

1use qudit_core::ComplexScalar;
2use qudit_core::UnitaryMatrix;
3
4#[derive(Clone)]
5pub enum InstantiationTarget<C: ComplexScalar> {
6    // Ket,
7    // StateSystem
8    // MixedState (Future, but worth thinking about in API)
9    UnitaryMatrix(UnitaryMatrix<C>),
10    // Kraus Operators (Future, but worth thinking about in API)
11}
12
13#[cfg(feature = "python")]
14mod python {
15    use super::InstantiationTarget;
16    use crate::python::PyInstantiationRegistrar;
17    use pyo3::prelude::*;
18    use qudit_core::UnitaryMatrix;
19    use qudit_core::c64;
20
21    #[pyclass(name = "InstantiationTarget")]
22    #[derive(Clone)]
23    pub struct PyInstantiationTarget {
24        inner: InstantiationTarget<c64>,
25    }
26
27    #[pymethods]
28    impl PyInstantiationTarget {
29        #[new]
30        pub fn new<'py>(obj: &Bound<'py, PyAny>) -> PyResult<Self> {
31            // Try to extract as UnitaryMatrix
32            if let Ok(unitary) = obj.extract::<UnitaryMatrix<c64>>() {
33                return Ok(Self {
34                    inner: InstantiationTarget::UnitaryMatrix(unitary),
35                });
36            }
37
38            // if let Ok(ket) = obj.extract::<Ket<c64>>() {
39            //     return Ok(Self {
40            //         inner: InstantiationTarget::Ket(ket),
41            //     });
42            // }
43
44            Err(pyo3::exceptions::PyTypeError::new_err(
45                "Cannot convert object to InstantiationTarget. Expected UnitaryMatrix.",
46            ))
47        }
48
49        pub fn is_unitary_matrix(&self) -> bool {
50            matches!(self.inner, InstantiationTarget::UnitaryMatrix(_))
51        }
52    }
53
54    impl<'py> IntoPyObject<'py> for InstantiationTarget<c64> {
55        type Target = PyInstantiationTarget;
56        type Output = Bound<'py, PyInstantiationTarget>;
57        type Error = PyErr;
58
59        fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
60            let py_target = PyInstantiationTarget { inner: self };
61            Bound::new(py, py_target)
62        }
63    }
64
65    impl<'a, 'py> FromPyObject<'a, 'py> for InstantiationTarget<c64> {
66        type Error = PyErr;
67
68        fn extract(obj: Borrowed<'a, 'py, PyAny>) -> PyResult<Self> {
69            if let Ok(py_target) = obj.extract::<PyInstantiationTarget>() {
70                return Ok(py_target.inner);
71            }
72
73            let py_target = PyInstantiationTarget::new(&obj)?;
74            Ok(py_target.inner)
75        }
76    }
77
78    /// Registers the InstantiationTarget class with the Python module.
79    fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> {
80        parent_module.add_class::<PyInstantiationTarget>()?;
81        Ok(())
82    }
83    inventory::submit!(PyInstantiationRegistrar { func: register });
84}