1
1
/*
2
2
* This file is part of MQT QFR library which is released under the MIT license.
3
- * See file README.md or go to http ://iic.jku.at/eda /research/quantum/ for more information.
3
+ * See file README.md or go to https ://www.cda.cit.tum.de /research/quantum/ for more information.
4
4
*/
5
5
6
- #ifndef QFR_QUANTUMCOMPUTATION_H
7
- #define QFR_QUANTUMCOMPUTATION_H
6
+ #pragma once
8
7
9
8
#include " Definitions.hpp"
9
+ #include " dd/Operations.hpp"
10
10
#include " operations/ClassicControlledOperation.hpp"
11
11
#include " operations/NonUnitaryOperation.hpp"
12
12
#include " operations/StandardOperation.hpp"
@@ -176,10 +176,10 @@ namespace qc {
176
176
mt.seed (seeds);
177
177
}
178
178
}
179
- explicit QuantumComputation (const std::string& filename, std::size_t seed = 0 ):
179
+ explicit QuantumComputation (const std::string& filename, std::size_t seed = 0U ):
180
180
seed(seed) {
181
181
import (filename);
182
- if (seed != 0 ) {
182
+ if (seed != 0U ) {
183
183
mt.seed (seed);
184
184
} else {
185
185
// create and properly seed rng
@@ -192,9 +192,11 @@ namespace qc {
192
192
}
193
193
QuantumComputation (const QuantumComputation& qc) = delete;
194
194
QuantumComputation (QuantumComputation&& qc) noexcept = default;
195
+
195
196
QuantumComputation& operator =(const QuantumComputation& qc) = delete;
196
197
QuantumComputation& operator =(QuantumComputation&& qc) noexcept = default ;
197
- virtual ~QuantumComputation () = default ;
198
+
199
+ virtual ~QuantumComputation () = default ;
198
200
199
201
[[nodiscard]] QuantumComputation clone () const {
200
202
auto qc = QuantumComputation (nqubits);
@@ -247,16 +249,17 @@ namespace qc {
247
249
[[nodiscard]] std::pair<std::string, dd::Qubit> getQubitRegisterAndIndex (dd::Qubit physicalQubitIndex) const ;
248
250
[[nodiscard]] std::pair<std::string, std::size_t > getClassicalRegisterAndIndex (std::size_t classicalIndex) const ;
249
251
250
- [[nodiscard]] dd::Qubit getIndexFromQubitRegister (const std::pair<std::string, dd::Qubit>& qubit) const ;
251
- [[nodiscard]] std::size_t getIndexFromClassicalRegister (const std::pair<std::string, std::size_t >& clbit) const ;
252
- [[nodiscard]] bool isIdleQubit (dd::Qubit physicalQubit) const ;
253
- [[nodiscard]] bool isLastOperationOnQubit (const decltype (ops.cbegin())& opIt, const decltype(ops.cend())& end) const ;
254
- [[nodiscard]] bool physicalQubitIsAncillary (dd::Qubit physicalQubitIndex) const ;
255
- [[nodiscard]] bool logicalQubitIsAncillary (dd::Qubit logicalQubitIndex) const { return ancillary[logicalQubitIndex]; }
256
- void setLogicalQubitAncillary (dd::Qubit logicalQubitIndex) { ancillary[logicalQubitIndex] = true ; }
257
- [[nodiscard]] bool logicalQubitIsGarbage (dd::Qubit logicalQubitIndex) const { return garbage[logicalQubitIndex]; }
258
- void setLogicalQubitGarbage (dd::Qubit logicalQubitIndex);
259
- MatrixDD createInitialMatrix (std::unique_ptr<dd::Package>& dd) const ; // creates identity matrix, which is reduced with respect to the ancillary qubits
252
+ [[nodiscard]] dd::Qubit getIndexFromQubitRegister (const std::pair<std::string, dd::Qubit>& qubit) const ;
253
+ [[nodiscard]] std::size_t getIndexFromClassicalRegister (const std::pair<std::string, std::size_t >& clbit) const ;
254
+ [[nodiscard]] bool isIdleQubit (dd::Qubit physicalQubit) const ;
255
+ [[nodiscard]] bool isLastOperationOnQubit (const decltype (ops.cbegin())& opIt, const decltype(ops.cend())& end) const ;
256
+ [[nodiscard]] bool physicalQubitIsAncillary (dd::Qubit physicalQubitIndex) const ;
257
+ [[nodiscard]] bool logicalQubitIsAncillary (dd::Qubit logicalQubitIndex) const { return ancillary[logicalQubitIndex]; }
258
+ void setLogicalQubitAncillary (dd::Qubit logicalQubitIndex) { ancillary[logicalQubitIndex] = true ; }
259
+ [[nodiscard]] bool logicalQubitIsGarbage (dd::Qubit logicalQubitIndex) const { return garbage[logicalQubitIndex]; }
260
+ void setLogicalQubitGarbage (dd::Qubit logicalQubitIndex);
261
+ [[nodiscard]] const std::vector<bool >& getAncillary () const { return ancillary; }
262
+ [[nodiscard]] const std::vector<bool >& getGarbage () const { return garbage; }
260
263
261
264
void i (dd::Qubit target) { emplace_back<StandardOperation>(getNqubits (), target, qc::I); }
262
265
void i (dd::Qubit target, const dd::Control& control) { emplace_back<StandardOperation>(getNqubits (), control, target, qc::I); }
@@ -362,55 +365,6 @@ namespace qc {
362
365
// / strip away qubits with no operations applied to them and which do not pop up in the output permutation
363
366
// / \param force if true, also strip away idle qubits occurring in the output permutation
364
367
void stripIdleQubits (bool force = false , bool reduceIOpermutations = true );
365
- // apply swaps 'on' DD in order to change 'from' to 'to'
366
- // where |from| >= |to|
367
- template <class DDType >
368
- static void changePermutation (DDType& on, Permutation& from, const Permutation& to, std::unique_ptr<dd::Package>& dd, bool regular = true ) {
369
- assert (from.size () >= to.size ());
370
-
371
- // iterate over (k,v) pairs of second permutation
372
- for (const auto & [i, goal]: to) {
373
- // search for key in the first map
374
- auto it = from.find (i);
375
- if (it == from.end ()) {
376
- throw QFRException (" [changePermutation] Key " + std::to_string (it->first ) + " was not found in first permutation. This should never happen." );
377
- }
378
- auto current = it->second ;
379
-
380
- // permutations agree for this key value
381
- if (current == goal) continue ;
382
-
383
- // search for goal value in first permutation
384
- dd::Qubit j = 0 ;
385
- for (const auto & [key, value]: from) {
386
- if (value == goal) {
387
- j = key;
388
- break ;
389
- }
390
- }
391
-
392
- // swap i and j
393
- auto saved = on;
394
- if constexpr (std::is_same_v<DDType, VectorDD>) {
395
- on = dd->multiply (dd->makeSWAPDD (on.p ->v + 1 , {}, from.at (i), from.at (j)), on);
396
- } else {
397
- // the regular flag only has an effect on matrix DDs
398
- if (regular) {
399
- on = dd->multiply (dd->makeSWAPDD (on.p ->v + 1 , {}, from.at (i), from.at (j)), on);
400
- } else {
401
- on = dd->multiply (on, dd->makeSWAPDD (on.p ->v + 1 , {}, from.at (i), from.at (j)));
402
- }
403
- }
404
-
405
- dd->incRef (on);
406
- dd->decRef (saved);
407
- dd->garbageCollect ();
408
-
409
- // update permutation
410
- from.at (i) = goal;
411
- from.at (j) = current;
412
- }
413
- }
414
368
415
369
void import (const std::string& filename);
416
370
void import (const std::string& filename, Format format);
@@ -448,14 +402,6 @@ namespace qc {
448
402
max_controls = std::max (ncontrols, max_controls);
449
403
}
450
404
451
- virtual VectorDD simulate (const VectorDD& in, std::unique_ptr<dd::Package>& dd) const ;
452
- virtual std::map<std::string, std::size_t > simulate (const VectorDD& in, std::unique_ptr<dd::Package>& dd, std::size_t shots);
453
- virtual MatrixDD buildFunctionality (std::unique_ptr<dd::Package>& dd) const ;
454
- virtual MatrixDD buildFunctionalityRecursive (std::unique_ptr<dd::Package>& dd) const ;
455
- virtual bool buildFunctionalityRecursive (std::size_t depth, std::size_t opIdx, std::stack<MatrixDD>& s, Permutation& permutation, std::unique_ptr<dd::Package>& dd) const ;
456
-
457
- virtual void extractProbabilityVector (const VectorDD& in, dd::ProbabilityVector& probVector, std::unique_ptr<dd::Package>& dd);
458
- virtual void extractProbabilityVectorRecursive (const VectorDD& currentState, decltype(ops.begin()) currentIt, std::map<std::size_t, char> measurements, dd::fp commonFactor, dd::ProbabilityVector& probVector, std::unique_ptr<dd::Package>& dd);
459
405
/* *
460
406
* printing
461
407
*/
@@ -549,6 +495,6 @@ namespace qc {
549
495
std::vector<std::unique_ptr<Operation>>::iterator insert (std::vector<std::unique_ptr<Operation>>::const_iterator pos, T&& op) { return ops.insert (pos, std::forward<T>(op)); }
550
496
551
497
[[nodiscard]] const auto & at (std::size_t i) const { return ops.at (i); }
498
+ [[nodiscard]] const auto & front () const { return ops.front (); }
552
499
};
553
500
} // namespace qc
554
- #endif // QFR_QUANTUMCOMPUTATION_H
0 commit comments