1use std::f64::consts::PI;
6
7use ket::{
8 controlled_gate,
9 error::KetError,
10 ir::{
11 block::BasicBlock,
12 gate::{Param, QuantumGate},
13 },
14 process::{Process, QPUConfig},
15 swap_gate,
16};
17
18fn qft(qubits: &[usize], do_swap: bool) -> Result<BasicBlock, KetError> {
19 let mut quantum_code = BasicBlock::new();
20 if qubits.len() == 1 {
21 quantum_code.append_gate(QuantumGate::Hadamard, qubits[0]);
22 return Ok(quantum_code);
23 }
24
25 let init = &qubits[..qubits.len() - 1];
26 let last = qubits[qubits.len() - 1];
27 quantum_code.append_gate(QuantumGate::Hadamard, last);
28 for (i, c) in init.iter().enumerate() {
29 quantum_code.append_block(
30 controlled_gate(
31 QuantumGate::Phase(Param::Value(PI / 2.0_f64.powi(i as i32 + 1))),
32 &[*c],
33 last,
34 )?,
35 None,
36 );
37 }
38 quantum_code.append_block(qft(init, false)?, None);
39
40 if do_swap {
41 for i in 0..qubits.len() / 2 {
42 quantum_code.append_block(swap_gate(qubits[i], qubits[qubits.len() - i - 1])?, None);
43 }
44 }
45
46 Ok(quantum_code)
47}
48
49fn main() -> Result<(), KetError> {
50 let num_qubits = 12;
51
52 let mut process = Process::new(QPUConfig {
53 num_qubits,
54 quantum_execution: None,
55 });
56
57 let qubits: Result<Vec<_>, _> = (0..num_qubits).map(|_| process.alloc()).collect();
58 let qubits = qubits?;
59
60 process.append_block(qft(&qubits, true)?)?;
61
62 println!("{:#?}", process);
63
64 Ok(())
65}