1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]

//! Quantum Computing library leveraging graph building to build efficient quantum circuit
//! simulations.
//!
//! See all the examples in the [examples directory](https://github.com/Renmusxd/RustQIP/tree/master/examples) of the Github repository.
//!
//! # Example (CSWAP)
//! Here's an example of a small circuit where two groups of qubits are swapped conditioned on a
//! third. This circuit is very small, only three operations plus a measurement, so the boilerplate
//! can look quite large in compairison, but that setup provides the ability to construct circuits
//! easily and safely when they do get larger.
//! ```
//! use qip::*;
//!
//! # fn main() -> Result<(), &'static str> {
//! // Make a new circuit builder.
//! let mut b = OpBuilder::new();
//!
//! // Make three logical groups of qubits of sizes 1, 3, 3 (7 qubits total).
//! let q = b.qubit(1)?;
//! let qa = b.qubit(3)?;
//! let qb = b.qubit(3)?;
//!
//! // We will want to feed in some inputs later, hang on to the handles
//! // so we don't need to actually remember any indices.
//! let a_handle = qa.handle();
//! let b_handle = qb.handle();
//!
//! // Define circuit
//! // First apply an H to q
//! let q = b.hadamard(q);
//! // Then run this subcircuit conditioned on q, applied to qa and qb
//! let (q, _) = condition(&mut b, q, (qa, qb), |c, (qa, qb)| {
//!     c.swap(qa, qb)
//! })?;
//! // Finally apply H to q again.
//! let q = b.hadamard(q);
//!
//! // Add a measurement to the first qubit, save a reference so we can get the result later.
//! let (q, m_handle) = b.measure(q);
//!
//! // Now q is the end result of the above circuit, and we can run the circuit by referencing it.
//!
//! // Make an initial state: |0,000,001>
//! let initial_state = [a_handle.make_init_from_index(0)?,
//!                      b_handle.make_init_from_index(1)?];
//! // Run circuit with a given precision.
//! let (_, measured) = run_local_with_init::<f64>(&q, &initial_state)?;
//!
//! // Lookup the result of the measurement we performed using the handle.
//! let (result, p) = measured.get_measurement(&m_handle).unwrap();
//!
//! // Print the measured result
//! println!("Measured: {:?} (with chance {:?})", result, p);
//! # Ok(())
//! # }
//! ```
//!

pub use self::common_circuits::condition;
pub use self::pipeline::{run_local, run_local_with_init, run_with_state, QuantumState};
pub use self::pipeline_debug::run_debug;
pub use self::qubit_chainer::{chain, chain_tuple, chain_vec};
pub use self::qubits::{NonUnitaryBuilder, OpBuilder, Qubit, UnitaryBuilder};
pub use num::Complex;

/// Common circuits for general usage.
pub mod common_circuits;
/// Code for building pipelines.
pub mod pipeline;
/// Tools for displaying pipelines.
pub mod pipeline_debug;
/// Quantum fourier transform support.
pub mod qfft;
/// Ease of use for chains of single qubit ops.
pub mod qubit_chainer;
/// Basic classes for defining circuits/pipelines.
pub mod qubits;
/// Commonly used types.
pub mod types;
/// Commonly used short functions.
pub mod utils;

/// Efficient iterators for sparse kronprod matrices.
pub mod iterators;
/// Functions for measuring states.
pub mod measurement_ops;
/// Functions for running ops on states.
pub mod state_ops;