Skip to content

Commit 62d6c0d

Browse files
committed
Remove non-emulated shor sim (see issue #26
1 parent aae48a8 commit 62d6c0d

File tree

4 files changed

+24
-273
lines changed

4 files changed

+24
-273
lines changed

apps/simple.cpp

+2-5
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ int main(int argc, char** argv) { // NOLINT(bugprone-exception-escape)
4747
("simulate_grover_oracle_emulated", "simulate Grover's search for given number of qubits with given oracle and emulation", cxxopts::value<std::string>())
4848
("simulate_shor", "simulate Shor's algorithm factoring this number", cxxopts::value<unsigned int>())
4949
("simulate_shor_coprime", "coprime number to use with Shor's algorithm (zero randomly generates a coprime)", cxxopts::value<unsigned int>()->default_value("0"))
50-
("simulate_shor_no_emulation", "Force Shor simulator to do modular exponentiation instead of using emulation (you'll usually want emulation)")
5150
("simulate_fast_shor", "simulate Shor's algorithm factoring this number with intermediate measurements", cxxopts::value<unsigned int>())
5251
("simulate_fast_shor_coprime","coprime number to use with Shor's algorithm (zero randomly generates a coprime)", cxxopts::value<unsigned int>()->default_value("0"));
5352
// clang-format on
@@ -108,12 +107,10 @@ int main(int argc, char** argv) { // NOLINT(bugprone-exception-escape)
108107
} else if (vm.count("simulate_shor") > 0) {
109108
const unsigned int compositeNumber = vm["simulate_shor"].as<unsigned int>();
110109
const unsigned int coprime = vm["simulate_shor_coprime"].as<unsigned int>();
111-
const bool emulate = vm.count("simulate_shor_no_emulation") == 0;
112110
if (seed == 0) {
113-
ddsim = std::make_unique<ShorSimulator<dd::DDPackageConfig>>(compositeNumber, coprime, emulate, verbose, stepFidelity < 1);
111+
ddsim = std::make_unique<ShorSimulator<dd::DDPackageConfig>>(compositeNumber, coprime, verbose, stepFidelity < 1);
114112
} else {
115-
ddsim = std::make_unique<ShorSimulator<dd::DDPackageConfig>>(compositeNumber, coprime, seed, emulate, verbose,
116-
stepFidelity < 1);
113+
ddsim = std::make_unique<ShorSimulator<dd::DDPackageConfig>>(compositeNumber, coprime, seed, verbose, stepFidelity < 1);
117114
}
118115
} else if (vm.count("simulate_grover") > 0) {
119116
const unsigned int nQubits = vm["simulate_grover"].as<unsigned int>();

include/ShorSimulator.hpp

+7-30
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,6 @@ class ShorSimulator: public Simulator<Config> {
3636
return std::sin((dd::PI * fac) / div);
3737
}
3838

39-
void uA(std::uint64_t a, std::uint32_t n, std::int32_t c);
40-
41-
void cmultInv(std::uint64_t a, std::uint32_t n, std::int32_t c);
42-
43-
void cmult(std::uint64_t a, std::uint32_t n, std::int32_t c);
44-
45-
void modAddPhiInv(std::uint64_t a, std::uint64_t n, std::int32_t c1, std::int32_t c2);
46-
47-
void modAddPhi(std::uint64_t a, std::uint32_t n, std::int32_t c1, std::int32_t c2);
48-
49-
void qftInv();
50-
51-
void qft();
52-
53-
void addPhiInv(std::uint64_t a, std::int32_t c1, std::int32_t c2);
54-
55-
void addPhi(std::uint64_t a, std::int32_t c1, std::int32_t c2);
56-
57-
static std::int32_t inverseMod(std::int32_t a, std::int32_t n);
58-
5939
void uAEmulate(std::uint64_t a, std::int32_t q);
6040

6141
void applyGate(dd::GateMatrix matrix, dd::Qubit target, const dd::Controls& controls);
@@ -87,41 +67,38 @@ class ShorSimulator: public Simulator<Config> {
8767
std::string polrResult = "did not start";
8868
std::pair<std::uint32_t, std::uint32_t> polrFactors{0, 0};
8969

90-
bool emulate;
9170
bool verbose;
9271
bool approximate;
9372
std::uint64_t approximationRuns{0};
9473
long double finalFidelity{1.0L};
9574
double stepFidelity{0.9};
9675

97-
dd::mEdge limitStateVector(dd::vEdge e);
98-
9976
std::map<dd::vNode*, dd::mEdge> dagEdges;
10077

10178
public:
10279
ShorSimulator(const std::size_t compositeNumber, const std::size_t coprimeNumber):
10380
Simulator<Config>(), compositeN(compositeNumber), coprimeA(coprimeNumber),
104-
requiredBits(static_cast<std::size_t>(std::ceil(std::log2(compositeNumber)))), emulate(true), verbose(false), approximate(false) {
81+
requiredBits(static_cast<std::size_t>(std::ceil(std::log2(compositeNumber)))), verbose(false), approximate(false) {
10582
ts.resize(nQubits);
10683
};
10784

10885
ShorSimulator(const std::size_t compositeNumber, const std::size_t coprimeNumber, const std::uint64_t seed_):
10986
Simulator<Config>(seed_), compositeN(compositeNumber), coprimeA(coprimeNumber),
110-
requiredBits(static_cast<std::size_t>(std::ceil(std::log2(compositeNumber)))), emulate(true), verbose(false), approximate(false) {
87+
requiredBits(static_cast<std::size_t>(std::ceil(std::log2(compositeNumber)))), verbose(false), approximate(false) {
11188
ts.resize(nQubits);
11289
};
11390

114-
ShorSimulator(const std::size_t compositeNumber, const std::size_t coprimeNumber, const bool emulate_, const bool verbose_, const bool approximate_):
91+
ShorSimulator(const std::size_t compositeNumber, const std::size_t coprimeNumber, const bool verbose_, const bool approximate_):
11592
Simulator<Config>(), compositeN(compositeNumber), coprimeA(coprimeNumber),
116-
requiredBits(static_cast<std::size_t>(std::ceil(std::log2(compositeNumber)))), emulate(emulate_), verbose(verbose_),
93+
requiredBits(static_cast<std::size_t>(std::ceil(std::log2(compositeNumber)))), verbose(verbose_),
11794
approximate(approximate_) {
11895
ts.resize(nQubits);
11996
};
12097

121-
ShorSimulator(const std::size_t compositeNumber, const std::size_t coprimeNumber, const std::uint64_t seed_, const bool emulate_, const bool verbose_, const bool approximate_):
98+
ShorSimulator(const std::size_t compositeNumber, const std::size_t coprimeNumber, const std::uint64_t seed_, const bool verbose_, const bool approximate_):
12299
Simulator<Config>(seed_),
123100
compositeN(compositeNumber), coprimeA(coprimeNumber),
124-
requiredBits(static_cast<std::size_t>(std::ceil(std::log2(compositeNumber)))), emulate(emulate_), verbose(verbose_),
101+
requiredBits(static_cast<std::size_t>(std::ceil(std::log2(compositeNumber)))), verbose(verbose_),
125102
approximate(approximate_) {
126103
ts.resize(nQubits);
127104
};
@@ -148,7 +125,7 @@ class ShorSimulator: public Simulator<Config> {
148125
return {
149126
{"composite_number", std::to_string(compositeN)},
150127
{"coprime_a", std::to_string(coprimeA)},
151-
{"emulation", (emulate ? "true" : "false")},
128+
{"emulation", "true"},
152129
{"sim_result", simResult},
153130
{"sim_factor1", std::to_string(simFactors.first)},
154131
{"sim_factor2", std::to_string(simFactors.second)},

src/ShorSimulator.cpp

+12-226
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,12 @@ std::map<std::string, std::size_t> ShorSimulator<Config>::simulate([[maybe_unuse
1414
std::clog << "simulate Shor's algorithm for n=" << compositeN;
1515
}
1616

17-
if (emulate) {
18-
nQubits = static_cast<dd::QubitCount>(3 * requiredBits);
19-
Simulator<Config>::rootEdge = Simulator<Config>::dd->makeZeroState(static_cast<dd::QubitCount>(nQubits));
20-
Simulator<Config>::dd->incRef(Simulator<Config>::rootEdge);
21-
//Initialize qubits
22-
//TODO: other init method where the initial value can be chosen
23-
applyGate(dd::Xmat, 0);
24-
25-
} else {
26-
nQubits = static_cast<dd::QubitCount>(2 * requiredBits + 3);
27-
Simulator<Config>::rootEdge = Simulator<Config>::dd->makeZeroState(static_cast<dd::QubitCount>(nQubits));
28-
Simulator<Config>::dd->incRef(Simulator<Config>::rootEdge);
29-
//Initialize qubits
30-
//TODO: other init method where the initial value can be chosen
31-
32-
applyGate(dd::Xmat, static_cast<dd::Qubit>(nQubits - 1));
33-
}
17+
nQubits = static_cast<dd::QubitCount>(3 * requiredBits);
18+
Simulator<Config>::rootEdge = Simulator<Config>::dd->makeZeroState(static_cast<dd::QubitCount>(nQubits));
19+
Simulator<Config>::dd->incRef(Simulator<Config>::rootEdge);
20+
//Initialize qubits
21+
//TODO: other init method where the initial value can be chosen
22+
applyGate(dd::Xmat, 0);
3423

3524
if (verbose) {
3625
std::clog << " (requires " << nQubits << " qubits):\n";
@@ -69,24 +58,13 @@ std::map<std::string, std::size_t> ShorSimulator<Config>::simulate([[maybe_unuse
6958
const auto mod = static_cast<std::int32_t>(std::ceil(2.0 * static_cast<double>(requiredBits) / 6.0)); // log_0.9(0.5) is about 6
7059
const auto t1 = std::chrono::steady_clock::now();
7160

72-
if (emulate) {
73-
for (std::uint32_t i = 0; i < 2 * requiredBits; i++) {
74-
if (verbose) {
75-
std::clog << "[ " << (i + 1) << "/" << 2 * requiredBits << " ] uAEmulate(" << as[i] << ", " << i
76-
<< ") " << std::chrono::duration<float>(std::chrono::steady_clock::now() - t1).count() << "\n"
77-
<< std::flush;
78-
}
79-
uAEmulate(as[i], static_cast<std::int32_t>(i));
80-
}
81-
} else {
82-
for (std::uint32_t i = 0; i < 2 * requiredBits; i++) {
83-
if (verbose) {
84-
std::clog << "[ " << (i + 1) << "/" << 2 * requiredBits << " ] uA(" << as[i] << ", " << compositeN << ", " << 0
85-
<< ") " << std::chrono::duration<float>(std::chrono::steady_clock::now() - t1).count() << "\n"
86-
<< std::flush;
87-
}
88-
uA(as[i], static_cast<std::uint32_t>(compositeN), 0);
61+
for (std::uint32_t i = 0; i < 2 * requiredBits; i++) {
62+
if (verbose) {
63+
std::clog << "[ " << (i + 1) << "/" << 2 * requiredBits << " ] uAEmulate(" << as[i] << ", " << i
64+
<< ") " << std::chrono::duration<float>(std::chrono::steady_clock::now() - t1).count() << "\n"
65+
<< std::flush;
8966
}
67+
uAEmulate(as[i], static_cast<std::int32_t>(i));
9068
}
9169

9270
if (verbose) {
@@ -450,198 +428,6 @@ void ShorSimulator<Config>::uAEmulate(std::uint64_t a, std::int32_t q) {
450428
Simulator<Config>::dd->garbageCollect();
451429
}
452430

453-
template<class Config>
454-
std::int32_t ShorSimulator<Config>::inverseMod(std::int32_t a, std::int32_t n) {
455-
std::int32_t t = 0;
456-
std::int32_t newt = 1;
457-
std::int32_t r = n;
458-
std::int32_t newr = a;
459-
while (newr != 0) {
460-
const std::int32_t quotient = r / newr;
461-
std::int32_t h = t;
462-
463-
t = newt;
464-
newt = h - quotient * newt;
465-
h = r;
466-
r = newr;
467-
newr = h - quotient * newr;
468-
}
469-
if (r > 1) {
470-
std::cerr << "ERROR: a=" << a << " with n=" << n << " is not invertible\n";
471-
std::exit(3);
472-
}
473-
if (t < 0) {
474-
t = t + n;
475-
}
476-
return t;
477-
}
478-
479-
template<class Config>
480-
void ShorSimulator<Config>::addPhi(std::uint64_t a, std::int32_t c1, std::int32_t c2) {
481-
for (auto i = static_cast<std::int32_t>(requiredBits); i >= 0; --i) {
482-
double q = 1;
483-
std::uint32_t fac = 0;
484-
for (std::int32_t j = i; j >= 0; --j) {
485-
if (((a >> j) & 1U) != 0U) {
486-
fac |= 1U;
487-
}
488-
fac *= 2;
489-
q *= 2;
490-
}
491-
492-
dd::Controls controls;
493-
if (c1 != std::numeric_limits<std::int32_t>::min()) {
494-
controls.emplace(dd::Control{static_cast<dd::Qubit>((nQubits - 1) - static_cast<std::size_t>(c1))});
495-
}
496-
if (c2 != std::numeric_limits<std::int32_t>::min()) {
497-
controls.emplace(dd::Control{static_cast<dd::Qubit>((nQubits - 1) - static_cast<std::size_t>(c2))});
498-
}
499-
500-
double qR = cosine(fac, q);
501-
double qI = sine(fac, q);
502-
const dd::GateMatrix qm{dd::complex_one, dd::complex_zero, dd::complex_zero, {qR, qI}};
503-
504-
applyGate(qm, static_cast<dd::Qubit>((nQubits - 1) - (1 + 2 * requiredBits - static_cast<std::uint32_t>(i))), controls);
505-
}
506-
}
507-
508-
template<class Config>
509-
void ShorSimulator<Config>::addPhiInv(std::uint64_t a, std::int32_t c1, std::int32_t c2) {
510-
for (auto i = static_cast<std::int32_t>(requiredBits); i >= 0; --i) {
511-
double q = 1;
512-
std::uint32_t fac = 0;
513-
for (std::int32_t j = i; j >= 0; --j) {
514-
if (((a >> j) & 1U) != 0U) {
515-
fac |= 1U;
516-
}
517-
fac *= 2;
518-
q *= 2;
519-
}
520-
dd::Controls controls;
521-
if (c1 != std::numeric_limits<std::int32_t>::min()) {
522-
controls.emplace(dd::Control{static_cast<dd::Qubit>((nQubits - 1) - static_cast<std::size_t>(c1))});
523-
}
524-
if (c2 != std::numeric_limits<std::int32_t>::min()) {
525-
controls.emplace(dd::Control{static_cast<dd::Qubit>((nQubits - 1) - static_cast<std::size_t>(c2))});
526-
}
527-
528-
double qR = cosine(fac, -q);
529-
double qI = sine(fac, -q);
530-
const dd::GateMatrix qm{dd::complex_one, dd::complex_zero, dd::complex_zero, {qR, qI}};
531-
applyGate(qm, static_cast<dd::Qubit>((nQubits - 1) - (1 + 2 * requiredBits - static_cast<std::size_t>(i))), controls);
532-
}
533-
}
534-
535-
template<class Config>
536-
void ShorSimulator<Config>::qft() {
537-
for (std::size_t i = requiredBits + 1; i < 2 * requiredBits + 2; i++) {
538-
applyGate(dd::Hmat, static_cast<dd::Qubit>((nQubits - 1) - i));
539-
540-
double q = 2;
541-
for (std::size_t j = i + 1; j < 2 * requiredBits + 2; j++) {
542-
double qR = cosine(1, q);
543-
double qI = sine(1, q);
544-
const dd::GateMatrix qm{dd::complex_one, dd::complex_zero, dd::complex_zero, {qR, qI}};
545-
applyGate(qm, static_cast<dd::Qubit>((nQubits - 1) - i), dd::Control{static_cast<dd::Qubit>((nQubits - 1) - j)});
546-
q *= 2;
547-
}
548-
}
549-
}
550-
551-
template<class Config>
552-
void ShorSimulator<Config>::qftInv() {
553-
for (std::size_t i = 2 * requiredBits + 1; i >= requiredBits + 1; i--) {
554-
double q = 2;
555-
for (std::size_t j = i + 1; j < 2 * requiredBits + 2; j++) {
556-
double qR = cosine(1, -q);
557-
double qI = sine(1, -q);
558-
const dd::GateMatrix qm{dd::complex_one, dd::complex_zero, dd::complex_zero, {qR, qI}};
559-
applyGate(qm, static_cast<dd::Qubit>((nQubits - 1) - i), dd::Control{static_cast<dd::Qubit>((nQubits - 1) - j)});
560-
q *= 2;
561-
}
562-
applyGate(dd::Hmat, static_cast<dd::Qubit>((nQubits - 1) - i));
563-
}
564-
}
565-
566-
template<class Config>
567-
void ShorSimulator<Config>::modAddPhi(std::uint64_t a, std::uint32_t n, std::int32_t c1, std::int32_t c2) {
568-
addPhi(a, c1, c2);
569-
addPhiInv(n, std::numeric_limits<std::int32_t>::min(), std::numeric_limits<std::int32_t>::min());
570-
571-
qftInv();
572-
573-
applyGate(dd::Xmat, static_cast<dd::Qubit>((nQubits - 1) - (2 * requiredBits + 2)), dd::Control{static_cast<dd::Qubit>((nQubits - 1) - (requiredBits + 1))});
574-
575-
qft();
576-
addPhi(n, static_cast<std::int32_t>(2 * requiredBits + 2), std::numeric_limits<std::int32_t>::min());
577-
addPhiInv(a, c1, c2);
578-
qftInv();
579-
580-
applyGate(dd::Xmat, static_cast<dd::Qubit>((nQubits - 1) - (2 * requiredBits + 2)), dd::Control{static_cast<dd::Qubit>((nQubits - 1) - (requiredBits + 1)), dd::Control::Type::neg});
581-
582-
qft();
583-
addPhi(a, c1, c2);
584-
}
585-
586-
template<class Config>
587-
void ShorSimulator<Config>::modAddPhiInv(std::uint64_t a, std::uint64_t n, std::int32_t c1, std::int32_t c2) {
588-
addPhiInv(a, c1, c2);
589-
qftInv();
590-
591-
applyGate(dd::Xmat, static_cast<dd::Qubit>((nQubits - 1) - (2 * requiredBits + 2)), dd::Control{static_cast<dd::Qubit>((nQubits - 1) - (requiredBits + 1)), dd::Control::Type::neg});
592-
593-
qft();
594-
addPhi(a, c1, c2);
595-
addPhiInv(n, static_cast<std::int32_t>(2 * requiredBits + 2), std::numeric_limits<std::int32_t>::min());
596-
qftInv();
597-
598-
applyGate(dd::Xmat, static_cast<dd::Qubit>((nQubits - 1) - (2 * requiredBits + 2)), dd::Control{static_cast<dd::Qubit>((nQubits - 1) - (requiredBits + 1))});
599-
600-
qft();
601-
addPhi(n, std::numeric_limits<std::int32_t>::min(), std::numeric_limits<std::int32_t>::min());
602-
addPhiInv(a, c1, c2);
603-
}
604-
605-
template<class Config>
606-
void ShorSimulator<Config>::cmult(std::uint64_t a, std::uint32_t n, std::int32_t c) {
607-
qft();
608-
609-
std::uint64_t t = a;
610-
for (auto i = static_cast<int32_t>(requiredBits); i >= 1; i--) {
611-
modAddPhi(t, n, i, c);
612-
t = (2 * t) % n;
613-
}
614-
qftInv();
615-
}
616-
617-
template<class Config>
618-
void ShorSimulator<Config>::cmultInv(std::uint64_t a, std::uint32_t n, std::int32_t c) {
619-
qft();
620-
std::uint64_t t = a;
621-
for (auto i = static_cast<int32_t>(requiredBits); i >= 1; i--) {
622-
modAddPhiInv(t, n, i, c);
623-
t = (2 * t) % n;
624-
}
625-
qftInv();
626-
}
627-
628-
template<class Config>
629-
void ShorSimulator<Config>::uA(std::uint64_t a, std::uint32_t n, std::int32_t c) {
630-
using namespace dd::literals;
631-
cmult(a, n, c);
632-
for (std::uint32_t i = 0; i < requiredBits; i++) {
633-
applyGate(dd::Xmat, static_cast<dd::Qubit>((nQubits - 1) - (i + 1)), dd::Control{static_cast<dd::Qubit>((nQubits - 1) - (requiredBits + 2 + i))});
634-
635-
applyGate(dd::Xmat, static_cast<dd::Qubit>((nQubits - 1) - (requiredBits + 2 + i)),
636-
dd::Controls{{dd::Control{static_cast<dd::Qubit>(nQubits - 1 - (i + 1))},
637-
dd::Control{static_cast<dd::Qubit>(nQubits - 1 - static_cast<std::size_t>(c))}}});
638-
639-
applyGate(dd::Xmat, static_cast<dd::Qubit>((nQubits - 1) - (i + 1)), dd::Control{static_cast<dd::Qubit>((nQubits - 1) - (requiredBits + 2 + i))});
640-
}
641-
642-
cmultInv(static_cast<std::uint64_t>(inverseMod(static_cast<std::int32_t>(a), static_cast<std::int32_t>(n))), n, c);
643-
}
644-
645431
template<class Config>
646432
void ShorSimulator<Config>::applyGate(dd::GateMatrix matrix, dd::Qubit target) {
647433
applyGate(matrix, target, dd::Controls{});

0 commit comments

Comments
 (0)