Maestro 0.3.1
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
Circuit/Factory.h
Go to the documentation of this file.
1
14
15#pragma once
16
17#ifndef _CIRCUIT_FACTORY_H_
18#define _CIRCUIT_FACTORY_H_
19
20#include "Circuit.h"
21#include "Conditional.h"
22#include "Measurements.h"
23#include "RandomOp.h"
24#include "Reset.h"
25
26namespace Circuits {
27
37template <typename Time = Types::time_type>
39 public:
48 static std::shared_ptr<Circuit<Time>> CreateCircuit(
49 const std::vector<std::shared_ptr<IOperation<Time>>> &ops = {}) {
50 return std::make_shared<Circuit<Time>>(ops);
51 }
52
65 static std::shared_ptr<IOperation<Time>> CreateReset(
66 const Types::qubits_vector &qubits = {},
67 const std::vector<bool> &resetTgts = {}) {
68 return std::make_shared<Reset<Time>>(qubits, 0, resetTgts);
69 }
70
79 static std::shared_ptr<IOperation<Time>> CreateDelay(
80 Types::qubit_t qubit = 0, Time duration = 0) {
81 return std::make_shared<Delay<Time>>(qubit, duration);
82 }
83
94 static std::shared_ptr<IOperation<Time>> CreateRandom(
95 const std::vector<size_t> &bits = {}, size_t seed = 0) {
96 return std::make_shared<Random<Time>>(bits, seed);
97 }
98
109 static const std::shared_ptr<IOperation<Time>> CreateMeasurement(
110 const std::vector<std::pair<Types::qubit_t, size_t>> &qs = {}) {
111 return std::make_shared<MeasurementOperation<Time>>(qs);
112 }
113
136 static const std::shared_ptr<IQuantumGate<Time>> CreateGate(
137 QuantumGateType type, size_t q1, size_t q2 = 0, size_t q3 = 0,
138 double param1 = 0, double param2 = 0, double param3 = 0,
139 double param4 = 0) {
140 // parameters that do not make sense for a gate are ignored, eg if it's a
141 // single qubit gate, q2 and q3 are ignored if it doesn't have a parameter,
142 // the parameter is ignored if it has only one, the others are ignored
143 // TODO: maybe make specialized variants, as in CreateOneQubitGate,
144 // CreateTwoQubitGate, etc
145 std::shared_ptr<IQuantumGate<Time>> gate;
146
147 switch (type) {
148 // one qubit gates
150 gate = std::make_shared<PhaseGate<Time>>(q1, param1);
151 break;
153 gate = std::make_shared<XGate<Time>>(q1);
154 break;
156 gate = std::make_shared<YGate<Time>>(q1);
157 break;
159 gate = std::make_shared<ZGate<Time>>(q1);
160 break;
162 gate = std::make_shared<HadamardGate<Time>>(q1);
163 break;
165 gate = std::make_shared<SGate<Time>>(q1);
166 break;
168 gate = std::make_shared<SdgGate<Time>>(q1);
169 break;
171 gate = std::make_shared<TGate<Time>>(q1);
172 break;
174 gate = std::make_shared<TdgGate<Time>>(q1);
175 break;
177 gate = std::make_shared<SxGate<Time>>(q1);
178 break;
180 gate = std::make_shared<SxDagGate<Time>>(q1);
181 break;
183 gate = std::make_shared<KGate<Time>>(q1);
184 break;
186 gate = std::make_shared<RxGate<Time>>(q1, param1);
187 break;
189 gate = std::make_shared<RyGate<Time>>(q1, param1);
190 break;
192 gate = std::make_shared<RzGate<Time>>(q1, param1);
193 break;
195 gate =
196 std::make_shared<UGate<Time>>(q1, param1, param2, param3, param4);
197 break;
198 // two qubit gates
200 gate = std::make_shared<SwapGate<Time>>(q1, q2);
201 break;
203 gate = std::make_shared<CXGate<Time>>(q1, q2);
204 break;
206 gate = std::make_shared<CYGate<Time>>(q1, q2);
207 break;
209 gate = std::make_shared<CZGate<Time>>(q1, q2);
210 break;
212 gate = std::make_shared<CPGate<Time>>(q1, q2, param1);
213 break;
215 gate = std::make_shared<CRxGate<Time>>(q1, q2, param1);
216 break;
218 gate = std::make_shared<CRyGate<Time>>(q1, q2, param1);
219 break;
221 gate = std::make_shared<CRzGate<Time>>(q1, q2, param1);
222 break;
224 gate = std::make_shared<CHGate<Time>>(q1, q2);
225 break;
227 gate = std::make_shared<CSxGate<Time>>(q1, q2);
228 break;
230 gate = std::make_shared<CSxDagGate<Time>>(q1, q2);
231 break;
233 gate = std::make_shared<CUGate<Time>>(q1, q2, param1, param2, param3,
234 param4);
235 break;
236 // three qubit gates
238 gate = std::make_shared<CSwapGate<Time>>(q1, q2, q3);
239 break;
241 gate = std::make_shared<CCXGate<Time>>(q1, q2, q3);
242 break;
243 default:
244 break;
245 }
246
247 return gate;
248 }
249
262 static const std::shared_ptr<IOperation<Time>> CreateGateWithVectors(
263 QuantumGateType type, const Types::qubits_vector &qubits,
264 const std::vector<double> &params = {}) {
265 return CreateGate(type, qubits.empty() ? 0 : qubits[0],
266 (qubits.size() < 2) ? 0 : qubits[1],
267 (qubits.size() < 3) ? 0 : qubits[2],
268 params.empty() ? 0. : params[0],
269 (params.size() < 2) ? 0. : params[1],
270 (params.size() < 3) ? 0. : params[2],
271 (params.size() < 4) ? 0. : params[3]);
272 }
273
274 // maybe this could be refined, have a CreateCondition with the condition
275 // type, but for now we only have equality can be done later
276
288 static std::shared_ptr<ICondition> CreateEqualCondition(
289 const std::vector<size_t> &ind, const std::vector<bool> &b) {
290 return std::make_shared<EqualCondition>(ind, b);
291 }
292
293 // we have only three conditional things, I don't think we need a single
294 // factory method for them (with a 'type' parameter)
295
308 static std::shared_ptr<IOperation<Time>> CreateConditionalGate(
309 const std::shared_ptr<IGateOperation<Time>> &operation,
310 const std::shared_ptr<ICondition> &condition) {
311 return std::make_shared<ConditionalGate<Time>>(operation, condition);
312 }
313
327 static std::shared_ptr<IOperation<Time>> CreateSimpleConditionalGate(
328 const std::shared_ptr<IGateOperation<Time>> &operation,
329 const size_t cbit) {
330 const auto eqcond = CreateEqualCondition({cbit}, {true});
331 return std::make_shared<ConditionalGate<Time>>(operation, eqcond);
332 }
333
347 static std::shared_ptr<IOperation<Time>> CreateConditionalMeasurement(
348 const std::shared_ptr<MeasurementOperation<Time>> &measurement,
349 const std::shared_ptr<ICondition> &condition) {
350 return std::make_shared<ConditionalMeasurement<Time>>(measurement,
351 condition);
352 }
353
368 static std::shared_ptr<IOperation<Time>> CreateConditionalRandomGen(
369 const std::shared_ptr<Random<Time>> &randomGen,
370 const std::shared_ptr<ICondition> &condition) {
371 return std::make_shared<ConditionalRandomGen<Time>>(randomGen, condition);
372 }
373
382 static std::shared_ptr<IOperation<Time>> CreateNoOp() {
383 return std::make_shared<NoOperation<Time>>();
384 }
385
398 static std::vector<std::shared_ptr<IOperation<Time>>> CreateBellStateCircuit(
399 size_t qbit1, size_t qbit2, bool qbit1X = false, bool qbit2X = false) {
400 size_t s = 2;
401 if (qbit1X) ++s;
402 if (qbit2X) ++s;
403
404 std::vector<std::shared_ptr<IOperation<Time>>> ops(s);
405
406 s = 0;
407 if (qbit1X) ops[s++] = CreateGate(QuantumGateType::kXGateType, qbit1);
408 if (qbit2X) ops[s++] = CreateGate(QuantumGateType::kXGateType, qbit2);
410 ops[s] = CreateGate(QuantumGateType::kCXGateType, qbit1, qbit2);
411
412 return ops;
413 }
414
425 static std::vector<std::shared_ptr<IOperation<Time>>>
426 CreateBellStateDecoderCircuit(size_t qbit1, size_t qbit2) {
427 std::vector<std::shared_ptr<IOperation<Time>>> ops(2);
428
429 ops[0] = CreateGate(QuantumGateType::kCXGateType, qbit1, qbit2);
431
432 return ops;
433 }
434
446 static std::vector<std::shared_ptr<IOperation<Time>>> CreateGZHStateCircuit(
447 size_t qbit1, size_t qbit2, size_t qbit3) {
448 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
449
451 ops[1] = CreateGate(QuantumGateType::kCXGateType, qbit1, qbit2);
452 ops[2] = CreateGate(QuantumGateType::kCXGateType, qbit2, qbit3);
453
454 return ops;
455 }
456
473 static std::vector<std::shared_ptr<IOperation<Time>>>
474 CreateTeleportationCircuit(size_t entqbit1, size_t entqbit2, size_t srcqbit,
475 size_t cbit1, size_t cbit2) {
476 std::vector<std::shared_ptr<IOperation<Time>>> ops(8);
477
478 // EPR pair
480 ops[1] = CreateGate(QuantumGateType::kCXGateType, entqbit1, entqbit2);
481
482 // teleportation follows, using the entangled qubits
483 ops[2] = CreateGate(QuantumGateType::kCXGateType, srcqbit, entqbit1);
485
486 // measurements
487 ops[4] = CreateMeasurement({{srcqbit, cbit1}});
488 ops[5] = CreateMeasurement({{entqbit1, cbit2}});
489
490 // apply the conditional gates based on the measurements
491 const auto xgate = CreateGate(QuantumGateType::kXGateType, entqbit2);
492 const auto zgate = CreateGate(QuantumGateType::kZGateType, entqbit2);
493
494 ops[6] = CreateSimpleConditionalGate(xgate, cbit2);
495 ops[7] = CreateSimpleConditionalGate(zgate, cbit1);
496
497 return ops;
498 }
499
512 static std::vector<std::shared_ptr<IOperation<Time>>>
513 CreateStartDistributionCircuit(size_t ctrlQubit, size_t ctrlEntangledQubit,
514 size_t tgtEntangledQubit,
515 size_t ctrlEntangledMeasureBit) {
516 std::vector<std::shared_ptr<IOperation<Time>>> ops(5);
517 // 1. Entangle qubits for the two hosts
518 // auto ops = CreateBellStateCircuit(ctrlEntangledQubit, tgtEntangledQubit);
519 ops[0] = CreateGate(QuantumGateType::kHadamardGateType, ctrlEntangledQubit);
520 ops[1] = CreateGate(QuantumGateType::kCXGateType, ctrlEntangledQubit,
521 tgtEntangledQubit);
522
523 // 2. Now apply cnot from ctrl to entangled qubit on ctrl host
524 // ops.emplace_back(std::make_shared<Circuits::CXGate<Time>>(ctrlQubit,
525 // ctrlEntangledQubit));
526 ops[2] =
527 CreateGate(QuantumGateType::kCXGateType, ctrlQubit, ctrlEntangledQubit);
528 // 3. Measure the entangled qubit on ctrl host (then the measurement result
529 // is sent to the other host)
530 const std::vector<std::pair<Types::qubit_t, size_t>> measureOps{
531 {ctrlEntangledQubit, ctrlEntangledMeasureBit}};
532 // ops.emplace_back(std::make_shared<Circuits::MeasurementOperation<Time>>(measureOps));
533 ops[3] = CreateMeasurement(measureOps);
534
535 // 4. Send the measurement result to the target host, use the result to
536 // apply not on the target entangled qubit
537 // ops.emplace_back(std::make_shared<Circuits::ConditionalGate<Time>>(std::make_shared<Circuits::XGate<Time>>(tgtEntangledQubit),
538 // std::make_shared<Circuits::EqualCondition>(std::vector<size_t>{
539 // ctrlEntangledMeasureBit }, std::vector<bool>{true})));
540 ops[4] = std::make_shared<Circuits::ConditionalGate<Time>>(
541 std::make_shared<Circuits::XGate<Time>>(tgtEntangledQubit),
542 std::make_shared<Circuits::EqualCondition>(
543 std::vector<size_t>{ctrlEntangledMeasureBit},
544 std::vector<bool>{true}));
545
546 return ops;
547 }
548
560 static std::vector<std::shared_ptr<IOperation<Time>>>
561 CreateEndDistributionCircuit(size_t ctrlQubit, size_t tgtEntangledQubit,
562 size_t tgtEntangledMeasureBit) {
563 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
564
565 ops[0] = std::make_shared<Circuits::HadamardGate<Time>>(tgtEntangledQubit);
566 const std::vector<std::pair<Types::qubit_t, size_t>> measureOps{
567 {tgtEntangledQubit, tgtEntangledMeasureBit}};
568 ops[1] = std::make_shared<Circuits::MeasurementOperation<Time>>(measureOps);
569 ops[2] = std::make_shared<Circuits::ConditionalGate<Time>>(
570 std::make_shared<Circuits::ZGate<Time>>(ctrlQubit),
571 std::make_shared<Circuits::EqualCondition>(
572 std::vector<size_t>{tgtEntangledMeasureBit},
573 std::vector<bool>{true}));
574
575 return ops;
576 }
577
586 static std::vector<std::shared_ptr<IOperation<Time>>> CreateMeasureX(
587 size_t qubit, size_t cbit) {
588 std::vector<std::shared_ptr<IOperation<Time>>> ops(2);
590 ops[1] = CreateMeasurement({{qubit, cbit}});
591
592 return ops;
593 }
594
603 static std::vector<std::shared_ptr<IOperation<Time>>> CreateMeasureY(
604 size_t qubit, size_t cbit) {
605 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
608 ops[2] = CreateMeasurement({{qubit, cbit}});
609
610 return ops;
611 }
612
621 static std::vector<std::shared_ptr<IOperation<Time>>> CreateMeasureZ(
622 size_t qubit, size_t cbit) {
623 std::vector<std::shared_ptr<IOperation<Time>>> ops(1);
624 ops[0] = CreateMeasurement({{qubit, cbit}});
625
626 return ops;
627 }
628
636 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitZero(
637 size_t qubit) {
638 std::vector<std::shared_ptr<IOperation<Time>>> ops(1);
639 ops[0] = CreateReset({qubit});
640
641 return ops;
642 }
643
651 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitOne(
652 size_t qubit) {
653 std::vector<std::shared_ptr<IOperation<Time>>> ops(2);
654 ops[0] = CreateReset({qubit});
656
657 return ops;
658 }
659
667 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitPlus(
668 size_t qubit) {
669 std::vector<std::shared_ptr<IOperation<Time>>> ops(2);
670 ops[0] = CreateReset({qubit});
672
673 return ops;
674 }
675
683 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitMinus(
684 size_t qubit) {
685 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
686 ops[0] = CreateReset({qubit});
689
690 return ops;
691 }
692
700 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitPlusI(
701 size_t qubit) {
702 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
703 ops[0] = CreateReset({qubit});
706
707 return ops;
708 }
709
717 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitMinusI(
718 size_t qubit) {
719 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
720 ops[0] = CreateReset({qubit});
723
724 return ops;
725 }
726};
727} // namespace Circuits
728
729#endif // !_CIRCUIT_FACTORY_H_
Factory for quantum gates and other operations.
static std::shared_ptr< IOperation< Time > > CreateSimpleConditionalGate(const std::shared_ptr< IGateOperation< Time > > &operation, const size_t cbit)
Construct a simple conditional gate.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateGZHStateCircuit(size_t qbit1, size_t qbit2, size_t qbit3)
Creates a circuit that prepares three qubits in a GHZ state.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateInitMinusI(size_t qubit)
Creates the circuit for initializing a qubit in the |-i> state.
static std::shared_ptr< IOperation< Time > > CreateNoOp()
Creates a no op.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateInitMinus(size_t qubit)
Creates the circuit for initializing a qubit in the |-> state.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateInitOne(size_t qubit)
Creates the circuit for initializing a qubit in the |1> state.
static const std::shared_ptr< IQuantumGate< Time > > CreateGate(QuantumGateType type, size_t q1, size_t q2=0, size_t q3=0, double param1=0, double param2=0, double param3=0, double param4=0)
Construct a quantum gate.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateInitZero(size_t qubit)
Creates the circuit for initializing a qubit in the |0> state.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateMeasureY(size_t qubit, size_t cbit)
Creates the circuit for measuring a qubit in the Y basis.
static std::shared_ptr< IOperation< Time > > CreateConditionalGate(const std::shared_ptr< IGateOperation< Time > > &operation, const std::shared_ptr< ICondition > &condition)
Construct a conditional gate.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateInitPlusI(size_t qubit)
Creates the circuit for initializing a qubit in the |i> state.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateMeasureZ(size_t qubit, size_t cbit)
Creates the circuit for measuring a qubit in the Z basis.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateMeasureX(size_t qubit, size_t cbit)
Creates the circuit for measuring a qubit in the X basis.
static std::shared_ptr< IOperation< Time > > CreateReset(const Types::qubits_vector &qubits={}, const std::vector< bool > &resetTgts={})
Construct a reset operation.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateStartDistributionCircuit(size_t ctrlQubit, size_t ctrlEntangledQubit, size_t tgtEntangledQubit, size_t ctrlEntangledMeasureBit)
Creates the circuit for distribution start.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateEndDistributionCircuit(size_t ctrlQubit, size_t tgtEntangledQubit, size_t tgtEntangledMeasureBit)
Creates the circuit for distribution end.
static const std::shared_ptr< IOperation< Time > > CreateMeasurement(const std::vector< std::pair< Types::qubit_t, size_t > > &qs={})
Construct a measurement operation.
static std::shared_ptr< Circuit< Time > > CreateCircuit(const std::vector< std::shared_ptr< IOperation< Time > > > &ops={})
Construct a circuit.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateTeleportationCircuit(size_t entqbit1, size_t entqbit2, size_t srcqbit, size_t cbit1, size_t cbit2)
Creates a teleportation circuit.
static std::shared_ptr< IOperation< Time > > CreateDelay(Types::qubit_t qubit=0, Time duration=0)
Construct a delay operation.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateBellStateDecoderCircuit(size_t qbit1, size_t qbit2)
Creates a Bell state decoder circuit.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateBellStateCircuit(size_t qbit1, size_t qbit2, bool qbit1X=false, bool qbit2X=false)
Creates a circuit that prepares a qubit pair in a Bell state.
static std::shared_ptr< IOperation< Time > > CreateConditionalRandomGen(const std::shared_ptr< Random< Time > > &randomGen, const std::shared_ptr< ICondition > &condition)
Constructs a conditional random number generator.
static const std::shared_ptr< IOperation< Time > > CreateGateWithVectors(QuantumGateType type, const Types::qubits_vector &qubits, const std::vector< double > &params={})
Construct a quantum gate.
static std::shared_ptr< IOperation< Time > > CreateRandom(const std::vector< size_t > &bits={}, size_t seed=0)
Construct a random operation.
static std::vector< std::shared_ptr< IOperation< Time > > > CreateInitPlus(size_t qubit)
Creates the circuit for initializing a qubit in the |+> state.
static std::shared_ptr< IOperation< Time > > CreateConditionalMeasurement(const std::shared_ptr< MeasurementOperation< Time > > &measurement, const std::shared_ptr< ICondition > &condition)
Constructs a conditional measurement.
static std::shared_ptr< ICondition > CreateEqualCondition(const std::vector< size_t > &ind, const std::vector< bool > &b)
Construct an equality condition.
The gate operation interface.
Definition Operations.h:618
The operation interface.
Definition Operations.h:360
Measurement operation class.
Random operation.
Definition RandomOp.h:34
QuantumGateType
The type of quantum gates.
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