#include <iostream>
#include <complex>
#include <cmath>
#include <random>
#define M_PI 3.14159265358979323846
class QBit {
private:
std::complex<double> _alpha{ 1, 0 }; // |0>
std::complex<double> _beta{ 0, 0 }; // |1>
static std::default_random_engine generator;
static std::uniform_real_distribution<double> distribution;
public:
// H: Hadamard gate
void H() {
auto newAlpha = (_alpha + _beta) / std::sqrt(2.0);
auto newBeta = (_alpha - _beta) / std::sqrt(2.0);
_alpha = newAlpha;
_beta = newBeta;
}
// X: Pauli-X gate or NOT gate
void X() {
auto temp = _alpha;
_alpha = _beta;
_beta = temp;
}
// Pauli-Y gate
void Y() {
auto newAlpha = std::complex<double>(0, 1) * _beta;
auto newBeta = -std::complex<double>(0, 1) * _alpha;
_alpha = newAlpha;
_beta = newBeta;
}
// Pauli-Z gate
void Z() {
_beta = -_beta;
}
// S: Phase gate
void S() {
_beta = std::complex<double>(0, 1) * _beta;
}
// T: π/8 gate or T gate
void T() {
_beta = std::exp(std::complex<double>(0, M_PI / 4.0)) * _beta;
}
// Measurement and Collapse!
bool M() {
double probabilityZero = std::norm(_alpha);
double randomValue = distribution(generator);
if (randomValue < probabilityZero) {
CollapseToZero();
return false;
}
else {
CollapseToOne();
return true;
}
}
void CollapseToZero() {
_alpha = { 1, 0 };
_beta = { 0, 0 };
}
void CollapseToOne() {
_alpha = { 0, 0 };
_beta = { 1, 0 };
}
// SWAP: Swap gate
void Swap(QBit& otherQBit) {
auto tempAlpha = _alpha;
auto tempBeta = _beta;
_alpha = otherQBit._alpha;
_beta = otherQBit._beta;
otherQBit._alpha = tempAlpha;
otherQBit._beta = tempBeta;
}
// CNOT: Controlled NOT gate or Controlled X gate
void CNot(QBit& control) {
if (std::norm(control._beta) > 0.5) { // Control qubit is more likely in |1> state
X();
}
}
// CCNOT: Double-controlled NOT gate or Toffoli gate
void CCNot(QBit& control1, QBit& control2) {
double probabilityControl1One = std::norm(control1._beta);
double probabilityControl2One = std::norm(control2._beta);
if (probabilityControl1One > 0.5 && probabilityControl2One > 0.5) {
X();
}
}
};
std::default_random_engine QBit::generator;
std::uniform_real_distribution<double> QBit::distribution(0.0, 1.0);
int main() {
for (int i = 0; i<10; i++)
{
QBit q1;
q1.H();
std::cout << q1.M() << std::endl;
}
return 0;
}