| 26 | } |
| 27 | |
| 28 | QCircuit CDKMRippleAdder::QAdd(QVec a, QVec b, QVec aux, ADDER_MODE mode /* = ADDER_MODE::CINOUT */) |
| 29 | { |
| 30 | if ((a.size() == 0) || a.size() != b.size()) |
| 31 | { |
| 32 | QCERR_AND_THROW(std::invalid_argument, "a and b must be equal, but not equal to 0!"); |
| 33 | } |
| 34 | int need_aux_size = 2; |
| 35 | if (!(mode & ADDER_MODE::CIN)) |
| 36 | { |
| 37 | need_aux_size = 3; |
| 38 | } |
| 39 | |
| 40 | QPANDA_ASSERT(aux.size() < need_aux_size, "auxiliary bit at least have size 3"); |
| 41 | int n = a.size(); |
| 42 | |
| 43 | auto qc = createEmptyCircuit(); |
| 44 | |
| 45 | /* |
| 46 | qubits layout |
| 47 | |
| 48 | aux |0|0| .... |0| highest bit |
| 49 | | | | not usde | | |
| 50 | ^ ^ ^ |
| 51 | c_in ancil c_out/overflow |
| 52 | */ |
| 53 | Qubit *c_in = aux.front(); |
| 54 | Qubit *ancil = *(aux.begin() + 1); |
| 55 | Qubit *c_out = aux.back(); |
| 56 | Qubit *overflow = aux.back(); |
| 57 | |
| 58 | if (mode & ADDER_MODE::CIN) |
| 59 | { |
| 60 | qc << addWithCin(a, b, aux, mode); |
| 61 | } |
| 62 | else |
| 63 | { |
| 64 | /* |
| 65 | * a_0 ──■────■── a_0 |
| 66 | * │ ┌─┴─┐ |
| 67 | * b_0 ──■──┤ X ├ a_0 ⊕ b_0 = s_0 |
| 68 | * ┌─┴─┐└───┘ |
| 69 | * anc ┤ X ├───── anc ⊕ a_0.b_0 = c_1 (anc should be |0>) |
| 70 | * └───┘ |
| 71 | */ |
| 72 | qc << X(ancil).control({a[0], b[0]}) |
| 73 | << CNOT(a[0], b[0]); |
| 74 | if (n > 1) |
| 75 | { |
| 76 | QVec a_1(a.begin() + 1, a.end()); |
| 77 | QVec b_1(b.begin() + 1, b.end()); |
| 78 | QVec new_aux; |
| 79 | new_aux += ancil; |
| 80 | new_aux += c_out; |
| 81 | if (n == 2 && (ADDER_MODE::OF & mode)) |
| 82 | { |
| 83 | qc << CNOT(ancil, overflow); |
| 84 | } |
| 85 | qc << addWithCin(a_1, b_1, new_aux, mode | ADDER_MODE::CIN); |