use crate::{
error::catch_quest_exception,
ffi,
Qreal,
QuestError,
};
#[derive(Debug, Clone, Copy)]
pub struct ComplexMatrix2(pub(crate) ffi::ComplexMatrix2);
impl ComplexMatrix2 {
#[must_use]
pub fn new(
real: [[Qreal; 2]; 2],
imag: [[Qreal; 2]; 2],
) -> Self {
Self(ffi::ComplexMatrix2 {
real,
imag,
})
}
}
#[derive(Debug)]
pub struct ComplexMatrix4(pub(crate) ffi::ComplexMatrix4);
impl ComplexMatrix4 {
#[must_use]
pub fn new(
real: [[Qreal; 4]; 4],
imag: [[Qreal; 4]; 4],
) -> Self {
Self(ffi::ComplexMatrix4 {
real,
imag,
})
}
}
#[derive(Debug)]
pub struct ComplexMatrixN(pub(crate) ffi::ComplexMatrixN);
impl ComplexMatrixN {
pub fn try_new(num_qubits: i32) -> Result<Self, QuestError> {
catch_quest_exception(|| {
Self(unsafe { ffi::createComplexMatrixN(num_qubits) })
})
}
pub fn num_qubits(&self) -> i32 {
self.0.numQubits
}
#[must_use]
pub fn row_real_as_slice(
&self,
i: usize,
) -> &[Qreal] {
assert!(i < 1 << self.0.numQubits);
unsafe {
std::slice::from_raw_parts(
*(self.0.real).add(i),
(1 << self.0.numQubits) as usize,
)
}
}
pub fn row_real_as_mut_slice(
&mut self,
i: usize,
) -> &mut [Qreal] {
unsafe {
std::slice::from_raw_parts_mut(
*(self.0.real).add(i),
(1 << self.0.numQubits) as usize,
)
}
}
#[must_use]
pub fn row_imag_as_slice(
&self,
i: usize,
) -> &[Qreal] {
unsafe {
std::slice::from_raw_parts(
*(self.0.imag).add(i),
(1 << self.0.numQubits) as usize,
)
}
}
pub fn row_imag_as_mut_slice(
&mut self,
i: usize,
) -> &mut [Qreal] {
unsafe {
std::slice::from_raw_parts_mut(
*(self.0.imag).add(i),
(1 << self.0.numQubits) as usize,
)
}
}
}
impl Drop for ComplexMatrixN {
fn drop(&mut self) {
catch_quest_exception(|| unsafe { ffi::destroyComplexMatrixN(self.0) })
.unwrap();
}
}
#[derive(Debug)]
pub struct Vector(pub(crate) ffi::Vector);
impl Vector {
#[must_use]
pub fn new(
x: Qreal,
y: Qreal,
z: Qreal,
) -> Self {
Self(ffi::Vector {
x,
y,
z,
})
}
}
#[allow(clippy::cast_sign_loss)]
#[allow(clippy::needless_pass_by_ref_mut)]
pub fn init_complex_matrix_n(
m: &mut ComplexMatrixN,
real: &[&[Qreal]],
imag: &[&[Qreal]],
) -> Result<(), QuestError> {
let num_elems = 1 << m.0.numQubits;
if real.len() < num_elems || imag.len() < num_elems {
return Err(QuestError::ArrayLengthError);
}
for i in 0..num_elems {
if real[i].len() < num_elems || imag[i].len() < num_elems {
return Err(QuestError::ArrayLengthError);
}
}
for i in 0..num_elems {
for j in 0..num_elems {
unsafe {
*(*m.0.real.add(i)).add(j) = real[i][j];
*(*m.0.imag.add(i)).add(j) = imag[i][j];
}
}
}
Ok(())
}