4 个稳定版本
1.4.0 | 2023年5月12日 |
---|---|
1.2.0 | 2023年5月12日 |
1.1.0 | 2023年5月11日 |
1.0.0 | 2023年5月10日 |
在 算法 中排名 925
用于 qip
45KB
1K SLoC
RustQIP
利用图构建来构建高效量子电路模拟的量子计算库。
请参阅 示例目录 中的所有示例。
欢迎提交 PR
Rust 语言非常适合量子计算,因为有借用检查器与 不可克隆定理 非常相似。
请参阅 Github 仓库 示例目录 中的所有示例。
示例(CSWAP)
这是一个小电路的示例,其中两个寄存器组在第三个寄存器的条件下交换。这个电路非常小,只有三个操作加一个测量,所以与这个设置相比,样板代码可能看起来相当大,但这样的设置能够在电路变大时轻松且安全地构建电路。
use qip::prelude::*;
use std::num::NonZeroUsize;
// Make a new circuit builder.
let mut b = LocalBuilder::<f64>::default();
let n = NonZeroUsize::new(3).unwrap();
// Make three registers of sizes 1, 3, 3 (7 qubits total).
let q = b.qubit(); // Same as b.register(1)?;
let ra = b.register(n);
let rb = b.register(n);
// Define circuit
// First apply an H to q
let q = b.h(q);
// Then swap ra and rb, conditioned on q.
let mut cb = b.condition_with(q);
let (ra, rb) = cb.swap(ra, rb) ?;
let q = cb.dissolve();
// Finally apply H to q again.
let q = b.h(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.
// Run circuit with a given precision.
let (_, measured) = b.calculate_state_with_init([( & ra, 0b000), ( & rb, 0b001)]);
// Lookup the result of the measurement we performed using the handle, and the probability
// of getting that measurement.
let (result, p) = measured.get_measurement(m_handle);
// Print the measured result
println!("Measured: {:?} (with chance {:?})", result, p);
程序宏
虽然 Rust 中的借用检查器是一个检查寄存器行为的出色工具,但它可能会很繁琐。因此,qip 还包括一个宏,它提供了类似于量子计算教科书中看到的 API。这个宏被 macros
功能所保护。
use qip::prelude::*;
use std::num::NonZeroUsize;
use qip_macros::program;
fn gamma<B>(b: &mut B, ra: B::Register, rb: B::Register) -> CircuitResult<(B::Register, B::Register)>
where B: AdvancedCircuitBuilder<f64>
{
let (ra, rb) = b.toffoli(ra, rb)?;
let (rb, ra) = b.toffoli(rb, ra)?;
Ok((ra, rb))
}
let n = NonZeroUsize::new(3).unwrap();
let mut b = LocalBuilder::default();
let ra = b.register(n);
let rb = b.register(n);
let (ra, rb) = program!(&mut b; ra, rb;
// Applies gamma to |ra[0] ra[1]>|ra[2]>
gamma ra[0..2], ra[2];
// Applies gamma to |ra[0] rb[0]>|ra[2]>
// Notice ra[0] and rb[0] are grouped by brackets.
gamma [ra[0], rb[0]], ra[2];
// Applies gamma to |ra[0]>|rb[0] ra[2]>
gamma ra[0], [rb[0], ra[2]];
// Applies gamma to |ra[0] ra[1]>|ra[2]> if rb == |111>
control gamma rb, ra[0..2], ra[2];
// Applies gamma to |ra[0] ra[1]>|ra[2]> if rb == |110> (rb[0] == |0>, rb[1] == 1, ...)
control(0b110) gamma rb, ra[0..2], ra[2];
)?;
我们还可以将此应用于接受其他参数的函数。在这里,gamma
接受一个布尔参数 skip
,它在寄存器之前传递。程序宏中的函数参数不能引用输入寄存器
use qip::prelude::*;
use std::num::NonZeroUsize;
use qip_macros::program;
fn gamma<B>(b: &mut B, skip: bool, ra: B::Register, rb: B::Register) -> CircuitResult<(B::Register, B::Register)>
where B: AdvancedCircuitBuilder<f64>
{
let (ra, rb) = b.toffoli(ra, rb)?;
let (rb, ra) = if skip {
b.toffoli(rb, ra)?
} else {
(rb, ra)
};
Ok((ra, rb))
}
let n = NonZeroUsize::new(3).unwrap();
let mut b = LocalBuilder::default();
let ra = b.register(n);
let rb = b.register(n);
let (ra, rb) = program!(&mut b; ra, rb;
gamma(true) ra[0..2], ra[2];
gamma(0 == 1) ra[0..2], ra[2];
)?;
反转宏
定义寄存器的函数及其逆函数通常很有用,#[invert]
宏自动化了这一过程的很大一部分。
use qip::prelude::*;
use std::num::NonZeroUsize;
use qip_macros::*;
use qip::inverter::Invertable;
// Make gamma and its inverse: gamma_inv
#[invert(gamma_inv)]
fn gamma<B>(b: &mut B, ra: B::Register, rb: B::Register) -> CircuitResult<(B::Register, B::Register)>
where B: AdvancedCircuitBuilder<f64> + Invertable<SimilarBuilder=B>
{
let (ra, rb) = b.toffoli(ra, rb)?;
let (rb, ra) = b.toffoli(rb, ra)?;
Ok((ra, rb))
}
let n = NonZeroUsize::new(3).unwrap();
let mut b = LocalBuilder::default();
let ra = b.register(n);
let rb = b.register(n);
let (ra, rb) = program!(&mut b; ra, rb;
gamma ra[0..2], ra[2];
gamma_inv ra[0..2], ra[2];
)?;
要反转具有附加参数的函数,我们必须列出非寄存器参数。
use qip::prelude::*;
use std::num::NonZeroUsize;
use qip_macros::*;
use qip::inverter::Invertable;
// Make gamma and its inverse: gamma_inv
#[invert(gamma_inv, skip)]
fn gamma<B>(b: &mut B, skip: bool, ra: B::Register, rb: B::Register) -> CircuitResult<(B::Register, B::Register)>
where B: AdvancedCircuitBuilder<f64> + Invertable<SimilarBuilder=B>
{
let (ra, rb) = b.toffoli(ra, rb)?;
let (rb, ra) = if skip {
b.toffoli(rb, ra)?
} else {
(rb, ra)
};
Ok((ra, rb))
}
let n = NonZeroUsize::new(3).unwrap();
let mut b = LocalBuilder::default();
let ra = b.register(n);
let rb = b.register(n);
let (ra, rb) = program!(&mut b; ra, rb;
gamma(true) ra[0..2], ra[2];
gamma_inv(true) ra[0..2], ra[2];
)?;
lib.rs
:
量子比特结构矩阵的矩阵乘法库。
依赖项
~94–420KB