Maestro 0.1.0
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
Measurements.h
Go to the documentation of this file.
1
15#pragma once
16
17#ifndef _MEASUREMENTS_H_
18#define _MEASUREMENTS_H_
19
20#include "Operations.h"
21#include <vector>
22
23namespace Circuits {
24
35template <typename Time = Types::time_type>
36class MeasurementOperation : public IOperation<Time> {
37 public:
49 const std::vector<std::pair<Types::qubit_t, size_t>> &qs = {},
50 Time delay = 0)
51 : IOperation<Time>(delay) {
52 SetQubits(qs);
53 }
54
63
70 virtual size_t GetNumQubits() const { return qubits.size(); }
71
77 void Clear() {
78 qubits.clear();
79 bits.clear();
80 }
81
90 void SetQubits(const std::vector<std::pair<Types::qubit_t, size_t>> &qs) {
91 qubits.resize(qs.size());
92 bits.resize(qs.size());
93 for (size_t i = 0; i < qs.size(); ++i) {
94 qubits[i] = qs[i].first;
95 bits[i] = qs[i].second;
96 }
97 }
98
105 const Types::qubits_vector &GetQubits() const { return qubits; }
106
113 const std::vector<size_t> &GetBitsIndices() const { return bits; }
114
124 void Execute(const std::shared_ptr<Simulators::ISimulator> &sim,
125 OperationState &state) const override {
126 if (qubits.empty()) return;
127
128 size_t res = sim->Measure(qubits);
129
130 for (size_t i = 0; i < qubits.size(); ++i) {
131 state.SetBit(bits[i], (res & 1) != 0);
132 res >>= 1;
133 }
134 }
135
147 void Sample(const std::shared_ptr<Simulators::ISimulator> &sim,
148 OperationState &state) const {
149 if (qubits.empty()) return;
150
151 size_t res = sim->SampleCounts(qubits, 1).begin()->first;
152
153 for (auto bit : bits) {
154 state.SetBit(bit, (res & 1) != 0);
155 res >>= 1;
156 }
157 }
158
159 void SetStateFromSample(size_t measurements, OperationState &state) const {
160 if (qubits.empty()) return;
161
162 for (size_t index = 0; index < qubits.size(); ++index) {
163 const auto cbit = bits[index];
164 const size_t qubitMask = 1ULL << index;
165 state.SetBit(cbit, (measurements & qubitMask) != 0);
166 }
167 }
168
169 void SetStateFromAllMeasurements(size_t allMeasurements,
170 OperationState &state) const {
171 if (qubits.empty()) return;
172
173 for (size_t index = 0; index < qubits.size(); ++index) {
174 const auto q = qubits[index];
175 const auto cbit = bits[index];
176
177 const size_t qubitMask = 1ULL << q;
178
179 state.SetBit(cbit, (allMeasurements & qubitMask) != 0);
180 }
181 }
182
189 std::shared_ptr<IOperation<Time>> Clone() const override {
190 std::vector<std::pair<Types::qubit_t, size_t>> qs(qubits.size());
191 for (size_t i = 0; i < qubits.size(); ++i)
192 qs[i] = std::make_pair(qubits[i], bits[i]);
193
194 return std::make_shared<MeasurementOperation<Time>>(
196 }
197
204 Types::qubits_vector AffectedQubits() const override { return qubits; }
205
212 std::vector<size_t> AffectedBits() const override { return GetBitsIndices(); }
213
224 std::shared_ptr<IOperation<Time>> Remap(
225 const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
226 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap = {})
227 const override {
228 auto newOp = this->Clone();
229
230 for (size_t i = 0; i < qubits.size(); ++i) {
231 const auto qubitit = qubitsMap.find(qubits[i]);
232 if (qubitit != qubitsMap.end())
233 std::static_pointer_cast<MeasurementOperation<Time>>(newOp)->SetQubit(
234 i, qubitit->second);
235 // else throw std::runtime_error("MeasurementOperation::Remap: qubit not
236 // found in map.");
237 }
238
239 for (size_t i = 0; i < bits.size(); ++i) {
240 const auto bitit = bitsMap.find(bits[i]);
241 if (bitit != bitsMap.end())
242 std::static_pointer_cast<MeasurementOperation<Time>>(newOp)->SetBit(
243 i, bitit->second);
244 // else throw std::runtime_error("MeasurementOperation::Remap: bit not
245 // found in map.");
246 }
247
248 return newOp;
249 }
250
260 bool IsClifford() const override { return true; }
261
269 void SetQubit(size_t index, Types::qubit_t qubit) {
270 if (index < qubits.size()) qubits[index] = qubit;
271 }
272
280 void SetBit(size_t index, Types::qubit_t bit) {
281 if (index < bits.size()) bits[index] = bit;
282 }
283
284 private:
285 Types::qubits_vector qubits;
286 std::vector<size_t>
287 bits;
288};
289
290} // namespace Circuits
291
292#endif // !_MEASUREMENTS_H_
The operation interface.
Definition Operations.h:357
Time GetDelay() const
Get the delay of the operation.
Definition Operations.h:496
Measurement operation class.
std::shared_ptr< IOperation< Time > > Clone() const override
Get a shared pointer to a clone of this object.
void SetBit(size_t index, Types::qubit_t bit)
Set the classical bit to index.
void Clear()
Clears the qubits and classical bits involved in the measurement.
void SetQubits(const std::vector< std::pair< Types::qubit_t, size_t > > &qs)
Sets the qubits and classical bits involved in the measurement.
virtual size_t GetNumQubits() const
Get the number of qubits affected by the operation.
const std::vector< size_t > & GetBitsIndices() const
Returns the classical bits where the measurement results are stored.
void SetStateFromSample(size_t measurements, OperationState &state) const
const Types::qubits_vector & GetQubits() const
Returns the qubits that are to be measured.
MeasurementOperation(const std::vector< std::pair< Types::qubit_t, size_t > > &qs={}, Time delay=0)
Constructor.
void Sample(const std::shared_ptr< Simulators::ISimulator > &sim, OperationState &state) const
Samples the measurement on the given simulator.
OperationType GetType() const override
Get the type of the operation.
void SetStateFromAllMeasurements(size_t allMeasurements, OperationState &state) const
void SetQubit(size_t index, Types::qubit_t qubit)
Set the qubit to measure.
std::vector< size_t > AffectedBits() const override
Returns the classical bits affected by the measurement.
bool IsClifford() const override
Checks if the operation is a Clifford one.
void Execute(const std::shared_ptr< Simulators::ISimulator > &sim, OperationState &state) const override
Executes the measurement on the given simulator.
std::shared_ptr< IOperation< Time > > Remap(const std::unordered_map< Types::qubit_t, Types::qubit_t > &qubitsMap, const std::unordered_map< Types::qubit_t, Types::qubit_t > &bitsMap={}) const override
Get a shared pointer to a remapped operation.
Types::qubits_vector AffectedQubits() const override
Returns the qubits affected by the measurement.
The state class that stores the classical state of a quantum circuit execution.
Definition Operations.h:62
void SetBit(size_t index, bool value=true)
Set the classical bit at the specified index.
Definition Operations.h:230
OperationType
The type of operations.
Definition Operations.h:26
@ kMeasurement
measurement, result in 'OperationState'