Maestro 0.3.11
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
Measurements.h
Go to the documentation of this file.
1
15
16#pragma once
17
18#ifndef _MEASUREMENTS_H_
19#define _MEASUREMENTS_H_
20
21#include "Operations.h"
22#include <utility>
23#include <vector>
24
25namespace Circuits
26{
27
36{
37 double p_meas1_prep0 = 0.0;
38 double p_meas0_prep1 = 0.0;
39};
40
51template <typename Time = Types::time_type> class MeasurementOperation : public IOperation<Time>
52{
53 public:
64 MeasurementOperation(const std::vector<std::pair<Types::qubit_t, size_t>> &qs = {}, Time delay = 0) : IOperation<Time>(delay)
65 {
66 SetQubits(qs);
67 }
68
76 OperationType GetType() const override
77 {
79 }
80
87 virtual size_t GetNumQubits() const
88 {
89 return qubits.size();
90 }
91
97 void Clear()
98 {
99 qubits.clear();
100 bits.clear();
101 }
102
111 void SetQubits(const std::vector<std::pair<Types::qubit_t, size_t>> &qs)
112 {
113 qubits.resize(qs.size());
114 bits.resize(qs.size());
115 for (size_t i = 0; i < qs.size(); ++i)
116 {
117 qubits[i] = qs[i].first;
118 bits[i] = qs[i].second;
119 }
120 }
121
129 {
130 return qubits;
131 }
132
139 const std::vector<size_t> &GetBitsIndices() const
140 {
141 return bits;
142 }
143
154 void Execute(const std::shared_ptr<Simulators::ISimulator> &sim, OperationState &state) const override
155 {
156 if (qubits.empty())
157 return;
158
159 auto res = sim->MeasureMany(qubits);
160
161 SetStateFromSample(res, state, sim.get());
162 }
163
175 void Sample(const std::shared_ptr<Simulators::ISimulator> &sim, OperationState &state) const
176 {
177 if (qubits.empty())
178 return;
179
180 const auto res = sim->SampleCountsMany(qubits, 1).begin()->first;
181
182 SetStateFromSample(res, state, sim.get());
183 }
184
196 void SetStateFromSample(const std::vector<bool> &measurements, OperationState &state, Simulators::ISimulator *rng = nullptr) const
197 {
198 if (qubits.empty())
199 return;
200
201 for (size_t index = 0; index < qubits.size(); ++index)
202 {
203 bool value = index < measurements.size() && measurements[index];
204
205 if (rng && index < readout.size())
206 {
207 const auto &rates = readout[index];
208 if (!value && rates.p_meas1_prep0 > 0.0 && rng->RandomUniform() < rates.p_meas1_prep0)
209 value = true;
210 else if (value && rates.p_meas0_prep1 > 0.0 && rng->RandomUniform() < rates.p_meas0_prep1)
211 value = false;
212 }
213
214 state.SetBit(bits[index], value);
215 }
216 }
217
224 std::shared_ptr<IOperation<Time>> Clone() const override
225 {
226 std::vector<std::pair<Types::qubit_t, size_t>> qs(qubits.size());
227 for (size_t i = 0; i < qubits.size(); ++i)
228 qs[i] = std::make_pair(qubits[i], bits[i]);
229
230 auto copy = std::make_shared<MeasurementOperation<Time>>(qs, IOperation<Time>::GetDelay());
231 copy->readout = readout;
232
233 return copy;
234 }
235
243 {
244 return qubits;
245 }
246
253 std::vector<size_t> AffectedBits() const override
254 {
255 return GetBitsIndices();
256 }
257
268 std::shared_ptr<IOperation<Time>> Remap(const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
269 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap = {}) const override
270 {
271 auto newOp = this->Clone();
272
273 for (size_t i = 0; i < qubits.size(); ++i)
274 {
275 const auto qubitit = qubitsMap.find(qubits[i]);
276 if (qubitit != qubitsMap.end())
277 std::static_pointer_cast<MeasurementOperation<Time>>(newOp)->SetQubit(i, qubitit->second);
278 // else throw std::runtime_error("MeasurementOperation::Remap: qubit not
279 // found in map.");
280 }
281
282 for (size_t i = 0; i < bits.size(); ++i)
283 {
284 const auto bitit = bitsMap.find(bits[i]);
285 if (bitit != bitsMap.end())
286 std::static_pointer_cast<MeasurementOperation<Time>>(newOp)->SetBit(i, bitit->second);
287 // else throw std::runtime_error("MeasurementOperation::Remap: bit not
288 // found in map.");
289 }
290
291 return newOp;
292 }
293
303 bool IsClifford() const override
304 {
305 return true;
306 }
307
315 void SetQubit(size_t index, Types::qubit_t qubit)
316 {
317 if (index < qubits.size())
318 qubits[index] = qubit;
319 }
320
328 void SetBit(size_t index, Types::qubit_t bit)
329 {
330 if (index < bits.size())
331 bits[index] = bit;
332 }
333
341 void SetReadout(std::vector<ReadoutRates> rates)
342 {
343 rates.resize(rates.empty() ? 0 : qubits.size());
344 readout = std::move(rates);
345 }
346
354 void SetReadoutAt(size_t index, const ReadoutRates &rates)
355 {
356 if (index >= qubits.size())
357 return;
358 if (readout.size() != qubits.size())
359 readout.resize(qubits.size());
360 readout[index] = rates;
361 }
362
364 const std::vector<ReadoutRates> &GetReadout() const
365 {
366 return readout;
367 }
368
370 bool HasReadout() const
371 {
372 return !readout.empty();
373 }
374
375 private:
376 Types::qubits_vector qubits;
377 std::vector<size_t> bits;
378 std::vector<ReadoutRates> readout;
379};
380
381} // namespace Circuits
382
383#endif // !_MEASUREMENTS_H_
The operation interface.
Definition Operations.h:402
Time GetDelay() const
Get the delay of the operation.
Definition Operations.h:546
IOperation(Types::time_type delay=0)
Definition Operations.h:410
std::shared_ptr< IOperation< Time > > Clone() const override
Get a shared pointer to a clone of this object.
void SetReadout(std::vector< ReadoutRates > rates)
Attach readout-error rates, one entry per measured index.
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.
void SetReadoutAt(size_t index, const ReadoutRates &rates)
Attach readout-error rates for a single measured index.
const std::vector< size_t > & GetBitsIndices() const
Returns the classical bits where the measurement results are stored.
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.
const std::vector< ReadoutRates > & GetReadout() const
Per-index readout rates, empty when none are attached.
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.
void SetStateFromSample(const std::vector< bool > &measurements, OperationState &state, Simulators::ISimulator *rng=nullptr) const
Writes sampled outcomes into the classical state, applying readout error per measured qubit.
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.
bool HasReadout() const
True when readout rates are attached to this measurement.
The state class that stores the classical state of a quantum circuit execution.
Definition Operations.h:68
void SetBit(size_t index, bool value=true)
Set the classical bit at the specified index.
Definition Operations.h:267
Interface class for a quantum computing simulator.
Definition Simulator.h:41
OperationType
The type of operations.
Definition Operations.h:29
@ kMeasurement
measurement, result in 'OperationState'
Definition Operations.h:31
double p_meas0_prep1
P(report 0 | measured 1).
double p_meas1_prep0
P(report 1 | measured 0).
Classical readout-error rates for one measured qubit.
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
Definition Types.h:24
uint_fast64_t qubit_t
The type of a qubit.
Definition Types.h:23