Maestro 0.1.0
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
Operations.h
Go to the documentation of this file.
1
12
13#pragma once
14
15#ifndef _CIRCUIT_OPERATIONS_H_
16#define _CIRCUIT_OPERATIONS_H_
17
19#include "../Types.h"
20
21namespace Circuits {
47
48// simulators keep track of the quantum state, but there are things that are not
49// part of it that need keeping around (for example, the result of a
50// measurement, or if it's a 'random generation' operation, the generated
51// number), so here it is the values in there are needed either for the end
52// result or for the next operation (conditional gate, conditional measurement)
53
63public:
71 OperationState(size_t numBits = 0) { AllocateBits(numBits); }
72
80 OperationState(const OperationState &other) : bits(other.bits) {}
81
90 : bits(std::move(other.bits)) {}
91
98 OperationState(const std::vector<bool> &b) : bits(b) {}
99
106 OperationState(std::vector<bool> &&b) : bits(std::move(b)) {}
107
115 bits = other.bits;
116 return *this;
117 }
118
126 bits.swap(other.bits);
127 return *this;
128 }
129
136 OperationState &operator=(const std::vector<bool> &b) {
137 bits = b;
138 return *this;
139 }
140
147 OperationState &operator=(std::vector<bool> &&b) {
148 bits.swap(b);
149 return *this;
150 }
151
159 void AllocateBits(size_t numBits) {
160 bits.resize(bits.size() + numBits, false);
161 }
162
168 void Clear() { bits.clear(); }
169
176 size_t GetNumBits() const { return bits.size(); }
177
185 bool GetBit(size_t index) const {
186 if (index > bits.size())
187 return false;
188
189 return bits[index];
190 }
191
199 std::vector<bool> GetBits(const std::vector<size_t> &indices) const {
200 std::vector<bool> results(indices.size(), false);
201
202 for (size_t i = 0; i < indices.size(); ++i)
203 if (indices[i] < bits.size())
204 results[i] = bits[indices[i]];
205
206 return results;
207 }
208
215 const std::vector<bool> &GetAllBits() const { return bits; }
216
223 std::vector<bool> GetAllBitsCopy() const { return bits; }
224
232 void SetBit(size_t index, bool value = true) {
233 if (index > bits.size())
234 return;
235
236 bits[index] = value;
237 }
238
246 void Reset(bool value = false) { std::fill(bits.begin(), bits.end(), value); }
247
255 void SetResultsInOrder(const std::vector<bool> &results) {
256 const size_t theSize = std::max(bits.size(), results.size());
257
258 bits = results;
259 bits.resize(theSize, false);
260 }
261
270 void SetResults(const std::vector<size_t> &indices, size_t results) {
271 for (int i = 0; i < static_cast<int>(indices.size()); ++i) {
272 if (indices[i] < bits.size())
273 bits[indices[i]] = results & 1;
274 results >>= 1;
275 }
276 }
277
286 void Swap(OperationState &results) { bits.swap(results.bits); }
287
300 void Remap(const std::unordered_map<Types::qubit_t, Types::qubit_t> &mapping,
301 bool ignoreNotMapped = false, size_t newSize = 0) {
302 std::vector<bool> newBits(
303 newSize > 0 ? newSize
304 : (ignoreNotMapped ? mapping.size() : bits.size()),
305 false);
306
307 for (size_t i = 0; i < bits.size(); ++i) {
308 const auto it = mapping.find(i);
309 if (it != mapping.end())
310 newBits[it->second] = bits[i];
311 else if (!ignoreNotMapped && i < newBits.size())
312 newBits[i] = bits[i];
313 }
314
315 bits.swap(newBits);
316 }
317
330 void RemapWithVector(const std::vector<Types::qubit_t> &mapping,
331 bool ignoreNotMapped = false, size_t newSize = 0) {
332 std::vector<bool> newBits(
333 newSize > 0 ? newSize
334 : (ignoreNotMapped ? mapping.size() : bits.size()),
335 false);
336
337 for (size_t i = 0; i < bits.size(); ++i) {
338 if (i < mapping.size())
339 newBits[mapping.at(i)] = bits[i];
340 else if (!ignoreNotMapped && i < newBits.size())
341 newBits[i] = bits[i];
342 }
343
344 bits.swap(newBits);
345 }
346
347private:
348 std::vector<bool> bits;
349};
350
360template <typename Time = Types::time_type>
361class IOperation : public std::enable_shared_from_this<IOperation<Time>> {
362public:
369 IOperation(Time delay = 0) : delay(delay){};
370
378 virtual ~IOperation() = default;
379
389 virtual void Execute(const std::shared_ptr<Simulators::ISimulator> &sim,
390 OperationState &state) const = 0;
391
399 virtual OperationType GetType() const { return OperationType::kNoOp; }
400
407 virtual std::shared_ptr<IOperation<Time>> Clone() const = 0;
408
419 virtual std::shared_ptr<IOperation<Time>>
420 Remap(const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
421 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap = {})
422 const = 0;
423
440
449 virtual bool NeedsEntanglementForDistribution() const {
450 return (GetType() == OperationType::kGate ||
452 AffectedQubits().size() > 1;
453 }
454
466
473 virtual Types::qubits_vector AffectedQubits() const { return {}; }
474
481 virtual std::vector<size_t> AffectedBits() const { return {}; }
482
490 std::shared_ptr<IOperation<Time>> getptr() {
491 return std::enable_shared_from_this<IOperation<Time>>::shared_from_this();
492 }
493
500 Time GetDelay() const { return delay; }
501
508 void SetDelay(Time d) { delay = d; }
509
519 virtual bool IsClifford() const { return false; }
520
521private:
522 Time delay;
523};
524
533template <typename Time = Types::time_type>
534class NoOperation : public IOperation<Time> {
535public:
542 NoOperation(Time delay = 0) : IOperation<Time>(delay){};
543
556 void Execute(const std::shared_ptr<Simulators::ISimulator> &sim,
557 OperationState &state) const override {}
558
565 std::shared_ptr<IOperation<Time>> Clone() const override {
566 return std::make_shared<NoOperation<Time>>(NoOperation<Time>::GetDelay());
567 }
568
579 std::shared_ptr<IOperation<Time>>
580 Remap(const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
581 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap)
582 const override {
583 return this->Clone();
584 }
585
595 bool IsClifford() const override { return true; }
596};
597
606template <typename Time = Types::time_type>
607class IGateOperation : public IOperation<Time> {
608public:
615 IGateOperation(Time delay = 0) : IOperation<Time>(delay){};
616
624 OperationType GetType() const override { return OperationType::kGate; }
625
632 virtual unsigned int GetNumQubits() const = 0;
633
642 virtual void SetQubit(Types::qubit_t qubit, unsigned long index = 0) = 0;
643
652 virtual Types::qubit_t GetQubit(unsigned int index = 0) const = 0;
653};
654
655} // namespace Circuits
656
657#endif // !_CIRCUIT_OPERATIONS_H_
virtual Types::qubit_t GetQubit(unsigned int index=0) const =0
Get the qubit involved.
OperationType GetType() const override
Get the type of the operation.
Definition Operations.h:624
virtual void SetQubit(Types::qubit_t qubit, unsigned long index=0)=0
Set the qubits involved.
IGateOperation(Time delay=0)
Construct a new IGateOperation object.
Definition Operations.h:615
virtual unsigned int GetNumQubits() const =0
Get the number of qubits.
virtual bool IsClifford() const
Checks if the operation is a Clifford one.
Definition Operations.h:519
virtual std::vector< size_t > AffectedBits() const
Returns the affected bits.
Definition Operations.h:481
virtual bool CanAffectQuantumState() const
Find if the operation can affect the quantum state.
Definition Operations.h:432
void SetDelay(Time d)
Set the delay of the operation.
Definition Operations.h:508
virtual Types::qubits_vector AffectedQubits() const
Returns the affected qubits.
Definition Operations.h:473
Time GetDelay() const
Get the delay of the operation.
Definition Operations.h:500
virtual OperationType GetType() const
Get the type of the operation.
Definition Operations.h:399
IOperation(Time delay=0)
Construct a new IOperation object.
Definition Operations.h:369
virtual bool IsConditional() const
Find if the operation is a conditional operation.
Definition Operations.h:461
virtual ~IOperation()=default
Destroy the IOperation object.
virtual 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 =0
Get a shared pointer to a remapped operation.
virtual std::shared_ptr< IOperation< Time > > Clone() const =0
Get a shared pointer to a clone of this object.
virtual void Execute(const std::shared_ptr< Simulators::ISimulator > &sim, OperationState &state) const =0
Execute the operation.
std::shared_ptr< IOperation< Time > > getptr()
Get a shared pointer to this object.
Definition Operations.h:490
virtual bool NeedsEntanglementForDistribution() const
Find if the operation needs entanglement for distribution.
Definition Operations.h:449
std::shared_ptr< IOperation< Time > > Clone() const override
Get a shared pointer to a clone of this object.
Definition Operations.h:565
bool IsClifford() const override
Checks if the operation is a Clifford one.
Definition Operations.h:595
NoOperation(Time delay=0)
Construct a new NoOperation object.
Definition Operations.h:542
void Execute(const std::shared_ptr< Simulators::ISimulator > &sim, OperationState &state) const override
Execute the operation.
Definition Operations.h:556
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.
Definition Operations.h:580
The state class that stores the classical state of a quantum circuit execution.
Definition Operations.h:62
void Reset(bool value=false)
Set the classical bits with the specified value.
Definition Operations.h:246
OperationState(const OperationState &other)
Construct a new Operation State object.
Definition Operations.h:80
const std::vector< bool > & GetAllBits() const
Get the classical bits.
Definition Operations.h:215
OperationState(size_t numBits=0)
Construct a new Operation State object.
Definition Operations.h:71
void AllocateBits(size_t numBits)
Allocate more bits.
Definition Operations.h:159
OperationState(std::vector< bool > &&b)
Construct a new Operation State object.
Definition Operations.h:106
std::vector< bool > GetBits(const std::vector< size_t > &indices) const
Get the classical bits at the specified indices.
Definition Operations.h:199
void SetBit(size_t index, bool value=true)
Set the classical bit at the specified index.
Definition Operations.h:232
OperationState & operator=(const std::vector< bool > &b)
Assign the bits.
Definition Operations.h:136
void Clear()
Clear the classical state.
Definition Operations.h:168
OperationState(OperationState &&other) noexcept
Construct a new Operation State object.
Definition Operations.h:89
void SetResultsInOrder(const std::vector< bool > &results)
Set the classical bits.
Definition Operations.h:255
size_t GetNumBits() const
Get the number of classical bits.
Definition Operations.h:176
void Remap(const std::unordered_map< Types::qubit_t, Types::qubit_t > &mapping, bool ignoreNotMapped=false, size_t newSize=0)
Convert the state using the provided mapping.
Definition Operations.h:300
OperationState(const std::vector< bool > &b)
Construct a new Operation State object.
Definition Operations.h:98
std::vector< bool > GetAllBitsCopy() const
Get the classical bits.
Definition Operations.h:223
bool GetBit(size_t index) const
Get the classical bit at the specified index.
Definition Operations.h:185
void RemapWithVector(const std::vector< Types::qubit_t > &mapping, bool ignoreNotMapped=false, size_t newSize=0)
Convert the state using the provided mapping.
Definition Operations.h:330
OperationState & operator=(OperationState &&other) noexcept
Assign the bits.
Definition Operations.h:125
void Swap(OperationState &results)
Set results.
Definition Operations.h:286
OperationState & operator=(const OperationState &other)
Assign the bits.
Definition Operations.h:114
OperationState & operator=(std::vector< bool > &&b)
Assign the bits.
Definition Operations.h:147
void SetResults(const std::vector< size_t > &indices, size_t results)
Set the classical bits at the specified indices.
Definition Operations.h:270
OperationType
The type of operations.
Definition Operations.h:26
@ kConditionalGate
conditional gate, similar with gate, but conditioned on something from 'OperationState'
Definition Operations.h:30
@ kNoOp
no operation, just a placeholder, could be used to erase some operation from a circuit
Definition Operations.h:41
@ kComposite
a composite operation, contains other operations - should not be used in the beginning,...
Definition Operations.h:43
@ kRandomGen
random classical bit generator, result in 'OperationState'
Definition Operations.h:29
@ kConditionalRandomGen
conditional random generator, similar with random gen, but conditioned on something from 'OperationSt...
Definition Operations.h:35
@ kConditionalMeasurement
conditional measurement, similar with measurement, but conditioned on something from 'OperationState'
Definition Operations.h:32
@ kMeasurement
measurement, result in 'OperationState'
Definition Operations.h:28
@ kGate
the usual quantum gate, result stays in simulator's state
Definition Operations.h:27
@ kReset
reset, no result in 'state', just apply measurement, then apply not on all qubits that were measured ...
Definition Operations.h:38
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
Definition Types.h:21
uint_fast64_t qubit_t
The type of a qubit.
Definition Types.h:20