use crate::gates::Gate;
pub struct U1
{
lambda: crate::gates::Parameter,
desc: String
}
impl U1
{
pub fn new<T>(lambda: T) -> Self
where crate::gates::Parameter: From<T>
{
let param = crate::gates::Parameter::from(lambda);
let desc = format!("U1({:.4})", param);
U1 { lambda: param, desc: desc }
}
pub fn cost() -> f64
{
7.0
}
}
impl crate::gates::Gate for U1
{
fn cost(&self) -> f64
{
Self::cost()
}
fn description(&self) -> &str
{
&self.desc
}
fn nr_affected_bits(&self) -> usize
{
1
}
fn matrix(&self) -> crate::cmatrix::CMatrix
{
let z = crate::cmatrix::COMPLEX_ZERO;
let o = crate::cmatrix::COMPLEX_ONE;
let p = num_complex::Complex::from_polar(&1.0, &self.lambda.value());
array![[o, z], [z, p]]
}
fn apply_slice(&self, mut state: crate::cmatrix::CVecSliceMut)
{
assert!(state.len() % 2 == 0, "Number of rows is not even.");
let n = state.len() / 2;
let mut slice = state.slice_mut(s![n..]);
slice *= num_complex::Complex::from_polar(&1.0, &self.lambda.value());
}
}
impl crate::export::OpenQasm for U1
{
fn open_qasm(&self, bit_names: &[String], bits: &[usize])
-> crate::error::Result<String>
{
Ok(format!("u1({}) {}", self.lambda, bit_names[bits[0]]))
}
}
impl crate::export::CQasm for U1
{
fn c_qasm(&self, bit_names: &[String], bits: &[usize])
-> crate::error::Result<String>
{
Ok(format!("rz {}, {}", bit_names[bits[0]], self.lambda))
}
}
impl crate::export::Latex for U1
{
fn latex(&self, bits: &[usize], state: &mut crate::export::LatexExportState)
-> crate::error::Result<()>
{
self.check_nr_bits(bits.len())?;
let contents = format!("U_1({:.4})", self.lambda);
state.add_block_gate(bits, &contents)
}
}
#[cfg(test)]
mod tests
{
use crate::gates::{gate_test, Gate, U1};
use crate::export::{Latex, LatexExportState, OpenQasm, CQasm};
#[test]
fn test_description()
{
let gate = U1::new(::std::f64::consts::FRAC_PI_4);
assert_eq!(gate.description(), "U1(0.7854)");
}
#[test]
fn test_cost()
{
let gate = U1::new(::std::f64::consts::FRAC_PI_4);
assert_eq!(gate.cost(), 7.0);
}
#[test]
fn test_matrix()
{
let gate = U1::new(::std::f64::consts::FRAC_PI_2);
let z = crate::cmatrix::COMPLEX_ZERO;
let o = crate::cmatrix::COMPLEX_ONE;
let i = crate::cmatrix::COMPLEX_I;
assert_complex_matrix_eq!(gate.matrix(), array![[o, z], [z, i]]);
}
#[test]
fn test_apply()
{
let z = crate::cmatrix::COMPLEX_ZERO;
let o = crate::cmatrix::COMPLEX_ONE;
let x = crate::cmatrix::COMPLEX_HSQRT2;
let i = crate::cmatrix::COMPLEX_I;
let mut state = array![[o, z, x, x], [z, o, x, -x]];
let result = array![[o, z, x, x], [z, x*(o+i), 0.5*(o+i), -0.5*(o+i)]];
let gate = U1::new(::std::f64::consts::FRAC_PI_4);
gate_test(gate, &mut state, &result);
}
#[test]
fn test_open_qasm()
{
let bit_names = [String::from("qb")];
let qasm = U1::new(::std::f64::consts::PI).open_qasm(&bit_names, &[0]);
assert_eq!(qasm, Ok(String::from("u1(3.141592653589793) qb")));
}
#[test]
fn test_c_qasm()
{
let bit_names = [String::from("qb")];
let qasm = U1::new(::std::f64::consts::PI).c_qasm(&bit_names, &[0]);
assert_eq!(qasm, Ok(String::from("rz qb, 3.141592653589793")));
}
#[test]
fn test_latex()
{
let gate = U1::new(::std::f64::consts::FRAC_PI_4);
let mut state = LatexExportState::new(1, 0);
assert_eq!(gate.latex(&[0], &mut state), Ok(()));
assert_eq!(state.code(),
r#"\Qcircuit @C=1em @R=.7em {
\lstick{\ket{0}} & \gate{U_1(0.7854)} & \qw \\
}
"#);
let gate = U1::new(-1.2);
let mut state = LatexExportState::new(1, 0);
assert_eq!(gate.latex(&[0], &mut state), Ok(()));
assert_eq!(state.code(),
r#"\Qcircuit @C=1em @R=.7em {
\lstick{\ket{0}} & \gate{U_1(-1.2000)} & \qw \\
}
"#);
}
}