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 multiplyReferenceOperator(qvector& state, qmatrix matrix) {
170 DEMAND( state.size() == matrix.size() );
173 applyReferenceOperator(state, matrix);
176void multiplyReferenceOperator(qmatrix& state, qmatrix matrix) {
177 DEMAND( state.size() == matrix.size() );
180 state = matrix * state;
186void applyReferenceOperator(qvector& state, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qmatrix matrix) {
188 qmatrix fullOp = getFullStateOperator(ctrls, ctrlStates, targs, matrix, getLog2(state.size()));
189 applyReferenceOperator(state, fullOp);
192void applyReferenceOperator(qmatrix& state, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qmatrix matrix) {
194 qmatrix fullOp = getFullStateOperator(ctrls, ctrlStates, targs, matrix, getLog2(state.size()));
195 applyReferenceOperator(state, fullOp);
198void multiplyReferenceOperator(qvector& state, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qmatrix matrix) {
200 applyReferenceOperator(state, ctrls, ctrlStates, targs, matrix);
203void multiplyReferenceOperator(qmatrix& state, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qmatrix matrix) {
205 qmatrix left = getFullStateOperator(ctrls, ctrlStates, targs, matrix, getLog2(state.size()));
206 multiplyReferenceOperator(state, left);
212void applyReferenceOperator(qvector& state, vector<int> ctrls, vector<int> targs, qmatrix matrix) {
214 applyReferenceOperator(state, ctrls, {}, targs, matrix);
216void applyReferenceOperator(qmatrix& state, vector<int> ctrls, vector<int> targs, qmatrix matrix) {
218 applyReferenceOperator(state, ctrls, {}, targs, matrix);
220void multiplyReferenceOperator(qvector& state, vector<int> ctrls, vector<int> targs, qmatrix matrix) {
222 multiplyReferenceOperator(state, ctrls, {}, targs, matrix);
224void multiplyReferenceOperator(qmatrix& state, vector<int> ctrls, vector<int> targs, qmatrix matrix) {
226 multiplyReferenceOperator(state, ctrls, {}, targs, matrix);
232void applyReferenceOperator(qvector& state, vector<int> targs, qmatrix matrix) {
234 applyReferenceOperator(state, {}, {}, targs, matrix);
236void applyReferenceOperator(qmatrix& state, vector<int> targs, qmatrix matrix) {
238 applyReferenceOperator(state, {}, {}, targs, matrix);
240void multiplyReferenceOperator(qvector& state, vector<int> targs, qmatrix matrix) {
242 multiplyReferenceOperator(state, {}, {}, targs, matrix);
244void multiplyReferenceOperator(qmatrix& state, vector<int> targs, qmatrix matrix) {
246 multiplyReferenceOperator(state, {}, {}, targs, matrix);
252void applyReferenceOperator(qmatrix& state, vector<int> targs, vector<qmatrix> matrices) {
257 for (
auto& matrix : matrices) {
259 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)