Maestro 0.3.1
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
Operations.h
Go to the documentation of this file.
1
13
14#pragma once
15
16#ifndef _CIRCUIT_OPERATIONS_H_
17#define _CIRCUIT_OPERATIONS_H_
18
20#include "../Types.h"
21
22namespace Circuits {
50
51// simulators keep track of the quantum state, but there are things that are not
52// part of it that need keeping around (for example, the result of a
53// measurement, or if it's a 'random generation' operation, the generated
54// number), so here it is the values in there are needed either for the end
55// result or for the next operation (conditional gate, conditional measurement)
56
66 public:
74 OperationState(size_t numBits = 0) { AllocateBits(numBits); }
75
83 OperationState(const OperationState &other) : bits(other.bits) {}
84
93 : bits(std::move(other.bits)) {}
94
101 OperationState(const std::vector<bool> &b) : bits(b) {}
102
109 OperationState(std::vector<bool> &&b) : bits(std::move(b)) {}
110
118 bits = other.bits;
119 return *this;
120 }
121
129 bits.swap(other.bits);
130 return *this;
131 }
132
139 OperationState &operator=(const std::vector<bool> &b) {
140 bits = b;
141 return *this;
142 }
143
150 OperationState &operator=(std::vector<bool> &&b) {
151 bits.swap(b);
152 return *this;
153 }
154
162 void AllocateBits(size_t numBits) {
163 bits.resize(bits.size() + numBits, false);
164 }
165
171 void Clear() { bits.clear(); }
172
179 size_t GetNumBits() const { return bits.size(); }
180
188 bool GetBit(size_t index) const {
189 if (index > bits.size()) return false;
190
191 return bits[index];
192 }
193
201 std::vector<bool> GetBits(const std::vector<size_t> &indices) const {
202 std::vector<bool> results(indices.size(), false);
203
204 for (size_t i = 0; i < indices.size(); ++i)
205 if (indices[i] < bits.size()) results[i] = bits[indices[i]];
206
207 return results;
208 }
209
216 const std::vector<bool> &GetAllBits() const { return bits; }
217
224 std::vector<bool> GetAllBitsCopy() const { return bits; }
225
233 void SetBit(size_t index, bool value = true) {
234 if (index > bits.size()) 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()) bits[indices[i]] = results & 1;
273 results >>= 1;
274 }
275 }
276
285 void Swap(OperationState &results) { bits.swap(results.bits); }
286
299 void Remap(const std::unordered_map<Types::qubit_t, Types::qubit_t> &mapping,
300 bool ignoreNotMapped = false, size_t newSize = 0) {
301 std::vector<bool> newBits(
302 newSize > 0 ? newSize
303 : (ignoreNotMapped ? mapping.size() : bits.size()),
304 false);
305
306 for (size_t i = 0; i < bits.size(); ++i) {
307 const auto it = mapping.find(i);
308 if (it != mapping.end())
309 newBits[it->second] = bits[i];
310 else if (!ignoreNotMapped && i < newBits.size())
311 newBits[i] = bits[i];
312 }
313
314 bits.swap(newBits);
315 }
316
329 void RemapWithVector(const std::vector<Types::qubit_t> &mapping,
330 bool ignoreNotMapped = false, size_t newSize = 0) {
331 std::vector<bool> newBits(
332 newSize > 0 ? newSize
333 : (ignoreNotMapped ? mapping.size() : bits.size()),
334 false);
335
336 for (size_t i = 0; i < bits.size(); ++i) {
337 if (i < mapping.size())
338 newBits[mapping.at(i)] = bits[i];
339 else if (!ignoreNotMapped && i < newBits.size())
340 newBits[i] = bits[i];
341 }
342
343 bits.swap(newBits);
344 }
345
346 private:
347 std::vector<bool> bits;
348};
349
359template <typename Time = Types::time_type>
360class IOperation : public std::enable_shared_from_this<IOperation<Time>> {
361 public:
368 IOperation(Time delay = 0) : delay(delay){};
369
377 virtual ~IOperation() = default;
378
388 virtual void Execute(const std::shared_ptr<Simulators::ISimulator> &sim,
389 OperationState &state) const = 0;
390
398 virtual OperationType GetType() const { return OperationType::kNoOp; }
399
406 virtual std::shared_ptr<IOperation<Time>> Clone() const = 0;
407
418 virtual std::shared_ptr<IOperation<Time>> Remap(
419 const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
420 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap = {})
421 const = 0;
422
440
455
467
474 virtual Types::qubits_vector AffectedQubits() const { return {}; }
475
482 virtual std::vector<size_t> AffectedBits() const { return {}; }
483
491 std::shared_ptr<IOperation<Time>> getptr() {
492 return std::enable_shared_from_this<IOperation<Time>>::shared_from_this();
493 }
494
501 Time GetDelay() const { return delay; }
502
509 virtual void SetDelay(Time d) { delay = d; }
510
520 virtual bool IsClifford() const { return false; }
521
530 virtual bool IsBranching() const { return false; }
531
532 private:
533 Time delay;
534};
535
544template <typename Time = Types::time_type>
545class NoOperation : public IOperation<Time> {
546 public:
553 NoOperation(Time delay = 0) : IOperation<Time>(delay){};
554
567 void Execute(const std::shared_ptr<Simulators::ISimulator> &sim,
568 OperationState &state) const override {}
569
576 std::shared_ptr<IOperation<Time>> Clone() const override {
577 return std::make_shared<NoOperation<Time>>(NoOperation<Time>::GetDelay());
578 }
579
590 std::shared_ptr<IOperation<Time>> Remap(
591 const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
592 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap)
593 const override {
594 return this->Clone();
595 }
596
606 bool IsClifford() const override { return true; }
607};
608
617template <typename Time = Types::time_type>
618class IGateOperation : public IOperation<Time> {
619 public:
626 IGateOperation(Time delay = 0) : IOperation<Time>(delay){};
627
635 OperationType GetType() const override { return OperationType::kGate; }
636
643 virtual unsigned int GetNumQubits() const = 0;
644
653 virtual void SetQubit(Types::qubit_t qubit, unsigned long index = 0) = 0;
654
663 virtual Types::qubit_t GetQubit(unsigned int index = 0) const = 0;
664};
665
666} // namespace Circuits
667
668#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:635
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:626
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:520
virtual std::vector< size_t > AffectedBits() const
Returns the affected bits.
Definition Operations.h:482
virtual bool CanAffectQuantumState() const
Find if the operation can affect the quantum state.
Definition Operations.h:431
virtual Types::qubits_vector AffectedQubits() const
Returns the affected qubits.
Definition Operations.h:474
Time GetDelay() const
Get the delay of the operation.
Definition Operations.h:501
virtual void SetDelay(Time d)
Set the delay of the operation.
Definition Operations.h:509
virtual OperationType GetType() const
Get the type of the operation.
Definition Operations.h:398
virtual bool IsBranching() const
Checks if the operation is a branching one.
Definition Operations.h:530
IOperation(Time delay=0)
Construct a new IOperation object.
Definition Operations.h:368
virtual bool IsConditional() const
Find if the operation is a conditional operation.
Definition Operations.h:462
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:491
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:576
bool IsClifford() const override
Checks if the operation is a Clifford one.
Definition Operations.h:606
NoOperation(Time delay=0)
Construct a new NoOperation object.
Definition Operations.h:553
void Execute(const std::shared_ptr< Simulators::ISimulator > &sim, OperationState &state) const override
Execute the operation.
Definition Operations.h:567
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:590
The state class that stores the classical state of a quantum circuit execution.
Definition Operations.h:65
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:83
const std::vector< bool > & GetAllBits() const
Get the classical bits.
Definition Operations.h:216
OperationState(size_t numBits=0)
Construct a new Operation State object.
Definition Operations.h:74
void AllocateBits(size_t numBits)
Allocate more bits.
Definition Operations.h:162
OperationState(std::vector< bool > &&b)
Construct a new Operation State object.
Definition Operations.h:109
std::vector< bool > GetBits(const std::vector< size_t > &indices) const
Get the classical bits at the specified indices.
Definition Operations.h:201
void SetBit(size_t index, bool value=true)
Set the classical bit at the specified index.
Definition Operations.h:233
OperationState & operator=(const std::vector< bool > &b)
Assign the bits.
Definition Operations.h:139
void Clear()
Clear the classical state.
Definition Operations.h:171
OperationState(OperationState &&other) noexcept
Construct a new Operation State object.
Definition Operations.h:92
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:179
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:299
OperationState(const std::vector< bool > &b)
Construct a new Operation State object.
Definition Operations.h:101
std::vector< bool > GetAllBitsCopy() const
Get the classical bits.
Definition Operations.h:224
bool GetBit(size_t index) const
Get the classical bit at the specified index.
Definition Operations.h:188
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:329
OperationState & operator=(OperationState &&other) noexcept
Assign the bits.
Definition Operations.h:128
void Swap(OperationState &results)
Set results.
Definition Operations.h:285
OperationState & operator=(const OperationState &other)
Assign the bits.
Definition Operations.h:117
OperationState & operator=(std::vector< bool > &&b)
Assign the bits.
Definition Operations.h:150
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:27
@ kConditionalGate
conditional gate, similar with gate, but conditioned on something from 'OperationState'
Definition Operations.h:31
@ kDelay
a delay or idle period on one or more qubits
Definition Operations.h:48
@ kNoOp
no operation, just a placeholder, could be used to erase some operation from a circuit
Definition Operations.h:42
@ kComposite
a composite operation, contains other operations - should not be used in the beginning,...
Definition Operations.h:44
@ kRandomGen
random classical bit generator, result in 'OperationState'
Definition Operations.h:30
@ kConditionalRandomGen
conditional random generator, similar with random gen, but conditioned on something from 'OperationSt...
Definition Operations.h:36
@ kConditionalMeasurement
conditional measurement, similar with measurement, but conditioned on something from 'OperationState'
Definition Operations.h:33
@ kMeasurement
measurement, result in 'OperationState'
Definition Operations.h:29
@ kGate
the usual quantum gate, result stays in simulator's state
Definition Operations.h:28
@ kReset
reset, no result in 'state', just apply measurement, then apply not on all qubits that were measured ...
Definition Operations.h:39
@ kQuantumChannel
a non-unitary CPTP operation on the simulator state
Definition Operations.h:47
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
Definition Types.h:22
uint_fast64_t qubit_t
The type of a qubit.
Definition Types.h:21