Maestro 0.1.0
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
Circuit/Factory.h
Go to the documentation of this file.
1
14#pragma once
15
16#ifndef _CIRCUIT_FACTORY_H_
17#define _CIRCUIT_FACTORY_H_
18
19#include "Circuit.h"
20#include "Conditional.h"
21#include "Measurements.h"
22#include "RandomOp.h"
23#include "Reset.h"
24
25namespace Circuits {
26
36template <typename Time = Types::time_type>
38 public:
47 static std::shared_ptr<Circuit<Time>> CreateCircuit(
48 const std::vector<std::shared_ptr<IOperation<Time>>> &ops = {}) {
49 return std::make_shared<Circuit<Time>>(ops);
50 }
51
64 static std::shared_ptr<IOperation<Time>> CreateReset(
65 const Types::qubits_vector &qubits = {},
66 const std::vector<bool> &resetTgts = {}) {
67 return std::make_shared<Reset<Time>>(qubits, 0, resetTgts);
68 }
69
80 static std::shared_ptr<IOperation<Time>> CreateRandom(
81 const std::vector<size_t> &bits = {}, size_t seed = 0) {
82 return std::make_shared<Random<Time>>(bits, seed);
83 }
84
95 static const std::shared_ptr<IOperation<Time>> CreateMeasurement(
96 const std::vector<std::pair<Types::qubit_t, size_t>> &qs = {}) {
97 return std::make_shared<MeasurementOperation<Time>>(qs);
98 }
99
122 static const std::shared_ptr<IQuantumGate<Time>> CreateGate(
123 QuantumGateType type, size_t q1, size_t q2 = 0, size_t q3 = 0,
124 double param1 = 0, double param2 = 0, double param3 = 0,
125 double param4 = 0) {
126 // parameters that do not make sense for a gate are ignored, eg if it's a
127 // single qubit gate, q2 and q3 are ignored if it doesn't have a parameter,
128 // the parameter is ignored if it has only one, the others are ignored
129 // TODO: maybe make specialized variants, as in CreateOneQubitGate,
130 // CreateTwoQubitGate, etc
131 std::shared_ptr<IQuantumGate<Time>> gate;
132
133 switch (type) {
134 // one qubit gates
136 gate = std::make_shared<PhaseGate<Time>>(q1, param1);
137 break;
139 gate = std::make_shared<XGate<Time>>(q1);
140 break;
142 gate = std::make_shared<YGate<Time>>(q1);
143 break;
145 gate = std::make_shared<ZGate<Time>>(q1);
146 break;
148 gate = std::make_shared<HadamardGate<Time>>(q1);
149 break;
151 gate = std::make_shared<SGate<Time>>(q1);
152 break;
154 gate = std::make_shared<SdgGate<Time>>(q1);
155 break;
157 gate = std::make_shared<TGate<Time>>(q1);
158 break;
160 gate = std::make_shared<TdgGate<Time>>(q1);
161 break;
163 gate = std::make_shared<SxGate<Time>>(q1);
164 break;
166 gate = std::make_shared<SxDagGate<Time>>(q1);
167 break;
169 gate = std::make_shared<KGate<Time>>(q1);
170 break;
172 gate = std::make_shared<RxGate<Time>>(q1, param1);
173 break;
175 gate = std::make_shared<RyGate<Time>>(q1, param1);
176 break;
178 gate = std::make_shared<RzGate<Time>>(q1, param1);
179 break;
181 gate =
182 std::make_shared<UGate<Time>>(q1, param1, param2, param3, param4);
183 break;
184 // two qubit gates
186 gate = std::make_shared<SwapGate<Time>>(q1, q2);
187 break;
189 gate = std::make_shared<CXGate<Time>>(q1, q2);
190 break;
192 gate = std::make_shared<CYGate<Time>>(q1, q2);
193 break;
195 gate = std::make_shared<CZGate<Time>>(q1, q2);
196 break;
198 gate = std::make_shared<CPGate<Time>>(q1, q2, param1);
199 break;
201 gate = std::make_shared<CRxGate<Time>>(q1, q2, param1);
202 break;
204 gate = std::make_shared<CRyGate<Time>>(q1, q2, param1);
205 break;
207 gate = std::make_shared<CRzGate<Time>>(q1, q2, param1);
208 break;
210 gate = std::make_shared<CHGate<Time>>(q1, q2);
211 break;
213 gate = std::make_shared<CSxGate<Time>>(q1, q2);
214 break;
216 gate = std::make_shared<CSxDagGate<Time>>(q1, q2);
217 break;
219 gate = std::make_shared<CUGate<Time>>(q1, q2, param1, param2, param3,
220 param4);
221 break;
222 // three qubit gates
224 gate = std::make_shared<CSwapGate<Time>>(q1, q2, q3);
225 break;
227 gate = std::make_shared<CCXGate<Time>>(q1, q2, q3);
228 break;
229 default:
230 break;
231 }
232
233 return gate;
234 }
235
248 static const std::shared_ptr<IOperation<Time>> CreateGateWithVectors(
249 QuantumGateType type, const Types::qubits_vector &qubits,
250 const std::vector<double> &params = {}) {
251 return CreateGate(type, qubits.empty() ? 0 : qubits[0],
252 (qubits.size() < 2) ? 0 : qubits[1],
253 (qubits.size() < 3) ? 0 : qubits[2],
254 params.empty() ? 0. : params[0],
255 (params.size() < 2) ? 0. : params[1],
256 (params.size() < 3) ? 0. : params[2],
257 (params.size() < 4) ? 0. : params[3]);
258 }
259
260 // maybe this could be refined, have a CreateCondition with the condition
261 // type, but for now we only have equality can be done later
262
274 static std::shared_ptr<ICondition> CreateEqualCondition(
275 const std::vector<size_t> &ind, const std::vector<bool> &b) {
276 return std::make_shared<EqualCondition>(ind, b);
277 }
278
279 // we have only three conditional things, I don't think we need a single
280 // factory method for them (with a 'type' parameter)
281
294 static std::shared_ptr<IOperation<Time>> CreateConditionalGate(
295 const std::shared_ptr<IGateOperation<Time>> &operation,
296 const std::shared_ptr<ICondition> &condition) {
297 return std::make_shared<ConditionalGate<Time>>(operation, condition);
298 }
299
313 static std::shared_ptr<IOperation<Time>> CreateSimpleConditionalGate(
314 const std::shared_ptr<IGateOperation<Time>> &operation,
315 const size_t cbit) {
316 const auto eqcond = CreateEqualCondition({cbit}, {true});
317 return std::make_shared<ConditionalGate<Time>>(operation, eqcond);
318 }
319
333 static std::shared_ptr<IOperation<Time>> CreateConditionalMeasurement(
334 const std::shared_ptr<MeasurementOperation<Time>> &measurement,
335 const std::shared_ptr<ICondition> &condition) {
336 return std::make_shared<ConditionalMeasurement<Time>>(measurement,
337 condition);
338 }
339
354 static std::shared_ptr<IOperation<Time>> CreateConditionalRandomGen(
355 const std::shared_ptr<Random<Time>> &randomGen,
356 const std::shared_ptr<ICondition> &condition) {
357 return std::make_shared<ConditionalRandomGen<Time>>(randomGen, condition);
358 }
359
368 static std::shared_ptr<IOperation<Time>> CreateNoOp() {
369 return std::make_shared<NoOperation<Time>>();
370 }
371
384 static std::vector<std::shared_ptr<IOperation<Time>>> CreateBellStateCircuit(
385 size_t qbit1, size_t qbit2, bool qbit1X = false, bool qbit2X = false) {
386 size_t s = 2;
387 if (qbit1X) ++s;
388 if (qbit2X) ++s;
389
390 std::vector<std::shared_ptr<IOperation<Time>>> ops(s);
391
392 s = 0;
393 if (qbit1X) ops[s++] = CreateGate(QuantumGateType::kXGateType, qbit1);
394 if (qbit2X) ops[s++] = CreateGate(QuantumGateType::kXGateType, qbit2);
396 ops[s] = CreateGate(QuantumGateType::kCXGateType, qbit1, qbit2);
397
398 return ops;
399 }
400
411 static std::vector<std::shared_ptr<IOperation<Time>>>
412 CreateBellStateDecoderCircuit(size_t qbit1, size_t qbit2) {
413 std::vector<std::shared_ptr<IOperation<Time>>> ops(2);
414
415 ops[0] = CreateGate(QuantumGateType::kCXGateType, qbit1, qbit2);
417
418 return ops;
419 }
420
432 static std::vector<std::shared_ptr<IOperation<Time>>> CreateGZHStateCircuit(
433 size_t qbit1, size_t qbit2, size_t qbit3) {
434 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
435
437 ops[1] = CreateGate(QuantumGateType::kCXGateType, qbit1, qbit2);
438 ops[2] = CreateGate(QuantumGateType::kCXGateType, qbit2, qbit3);
439
440 return ops;
441 }
442
459 static std::vector<std::shared_ptr<IOperation<Time>>>
460 CreateTeleportationCircuit(size_t entqbit1, size_t entqbit2, size_t srcqbit,
461 size_t cbit1, size_t cbit2) {
462 std::vector<std::shared_ptr<IOperation<Time>>> ops(8);
463
464 // EPR pair
466 ops[1] = CreateGate(QuantumGateType::kCXGateType, entqbit1, entqbit2);
467
468 // teleportation follows, using the entangled qubits
469 ops[2] = CreateGate(QuantumGateType::kCXGateType, srcqbit, entqbit1);
471
472 // measurements
473 ops[4] = CreateMeasurement({{srcqbit, cbit1}});
474 ops[5] = CreateMeasurement({{entqbit1, cbit2}});
475
476 // apply the conditional gates based on the measurements
477 const auto xgate = CreateGate(QuantumGateType::kXGateType, entqbit2);
478 const auto zgate = CreateGate(QuantumGateType::kZGateType, entqbit2);
479
480 ops[6] = CreateSimpleConditionalGate(xgate, cbit2);
481 ops[7] = CreateSimpleConditionalGate(zgate, cbit1);
482
483 return ops;
484 }
485
498 static std::vector<std::shared_ptr<IOperation<Time>>>
499 CreateStartDistributionCircuit(size_t ctrlQubit, size_t ctrlEntangledQubit,
500 size_t tgtEntangledQubit,
501 size_t ctrlEntangledMeasureBit) {
502 std::vector<std::shared_ptr<IOperation<Time>>> ops(5);
503 // 1. Entangle qubits for the two hosts
504 // auto ops = CreateBellStateCircuit(ctrlEntangledQubit, tgtEntangledQubit);
505 ops[0] = CreateGate(QuantumGateType::kHadamardGateType, ctrlEntangledQubit);
506 ops[1] = CreateGate(QuantumGateType::kCXGateType, ctrlEntangledQubit,
507 tgtEntangledQubit);
508
509 // 2. Now apply cnot from ctrl to entangled qubit on ctrl host
510 // ops.emplace_back(std::make_shared<Circuits::CXGate<Time>>(ctrlQubit,
511 // ctrlEntangledQubit));
512 ops[2] =
513 CreateGate(QuantumGateType::kCXGateType, ctrlQubit, ctrlEntangledQubit);
514 // 3. Measure the entangled qubit on ctrl host (then the measurement result
515 // is sent to the other host)
516 const std::vector<std::pair<Types::qubit_t, size_t>> measureOps{
517 {ctrlEntangledQubit, ctrlEntangledMeasureBit}};
518 // ops.emplace_back(std::make_shared<Circuits::MeasurementOperation<Time>>(measureOps));
519 ops[3] = CreateMeasurement(measureOps);
520
521 // 4. Send the measurement result to the target host, use the result to
522 // apply not on the target entangled qubit
523 // ops.emplace_back(std::make_shared<Circuits::ConditionalGate<Time>>(std::make_shared<Circuits::XGate<Time>>(tgtEntangledQubit),
524 // std::make_shared<Circuits::EqualCondition>(std::vector<size_t>{
525 // ctrlEntangledMeasureBit }, std::vector<bool>{true})));
526 ops[4] = std::make_shared<Circuits::ConditionalGate<Time>>(
527 std::make_shared<Circuits::XGate<Time>>(tgtEntangledQubit),
528 std::make_shared<Circuits::EqualCondition>(
529 std::vector<size_t>{ctrlEntangledMeasureBit},
530 std::vector<bool>{true}));
531
532 return ops;
533 }
534
546 static std::vector<std::shared_ptr<IOperation<Time>>>
547 CreateEndDistributionCircuit(size_t ctrlQubit, size_t tgtEntangledQubit,
548 size_t tgtEntangledMeasureBit) {
549 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
550
551 ops[0] = std::make_shared<Circuits::HadamardGate<Time>>(tgtEntangledQubit);
552 const std::vector<std::pair<Types::qubit_t, size_t>> measureOps{
553 {tgtEntangledQubit, tgtEntangledMeasureBit}};
554 ops[1] = std::make_shared<Circuits::MeasurementOperation<Time>>(measureOps);
555 ops[2] = std::make_shared<Circuits::ConditionalGate<Time>>(
556 std::make_shared<Circuits::ZGate<Time>>(ctrlQubit),
557 std::make_shared<Circuits::EqualCondition>(
558 std::vector<size_t>{tgtEntangledMeasureBit},
559 std::vector<bool>{true}));
560
561 return ops;
562 }
563
572 static std::vector<std::shared_ptr<IOperation<Time>>> CreateMeasureX(
573 size_t qubit, size_t cbit) {
574 std::vector<std::shared_ptr<IOperation<Time>>> ops(2);
576 ops[1] = CreateMeasurement({{qubit, cbit}});
577
578 return ops;
579 }
580
589 static std::vector<std::shared_ptr<IOperation<Time>>> CreateMeasureY(
590 size_t qubit, size_t cbit) {
591 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
594 ops[2] = CreateMeasurement({{qubit, cbit}});
595
596 return ops;
597 }
598
607 static std::vector<std::shared_ptr<IOperation<Time>>> CreateMeasureZ(
608 size_t qubit, size_t cbit) {
609 std::vector<std::shared_ptr<IOperation<Time>>> ops(1);
610 ops[0] = CreateMeasurement({{qubit, cbit}});
611
612 return ops;
613 }
614
622 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitZero(
623 size_t qubit) {
624 std::vector<std::shared_ptr<IOperation<Time>>> ops(1);
625 ops[0] = CreateReset({qubit});
626
627 return ops;
628 }
629
637 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitOne(
638 size_t qubit) {
639 std::vector<std::shared_ptr<IOperation<Time>>> ops(2);
640 ops[0] = CreateReset({qubit});
642
643 return ops;
644 }
645
653 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitPlus(
654 size_t qubit) {
655 std::vector<std::shared_ptr<IOperation<Time>>> ops(2);
656 ops[0] = CreateReset({qubit});
658
659 return ops;
660 }
661
669 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitMinus(
670 size_t qubit) {
671 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
672 ops[0] = CreateReset({qubit});
675
676 return ops;
677 }
678
686 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitPlusI(
687 size_t qubit) {
688 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
689 ops[0] = CreateReset({qubit});
692
693 return ops;
694 }
695
703 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitMinusI(
704 size_t qubit) {
705 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
706 ops[0] = CreateReset({qubit});
709
710 return ops;
711 }
712};
713} // namespace Circuits
714
715#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::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:603
The operation interface.
Definition Operations.h:357
Measurement operation class.
Random operation.
Definition RandomOp.h:33
QuantumGateType
The type of quantum gates.