Last active
January 27, 2018 18:37
-
-
Save PhDP/474dfc28ed911b32b79a57d997ee1db3 to your computer and use it in GitHub Desktop.
C++17 sum-types version of a quantum circuit model for a 2-bit demultiplexer. It's like the object-oriented version, but it doesn't suck.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// With gcc 7+ or clang 5+, compiles with -std=c++17 flag | |
#include <iostream> | |
#include <variant> | |
#include <vector> | |
struct toffoli_gate { | |
uint32_t c0, c1, x; | |
toffoli_gate(uint32_t c0_, uint32_t c1_, uint32_t x_) noexcept | |
: c0(c0_), c1(c1_), x(x_) { | |
} | |
auto apply(std::vector<bool>& bits) const -> void { | |
if (bits[c0] && bits[c1]) bits[x] = !bits[x]; | |
} | |
auto print(std::ostream& os) const -> std::ostream& { | |
os << "toffoli(" << c0 << ',' << c1 << ',' << x << ')'; | |
return os; | |
}; | |
}; | |
struct fredkin_gate { | |
uint32_t c, a, b; | |
fredkin_gate(uint32_t c_, uint32_t a_, uint32_t b_) noexcept | |
: c(c_), a(a_), b(b_) { | |
} | |
auto apply(std::vector<bool>& bits) const -> void { | |
if (bits[c]) { | |
// std::vector<bool>'s operator() returns values so std::swap would fail. | |
auto const old_a = bits[a]; // The xor trick would do too... | |
bits[a] = bits[b]; | |
bits[b] = old_a; | |
} | |
} | |
auto print(std::ostream& os) const -> std::ostream& { | |
os << "fredkin(" << c << ',' << a << ',' << b << ')'; | |
return os; | |
}; | |
}; | |
struct not_gate { | |
uint32_t x; | |
not_gate(uint32_t x_) noexcept : x(x_) { } | |
auto apply(std::vector<bool>& bits) const -> void { | |
bits[x] = !bits[x]; | |
} | |
auto print(std::ostream& os) const -> std::ostream& { | |
os << "not(" << x << ')'; | |
return os; | |
}; | |
}; | |
struct cnot_gate { | |
uint32_t c, x; | |
cnot_gate(uint32_t c_, uint32_t x_) noexcept : c(c_), x(x_) { } | |
auto apply(std::vector<bool>& bits) const -> void { | |
if (bits[c]) bits[x] = !bits[x]; | |
} | |
auto print(std::ostream& os) const -> std::ostream& { | |
os << "cnot(" << c << ',' << x << ')'; | |
return os; | |
}; | |
}; | |
struct swap_gate { | |
uint32_t a, b; | |
swap_gate(uint32_t a_, uint32_t b_) noexcept : a(a_), b(b_) { } | |
auto apply(std::vector<bool>& bits) const -> void { | |
auto const old_a = bits[a]; | |
bits[a] = bits[b]; | |
bits[b] = old_a; | |
} | |
auto print(std::ostream& os) const -> std::ostream& { | |
os << "swap(" << a << ',' << b << ')'; | |
return os; | |
}; | |
}; | |
using gate = std::variant< | |
not_gate, | |
cnot_gate, | |
swap_gate, | |
toffoli_gate, | |
fredkin_gate | |
>; | |
// Can store directly in a vector because it's not fucking pointers to a base class: | |
using gates = std::vector<gate>; | |
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; | |
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; | |
auto apply_gates(std::vector<bool> const& bits, gates const& gs) -> std::vector<bool> { | |
auto new_bits = bits; | |
for (auto const& g : gs) { | |
std::visit([&new_bits](auto const& x) { x.apply(new_bits); }, g); | |
} | |
return new_bits; | |
} | |
auto operator<<(std::ostream& os, gate const& g) -> std::ostream& { | |
return std::visit([&os](auto const& v) -> std::ostream& { return v.print(os); }, g); | |
} | |
int main() { | |
// std::cout << "sizeof(toffoli_gate): " << sizeof(toffoli_gate) << "\n" | |
// << "sizeof(gate): " << sizeof(gate) << "\n\n"; | |
// 2-bit demultiplexer: | |
auto one_hot = gates{}; | |
one_hot.push_back(toffoli_gate(0, 1, 3)); | |
one_hot.push_back(cnot_gate(0, 1)); | |
one_hot.push_back(not_gate(0)); | |
one_hot.push_back(toffoli_gate(0, 1, 2)); | |
one_hot.push_back(cnot_gate(2, 0)); | |
one_hot.push_back(cnot_gate(2, 1)); | |
std::cout << "2-bit demultiplexer:\n"; | |
for (auto const& g : one_hot) std::cout << " " << g << '\n'; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment