use crate::expr::Expression;
use crate::ops::trig;
#[must_use]
pub fn hadamard() -> Expression {
Expression::new("1/sqrt(2) * Matrix([[1, 1], [1, -1]])")
}
#[must_use]
pub fn phase() -> Expression {
Expression::new("Matrix([[1, 0], [0, I]])")
}
#[must_use]
pub fn t_gate() -> Expression {
Expression::new("Matrix([[1, 0], [0, exp(I*pi/4)]])")
}
#[must_use]
pub fn cnot() -> Expression {
Expression::new("Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])")
}
#[must_use]
pub fn swap() -> Expression {
Expression::new("Matrix([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]])")
}
#[must_use]
pub fn rx(theta: &Expression) -> Expression {
let half = theta.clone() / Expression::int(2);
let cos_half = trig::cos(&half);
let sin_half = trig::sin(&half);
let i_sin = Expression::i().neg() * sin_half;
Expression::new(format!(
"Matrix([[cos({theta}/2), -I*sin({theta}/2)], [-I*sin({theta}/2), cos({theta}/2)]])"
))
}
#[must_use]
pub fn ry(theta: &Expression) -> Expression {
Expression::new(format!(
"Matrix([[cos({theta}/2), -sin({theta}/2)], [sin({theta}/2), cos({theta}/2)]])"
))
}
#[must_use]
pub fn rz(theta: &Expression) -> Expression {
Expression::new(format!(
"Matrix([[exp(-I*{theta}/2), 0], [0, exp(I*{theta}/2)]])"
))
}
#[must_use]
pub fn u3(theta: &Expression, phi: &Expression, lambda: &Expression) -> Expression {
Expression::new(format!(
"Matrix([[cos({theta}/2), -exp(I*{lambda})*sin({theta}/2)], \
[exp(I*{phi})*sin({theta}/2), exp(I*({phi}+{lambda}))*cos({theta}/2)]])"
))
}
#[must_use]
pub fn cz() -> Expression {
Expression::new("Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, -1]])")
}
#[must_use]
pub fn toffoli() -> Expression {
Expression::new(
"Matrix([[1,0,0,0,0,0,0,0],\
[0,1,0,0,0,0,0,0],\
[0,0,1,0,0,0,0,0],\
[0,0,0,1,0,0,0,0],\
[0,0,0,0,1,0,0,0],\
[0,0,0,0,0,1,0,0],\
[0,0,0,0,0,0,0,1],\
[0,0,0,0,0,0,1,0]])",
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_quantum_gates() {
let h = hadamard();
let s = phase();
let t = t_gate();
let cx = cnot();
assert!(!h.to_string().is_empty());
assert!(!s.to_string().is_empty());
assert!(!t.to_string().is_empty());
assert!(!cx.to_string().is_empty());
}
#[test]
fn test_rotation_gates() {
let theta = Expression::symbol("theta");
let rx_gate = rx(&theta);
let ry_gate = ry(&theta);
let rz_gate = rz(&theta);
assert!(rx_gate.to_string().contains("theta"));
assert!(ry_gate.to_string().contains("theta"));
assert!(rz_gate.to_string().contains("theta"));
}
}