-
-
Notifications
You must be signed in to change notification settings - Fork 54
Add multi-control functionality #1380
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
2134c2e
0ae2b61
f8c4503
894add1
fb32afb
2375b74
275e832
c873318
068560c
53032bb
5c68a2f
3f46cd3
33b48a7
453e00a
b81e3e3
2505f27
9ab82f3
06a40af
92ed957
0911f7c
3d74d1b
9915b6a
cdc0ec3
ee9b279
cbda9d6
a8af5a7
8236fbf
14e1955
9de9ac9
826829e
93bf49d
48caa99
8cbe448
e10767e
9816218
ef2f343
77dae77
6460a92
4af8da7
63f2325
eed43bf
bf5e23e
3f1fa28
340bad9
4780212
ff77fa4
297078e
9ab3177
553ab8f
67b8fc2
440ff42
e82defd
1f224ce
18a8aa1
c4c524c
4a51d10
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -307,6 +307,145 @@ | |
| addCnot(diag, ctrl0, ctrl1, qubits); | ||
| } | ||
|
|
||
| void FunctionalityConstruction::addCcz(ZXDiagram& diag, const Qubit ctrl0, | ||
| const Qubit ctrl1, const Qubit target, | ||
| std::vector<Vertex>& qubits) { | ||
|
|
||
| addCnot(diag, ctrl1, target, qubits); | ||
| addZSpider(diag, target, qubits, PiExpression(PiRational(-1, 4))); | ||
| addCnot(diag, ctrl0, target, qubits); | ||
| addZSpider(diag, target, qubits, PiExpression(PiRational(1, 4))); | ||
| addCnot(diag, ctrl1, target, qubits); | ||
| addZSpider(diag, ctrl1, qubits, PiExpression(PiRational(1, 4))); | ||
| addZSpider(diag, target, qubits, PiExpression(PiRational(-1, 4))); | ||
| addCnot(diag, ctrl0, target, qubits); | ||
| addZSpider(diag, target, qubits, PiExpression(PiRational(1, 4))); | ||
| addCnot(diag, ctrl0, ctrl1, qubits); | ||
| addZSpider(diag, ctrl0, qubits, PiExpression(PiRational(1, 4))); | ||
| addZSpider(diag, ctrl1, qubits, PiExpression(PiRational(-1, 4))); | ||
| addZSpider(diag, target, qubits, PiExpression(PiRational(0, 1)), | ||
| EdgeType::Hadamard); | ||
| addCnot(diag, ctrl0, ctrl1, qubits); | ||
| addZSpider(diag, target, qubits, PiExpression(), EdgeType::Hadamard); | ||
| } | ||
|
|
||
| void FunctionalityConstruction::addCrz(ZXDiagram& diag, | ||
| const PiExpression& phase, | ||
| const Qubit control, const Qubit target, | ||
| std::vector<Vertex>& qubits) { | ||
| addCnot(diag, target, control, qubits); | ||
|
Check warning on line 336 in src/zx/FunctionalityConstruction.cpp
|
||
| addZSpider(diag, control, qubits, -phase / 2); | ||
| addZSpider(diag, target, qubits, phase / 2); | ||
| addCnot(diag, target, control, qubits); | ||
|
Check warning on line 339 in src/zx/FunctionalityConstruction.cpp
|
||
| } | ||
|
|
||
| void FunctionalityConstruction::addMcrz(ZXDiagram& diag, | ||
| const PiExpression& phase, | ||
| std::vector<Qubit> controls, | ||
| const Qubit target, | ||
| std::vector<Vertex>& qubits) { | ||
|
|
||
| switch (controls.size()) { | ||
| case 0: | ||
| addZSpider(diag, target, qubits, phase); | ||
| return; | ||
| case 1: | ||
| addCrz(diag, phase, controls.front(), target, qubits); | ||
| return; | ||
| default: | ||
| Qubit nextControl = controls.back(); | ||
| controls.pop_back(); | ||
|
|
||
| addCrz(diag, phase / 2, nextControl, target, qubits); | ||
| addMcx(diag, controls, target, qubits); | ||
| addCrz(diag, -phase / 2, nextControl, target, qubits); | ||
| addMcx(diag, controls, target, qubits); | ||
| } | ||
| } | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| void FunctionalityConstruction::addMcx(ZXDiagram& diag, | ||
| std::vector<Qubit> controls, | ||
| const Qubit target, | ||
| std::vector<Vertex>& qubits) { | ||
|
|
||
| switch (controls.size()) { | ||
| case 0: | ||
| addXSpider(diag, target, qubits, PiExpression(PiRational(1, 1))); | ||
| return; | ||
| case 1: | ||
| addCnot(diag, controls.front(), target, qubits); | ||
| return; | ||
| case 2: | ||
| addCcx(diag, controls.front(), controls.back(), target, qubits); | ||
| return; | ||
| default: | ||
| size_t half = (controls.size() + 1) / 2; | ||
| std::vector<Qubit> first(controls.begin(), controls.begin() + half); | ||
|
Check warning on line 383 in src/zx/FunctionalityConstruction.cpp
|
||
| std::vector<Qubit> second(controls.begin() + half, controls.end()); | ||
|
Check warning on line 384 in src/zx/FunctionalityConstruction.cpp
|
||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| if (qubits.size() > controls.size() + 1) { | ||
| controls.push_back(target); | ||
| Qubit anc; | ||
| for (int x : qubits) { | ||
| if (std::find(controls.begin(), controls.end(), | ||
| static_cast<Qubit>(x)) == controls.end()) { | ||
| anc = x; | ||
| break; | ||
| } | ||
| } | ||
| controls.pop_back(); | ||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| second.push_back(anc); | ||
|
|
||
| addMcx(diag, first, anc, qubits); | ||
| addMcx(diag, second, target, qubits); | ||
|
|
||
| addMcx(diag, first, anc, qubits); | ||
| addMcx(diag, second, target, qubits); | ||
| } else { | ||
| addRx(diag, PiExpression(PiRational(1, 4)), target, qubits); | ||
| addMcz(diag, second, target, qubits); | ||
| addRx(diag, PiExpression(-PiRational(1, 4)), target, qubits); | ||
| addMcx(diag, first, target, qubits); | ||
|
|
||
| addRx(diag, PiExpression(PiRational(1, 4)), target, qubits); | ||
| addMcz(diag, second, target, qubits); | ||
| addRx(diag, PiExpression(-PiRational(1, 4)), target, qubits); | ||
| addMcx(diag, first, target, qubits); | ||
| Qubit lastControl = controls.back(); | ||
| controls.pop_back(); | ||
| addMcrz(diag, PiExpression(PiRational(1, 2)), controls, lastControl, | ||
| qubits); | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+433
to
+474
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial
Static analysis flags that Proposed fix- std::vector<Qubit> second(controls.begin() + half, controls.end());
+ const std::vector<Qubit> second(controls.begin() + half, controls.end());🧰 Tools🪛 GitHub Check: 🇨 Lint / 🚨 Lint[warning] 451-451: src/zx/FunctionalityConstruction.cpp:451:5 [misc-const-correctness] 🤖 Prompt for AI Agents |
||
|
|
||
| void FunctionalityConstruction::addMcz(ZXDiagram& diag, | ||
| std::vector<Qubit> controls, | ||
| const Qubit target, | ||
| std::vector<Vertex>& qubits) { | ||
|
|
||
| switch (controls.size()) { | ||
| case 0: | ||
| addZSpider(diag, target, qubits, PiExpression(PiRational(1, 1))); | ||
| return; | ||
| case 1: | ||
| addCrz(diag, PiExpression(PiRational(1, 1)), controls.front(), target, | ||
| qubits); | ||
| return; | ||
| case 2: | ||
| addCcz(diag, controls.front(), controls.back(), target, qubits); | ||
| return; | ||
| default: | ||
| Qubit nextControl = controls.back(); | ||
| controls.pop_back(); | ||
|
|
||
| addCrz(diag, PiExpression(PiRational(1, 2)), nextControl, target, qubits); | ||
| addMcx(diag, controls, target, qubits); | ||
| addCrz(diag, PiExpression(-PiRational(1, 2)), nextControl, target, qubits); | ||
| addMcx(diag, controls, target, qubits); | ||
| } | ||
| } | ||
keefehuang marked this conversation as resolved.
Show resolved
Hide resolved
Comment on lines
+476
to
+483
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Move Same as Proposed fix void FunctionalityConstruction::addMcz(ZXDiagram& diag,
std::vector<Qubit> controls,
const Qubit target,
std::vector<Vertex>& qubits) {
addZSpider(diag, target, qubits, PiExpression(), EdgeType::Hadamard);
- addMcx(diag, controls, target, qubits);
+ addMcx(diag, std::move(controls), target, qubits);
addZSpider(diag, target, qubits, PiExpression(), EdgeType::Hadamard);
}🧰 Tools🪛 GitHub Check: 🇨 Lint / 🚨 Lint[warning] 481-481: src/zx/FunctionalityConstruction.cpp:481:16 [performance-unnecessary-value-param] 🤖 Prompt for AI Agents |
||
|
|
||
| FunctionalityConstruction::op_it | ||
| FunctionalityConstruction::parseOp(ZXDiagram& diag, op_it it, op_it end, | ||
| std::vector<Vertex>& qubits, | ||
|
|
@@ -538,6 +677,9 @@ | |
| qubits[static_cast<std::size_t>(target)], | ||
| EdgeType::Hadamard); | ||
| break; | ||
| case qc::OpType::RZ: | ||
| addCrz(diag, parseParam(op.get(), 0), ctrl, target, qubits); | ||
| break; | ||
|
|
||
| case qc::OpType::I: | ||
| break; | ||
|
|
@@ -578,16 +720,42 @@ | |
| ctrl1 = static_cast<Qubit>(p.at(ctrl.qubit)); | ||
| } | ||
| } | ||
| std::vector<Qubit> controls; | ||
| for (const auto& ctrl : op->getControls()) { | ||
| controls.push_back(p.at(ctrl.qubit)); | ||
| } | ||
| switch (op->getType()) { | ||
| case qc::OpType::X: | ||
| addCcx(diag, ctrl0, ctrl1, target, qubits); | ||
| break; | ||
|
|
||
| case qc::OpType::Z: | ||
| addCcz(diag, ctrl0, ctrl1, target, qubits); | ||
| break; | ||
| case qc::OpType::RZ: | ||
| addMcrz(diag, parseParam(op.get(), 0), controls, target, qubits); | ||
| break; | ||
| default: | ||
| throw ZXException("Unsupported Multi-control operation: " + | ||
| qc::toString(op->getType())); | ||
| } | ||
| } else if (op->getNtargets() == 1) { | ||
| const auto target = static_cast<Qubit>(p.at(op->getTargets().front())); | ||
| std::vector<Qubit> controls; | ||
| for (const auto& ctrl : op->getControls()) { | ||
| controls.push_back(p.at(ctrl.qubit)); | ||
| } | ||
burgholzer marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| switch (op->getType()) { | ||
| case qc::OpType::X: | ||
| addMcx(diag, controls, target, qubits); | ||
| break; | ||
| case qc::OpType::Z: | ||
| addZSpider(diag, target, qubits, PiExpression(), EdgeType::Hadamard); | ||
| addCcx(diag, ctrl0, ctrl1, target, qubits); | ||
| addMcx(diag, controls, target, qubits); | ||
| addZSpider(diag, target, qubits, PiExpression(), EdgeType::Hadamard); | ||
| break; | ||
| case qc::OpType::RZ: | ||
| addMcrz(diag, parseParam(op.get(), 0), controls, target, qubits); | ||
| break; | ||
| default: | ||
| throw ZXException("Unsupported Multi-control operation: " + | ||
| qc::toString(op->getType())); | ||
|
|
@@ -701,6 +869,7 @@ | |
| case qc::OpType::S: | ||
| case qc::OpType::Tdg: | ||
| case qc::OpType::Sdg: | ||
| case qc::OpType::RZ: | ||
| return true; | ||
|
|
||
| default: | ||
|
|
@@ -710,12 +879,22 @@ | |
| switch (op->getType()) { | ||
| case qc::OpType::X: | ||
| case qc::OpType::Z: | ||
| case qc::OpType::RZ: | ||
| return true; | ||
| default: | ||
| return false; | ||
| } | ||
| } else if (op->getNtargets() == 1) { | ||
| switch (op->getType()) { | ||
| case qc::OpType::X: | ||
| case qc::OpType::Z: | ||
| case qc::OpType::RZ: | ||
| return true; | ||
| default: | ||
| return false; | ||
| } | ||
| return false; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| PiExpression FunctionalityConstruction::parseParam(const qc::Operation* op, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.