-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathquantum.hpp
More file actions
108 lines (79 loc) · 3.02 KB
/
quantum.hpp
File metadata and controls
108 lines (79 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#pragma once
#include <cstdint>
#include <complex>
#include <initializer_list>
#include <string>
#include <vector>
#include <iostream>
using qufloat_t = double;
using amp_t = std::complex<qufloat_t>;
//takes in relevant state amplitudes of the block and writes back their new values (void* is extra data)
using qugate_fn = void(*)(amp_t**, amp_t*, void*);
struct qugate {
qugate_fn fun;
void *data;
uint8_t bits;
bool should_free;
qugate(qugate_fn fn, uint8_t bits = 1, void* dat = nullptr, bool free_dat = false)
: fun(fn), bits(bits), data(dat), should_free(free_dat) {}
~qugate() { if (should_free) free(data); }
inline qugate& operator()(std::vector<amp_t*>& in, std::vector<amp_t>& out) {
fun(in.data(), out.data(), data);
return *this;
}
static qugate hadamard();
static qugate pauli_X();
static qugate pauli_Y();
static qugate pauli_Z();
static qugate rot_X(qufloat_t angle);
static qugate rot_Y(qufloat_t angle);
static qugate rot_Z(qufloat_t angle);
static qugate swap();
//matrix must be 2^n by 2^n for n being the number of input bits
static qugate matrix(amp_t* m, uint8_t bit_num);
static qugate increment(int by, uint8_t bit_num);
};
//quantum register; A series of qubits that are entangled
struct qureg {
std::vector<amp_t> state; //writing directly to this is not recommended
uint_fast8_t size; //in qubits
//good place to draw the line
static constexpr int max_qubits = 32;
//throws an out_of_range if 0 or greater than max
void resize(uint_fast8_t num);
//state starts out fully randomized (equal probabilities)
qureg(uint8_t num);
//collapses state to a single value
qureg(uint8_t num, uint64_t bits);
//used internally, not hardware feasible
double probability(uint64_t bits) const;
//returns a collapsed state without collapsing (not hardware feasible)
uint64_t measure(void) const;
//collapses state and measures it
uint64_t collapse(void);
using bit_list = const std::vector<uint8_t>;
void gate(qugate gate, bit_list bits = {0}, bit_list c_on = {}, bit_list c_off = {});
//gate shorthands
void op_X(uint8_t bit = 0);
void op_Y(uint8_t bit = 0);
void op_Z(uint8_t bit = 0);
void op_hadamard(uint8_t bit = 0);
void op_swap(uint8_t a, uint8_t b);
void op_X_range(uint8_t start, uint8_t end);
void op_Y_range(uint8_t start, uint8_t end);
void op_Z_range(uint8_t start, uint8_t end);
void op_hadamard_range(uint8_t start, uint8_t end);
//bit must not be the same as control
void op_CX(uint8_t bit, uint8_t control);
void op_CY(uint8_t bit, uint8_t control);
void op_CZ(uint8_t bit, uint8_t control);
//also known as CCNOT or Toffoli
void op_CCX(uint8_t bit, uint8_t c1, uint8_t c2);
void op_CCY(uint8_t bit, uint8_t c1, uint8_t c2);
void op_CCZ(uint8_t bit, uint8_t c1, uint8_t c2);
};
std::vector<uint8_t> bit_range(uint8_t start, uint8_t end);
//iostream support for state vector
std::ostream& operator<<(std::ostream& os, const std::vector<amp_t>& vec);
//bit num 0 will print in a flexible length manner
std::string print_bits(uint64_t x, int bit_num = 0);