[−][src]Macro qip::program
A helper macro for applying functions to specific qubits in registers.
The macro takes an expression which yields &mut dyn UnitaryBuilder
, a list of registers, then
a series of function call expressions of the form:
function [register <indices?>, ...];
Registers can be groups by surrounding them with vertical bars, for example:
function |ra, rb[0,2],| rc
(Notice the comma is inside the bars, not the best syntax but macros are restrictive).
Example
use qip::*; let n = 3; let mut b = OpBuilder::new(); let ra = b.register(n)?; let rb = b.register(n)?; let gamma = |b: &mut dyn UnitaryBuilder, mut rs: Vec<Register>| -> Result<Vec<Register>, CircuitError> { let rb = rs.pop().unwrap(); let ra = rs.pop().unwrap(); let (ra, rb) = b.cnot(ra, rb); Ok(vec![ra, rb]) }; // Gamma |ra>|rb[2]> // Gamma |ra[0]>|rb> let (ra, rb) = program!(&mut b, ra, rb; gamma ra, rb[2]; gamma ra[0], rb; )?; let r = b.merge(vec![ra, rb])?;
Example with grouping
use qip::*; let n = 3; let mut b = OpBuilder::new(); let ra = b.register(n)?; let rb = b.register(n)?; let gamma = |b: &mut dyn UnitaryBuilder, mut rs: Vec<Register>| -> Result<Vec<Register>, CircuitError> { let rb = rs.pop().unwrap(); let ra = rs.pop().unwrap(); let (ra, rb) = b.cnot(ra, rb); Ok(vec![ra, rb]) }; // Gamma |ra[0] ra[2]>|rb[2]> // Gamma |ra>|rb[0] rb[2]> // Gamma |ra[0]>|ra[1,2] rb> // Gamma |rb[0]>|ra rb[1,2]> let (ra, rb) = program!(&mut b, ra, rb; gamma |ra[0], ra[2],| rb[2]; gamma ra, |rb[0], rb[2],|; gamma ra[0], |ra[1, 2], rb,|; gamma rb[0], |ra, rb[1, 2],|; )?; let r = b.merge(vec![ra, rb])?;
Example with inline ranges:
use qip::*; let n = 3; let mut b = OpBuilder::new(); let ra = b.register(n)?; let rb = b.register(n)?; let gamma = |b: &mut dyn UnitaryBuilder, mut rs: Vec<Register>| -> Result<Vec<Register>, CircuitError> { let rb = rs.pop().unwrap(); let ra = rs.pop().unwrap(); let (ra, rb) = b.cnot(ra, rb); Ok(vec![ra, rb]) }; // Gamma |ra[0] ra[1]>|ra[2]> let (ra, rb) = program!(&mut b, ra, rb; gamma ra[0..2], ra[2]; )?; let r = b.merge(vec![ra, rb])?;
Example with inline control:
use qip::*; let n = 3; let mut b = OpBuilder::new(); let ra = b.register(n)?; let rb = b.register(n)?; let gamma = |b: &mut dyn UnitaryBuilder, mut rs: Vec<Register>| -> Result<Vec<Register>, CircuitError> { let ra = rs.pop().unwrap(); let ra = b.not(ra); Ok(vec![ra]) }; // |ra[0] ra[1]> control Gamma |rb[2]> let (ra, rb) = program!(&mut b, ra, rb; control gamma ra[0..2], rb[2]; )?; let r = b.merge(vec![ra, rb])?;