Maestro 0.2.11
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
Conditional.h
Go to the documentation of this file.
1
16
17#pragma once
18
19#ifndef _CONDITIONAL_H_
20#define _CONDITIONAL_H_
21
22#include "Measurements.h"
23#include "QuantumGates.h"
24#include "RandomOp.h"
25
26namespace Circuits {
27
36class ICondition : public std::enable_shared_from_this<ICondition> {
37 public:
44 ICondition(const std::vector<size_t> &ind) : indices(ind) {}
45
53 virtual ~ICondition() = default;
54
63 virtual bool IsConditionMet(OperationState &state) const = 0;
64
71 const std::vector<size_t> &GetBitsIndices() const { return indices; }
72
79 void SetBitsIndices(const std::vector<size_t> &ind) { indices = ind; }
80
87 virtual std::shared_ptr<ICondition> Clone() const = 0;
88
98 virtual std::shared_ptr<ICondition> Remap(
99 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap = {})
100 const = 0;
101
109 std::shared_ptr<ICondition> getptr() {
110 return std::enable_shared_from_this<ICondition>::shared_from_this();
111 }
112
113 private:
114 std::vector<size_t>
115 indices;
116};
117
128 public:
137 EqualCondition(const std::vector<size_t> &ind, const std::vector<bool> &b)
138 : ICondition(ind), bits(b) {}
139
147 bool IsConditionMet(OperationState &state) const override {
148 return state.GetBits(GetBitsIndices()) == GetAllBits();
149 }
150
157 const std::vector<bool> &GetAllBits() const { return bits; }
158
165 void SetBits(const std::vector<bool> &b) { bits = b; }
166
173 std::shared_ptr<ICondition> Clone() const override {
174 return std::make_shared<EqualCondition>(GetBitsIndices(), GetAllBits());
175 }
176
186 std::shared_ptr<ICondition> Remap(
187 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap = {})
188 const override {
189 auto newCond = this->Clone();
190
191 auto newBits = newCond->GetBitsIndices();
192 for (size_t i = 0; i < newBits.size(); ++i) {
193 const auto bitit = bitsMap.find(newBits[i]);
194 if (bitit != bitsMap.end()) newBits[i] = bitit->second;
195 // else throw std::invalid_argument("Conditional operation: bit not found
196 // in the map, couldn't remap.");
197 }
198 newCond->SetBitsIndices(newBits);
199
200 return newCond;
201 }
202
203 private:
204 std::vector<bool> bits;
205};
206
217template <typename Time = Types::time_type>
218class IConditionalOperation : public IOperation<Time> {
219 public:
231 IConditionalOperation(const std::shared_ptr<IOperation<Time>> &operation,
232 const std::shared_ptr<ICondition> &condition,
233 Time delay = 0)
234 : IOperation<Time>(delay), operation(operation), condition(condition) {}
235
248 void Execute(const std::shared_ptr<Simulators::ISimulator> &sim,
249 OperationState &state) const override {
250 if (!condition || !operation) return;
251
252 if (condition->IsConditionMet(state))
253 operation->Execute(sim, state);
254 else if (sim)
255 sim->IncrementGatesCounter();
256 }
257
264 void SetOperation(const std::shared_ptr<IOperation<Time>> &op) {
265 if (!op) return;
266 // the reason why 'recursive' conditional gates are not allowed (as in
267 // conditional-conditional-...-gate) is because of the distribution for the
268 // network execution would work fine as long as it's 'local'
269 else if ((op->GetType() == OperationType::kGate &&
270 this->GetType() != OperationType::kConditionalGate) ||
271 (op->GetType() == OperationType::kMeasurement &&
272 this->GetType() != OperationType::kConditionalMeasurement) ||
273 (op->GetType() == OperationType::kRandomGen &&
274 this->GetType() != OperationType::kConditionalRandomGen))
275 return;
276
277 operation = op;
278 }
279
287 std::shared_ptr<IOperation<Time>> GetOperation() const { return operation; }
288
296 void SetCondition(const std::shared_ptr<ICondition> &cond) {
297 condition = cond;
298 }
299
307 std::shared_ptr<ICondition> GetCondition() const { return condition; }
308
315 std::vector<size_t> AffectedBits() const override {
316 if (!condition) return {};
317
318 return condition->GetBitsIndices();
319 }
320
328 if (!operation) return {};
329
330 return operation->AffectedQubits();
331 }
332
343 std::shared_ptr<IOperation<Time>> Remap(
344 const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
345 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap = {})
346 const override {
347 const auto condOp =
348 std::static_pointer_cast<IConditionalOperation<Time>>(this->Clone());
349
350 condOp->SetCondition(condOp->GetCondition()->Remap(bitsMap));
351 condOp->SetOperation(condOp->GetOperation()->Remap(qubitsMap, bitsMap));
352
353 return condOp;
354 }
355
365 bool IsClifford() const override {
366 if (!operation) return true;
367
368 return operation->IsClifford();
369 }
370
379 bool IsBranching() const override {
380 if (!operation) return false;
381
382 return operation->IsBranching();
383 }
384
385 private:
386 std::shared_ptr<IOperation<Time>>
387 operation;
388 std::shared_ptr<ICondition> condition;
389};
390
400template <typename Time = Types::time_type>
402 public:
415 ConditionalGate(const std::shared_ptr<IGateOperation<Time>> &operation,
416 const std::shared_ptr<ICondition> &condition, Time delay = 0)
417 : IConditionalOperation<Time>(operation, condition, delay) {}
418
426 OperationType GetType() const override {
428 }
429
436 std::shared_ptr<IOperation<Time>> Clone() const override {
437 const auto gate = std::static_pointer_cast<IGateOperation<Time>>(
439 const auto cond = std::static_pointer_cast<ICondition>(
441
442 return std::make_shared<ConditionalGate<Time>>(
443 gate, cond, IOperation<Time>::GetDelay());
444 }
445};
446
456template <typename Time = Types::time_type>
458 public:
472 const std::shared_ptr<MeasurementOperation<Time>> &operation,
473 const std::shared_ptr<ICondition> &condition, Time delay = 0)
474 : IConditionalOperation<Time>(operation, condition, delay) {}
475
486
493 std::shared_ptr<IOperation<Time>> Clone() const override {
494 return std::make_shared<ConditionalMeasurement<Time>>(
495 std::static_pointer_cast<MeasurementOperation<Time>>(
497 std::static_pointer_cast<ICondition>(
500 }
501};
502
512template <typename Time = Types::time_type>
514 public:
527 ConditionalRandomGen(const std::shared_ptr<Random<Time>> &operation,
528 const std::shared_ptr<ICondition> &condition,
529 Time delay = 0)
530 : IConditionalOperation<Time>(operation, condition, delay) {}
531
539 OperationType GetType() const override {
541 }
542
549 std::shared_ptr<IOperation<Time>> Clone() const override {
550 return std::make_shared<ConditionalRandomGen<Time>>(
551 std::static_pointer_cast<Random<Time>>(
553 std::static_pointer_cast<ICondition>(
556 }
557
566 Types::qubits_vector AffectedQubits() const override { return {}; }
567};
568
569} // namespace Circuits
570
571#endif // !_CONDITIONAL_H_
ConditionalGate(const std::shared_ptr< IGateOperation< Time > > &operation, const std::shared_ptr< ICondition > &condition, Time delay=0)
Construct a new ConditionalGate object.
OperationType GetType() const override
Get the type of the operation.
std::shared_ptr< IOperation< Time > > Clone() const override
Get a shared pointer to a clone of this object.
ConditionalMeasurement(const std::shared_ptr< MeasurementOperation< Time > > &operation, const std::shared_ptr< ICondition > &condition, Time delay=0)
Construct a new ConditionalMeasurement object.
OperationType GetType() const override
Get the type of the operation.
std::shared_ptr< IOperation< Time > > Clone() const override
Get a shared pointer to a clone of this object.
OperationType GetType() const override
Get the type of the operation.
ConditionalRandomGen(const std::shared_ptr< Random< Time > > &operation, const std::shared_ptr< ICondition > &condition, Time delay=0)
Construct a new ConditionalRandomGen object.
Types::qubits_vector AffectedQubits() const override
Get the quantum bits affected by the operation.
std::shared_ptr< IOperation< Time > > Clone() const override
Get a shared pointer to a clone of this object.
std::shared_ptr< ICondition > Remap(const std::unordered_map< Types::qubit_t, Types::qubit_t > &bitsMap={}) const override
Get a shared pointer to a remapped condition.
bool IsConditionMet(OperationState &state) const override
Check if the condition is met.
const std::vector< bool > & GetAllBits() const
Get the values to compare the bits to.
std::shared_ptr< ICondition > Clone() const override
Get a shared pointer to a clone of this object.
void SetBits(const std::vector< bool > &b)
Set the values to compare the bits to.
EqualCondition(const std::vector< size_t > &ind, const std::vector< bool > &b)
Construct a new EqualCondition object.
virtual ~ICondition()=default
Virtual destructor.
virtual bool IsConditionMet(OperationState &state) const =0
Check if the condition is met.
const std::vector< size_t > & GetBitsIndices() const
Get the indices of the bits used in the condition.
Definition Conditional.h:71
std::shared_ptr< ICondition > getptr()
Get a shared pointer to this object.
void SetBitsIndices(const std::vector< size_t > &ind)
Set the indices of the bits used in the condition.
Definition Conditional.h:79
virtual std::shared_ptr< ICondition > Remap(const std::unordered_map< Types::qubit_t, Types::qubit_t > &bitsMap={}) const =0
Get a shared pointer to a remapped condition.
virtual std::shared_ptr< ICondition > Clone() const =0
Get a shared pointer to a clone of this object.
ICondition(const std::vector< size_t > &ind)
Construct a new ICondition object.
Definition Conditional.h:44
void SetCondition(const std::shared_ptr< ICondition > &cond)
Set the condition for the conditional operation.
bool IsClifford() const override
Checks if the operation is a Clifford one.
std::shared_ptr< IOperation< Time > > GetOperation() const
Get the operation for the conditional operation.
bool IsBranching() const override
Checks if the operation is a branching one.
IConditionalOperation(const std::shared_ptr< IOperation< Time > > &operation, const std::shared_ptr< ICondition > &condition, Time delay=0)
Construct a new IConditionalOperation object.
void SetOperation(const std::shared_ptr< IOperation< Time > > &op)
Set the operation for the conditional operation.
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.
std::vector< size_t > AffectedBits() const override
Get bits that are involved in the condition.
std::shared_ptr< ICondition > GetCondition() const
Get the condition for the conditional operation.
void Execute(const std::shared_ptr< Simulators::ISimulator > &sim, OperationState &state) const override
Execute the operation.
Types::qubits_vector AffectedQubits() const override
Get the qubits affected by the operation.
The gate operation interface.
Definition Operations.h:614
Time GetDelay() const
Get the delay of the operation.
Definition Operations.h:497
IOperation(Types::time_type delay=0)
Definition Operations.h:366
virtual std::shared_ptr< IOperation< Types::time_type > > Clone() const=0
Measurement operation class.
The state class that stores the classical state of a quantum circuit execution.
Definition Operations.h:63
std::vector< bool > GetBits(const std::vector< size_t > &indices) const
Get the classical bits at the specified indices.
Definition Operations.h:199
Random operation.
Definition RandomOp.h:34
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
@ 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
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
Definition Types.h:22