Line data Source code
1 : // Copyright © 2021 HQS Quantum Simulations GmbH. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4 : // in compliance with the License. You may obtain a copy of the License at
5 : //
6 : // http://www.apache.org/licenses/LICENSE-2.0
7 : //
8 : // Unless required by applicable law or agreed to in writing, software distributed under the
9 : // License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
10 : // express or implied. See the License for the specific language governing permissions and
11 : // limitations under the License.
12 :
13 : use crate::measurements::Measure;
14 : use crate::Circuit;
15 : use crate::RoqoqoError;
16 : use std::collections::HashMap;
17 :
18 : /// Classical register measurement.
19 : ///
20 : /// Runs a sequence of circuits and returns the classical registers written during circuit execution.
21 2 : #[derive(Debug, PartialEq, Clone)]
22 : #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
23 : pub struct ClassicalRegister {
24 : /// Constant Circuit that is executed before each Circuit in circuits.
25 : pub constant_circuit: Option<Circuit>,
26 : /// Collection of quantum circuits for the separate basis rotations.
27 : pub circuits: Vec<Circuit>,
28 : }
29 :
30 : impl Measure for ClassicalRegister {
31 : /// Returns the constant Circuit that is executed before each Circuit in circuits.
32 : ///
33 : /// # Returns
34 : ///
35 : /// * `&Option<Circuit` - The constant Circuit (None if not defined).
36 3 : fn constant_circuit(&self) -> &Option<Circuit> {
37 3 : &self.constant_circuit
38 3 : }
39 :
40 : /// Returns iterator over circuits for measurement.
41 : ///
42 : /// # Returns
43 : ///
44 : /// * `Box<dyn Iterator<Item = &'a Circuit> + 'a>` - The quantum circuits.
45 3 : fn circuits<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Circuit> + 'a> {
46 3 : Box::new(self.circuits.iter())
47 3 : }
48 :
49 : /// Returns clone of Measurement with symbolic parameters replaced.
50 : ///
51 : /// # Arguments
52 : ///
53 : /// * `substituted_parameters` - The HashMap containing the substitutions to use in the Circuit.
54 : ///
55 : /// # Returns
56 : ///
57 : /// * `Ok(Self)` - The Circuits with the parameters substituted.
58 : /// * `Err(RoqoqoError)` - The substitution failed.
59 : ///
60 3 : fn substitute_parameters(
61 3 : &self,
62 3 : substituted_parameters: HashMap<String, f64>,
63 3 : ) -> Result<Self, RoqoqoError> {
64 3 : let mut calculator = qoqo_calculator::Calculator::new();
65 9 : for (name, val) in substituted_parameters.iter() {
66 6 : calculator.set_variable(name, *val)
67 : }
68 3 : let new_constant_circuit = match &self.constant_circuit {
69 0 : None => None,
70 3 : Some(c) => Some(c.substitute_parameters(&mut calculator)?),
71 : };
72 2 : let mut new_circuits = Vec::new();
73 2 : for circ in self.circuits.iter() {
74 2 : let mut calculator = qoqo_calculator::Calculator::new();
75 6 : for (name, val) in substituted_parameters.iter() {
76 4 : calculator.set_variable(name, *val)
77 : }
78 2 : new_circuits.push(circ.substitute_parameters(&mut calculator)?)
79 : }
80 2 : Ok(Self {
81 2 : constant_circuit: new_constant_circuit,
82 2 : circuits: new_circuits,
83 2 : })
84 3 : }
85 : }
|