30 DEMAND( (qb1 >= 0 && qb1 < numQb) );
31 DEMAND( (qb2 >= 0 && qb2 < numQb) );
43 out = qmatrix{{1,0,0,0},{0,0,1,0},{0,1,0,0},{0,0,0,1}};
47 int block = getPow2(qb2 - qb1);
52 qmatrix p0{{1,0},{0,0}};
53 qmatrix l0{{0,1},{0,0}};
54 qmatrix l1{{0,0},{1,0}};
55 qmatrix p1{{0,0},{0,1}};
78auto getSwapAndUnswapMatrices(vector<int> ctrls, vector<int> targs,
size_t numQubits) {
79 DEMAND( numQubits >= ctrls.size() + targs.size() );
86 for (
size_t i=0; i<targs.size(); i++) {
88 if (i == (
size_t) targs[i])
93 unswaps = unswaps * m;
95 std::replace(ctrls.begin(), ctrls.end(), (
int) i, targs[i]);
96 std::replace(targs.begin(), targs.end(), (
int) i, targs[i]);
100 for (
size_t i=0; i<ctrls.size(); i++) {
102 size_t j = i + targs.size();
103 if (j == (
size_t) ctrls[i])
108 unswaps = unswaps * m;
110 std::replace(ctrls.begin(), ctrls.end(), (
int) j, ctrls[i]);
113 return std::tuple{swaps, unswaps};
117qmatrix getFullStateOperator(vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qmatrix matrix,
size_t numQubits) {
118 DEMAND( numQubits >= ctrls.size() + targs.size() );
119 DEMAND( getPow2(targs.size()) == (qindex) matrix.size() );
120 DEMAND( (ctrlStates.empty() || ctrlStates.size() == ctrls.size()) );
123 qmatrix full = getControlledMatrix(matrix, ctrls.size());
126 if (numQubits > ctrls.size() + targs.size()) {
127 size_t pad = getPow2(numQubits - ctrls.size() - targs.size());
132 auto [swaps, unswaps] = getSwapAndUnswapMatrices(ctrls, targs, numQubits);
133 qmatrix out = unswaps * full * swaps;
136 qmatrix matrX = {{0,1},{1,0}};
137 for (
size_t i=0; i<ctrlStates.size(); i++) {
139 if (ctrlStates[i] == 1)
142 qmatrix fullX = getFullStateOperator({}, {}, {ctrls[i]}, matrX, numQubits);
143 out = fullX * out * fullX;
158void applyReferenceOperator(qvector& state, qmatrix matrix) {
159 DEMAND( state.size() == matrix.size() );
161 state = matrix * state;
163void applyReferenceOperator(qmatrix& state, qmatrix matrix) {
164 DEMAND( state.size() == matrix.size() );
169void leftapplyReferenceOperator(qvector& state, qmatrix matrix) {
170 DEMAND( state.size() == matrix.size() );
173 applyReferenceOperator(state, matrix);
176void leftapplyReferenceOperator(qmatrix& state, qmatrix matrix) {
177 DEMAND( state.size() == matrix.size() );
180 state = matrix * state;
183void rightapplyReferenceOperator(qmatrix& state, qmatrix matrix) {
184 DEMAND( state.size() == matrix.size() );
187 state = state * matrix;
193void applyReferenceOperator(qvector& state, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qmatrix matrix) {
195 qmatrix fullOp = getFullStateOperator(ctrls, ctrlStates, targs, matrix, getLog2(state.size()));
196 applyReferenceOperator(state, fullOp);
199void applyReferenceOperator(qmatrix& state, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qmatrix matrix) {
201 qmatrix fullOp = getFullStateOperator(ctrls, ctrlStates, targs, matrix, getLog2(state.size()));
202 applyReferenceOperator(state, fullOp);
205void leftapplyReferenceOperator(qvector& state, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qmatrix matrix) {
207 applyReferenceOperator(state, ctrls, ctrlStates, targs, matrix);
210void leftapplyReferenceOperator(qmatrix& state, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qmatrix matrix) {
212 qmatrix left = getFullStateOperator(ctrls, ctrlStates, targs, matrix, getLog2(state.size()));
213 leftapplyReferenceOperator(state, left);
216void rightapplyReferenceOperator(qmatrix& state, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qmatrix matrix) {
218 qmatrix left = getFullStateOperator(ctrls, ctrlStates, targs, matrix, getLog2(state.size()));
219 rightapplyReferenceOperator(state, left);
225void applyReferenceOperator(qvector& state, vector<int> ctrls, vector<int> targs, qmatrix matrix) {
227 applyReferenceOperator(state, ctrls, {}, targs, matrix);
229void applyReferenceOperator(qmatrix& state, vector<int> ctrls, vector<int> targs, qmatrix matrix) {
231 applyReferenceOperator(state, ctrls, {}, targs, matrix);
233void leftapplyReferenceOperator(qvector& state, vector<int> ctrls, vector<int> targs, qmatrix matrix) {
235 leftapplyReferenceOperator(state, ctrls, {}, targs, matrix);
237void leftapplyReferenceOperator(qmatrix& state, vector<int> ctrls, vector<int> targs, qmatrix matrix) {
239 leftapplyReferenceOperator(state, ctrls, {}, targs, matrix);
241void rightapplyReferenceOperator(qmatrix& state, vector<int> ctrls, vector<int> targs, qmatrix matrix) {
243 rightapplyReferenceOperator(state, ctrls, {}, targs, matrix);
249void applyReferenceOperator(qvector& state, vector<int> targs, qmatrix matrix) {
251 applyReferenceOperator(state, {}, {}, targs, matrix);
253void applyReferenceOperator(qmatrix& state, vector<int> targs, qmatrix matrix) {
255 applyReferenceOperator(state, {}, {}, targs, matrix);
257void leftapplyReferenceOperator(qvector& state, vector<int> targs, qmatrix matrix) {
259 leftapplyReferenceOperator(state, {}, {}, targs, matrix);
261void leftapplyReferenceOperator(qmatrix& state, vector<int> targs, qmatrix matrix) {
263 leftapplyReferenceOperator(state, {}, {}, targs, matrix);
265void rightapplyReferenceOperator(qmatrix& state, vector<int> targs, qmatrix matrix) {
267 rightapplyReferenceOperator(state, {}, {}, targs, matrix);
273void applyReferenceOperator(qmatrix& state, vector<int> targs, vector<qmatrix> matrices) {
278 for (
auto& matrix : matrices) {
280 applyReferenceOperator(state, targs, matrix);
qmatrix getSwapMatrix(int qb1, int qb2, int numQb)
qmatrix getKroneckerProduct(qmatrix a, qmatrix b)
qmatrix getConjugateTranspose(qmatrix m)
qmatrix getIdentityMatrix(size_t dim)
void setSubMatrix(qmatrix &dest, qmatrix sub, size_t r, size_t c)
qmatrix getZeroMatrix(size_t dim)