pub struct Process { /* private fields */ }
Expand description
Quantum Process for managing qubit allocation and circuit creation.
This struct encapsulates the necessary information for handling qubit allocations and creating quantum circuits. It provides functions to apply quantum gates, measure qubits, and execute quantum code.
§Examples
use ket::{Configuration, Process, QuantumGate};
// Configuration instance must be provided by the quantum execution.
// See the KBW documentation for examples.
let configuration = Configuration::new(2);
// Create a new process with the provided configurations.
// The configuration will specify the maximum number of qubits the quantum
// execution can handle, the execution mode, and more.
let mut process = Process::new(configuration);
// Allocate qubits and return their references for later usage.
let qubit_a = process.allocate_qubit()?;
let qubit_b = process.allocate_qubit()?;
// Apply a Hadamard gate to the first qubit.
process.apply_gate(QuantumGate::Hadamard, qubit_a)?;
// Push the first qubit to the control stack, apply a Pauli X gate to the second qubit,
// and pop the qubit from the control stack.
process.ctrl_push(&[qubit_a])?;
process.apply_gate(QuantumGate::PauliX, qubit_b)?;
process.ctrl_pop()?;
// Measure the qubits and return the results references.
let m_a = process.measure(&[qubit_a])?;
let m_b = process.measure(&[qubit_b])?;
Implementations§
source§impl Process
impl Process
sourcepub fn new(config: Configuration) -> Self
pub fn new(config: Configuration) -> Self
Creates a new Process
with the given configurations
Examples found in repository?
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
fn main() -> Result<(), KetError> {
// Configuration instance must be provided by the quantum execution.
// See the KBW documentation for examples.
let configuration = Configuration::new(2);
// Create a new process with the provided configurations.
// The configuration will specify the maximum number of qubits the quantum
// execution can handle, the execution mode, and more.
let mut process = Process::new(configuration);
// Allocate qubits and return their references for later usage.
let qubit_a = process.allocate_qubit()?;
let qubit_b = process.allocate_qubit()?;
// Apply a Hadamard gate to the first qubit.
process.apply_gate(QuantumGate::Hadamard, qubit_a)?;
// Push the first qubit to the control stack, apply a Pauli X gate to the second qubit,
// and pop the qubit from the control stack.
process.ctrl_push(&[qubit_a])?;
process.apply_gate(QuantumGate::PauliX, qubit_b)?;
process.ctrl_pop()?;
// Measure the qubits and return the results references.
let _m_a = process.measure(&[qubit_a])?;
let _m_b = process.measure(&[qubit_b])?;
let _exp = process.exp_values(PauliHamiltonian {
coefficients: vec![1.0],
products: vec![vec![
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_a,
},
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_b,
},
]],
})?;
Ok(())
}
sourcepub fn allocate_qubit(&mut self) -> Result<usize>
pub fn allocate_qubit(&mut self) -> Result<usize>
Allocate a qubit and return its index.
The qubit index resulting from the allocation is used in quantum gate application, measurement, quantum state dump, and expected value calculations.
§Examples
let qubit_index = process.allocate_qubit()?;
// Now you can use the allocated qubit_index in quantum operations.
§Errors
Returns an error if the process is in an inverse scope, if it is ready for execution, or if the number of allocated qubits exceeds the configured limit.
Examples found in repository?
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
fn main() -> Result<(), KetError> {
// Configuration instance must be provided by the quantum execution.
// See the KBW documentation for examples.
let configuration = Configuration::new(2);
// Create a new process with the provided configurations.
// The configuration will specify the maximum number of qubits the quantum
// execution can handle, the execution mode, and more.
let mut process = Process::new(configuration);
// Allocate qubits and return their references for later usage.
let qubit_a = process.allocate_qubit()?;
let qubit_b = process.allocate_qubit()?;
// Apply a Hadamard gate to the first qubit.
process.apply_gate(QuantumGate::Hadamard, qubit_a)?;
// Push the first qubit to the control stack, apply a Pauli X gate to the second qubit,
// and pop the qubit from the control stack.
process.ctrl_push(&[qubit_a])?;
process.apply_gate(QuantumGate::PauliX, qubit_b)?;
process.ctrl_pop()?;
// Measure the qubits and return the results references.
let _m_a = process.measure(&[qubit_a])?;
let _m_b = process.measure(&[qubit_b])?;
let _exp = process.exp_values(PauliHamiltonian {
coefficients: vec![1.0],
products: vec![vec![
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_a,
},
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_b,
},
]],
})?;
Ok(())
}
sourcepub fn free_qubit(&mut self, qubit: usize) -> Result<()>
pub fn free_qubit(&mut self, qubit: usize) -> Result<()>
Frees a previously allocated qubit
§Examples
let qubit_index = process.allocate_qubit()?;
// Perform quantum operations...
process.free_qubit(qubit_index)?;
// Qubit has been freed and can no longer be used in quantum operations.
§Errors
Returns an error if the process is in an inverse scope, if it is ready for execution, or if the specified qubit has not been allocated.
sourcepub fn apply_gate(&mut self, gate: QuantumGate, target: usize) -> Result<()>
pub fn apply_gate(&mut self, gate: QuantumGate, target: usize) -> Result<()>
Applies a quantum gate to a target qubit
This function considers the control qubit list to apply the quantum gate in the target qubit.
If the process has an opened inverse scope, the gate will only be applied when the scope is closed.
§Examples
let qubit_index = process.allocate_qubit()?;
process.apply_gate(QuantumGate::Hadamard, qubit_index)?;
// Perform additional quantum operations...
§Errors
Returns an error if the process is ready for execution, if the specified qubit has not been allocated, or if the target qubit is part of the control qubits.
Examples found in repository?
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
fn main() -> Result<(), KetError> {
// Configuration instance must be provided by the quantum execution.
// See the KBW documentation for examples.
let configuration = Configuration::new(2);
// Create a new process with the provided configurations.
// The configuration will specify the maximum number of qubits the quantum
// execution can handle, the execution mode, and more.
let mut process = Process::new(configuration);
// Allocate qubits and return their references for later usage.
let qubit_a = process.allocate_qubit()?;
let qubit_b = process.allocate_qubit()?;
// Apply a Hadamard gate to the first qubit.
process.apply_gate(QuantumGate::Hadamard, qubit_a)?;
// Push the first qubit to the control stack, apply a Pauli X gate to the second qubit,
// and pop the qubit from the control stack.
process.ctrl_push(&[qubit_a])?;
process.apply_gate(QuantumGate::PauliX, qubit_b)?;
process.ctrl_pop()?;
// Measure the qubits and return the results references.
let _m_a = process.measure(&[qubit_a])?;
let _m_b = process.measure(&[qubit_b])?;
let _exp = process.exp_values(PauliHamiltonian {
coefficients: vec![1.0],
products: vec![vec![
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_a,
},
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_b,
},
]],
})?;
Ok(())
}
sourcepub fn measure(&mut self, qubits: &[usize]) -> Result<usize>
pub fn measure(&mut self, qubits: &[usize]) -> Result<usize>
Measures the specified qubits
This function performs measurements on the specified qubits. It updates the internal state of the process, records measurement instructions, and returns the index of the measurement result.
§Examples
let qubit_index = process.allocate_qubit()?;
let measurement_index = process.measure(&[qubit_index])?;
// Perform additional quantum operations or measurements...
§Errors
Returns an error if the process is in an adjacent scope, if the process is ready for execution, or if measurements are not allowed based on the process configuration.
Examples found in repository?
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
fn main() -> Result<(), KetError> {
// Configuration instance must be provided by the quantum execution.
// See the KBW documentation for examples.
let configuration = Configuration::new(2);
// Create a new process with the provided configurations.
// The configuration will specify the maximum number of qubits the quantum
// execution can handle, the execution mode, and more.
let mut process = Process::new(configuration);
// Allocate qubits and return their references for later usage.
let qubit_a = process.allocate_qubit()?;
let qubit_b = process.allocate_qubit()?;
// Apply a Hadamard gate to the first qubit.
process.apply_gate(QuantumGate::Hadamard, qubit_a)?;
// Push the first qubit to the control stack, apply a Pauli X gate to the second qubit,
// and pop the qubit from the control stack.
process.ctrl_push(&[qubit_a])?;
process.apply_gate(QuantumGate::PauliX, qubit_b)?;
process.ctrl_pop()?;
// Measure the qubits and return the results references.
let _m_a = process.measure(&[qubit_a])?;
let _m_b = process.measure(&[qubit_b])?;
let _exp = process.exp_values(PauliHamiltonian {
coefficients: vec![1.0],
products: vec![vec![
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_a,
},
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_b,
},
]],
})?;
Ok(())
}
sourcepub fn exp_values(&mut self, hamiltonian: PauliHamiltonian) -> Result<usize>
pub fn exp_values(&mut self, hamiltonian: PauliHamiltonian) -> Result<usize>
Calculates the expected values of a Pauli Hamiltonian
This function calculates the expected values of a Pauli Hamiltonian. It updates the internal state of the process, records the calculation instructions, and returns the index of the expected value result.
§Examples
use ket::{Pauli, PauliHamiltonian, PauliTerm};
let qubit_a = process.allocate_qubit()?;
let qubit_b = process.allocate_qubit()?;
let _exp = process.exp_values(PauliHamiltonian {
coefficients: vec![1.0],
products: vec![vec![
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_a,
},
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_b,
},
]],
})?;
§Errors
Returns an error if the process is in an adjacent scope, if the process is ready for execution, or if expected value calculations are not allowed based on the process configuration. Additionally, it verifies whether the qubits involved in the Hamiltonian are allocated.
Examples found in repository?
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
fn main() -> Result<(), KetError> {
// Configuration instance must be provided by the quantum execution.
// See the KBW documentation for examples.
let configuration = Configuration::new(2);
// Create a new process with the provided configurations.
// The configuration will specify the maximum number of qubits the quantum
// execution can handle, the execution mode, and more.
let mut process = Process::new(configuration);
// Allocate qubits and return their references for later usage.
let qubit_a = process.allocate_qubit()?;
let qubit_b = process.allocate_qubit()?;
// Apply a Hadamard gate to the first qubit.
process.apply_gate(QuantumGate::Hadamard, qubit_a)?;
// Push the first qubit to the control stack, apply a Pauli X gate to the second qubit,
// and pop the qubit from the control stack.
process.ctrl_push(&[qubit_a])?;
process.apply_gate(QuantumGate::PauliX, qubit_b)?;
process.ctrl_pop()?;
// Measure the qubits and return the results references.
let _m_a = process.measure(&[qubit_a])?;
let _m_b = process.measure(&[qubit_b])?;
let _exp = process.exp_values(PauliHamiltonian {
coefficients: vec![1.0],
products: vec![vec![
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_a,
},
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_b,
},
]],
})?;
Ok(())
}
sourcepub fn sample(&mut self, qubits: &[usize], shots: u64) -> Result<usize>
pub fn sample(&mut self, qubits: &[usize], shots: u64) -> Result<usize>
Performs sampling on specified qubits
This function performs sampling on the specified qubits with a specified number of shots. It updates the internal state of the process, records sampling instructions, and returns the index of the sample result.
§Examples
let qubit_a = process.allocate_qubit()?;
let qubit_b = process.allocate_qubit()?;
let shots = 1000;
let sample_index = process.sample(&[qubit_a, qubit_b], shots)?;
// Perform additional quantum operations or sampling...
§Errors
Returns an error if the process is in an adjacent scope, if the process is ready for execution, or if sampling is not allowed based on the process configuration. Additionally, it verifies whether the qubits involved in the sampling are allocated.
sourcepub fn dump(&mut self, qubits: &[usize]) -> Result<usize>
pub fn dump(&mut self, qubits: &[usize]) -> Result<usize>
Dumps the state of specified qubits
This function dumps the state of the specified qubits. It updates the internal state of the process, records dump instructions, and returns the index of the dump result.
§Examples
let qubit_a = process.allocate_qubit()?;
let qubit_b = process.allocate_qubit()?;
let dump_index = process.dump(&[qubit_a, qubit_b])?;
// Perform additional quantum operations or dumps...
§Errors
Returns an error if the process is in an adjacent scope, if the process is ready for execution, or if dumping is not allowed based on the process configuration. Additionally, it verifies whether the qubits involved in the dump operation are allocated.
sourcepub fn ctrl_push(&mut self, qubits: &[usize]) -> Result<()>
pub fn ctrl_push(&mut self, qubits: &[usize]) -> Result<()>
Pushes control qubits onto the control stack
This function pushes control qubits onto the control stack. It updates the internal state of the process and ensures that qubits are not controlled more than once.
§Examples
let qubit_a = process.allocate_qubit()?;
let qubit_b = process.allocate_qubit()?;
process.ctrl_push(&[qubit_a, qubit_b])?;
// Perform additional quantum operations...
§Errors
Returns an error if the process is ready for execution or if the control qubits are allocated more than once during a control operation.
Examples found in repository?
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
fn main() -> Result<(), KetError> {
// Configuration instance must be provided by the quantum execution.
// See the KBW documentation for examples.
let configuration = Configuration::new(2);
// Create a new process with the provided configurations.
// The configuration will specify the maximum number of qubits the quantum
// execution can handle, the execution mode, and more.
let mut process = Process::new(configuration);
// Allocate qubits and return their references for later usage.
let qubit_a = process.allocate_qubit()?;
let qubit_b = process.allocate_qubit()?;
// Apply a Hadamard gate to the first qubit.
process.apply_gate(QuantumGate::Hadamard, qubit_a)?;
// Push the first qubit to the control stack, apply a Pauli X gate to the second qubit,
// and pop the qubit from the control stack.
process.ctrl_push(&[qubit_a])?;
process.apply_gate(QuantumGate::PauliX, qubit_b)?;
process.ctrl_pop()?;
// Measure the qubits and return the results references.
let _m_a = process.measure(&[qubit_a])?;
let _m_b = process.measure(&[qubit_b])?;
let _exp = process.exp_values(PauliHamiltonian {
coefficients: vec![1.0],
products: vec![vec![
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_a,
},
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_b,
},
]],
})?;
Ok(())
}
sourcepub fn ctrl_pop(&mut self) -> Result<()>
pub fn ctrl_pop(&mut self) -> Result<()>
Pops the last added control qubits from the control stack
§Errors
Returns an error if the process is ready for execution or if there are no control configurations on the control stack to pop.
Examples found in repository?
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
fn main() -> Result<(), KetError> {
// Configuration instance must be provided by the quantum execution.
// See the KBW documentation for examples.
let configuration = Configuration::new(2);
// Create a new process with the provided configurations.
// The configuration will specify the maximum number of qubits the quantum
// execution can handle, the execution mode, and more.
let mut process = Process::new(configuration);
// Allocate qubits and return their references for later usage.
let qubit_a = process.allocate_qubit()?;
let qubit_b = process.allocate_qubit()?;
// Apply a Hadamard gate to the first qubit.
process.apply_gate(QuantumGate::Hadamard, qubit_a)?;
// Push the first qubit to the control stack, apply a Pauli X gate to the second qubit,
// and pop the qubit from the control stack.
process.ctrl_push(&[qubit_a])?;
process.apply_gate(QuantumGate::PauliX, qubit_b)?;
process.ctrl_pop()?;
// Measure the qubits and return the results references.
let _m_a = process.measure(&[qubit_a])?;
let _m_b = process.measure(&[qubit_b])?;
let _exp = process.exp_values(PauliHamiltonian {
coefficients: vec![1.0],
products: vec![vec![
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_a,
},
PauliTerm {
pauli: Pauli::PauliX,
qubit: qubit_b,
},
]],
})?;
Ok(())
}
sourcepub fn adj_begin(&mut self) -> Result<()>
pub fn adj_begin(&mut self) -> Result<()>
Begins an adjoint block, where gates are inverted upon insertion
§Errors
Returns an error if the process is ready for execution.
sourcepub fn adj_end(&mut self) -> Result<()>
pub fn adj_end(&mut self) -> Result<()>
Ends the adjoint block, reverting to normal gate insertion
§Errors
Returns an error if the process is ready for execution or if there is no adjoint block to end.
sourcepub fn prepare_for_execution(&mut self) -> Result<()>
pub fn prepare_for_execution(&mut self) -> Result<()>
Prepares the process for quantum execution
sourcepub fn get_qubit_status(&self, qubit: usize) -> &QubitStatus
pub fn get_qubit_status(&self, qubit: usize) -> &QubitStatus
Returns the status of the specified qubit
sourcepub fn get_measurement(&self, index: usize) -> &Measurement
pub fn get_measurement(&self, index: usize) -> &Measurement
Returns the measurement result at the specified index
sourcepub fn get_exp_value(&self, index: usize) -> &ExpValue
pub fn get_exp_value(&self, index: usize) -> &ExpValue
Returns the expected value result at the specified index
sourcepub fn get_sample(&self, index: usize) -> &Sample
pub fn get_sample(&self, index: usize) -> &Sample
Returns the sample result at the specified index
sourcepub fn get_metadata(&self) -> &Metadata
pub fn get_metadata(&self) -> &Metadata
Return process metadata
sourcepub fn set_result(&mut self, results: ResultData) -> Result<()>
pub fn set_result(&mut self, results: ResultData) -> Result<()>
Set the quantum execution result
This function allow to manually set the quantum execution result for the process. However, this function should only be used for testing purposes. The result must be provided by the quantum executor set in the configuration.