use ndarray::{array, Array2};
use num_complex::Complex64;
use qoqo_calculator::CalculatorFloat;
use std::convert::TryFrom;
use std::f64::consts::PI;
use crate::operations::{
InvolveQubits, InvolvedQubits, Operate, OperateGate, OperateSingleQubit,
OperateSingleQubitGate, Rotate, Substitute, SupportedVersion,
};
use crate::RoqoqoError;
#[cfg(feature = "overrotate")]
use rand_distr::{Distribution, Normal};
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct SingleQubitGate {
qubit: usize,
alpha_r: CalculatorFloat,
alpha_i: CalculatorFloat,
beta_r: CalculatorFloat,
beta_i: CalculatorFloat,
global_phase: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_SingleQubitGate: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"SingleQubitGate",
];
impl OperateGate for SingleQubitGate {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let alpha_r: f64 = f64::try_from(self.alpha_r())?;
let alpha_i: f64 = f64::try_from(self.alpha_i())?;
let beta_r: f64 = f64::try_from(self.beta_r())?;
let beta_i: f64 = f64::try_from(self.beta_i())?;
let global_phase: f64 = f64::try_from(self.global_phase())?;
if alpha_r == 0.0 && alpha_i == 0.0 && beta_r == 0.0 && beta_i == 0.0
|| (alpha_r.powf(2.0) + alpha_i.powf(2.0) + beta_r.powf(2.0) + beta_i.powf(2.0) - 1.0)
.abs()
> 1e-6
{
let norm: f64 =
alpha_r.powf(2.0) + alpha_i.powf(2.0) + beta_r.powf(2.0) + beta_i.powf(2.0);
Err(RoqoqoError::UnitaryMatrixErrror {
alpha_r,
alpha_i,
beta_r,
beta_i,
norm,
})
} else {
let pref = Complex64::new(0.0, global_phase).exp();
Ok(array![
[
pref * Complex64::new(alpha_r, alpha_i),
pref * Complex64::new(-beta_r, beta_i)
],
[
pref * Complex64::new(beta_r, beta_i),
pref * Complex64::new(alpha_r, -alpha_i)
]
])
}
}
}
impl OperateSingleQubitGate for SingleQubitGate {
fn alpha_r(&self) -> CalculatorFloat {
self.alpha_r.clone()
}
fn alpha_i(&self) -> CalculatorFloat {
self.alpha_i.clone()
}
fn beta_r(&self) -> CalculatorFloat {
self.beta_r.clone()
}
fn beta_i(&self) -> CalculatorFloat {
self.beta_i.clone()
}
fn global_phase(&self) -> CalculatorFloat {
self.global_phase.clone()
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::Rotate,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct RotateZ {
qubit: usize,
theta: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_RotateZ: &[&str; 5] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"Rotation",
"RotateZ",
];
impl OperateGate for RotateZ {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let c: f64 = (f64::try_from(self.theta.clone())? / 2.0).cos();
let s: f64 = (f64::try_from(self.theta.clone())? / 2.0).sin();
Ok(array![
[Complex64::new(c, -s), Complex64::new(0.0, 0.0)],
[Complex64::new(0.0, 0.0), Complex64::new(c, s)]
])
}
}
impl OperateSingleQubitGate for RotateZ {
fn alpha_r(&self) -> CalculatorFloat {
(self.theta.clone() / 2.0).cos()
}
fn alpha_i(&self) -> CalculatorFloat {
(self.theta.clone() / 2.0).sin() * (-1.0)
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::Rotate,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct RotateX {
qubit: usize,
theta: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_RotateX: &[&str; 5] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"Rotation",
"RotateX",
];
impl OperateGate for RotateX {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let c: f64 = (f64::try_from(self.theta.clone())? / 2.0).cos();
let s: f64 = (f64::try_from(self.theta.clone())? / 2.0).sin();
Ok(array![
[Complex64::new(c, 0.0), Complex64::new(0.0, -s)],
[Complex64::new(0.0, -s), Complex64::new(c, 0.0)]
])
}
}
impl OperateSingleQubitGate for RotateX {
fn alpha_r(&self) -> CalculatorFloat {
(self.theta.clone() / 2.0).cos()
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
(self.theta.clone() / 2.0).sin() * (-1.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::Rotate,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct RotateY {
qubit: usize,
theta: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_RotateY: &[&str; 5] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"Rotation",
"RotateY",
];
impl OperateGate for RotateY {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let c: f64 = (f64::try_from(self.theta.clone())? / 2.0).cos();
let s: f64 = (f64::try_from(self.theta.clone())? / 2.0).sin();
Ok(array![
[Complex64::new(c, 0.0), Complex64::new(-s, 0.0)],
[Complex64::new(s, 0.0), Complex64::new(c, 0.0)]
])
}
}
impl OperateSingleQubitGate for RotateY {
fn alpha_r(&self) -> CalculatorFloat {
(self.theta.clone() / 2.0).cos()
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
(self.theta.clone() / 2.0).sin()
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PauliX {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_PauliX: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"PauliX",
];
impl OperateGate for PauliX {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
Ok(array![
[Complex64::new(0.0, 0.0), Complex64::new(1.0, 0.0)],
[Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0)]
])
}
}
impl OperateSingleQubitGate for PauliX {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(-1.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from((PI) / 2.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PauliY {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_PauliY: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"PauliY",
];
impl OperateGate for PauliY {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
Ok(array![
[Complex64::new(0.0, 0.0), Complex64::new(0.0, -1.0)],
[Complex64::new(0.0, 1.0), Complex64::new(0.0, 0.0)]
])
}
}
impl OperateSingleQubitGate for PauliY {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(1.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(PI / 2.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PauliZ {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_PauliZ: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"PauliZ",
];
impl OperateGate for PauliZ {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
Ok(array![
[Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0)],
[Complex64::new(0.0, 0.0), Complex64::new(-1.0, 0.0)]
])
}
}
impl OperateSingleQubitGate for PauliZ {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(-1.0)
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(PI / 2.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct SqrtPauliX {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_SqrtPauliX: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"SqrtPauliX",
];
impl OperateGate for SqrtPauliX {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let theta: f64 = PI / 2.0;
let c: f64 = (theta / 2.0).cos();
let s: f64 = (theta / 2.0).sin();
Ok(array![
[Complex64::new(c, 0.0), Complex64::new(0.0, -s)],
[Complex64::new(0.0, -s), Complex64::new(c, 0.0)]
])
}
}
impl OperateSingleQubitGate for SqrtPauliX {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from((PI / 4.0).cos())
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(-(PI / 4.0).sin())
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct InvSqrtPauliX {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_InvSqrtPauliX: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"InvSqrtPauliX",
];
impl OperateGate for InvSqrtPauliX {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let theta: f64 = PI / 2.0;
let c: f64 = (theta / 2.0).cos();
let s: f64 = (theta / 2.0).sin();
Ok(array![
[Complex64::new(c, 0.0), Complex64::new(0.0, 1.0 * s)],
[Complex64::new(0.0, 1.0 * s), Complex64::new(c, 0.0)]
])
}
}
impl OperateSingleQubitGate for InvSqrtPauliX {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from((PI / 4.0).cos())
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from((PI / 4.0).sin())
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct Hadamard {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_Hadamard: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"Hadamard",
];
impl OperateGate for Hadamard {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let f: f64 = 1.0 / ((2.0_f64).sqrt());
Ok(array![
[Complex64::new(f, 0.0), Complex64::new(f, 0.0)],
[Complex64::new(f, 0.0), Complex64::new(-f, 0.0)]
])
}
}
impl OperateSingleQubitGate for Hadamard {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(-1.0 / ((2.0_f64).sqrt()))
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(-1.0 / ((2.0_f64).sqrt()))
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(PI / 2.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct SGate {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_SGate: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"SGate",
];
impl OperateGate for SGate {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
Ok(array![
[Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0)],
[Complex64::new(0.0, 0.0), Complex64::new(0.0, 1.0)]
])
}
}
impl OperateSingleQubitGate for SGate {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from(1.0 / ((2.0_f64).sqrt()))
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(-1.0 / ((2.0_f64).sqrt()))
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(PI / 4.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct TGate {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_TGate: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"TGate",
];
impl OperateGate for TGate {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
Ok(array![
[Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0)],
[
Complex64::new(0.0, 0.0),
Complex64::new((PI / 4.0).cos(), (PI / 4.0).sin())
] ])
}
}
impl OperateSingleQubitGate for TGate {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from((PI / 8.0).cos())
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(-(PI / 8.0).sin())
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(PI / 8.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::Rotate,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PhaseShiftState1 {
qubit: usize,
theta: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_PhaseShiftState1: &[&str; 5] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"Rotation",
"PhaseShiftState1",
];
impl OperateGate for PhaseShiftState1 {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let theta: f64 = f64::try_from(self.theta().clone())?;
Ok(array![
[Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0)],
[
Complex64::new(0.0, 0.0),
Complex64::new(theta.cos(), theta.sin())
]
])
}
}
impl OperateSingleQubitGate for PhaseShiftState1 {
fn alpha_r(&self) -> CalculatorFloat {
(self.theta().clone() / 2.0).cos()
}
fn alpha_i(&self) -> CalculatorFloat {
(self.theta().clone() / 2.0).sin() * (-1.0)
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn global_phase(&self) -> CalculatorFloat {
self.theta().clone() / 2.0
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::Rotate,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PhaseShiftState0 {
qubit: usize,
theta: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_PhaseShiftState0: &[&str; 5] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"Rotation",
"PhaseShiftState0",
];
impl OperateGate for PhaseShiftState0 {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let theta: f64 = f64::try_from(self.theta().clone())?;
Ok(array![
[
Complex64::new(theta.cos(), theta.sin()),
Complex64::new(0.0, 0.0)
],
[Complex64::new(0.0, 0.0), Complex64::new(1.0, 0.0)]
])
}
}
impl OperateSingleQubitGate for PhaseShiftState0 {
fn alpha_r(&self) -> CalculatorFloat {
(self.theta().clone() / 2.0).cos()
}
fn alpha_i(&self) -> CalculatorFloat {
(self.theta().clone() / 2.0).sin()
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn global_phase(&self) -> CalculatorFloat {
self.theta().clone() / 2.0
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::Rotate,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct RotateAroundSphericalAxis {
qubit: usize,
theta: CalculatorFloat,
spherical_theta: CalculatorFloat,
spherical_phi: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_RotateAroundSphericalAxis: &[&str; 5] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"Rotation",
"RotateAroundSphericalAxis",
];
impl OperateGate for RotateAroundSphericalAxis {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let c: f64 = (f64::try_from(self.theta.clone())? / 2.0).cos();
let s: f64 = (f64::try_from(self.theta.clone())? / 2.0).sin();
let vx: f64 = ((f64::try_from(self.spherical_theta.clone())?).sin())
* ((f64::try_from(self.spherical_phi.clone())?).cos());
let vy: f64 = ((f64::try_from(self.spherical_theta.clone())?).sin())
* ((f64::try_from(self.spherical_phi.clone())?).sin());
let vz: f64 = (f64::try_from(self.spherical_theta.clone())?).cos();
Ok(array![
[Complex64::new(c, -s * vz), Complex64::new(-s * vy, -s * vx)],
[Complex64::new(s * vy, -s * vx), Complex64::new(c, s * vz)]
])
}
}
impl OperateSingleQubitGate for RotateAroundSphericalAxis {
fn alpha_r(&self) -> CalculatorFloat {
(self.theta.clone() / 2.0).cos()
}
fn alpha_i(&self) -> CalculatorFloat {
let s = (self.theta.clone() / 2.0).sin();
let vz = (self.spherical_theta.clone()).cos();
s * vz * (-1.0) }
fn beta_r(&self) -> CalculatorFloat {
let s = (self.theta.clone() / 2.0).sin();
let vy = (self.spherical_phi.clone()).sin();
let st = (self.spherical_theta.clone()).sin();
s * vy * st
}
fn beta_i(&self) -> CalculatorFloat {
let s = (self.theta.clone() / 2.0).sin();
let vx = (self.spherical_phi.clone()).cos();
let st = (self.spherical_theta.clone()).sin();
s * vx * st * (-1.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::Rotate,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct RotateXY {
qubit: usize,
theta: CalculatorFloat,
phi: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_RotateXY: &[&str; 5] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"Rotation",
"RotateXY",
];
impl OperateGate for RotateXY {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let c: f64 = (f64::try_from(self.theta.clone())? / 2.0).cos();
let s: f64 = (f64::try_from(self.theta.clone())? / 2.0).sin();
let vx: f64 = (f64::try_from(self.phi.clone())?).cos();
let vy: f64 = (f64::try_from(self.phi.clone())?).sin();
Ok(array![
[Complex64::new(c, 0.0), Complex64::new(-s * vy, -s * vx)],
[Complex64::new(s * vy, -s * vx), Complex64::new(c, 0.0)]
])
}
}
impl OperateSingleQubitGate for RotateXY {
fn alpha_r(&self) -> CalculatorFloat {
(self.theta.clone() / 2.0).cos()
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
let s = (self.theta.clone() / 2.0).sin();
let vy = (self.phi.clone()).sin();
s * vy
}
fn beta_i(&self) -> CalculatorFloat {
let s = (self.theta.clone() / 2.0).sin();
let vx = (self.phi.clone()).cos();
s * vx * (-1.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::Rotate,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct GPi {
qubit: usize,
theta: CalculatorFloat,
}
impl SupportedVersion for GPi {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
(1, 4, 0)
}
}
impl super::ImplementedIn1point4 for GPi {}
#[allow(non_upper_case_globals)]
const TAGS_GPi: &[&str; 5] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"Rotation",
"GPi",
];
impl OperateGate for GPi {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let c: f64 = (f64::try_from(self.theta.clone())?).cos();
let s: f64 = (f64::try_from(self.theta.clone())?).sin();
Ok(array![
[Complex64::new(0.0, 0.0), Complex64::new(c, -s)],
[Complex64::new(c, s), Complex64::new(0.0, 0.0)]
])
}
}
impl OperateSingleQubitGate for GPi {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
(self.theta.clone()).sin()
}
fn beta_i(&self) -> CalculatorFloat {
(self.theta.clone()).cos() * -1.0
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(PI / 2.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::Rotate,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct GPi2 {
qubit: usize,
theta: CalculatorFloat,
}
impl super::ImplementedIn1point4 for GPi2 {}
impl SupportedVersion for GPi2 {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
(1, 4, 0)
}
}
#[allow(non_upper_case_globals)]
const TAGS_GPi2: &[&str; 5] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"Rotation",
"GPi2",
];
impl OperateGate for GPi2 {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let c: f64 = (f64::try_from(self.theta.clone())?).cos();
let s: f64 = (f64::try_from(self.theta.clone())?).sin();
Ok(array![
[Complex64::new(1.0, 0.0), Complex64::new(-s, -c)],
[Complex64::new(s, -c), Complex64::new(1.0, 0.0)]
] / 2.0_f64.sqrt())
}
}
impl OperateSingleQubitGate for GPi2 {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from(1.0) / 2.0_f64.sqrt()
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
(self.theta.clone()).sin() / 2.0_f64.sqrt()
}
fn beta_i(&self) -> CalculatorFloat {
(self.theta.clone()).cos() * -1.0 / 2.0_f64.sqrt()
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
// roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct Identity {
qubit: usize,
}
impl SupportedVersion for Identity {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
(1, 7, 0)
}
}
impl super::ImplementedIn1point7 for Identity {}
#[allow(non_upper_case_globals)]
const TAGS_Identity: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"Identity",
];
impl OperateGate for Identity {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
Ok(array![
[Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0)],
[Complex64::new(0.0, 0.0), Complex64::new(1.0, 0.0)]
])
}
}
impl OperateSingleQubitGate for Identity {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from(1.0)
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct SqrtPauliY {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_SqrtPauliY: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"SqrtPauliY",
];
impl SupportedVersion for SqrtPauliY {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
(1, 15, 0)
}
}
impl super::ImplementedIn1point15 for SqrtPauliY {}
impl OperateGate for SqrtPauliY {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let theta: f64 = PI / 2.0;
let c: f64 = (theta / 2.0).cos();
let s: f64 = (theta / 2.0).sin();
Ok(array![
[Complex64::new(c, 0.0), Complex64::new(-s, 0.0)],
[Complex64::new(s, 0.0), Complex64::new(c, 0.0)]
])
}
}
impl OperateSingleQubitGate for SqrtPauliY {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from((PI / 4.0).cos())
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from((PI / 4.0).sin())
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct InvSqrtPauliY {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_InvSqrtPauliY: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"InvSqrtPauliY",
];
impl SupportedVersion for InvSqrtPauliY {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
(1, 15, 0)
}
}
impl super::ImplementedIn1point15 for InvSqrtPauliY {}
impl OperateGate for InvSqrtPauliY {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let theta: f64 = -PI / 2.0;
let c: f64 = (theta / 2.0).cos();
let s: f64 = (theta / 2.0).sin();
Ok(array![
[Complex64::new(c, 0.0), Complex64::new(-s, 0.0)],
[Complex64::new(s, 0.0), Complex64::new(c, 0.0)]
])
}
}
impl OperateSingleQubitGate for InvSqrtPauliY {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from((PI / 4.0).cos())
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(-(PI / 4.0).sin())
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct InvSGate {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_InvSGate: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"InvSGate",
];
impl SupportedVersion for InvSGate {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
(1, 16, 0)
}
}
impl super::ImplementedIn1point16 for InvSGate {}
impl OperateGate for InvSGate {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
Ok(array![
[Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0)],
[Complex64::new(0.0, 0.0), Complex64::new(0.0, -1.0)]
])
}
}
impl OperateSingleQubitGate for InvSGate {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from(1.0 / ((2.0_f64).sqrt()))
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(1.0 / ((2.0_f64).sqrt()))
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(-PI / 4.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct InvTGate {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_InvTGate: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"InvTGate",
];
impl SupportedVersion for InvTGate {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
(1, 16, 0)
}
}
impl super::ImplementedIn1point16 for InvTGate {}
impl OperateGate for InvTGate {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
Ok(array![
[Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0)],
[
Complex64::new(0.0, 0.0),
Complex64::new((PI / 4.0).cos(), -(PI / 4.0).sin())
] ])
}
}
impl OperateSingleQubitGate for InvTGate {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from((PI / 8.0).cos())
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from((PI / 8.0).sin())
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(-PI / 8.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct SXGate {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_SXGate: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"SXGate",
];
impl SupportedVersion for SXGate {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
(1, 16, 0)
}
}
impl super::ImplementedIn1point16 for SXGate {}
impl OperateGate for SXGate {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let theta: f64 = PI / 2.0;
let c: f64 = (theta / 2.0).cos();
let s: f64 = (theta / 2.0).sin();
let gp = Complex64::new(0.0, PI / 4.0).exp();
Ok(array![
[gp * Complex64::new(c, 0.0), gp * Complex64::new(0.0, -s)],
[gp * Complex64::new(0.0, -s), gp * Complex64::new(c, 0.0)]
])
}
}
impl OperateSingleQubitGate for SXGate {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from((PI / 4.0).cos())
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from(-(PI / 4.0).sin())
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(PI / 4.0)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct InvSXGate {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_InvSXGate: &[&str; 4] = &[
"Operation",
"GateOperation",
"SingleQubitGateOperation",
"InvSXGate",
];
impl SupportedVersion for InvSXGate {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
(1, 16, 0)
}
}
impl super::ImplementedIn1point16 for InvSXGate {}
impl OperateGate for InvSXGate {
fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
let theta: f64 = PI / 2.0;
let c: f64 = (theta / 2.0).cos();
let s: f64 = (theta / 2.0).sin();
let gp = Complex64::new(0.0, PI / 4.0).exp();
Ok(array![
[
gp * Complex64::new(c, 0.0),
gp * Complex64::new(0.0, 1.0 * s)
],
[
gp * Complex64::new(0.0, 1.0 * s),
gp * Complex64::new(c, 0.0)
]
])
}
}
impl OperateSingleQubitGate for InvSXGate {
fn alpha_r(&self) -> CalculatorFloat {
CalculatorFloat::from((PI / 4.0).cos())
}
fn alpha_i(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_r(&self) -> CalculatorFloat {
CalculatorFloat::from(0.0)
}
fn beta_i(&self) -> CalculatorFloat {
CalculatorFloat::from((PI / 4.0).sin())
}
fn global_phase(&self) -> CalculatorFloat {
CalculatorFloat::from(PI / 4.0)
}
}