Maestro 0.3.11
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"
23#include "Operations/RandomOp.h"
24#include "Operations/Reset.h"
25
26namespace Circuits
27{
28
38template <typename Time = Types::time_type> class CircuitFactory
39{
40 public:
49 static std::shared_ptr<Circuit<Time>> CreateCircuit(const std::vector<std::shared_ptr<IOperation<Time>>> &ops = {})
50 {
51 return std::make_shared<Circuit<Time>>(ops);
52 }
53
66 static std::shared_ptr<IOperation<Time>> CreateReset(const Types::qubits_vector &qubits = {}, const std::vector<bool> &resetTgts = {})
67 {
68 return std::make_shared<Reset<Time>>(qubits, 0, resetTgts);
69 }
70
79 static std::shared_ptr<IOperation<Time>> CreateDelay(Types::qubit_t qubit = 0, Time duration = 0)
80 {
81 return std::make_shared<Delay<Time>>(qubit, duration);
82 }
83
87 static std::shared_ptr<IOperation<Time>> CreateRandom(const std::vector<size_t> &bits = {})
88 {
89 return std::make_shared<Random<Time>>(bits);
90 }
91
102 static std::shared_ptr<IOperation<Time>> CreateRandom(const std::vector<size_t> &bits, size_t seed)
103 {
104 return std::make_shared<Random<Time>>(bits, seed);
105 }
106
117 static const std::shared_ptr<IOperation<Time>> CreateMeasurement(const std::vector<std::pair<Types::qubit_t, size_t>> &qs = {})
118 {
119 return std::make_shared<MeasurementOperation<Time>>(qs);
120 }
121
144 static const std::shared_ptr<IQuantumGate<Time>> CreateGate(QuantumGateType type, size_t q1, size_t q2 = 0, size_t q3 = 0, double param1 = 0,
145 double param2 = 0, double param3 = 0, double param4 = 0)
146 {
147 // parameters that do not make sense for a gate are ignored, eg if it's a
148 // single qubit gate, q2 and q3 are ignored if it doesn't have a parameter,
149 // the parameter is ignored if it has only one, the others are ignored
150 // TODO: maybe make specialized variants, as in CreateOneQubitGate,
151 // CreateTwoQubitGate, etc
152 std::shared_ptr<IQuantumGate<Time>> gate;
153
154 switch (type)
155 {
156 // one qubit gates
158 gate = std::make_shared<PhaseGate<Time>>(q1, param1);
159 break;
161 gate = std::make_shared<XGate<Time>>(q1);
162 break;
164 gate = std::make_shared<YGate<Time>>(q1);
165 break;
167 gate = std::make_shared<ZGate<Time>>(q1);
168 break;
170 gate = std::make_shared<HadamardGate<Time>>(q1);
171 break;
173 gate = std::make_shared<SGate<Time>>(q1);
174 break;
176 gate = std::make_shared<SdgGate<Time>>(q1);
177 break;
179 gate = std::make_shared<TGate<Time>>(q1);
180 break;
182 gate = std::make_shared<TdgGate<Time>>(q1);
183 break;
185 gate = std::make_shared<SxGate<Time>>(q1);
186 break;
188 gate = std::make_shared<SxDagGate<Time>>(q1);
189 break;
191 gate = std::make_shared<KGate<Time>>(q1);
192 break;
194 gate = std::make_shared<RxGate<Time>>(q1, param1);
195 break;
197 gate = std::make_shared<RyGate<Time>>(q1, param1);
198 break;
200 gate = std::make_shared<RzGate<Time>>(q1, param1);
201 break;
203 gate = std::make_shared<UGate<Time>>(q1, param1, param2, param3, param4);
204 break;
205 // two qubit gates
207 gate = std::make_shared<SwapGate<Time>>(q1, q2);
208 break;
210 gate = std::make_shared<CXGate<Time>>(q1, q2);
211 break;
213 gate = std::make_shared<CYGate<Time>>(q1, q2);
214 break;
216 gate = std::make_shared<CZGate<Time>>(q1, q2);
217 break;
219 gate = std::make_shared<CPGate<Time>>(q1, q2, param1);
220 break;
222 gate = std::make_shared<CRxGate<Time>>(q1, q2, param1);
223 break;
225 gate = std::make_shared<CRyGate<Time>>(q1, q2, param1);
226 break;
228 gate = std::make_shared<CRzGate<Time>>(q1, q2, param1);
229 break;
231 gate = std::make_shared<CHGate<Time>>(q1, q2);
232 break;
234 gate = std::make_shared<CSxGate<Time>>(q1, q2);
235 break;
237 gate = std::make_shared<CSxDagGate<Time>>(q1, q2);
238 break;
240 gate = std::make_shared<CUGate<Time>>(q1, q2, param1, param2, param3, param4);
241 break;
242 // three qubit gates
244 gate = std::make_shared<CSwapGate<Time>>(q1, q2, q3);
245 break;
247 gate = std::make_shared<CCXGate<Time>>(q1, q2, q3);
248 break;
249 default:
250 break;
251 }
252
253 return gate;
254 }
255
268 static const std::shared_ptr<IOperation<Time>> CreateGateWithVectors(QuantumGateType type, const Types::qubits_vector &qubits,
269 const std::vector<double> &params = {})
270 {
271 return CreateGate(type, qubits.empty() ? 0 : qubits[0], (qubits.size() < 2) ? 0 : qubits[1], (qubits.size() < 3) ? 0 : qubits[2],
272 params.empty() ? 0. : params[0], (params.size() < 2) ? 0. : params[1], (params.size() < 3) ? 0. : params[2],
273 (params.size() < 4) ? 0. : params[3]);
274 }
275
276 // maybe this could be refined, have a CreateCondition with the condition
277 // type, but for now we only have equality can be done later
278
290 static std::shared_ptr<ICondition> CreateEqualCondition(const std::vector<size_t> &ind, const std::vector<bool> &b)
291 {
292 return std::make_shared<EqualCondition>(ind, b);
293 }
294
295 // we have only three conditional things, I don't think we need a single
296 // factory method for them (with a 'type' parameter)
297
310 static std::shared_ptr<IOperation<Time>> CreateConditionalGate(const std::shared_ptr<IGateOperation<Time>> &operation,
311 const std::shared_ptr<ICondition> &condition)
312 {
313 return std::make_shared<ConditionalGate<Time>>(operation, condition);
314 }
315
329 static std::shared_ptr<IOperation<Time>> CreateSimpleConditionalGate(const std::shared_ptr<IGateOperation<Time>> &operation, const size_t cbit)
330 {
331 const auto eqcond = CreateEqualCondition({cbit}, {true});
332 return std::make_shared<ConditionalGate<Time>>(operation, eqcond);
333 }
334
348 static std::shared_ptr<IOperation<Time>> CreateConditionalMeasurement(const std::shared_ptr<MeasurementOperation<Time>> &measurement,
349 const std::shared_ptr<ICondition> &condition)
350 {
351 return std::make_shared<ConditionalMeasurement<Time>>(measurement, condition);
352 }
353
368 static std::shared_ptr<IOperation<Time>> CreateConditionalRandomGen(const std::shared_ptr<Random<Time>> &randomGen,
369 const std::shared_ptr<ICondition> &condition)
370 {
371 return std::make_shared<ConditionalRandomGen<Time>>(randomGen, condition);
372 }
373
382 static std::shared_ptr<IOperation<Time>> CreateNoOp()
383 {
384 return std::make_shared<NoOperation<Time>>();
385 }
386
399 static std::vector<std::shared_ptr<IOperation<Time>>> CreateBellStateCircuit(size_t qbit1, size_t qbit2, bool qbit1X = false, bool qbit2X = false)
400 {
401 size_t s = 2;
402 if (qbit1X)
403 ++s;
404 if (qbit2X)
405 ++s;
406
407 std::vector<std::shared_ptr<IOperation<Time>>> ops(s);
408
409 s = 0;
410 if (qbit1X)
411 ops[s++] = CreateGate(QuantumGateType::kXGateType, qbit1);
412 if (qbit2X)
413 ops[s++] = CreateGate(QuantumGateType::kXGateType, qbit2);
415 ops[s] = CreateGate(QuantumGateType::kCXGateType, qbit1, qbit2);
416
417 return ops;
418 }
419
430 static std::vector<std::shared_ptr<IOperation<Time>>> CreateBellStateDecoderCircuit(size_t qbit1, size_t qbit2)
431 {
432 std::vector<std::shared_ptr<IOperation<Time>>> ops(2);
433
434 ops[0] = CreateGate(QuantumGateType::kCXGateType, qbit1, qbit2);
436
437 return ops;
438 }
439
451 static std::vector<std::shared_ptr<IOperation<Time>>> CreateGZHStateCircuit(size_t qbit1, size_t qbit2, size_t qbit3)
452 {
453 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
454
456 ops[1] = CreateGate(QuantumGateType::kCXGateType, qbit1, qbit2);
457 ops[2] = CreateGate(QuantumGateType::kCXGateType, qbit2, qbit3);
458
459 return ops;
460 }
461
478 static std::vector<std::shared_ptr<IOperation<Time>>> CreateTeleportationCircuit(size_t entqbit1, size_t entqbit2, size_t srcqbit, size_t cbit1,
479 size_t cbit2)
480 {
481 std::vector<std::shared_ptr<IOperation<Time>>> ops(8);
482
483 // EPR pair
485 ops[1] = CreateGate(QuantumGateType::kCXGateType, entqbit1, entqbit2);
486
487 // teleportation follows, using the entangled qubits
488 ops[2] = CreateGate(QuantumGateType::kCXGateType, srcqbit, entqbit1);
490
491 // measurements
492 ops[4] = CreateMeasurement({{srcqbit, cbit1}});
493 ops[5] = CreateMeasurement({{entqbit1, cbit2}});
494
495 // apply the conditional gates based on the measurements
496 const auto xgate = CreateGate(QuantumGateType::kXGateType, entqbit2);
497 const auto zgate = CreateGate(QuantumGateType::kZGateType, entqbit2);
498
499 ops[6] = CreateSimpleConditionalGate(xgate, cbit2);
500 ops[7] = CreateSimpleConditionalGate(zgate, cbit1);
501
502 return ops;
503 }
504
517 static std::vector<std::shared_ptr<IOperation<Time>>> CreateStartDistributionCircuit(size_t ctrlQubit, size_t ctrlEntangledQubit, size_t tgtEntangledQubit,
518 size_t ctrlEntangledMeasureBit)
519 {
520 std::vector<std::shared_ptr<IOperation<Time>>> ops(5);
521 // 1. Entangle qubits for the two hosts
522 // auto ops = CreateBellStateCircuit(ctrlEntangledQubit, tgtEntangledQubit);
523 ops[0] = CreateGate(QuantumGateType::kHadamardGateType, ctrlEntangledQubit);
524 ops[1] = CreateGate(QuantumGateType::kCXGateType, ctrlEntangledQubit, tgtEntangledQubit);
525
526 // 2. Now apply cnot from ctrl to entangled qubit on ctrl host
527 // ops.emplace_back(std::make_shared<Circuits::CXGate<Time>>(ctrlQubit,
528 // ctrlEntangledQubit));
529 ops[2] = CreateGate(QuantumGateType::kCXGateType, ctrlQubit, ctrlEntangledQubit);
530 // 3. Measure the entangled qubit on ctrl host (then the measurement result
531 // is sent to the other host)
532 const std::vector<std::pair<Types::qubit_t, size_t>> measureOps{{ctrlEntangledQubit, ctrlEntangledMeasureBit}};
533 // ops.emplace_back(std::make_shared<Circuits::MeasurementOperation<Time>>(measureOps));
534 ops[3] = CreateMeasurement(measureOps);
535
536 // 4. Send the measurement result to the target host, use the result to
537 // apply not on the target entangled qubit
538 // ops.emplace_back(std::make_shared<Circuits::ConditionalGate<Time>>(std::make_shared<Circuits::XGate<Time>>(tgtEntangledQubit),
539 // std::make_shared<Circuits::EqualCondition>(std::vector<size_t>{
540 // ctrlEntangledMeasureBit }, std::vector<bool>{true})));
541 ops[4] = std::make_shared<Circuits::ConditionalGate<Time>>(
542 std::make_shared<Circuits::XGate<Time>>(tgtEntangledQubit),
543 std::make_shared<Circuits::EqualCondition>(std::vector<size_t>{ctrlEntangledMeasureBit}, std::vector<bool>{true}));
544
545 return ops;
546 }
547
559 static std::vector<std::shared_ptr<IOperation<Time>>> CreateEndDistributionCircuit(size_t ctrlQubit, size_t tgtEntangledQubit,
560 size_t tgtEntangledMeasureBit)
561 {
562 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
563
564 ops[0] = std::make_shared<Circuits::HadamardGate<Time>>(tgtEntangledQubit);
565 const std::vector<std::pair<Types::qubit_t, size_t>> measureOps{{tgtEntangledQubit, tgtEntangledMeasureBit}};
566 ops[1] = std::make_shared<Circuits::MeasurementOperation<Time>>(measureOps);
567 ops[2] = std::make_shared<Circuits::ConditionalGate<Time>>(
568 std::make_shared<Circuits::ZGate<Time>>(ctrlQubit),
569 std::make_shared<Circuits::EqualCondition>(std::vector<size_t>{tgtEntangledMeasureBit}, std::vector<bool>{true}));
570
571 return ops;
572 }
573
582 static std::vector<std::shared_ptr<IOperation<Time>>> CreateMeasureX(size_t qubit, size_t cbit)
583 {
584 std::vector<std::shared_ptr<IOperation<Time>>> ops(2);
586 ops[1] = CreateMeasurement({{qubit, cbit}});
587
588 return ops;
589 }
590
599 static std::vector<std::shared_ptr<IOperation<Time>>> CreateMeasureY(size_t qubit, size_t cbit)
600 {
601 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
604 ops[2] = CreateMeasurement({{qubit, cbit}});
605
606 return ops;
607 }
608
617 static std::vector<std::shared_ptr<IOperation<Time>>> CreateMeasureZ(size_t qubit, size_t cbit)
618 {
619 std::vector<std::shared_ptr<IOperation<Time>>> ops(1);
620 ops[0] = CreateMeasurement({{qubit, cbit}});
621
622 return ops;
623 }
624
632 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitZero(size_t qubit)
633 {
634 std::vector<std::shared_ptr<IOperation<Time>>> ops(1);
635 ops[0] = CreateReset({qubit});
636
637 return ops;
638 }
639
647 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitOne(size_t qubit)
648 {
649 std::vector<std::shared_ptr<IOperation<Time>>> ops(2);
650 ops[0] = CreateReset({qubit});
652
653 return ops;
654 }
655
663 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitPlus(size_t qubit)
664 {
665 std::vector<std::shared_ptr<IOperation<Time>>> ops(2);
666 ops[0] = CreateReset({qubit});
668
669 return ops;
670 }
671
679 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitMinus(size_t qubit)
680 {
681 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
682 ops[0] = CreateReset({qubit});
685
686 return ops;
687 }
688
696 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitPlusI(size_t qubit)
697 {
698 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
699 ops[0] = CreateReset({qubit});
702
703 return ops;
704 }
705
713 static std::vector<std::shared_ptr<IOperation<Time>>> CreateInitMinusI(size_t qubit)
714 {
715 std::vector<std::shared_ptr<IOperation<Time>>> ops(3);
716 ops[0] = CreateReset({qubit});
719
720 return ops;
721 }
722};
723} // namespace Circuits
724
725#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 std::shared_ptr< IOperation< Time > > CreateRandom(const std::vector< size_t > &bits={})
Construct a random operation without an explicit seed.
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::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 > > CreateRandom(const std::vector< size_t > &bits, size_t seed)
Construct a random operation with an explicit seed, including zero.
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:703
The operation interface.
Definition Operations.h:402
Measurement operation class.
Random operation.
Definition RandomOp.h:35
QuantumGateType
The type of quantum gates.
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
Definition Types.h:24
uint_fast64_t qubit_t
The type of a qubit.
Definition Types.h:23