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;