struqture_py/
lib.rs

1// Copyright © 2021-2023 HQS Quantum Simulations GmbH. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4// in compliance with the License. You may obtain a copy of the License at
5//
6//     http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software distributed under the
9// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
10// express or implied. See the License for the specific language governing permissions and
11// limitations under the License.
12
13use pyo3::prelude::*;
14use pyo3::types::PyDict;
15use pyo3::wrap_pymodule;
16
17pub mod bosons;
18pub mod fermions;
19pub mod mixed_systems;
20pub mod spins;
21
22use thiserror::Error;
23
24/// Errors that can occur in roqoqo.
25#[derive(Debug, Error, PartialEq, Eq)]
26pub enum StruqturePyError {
27    /// Error when remapping qubits fails because qubit in operation is not in keys of BTreeMap.
28    #[error("Failed to convert input to PauliProduct")]
29    ConversionError,
30}
31
32/// Struqture python interface
33///
34/// `HQS Quantum Simulations <https://quantumsimulations.de>`_ package for representing physical operators.
35///
36/// Copyright © 2021-2023 HQS Quantum Simulations GmbH. All Rights Reserved.
37///
38/// .. autosummary::
39///     :toctree: generated/
40///
41///     bosons
42///     fermions
43///     mixed_systems
44///     spins
45///
46#[pymodule]
47fn struqture_py(_py: Python, module: &Bound<PyModule>) -> PyResult<()> {
48    let wrapper1 = wrap_pymodule!(spins::spins);
49    module.add_wrapped(wrapper1)?;
50
51    let wrapper2 = wrap_pymodule!(fermions::fermions);
52    module.add_wrapped(wrapper2)?;
53
54    let wrapper4 = wrap_pymodule!(mixed_systems::mixed_systems);
55    module.add_wrapped(wrapper4)?;
56
57    let wrapper3 = wrap_pymodule!(bosons::bosons);
58    module.add_wrapped(wrapper3)?;
59
60    let system = PyModule::import(_py, "sys")?;
61    let binding = system.getattr("modules")?;
62    let system_modules: &Bound<PyDict> = binding.downcast()?;
63    system_modules.set_item("struqture_py.spins", module.getattr("spins")?)?;
64    system_modules.set_item("struqture_py.fermions", module.getattr("fermions")?)?;
65    system_modules.set_item(
66        "struqture_py.mixed_systems",
67        module.getattr("mixed_systems")?,
68    )?;
69    system_modules.set_item("struqture_py.bosons", module.getattr("bosons")?)?;
70    Ok(())
71}
72
73use num_complex::Complex64;
74use numpy::{IntoPyArray, PyArray1};
75use struqture::CooSparseMatrix;
76
77pub type PyCooMatrix = (
78    Py<PyArray1<Complex64>>,
79    (Py<PyArray1<usize>>, Py<PyArray1<usize>>),
80);
81
82// Simple wrapper function to convert internal COO matrix to a Python compatible form,
83// it expects a CooSparseMatrix so any error handling should be done before using it.
84fn to_py_coo(coo: CooSparseMatrix) -> PyResult<PyCooMatrix> {
85    Python::with_gil(|py| -> PyResult<PyCooMatrix> {
86        let values: Py<PyArray1<Complex64>> = coo.0.into_pyarray(py).into();
87        let rows: Py<PyArray1<usize>> = coo.1 .0.into_pyarray(py).into();
88        let columns: Py<PyArray1<usize>> = coo.1 .1.into_pyarray(py).into();
89        Ok((values, (rows, columns)))
90    })
91}