├── .gitignore
├── LICENSE.txt
├── README.md
├── benchmark
├── README.md
├── benchmark1.csv
├── benchmark1.js
├── benchmark1.numbers
├── benchmark2.csv
├── benchmark2.js
├── benchmark2.numbers
├── benchmark3.csv
├── benchmark3.js
└── benchmark3.numbers
├── dist
├── quantum-circuit.js
├── quantum-circuit.min.js
└── quantum-circuit.min.js.map
├── example
├── browser
│ ├── example.html
│ ├── example_cudaq.html
│ └── transform.html
├── jupyter
│ ├── bell.ipynb
│ └── qsharp-export-test.ipynb
└── nodejs
│ ├── adder.js
│ ├── adder_qasm.js
│ ├── all_gates.js
│ ├── bell.js
│ ├── bigadder_qasm.js
│ ├── blocks.js
│ ├── classical_control.js
│ ├── export_qsharp.js
│ ├── inverseqft1_qasm.js
│ ├── new_export_cirq.js
│ ├── pea_3.js
│ ├── qft20_qasm.js
│ ├── qft_qasm.js
│ ├── teleportation.js
│ └── w_state_qasm.js
├── lib
├── qasm_import
│ ├── QASMImport.js
│ ├── QASMLexer.js
│ ├── QASMListener.js
│ └── QASMParser.js
└── quantum-circuit.js
├── media
├── benchmark1.png
├── benchmark2.png
└── benchmark3.png
├── package-lock.json
├── package.json
├── test
└── test.js
└── utils
├── README_TEMPLATE.md
├── export_gatedefs.js
└── generate_readme.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 |
78 | # next.js build output
79 | .next
80 |
81 | # nuxt.js build output
82 | .nuxt
83 |
84 | # gatsby files
85 | .cache/
86 | public
87 |
88 | # vuepress build output
89 | .vuepress/dist
90 |
91 | # Serverless directories
92 | .serverless/
93 |
94 | # FuseBox cache
95 | .fusebox/
96 |
97 | # DynamoDB Local files
98 | .dynamodb/
99 |
100 | # TernJS port file
101 | .tern-port
102 |
103 | # DS_Store
104 | .DS_Store
105 |
106 | # Visual Studio Code
107 | .vscode/
108 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Quantastica
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/benchmark/README.md:
--------------------------------------------------------------------------------
1 | To avoid node.js default 1.5 GB memory limit, run tests with `--max-old-space-size=MEMORY_MB`
2 |
3 | Example:
4 |
5 | ```
6 | node --max-old-space-size=4096 benchmark3.js
7 | ```
8 |
--------------------------------------------------------------------------------
/benchmark/benchmark1.csv:
--------------------------------------------------------------------------------
1 | Qubits Time ms Memory MB
2 | 2 90 16.59
3 | 3 1 16.97
4 | 4 0 17.10
5 | 5 1 17.23
6 | 6 0 17.36
7 | 7 0 17.49
8 | 8 0 17.62
9 | 9 0 17.75
10 | 10 0 17.90
11 | 11 1 18.05
12 | 12 1 18.18
13 | 13 1 18.31
14 | 14 1 18.44
15 | 15 2 18.57
16 | 16 13 18.76
17 | 17 3 18.89
18 | 18 6 19.03
19 | 19 12 19.16
20 | 20 20 19.30
21 | 21 45 19.43
22 | 22 80 19.57
23 | 23 174 19.70
24 | 24 336 19.84
25 | 25 641 19.98
26 |
--------------------------------------------------------------------------------
/benchmark/benchmark1.js:
--------------------------------------------------------------------------------
1 | var QuantumCircuit = require("../lib/quantum-circuit.js");
2 |
3 | console.log("Qubits\tTime ms\tMemory MB");
4 |
5 | for(var qubits = 2; qubits <= 25; qubits++) {
6 |
7 | var circ = new QuantumCircuit();
8 |
9 | circ.addGate("h", 0, 0);
10 | circ.addGate("cx", 1, [0, qubits - 1]);
11 |
12 | circ.run();
13 |
14 | var heapUsedMB = process.memoryUsage().heapUsed / 1024 / 1024;
15 |
16 | console.log(qubits + "\t" + circ.stats.duration + "\t" + heapUsedMB.toFixed(2));
17 | }
18 |
--------------------------------------------------------------------------------
/benchmark/benchmark1.numbers:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quantastica/quantum-circuit/783ae10f0499a51d0957d22cda8782e941516752/benchmark/benchmark1.numbers
--------------------------------------------------------------------------------
/benchmark/benchmark2.csv:
--------------------------------------------------------------------------------
1 | Qubits Time ms Memory MB
2 | 2 88 16.69
3 | 3 1 17.16
4 | 4 1 17.43
5 | 5 2 17.77
6 | 6 1 18.20
7 | 7 2 18.74
8 | 8 2 19.48
9 | 9 4 20.56
10 | 10 8 15.47
11 | 11 8 18.28
12 | 12 14 16.03
13 | 13 23 17.04
14 | 14 31 15.99
15 | 15 66 21.85
16 | 16 121 26.99
17 | 17 158 47.90
18 | 18 354 84.23
19 | 19 844 53.29
20 | 20 1615 94.56
21 | 21 3240 280.83
22 | 22 7018 381.97
23 | 23 15619 659.44
24 | 24 32008 1458.24
25 | 25 71844 2478.79
26 |
--------------------------------------------------------------------------------
/benchmark/benchmark2.js:
--------------------------------------------------------------------------------
1 | var QuantumCircuit = require("../lib/quantum-circuit.js");
2 |
3 | console.log("Qubits\tTime ms\tMemory MB");
4 |
5 | for(var qubits = 2; qubits <= 25; qubits++) {
6 |
7 | var circ = new QuantumCircuit(qubits);
8 |
9 | for(var i = 0; i < circ.numQubits; i++) {
10 | circ.addGate("h", 0, i);
11 | }
12 |
13 | circ.run();
14 |
15 | var heapUsedMB = process.memoryUsage().heapUsed / 1024 / 1024;
16 |
17 | console.log(qubits + "\t" + circ.stats.duration + "\t" + heapUsedMB.toFixed(2));
18 | }
19 |
--------------------------------------------------------------------------------
/benchmark/benchmark2.numbers:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quantastica/quantum-circuit/783ae10f0499a51d0957d22cda8782e941516752/benchmark/benchmark2.numbers
--------------------------------------------------------------------------------
/benchmark/benchmark3.csv:
--------------------------------------------------------------------------------
1 | Qubits Time ms Memory MB
2 | 2 91 17.01
3 | 3 2 17.41
4 | 4 2 18.04
5 | 5 4 18.97
6 | 6 5 20.34
7 | 7 10 15.39
8 | 8 10 18.38
9 | 9 15 15.66
10 | 10 20 14.93
11 | 11 28 18.67
12 | 12 46 21.01
13 | 13 67 30.17
14 | 14 121 27.70
15 | 15 176 21.22
16 | 16 369 61.88
17 | 17 811 101.99
18 | 18 1838 127.91
19 | 19 4087 193.26
20 | 20 9251 363.62
21 | 21 19779 615.40
22 | 22 45101 930.96
23 | 23 96248 1653.97
24 | 24 215496 1576.97
25 | 25 472815 3523.93
26 |
--------------------------------------------------------------------------------
/benchmark/benchmark3.js:
--------------------------------------------------------------------------------
1 | //
2 | // Quantum Fourier Transform
3 | //
4 |
5 | var QuantumCircuit = require("../lib/quantum-circuit.js");
6 |
7 | console.log("Qubits\tTime ms\tMemory MB");
8 |
9 | for(var qubits = 2; qubits <= 25; qubits++) {
10 |
11 | var circ = new QuantumCircuit(qubits);
12 |
13 | for(var i = 0; i < qubits; i++) {
14 | circ.addGate("h", -1, i);
15 | var rcount = 0;
16 | for(var x = i + 1; x < qubits; x++) {
17 | rcount++;
18 | circ.addGate("cu1", -1, [x, i], {
19 | params: {
20 | lambda: "pi/" + (1 << rcount)
21 | }
22 | });
23 | }
24 | }
25 |
26 | for(var i = 0; i < Math.floor(qubits / 2); i++) {
27 | circ.addGate("swap", -1, [i, (qubits - i) - 1]);
28 | }
29 |
30 | circ.run();
31 |
32 | var heapUsedMB = process.memoryUsage().heapUsed / 1024 / 1024;
33 |
34 | console.log(qubits + "\t" + circ.stats.duration + "\t" + heapUsedMB.toFixed(2));
35 | }
36 |
37 | /*
38 | console.log("Qubits\tTime ms\tMemory MB");
39 |
40 | for(var qubits = 2; qubits <= 25; qubits++) {
41 |
42 | var circ = new QuantumCircuit(qubits);
43 |
44 | var lastQubit = qubits - 1;
45 | for(var i = lastQubit; i >= 0; i--) {
46 | circ.addGate("h", -1, i);
47 |
48 | if(i > 0) {
49 | w = i - 1;
50 | for(var x = lastQubit; x > w; x--) {
51 | circ.addGate("cu1", -1, [w, x], {
52 | params: {
53 | lambda: "pi/" + (1 << (x - w))
54 | }
55 | });
56 | }
57 | }
58 | }
59 |
60 | for(var i = 0; i < Math.floor(qubits / 2); i++) {
61 | circ.addGate("swap", -1, [i, (qubits - i) - 1]);
62 | }
63 |
64 | circ.run(null, { partitioning: false });
65 |
66 | var heapUsedMB = process.memoryUsage().heapUsed / 1024 / 1024;
67 |
68 | console.log(qubits + "\t" + circ.stats.duration + "\t" + heapUsedMB.toFixed(2));
69 | }
70 | */
71 |
--------------------------------------------------------------------------------
/benchmark/benchmark3.numbers:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quantastica/quantum-circuit/783ae10f0499a51d0957d22cda8782e941516752/benchmark/benchmark3.numbers
--------------------------------------------------------------------------------
/example/browser/example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
13 |
14 |
Transformation matrix playground
15 |
16 |
17 |
18 |
19 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
71 |
72 |
73 |
74 |
169 |
170 |
171 |
--------------------------------------------------------------------------------
/example/jupyter/bell.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "// import quantum-circuit npm module\n",
10 | "const QuantumCircuit = require(\"quantum-circuit\");\n",
11 | "\n",
12 | "// create instance of QuantumCircuit object\n",
13 | "let circ = new QuantumCircuit();\n"
14 | ]
15 | },
16 | {
17 | "cell_type": "code",
18 | "execution_count": 6,
19 | "metadata": {},
20 | "outputs": [
21 | {
22 | "data": {
23 | "text/html": [
24 | "
"
25 | ]
26 | },
27 | "execution_count": 6,
28 | "metadata": {},
29 | "output_type": "execute_result"
30 | },
31 | {
32 | "name": "stdout",
33 | "output_type": "stream",
34 | "text": [
35 | "State:\n",
36 | " 0.70710678+0.00000000i|00>\t50.00000%\n",
37 | " 0.70710678+0.00000000i|11>\t50.00000%\n",
38 | "\n",
39 | "Probabilities:\n",
40 | "[ 0.5, 0.5 ]\n",
41 | "\n",
42 | "Measured:\n",
43 | "[ 0, 0 ]\n",
44 | "[ 0, 0 ]\n",
45 | "[ 1, 1 ]\n",
46 | "[ 0, 0 ]\n",
47 | "[ 0, 0 ]\n",
48 | "[ 0, 0 ]\n",
49 | "[ 1, 1 ]\n",
50 | "[ 0, 0 ]\n",
51 | "[ 0, 0 ]\n",
52 | "[ 0, 0 ]\n"
53 | ]
54 | }
55 | ],
56 | "source": [
57 | "// clear circuit\n",
58 | "circ.clear();\n",
59 | "\n",
60 | "// add gates to circuit\n",
61 | "circ.addGate(\"h\", -1, 0);\n",
62 | "circ.addGate(\"cx\", -1, [0, 1]);\n",
63 | "\n",
64 | "// draw circuit\n",
65 | "$$html$$ = circ.exportSVG(true);\n",
66 | "\n",
67 | "\n",
68 | "// execute circuit\n",
69 | "circ.run();\n",
70 | "\n",
71 | "// print state\n",
72 | "console.log(\"State:\");\n",
73 | "console.log(circ.stateAsString(true));\n",
74 | "\n",
75 | "// print probabilities\n",
76 | "console.log(\"Probabilities:\");\n",
77 | "console.log(circ.probabilities());\n",
78 | "\n",
79 | "// measure and print (ten times)\n",
80 | "console.log(\"\");\n",
81 | "console.log(\"Measured:\");\n",
82 | "for(var i = 0; i < 10; i++ ) {\n",
83 | " console.log(circ.measureAll(true));\n",
84 | "}\n"
85 | ]
86 | },
87 | {
88 | "cell_type": "code",
89 | "execution_count": null,
90 | "metadata": {},
91 | "outputs": [],
92 | "source": []
93 | }
94 | ],
95 | "metadata": {
96 | "kernelspec": {
97 | "display_name": "Javascript (Node.js)",
98 | "language": "javascript",
99 | "name": "javascript"
100 | },
101 | "language_info": {
102 | "file_extension": ".js",
103 | "mimetype": "application/javascript",
104 | "name": "javascript",
105 | "version": "9.7.1"
106 | }
107 | },
108 | "nbformat": 4,
109 | "nbformat_minor": 2
110 | }
111 |
--------------------------------------------------------------------------------
/example/jupyter/qsharp-export-test.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 57,
6 | "metadata": {
7 | "scrolled": true
8 | },
9 | "outputs": [
10 | {
11 | "data": {
12 | "application/json": "[\"ExportedQsharpCode\"]",
13 | "text/html": [
14 | "
"
15 | ],
16 | "text/plain": [
17 | "ExportedQsharpCode"
18 | ]
19 | },
20 | "execution_count": 57,
21 | "metadata": {},
22 | "output_type": "execute_result"
23 | }
24 | ],
25 | "source": [
26 | "operation ExportedQsharpCode() : Result {\n",
27 | " using(q_reg = Qubit[3]) {\n",
28 | " X(q_reg[0]);\n",
29 | " X(q_reg[1]);\n",
30 | " X(q_reg[2]);\n",
31 | " CCNOT(q_reg[0], q_reg[1], q_reg[2]);\n",
32 | " let r = M(q_reg[2]);\n",
33 | " ResetAll(q_reg);\n",
34 | " return r;\n",
35 | " }\n",
36 | " }"
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": 72,
42 | "metadata": {},
43 | "outputs": [
44 | {
45 | "data": {
46 | "application/json": "0",
47 | "text/plain": [
48 | "Zero"
49 | ]
50 | },
51 | "execution_count": 72,
52 | "metadata": {},
53 | "output_type": "execute_result"
54 | }
55 | ],
56 | "source": [
57 | "%simulate ExportedQsharpCode"
58 | ]
59 | },
60 | {
61 | "cell_type": "code",
62 | "execution_count": null,
63 | "metadata": {},
64 | "outputs": [],
65 | "source": []
66 | }
67 | ],
68 | "metadata": {
69 | "kernelspec": {
70 | "display_name": "Q#",
71 | "language": "qsharp",
72 | "name": "iqsharp"
73 | },
74 | "language_info": {
75 | "file_extension": ".qs",
76 | "mimetype": "text/x-qsharp",
77 | "name": "qsharp",
78 | "version": "0.4"
79 | }
80 | },
81 | "nbformat": 4,
82 | "nbformat_minor": 2
83 | }
84 |
--------------------------------------------------------------------------------
/example/nodejs/adder.js:
--------------------------------------------------------------------------------
1 | //
2 | // Adder: sums two 4-bit numbers
3 | // Input: first number in qubits 1, 2, 3, 4. Second number in qubits 5, 6, 7, 8
4 | // Output: qubits 5, 6, 7, 8, 9
5 | //
6 |
7 | var QuantumCircuit = require("../../lib/quantum-circuit.js");
8 |
9 |
10 | var majority = new QuantumCircuit();
11 | majority.addGate("cx", 0, [2, 1]);
12 | majority.addGate("cx", 1, [2, 0]);
13 | majority.addGate("ccx", 2, [0, 1, 2]);
14 |
15 | var unmaj = new QuantumCircuit();
16 | unmaj.addGate("ccx", 0, [0, 1, 2]);
17 | unmaj.addGate("cx", 1, [2, 0]);
18 | unmaj.addGate("cx", 2, [0, 1]);
19 |
20 | var adder = new QuantumCircuit();
21 | adder.registerGate("majority", majority.save());
22 | adder.registerGate("unmaj", unmaj.save());
23 |
24 | adder.addGate("majority", 0, [0, 5, 1]);
25 | adder.addGate("majority", 1, [1, 6, 2]);
26 | adder.addGate("majority", 2, [2, 7, 3]);
27 | adder.addGate("majority", 3, [3, 8, 4]);
28 | adder.addGate("cx", 4, [4, 9]);
29 | adder.addGate("unmaj", 5, [3, 8, 4]);
30 | adder.addGate("unmaj", 6, [2, 7, 3]);
31 | adder.addGate("unmaj", 7, [1, 6, 2]);
32 | adder.addGate("unmaj", 8, [0, 5, 1]);
33 |
34 | adder.addMeasure(5, "ans", 0);
35 | adder.addMeasure(6, "ans", 1);
36 | adder.addMeasure(7, "ans", 2);
37 | adder.addMeasure(8, "ans", 3);
38 | adder.addMeasure(9, "ans", 4);
39 |
40 | console.log("");
41 | console.log("Calculating...");
42 |
43 | adder.run([0, 1, 0, 0, 0, 1, 1, 1, 1, 0]);
44 |
45 |
46 | console.log("");
47 | console.log("Answer:", adder.getCregValue("ans"));
48 |
49 |
50 | console.log("");
51 | console.log("Final amplitudes:");
52 | adder.print(true);
53 |
54 | console.log("");
55 | console.log("Angles:");
56 | console.log(adder.angles());
57 |
58 | console.log("");
59 | console.log("Probabilities:");
60 | console.log(adder.probabilities());
61 |
62 | console.log("");
63 | console.log("Measured (single-shot)");
64 | console.log(adder.measureAll());
65 |
66 | console.log("");
67 | console.log("Counts (1000 shots)");
68 | console.log(adder.measureAllMultishot(1000));
69 |
70 |
--------------------------------------------------------------------------------
/example/nodejs/adder_qasm.js:
--------------------------------------------------------------------------------
1 | const QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | var input = "";
4 | input += "// quantum ripple-carry adder from Cuccaro et al, quant-ph/0410184\n";
5 | input += "OPENQASM 2.0;\n";
6 | input += "include \"qelib1.inc\";\n";
7 |
8 | input += "gate majority a,b,c\n";
9 | input += "{\n";
10 | input += " cx c,b;\n";
11 | input += " cx c,a;\n";
12 | input += " ccx a,b,c;\n";
13 | input += "}\n";
14 |
15 | input += "gate unmaj a,b,c\n";
16 | input += "{\n";
17 | input += " ccx a,b,c;\n";
18 | input += " cx c,a;\n";
19 | input += " cx a,b;\n";
20 | input += "}\n";
21 |
22 | input += "qreg cin[1];\n";
23 | input += "qreg a[4];\n";
24 | input += "qreg b[4];\n";
25 | input += "qreg cout[1];\n";
26 | input += "creg ans[5];\n";
27 |
28 | input += "// set input states\n";
29 | input += "x a[0]; // a = 0001\n";
30 | input += "x b; // b = 1111\n";
31 |
32 | input += "// add a to b, storing result in b\n";
33 | input += "majority cin[0],b[0],a[0];\n";
34 | input += "majority a[0],b[1],a[1];\n";
35 | input += "majority a[1],b[2],a[2];\n";
36 | input += "majority a[2],b[3],a[3];\n";
37 | input += "cx a[3],cout[0];\n";
38 | input += "unmaj a[2],b[3],a[3];\n";
39 | input += "unmaj a[1],b[2],a[2];\n";
40 | input += "unmaj a[0],b[1],a[1];\n";
41 | input += "unmaj cin[0],b[0],a[0];\n";
42 |
43 | input += "measure b[0] -> ans[0];\n";
44 | input += "measure b[1] -> ans[1];\n";
45 | input += "measure b[2] -> ans[2];\n";
46 | input += "measure b[3] -> ans[3];\n";
47 | input += "measure cout[0] -> ans[4];\n";
48 |
49 | var adder = new QuantumCircuit();
50 |
51 | console.log("");
52 | console.log("Importing QASM...");
53 |
54 | adder.importQASM(input);
55 |
56 | console.log("");
57 | console.log(adder.exportQASM("Sum two numbers"));
58 |
59 | console.log("");
60 | console.log(adder.exportPyquil("Sum two numbers"));
61 |
62 | //console.log("");
63 | //console.log(JSON.stringify(adder.exportRaw(), null, '\t'));
64 |
65 | console.log("");
66 | console.log("Calculating...");
67 |
68 | adder.run();
69 |
70 | console.log("");
71 | console.log("Answer:", adder.getCregValue("ans"));
72 |
73 |
74 | console.log("");
75 | console.log("Final amplitudes:");
76 | adder.print(true);
77 |
78 | console.log("");
79 | console.log("Angles:");
80 | console.log(adder.angles());
81 |
82 | console.log("");
83 | console.log("Probabilities:");
84 | console.log(adder.probabilities());
85 |
86 | console.log("");
87 | console.log("Measured (single-shot)");
88 | console.log(adder.measureAll());
89 |
90 | console.log("");
91 | console.log("Counts (1000 shots)");
92 | console.log(adder.measureAllMultishot(1000));
93 |
94 |
--------------------------------------------------------------------------------
/example/nodejs/all_gates.js:
--------------------------------------------------------------------------------
1 | var QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | const circuit = new QuantumCircuit(3);
4 |
5 | circuit.createCreg("c1", 1);
6 |
7 | circuit.appendGate("id", 0, {});
8 | circuit.appendGate("x", 0, {});
9 | circuit.appendGate("y", 0, {});
10 | circuit.appendGate("z", 0, {});
11 | circuit.appendGate("h", 0, {});
12 | circuit.appendGate("srn", 0, {});
13 | circuit.appendGate("r2", 0, {});
14 | circuit.appendGate("r4", 0, {});
15 | circuit.appendGate("r8", 0, {});
16 | circuit.appendGate("rx", 0, {"params":{"theta":"pi/3"}});
17 | circuit.appendGate("ry", 0, {"params":{"theta":"pi/3"}});
18 | circuit.appendGate("rz", 0, {"params":{"phi":"pi/3"}});
19 | circuit.appendGate("u1", 0, {"params":{"lambda":"pi/3"}});
20 | circuit.appendGate("u2", 0, {"params":{"phi":"pi/3","lambda":"pi/3"}});
21 | circuit.appendGate("u3", 0, {"params":{"theta":"pi/3","phi":"pi/3","lambda":"pi/3"}});
22 | circuit.appendGate("s", 0, {});
23 | circuit.appendGate("t", 0, {});
24 | circuit.appendGate("sdg", 0, {});
25 | circuit.appendGate("tdg", 0, {});
26 | circuit.appendGate("swap", [0,1], {});
27 | circuit.appendGate("srswap", [0,1], {});
28 | circuit.appendGate("iswap", [0,1], {});
29 | circuit.appendGate("xy", [0,1], {"params":{"phi":"pi/3"}});
30 | circuit.appendGate("cx", [0,1], {});
31 | circuit.appendGate("cy", [0,1], {});
32 | circuit.appendGate("cz", [0,1], {});
33 | circuit.appendGate("ch", [0,1], {});
34 | circuit.appendGate("csrn", [0,1], {});
35 | circuit.appendGate("ms", [0,1], {"params":{"theta":"pi/3"}});
36 | circuit.appendGate("yy", [0,1], {"params":{"theta":"pi/3"}});
37 | circuit.appendGate("cr2", [0,1], {});
38 | circuit.appendGate("cr4", [0,1], {});
39 | circuit.appendGate("cr8", [0,1], {});
40 | circuit.appendGate("crx", [0,1], {"params":{"theta":"pi/3"}});
41 | circuit.appendGate("cry", [0,1], {"params":{"theta":"pi/3"}});
42 | circuit.appendGate("crz", [0,1], {"params":{"phi":"pi/3"}});
43 | circuit.appendGate("cu1", [0,1], {"params":{"lambda":"pi/3"}});
44 | circuit.appendGate("cu2", [0,1], {"params":{"phi":"pi/3","lambda":"pi/3"}});
45 | circuit.appendGate("cu3", [0,1], {"params":{"theta":"pi/3","phi":"pi/3","lambda":"pi/3"}});
46 | circuit.appendGate("cs", [0,1], {});
47 | circuit.appendGate("ct", [0,1], {});
48 | circuit.appendGate("csdg", [0,1], {});
49 | circuit.appendGate("ctdg", [0,1], {});
50 | circuit.appendGate("ccx", [0,1,2], {});
51 | circuit.appendGate("cswap", [0,1,2], {});
52 | circuit.appendGate("csrswap", [0,1,2], {});
53 | circuit.appendGate("reset", 0, {});
54 | circuit.addMeasure(0, "c1", 0);
55 |
56 | circuit.run();
57 |
58 | console.log("Probabilities:");
59 | console.log(JSON.stringify(circuit.probabilities()));
60 |
61 | console.log("Measure all:");
62 | console.log(JSON.stringify(circuit.measureAll()));
63 |
64 | console.log("Classical registers:");
65 | console.log(circuit.cregsAsString());
66 |
--------------------------------------------------------------------------------
/example/nodejs/bell.js:
--------------------------------------------------------------------------------
1 | var QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | var circ = new QuantumCircuit();
4 |
5 | circ.addGate("h", -1, 0);
6 | circ.addGate("cx", -1, [0, 1]);
7 |
8 | circ.run();
9 |
10 | console.log("");
11 | console.log(circ.exportQASM());
12 |
13 | console.log("");
14 | console.log(circ.exportPyquil());
15 |
16 | //console.log("");
17 | //console.log(JSON.stringify(circ.exportRaw(), null, '\t'));
18 |
19 | console.log("");
20 | console.log("Final amplitudes:");
21 | circ.print(true);
22 |
23 | console.log("");
24 | console.log("Angles:");
25 | console.log(circ.angles());
26 |
27 | console.log("");
28 | console.log("Probabilities:");
29 | console.log(circ.probabilities());
30 |
31 | console.log("");
32 | console.log("Measured (single-shot)");
33 | console.log(circ.measureAll());
34 |
35 | console.log("");
36 | console.log("Counts (1000 shots)");
37 | console.log(circ.measureAllMultishot(1000));
38 |
39 |
--------------------------------------------------------------------------------
/example/nodejs/bigadder_qasm.js:
--------------------------------------------------------------------------------
1 | const QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | var input = "\n";
4 | input += "// quantum ripple-carry adder\n";
5 | input += "// 8-bit adder made out of 2 4-bit adders from adder.qasm\n";
6 | input += "// Cuccaro et al, quant-ph/0410184\n";
7 | input += "OPENQASM 2.0;\n";
8 | input += "include \"qelib1.inc\";\n";
9 |
10 | input += "gate majority a,b,c\n";
11 | input += "{\n";
12 | input += " cx c,b;\n";
13 | input += " cx c,a;\n";
14 | input += " ccx a,b,c;\n";
15 | input += "}\n";
16 | input += "gate unmaj a,b,c\n";
17 | input += "{\n";
18 | input += " ccx a,b,c;\n";
19 | input += " cx c,a;\n";
20 | input += " cx a,b;\n";
21 | input += "}\n";
22 |
23 | input += "// add a to b, storing result in b\n";
24 | input += "gate add4 a0,a1,a2,a3,b0,b1,b2,b3,cin,cout\n";
25 | input += "{\n";
26 | input += " majority cin,b0,a0;\n";
27 | input += " majority a0,b1,a1;\n";
28 | input += " majority a1,b2,a2;\n";
29 | input += " majority a2,b3,a3;\n";
30 | input += " cx a3,cout;\n";
31 | input += " unmaj a2,b3,a3;\n";
32 | input += " unmaj a1,b2,a2;\n";
33 | input += " unmaj a0,b1,a1;\n";
34 | input += " unmaj cin,b0,a0;\n";
35 | input += "}\n";
36 |
37 | input += "// add two 8-bit numbers by calling the 4-bit ripple-carry adder\n";
38 | input += "qreg carry[2];\n";
39 | input += "qreg a[8];\n";
40 | input += "qreg b[8];\n";
41 | input += "creg ans[8];\n";
42 | input += "creg carryout[1];\n";
43 | input += "// set input states\n";
44 | input += "x a[0];\n"; // a = 00000001
45 | input += "x b;\n";
46 | input += "x b[6];\n"; // b = 10111111
47 |
48 | input += "// output should be 11000000 0\n";
49 | input += "add4 a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],carry[0],carry[1];\n";
50 | input += "add4 a[4],a[5],a[6],a[7],b[4],b[5],b[6],b[7],carry[1],carry[0];\n";
51 |
52 | input += "measure b[0] -> ans[0];\n";
53 | input += "measure b[1] -> ans[1];\n";
54 | input += "measure b[2] -> ans[2];\n";
55 | input += "measure b[3] -> ans[3];\n";
56 | input += "measure b[4] -> ans[4];\n";
57 | input += "measure b[5] -> ans[5];\n";
58 | input += "measure b[6] -> ans[6];\n";
59 | input += "measure b[7] -> ans[7];\n";
60 | input += "measure carry[0] -> carryout[0];\n";
61 |
62 | var adder = new QuantumCircuit();
63 |
64 | console.log("");
65 | console.log("Importing QASM...");
66 |
67 | adder.importQASM(input);
68 |
69 | console.log("");
70 | console.log("Calculating...");
71 |
72 | adder.run(null, { partitioning: false });
73 |
74 | var answer = adder.getCregValue("ans");
75 | console.log("");
76 | console.log("Answer:", answer, " (" + answer.toString(2) + ")");
77 |
78 | console.log("");
79 | console.log("Qubits: " + adder.numQubits);
80 | console.log("Gates: " + adder.numGates(false) + " (" + adder.numGates(true) + " decomposed)");
81 | console.log("Time: " + adder.stats.duration + " ms");
82 |
83 | console.log("");
84 | console.log("Final amplitudes:");
85 | adder.print(true);
86 |
87 | console.log("");
88 | console.log("Angles:");
89 | console.log(adder.angles());
90 |
91 |
92 | console.log("");
93 | console.log("Probabilities:");
94 | console.log(adder.probabilities());
95 |
96 | console.log("");
97 | console.log("Measured (single-shot)");
98 | console.log(adder.measureAll());
99 |
100 | console.log("");
101 | console.log("Counts (1000 shots)");
102 | console.log(adder.measureAllMultishot(1000));
103 |
104 |
--------------------------------------------------------------------------------
/example/nodejs/blocks.js:
--------------------------------------------------------------------------------
1 | var QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | var circuit = new QuantumCircuit();
4 |
5 | var qasm = `
6 | OPENQASM 2.0;
7 | include "qelib1.inc";
8 | qreg q[5];
9 | h q[0];
10 | cu1 (pi / 2) q[0], q[1];
11 | cu1 (pi / 4) q[0], q[2];
12 | cu1 (pi / 8) q[0], q[3];
13 | cu1 (pi / 16) q[0], q[4];
14 | h q[1];
15 | cu1 (pi / 2) q[1], q[2];
16 | cu1 (pi / 4) q[1], q[3];
17 | cu1 (pi / 8) q[1], q[4];
18 | h q[2];
19 | cu1 (pi / 2) q[2], q[3];
20 | cu1 (pi / 4) q[2], q[4];
21 | h q[3];
22 | cu1 (pi / 2) q[3], q[4];
23 | h q[4];
24 | swap q[0], q[4];
25 | swap q[1], q[3];
26 | measure q[0]->c[0];
27 | measure q[1]->c[1];
28 | measure q[2]->c[2];
29 | measure q[3]->c[3];
30 | `;
31 |
32 | circuit.importQASM(qasm);
33 |
34 | circuit.splitIntoBlocks(2);
35 |
36 | console.log(circuit.exportQASM());
37 |
--------------------------------------------------------------------------------
/example/nodejs/classical_control.js:
--------------------------------------------------------------------------------
1 | var QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | var circ = new QuantumCircuit();
4 |
5 | circ.addGate("h", -1, 0);
6 | circ.addMeasure(0, "c", 0);
7 | circ.addGate("x", -1, 1, {
8 | condition: {
9 | creg: "c",
10 | value: 1
11 | }
12 | });
13 |
14 | circ.run();
15 |
16 | console.log("");
17 | console.log(circ.exportQASM());
18 |
19 | console.log("");
20 | console.log(circ.exportPyquil());
21 |
22 | //console.log("");
23 | //console.log(JSON.stringify(circ.exportRaw(), null, '\t'));
24 |
25 | console.log("");
26 | console.log("Final amplitudes:");
27 | circ.print(true);
28 |
29 | console.log("");
30 | console.log("Angles:");
31 | console.log(circ.angles());
32 |
33 | console.log("");
34 | console.log("Probabilities:");
35 | console.log(circ.probabilities());
36 |
37 | console.log("");
38 | console.log("Measured (single-shot)");
39 | console.log(circ.measureAll());
40 |
41 | console.log("");
42 | console.log("Counts (1000 shots)");
43 | console.log(circ.measureAllMultishot(1000));
44 |
45 |
--------------------------------------------------------------------------------
/example/nodejs/export_qsharp.js:
--------------------------------------------------------------------------------
1 | var QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | const circuit = new QuantumCircuit();
4 |
5 | circuit.createCreg("c1", 1);
6 |
7 | // circuit.appendGate("id", 0, {});
8 | // circuit.appendGate("x", 0, {});
9 | // circuit.appendGate("y", 0, {});
10 | // circuit.appendGate("z", 0, {});
11 | // circuit.appendGate("h", 0, {});
12 | // circuit.appendGate("srn", 0, {});
13 | // circuit.appendGate("r2", 0, {});
14 | // circuit.appendGate("r4", 0, {});
15 | // circuit.appendGate("r8", 0, {});
16 | // circuit.appendGate("rx", 0, {"params":{"theta":"pi/3"}});
17 | // circuit.appendGate("ry", 0, {"params":{"theta":"pi/3"}});
18 | // circuit.appendGate("rz", 0, {"params":{"phi":"pi/3"}});
19 | // circuit.appendGate("u1", 0, {"params":{"lambda":"pi/3"}});
20 | // circuit.appendGate("u2", 0, {"params":{"phi":"pi/3","lambda":"pi/3"}});
21 | // circuit.appendGate("u3", 0, {"params":{"theta":"pi/3","phi":"pi/3","lambda":"pi/3"}});
22 | // circuit.appendGate("s", 0, {});
23 | // circuit.appendGate("t", 0, {});
24 | // circuit.appendGate("sdg", 0, {});
25 | // circuit.appendGate("tdg", 0, {});
26 | // circuit.appendGate("swap", [0,1], {});
27 | // circuit.appendGate("srswap", [0,1], {});
28 | // circuit.appendGate("iswap", [0,1], {});
29 | // circuit.appendGate("xy", [0,1], {"params":{"phi":"pi/2"}});
30 | // circuit.appendGate("cx", [0,1], {});
31 | // circuit.appendGate("cy", [0,1], {});
32 | // circuit.appendGate("cz", [0,1], {});
33 | // circuit.appendGate("ch", [0,1], {});
34 | // circuit.appendGate("csrn", [0,1], {
35 | // condition: {
36 | // creg: "c1",
37 | // value: 7
38 | // }
39 | // });
40 | // circuit.appendGate("ms", [0,1], {"params":{"theta":"pi/3"}});
41 | // circuit.appendGate("yy", [0,1], {"params":{"theta":"pi/3"}});
42 | // circuit.appendGate("cr2", [0,1], {});
43 | // circuit.appendGate("cr4", [0,1], {});
44 | // circuit.appendGate("cr8", [0,1], {});
45 | // circuit.appendGate("crx", [0,1], {"params":{"theta":"pi/3"}});
46 | // circuit.appendGate("cry", [0,1], {"params":{"theta":"pi/3"}});
47 | // circuit.appendGate("crz", [0,1], {"params":{"phi":"pi/3"}});
48 | // circuit.appendGate("cu1", [0,1], {"params":{"lambda":"pi/3"}});
49 | // circuit.appendGate("cu2", [0,1], {"params":{"phi":"pi/3","la`mbda":"pi/3"}});
50 | // circuit.appendGate("cu3", [0,1], {"params":{"theta":"pi/3","phi":"pi/3","lambda":"pi/3"}});
51 | // circuit.appendGate("cs", [0,1], {});
52 | // circuit.appendGate("ct", [0,1], {});
53 | // circuit.appendGate("csdg", [0,1], {});
54 | // circuit.appendGate("ctdg", [0,1], {});
55 | // circuit.appendGate("ccx", [0,1,2], {});
56 | // circuit.appendGate("cswap", [0,1,2], {});
57 | circuit.appendGate("csrswap", [0,1,2], {});
58 | // circuit.appendGate("reset", 0, {});
59 | circuit.addMeasure(0, "c1", 0);
60 |
61 | // circuit.run();
62 |
63 | // console.log(circuit.exportQiskit());
64 |
65 | // var input = `
66 | // OPENQASM 2.0;
67 | // include "qelib1.inc";
68 | // qreg q[2];
69 | // gate sub1 a, b
70 | // {
71 | // xy a, b;
72 | // }
73 |
74 | // sub1 q[0], q[1];
75 | // `;
76 |
77 | // console.log("");
78 | // console.log("Importing QASM...");
79 |
80 | // circuit.importQASM(input);
81 |
82 | console.log("");
83 | console.log(circuit.exportCirq());
84 | // console.log(circuit.exportQASM())
--------------------------------------------------------------------------------
/example/nodejs/inverseqft1_qasm.js:
--------------------------------------------------------------------------------
1 | const QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | var input = "";
4 |
5 | input += "// QFT and measure, version 1";
6 | input += "OPENQASM 2.0;\n";
7 | input += "include \"qelib1.inc\";\n";
8 | input += "qreg q[4];\n";
9 | input += "creg c[4];\n";
10 | input += "h q;\n";
11 | input += "barrier q;\n";
12 | input += "h q[0];\n";
13 | input += "measure q[0] -> c[0];\n";
14 | input += "if(c==1) u1(pi/2) q[1];\n";
15 | input += "h q[1];\n";
16 | input += "measure q[1] -> c[1];\n";
17 | input += "if(c==1) u1(pi/4) q[2];\n";
18 | input += "if(c==2) u1(pi/2) q[2];\n";
19 | input += "if(c==3) u1(pi/2+pi/4) q[2];\n";
20 | input += "h q[2];\n";
21 | input += "measure q[2] -> c[2];\n";
22 | input += "if(c==1) u1(pi/8) q[3];\n";
23 | input += "if(c==2) u1(pi/4) q[3];\n";
24 | input += "if(c==3) u1(pi/4+pi/8) q[3];\n";
25 | input += "if(c==4) u1(pi/2) q[3];\n";
26 | input += "if(c==5) u1(pi/2+pi/8) q[3];\n";
27 | input += "if(c==6) u1(pi/2+pi/4) q[3];\n";
28 | input += "if(c==7) u1(pi/2+pi/4+pi/8) q[3];\n";
29 | input += "h q[3];\n";
30 | input += "measure q[3] -> c[3];\n";
31 |
32 | var circuit = new QuantumCircuit();
33 |
34 | console.log("");
35 | console.log("Importing QASM...");
36 |
37 | circuit.importQASM(input);
38 |
39 | console.log("");
40 | console.log(circuit.exportQASM());
41 |
42 | //console.log("");
43 | //console.log(JSON.stringify(circuit.exportRaw(), null, '\t'));
44 |
45 | console.log("");
46 | console.log("Calculating...");
47 |
48 | circuit.run();
49 |
50 | console.log("");
51 | console.log("Final amplitudes:");
52 | circuit.print(true);
53 |
54 | console.log("");
55 | console.log("Angles:");
56 | console.log(circuit.angles());
57 |
58 | console.log("");
59 | console.log("Probabilities:");
60 | console.log(circuit.probabilities());
61 |
62 | console.log("");
63 | console.log("Measured (single-shot)");
64 | console.log(circuit.measureAll());
65 |
66 | console.log("");
67 | console.log("Counts (1000 shots)");
68 | console.log(circuit.measureAllMultishot(1000));
69 |
70 |
--------------------------------------------------------------------------------
/example/nodejs/new_export_cirq.js:
--------------------------------------------------------------------------------
1 | var QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | var circuit = new QuantumCircuit();
4 |
5 | circuit.addGate("id", -1, 0);
6 | circuit.addGate("x", -1, 0);
7 | circuit.addGate("y", -1, 0);
8 | circuit.addGate("z", -1, 0);
9 | circuit.addGate("h", -1, 0);
10 | circuit.addGate("srn", -1, 0);
11 | circuit.addGate("r2", -1, 0);
12 | circuit.addGate("r4", -1, 0);
13 | circuit.addGate("r8", -1, 0);
14 | circuit.addGate("rx", -1, 0, {
15 | params: {
16 | theta: "pi/2"
17 | }
18 | });
19 | circuit.addGate("ry", -1, 0, {
20 | params: {
21 | theta: "pi/2"
22 | }
23 | });
24 | circuit.addGate("rz", -1, 0, {
25 | params: {
26 | phi: "pi/2"
27 | }
28 | });
29 | circuit.addGate("u1", -1, 0, {
30 | params: {
31 | lambda: "pi/2"
32 | }
33 | });
34 | circuit.addGate("u2", -1, 0, {
35 | params: {
36 | phi: "pi/2",
37 | lambda: "pi/2"
38 | }
39 | });
40 | circuit.addGate("u3", -1, 0, {
41 | params: {
42 | theta: "pi/2",
43 | phi: "pi/2",
44 | lambda: "pi/2"
45 | }
46 | });
47 | circuit.addGate("s", -1, 0);
48 | circuit.addGate("t", -1, 0);
49 | circuit.addGate("sdg", -1, 0);
50 | circuit.addGate("tdg", -1, 0);
51 | circuit.addGate("swap", -1, [0, 1]);
52 | circuit.addGate("srswap", -1, [0, 1]);
53 | circuit.addGate("cx", -1, [0, 1]);
54 | circuit.addGate("cz", -1, [0, 1]);
55 | circuit.addGate("ms", -1, [0, 1], {
56 | params: {
57 | theta: "pi/2"
58 | }
59 | });
60 | circuit.addGate("cr2", -1, [0, 1]);
61 | circuit.addGate("cr4", -1, [0, 1]);
62 | circuit.addGate("cr8", -1, [0, 1]);
63 | circuit.addGate("crz", -1, [0, 1], {
64 | params: {
65 | phi: "pi/2"
66 | }
67 | });
68 | circuit.addGate("cu1", -1, [0, 1], {
69 | params: {
70 | lambda: "pi/2"
71 | }
72 | });
73 | circuit.addGate("cu2", -1, [0, 1], {
74 | params: {
75 | phi: "pi/2",
76 | lambda: "pi/2"
77 | }
78 | });
79 | circuit.addGate("cu3", -1, [0, 1], {
80 | params: {
81 | theta: "pi/2",
82 | phi: "pi/2",
83 | lambda: "pi/2"
84 | }
85 | });
86 | circuit.addGate("cs", -1, [0, 1]);
87 | circuit.addGate("ct", -1, [0, 1]);
88 | circuit.addGate("csdg", -1, [0, 1]);
89 | circuit.addGate("ctdg", -1, [0, 1]);
90 | circuit.addGate("ccx", -1, [0, 1, 2]);
91 | circuit.addGate("cswap", -1, [0, 1, 2]);
92 | circuit.addMeasure(0, "c", 3);
93 |
94 | circuit.run();
95 |
96 | console.log("");
97 | console.log(circuit.exportCirq());
--------------------------------------------------------------------------------
/example/nodejs/pea_3.js:
--------------------------------------------------------------------------------
1 | const QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | var input = "";
4 | input += "// Name of Experiment: pea_3*pi/8 v3\n";
5 |
6 | input += "OPENQASM 2.0;\n";
7 | input += "include \"qelib1.inc\";\n";
8 |
9 |
10 | input += "qreg q[5];\n";
11 | input += "creg c[4];\n";
12 | input += "gate cu1fixed (a) c,t {\n";
13 | input += " u1 (-1*a) t;\n";
14 | input += " cx c,t;\n";
15 | input += " u1 (a) t;\n";
16 | input += " cx c,t;\n";
17 | input += "}\n";
18 |
19 | input += "gate cu c,t {\n";
20 | input += " cu1fixed (3*pi/8) c,t;\n";
21 | input += "}\n";
22 |
23 | input += "h q[0];\n";
24 | input += "h q[1];\n";
25 | input += "h q[2];\n";
26 | input += "h q[3];\n";
27 | input += "cu q[3],q[4];\n";
28 | input += "cu q[2],q[4];\n";
29 | input += "cu q[2],q[4];\n";
30 | input += "cu q[1],q[4];\n";
31 | input += "cu q[1],q[4];\n";
32 | input += "cu q[1],q[4];\n";
33 | input += "cu q[1],q[4];\n";
34 | input += "cu q[0],q[4];\n";
35 | input += "cu q[0],q[4];\n";
36 | input += "cu q[0],q[4];\n";
37 | input += "cu q[0],q[4];\n";
38 | input += "cu q[0],q[4];\n";
39 | input += "cu q[0],q[4];\n";
40 | input += "cu q[0],q[4];\n";
41 | input += "cu q[0],q[4];\n";
42 | input += "h q[0];\n";
43 | input += "cu1(-1*pi/2) q[0],q[1];\n";
44 | input += "h q[1];\n";
45 | input += "cu1(-1*pi/4) q[0],q[2];\n";
46 | input += "cu1(-1*pi/2) q[1],q[2];\n";
47 | input += "h q[2];\n";
48 | input += "cu1(-1*pi/8) q[0],q[3];\n";
49 | input += "cu1(-1*pi/4) q[1],q[3];\n";
50 | input += "cu1(-1*pi/2) q[2],q[3];\n";
51 | input += "h q[3];\n";
52 | input += "measure q[0] -> c[0];\n";
53 | input += "measure q[1] -> c[1];\n";
54 | input += "measure q[2] -> c[2];\n";
55 | input += "measure q[3] -> c[3];\n";
56 |
57 | var circuit = new QuantumCircuit();
58 |
59 | console.log("");
60 | console.log("Importing QASM...");
61 |
62 | circuit.importQASM(input);
63 |
64 | console.log("");
65 | console.log("Calculating...");
66 |
67 | circuit.run();
68 |
69 | console.log("");
70 | console.log("Final amplitudes:");
71 | circuit.print(true);
72 |
73 | console.log("");
74 | console.log("Angles:");
75 | console.log(circuit.angles());
76 |
77 | console.log("");
78 | console.log("Probabilities:");
79 | console.log(circuit.probabilities());
80 |
81 | console.log("");
82 | console.log("Measured (single-shot)");
83 | console.log(circuit.measureAll());
84 |
85 | console.log("");
86 | console.log("Counts (1000 shots)");
87 | console.log(circuit.measureAllMultishot(1000));
88 |
89 |
--------------------------------------------------------------------------------
/example/nodejs/qft20_qasm.js:
--------------------------------------------------------------------------------
1 | const QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | var input = "";
4 |
5 | input += "OPENQASM 2.0;";
6 | input += "include \"qelib1.inc\";";
7 | input += "qreg q[20];";
8 | input += "h q[0];";
9 | input += "cu1 (pi/2) q[1], q[0];";
10 | input += "cu1 (pi/4) q[2], q[0];";
11 | input += "cu1 (pi/8) q[3], q[0];";
12 | input += "cu1 (pi/16) q[4], q[0];";
13 | input += "cu1 (pi/32) q[5], q[0];";
14 | input += "cu1 (pi/64) q[6], q[0];";
15 | input += "cu1 (pi/128) q[7], q[0];";
16 | input += "cu1 (pi/256) q[8], q[0];";
17 | input += "cu1 (pi/512) q[9], q[0];";
18 | input += "cu1 (pi/1024) q[10], q[0];";
19 | input += "cu1 (pi/2048) q[11], q[0];";
20 | input += "cu1 (pi/4096) q[12], q[0];";
21 | input += "cu1 (pi/8192) q[13], q[0];";
22 | input += "cu1 (pi/16384) q[14], q[0];";
23 | input += "cu1 (pi/32768) q[15], q[0];";
24 | input += "cu1 (pi/65536) q[16], q[0];";
25 | input += "cu1 (pi/131072) q[17], q[0];";
26 | input += "cu1 (pi/262144) q[18], q[0];";
27 | input += "cu1 (pi/524288) q[19], q[0];";
28 | input += "h q[1];";
29 | input += "cu1 (pi/2) q[2], q[1];";
30 | input += "cu1 (pi/4) q[3], q[1];";
31 | input += "cu1 (pi/8) q[4], q[1];";
32 | input += "cu1 (pi/16) q[5], q[1];";
33 | input += "cu1 (pi/32) q[6], q[1];";
34 | input += "cu1 (pi/64) q[7], q[1];";
35 | input += "cu1 (pi/128) q[8], q[1];";
36 | input += "cu1 (pi/256) q[9], q[1];";
37 | input += "cu1 (pi/512) q[10], q[1];";
38 | input += "cu1 (pi/1024) q[11], q[1];";
39 | input += "cu1 (pi/2048) q[12], q[1];";
40 | input += "cu1 (pi/4096) q[13], q[1];";
41 | input += "cu1 (pi/8192) q[14], q[1];";
42 | input += "cu1 (pi/16384) q[15], q[1];";
43 | input += "cu1 (pi/32768) q[16], q[1];";
44 | input += "cu1 (pi/65536) q[17], q[1];";
45 | input += "cu1 (pi/131072) q[18], q[1];";
46 | input += "cu1 (pi/262144) q[19], q[1];";
47 | input += "h q[2];";
48 | input += "cu1 (pi/2) q[3], q[2];";
49 | input += "cu1 (pi/4) q[4], q[2];";
50 | input += "cu1 (pi/8) q[5], q[2];";
51 | input += "cu1 (pi/16) q[6], q[2];";
52 | input += "cu1 (pi/32) q[7], q[2];";
53 | input += "cu1 (pi/64) q[8], q[2];";
54 | input += "cu1 (pi/128) q[9], q[2];";
55 | input += "cu1 (pi/256) q[10], q[2];";
56 | input += "cu1 (pi/512) q[11], q[2];";
57 | input += "cu1 (pi/1024) q[12], q[2];";
58 | input += "cu1 (pi/2048) q[13], q[2];";
59 | input += "cu1 (pi/4096) q[14], q[2];";
60 | input += "cu1 (pi/8192) q[15], q[2];";
61 | input += "cu1 (pi/16384) q[16], q[2];";
62 | input += "cu1 (pi/32768) q[17], q[2];";
63 | input += "cu1 (pi/65536) q[18], q[2];";
64 | input += "cu1 (pi/131072) q[19], q[2];";
65 | input += "h q[3];";
66 | input += "cu1 (pi/2) q[4], q[3];";
67 | input += "cu1 (pi/4) q[5], q[3];";
68 | input += "cu1 (pi/8) q[6], q[3];";
69 | input += "cu1 (pi/16) q[7], q[3];";
70 | input += "cu1 (pi/32) q[8], q[3];";
71 | input += "cu1 (pi/64) q[9], q[3];";
72 | input += "cu1 (pi/128) q[10], q[3];";
73 | input += "cu1 (pi/256) q[11], q[3];";
74 | input += "cu1 (pi/512) q[12], q[3];";
75 | input += "cu1 (pi/1024) q[13], q[3];";
76 | input += "cu1 (pi/2048) q[14], q[3];";
77 | input += "cu1 (pi/4096) q[15], q[3];";
78 | input += "cu1 (pi/8192) q[16], q[3];";
79 | input += "cu1 (pi/16384) q[17], q[3];";
80 | input += "cu1 (pi/32768) q[18], q[3];";
81 | input += "cu1 (pi/65536) q[19], q[3];";
82 | input += "h q[4];";
83 | input += "cu1 (pi/2) q[5], q[4];";
84 | input += "cu1 (pi/4) q[6], q[4];";
85 | input += "cu1 (pi/8) q[7], q[4];";
86 | input += "cu1 (pi/16) q[8], q[4];";
87 | input += "cu1 (pi/32) q[9], q[4];";
88 | input += "cu1 (pi/64) q[10], q[4];";
89 | input += "cu1 (pi/128) q[11], q[4];";
90 | input += "cu1 (pi/256) q[12], q[4];";
91 | input += "cu1 (pi/512) q[13], q[4];";
92 | input += "cu1 (pi/1024) q[14], q[4];";
93 | input += "cu1 (pi/2048) q[15], q[4];";
94 | input += "cu1 (pi/4096) q[16], q[4];";
95 | input += "cu1 (pi/8192) q[17], q[4];";
96 | input += "cu1 (pi/16384) q[18], q[4];";
97 | input += "cu1 (pi/32768) q[19], q[4];";
98 | input += "h q[5];";
99 | input += "cu1 (pi/2) q[6], q[5];";
100 | input += "cu1 (pi/4) q[7], q[5];";
101 | input += "cu1 (pi/8) q[8], q[5];";
102 | input += "cu1 (pi/16) q[9], q[5];";
103 | input += "cu1 (pi/32) q[10], q[5];";
104 | input += "cu1 (pi/64) q[11], q[5];";
105 | input += "cu1 (pi/128) q[12], q[5];";
106 | input += "cu1 (pi/256) q[13], q[5];";
107 | input += "cu1 (pi/512) q[14], q[5];";
108 | input += "cu1 (pi/1024) q[15], q[5];";
109 | input += "cu1 (pi/2048) q[16], q[5];";
110 | input += "cu1 (pi/4096) q[17], q[5];";
111 | input += "cu1 (pi/8192) q[18], q[5];";
112 | input += "cu1 (pi/16384) q[19], q[5];";
113 | input += "h q[6];";
114 | input += "cu1 (pi/2) q[7], q[6];";
115 | input += "cu1 (pi/4) q[8], q[6];";
116 | input += "cu1 (pi/8) q[9], q[6];";
117 | input += "cu1 (pi/16) q[10], q[6];";
118 | input += "cu1 (pi/32) q[11], q[6];";
119 | input += "cu1 (pi/64) q[12], q[6];";
120 | input += "cu1 (pi/128) q[13], q[6];";
121 | input += "cu1 (pi/256) q[14], q[6];";
122 | input += "cu1 (pi/512) q[15], q[6];";
123 | input += "cu1 (pi/1024) q[16], q[6];";
124 | input += "cu1 (pi/2048) q[17], q[6];";
125 | input += "cu1 (pi/4096) q[18], q[6];";
126 | input += "cu1 (pi/8192) q[19], q[6];";
127 | input += "h q[7];";
128 | input += "cu1 (pi/2) q[8], q[7];";
129 | input += "cu1 (pi/4) q[9], q[7];";
130 | input += "cu1 (pi/8) q[10], q[7];";
131 | input += "cu1 (pi/16) q[11], q[7];";
132 | input += "cu1 (pi/32) q[12], q[7];";
133 | input += "cu1 (pi/64) q[13], q[7];";
134 | input += "cu1 (pi/128) q[14], q[7];";
135 | input += "cu1 (pi/256) q[15], q[7];";
136 | input += "cu1 (pi/512) q[16], q[7];";
137 | input += "cu1 (pi/1024) q[17], q[7];";
138 | input += "cu1 (pi/2048) q[18], q[7];";
139 | input += "cu1 (pi/4096) q[19], q[7];";
140 | input += "h q[8];";
141 | input += "cu1 (pi/2) q[9], q[8];";
142 | input += "cu1 (pi/4) q[10], q[8];";
143 | input += "cu1 (pi/8) q[11], q[8];";
144 | input += "cu1 (pi/16) q[12], q[8];";
145 | input += "cu1 (pi/32) q[13], q[8];";
146 | input += "cu1 (pi/64) q[14], q[8];";
147 | input += "cu1 (pi/128) q[15], q[8];";
148 | input += "cu1 (pi/256) q[16], q[8];";
149 | input += "cu1 (pi/512) q[17], q[8];";
150 | input += "cu1 (pi/1024) q[18], q[8];";
151 | input += "cu1 (pi/2048) q[19], q[8];";
152 | input += "h q[9];";
153 | input += "cu1 (pi/2) q[10], q[9];";
154 | input += "cu1 (pi/4) q[11], q[9];";
155 | input += "cu1 (pi/8) q[12], q[9];";
156 | input += "cu1 (pi/16) q[13], q[9];";
157 | input += "cu1 (pi/32) q[14], q[9];";
158 | input += "cu1 (pi/64) q[15], q[9];";
159 | input += "cu1 (pi/128) q[16], q[9];";
160 | input += "cu1 (pi/256) q[17], q[9];";
161 | input += "cu1 (pi/512) q[18], q[9];";
162 | input += "cu1 (pi/1024) q[19], q[9];";
163 | input += "h q[10];";
164 | input += "cu1 (pi/2) q[11], q[10];";
165 | input += "cu1 (pi/4) q[12], q[10];";
166 | input += "cu1 (pi/8) q[13], q[10];";
167 | input += "cu1 (pi/16) q[14], q[10];";
168 | input += "cu1 (pi/32) q[15], q[10];";
169 | input += "cu1 (pi/64) q[16], q[10];";
170 | input += "cu1 (pi/128) q[17], q[10];";
171 | input += "cu1 (pi/256) q[18], q[10];";
172 | input += "cu1 (pi/512) q[19], q[10];";
173 | input += "h q[11];";
174 | input += "cu1 (pi/2) q[12], q[11];";
175 | input += "cu1 (pi/4) q[13], q[11];";
176 | input += "cu1 (pi/8) q[14], q[11];";
177 | input += "cu1 (pi/16) q[15], q[11];";
178 | input += "cu1 (pi/32) q[16], q[11];";
179 | input += "cu1 (pi/64) q[17], q[11];";
180 | input += "cu1 (pi/128) q[18], q[11];";
181 | input += "cu1 (pi/256) q[19], q[11];";
182 | input += "h q[12];";
183 | input += "cu1 (pi/2) q[13], q[12];";
184 | input += "cu1 (pi/4) q[14], q[12];";
185 | input += "cu1 (pi/8) q[15], q[12];";
186 | input += "cu1 (pi/16) q[16], q[12];";
187 | input += "cu1 (pi/32) q[17], q[12];";
188 | input += "cu1 (pi/64) q[18], q[12];";
189 | input += "cu1 (pi/128) q[19], q[12];";
190 | input += "h q[13];";
191 | input += "cu1 (pi/2) q[14], q[13];";
192 | input += "cu1 (pi/4) q[15], q[13];";
193 | input += "cu1 (pi/8) q[16], q[13];";
194 | input += "cu1 (pi/16) q[17], q[13];";
195 | input += "cu1 (pi/32) q[18], q[13];";
196 | input += "cu1 (pi/64) q[19], q[13];";
197 | input += "h q[14];";
198 | input += "cu1 (pi/2) q[15], q[14];";
199 | input += "cu1 (pi/4) q[16], q[14];";
200 | input += "cu1 (pi/8) q[17], q[14];";
201 | input += "cu1 (pi/16) q[18], q[14];";
202 | input += "cu1 (pi/32) q[19], q[14];";
203 | input += "h q[15];";
204 | input += "cu1 (pi/2) q[16], q[15];";
205 | input += "cu1 (pi/4) q[17], q[15];";
206 | input += "cu1 (pi/8) q[18], q[15];";
207 | input += "cu1 (pi/16) q[19], q[15];";
208 | input += "h q[16];";
209 | input += "cu1 (pi/2) q[17], q[16];";
210 | input += "cu1 (pi/4) q[18], q[16];";
211 | input += "cu1 (pi/8) q[19], q[16];";
212 | input += "h q[17];";
213 | input += "cu1 (pi/2) q[18], q[17];";
214 | input += "cu1 (pi/4) q[19], q[17];";
215 | input += "h q[18];";
216 | input += "cu1 (pi/2) q[19], q[18];";
217 | input += "h q[19];";
218 | input += "swap q[0], q[19];";
219 | input += "swap q[1], q[18];";
220 | input += "swap q[2], q[17];";
221 | input += "swap q[3], q[16];";
222 | input += "swap q[4], q[15];";
223 | input += "swap q[5], q[14];";
224 | input += "swap q[6], q[13];";
225 | input += "swap q[7], q[12];";
226 | input += "swap q[8], q[11];";
227 | input += "swap q[9], q[10];";
228 |
229 | var qft = new QuantumCircuit();
230 |
231 | console.log("");
232 | console.log("Importing QASM...");
233 |
234 | qft.importQASM(input);
235 |
236 | console.log("");
237 | console.log("Calculating...");
238 |
239 | qft.run();
240 |
241 | console.log("");
242 | console.log("Time: " + qft.stats.duration + " ms");
243 |
244 | //console.log("");
245 | //console.log("Final amplitudes:");
246 | //qft.print(true);
247 |
248 | //console.log("");
249 | //console.log("Angles:");
250 | //console.log(qft.angles());
251 |
252 | console.log("");
253 | console.log("Probabilities:");
254 | console.log(qft.probabilities());
255 |
256 | console.log("");
257 | console.log("Measured (single-shot)");
258 | console.log(qft.measureAll());
259 |
260 | console.log("");
261 | console.log("Counts (1000 shots)");
262 | console.log(qft.measureAllMultishot(1000));
263 |
264 |
--------------------------------------------------------------------------------
/example/nodejs/qft_qasm.js:
--------------------------------------------------------------------------------
1 | const QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | var input = "";
4 |
5 | input += "// quantum Fourier transform\n";
6 | input += "OPENQASM 2.0;\n";
7 | input += "include \"qelib1.inc\";\n";
8 | input += "qreg q[4];\n";
9 | input += "creg c[4];\n";
10 | input += "x q[0]; \n";
11 | input += "x q[2];\n";
12 | input += "barrier q;\n";
13 | input += "h q[0];\n";
14 | input += "cu1(pi/2) q[1],q[0];\n";
15 | input += "h q[1];\n";
16 | input += "cu1(pi/4) q[2],q[0];\n";
17 | input += "cu1(pi/2) q[2],q[1];\n";
18 | input += "h q[2];\n";
19 | input += "cu1(pi/8) q[3],q[0];\n";
20 | input += "cu1(pi/4) q[3],q[1];\n";
21 | input += "cu1(pi/2) q[3],q[2];\n";
22 | input += "h q[3];\n";
23 | input += "measure q -> c;\n";
24 |
25 |
26 |
27 | var qft = new QuantumCircuit();
28 |
29 | console.log("");
30 | console.log("Importing QASM...");
31 |
32 | qft.importQASM(input);
33 |
34 | console.log("");
35 | console.log(qft.exportQASM("4-bit QFT"));
36 |
37 | console.log("");
38 | console.log(qft.exportPyquil("4-bit QFT"));
39 |
40 | console.log("");
41 | console.log("Calculating...");
42 |
43 | qft.run();
44 |
45 | console.log("");
46 | console.log("Time: " + qft.stats.duration + " ms");
47 |
48 | console.log("");
49 | console.log("Final amplitudes:");
50 | qft.print(true);
51 |
52 | console.log("");
53 | console.log("Angles:");
54 | console.log(qft.angles());
55 |
56 | console.log("");
57 | console.log("Probabilities:");
58 | console.log(qft.probabilities());
59 |
60 | console.log("");
61 | console.log("Measured (single-shot)");
62 | console.log(qft.measureAll());
63 |
64 | console.log("");
65 | console.log("Counts (1000 shots)");
66 | console.log(qft.measureAllMultishot(1000));
67 |
68 |
--------------------------------------------------------------------------------
/example/nodejs/teleportation.js:
--------------------------------------------------------------------------------
1 | const QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | var input = `
4 | OPENQASM 2.0;
5 | include "qelib1.inc";
6 | qreg q[3];
7 | creg c0[1];
8 | creg c1[1];
9 | rx (pi/4) q[0]; // this message will be teleported from qubit 0 to qubit 2
10 | h q[1];
11 | cx q[1], q[2];
12 | cx q[0], q[1];
13 | h q[0];
14 | measure q[1] -> c1[0];
15 | if(c1==1) x q[2];
16 | measure q[0] -> c0[0];
17 | if(c0==1) z q[2];
18 | `;
19 |
20 | var circuit = new QuantumCircuit();
21 |
22 | console.log("");
23 | console.log("Importing QASM...");
24 |
25 | circuit.importQASM(input);
26 |
27 | console.log("");
28 | console.log(circuit.exportQASM("Teleportation"));
29 |
30 | console.log("");
31 | console.log(circuit.exportPyquil("Teleportation"));
32 |
33 | console.log("");
34 | console.log("Teleporting...");
35 |
36 | circuit.run();
37 |
38 | console.log("");
39 | console.log("Time: " + circuit.stats.duration + " ms");
40 |
41 | console.log("");
42 | console.log("Final amplitudes:");
43 | circuit.print(true);
44 |
45 | console.log("");
46 | console.log("Angles:");
47 | console.log(circuit.angles());
48 |
49 | console.log("");
50 | console.log("Probabilities:");
51 | console.log(circuit.probabilities());
52 |
53 | console.log("");
54 | console.log("Measured (single-shot)");
55 | console.log(circuit.measureAll());
56 |
57 | console.log("");
58 | console.log("Counts (1000 shots)");
59 | console.log(circuit.measureAllMultishot(1000));
60 |
61 |
--------------------------------------------------------------------------------
/example/nodejs/w_state_qasm.js:
--------------------------------------------------------------------------------
1 | const QuantumCircuit = require("../../lib/quantum-circuit.js");
2 |
3 | var input = "";
4 | input += "// Name of Experiment: W-state v1\n";
5 |
6 | input += "OPENQASM 2.0;\n";
7 | input += "include \"qelib1.inc\";\n";
8 |
9 | input += "qreg q[3];\n";
10 | input += "creg c[3];\n";
11 |
12 | input += "gate cH a,b {\n";
13 | input += " h b;\n";
14 | input += " sdg b;\n";
15 | input += " cx a,b;\n";
16 | input += " h b;\n";
17 | input += " t b;\n";
18 | input += " cx a,b;\n";
19 | input += " t b;\n";
20 | input += " h b;\n";
21 | input += " s b;\n";
22 | input += " x b;\n";
23 | input += " s a;\n";
24 | input += "}\n";
25 |
26 | input += "u3(1.91063,0,0) q[0];\n";
27 | input += "cH q[0],q[1];\n";
28 | input += "ccx q[0],q[1],q[2];\n";
29 | input += "x q[0];\n";
30 | input += "x q[1];\n";
31 | input += "cx q[0],q[1];\n";
32 | input += "measure q[0] -> c[0];\n";
33 | input += "measure q[1] -> c[1];\n";
34 | input += "measure q[2] -> c[2];\n";
35 |
36 | var circuit = new QuantumCircuit();
37 |
38 | console.log("");
39 | console.log("Importing QASM...");
40 |
41 | circuit.importQASM(input);
42 |
43 | console.log("");
44 | console.log("Calculating...");
45 |
46 | circuit.run();
47 |
48 | console.log("");
49 | console.log("Final amplitudes:");
50 | circuit.print(true);
51 |
52 | console.log("");
53 | console.log("Angles:");
54 | console.log(circuit.angles());
55 |
56 | console.log("");
57 | console.log("Probabilities:");
58 | console.log(circuit.probabilities());
59 |
60 | console.log("");
61 | console.log("Measured (single-shot)");
62 | console.log(circuit.measureAll());
63 |
64 | console.log("");
65 | console.log("Counts (1000 shots)");
66 | console.log(circuit.measureAllMultishot(1000));
67 |
68 |
--------------------------------------------------------------------------------
/lib/qasm_import/QASMImport.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | *
4 | * Copyright (c) 2016, Petar Korponaić
5 | *
6 | * This source code is licensed under the MIT License, found in
7 | * the LICENSE.txt file in the root directory of this source tree.
8 | */
9 |
10 | var antlr4 = require('antlr4/index');
11 | var QASMLexer = require('./QASMLexer');
12 | var QASMParser = require('./QASMParser');
13 | var QASMListener = require('./QASMListener').QASMListener;
14 |
15 | var ErrorListener = function(errors) {
16 | antlr4.error.ErrorListener.call(this);
17 | this.errors = errors;
18 | return this;
19 | };
20 |
21 | ErrorListener.prototype = Object.create(antlr4.error.ErrorListener.prototype);
22 | ErrorListener.prototype.constructor = ErrorListener;
23 | ErrorListener.prototype.syntaxError = function(rec, sym, line, col, msg, e) {
24 | this.errors.push({
25 | line: line,
26 | col: col,
27 | msg: msg
28 | });
29 | };
30 |
31 | var QCQASMListener = function(circuit, compatibilityMode) {
32 | this.circuit = circuit;
33 | this.qregMap = {};
34 | this.condition = {};
35 | this.compatibilityMode = compatibilityMode;
36 |
37 | QASMListener.call(this); // inherit default listener
38 | return this;
39 | };
40 |
41 | var QASMImport = function(circuit, input, errorCallback, compatibilityMode) {
42 | var chars = new antlr4.InputStream(input);
43 | var lexer = new QASMLexer.QASMLexer(chars);
44 | var tokens = new antlr4.CommonTokenStream(lexer);
45 | var parser = new QASMParser.QASMParser(tokens);
46 | parser.buildParseTrees = true;
47 |
48 | parser.removeErrorListeners();
49 | var errors = [];
50 | var errorListener = new ErrorListener(errors);
51 | parser.addErrorListener(errorListener);
52 |
53 | var tree = parser.mainprog();
54 | var QASM = new QCQASMListener(circuit, compatibilityMode);
55 | antlr4.tree.ParseTreeWalker.DEFAULT.walk(QASM, tree);
56 | if(errorCallback) {
57 | errorCallback(errors);
58 | }
59 | };
60 |
61 |
62 | // inherit default listener
63 | QCQASMListener.prototype = Object.create(QASMListener.prototype);
64 | QCQASMListener.prototype.constructor = QCQASMListener;
65 |
66 |
67 | QCQASMListener.prototype.numQbit = function() {
68 | var num = 0;
69 | for(var reg in this.qregMap) {
70 | num += this.qregMap[reg];
71 | }
72 | return num;
73 | };
74 |
75 | QCQASMListener.prototype.qregBase = function(qreg) {
76 | var base = 0;
77 | for(var reg in this.qregMap) {
78 | if(reg == qreg) {
79 | return base;
80 | }
81 | base += this.qregMap[reg];
82 | }
83 | return base;
84 | };
85 |
86 | QCQASMListener.prototype.qregLen = function(reg) {
87 | return this.qregMap[reg] || 0;
88 | };
89 |
90 |
91 | // Enter a parse tree produced by QASMParser#mainprog.
92 | QCQASMListener.prototype.enterMainprog = function(ctx) {
93 | };
94 |
95 | // Exit a parse tree produced by QASMParser#mainprog.
96 | QCQASMListener.prototype.exitMainprog = function(ctx) {
97 | };
98 |
99 |
100 | // Enter a parse tree produced by QASMParser#statement.
101 | QCQASMListener.prototype.enterStatement = function(ctx) {
102 | var self = this;
103 |
104 | // condition
105 | var name = ctx.getChildCount() ? ctx.getChild(0).getText() : "";
106 | if(name == "if") {
107 | this.condition = {
108 | creg: ctx.ID().getText(),
109 | value: parseInt(ctx.INT().getText())
110 | }
111 | }
112 |
113 | // subroutine (gate declaration)
114 | if(ctx.gatedecl()) {
115 | var gatedecl = ctx.gatedecl();
116 | var args = [];
117 | var params = [];
118 |
119 | var ccount = gatedecl.getChildCount();
120 | if(ccount > 2 && gatedecl.getChild(2).ID) {
121 | // no params
122 | args = gatedecl.getChild(2).ID();
123 | } else {
124 | if(ccount > 3 && gatedecl.getChild(3).ID) {
125 | params = gatedecl.getChild(3).ID();
126 | }
127 | if(ccount > 5 && gatedecl.getChild(5).ID) {
128 | // no params
129 | args = gatedecl.getChild(5).ID();
130 | }
131 | }
132 |
133 | var proto = Object.getPrototypeOf(this.circuit);
134 | var customGate = new proto.constructor(args.length);
135 | var customGateName = gatedecl.ID().getText();
136 | var customGateRegs = [];
137 |
138 | args.map(function(reg) {
139 | customGateRegs.push(reg.getText());
140 | });
141 |
142 | params.map(function(par) {
143 | var parName = par.getText();
144 | customGate.params.push(parName);
145 | });
146 |
147 | if(ctx.goplist()) {
148 | var goplist = ctx.goplist();
149 | goplist.uop().map(function(uop) {
150 | var gateName = uop.ID() ? uop.ID().getText() : "";
151 | if(gateName) {
152 | var idlist = uop.anylist() ? uop.anylist().idlist() : null;
153 | var mixedlist = uop.anylist() ? uop.anylist().mixedlist() : null;
154 | var explist = uop.explist();
155 |
156 |
157 | switch(gateName) {
158 | case "CX": gateName = "cx"; break;
159 | case "U": gateName = "u3"; break;
160 | }
161 |
162 | if(!self.circuit.basicGates[gateName] && !self.circuit.customGates[gateName]) {
163 | // find gate by qasm name
164 | for(var tmpName in self.circuit.basicGates) {
165 | var tmpDef = self.circuit.basicGates[tmpName];
166 | if(tmpDef.exportInfo && tmpDef.exportInfo.qasm && tmpDef.exportInfo.qasm.name && tmpDef.exportInfo.qasm.name == gateName) {
167 | gateName = tmpName;
168 | break;
169 | }
170 | // newer versions of qiskit exports to qasm with gate names undefined by qasm 2.0 definition...
171 | if(tmpDef.exportInfo && tmpDef.exportInfo.qiskit && tmpDef.exportInfo.qiskit.name && tmpDef.exportInfo.qiskit.name == gateName) {
172 | gateName = tmpName;
173 | break;
174 | }
175 | }
176 | }
177 |
178 |
179 | var params = {};
180 | if(explist && explist.exp()) {
181 | var gateDef = self.circuit.basicGates[gateName];
182 | if(!gateDef) {
183 | gateDef = self.circuit.customGates[gateName];
184 | }
185 |
186 | if(gateDef) {
187 | var paramList = explist.exp();
188 | var paramDef = gateDef.params || [];
189 | paramList.map(function(paramItem, paramIndex) {
190 | var paramValue = paramItem.getText();
191 | var paramName = paramDef.length >= paramIndex ? paramDef[paramIndex] : "";
192 | if(paramName) {
193 | params[paramName] = paramValue;
194 | }
195 | });
196 | }
197 | }
198 |
199 | var options = { params: params };
200 |
201 |
202 | var wires = [];
203 |
204 | if(idlist) {
205 | var count = idlist.ID().length;
206 | for(var i = 0; i < count; i++) {
207 | wires.push(customGateRegs.indexOf(idlist.ID()[i].getText()));
208 | }
209 | }
210 |
211 | if(mixedlist) {
212 | // ?
213 | }
214 |
215 | /*
216 | if(!self.compatibilityMode) {
217 | switch(gateName) {
218 | case "rz": {
219 | gateName = "u1";
220 | if(options && options.params && options.params.phi) {
221 | options.params.lambda = options.params.phi;
222 | delete options.params.phi;
223 | }
224 | }; break;
225 | }
226 | }
227 | */
228 | var external = self.circuit.customGates[gateName];
229 | if(external) {
230 | customGate.registerGate(gateName, JSON.parse(JSON.stringify(external)));
231 | }
232 |
233 | customGate.addGate(gateName, -1, wires, options);
234 | }
235 | });
236 | }
237 |
238 | this.circuit.registerGate(customGateName, customGate.save(false));
239 | }
240 | };
241 |
242 | // Exit a parse tree produced by QASMParser#statement.
243 | QCQASMListener.prototype.exitStatement = function(ctx) {
244 | };
245 |
246 |
247 | // Enter a parse tree produced by QASMParser#version.
248 | QCQASMListener.prototype.enterVersion = function(ctx) {
249 | };
250 |
251 | // Exit a parse tree produced by QASMParser#version.
252 | QCQASMListener.prototype.exitVersion = function(ctx) {
253 | };
254 |
255 |
256 | // Enter a parse tree produced by QASMParser#decl.
257 | QCQASMListener.prototype.enterDecl = function(ctx) {
258 | switch(ctx.getChild(0).getText()) {
259 | case "qreg": this.qregMap[ctx.getChild(1).getText()] = parseInt(ctx.getChild(3).getText()); break;
260 | case "creg": this.circuit.createCreg(ctx.getChild(1).getText(), parseInt(ctx.getChild(3).getText())); break;
261 | }
262 | };
263 |
264 | // Exit a parse tree produced by QASMParser#decl.
265 | QCQASMListener.prototype.exitDecl = function(ctx) {
266 | };
267 |
268 |
269 | // Enter a parse tree produced by QASMParser#gatedecl.
270 | QCQASMListener.prototype.enterGatedecl = function(ctx) {
271 | };
272 |
273 | // Exit a parse tree produced by QASMParser#gatedecl.
274 | QCQASMListener.prototype.exitGatedecl = function(ctx) {
275 | };
276 |
277 |
278 | // Enter a parse tree produced by QASMParser#goplist.
279 | QCQASMListener.prototype.enterGoplist = function(ctx) {
280 | };
281 |
282 | // Exit a parse tree produced by QASMParser#goplist.
283 | QCQASMListener.prototype.exitGoplist = function(ctx) {
284 | };
285 |
286 | // Enter a parse tree produced by QASMParser#qop.
287 | QCQASMListener.prototype.enterQop = function(ctx) {
288 | var self = this;
289 | var condition = JSON.parse(JSON.stringify(this.condition));
290 | this.condition = {};
291 |
292 | var name = ctx.getChildCount() ? ctx.getChild(0).getText() : "";
293 |
294 | if(name == "reset") {
295 | var qreg = "";
296 | var qbit = -1;
297 | var count = ctx.argument().length;
298 | for(var i = 0; i < count; i++) {
299 | var arg = ctx.argument()[i];
300 | if(i == 0) {
301 | qreg = arg.ID().getText();
302 | qbit = arg.INT() ? parseInt(arg.INT().getText()) : -1;
303 | }
304 | }
305 |
306 | if(qreg) {
307 | var numBits = self.qregLen(qreg);
308 | if(qbit < 0) {
309 | //
310 | // argument is entire register
311 | //
312 | for(var x = 0; x < numBits; x++) {
313 | self.circuit.addGate("reset", -1, x + self.qregBase(qreg), { condition: condition || {} } );
314 | }
315 |
316 | } else {
317 | //
318 | // both arguments are single bits
319 | //
320 | self.circuit.addGate("reset", -1, qbit + self.qregBase(qreg), { condition: condition || {} } );
321 | }
322 | }
323 | }
324 |
325 | if(name == "measure") {
326 | var qreg = "";
327 | var qbit = -1;
328 | var creg = "";
329 | var cbit = -1;
330 | var count = ctx.argument().length;
331 | for(var i = 0; i < count; i++) {
332 | var arg = ctx.argument()[i];
333 | if(i == 0) {
334 | qreg = arg.ID().getText();
335 | qbit = arg.INT() ? parseInt(arg.INT().getText()) : -1;
336 | }
337 | if(i == 1) {
338 | creg = arg.ID().getText();
339 | cbit = arg.INT() ? parseInt(arg.INT().getText()) : -1;
340 | }
341 | }
342 |
343 | if(qreg && creg) {
344 | var numBits = self.qregLen(qreg);
345 | if(qbit < 0 && cbit < 0) {
346 | //
347 | // both arguments are entire registers
348 | //
349 | for(var x = 0; x < numBits; x++) {
350 | self.circuit.addGate("measure", -1, x + self.qregBase(qreg), { creg: { name: creg, bit: x }, condition: condition || {} } );
351 | }
352 |
353 | } else {
354 | if(qbit >= 0 && cbit >= 0) {
355 | //
356 | // both arguments are single bits
357 | //
358 | self.circuit.addGate("measure", -1, qbit + self.qregBase(qreg), { creg: { name: creg, bit: cbit }, condition: condition || {} } );
359 | } else {
360 | if(qbit >= 0 && cbit < 0) {
361 | //
362 | // qbit is single, creg is entire register
363 | //
364 | for(var x = 0; x < numBits; x++) {
365 | self.circuit.addGate("measure", -1, qbit + self.qregBase(qreg), { creg: { name: creg, bit: x }, condition: condition || {} } );
366 | }
367 | } else {
368 | //
369 | // qbit is entire register, creg is single bit
370 | //
371 | for(var x = 0; x < numBits; x++) {
372 | self.circuit.addGate("measure", -1, x + self.qregBase(qreg), { creg: { name: creg, bit: cbit }, condition: condition || {} } );
373 | }
374 |
375 | }
376 | }
377 | }
378 | }
379 | }
380 |
381 | var uop = ctx.uop();
382 | if(uop && uop.ID()) {
383 | var gateName = uop.ID().getText();
384 | var idlist = uop.anylist() ? uop.anylist().idlist() : null;
385 | var mixedlist = uop.anylist() ? uop.anylist().mixedlist() : null;
386 | var explist = uop.explist();
387 |
388 | switch(gateName) {
389 | case "CX": gateName = "cx"; break;
390 | case "U": gateName = "u3"; break;
391 | }
392 |
393 | if(!self.circuit.basicGates[gateName] && !self.circuit.customGates[gateName]) {
394 | // find gate by qasm name
395 | for(var tmpName in self.circuit.basicGates) {
396 | var tmpDef = self.circuit.basicGates[tmpName];
397 | if(tmpDef.exportInfo && tmpDef.exportInfo.qasm && tmpDef.exportInfo.qasm.name && tmpDef.exportInfo.qasm.name == gateName) {
398 | gateName = tmpName;
399 | break;
400 | }
401 | // newer versions of qiskit exports to qasm with gate names undefined by qasm 2.0 definition...
402 | if(tmpDef.exportInfo && tmpDef.exportInfo.qiskit && tmpDef.exportInfo.qiskit.name && tmpDef.exportInfo.qiskit.name == gateName) {
403 | gateName = tmpName;
404 | break;
405 | }
406 | }
407 | }
408 |
409 | var params = {};
410 | if(explist && explist.exp()) {
411 | var gateDef = self.circuit.basicGates[gateName];
412 | if(!gateDef) {
413 | gateDef = self.circuit.customGates[gateName];
414 | }
415 | if(gateDef) {
416 | var paramList = explist.exp();
417 | var paramDef = gateDef.params || [];
418 | paramList.map(function(paramItem, paramIndex) {
419 | var paramValue = paramItem.getText();
420 | var paramName = paramDef.length >= paramIndex ? paramDef[paramIndex] : "";
421 | if(paramName) {
422 | params[paramName] = paramValue;
423 | }
424 | });
425 | }
426 | }
427 |
428 | var options = { params: params, condition: condition || {} };
429 |
430 | if(idlist) {
431 | //
432 | // arguments are entire registers
433 | // example: cx q,r;
434 | //
435 | var numBits = self.qregLen(idlist.ID()[0].getText());
436 | for(var x = 0; x < numBits; x++) {
437 | var args = [];
438 | var count = idlist.ID().length;
439 | for(var i = 0; i < count; i++) {
440 | args.push({ reg: idlist.ID()[i].getText(), bit: x });
441 | }
442 |
443 | var wires = [];
444 | args.map(function(a) {
445 | wires.push(a.bit + self.qregBase(a.reg));
446 | });
447 | /*
448 | if(!self.compatibilityMode) {
449 | switch(gateName) {
450 | case "rz": {
451 | gateName = "u1";
452 | if(options && options.params && options.params.phi) {
453 | options.params.lambda = options.params.phi;
454 | delete options.params.phi;
455 | }
456 | }; break;
457 | }
458 | }
459 | */
460 | self.circuit.addGate(gateName, -1, wires, options);
461 | }
462 | }
463 |
464 | // arguments are qbits or mixed
465 | if(mixedlist) {
466 | if(mixedlist.ID().length != mixedlist.INT().length) {
467 | //
468 | // TODO: mixed qbits and entire registers
469 | // example: cx q,r[0];
470 | //
471 | } else {
472 | //
473 | // qbits, for example: cx q[0],r[0];
474 | //
475 | var args = [];
476 | var count = mixedlist.ID().length;
477 | for(var i = 0; i < count; i++) {
478 | args.push({ reg: mixedlist.ID()[i].getText(), bit: parseInt(mixedlist.INT()[i].getText()) });
479 | }
480 |
481 | var wires = [];
482 | args.map(function(a) {
483 | wires.push(a.bit + self.qregBase(a.reg));
484 | });
485 | /*
486 | if(!self.compatibilityMode) {
487 | switch(gateName) {
488 | case "rz": {
489 | gateName = "u1";
490 | if(options && options.params && options.params.phi) {
491 | options.params.lambda = options.params.phi;
492 | delete options.params.phi;
493 | }
494 | }; break;
495 | }
496 | }
497 | */
498 | self.circuit.addGate(gateName, -1, wires, options);
499 | }
500 | }
501 | }
502 | };
503 |
504 | // Exit a parse tree produced by QASMParser#qop.
505 | QCQASMListener.prototype.exitQop = function(ctx) {
506 | };
507 |
508 |
509 | // Enter a parse tree produced by QASMParser#uop.
510 | QCQASMListener.prototype.enterUop = function(ctx) {
511 | };
512 |
513 | // Exit a parse tree produced by QASMParser#uop.
514 | QCQASMListener.prototype.exitUop = function(ctx) {
515 | };
516 |
517 |
518 | // Enter a parse tree produced by QASMParser#anylist.
519 | QCQASMListener.prototype.enterAnylist = function(ctx) {
520 | };
521 |
522 | // Exit a parse tree produced by QASMParser#anylist.
523 | QCQASMListener.prototype.exitAnylist = function(ctx) {
524 | };
525 |
526 |
527 | // Enter a parse tree produced by QASMParser#idlist.
528 | QCQASMListener.prototype.enterIdlist = function(ctx) {
529 | };
530 |
531 | // Exit a parse tree produced by QASMParser#idlist.
532 | QCQASMListener.prototype.exitIdlist = function(ctx) {
533 | };
534 |
535 |
536 | // Enter a parse tree produced by QASMParser#mixedlist.
537 | QCQASMListener.prototype.enterMixedlist = function(ctx) {
538 | };
539 |
540 | // Exit a parse tree produced by QASMParser#mixedlist.
541 | QCQASMListener.prototype.exitMixedlist = function(ctx) {
542 | };
543 |
544 |
545 | // Enter a parse tree produced by QASMParser#argument.
546 | QCQASMListener.prototype.enterArgument = function(ctx) {
547 | };
548 |
549 | // Exit a parse tree produced by QASMParser#argument.
550 | QCQASMListener.prototype.exitArgument = function(ctx) {
551 | };
552 |
553 |
554 | // Enter a parse tree produced by QASMParser#explist.
555 | QCQASMListener.prototype.enterExplist = function(ctx) {
556 | };
557 |
558 | // Exit a parse tree produced by QASMParser#explist.
559 | QCQASMListener.prototype.exitExplist = function(ctx) {
560 | };
561 |
562 |
563 | // Enter a parse tree produced by QASMParser#exp.
564 | QCQASMListener.prototype.enterExp = function(ctx) {
565 | };
566 |
567 | // Exit a parse tree produced by QASMParser#exp.
568 | QCQASMListener.prototype.exitExp = function(ctx) {
569 | };
570 |
571 |
572 | // Enter a parse tree produced by QASMParser#unaryop.
573 | QCQASMListener.prototype.enterUnaryop = function(ctx) {
574 | };
575 |
576 | // Exit a parse tree produced by QASMParser#unaryop.
577 | QCQASMListener.prototype.exitUnaryop = function(ctx) {
578 | };
579 |
580 | module.exports = QASMImport;
581 |
--------------------------------------------------------------------------------
/lib/qasm_import/QASMLexer.js:
--------------------------------------------------------------------------------
1 | // Generated from QASM.g4 by ANTLR 4.7.1
2 | // jshint ignore: start
3 | var antlr4 = require('antlr4/index');
4 |
5 |
6 | var serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964",
7 | "\u0002-\u0124\b\u0001\u0004\u0002\t\u0002\u0004\u0003\t\u0003\u0004",
8 | "\u0004\t\u0004\u0004\u0005\t\u0005\u0004\u0006\t\u0006\u0004\u0007\t",
9 | "\u0007\u0004\b\t\b\u0004\t\t\t\u0004\n\t\n\u0004\u000b\t\u000b\u0004",
10 | "\f\t\f\u0004\r\t\r\u0004\u000e\t\u000e\u0004\u000f\t\u000f\u0004\u0010",
11 | "\t\u0010\u0004\u0011\t\u0011\u0004\u0012\t\u0012\u0004\u0013\t\u0013",
12 | "\u0004\u0014\t\u0014\u0004\u0015\t\u0015\u0004\u0016\t\u0016\u0004\u0017",
13 | "\t\u0017\u0004\u0018\t\u0018\u0004\u0019\t\u0019\u0004\u001a\t\u001a",
14 | "\u0004\u001b\t\u001b\u0004\u001c\t\u001c\u0004\u001d\t\u001d\u0004\u001e",
15 | "\t\u001e\u0004\u001f\t\u001f\u0004 \t \u0004!\t!\u0004\"\t\"\u0004#",
16 | "\t#\u0004$\t$\u0004%\t%\u0004&\t&\u0004\'\t\'\u0004(\t(\u0004)\t)\u0004",
17 | "*\t*\u0004+\t+\u0004,\t,\u0003\u0002\u0003\u0002\u0003\u0003\u0003\u0003",
18 | "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0004",
19 | "\u0003\u0004\u0003\u0005\u0003\u0005\u0003\u0006\u0003\u0006\u0003\u0007",
20 | "\u0003\u0007\u0003\u0007\u0003\b\u0003\b\u0003\b\u0003\t\u0003\t\u0003",
21 | "\t\u0003\t\u0003\t\u0003\t\u0003\t\u0003\t\u0003\n\u0003\n\u0003\n\u0003",
22 | "\n\u0003\n\u0003\n\u0003\n\u0003\n\u0003\n\u0003\u000b\u0003\u000b\u0003",
23 | "\u000b\u0003\u000b\u0003\u000b\u0003\u000b\u0003\u000b\u0003\u000b\u0003",
24 | "\f\u0003\f\u0003\f\u0003\f\u0003\f\u0003\r\u0003\r\u0003\u000e\u0003",
25 | "\u000e\u0003\u000f\u0003\u000f\u0003\u000f\u0003\u000f\u0003\u000f\u0003",
26 | "\u0010\u0003\u0010\u0003\u0010\u0003\u0010\u0003\u0010\u0003\u0011\u0003",
27 | "\u0011\u0003\u0012\u0003\u0012\u0003\u0012\u0003\u0012\u0003\u0012\u0003",
28 | "\u0012\u0003\u0012\u0003\u0012\u0003\u0013\u0003\u0013\u0003\u0013\u0003",
29 | "\u0014\u0003\u0014\u0003\u0014\u0003\u0014\u0003\u0014\u0003\u0014\u0003",
30 | "\u0015\u0003\u0015\u0003\u0016\u0003\u0016\u0003\u0016\u0003\u0017\u0003",
31 | "\u0017\u0003\u0018\u0003\u0018\u0003\u0019\u0003\u0019\u0003\u001a\u0003",
32 | "\u001a\u0003\u001b\u0003\u001b\u0003\u001c\u0003\u001c\u0003\u001d\u0003",
33 | "\u001d\u0003\u001d\u0003\u001d\u0003\u001e\u0003\u001e\u0003\u001e\u0003",
34 | "\u001e\u0003\u001f\u0003\u001f\u0003\u001f\u0003\u001f\u0003 \u0003",
35 | " \u0003 \u0003 \u0003!\u0003!\u0003!\u0003\"\u0003\"\u0003\"\u0003\"",
36 | "\u0003\"\u0003#\u0003#\u0003#\u0003$\u0003$\u0003$\u0003$\u0003$\u0003",
37 | "$\u0003$\u0005$\u00e1\n$\u0003%\u0003%\u0003%\u0006%\u00e6\n%\r%\u000e",
38 | "%\u00e7\u0003&\u0003&\u0003&\u0006&\u00ed\n&\r&\u000e&\u00ee\u0003\'",
39 | "\u0006\'\u00f2\n\'\r\'\u000e\'\u00f3\u0003(\u0003(\u0007(\u00f8\n(\f",
40 | "(\u000e(\u00fb\u000b(\u0003)\u0006)\u00fe\n)\r)\u000e)\u00ff\u0003)",
41 | "\u0003)\u0003*\u0003*\u0006*\u0106\n*\r*\u000e*\u0107\u0003*\u0003*",
42 | "\u0003+\u0003+\u0003+\u0003+\u0007+\u0110\n+\f+\u000e+\u0113\u000b+",
43 | "\u0003+\u0003+\u0003+\u0003+\u0003+\u0003,\u0003,\u0003,\u0003,\u0007",
44 | ",\u011e\n,\f,\u000e,\u0121\u000b,\u0003,\u0003,\u0003\u0111\u0002-\u0003",
45 | "\u0003\u0005\u0004\u0007\u0005\t\u0006\u000b\u0007\r\b\u000f\t\u0011",
46 | "\n\u0013\u000b\u0015\f\u0017\r\u0019\u000e\u001b\u000f\u001d\u0010\u001f",
47 | "\u0011!\u0012#\u0013%\u0014\'\u0015)\u0016+\u0017-\u0018/\u00191\u001a",
48 | "3\u001b5\u001c7\u001d9\u001e;\u001f= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-\u0003",
49 | "\u0002\n\u0003\u00022;\u0004\u0002GGgg\u0004\u0002--//\u0003\u0002c",
50 | "|\u0006\u00022;C\\aac|\u0005\u0002\u000b\f\u000e\u000f\"\"\u0007\u0002",
51 | "/02;C\\aac|\u0004\u0002\f\f\u000f\u000f\u0002\u012d\u0002\u0003\u0003",
52 | "\u0002\u0002\u0002\u0002\u0005\u0003\u0002\u0002\u0002\u0002\u0007\u0003",
53 | "\u0002\u0002\u0002\u0002\t\u0003\u0002\u0002\u0002\u0002\u000b\u0003",
54 | "\u0002\u0002\u0002\u0002\r\u0003\u0002\u0002\u0002\u0002\u000f\u0003",
55 | "\u0002\u0002\u0002\u0002\u0011\u0003\u0002\u0002\u0002\u0002\u0013\u0003",
56 | "\u0002\u0002\u0002\u0002\u0015\u0003\u0002\u0002\u0002\u0002\u0017\u0003",
57 | "\u0002\u0002\u0002\u0002\u0019\u0003\u0002\u0002\u0002\u0002\u001b\u0003",
58 | "\u0002\u0002\u0002\u0002\u001d\u0003\u0002\u0002\u0002\u0002\u001f\u0003",
59 | "\u0002\u0002\u0002\u0002!\u0003\u0002\u0002\u0002\u0002#\u0003\u0002",
60 | "\u0002\u0002\u0002%\u0003\u0002\u0002\u0002\u0002\'\u0003\u0002\u0002",
61 | "\u0002\u0002)\u0003\u0002\u0002\u0002\u0002+\u0003\u0002\u0002\u0002",
62 | "\u0002-\u0003\u0002\u0002\u0002\u0002/\u0003\u0002\u0002\u0002\u0002",
63 | "1\u0003\u0002\u0002\u0002\u00023\u0003\u0002\u0002\u0002\u00025\u0003",
64 | "\u0002\u0002\u0002\u00027\u0003\u0002\u0002\u0002\u00029\u0003\u0002",
65 | "\u0002\u0002\u0002;\u0003\u0002\u0002\u0002\u0002=\u0003\u0002\u0002",
66 | "\u0002\u0002?\u0003\u0002\u0002\u0002\u0002A\u0003\u0002\u0002\u0002",
67 | "\u0002C\u0003\u0002\u0002\u0002\u0002E\u0003\u0002\u0002\u0002\u0002",
68 | "G\u0003\u0002\u0002\u0002\u0002I\u0003\u0002\u0002\u0002\u0002K\u0003",
69 | "\u0002\u0002\u0002\u0002M\u0003\u0002\u0002\u0002\u0002O\u0003\u0002",
70 | "\u0002\u0002\u0002Q\u0003\u0002\u0002\u0002\u0002S\u0003\u0002\u0002",
71 | "\u0002\u0002U\u0003\u0002\u0002\u0002\u0002W\u0003\u0002\u0002\u0002",
72 | "\u0003Y\u0003\u0002\u0002\u0002\u0005[\u0003\u0002\u0002\u0002\u0007",
73 | "b\u0003\u0002\u0002\u0002\td\u0003\u0002\u0002\u0002\u000bf\u0003\u0002",
74 | "\u0002\u0002\rh\u0003\u0002\u0002\u0002\u000fk\u0003\u0002\u0002\u0002",
75 | "\u0011n\u0003\u0002\u0002\u0002\u0013v\u0003\u0002\u0002\u0002\u0015",
76 | "\u007f\u0003\u0002\u0002\u0002\u0017\u0087\u0003\u0002\u0002\u0002\u0019",
77 | "\u008c\u0003\u0002\u0002\u0002\u001b\u008e\u0003\u0002\u0002\u0002\u001d",
78 | "\u0090\u0003\u0002\u0002\u0002\u001f\u0095\u0003\u0002\u0002\u0002!",
79 | "\u009a\u0003\u0002\u0002\u0002#\u009c\u0003\u0002\u0002\u0002%\u00a4",
80 | "\u0003\u0002\u0002\u0002\'\u00a7\u0003\u0002\u0002\u0002)\u00ad\u0003",
81 | "\u0002\u0002\u0002+\u00af\u0003\u0002\u0002\u0002-\u00b2\u0003\u0002",
82 | "\u0002\u0002/\u00b4\u0003\u0002\u0002\u00021\u00b6\u0003\u0002\u0002",
83 | "\u00023\u00b8\u0003\u0002\u0002\u00025\u00ba\u0003\u0002\u0002\u0002",
84 | "7\u00bc\u0003\u0002\u0002\u00029\u00be\u0003\u0002\u0002\u0002;\u00c2",
85 | "\u0003\u0002\u0002\u0002=\u00c6\u0003\u0002\u0002\u0002?\u00ca\u0003",
86 | "\u0002\u0002\u0002A\u00ce\u0003\u0002\u0002\u0002C\u00d1\u0003\u0002",
87 | "\u0002\u0002E\u00d6\u0003\u0002\u0002\u0002G\u00e0\u0003\u0002\u0002",
88 | "\u0002I\u00e2\u0003\u0002\u0002\u0002K\u00e9\u0003\u0002\u0002\u0002",
89 | "M\u00f1\u0003\u0002\u0002\u0002O\u00f5\u0003\u0002\u0002\u0002Q\u00fd",
90 | "\u0003\u0002\u0002\u0002S\u0103\u0003\u0002\u0002\u0002U\u010b\u0003",
91 | "\u0002\u0002\u0002W\u0119\u0003\u0002\u0002\u0002YZ\u0007\u007f\u0002",
92 | "\u0002Z\u0004\u0003\u0002\u0002\u0002[\\\u0007q\u0002\u0002\\]\u0007",
93 | "r\u0002\u0002]^\u0007c\u0002\u0002^_\u0007s\u0002\u0002_`\u0007w\u0002",
94 | "\u0002`a\u0007g\u0002\u0002a\u0006\u0003\u0002\u0002\u0002bc\u0007=",
95 | "\u0002\u0002c\b\u0003\u0002\u0002\u0002de\u0007*\u0002\u0002e\n\u0003",
96 | "\u0002\u0002\u0002fg\u0007+\u0002\u0002g\f\u0003\u0002\u0002\u0002h",
97 | "i\u0007k\u0002\u0002ij\u0007h\u0002\u0002j\u000e\u0003\u0002\u0002\u0002",
98 | "kl\u0007?\u0002\u0002lm\u0007?\u0002\u0002m\u0010\u0003\u0002\u0002",
99 | "\u0002no\u0007d\u0002\u0002op\u0007c\u0002\u0002pq\u0007t\u0002\u0002",
100 | "qr\u0007t\u0002\u0002rs\u0007k\u0002\u0002st\u0007g\u0002\u0002tu\u0007",
101 | "t\u0002\u0002u\u0012\u0003\u0002\u0002\u0002vw\u0007Q\u0002\u0002wx",
102 | "\u0007R\u0002\u0002xy\u0007G\u0002\u0002yz\u0007P\u0002\u0002z{\u0007",
103 | "S\u0002\u0002{|\u0007C\u0002\u0002|}\u0007U\u0002\u0002}~\u0007O\u0002",
104 | "\u0002~\u0014\u0003\u0002\u0002\u0002\u007f\u0080\u0007k\u0002\u0002",
105 | "\u0080\u0081\u0007p\u0002\u0002\u0081\u0082\u0007e\u0002\u0002\u0082",
106 | "\u0083\u0007n\u0002\u0002\u0083\u0084\u0007w\u0002\u0002\u0084\u0085",
107 | "\u0007f\u0002\u0002\u0085\u0086\u0007g\u0002\u0002\u0086\u0016\u0003",
108 | "\u0002\u0002\u0002\u0087\u0088\u0007s\u0002\u0002\u0088\u0089\u0007",
109 | "t\u0002\u0002\u0089\u008a\u0007g\u0002\u0002\u008a\u008b\u0007i\u0002",
110 | "\u0002\u008b\u0018\u0003\u0002\u0002\u0002\u008c\u008d\u0007]\u0002",
111 | "\u0002\u008d\u001a\u0003\u0002\u0002\u0002\u008e\u008f\u0007_\u0002",
112 | "\u0002\u008f\u001c\u0003\u0002\u0002\u0002\u0090\u0091\u0007e\u0002",
113 | "\u0002\u0091\u0092\u0007t\u0002\u0002\u0092\u0093\u0007g\u0002\u0002",
114 | "\u0093\u0094\u0007i\u0002\u0002\u0094\u001e\u0003\u0002\u0002\u0002",
115 | "\u0095\u0096\u0007i\u0002\u0002\u0096\u0097\u0007c\u0002\u0002\u0097",
116 | "\u0098\u0007v\u0002\u0002\u0098\u0099\u0007g\u0002\u0002\u0099 \u0003",
117 | "\u0002\u0002\u0002\u009a\u009b\u0007}\u0002\u0002\u009b\"\u0003\u0002",
118 | "\u0002\u0002\u009c\u009d\u0007o\u0002\u0002\u009d\u009e\u0007g\u0002",
119 | "\u0002\u009e\u009f\u0007c\u0002\u0002\u009f\u00a0\u0007u\u0002\u0002",
120 | "\u00a0\u00a1\u0007w\u0002\u0002\u00a1\u00a2\u0007t\u0002\u0002\u00a2",
121 | "\u00a3\u0007g\u0002\u0002\u00a3$\u0003\u0002\u0002\u0002\u00a4\u00a5",
122 | "\u0007/\u0002\u0002\u00a5\u00a6\u0007@\u0002\u0002\u00a6&\u0003\u0002",
123 | "\u0002\u0002\u00a7\u00a8\u0007t\u0002\u0002\u00a8\u00a9\u0007g\u0002",
124 | "\u0002\u00a9\u00aa\u0007u\u0002\u0002\u00aa\u00ab\u0007g\u0002\u0002",
125 | "\u00ab\u00ac\u0007v\u0002\u0002\u00ac(\u0003\u0002\u0002\u0002\u00ad",
126 | "\u00ae\u0007W\u0002\u0002\u00ae*\u0003\u0002\u0002\u0002\u00af\u00b0",
127 | "\u0007E\u0002\u0002\u00b0\u00b1\u0007Z\u0002\u0002\u00b1,\u0003\u0002",
128 | "\u0002\u0002\u00b2\u00b3\u0007.\u0002\u0002\u00b3.\u0003\u0002\u0002",
129 | "\u0002\u00b4\u00b5\u0007`\u0002\u0002\u00b50\u0003\u0002\u0002\u0002",
130 | "\u00b6\u00b7\u0007,\u0002\u0002\u00b72\u0003\u0002\u0002\u0002\u00b8",
131 | "\u00b9\u00071\u0002\u0002\u00b94\u0003\u0002\u0002\u0002\u00ba\u00bb",
132 | "\u0007-\u0002\u0002\u00bb6\u0003\u0002\u0002\u0002\u00bc\u00bd\u0007",
133 | "/\u0002\u0002\u00bd8\u0003\u0002\u0002\u0002\u00be\u00bf\u0007u\u0002",
134 | "\u0002\u00bf\u00c0\u0007k\u0002\u0002\u00c0\u00c1\u0007p\u0002\u0002",
135 | "\u00c1:\u0003\u0002\u0002\u0002\u00c2\u00c3\u0007e\u0002\u0002\u00c3",
136 | "\u00c4\u0007q\u0002\u0002\u00c4\u00c5\u0007u\u0002\u0002\u00c5<\u0003",
137 | "\u0002\u0002\u0002\u00c6\u00c7\u0007v\u0002\u0002\u00c7\u00c8\u0007",
138 | "c\u0002\u0002\u00c8\u00c9\u0007p\u0002\u0002\u00c9>\u0003\u0002\u0002",
139 | "\u0002\u00ca\u00cb\u0007g\u0002\u0002\u00cb\u00cc\u0007z\u0002\u0002",
140 | "\u00cc\u00cd\u0007r\u0002\u0002\u00cd@\u0003\u0002\u0002\u0002\u00ce",
141 | "\u00cf\u0007n\u0002\u0002\u00cf\u00d0\u0007p\u0002\u0002\u00d0B\u0003",
142 | "\u0002\u0002\u0002\u00d1\u00d2\u0007u\u0002\u0002\u00d2\u00d3\u0007",
143 | "s\u0002\u0002\u00d3\u00d4\u0007t\u0002\u0002\u00d4\u00d5\u0007v\u0002",
144 | "\u0002\u00d5D\u0003\u0002\u0002\u0002\u00d6\u00d7\u0007r\u0002\u0002",
145 | "\u00d7\u00d8\u0007k\u0002\u0002\u00d8F\u0003\u0002\u0002\u0002\u00d9",
146 | "\u00da\u0005I%\u0002\u00da\u00db\u0005K&\u0002\u00db\u00e1\u0003\u0002",
147 | "\u0002\u0002\u00dc\u00dd\u0005M\'\u0002\u00dd\u00de\u0005K&\u0002\u00de",
148 | "\u00e1\u0003\u0002\u0002\u0002\u00df\u00e1\u0005I%\u0002\u00e0\u00d9",
149 | "\u0003\u0002\u0002\u0002\u00e0\u00dc\u0003\u0002\u0002\u0002\u00e0\u00df",
150 | "\u0003\u0002\u0002\u0002\u00e1H\u0003\u0002\u0002\u0002\u00e2\u00e3",
151 | "\u0005M\'\u0002\u00e3\u00e5\u00070\u0002\u0002\u00e4\u00e6\t\u0002\u0002",
152 | "\u0002\u00e5\u00e4\u0003\u0002\u0002\u0002\u00e6\u00e7\u0003\u0002\u0002",
153 | "\u0002\u00e7\u00e5\u0003\u0002\u0002\u0002\u00e7\u00e8\u0003\u0002\u0002",
154 | "\u0002\u00e8J\u0003\u0002\u0002\u0002\u00e9\u00ea\t\u0003\u0002\u0002",
155 | "\u00ea\u00ec\t\u0004\u0002\u0002\u00eb\u00ed\t\u0002\u0002\u0002\u00ec",
156 | "\u00eb\u0003\u0002\u0002\u0002\u00ed\u00ee\u0003\u0002\u0002\u0002\u00ee",
157 | "\u00ec\u0003\u0002\u0002\u0002\u00ee\u00ef\u0003\u0002\u0002\u0002\u00ef",
158 | "L\u0003\u0002\u0002\u0002\u00f0\u00f2\t\u0002\u0002\u0002\u00f1\u00f0",
159 | "\u0003\u0002\u0002\u0002\u00f2\u00f3\u0003\u0002\u0002\u0002\u00f3\u00f1",
160 | "\u0003\u0002\u0002\u0002\u00f3\u00f4\u0003\u0002\u0002\u0002\u00f4N",
161 | "\u0003\u0002\u0002\u0002\u00f5\u00f9\t\u0005\u0002\u0002\u00f6\u00f8",
162 | "\t\u0006\u0002\u0002\u00f7\u00f6\u0003\u0002\u0002\u0002\u00f8\u00fb",
163 | "\u0003\u0002\u0002\u0002\u00f9\u00f7\u0003\u0002\u0002\u0002\u00f9\u00fa",
164 | "\u0003\u0002\u0002\u0002\u00faP\u0003\u0002\u0002\u0002\u00fb\u00f9",
165 | "\u0003\u0002\u0002\u0002\u00fc\u00fe\t\u0007\u0002\u0002\u00fd\u00fc",
166 | "\u0003\u0002\u0002\u0002\u00fe\u00ff\u0003\u0002\u0002\u0002\u00ff\u00fd",
167 | "\u0003\u0002\u0002\u0002\u00ff\u0100\u0003\u0002\u0002\u0002\u0100\u0101",
168 | "\u0003\u0002\u0002\u0002\u0101\u0102\b)\u0002\u0002\u0102R\u0003\u0002",
169 | "\u0002\u0002\u0103\u0105\u0007$\u0002\u0002\u0104\u0106\t\b\u0002\u0002",
170 | "\u0105\u0104\u0003\u0002\u0002\u0002\u0106\u0107\u0003\u0002\u0002\u0002",
171 | "\u0107\u0105\u0003\u0002\u0002\u0002\u0107\u0108\u0003\u0002\u0002\u0002",
172 | "\u0108\u0109\u0003\u0002\u0002\u0002\u0109\u010a\u0007$\u0002\u0002",
173 | "\u010aT\u0003\u0002\u0002\u0002\u010b\u010c\u00071\u0002\u0002\u010c",
174 | "\u010d\u0007,\u0002\u0002\u010d\u0111\u0003\u0002\u0002\u0002\u010e",
175 | "\u0110\u000b\u0002\u0002\u0002\u010f\u010e\u0003\u0002\u0002\u0002\u0110",
176 | "\u0113\u0003\u0002\u0002\u0002\u0111\u0112\u0003\u0002\u0002\u0002\u0111",
177 | "\u010f\u0003\u0002\u0002\u0002\u0112\u0114\u0003\u0002\u0002\u0002\u0113",
178 | "\u0111\u0003\u0002\u0002\u0002\u0114\u0115\u0007,\u0002\u0002\u0115",
179 | "\u0116\u00071\u0002\u0002\u0116\u0117\u0003\u0002\u0002\u0002\u0117",
180 | "\u0118\b+\u0002\u0002\u0118V\u0003\u0002\u0002\u0002\u0119\u011a\u0007",
181 | "1\u0002\u0002\u011a\u011b\u00071\u0002\u0002\u011b\u011f\u0003\u0002",
182 | "\u0002\u0002\u011c\u011e\n\t\u0002\u0002\u011d\u011c\u0003\u0002\u0002",
183 | "\u0002\u011e\u0121\u0003\u0002\u0002\u0002\u011f\u011d\u0003\u0002\u0002",
184 | "\u0002\u011f\u0120\u0003\u0002\u0002\u0002\u0120\u0122\u0003\u0002\u0002",
185 | "\u0002\u0121\u011f\u0003\u0002\u0002\u0002\u0122\u0123\b,\u0002\u0002",
186 | "\u0123X\u0003\u0002\u0002\u0002\f\u0002\u00e0\u00e7\u00ee\u00f3\u00f9",
187 | "\u00ff\u0107\u0111\u011f\u0003\b\u0002\u0002"].join("");
188 |
189 |
190 | var atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN);
191 |
192 | var decisionsToDFA = atn.decisionToState.map( function(ds, index) { return new antlr4.dfa.DFA(ds, index); });
193 |
194 | function QASMLexer(input) {
195 | antlr4.Lexer.call(this, input);
196 | this._interp = new antlr4.atn.LexerATNSimulator(this, atn, decisionsToDFA, new antlr4.PredictionContextCache());
197 | return this;
198 | }
199 |
200 | QASMLexer.prototype = Object.create(antlr4.Lexer.prototype);
201 | QASMLexer.prototype.constructor = QASMLexer;
202 |
203 | Object.defineProperty(QASMLexer.prototype, "atn", {
204 | get : function() {
205 | return atn;
206 | }
207 | });
208 |
209 | QASMLexer.EOF = antlr4.Token.EOF;
210 | QASMLexer.T__0 = 1;
211 | QASMLexer.T__1 = 2;
212 | QASMLexer.T__2 = 3;
213 | QASMLexer.T__3 = 4;
214 | QASMLexer.T__4 = 5;
215 | QASMLexer.T__5 = 6;
216 | QASMLexer.T__6 = 7;
217 | QASMLexer.T__7 = 8;
218 | QASMLexer.T__8 = 9;
219 | QASMLexer.T__9 = 10;
220 | QASMLexer.T__10 = 11;
221 | QASMLexer.T__11 = 12;
222 | QASMLexer.T__12 = 13;
223 | QASMLexer.T__13 = 14;
224 | QASMLexer.T__14 = 15;
225 | QASMLexer.T__15 = 16;
226 | QASMLexer.T__16 = 17;
227 | QASMLexer.T__17 = 18;
228 | QASMLexer.T__18 = 19;
229 | QASMLexer.T__19 = 20;
230 | QASMLexer.T__20 = 21;
231 | QASMLexer.T__21 = 22;
232 | QASMLexer.T__22 = 23;
233 | QASMLexer.T__23 = 24;
234 | QASMLexer.T__24 = 25;
235 | QASMLexer.T__25 = 26;
236 | QASMLexer.T__26 = 27;
237 | QASMLexer.T__27 = 28;
238 | QASMLexer.T__28 = 29;
239 | QASMLexer.T__29 = 30;
240 | QASMLexer.T__30 = 31;
241 | QASMLexer.T__31 = 32;
242 | QASMLexer.T__32 = 33;
243 | QASMLexer.PI = 34;
244 | QASMLexer.REAL = 35;
245 | QASMLexer.SUBREAL = 36;
246 | QASMLexer.EXPREAL = 37;
247 | QASMLexer.INT = 38;
248 | QASMLexer.ID = 39;
249 | QASMLexer.WS = 40;
250 | QASMLexer.FILENAME = 41;
251 | QASMLexer.COMMENT = 42;
252 | QASMLexer.LINE_COMMENT = 43;
253 |
254 | QASMLexer.prototype.channelNames = [ "DEFAULT_TOKEN_CHANNEL", "HIDDEN" ];
255 |
256 | QASMLexer.prototype.modeNames = [ "DEFAULT_MODE" ];
257 |
258 | QASMLexer.prototype.literalNames = [ null, "'}'", "'opaque'", "';'", "'('",
259 | "')'", "'if'", "'=='", "'barrier'",
260 | "'OPENQASM'", "'include'", "'qreg'",
261 | "'['", "']'", "'creg'", "'gate'", "'{'",
262 | "'measure'", "'->'", "'reset'", "'U'",
263 | "'CX'", "','", "'^'", "'*'", "'/'",
264 | "'+'", "'-'", "'sin'", "'cos'", "'tan'",
265 | "'exp'", "'ln'", "'sqrt'", "'pi'" ];
266 |
267 | QASMLexer.prototype.symbolicNames = [ null, null, null, null, null, null,
268 | null, null, null, null, null, null,
269 | null, null, null, null, null, null,
270 | null, null, null, null, null, null,
271 | null, null, null, null, null, null,
272 | null, null, null, null, "PI", "REAL",
273 | "SUBREAL", "EXPREAL", "INT", "ID",
274 | "WS", "FILENAME", "COMMENT", "LINE_COMMENT" ];
275 |
276 | QASMLexer.prototype.ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4",
277 | "T__5", "T__6", "T__7", "T__8", "T__9",
278 | "T__10", "T__11", "T__12", "T__13", "T__14",
279 | "T__15", "T__16", "T__17", "T__18", "T__19",
280 | "T__20", "T__21", "T__22", "T__23", "T__24",
281 | "T__25", "T__26", "T__27", "T__28", "T__29",
282 | "T__30", "T__31", "T__32", "PI", "REAL",
283 | "SUBREAL", "EXPREAL", "INT", "ID", "WS",
284 | "FILENAME", "COMMENT", "LINE_COMMENT" ];
285 |
286 | QASMLexer.prototype.grammarFileName = "QASM.g4";
287 |
288 |
289 |
290 | exports.QASMLexer = QASMLexer;
291 |
292 |
--------------------------------------------------------------------------------
/lib/qasm_import/QASMListener.js:
--------------------------------------------------------------------------------
1 | // Generated from QASM.g4 by ANTLR 4.7.1
2 | // jshint ignore: start
3 | var antlr4 = require('antlr4/index');
4 |
5 | // This class defines a complete listener for a parse tree produced by QASMParser.
6 | function QASMListener() {
7 | antlr4.tree.ParseTreeListener.call(this);
8 | return this;
9 | }
10 |
11 | QASMListener.prototype = Object.create(antlr4.tree.ParseTreeListener.prototype);
12 | QASMListener.prototype.constructor = QASMListener;
13 |
14 | // Enter a parse tree produced by QASMParser#mainprog.
15 | QASMListener.prototype.enterMainprog = function(ctx) {
16 | };
17 |
18 | // Exit a parse tree produced by QASMParser#mainprog.
19 | QASMListener.prototype.exitMainprog = function(ctx) {
20 | };
21 |
22 |
23 | // Enter a parse tree produced by QASMParser#statement.
24 | QASMListener.prototype.enterStatement = function(ctx) {
25 | };
26 |
27 | // Exit a parse tree produced by QASMParser#statement.
28 | QASMListener.prototype.exitStatement = function(ctx) {
29 | };
30 |
31 |
32 | // Enter a parse tree produced by QASMParser#version.
33 | QASMListener.prototype.enterVersion = function(ctx) {
34 | };
35 |
36 | // Exit a parse tree produced by QASMParser#version.
37 | QASMListener.prototype.exitVersion = function(ctx) {
38 | };
39 |
40 |
41 | // Enter a parse tree produced by QASMParser#include.
42 | QASMListener.prototype.enterInclude = function(ctx) {
43 | };
44 |
45 | // Exit a parse tree produced by QASMParser#include.
46 | QASMListener.prototype.exitInclude = function(ctx) {
47 | };
48 |
49 |
50 | // Enter a parse tree produced by QASMParser#filename.
51 | QASMListener.prototype.enterFilename = function(ctx) {
52 | };
53 |
54 | // Exit a parse tree produced by QASMParser#filename.
55 | QASMListener.prototype.exitFilename = function(ctx) {
56 | };
57 |
58 |
59 | // Enter a parse tree produced by QASMParser#decl.
60 | QASMListener.prototype.enterDecl = function(ctx) {
61 | };
62 |
63 | // Exit a parse tree produced by QASMParser#decl.
64 | QASMListener.prototype.exitDecl = function(ctx) {
65 | };
66 |
67 |
68 | // Enter a parse tree produced by QASMParser#gatedecl.
69 | QASMListener.prototype.enterGatedecl = function(ctx) {
70 | };
71 |
72 | // Exit a parse tree produced by QASMParser#gatedecl.
73 | QASMListener.prototype.exitGatedecl = function(ctx) {
74 | };
75 |
76 |
77 | // Enter a parse tree produced by QASMParser#goplist.
78 | QASMListener.prototype.enterGoplist = function(ctx) {
79 | };
80 |
81 | // Exit a parse tree produced by QASMParser#goplist.
82 | QASMListener.prototype.exitGoplist = function(ctx) {
83 | };
84 |
85 |
86 | // Enter a parse tree produced by QASMParser#qop.
87 | QASMListener.prototype.enterQop = function(ctx) {
88 | };
89 |
90 | // Exit a parse tree produced by QASMParser#qop.
91 | QASMListener.prototype.exitQop = function(ctx) {
92 | };
93 |
94 |
95 | // Enter a parse tree produced by QASMParser#uop.
96 | QASMListener.prototype.enterUop = function(ctx) {
97 | };
98 |
99 | // Exit a parse tree produced by QASMParser#uop.
100 | QASMListener.prototype.exitUop = function(ctx) {
101 | };
102 |
103 |
104 | // Enter a parse tree produced by QASMParser#anylist.
105 | QASMListener.prototype.enterAnylist = function(ctx) {
106 | };
107 |
108 | // Exit a parse tree produced by QASMParser#anylist.
109 | QASMListener.prototype.exitAnylist = function(ctx) {
110 | };
111 |
112 |
113 | // Enter a parse tree produced by QASMParser#idlist.
114 | QASMListener.prototype.enterIdlist = function(ctx) {
115 | };
116 |
117 | // Exit a parse tree produced by QASMParser#idlist.
118 | QASMListener.prototype.exitIdlist = function(ctx) {
119 | };
120 |
121 |
122 | // Enter a parse tree produced by QASMParser#mixedlist.
123 | QASMListener.prototype.enterMixedlist = function(ctx) {
124 | };
125 |
126 | // Exit a parse tree produced by QASMParser#mixedlist.
127 | QASMListener.prototype.exitMixedlist = function(ctx) {
128 | };
129 |
130 |
131 | // Enter a parse tree produced by QASMParser#argument.
132 | QASMListener.prototype.enterArgument = function(ctx) {
133 | };
134 |
135 | // Exit a parse tree produced by QASMParser#argument.
136 | QASMListener.prototype.exitArgument = function(ctx) {
137 | };
138 |
139 |
140 | // Enter a parse tree produced by QASMParser#explist.
141 | QASMListener.prototype.enterExplist = function(ctx) {
142 | };
143 |
144 | // Exit a parse tree produced by QASMParser#explist.
145 | QASMListener.prototype.exitExplist = function(ctx) {
146 | };
147 |
148 |
149 | // Enter a parse tree produced by QASMParser#exp.
150 | QASMListener.prototype.enterExp = function(ctx) {
151 | };
152 |
153 | // Exit a parse tree produced by QASMParser#exp.
154 | QASMListener.prototype.exitExp = function(ctx) {
155 | };
156 |
157 |
158 | // Enter a parse tree produced by QASMParser#atom.
159 | QASMListener.prototype.enterAtom = function(ctx) {
160 | };
161 |
162 | // Exit a parse tree produced by QASMParser#atom.
163 | QASMListener.prototype.exitAtom = function(ctx) {
164 | };
165 |
166 |
167 | // Enter a parse tree produced by QASMParser#unaryop.
168 | QASMListener.prototype.enterUnaryop = function(ctx) {
169 | };
170 |
171 | // Exit a parse tree produced by QASMParser#unaryop.
172 | QASMListener.prototype.exitUnaryop = function(ctx) {
173 | };
174 |
175 |
176 |
177 | exports.QASMListener = QASMListener;
--------------------------------------------------------------------------------
/media/benchmark1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quantastica/quantum-circuit/783ae10f0499a51d0957d22cda8782e941516752/media/benchmark1.png
--------------------------------------------------------------------------------
/media/benchmark2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quantastica/quantum-circuit/783ae10f0499a51d0957d22cda8782e941516752/media/benchmark2.png
--------------------------------------------------------------------------------
/media/benchmark3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quantastica/quantum-circuit/783ae10f0499a51d0957d22cda8782e941516752/media/benchmark3.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "quantum-circuit",
3 | "version": "0.9.240",
4 | "description": "Quantum Circuit Simulator",
5 | "main": "lib/quantum-circuit.js",
6 | "unpkg": "dist/quantum-circuit.min.js",
7 | "scripts": {
8 | "test": "mocha",
9 | "export-gatedefs": "node ./utils/export_gatedefs.js",
10 | "browserify-debug": "browserify ./lib/quantum-circuit.js -o ./dist/quantum-circuit.js -d -s QuantumCircuit",
11 | "browserify-min": "browserify ./lib/quantum-circuit.js -s QuantumCircuit | uglifyjs --source-map -c -b beautify=false,ascii_only=true -o ./dist/quantum-circuit.min.js",
12 | "make-docs": "node ./utils/generate_readme.js",
13 | "build": "npm run browserify-debug && npm run browserify-min && npm run make-docs",
14 | "prepublish": "npm run build"
15 | },
16 | "repository": {
17 | "type": "git",
18 | "url": "git+https://github.com/quantastica/quantum-circuit.git"
19 | },
20 | "keywords": [
21 | "quantum",
22 | "qubit",
23 | "simulator",
24 | "emulator",
25 | "qiskit",
26 | "qasm",
27 | "openqasm",
28 | "qobj",
29 | "quil",
30 | "pyquil",
31 | "cirq",
32 | "qsharp"
33 | ],
34 | "author": "Quantastica ",
35 | "license": "MIT",
36 | "bugs": {
37 | "url": "https://github.com/quantastica/quantum-circuit/issues"
38 | },
39 | "homepage": "https://quantum-circuit.com",
40 | "dependencies": {
41 | "antlr4": "4.7.2",
42 | "mathjs": "^6.0.3"
43 | },
44 | "devDependencies": {
45 | "browserify": "^16.5.1",
46 | "mocha": "^6.2.3",
47 | "uglify-js": "^3.10.0",
48 | "url": "^0.11.0"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | *
4 | * Copyright (c) 2016, Petar Korponaić
5 | *
6 | * This source code is licensed under the MIT License, found in
7 | * the LICENSE.txt file in the root directory of this source tree.
8 | */
9 |
10 | var QuantumCircuit = require("../lib/quantum-circuit.js");
11 | var math = require("mathjs");
12 |
13 | var assert = require("assert");
14 |
15 | var circuit = new QuantumCircuit();
16 |
17 | var checkBasicGates = function() {
18 | for(var gateName in circuit.basicGates) {
19 | var gate = circuit.basicGates[gateName];
20 |
21 | // if gate has matrix
22 | if(gate.matrix && gate.matrix.length) {
23 |
24 | // gate params
25 | var params = {};
26 | if(gate.params && gate.params.length) {
27 | gate.params.map(function(paramName) {
28 | params[paramName] = Math.PI / 3;
29 | });
30 | }
31 |
32 | // calculate matrix with params
33 | var matrix = JSON.parse(JSON.stringify(gate.matrix));
34 | matrix.map(function(row, rowIndex) {
35 | row.map(function(value, colIndex) {
36 | matrix[rowIndex][colIndex] = math.evaluate(value, params);
37 | });
38 | });
39 |
40 | it("\"" + gateName + "\" should be unitary", function() {
41 | assert(circuit.isUnitaryMatrix(matrix));
42 | });
43 | }
44 | }
45 | return true;
46 | };
47 |
48 | var checkImportExportQASM = function() {
49 | for(var gateName in circuit.basicGates) {
50 | var gate = circuit.basicGates[gateName];
51 |
52 |
53 | if(gate.matrix && gate.matrix.length) {
54 | var wires = [];
55 | for(var i = 0; i < Math.log2(gate.matrix.length); i++){
56 | wires.push(i);
57 | }
58 |
59 | var params = {};
60 | if(gate.params && gate.params.length) {
61 | gate.params.map(function(paramName) {
62 | params[paramName] = Math.PI / 5;
63 | });
64 | }
65 |
66 | var circ = new QuantumCircuit();
67 |
68 | circ.appendGate(gateName, wires, { params: params });
69 |
70 | var M1 = circ.circuitMatrix();
71 | circ.importQASM(circ.exportToQASM({ compatibilityMode: true }));
72 | var M2 = circ.circuitMatrix();
73 |
74 | it("Circuit for " + gateName + " from exportQASM should be same as original circuit", function() {
75 | assert(Math.round(circ.matrixDiff(M1, M2), 7) == 0);
76 | });
77 | }
78 | }
79 | return true;
80 | };
81 |
82 | var checkImportExportQuil = function() {
83 | for(var gateName in circuit.basicGates) {
84 | var gate = circuit.basicGates[gateName];
85 |
86 | if(gate.matrix && gate.matrix.length) {
87 | var wires = [];
88 | for(var i = 0; i < Math.log2(gate.matrix.length); i++){
89 | wires.push(i);
90 | }
91 |
92 | var params = {};
93 | if(gate.params && gate.params.length) {
94 | gate.params.map(function(paramName) {
95 | params[paramName] = Math.PI / 5;
96 | });
97 | }
98 |
99 | var circ = new QuantumCircuit();
100 |
101 | circ.appendGate(gateName, wires, { params: params });
102 |
103 | var M1 = circ.circuitMatrix();
104 | circ.importQuil(circ.exportQuil());
105 | var M2 = circ.circuitMatrix();
106 |
107 | it("Circuit for " + gateName + " from exportQuil should be same as original circuit", function() {
108 | assert(Math.round(circ.matrixDiff(M1, M2), 7) == 0);
109 | });
110 | }
111 | }
112 | return true;
113 | };
114 |
115 | var circuits = {
116 |
117 | "X": {
118 | circuit: [
119 | ["x", 0, 0]
120 | ],
121 | state: [
122 | [0, 0],
123 | [1, 0]
124 | ]
125 | },
126 |
127 | "Y": {
128 | circuit: [
129 | ["y", 0, 0]
130 | ],
131 | state: [
132 | [0, 0],
133 | [0, 1]
134 | ]
135 | },
136 |
137 | "Z": {
138 | circuit: [
139 | ["z", 0, 0]
140 | ],
141 | state: [
142 | [1, 0],
143 | [0, 0]
144 | ]
145 | },
146 |
147 | "H": {
148 | circuit: [
149 | ["h", 0, 0]
150 | ],
151 | state: [
152 | [0.70710678, 0],
153 | [0.70710678, 0]
154 | ]
155 | },
156 |
157 | "SRN": {
158 | circuit: [
159 | ["srn", 0, 0]
160 | ],
161 | state: [
162 | [0.5, 0.5],
163 | [0.5, -0.5]
164 | ]
165 | },
166 |
167 | "X-R2": {
168 | circuit: [
169 | ["x", 0, 0],
170 | ["r2", 1, 0]
171 | ],
172 | state: [
173 | [0, 0],
174 | [0, 1]
175 | ]
176 | },
177 |
178 | "X-R4": {
179 | circuit: [
180 | ["x", 0, 0],
181 | ["r4", 1, 0]
182 | ], state: [
183 | [0, 0],
184 | [0.70710678, 0.70710678]
185 | ]
186 | },
187 |
188 | "X-R8": {
189 | circuit: [
190 | ["x", 0, 0],
191 | ["r8", 1, 0]
192 | ], state: [
193 | [0, 0],
194 | [0.92387953, 0.38268343]
195 | ]
196 | },
197 |
198 | "Bell": {
199 | circuit: [
200 | ["h", 0, 0],
201 | ["cx", 1, [0, 1]]
202 | ],
203 | state: [
204 | [0.70710678, 0],
205 | [0, 0],
206 | [0, 0],
207 | [0.70710678, 0]
208 | ]
209 | }
210 | };
211 |
212 | var testCircuit = function(name, gates, expectedState) {
213 | circuit.clear();
214 |
215 | if(!gates || !gates.length) {
216 | console.log("Invalid input");
217 | return false;
218 | }
219 |
220 | for(var i = 0; i < gates.length; i++) {
221 | var gate = gates[i];
222 | if(!gate || !gate.length || gate.length < 3) {
223 | console.log("Invalid input");
224 | return false;
225 | }
226 | circuit.addGate(gate[0], gate[1], gate[2]);
227 | }
228 |
229 | circuit.run();
230 |
231 | var numRes = circuit.numAmplitudes();
232 | if(numRes > expectedState.length) {
233 | console.log("Warning: expected state provided to test is incomplette.");
234 | numRes = expectedState.length;
235 | }
236 |
237 | var gotError = false;
238 | for(var i = 0; i < numRes; i++) {
239 | var expected = expectedState[i];
240 | var state = circuit.state[i] || math.complex(0, 0);
241 |
242 | if(math.round(expected[0], 7) != math.round(state.re, 7) || math.round(expected[1], 7) != math.round(state.im, 7)) {
243 | if(!gotError) {
244 | gotError = true;
245 | console.log("ERROR");
246 | }
247 |
248 | var bin = i.toString(2);
249 | while(bin.length < circuit.numQubits) {
250 | bin = "0" + bin;
251 | }
252 |
253 | console.log("|" + bin + "> Expected: " + formatComplex2(expected[0], expected[1]) + " Got: " + formatComplex(state));
254 | }
255 | }
256 |
257 | return !gotError;
258 | };
259 |
260 | var testCircuits = function() {
261 | for(var name in circuits) {
262 | var circ = circuits[name];
263 |
264 | it("\"" + name + "\" output state should be correct", function() {
265 | assert(testCircuit(name, circ.circuit, circ.state));
266 | });
267 | }
268 | return true;
269 | };
270 |
271 |
272 | describe("Check if all gate matrices are unitary", function() {
273 | checkBasicGates();
274 | });
275 |
276 | describe("Check if import from and export to QASM works properly", function() {
277 | checkImportExportQASM();
278 | });
279 |
280 | describe("Check if import from and export to QUIL works properly", function() {
281 | checkImportExportQuil();
282 | });
283 |
284 | describe("Run circuits and check output", function() {
285 | testCircuits();
286 | });
287 |
--------------------------------------------------------------------------------
/utils/README_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | {TITLE}
2 |
3 | [quantum-circuit](https://www.npmjs.com/package/quantum-circuit) is open source quantum circuit simulator implemented in javascript. Smoothly runs 20+ qubit simulations in browser or at server (node.js). You can use it in your javascript program to run quantum simulations.
4 |
5 | Circuit can be imported from [OpenQASM](https://github.com/Qiskit/openqasm), [Quil](https://arxiv.org/abs/1608.03355) and [IONQ](https://docs.ionq.com/). You can export circuits to [OpenQASM](https://github.com/Qiskit/openqasm), [pyQuil](http://docs.rigetti.com/en/latest/index.html), [Quil](https://arxiv.org/abs/1608.03355), [Qiskit](https://qiskit.org/documentation/), [Cirq](https://github.com/quantumlib/Cirq), [TensorFlow Quantum](https://www.tensorflow.org/quantum), [QSharp](https://docs.microsoft.com/en-us/quantum/language/index?view=qsharp-preview), and [CudaQ](https://nvidia.github.io/cuda-quantum/latest/index.html), so it can be used for conversion between quantum programming languages. Circuit drawing can be exported to [SVG](https://www.w3.org/Graphics/SVG/) vector image.
6 |
7 |
8 | ## Live examples
9 |
10 | ### Quantum Programming Studio
11 |
12 | [Quantum Programming Studio](https://quantum-circuit.com) is web based quantum programming IDE and simulator built on top of this package. Circuit can be executed on real quantum computer directly from the UI.
13 |
14 | ### Other live examples
15 |
16 | - [qconvert](https://quantum-circuit.com/qconvert) Online quantum programming language converter
17 |
18 | - [example.html](https://quantum-circuit.com/example.html)
19 |
20 |
21 | ## Using in browser
22 |
23 | Simply include [quantum-circuit.min.js](dist/) into your html page (available via unpkg CDN [https://unpkg.com/quantum-circuit](https://unpkg.com/quantum-circuit))
24 |
25 | ```html
26 |
27 |
28 |
29 | Quantum Circuit Simulator Example
30 |
31 |
32 |
33 |
34 |
35 |
38 |
39 |
40 | ```
41 |
42 |
43 | ## Using at server with node.js
44 |
45 | Add [quantum-circuit](https://www.npmjs.com/package/quantum-circuit) npm module to your node.js project:
46 |
47 | ```bash
48 | npm install --save quantum-circuit
49 | ```
50 |
51 | And then import it into your program:
52 |
53 | ```javascript
54 | var QuantumCircuit = require("quantum-circuit");
55 |
56 | // Your code here
57 |
58 | ```
59 |
60 | ### Node.js examples
61 |
62 | See [/example/nodejs](example/nodejs/) directory.
63 |
64 |
65 | Using with Jupyter notebook
66 | ---------------------------
67 |
68 | You need to install [ijavascript](https://github.com/n-riesco/ijavascript) kernel for [Jupyter notebook](http://jupyter.org/)
69 |
70 | You can install quantum-circuit npm module globally and invoke jupyter notebook from any directory:
71 |
72 | ```
73 | npm install -g quantum-circuit
74 | ```
75 |
76 | Or inside new directory do:
77 |
78 | ```
79 | npm init
80 | npm install --save quantum-circuit
81 | jupyter notebook
82 | ```
83 |
84 | ### Jupyter notebook examples
85 |
86 | See [/example/jupyter](example/jupyter/) directory.
87 |
88 |
89 | # Getting started
90 |
91 | ## Create circuit
92 |
93 | Create instance of `QuantumCircuit` class, optionally passing number of qubits (wires) to constructor:
94 |
95 | ```javascript
96 | var circuit = new QuantumCircuit(3);
97 | ```
98 | *Note: number of qubits is optional argument - circuit will expand automatically if you add gates to non-existing wires*
99 |
100 |
101 | ## Add single-qubit gates
102 |
103 | Call `appendGate` method passing gate name and qubit (wire) index:
104 |
105 | ```javascript
106 | circuit.appendGate(gateName, wire, options);
107 | ```
108 |
109 | For example, to add Hadamard gate to a first qubit (wire 0) type:
110 |
111 | ```javascript
112 | circuit.appendGate("h", 0);
113 | ```
114 |
115 | For parametrized gates, provide `options` object with `params`:
116 |
117 | ```javascript
118 | circuit.appendGate("ry", 0, { "params": { "theta":"pi/2" } });
119 | ```
120 |
121 | **For more control on gate placement use `addGate` and specify a column as well:**
122 |
123 | Call `addGate` method passing gate name, column index and qubit (wire) index:
124 |
125 | ```javascript
126 | circuit.addGate(gateName, column, wire);
127 | ```
128 |
129 | For example, to add Hadamard to a second column (column 1) at first qubit (wire 0) type:
130 |
131 | ```javascript
132 | circuit.addGate("h", 1, 0);
133 | ```
134 |
135 | Result is:
136 |
137 | ```
138 |
139 | Column 0 Column 1
140 |
141 | |-----|
142 | Wire 0 --------------| H |---
143 | |-----|
144 |
145 |
146 | ```
147 |
148 | *Note: if `column` is negative integer then gate will be added to the end of the wire*
149 |
150 |
151 | ## Add multi-qubit gates
152 |
153 | Call `appendGate` method passing gate name and array of qubit indexes (wires):
154 |
155 | ```javascript
156 | circuit.appendGate(gateName, arrayOfWires);
157 | ```
158 |
159 | Example:
160 | ```javascript
161 | circuit.appendGate("cx", [0, 1]);
162 | ```
163 |
164 | For parametrized gates, provide `options` object with `params`:
165 |
166 | ```javascript
167 | circuit.appendGate("cry", [0, 1], { "params": { "theta":"pi/2" } });
168 | ```
169 |
170 | **For more control on gate placement use `addGate` and specify a column as well:**
171 |
172 |
173 | Call `addGate` method passing gate name, column index and array of connected qubits (wires):
174 |
175 | ```javascript
176 | circuit.addGate(gateName, column, arrayOfWires);
177 | ```
178 |
179 | For example, to add CNOT to a second column (column 1) controlled by second qubit (wire 1) at third qubit as target (wire 2) do:
180 |
181 | ```javascript
182 | circuit.addGate("cx", 1, [1, 2]);
183 | ```
184 |
185 | ```
186 |
187 | Column 0 Column 1
188 |
189 | Wire 0 ------------------------
190 |
191 |
192 | Wire 1 -----------------o------
193 | |
194 | |-----|
195 | Wire 2 --------------| CX |---
196 | |-----|
197 |
198 | ```
199 |
200 | *Note: if `column` is negative integer then gate will be added to the end*
201 |
202 |
203 | ## Example - Quantum random number generator
204 |
205 | ```javascript
206 |
207 | var QuantumCircuit = require("quantum-circuit");
208 |
209 | //
210 | // 8-bit quantum random number generator
211 | //
212 |
213 | var quantumRandom = function() {
214 |
215 | var circuit = new QuantumCircuit();
216 |
217 | for(var i = 0; i < 8; i++) {
218 | //
219 | // add Hadamard gate to the end (-1) of i-th wire
220 | //
221 | circuit.appendGate("h", i);
222 |
223 | //
224 | // add measurement gate to i-th qubit which will store result
225 | // into classical register "c", into i-th classical bit
226 | //
227 | circuit.addMeasure(i, "c", i);
228 | }
229 |
230 | // run circuit
231 | circuit.run();
232 |
233 | // return value of register "c"
234 | return circuit.getCregValue("c");
235 | };
236 |
237 | // Usage - print random number to terminal
238 | console.log(quantumRandom());
239 |
240 | ```
241 |
242 |
243 | ## Implemented gates
244 |
245 | {GATE_INDEX}
246 |
247 | *For more details see [gate reference](#gates)*
248 |
249 |
250 | ## Run circuit
251 |
252 | Simply call `run` method.
253 |
254 | ```javascript
255 | circuit.run();
256 | ```
257 |
258 | ## Initial state
259 |
260 | By default, initial state of each qubit is `|0>`. You can pass initial values as array of bool (`true` or `false`) or integers (`0` or `1`). This will set first two qubits to `|1>` and evaluate circuit:
261 |
262 | ```javascript
263 | circuit.run([1, 1]);
264 | ```
265 |
266 |
267 | ## Measurement
268 |
269 | Method `probabilities()` will return array of probabilities (real numbers between 0 and 1) for each qubit:
270 |
271 | ```javascript
272 | console.log(circuit.probabilities());
273 | ```
274 |
275 | Method `probability(wire)` will return probability (real number between 0 and 1) for given qubit:
276 |
277 | ```javascript
278 | console.log(circuit.probability(0));
279 | ```
280 |
281 | Method `measureAll()` returns array of chances (as integers 0 or 1) for each qubit:
282 |
283 | Example:
284 | ```javascript
285 | console.log(circuit.measureAll());
286 | ```
287 |
288 | Method `measure(wire)` returns chance (as integer 0 or 1) for given qubit:
289 |
290 | Example:
291 | ```javascript
292 | console.log(circuit.measure(0));
293 | ```
294 |
295 | You can store measurement into classical register. For example, to measure first qubit (wire 0) and store result into classical register named `c` as fourth bit (bit 3):
296 |
297 | ```javascript
298 | circuit.measure(0, "c", 3);
299 | ```
300 |
301 | You can add `measure` gate to circuit and then measurement will be done automatically and result will be stored into classical register:
302 |
303 | ```javascript
304 | circuit.addGate("measure", -1, 0, { creg: { name: "c", bit: 3 } });
305 | ```
306 |
307 | Short form of writing this is `addMeasure(wire, creg, cbit)`:
308 |
309 | ```javascript
310 | circuit.addMeasure(0, "c", 3);
311 | ```
312 |
313 | *Note:*
314 |
315 | - *Measurement gate will reset qubit to measured value only if there are gates with classical control (gates controlled by classical registers). Otherwise, measurement gate will leave qubit as is - measured value will be written to classical register and qubit will remain unchanged. This "nondestructive" behavior is handy when experimenting. However, it will automatically switches to "destructive" mode when needed (when classical control is present)*
316 |
317 | - *If specified classical register doesn't exists - it will be created automatically.*
318 |
319 |
320 | ## Classical registers
321 |
322 | **Create register**
323 |
324 | Classical registers are created automatically if you add measurement gate to the circuit but you can also manually create registers by calling `createCreg(name, len)`.
325 |
326 | Example: create classical 5-bit register named `ans`:
327 | ```javascript
328 | circuit.createCreg("ans", 5);
329 | ```
330 |
331 | **Read register**
332 |
333 | To get register value as integer, call `getCregValue(name)`.
334 |
335 | Example:
336 | ```javascript
337 | var value = circuit.getCregValue("ans");
338 | ```
339 |
340 | **Read all registers as dictionary**
341 |
342 | ```javascript
343 | var regs = circuit.getCregs();
344 | console.log(regs);
345 | ```
346 |
347 | **Read all registers as tab delimited CSV string**
348 |
349 | ```javascript
350 | var tsv = circuit.cregsAsString();
351 | console.log(tsv);
352 | ```
353 |
354 | **Read single bit**
355 |
356 | Example: get bit 3 from register named `ans`:
357 |
358 | ```javascript
359 | console.log(circuit.getCregBit("ans", 3));
360 | ```
361 | *Returns integer: 0 or 1*
362 |
363 |
364 | **Set single bit**
365 |
366 | Example: set bit 3 to `1` in register named `ans`:
367 |
368 | ```javascript
369 | circuit.setCregBit("ans", 3, 1);
370 | ```
371 |
372 | ## Control by classical register
373 |
374 | Each quatum gate in the circuit (except "measure" gate) can be controlled by classical register - gate will be executed only if classical register contains specified value. Pass `options` object as fourth argument to `addGate` method:
375 |
376 | Example:
377 | ```javascript
378 | circuit.addGate("x", -1, 0, {
379 | condition: {
380 | creg: "ans",
381 | value: 7
382 | }
383 | });
384 | ```
385 | In this example, "x" gate will execute on qubit 0 only if value of register named "ans" equals 7.
386 |
387 |
388 | ## Reset qubit
389 |
390 | You can reset qubit to value `|0>` or `|1>` with `resetQubit` method:
391 |
392 | ```javascript
393 | circuit.resetQubit(3, 0);
394 | ```
395 | In this example, qubit 3 will be set to `0|>`.
396 |
397 | *Note that all entangled qubits will be changed as well*
398 |
399 |
400 | ## View/print state vector
401 |
402 | You can get state as string with method `stateAsString(onlyPossible)`:
403 |
404 | ```javascript
405 | var s = circuit.stateAsString(false);
406 | ```
407 |
408 | If you want only possible values (only values with probability > 0) then pass `true`:
409 | ```javascript
410 | var s = circuit.stateAsString(true);
411 | ```
412 |
413 |
414 | Or, you can print state to javascript console with method `print(onlyPossible)`:
415 |
416 | ```javascript
417 | circuit.print(false);
418 | ```
419 |
420 | If you want to print only possible values (only values with probability > 0) then pass `true`:
421 | ```javascript
422 | var s = circuit.print(true);
423 | ```
424 |
425 |
426 | ## Save/Load circuit
427 |
428 | You can export circuit to javascript object (format internally used by QuantumCircuit) by calling `save` method:
429 |
430 | ```javascript
431 | var obj = circuit.save();
432 |
433 | // now do something with obj, save to file or whatever...
434 |
435 | ```
436 |
437 | And load previously saved circuit by calling `load` method:
438 |
439 | ```javascript
440 | var obj = // ...load object from file or from another circuit or whatever
441 |
442 | circuit.load(obj);
443 |
444 | ```
445 |
446 |
447 | ## Use circuit as a gate in another circuit
448 |
449 | You can "compile" any circuit and use it as a gate in another circuit like this:
450 |
451 | ```javascript
452 | // export circuit to variable
453 | var obj = someCircuit.save();
454 |
455 | // register it as a gate in another circuit
456 | anotherCircuit.registerGate("my_gate", obj);
457 |
458 | // use it as a gate in another circuit
459 | // assuming original circuit has three qubits then gate must spread to 3 qubits, in this example: 2, 3, 4)
460 | anotherCircuit.addGate("my_gate", 0, [2, 3, 4]);
461 |
462 | ```
463 |
464 |
465 | ## Decompose circuit
466 |
467 | If your circuit contains user defined gates (created from another circuit), you can decompose it into equivalent circuit containing only basic gates.
468 |
469 | If you pass `true` as argument to function `save`, you'll get decomposed circuit.
470 |
471 | Example:
472 | ```javascript
473 | var obj = circuit.save(true);
474 | // now obj contains decomposed circuit. You can load it:
475 | circuit.load(obj);
476 | ```
477 |
478 | # Import circuit
479 |
480 | ## Import from QASM
481 |
482 | Circuit can be imported from [OpenQASM](https://github.com/Qiskit/openqasm) with following limitations:
483 |
484 | - `import` directive is ignored (but gates defined in `qelib1.inc` are supported) **TODO**
485 |
486 | - `barrier` is ignored. **TODO**
487 |
488 |
489 | To import circuit from OpenQASM use `importQASM(input, errorCallback)` method:
490 |
491 | Example:
492 | ```javascript
493 | circuit.importQASM("OPENQASM 2.0;\nimport \"qelib1.inc\";\nqreg q[2];\nh q[0];\ncx q[0],q[1];\n", function(errors) {
494 | console.log(errors);
495 | });
496 | ```
497 |
498 | - `input` is string containing QASM source code.
499 |
500 | - `errorCallback` (optional) callback will be called after parsing with one argument: array containing errors or empty array on success. If no callback is provided, function will throw error if input contains errors.
501 |
502 |
503 | ## Import from QUIL
504 |
505 | Circuit can be imported from [Quil](https://arxiv.org/abs/1608.03355):
506 |
507 |
508 | To import circuit from QUIL use `importQuil(quil, errorCallback, options, qubitNames, renamedGates, lineOffset)` method:
509 |
510 | Example:
511 | ```javascript
512 | circuit.importQuil("H 0\nCNOT 0 1\n", function(errors) {
513 | console.log(errors);
514 | });
515 | ```
516 |
517 | - `quil` is string containing QUIL source code.
518 |
519 | - `errorCallback` (optional) callback will be called after parsing with one argument: array containing errors or empty array on success. If no callback is provided, function will throw error if input contains errors.
520 |
521 | - `options` (optional) function will be called after parsing with array containing syntax errors.
522 |
523 | - `qubitNames` (optional) names to be given to the qubits.
524 |
525 | - `renamedGates` (optional) custom names given to basic commands
526 |
527 | - `lineOffset` (optional) no. of spaces before a new line
528 |
529 |
530 | ## Import from Qobj
531 |
532 | Circuit can be imported from [Qobj](https://qiskit.org/documentation/apidoc/qobj.html):
533 |
534 | To import circuit from OpenQASM use `importQobj(qobj, errorCallback)` method:
535 |
536 | Example:
537 | ```javascript
538 | circuit.importQobj({"qobj_id":"qobj_WlLkcGHxihyqWGrKEZ","type":"QASM","schema_version":"1.0","experiments":[{"header":{"memory_slots":0,"n_qubits":2,"qreg_sizes":[["q",2]],"qubit_labels":[["q",0],["q",1]],"creg_sizes":[],"clbit_labels":[],"name":"circuit0","description":"text_exp"},"config":{"n_qubits":2,"memory_slots":0},"instructions":[{"name":"x","qubits":[0,1]}]}],"header":{"description":"test_circ"},"config":{"shots":1,"memory_slots":0}}, function(errors) {
539 | console.log(errors);
540 | });
541 | ```
542 |
543 | - `qobj` is Qobj JSON (`"type": "QASM"`).
544 |
545 | - `errorCallback` (optional) callback will be called after parsing with one argument: array containing errors or empty array on success. If no callback is provided, function will throw error if input contains errors.
546 |
547 |
548 | ## Import from IONQ json
549 |
550 | Circuit can be imported from [IONQ json](https://docs.ionq.com/#tag/quantum_programs):
551 |
552 |
553 | To import circuit from IONQ json use `importIonq(data, errorCallback)` method:
554 |
555 | Example:
556 | ```javascript
557 | var ionqCircuit = {
558 | "qubits": 2,
559 | "circuit": [
560 | {
561 | "gate": "h",
562 | "target": 0
563 | },
564 | {
565 | "gate": "cnot",
566 | "target": 1,
567 | "control": 0
568 | }
569 | ]
570 | };
571 |
572 | circuit.importIonq(ionqCircuit, function(errors) {
573 | console.log(errors);
574 | });
575 | ```
576 |
577 | - `data` is IONQ JSON object.
578 |
579 | - `errorCallback` (optional) callback will be called after parsing with one argument: array containing errors or empty array on success. If no callback is provided, function will throw error if input contains errors.
580 |
581 |
582 | # Export circuit
583 |
584 | ## Export to JavaScript
585 |
586 | Circuit can be exported to JavaScript with `exportJavaScript(comment, decompose, null, asJupyter)` method:
587 |
588 | Example:
589 | ```javascript
590 | var js = circuit.exportJavaScript("Comment to insert at the beginning.\nCan be multi-line comment like this one.", false);
591 | ```
592 |
593 | - `comment` - comment to insert at the beginning of the file.
594 |
595 | - `decompose` - if set to `true` and circuit contains user defined gates then it will be decomposed to basic gates and then exported. If set to `false` then user defined gates will exported as subroutines.
596 |
597 | - `asJupyter` - when this argument is `true` jupyter notebook (set to use `ijavascript` kernel) will be returned.
598 |
599 |
600 | ## Export to Qiskit (python)
601 |
602 | Circuit can be exported to [Qiskit](https://qiskit.org/documentation/) with following limitation:
603 |
604 | - User defined gates are not generated. Instead, circuit is decomposed to basic gates and exported. Effect is the same but code is less readable. **TODO**
605 |
606 | - Gates not directly supported by Qiskit are exported as-is - their definition is not generated. **TODO**
607 |
608 | To export circuit to Qiskit use `exportToQiskit(options, exportAsGateName, circuitReplacement, insideSubmodule)` method :
609 |
610 | Example:
611 | ```javascript
612 | var qiskit = circuit.exportToQiskit({comment:"Comment to insert at the beginning.\nCan be multi-line comment as this one."}, false, null, null);
613 | ```
614 | - `options` - consists of parameters for circuit export as follows:
615 |
616 | - `comment` - comment to insert at the beginning of the file.
617 |
618 | - `decompose` - if set to `true` and circuit contains user defined gates then it will be decomposed to basic gates and then exported. If set to `false` then user defined gates will exported as subroutines.
619 |
620 | - `versionStr` - Qiskit version. Can be `"0.7"`. Exports to latest supported version when empty string is provided. Remember - it is a string.
621 |
622 | - `providerName` - name of the Qiskit backend simulator provider.
623 |
624 | - `backendName` - name of the Qiskit backend simulator.
625 |
626 | - `asJupyter` - when this argument is `true` jupyter notebook will be returned.
627 |
628 | - `shots` - no. of trials.
629 |
630 | - `hybrid` - when `true` exports user defined cost function along with circuit for hybrid Quantum-Classical Algorithms
631 |
632 | - `insideSubmodule` - used internally (when `true` adds extra indent for alignment)
633 |
634 | - `exportAsGateName` - used internally (name of the custom gate containing the Qiskit circuit)
635 |
636 | - `circuitReplacement` - used internally (when `true` exports only gates in the circuit)
637 |
638 |
639 | ## Export to QASM
640 |
641 | Circuit can be exported to [OpenQASM](https://github.com/Qiskit/openqasm) with following limitation:
642 |
643 | - at the moment, gates not directly supported by QASM and qelib1.inc are exported as-is - their definition is not generated. **TODO**
644 |
645 | To export circuit to OpenQASM use `exportToQASM(options, exportAsGateName, circuitReplacement, insideSubmodule)` method:
646 |
647 | Example:
648 | ```javascript
649 | var qasm = circuit.exportToQASM({comment:"Comment to insert at the beginning.\nCan be multi-line comment as this one."}, false);
650 | ```
651 | - `options` - consists of parameters for circuit export as follows:
652 |
653 | - `comment` - comment to insert at the beginning of the file.
654 |
655 | - `decompose` - if set to `true` and circuit contains user defined gates then it will be decomposed to basic gates and then exported. If set to `false` then user defined gates will exported as subroutines.
656 |
657 | - `compatibilityMode` - if set to `true` exports the circuit in compatible mode
658 |
659 | - `insideSubmodule` - when `true` adds extra indent for alignment
660 |
661 | - `exportAsGateName` - name of the custom gate containing the Qiskit circuit.
662 |
663 | - `circuitReplacement` - when `true` exports only gates in the circuit
664 |
665 |
666 |
667 | ## Export to pyQuil (python)
668 |
669 | Circuit can be exported to [pyQuil](http://docs.rigetti.com/en/latest/index.html)
670 |
671 | To export circuit to pyQuil use `exportToPyquil(options, exportAsGateName)` method:
672 |
673 | Example:
674 | ```javascript
675 | var qasm = circuit.exportToPyquil({comment:"Comment to insert at the beginning.\nCan be multi-line comment as this one."}, false);
676 | ```
677 | - `options` - consists of parameters for circuit export as follows:
678 |
679 | - `comment` - comment to insert at the beginning of the file.
680 |
681 | - `decompose` - if set to `true` and circuit contains user defined gates then it will be decomposed to basic gates and then exported. If set to `false` then user defined gates will exported as subroutines.
682 |
683 | - `versionStr` - pyQuil version. Can be `"1.9"`, `"2.0"` or `"2.1"`. Exports to latest supported version when empty string is provided. Remember - it is a string.
684 |
685 | - `lattice` - You can optionally pass then name of the lattice.
686 |
687 | - `asQVM` - If this argument is `true` (and if `lattice` is specified) then produced code will run on QVM mimicking running on QPU. Otherwise, produced code will run on QPU.
688 |
689 | - `asJupyter` - when this argument is `true` jupyter notebook will be returned.
690 |
691 | - `shots` - no. of trials.
692 |
693 | - `hybrid` - when `true` exports user defined cost function along with circuit for hybrid Quantum-Classical Algorithms
694 |
695 | - `exportAsGateName` - name of the custom gate containing the Pyquil circuit.
696 |
697 |
698 | ## Export to Quil
699 |
700 | Circuit can be exported to [Quil](https://arxiv.org/abs/1608.03355)
701 |
702 | To export circuit to Quil use `exportToQuil(options, exportAsGateName)` method:
703 |
704 | Example:
705 | ```javascript
706 | var quil = circuit.exportToQuil({comment:"Comment to insert at the beginning.\nCan be multi-line comment as this one."}, false);
707 | ```
708 | - `options` - consists of parameters for circuit export as follows:
709 |
710 | - `comment` - comment to insert at the beginning of the file.
711 |
712 | - `decompose` - if set to `true` and circuit contains user defined gates then it will be decomposed to basic gates and then exported. If set to `false` then user defined gates will exported as subroutines.
713 |
714 | - `versionStr` - pyQuil version. Can be `"1.9"`, `"2.0"` or `"2.1"`. Exports to latest supported version when empty string is provided. Remember - it is a string.
715 |
716 | - `exportAsGateName` - name of the custom gate containing the Pyquil circuit.
717 |
718 |
719 |
720 | ## Export to Cirq (python)
721 |
722 | Circuit can be exported to [Cirq](https://github.com/quantumlib/Cirq) with following limitation:
723 |
724 | - Gates not directly supported by Cirq are exported as-is - their definition is not generated. **TODO**
725 |
726 | - Classical control is ignored (comment with warning is generated). **TODO**
727 |
728 | To export circuit to Cirq use `exportToCirq(options, exportAsGateName)` method:
729 |
730 | Example:
731 | ```javascript
732 | var cirq = circuit.exportToCirq({comment:"Comment to insert at the beginning.\nCan be multi-line comment as this one."}, false);
733 | ```
734 | - `options` - consists of parameters for circuit export as follows:
735 |
736 | - `comment` - comment to insert at the beginning of the file.
737 |
738 | - `decompose` - if set to `true` and circuit contains user defined gates then it will be decomposed to basic gates and then exported. If set to `false` then user defined gates will exported as subroutines.
739 |
740 | - `versionStr` - Cirq version. Can be `"0.5"` or empty string. Exports to latest supported version when empty string is provided. Remember - it is a string.
741 |
742 | - `asJupyter` - when this argument is `true` jupyter notebook will be returned.
743 |
744 | - `shots` - no. of trials.
745 |
746 | - `exportTfq` - if set to `true` the export function will export circuit to Tensorflow Quantum.
747 |
748 | - `exportAsGateName` - name of the custom gate containing the Cirq circuit.
749 |
750 |
751 | ## Export to C/C++ (QuEST)
752 |
753 | Circuit can be exported to [QuEST](https://quest.qtechtheory.org/)
754 |
755 | To export circuit to QuEST use `exportQuEST(newOptions, exportAsGateName, definedFunc)` method:
756 |
757 | Example:
758 | ```javascript
759 | var quest = circuit.exportToQuEST("Comment to insert at the beginning.\nCan be multi-line comment as this one.", false);
760 | ```
761 |
762 | - `options` - consists of parameters for circuit export as follows:
763 |
764 | - `comment` - comment to insert at the beginning of the file.
765 |
766 | - `decompose` - if set to `true` and circuit contains user defined gates then it will be decomposed to basic gates and then exported. If set to `false` then user defined gates will exported as subroutines.
767 |
768 | - `exportAsGateName` - name of the custom gate containing the Cirq circuit.
769 |
770 | - `definedFunc` - list of gates that must be present in the defined function
771 |
772 |
773 |
774 | ## Export to Q# (QSharp)
775 |
776 | Circuit can be exported to [Q#](https://docs.microsoft.com/en-us/quantum/language/index?view=qsharp-preview).
777 |
778 | To export circuit to Q# use `exportQSharp(options, exportAsGateName)` method:
779 |
780 | Example:
781 | ```javascript
782 | var qsharp = circuit.exportQSharp("Comment to insert at the beginning.\nCan be multi-line comment as this one.", false, null, null, false, null);
783 | ```
784 |
785 | - `options` - consists of parameters for circuit export as follows:
786 |
787 | - `comment` - comment to insert at the beginning of the file.
788 |
789 | - `decompose` - if set to `true` and circuit contains user defined gates then it will be decomposed to basic gates and then exported. If set to `false` then user defined gates will exported as subroutines.
790 |
791 | - `versionStr` - QSharp version. Can be `"0.1"` or empty string. Exports to latest supported version when empty string is provided. Remember - it is a string.
792 |
793 | - `asJupyter` - when this argument is `true` jupyter notebook (set to use qsharp kernel) will be returned.
794 |
795 | - `circuitName` - Name of the circuit that is being exported to QSharp. By default set to `"Circuit"`
796 |
797 | - `indentDepth` - The no. of tabs to be put before a Python line of code.
798 |
799 | - `exportAsGateName` - name of the custom gate containing the QSharp circuit.
800 |
801 |
802 | ## Export to Qobj
803 |
804 | Circuit can be exported to [Qobj](https://qiskit.org/documentation/apidoc/qobj.html):
805 |
806 | To export circuit to Qiskit use `exportToQobj(options, circuitReplacement)` method :
807 |
808 | Example:
809 | ```javascript
810 | var qobj = circuit.exportToQobj({circuitName:"new_circuit"}, false);
811 | ```
812 | - `options` - consists of parameters for circuit export as follows:
813 |
814 | - `circuitName` - name of the circuit that is being exported to Qobj
815 |
816 | - `experimentName` - name of the experiment that describes the number of memory slots, qubits, qubit names, classical bit names etc.
817 |
818 | - `numShots` - no. of trials.
819 |
820 | - `circuitReplacement` - when `true` exports only gates in the circuit
821 |
822 |
823 | ## Export to TensorFlow Quantum (python)
824 |
825 | Circuit can be exported to [Tensorflow Quantum](https://www.tensorflow.org/quantum):
826 |
827 | To export circuit to TFQ use `exportToTFQ(options, exportAsGateName)` method :
828 |
829 | Example:
830 | ```javascript
831 | var tfq = circuit.exportToTFQ({comment:"Comment to insert at the beginning.\nCan be multi-line comment as this one."}, false);
832 | ```
833 | - `options` - consists of parameters for circuit export as follows:
834 |
835 | - `comment` - comment to insert at the beginning of the file.
836 |
837 | - `decompose` - if set to `true` and circuit contains user defined gates then it will be decomposed to basic gates and then exported. If set to `false` then user defined gates will exported as subroutines.
838 |
839 | - `versionStr` - TFQ version. Exports to latest supported version when empty string is provided. Remember - it is a string.
840 |
841 | - `asJupyter` - when this argument is `true` jupyter notebook will be returned.
842 |
843 | - `shots` - no. of trials.
844 |
845 | - `exportAsGateName` - name of the custom gate containing the TFQ circuit.
846 |
847 |
848 | ## Export to Braket (python)
849 |
850 | Circuit can be exported to [Braket](https://docs.aws.amazon.com/braket/):
851 |
852 | To export circuit to Braket use `exportToBraket(options, exportAsGateName)` method :
853 |
854 | Example:
855 | ```javascript
856 | var braket = circuit.exportToBraket({comment:"Comment to insert at the beginning.\nCan be multi-line comment as this one."}, false);
857 | ```
858 | - `options` - consists of parameters for circuit export as follows:
859 |
860 | - `comment` - comment to insert at the beginning of the file.
861 |
862 | - `decompose` - if set to `true` and circuit contains user defined gates then it will be decomposed to basic gates and then exported. If set to `false` then user defined gates will exported as subroutines.
863 |
864 | - `versionStr` - Braket version. Exports to latest supported version when empty string is provided. Remember - it is a string.
865 |
866 | - `asJupyter` - when this argument is `true` jupyter notebook will be returned.
867 |
868 | - `shots` - no. of trials.
869 |
870 | - `indentDepth` - The no. of tabs to be put before a Python line of code.
871 |
872 | - `hybrid` - when `true` exports user defined cost function along with circuit for hybrid Quantum-Classical Algorithms
873 |
874 | - `exportAsGateName` - name of the custom gate containing the Braket circuit.
875 |
876 |
877 | ## Export to pyAQASM (python)
878 |
879 | Circuit can be exported to [pyAQASM](https://myqlm.github.io/):
880 |
881 | To export circuit to pyAQASM use `exportToPyAQASM(options, exportAsGateName)` method :
882 |
883 | Example:
884 | ```javascript
885 | var pyAqasm = circuit.exportToPyAQASM({comment:"Comment to insert at the beginning.\nCan be multi-line comment as this one."}, false);
886 | ```
887 | - `options` - consists of parameters for circuit export as follows:
888 |
889 | - `comment` - comment to insert at the beginning of the file.
890 |
891 | - `decompose` - if set to `true` and circuit contains user defined gates then it will be decomposed to basic gates and then exported. If set to `false` then user defined gates will exported as subroutines.
892 |
893 | - `asJupyter` - when this argument is `true` jupyter notebook will be returned.
894 |
895 | - `shots` - no. of trials.
896 |
897 | - `hybrid` - when `true` exports user defined cost function along with circuit for hybrid Quantum-Classical Algorithms
898 |
899 | - `exportAsGateName` - name of the custom gate containing the pyAQASM circuit.
900 |
901 |
902 | ## Export to AQASM
903 |
904 | Circuit can be exported to [AQASM](https://myqlm.github.io/aqasm.html):
905 |
906 | To export circuit to AQASM use `exportToAQASM(options, isExportPyAQASM, exportAsGateName, indentDepth)` method :
907 |
908 | Example:
909 | ```javascript
910 | var aqasm = circuit.exportToAQASM({comment:"Comment to insert at the beginning.\nCan be multi-line comment as this one."}, false);
911 | ```
912 | - `options` - consists of parameters for circuit export as follows:
913 |
914 | - `comment` - comment to insert at the beginning of the file.
915 |
916 | - `decompose` - if set to `true` and circuit contains user defined gates then it will be decomposed to basic gates and then exported. If set to `false` then user defined gates will exported as subroutines.
917 |
918 | - `asJupyter` - when this argument is `true` jupyter notebook will be returned.
919 |
920 | - `shots` - no. of trials.
921 |
922 | - `hybrid` - when `true` exports user defined cost function along with circuit for hybrid Quantum-Classical Algorithms
923 |
924 | - `isExportPyAQASM` - if `true`, this function will be used to export to pyAQASM instead of AQASM.
925 |
926 | - `exportAsGateName` - name of the custom gate containing the AQASM circuit.
927 |
928 | - `indentDepth` - The no. of tabs to be put before a Python line of code.
929 |
930 |
931 |
932 | ## Export to CudaQ (python)
933 |
934 | Circuit can be exported to [CudaQ](https://nvidia.github.io/cuda-quantum/latest/index.html)
935 |
936 | To export circuit to CudaQ use `exportToCudaQ(options, exportAsGateName, circuitReplacement, insideSubmodule)` method :
937 |
938 | Example:
939 | ```javascript
940 | var cudaq = circuit.exportToCudaQ({comment:"Comment to insert at the beginning.\nCan be multi-line comment as this one."}, false, null, null);
941 | ```
942 |
943 | - `options` - consists of parameters for circuit export as follows:
944 |
945 | - `comment` - comment to insert at the beginning of the file.
946 |
947 | - `decompose` - if set to `true` and circuit contains user defined gates then it will be decomposed to basic gates and then exported. If set to `false` then user defined gates will exported as subroutines.
948 |
949 | - `backendName` - name of the CudaQ backend.
950 |
951 | - `asJupyter` - when this argument is `true` jupyter notebook will be returned.
952 |
953 | - `shots` - number of shots (if code is sampling).
954 |
955 | - `hybrid` - when `true` exports user defined cost function along with circuit for hybrid Quantum-Classical Algorithms
956 |
957 | - `insideSubmodule` - used internally (when `true` adds extra indent for alignment)
958 |
959 | - `exportAsGateName` - used internally (name of the custom gate containing the CudaQ circuit)
960 |
961 | - `circuitReplacement` - used internally (when `true` exports only gates in the circuit)
962 |
963 |
964 |
965 |
966 | ## Export to SVG
967 |
968 | Vector `.svg` image of circuit can be created with `exportSVG(embedded)` function with following limitations:
969 |
970 | - Gate symbols are non-standard. **TODO** *(BTW, do we have standard?)*
971 |
972 |
973 | **Example 1**
974 |
975 | Show circuit in browser:
976 |
977 | ```javascript
978 |
979 | // Assuming we have somewhere in HTML
980 | var container = document.getElementById("drawing");
981 |
982 | // SVG is returned as string
983 | var svg = circuit.exportSVG(true);
984 |
985 | // add SVG into container
986 | container.innerHTML = svg;
987 |
988 | ```
989 |
990 | **Example 2**
991 |
992 | Generate standalone SVG image at server with node.js:
993 |
994 | ```javascript
995 |
996 | // export as standalone SVG
997 | var svg = circuit.exportSVG(false);
998 |
999 | // do something with svg string (e.g. save to file)
1000 | ...
1001 |
1002 | // Or, export as embedded SVG for use in browser
1003 | svg = circuit.exportSVG(true);
1004 |
1005 | // do something with svg string (e.g. serve via HTTP)
1006 | ...
1007 |
1008 | ```
1009 |
1010 |
1011 | ## Export to Quirk
1012 |
1013 | Circuit can be exported to popular open-source drag-and-drop quantum circuit simulator [Quirk](https://algassert.com/quirk) with following limitations:
1014 |
1015 | - Quirk doesn't support more than 16 qubits.
1016 |
1017 | - Quirk can possibly incorrectly interpret circuit if we have multiple controlled gates in the same column.
1018 |
1019 | - Quirk doesn't support non-sequentially positioned multi-qubit user-defined gates (for example gate on wires [3, 0, 1]) so it's best to export decomposed circuit.
1020 |
1021 |
1022 | Example:
1023 |
1024 | ```javascript
1025 |
1026 | var quirkData = circuit.exportQuirk(true);
1027 |
1028 | var quirkURL = "http://algassert.com/quirk#circuit=" + JSON.stringify(quirkData);
1029 |
1030 | // Now do something with quirkURL. Assuming this code runs in browser and we have somewhere, you can:
1031 | var quirkLink = document.getElementById("quirk");
1032 | quirkLink.setAttr("href", quirkLink);
1033 |
1034 | ```
1035 |
1036 |
1037 | # About simulator algorithm
1038 |
1039 | Memory usage: up to `2 * (2^numQubits) * sizeOfComplexNumber`
1040 |
1041 |
1042 | - Naive implementation stores entire state vector in an array of size `2^numQubits`. We are storing state in a "map", and only amplitudes with non-zero probabilities are stored. So, in worst case, size of state map is `2^n`, but it's less most of the time because we don't store zeroes.
1043 |
1044 | - Naive implementation creates transformation matrix and multiplies it with state vector. We are not creating and not storing entire transformation matrix in memory. Instead, elements of transformation matrix are calculated one by one and state is multiplied and stored in new state map on the fly. This way, memory usage is minimal (in worst case we have two `2^n` state vectors at a time).
1045 |
1046 | - Algorithm is parallelizable so it could use GPU, but GPU support is not implemented yet (work in progress).
1047 |
1048 |
1049 | ## Benchmark
1050 |
1051 | *Performance is measured on MacBook Pro MJLT2 mid-2015 (Core i7 2.5 GHz, 16GB RAM)*
1052 |
1053 | 
1054 |
1055 | 
1056 |
1057 | 
1058 |
1059 | *You can find scripts in [/benchmark](benchmark/) directory.*
1060 |
1061 |
1062 | # Gates
1063 |
1064 | {GATE_REFERENCE}
1065 |
1066 |
1067 | # API docs
1068 |
1069 | {API_DOCS}
1070 |
1071 |
1072 | # License
1073 | [MIT](LICENSE.txt)
1074 |
--------------------------------------------------------------------------------
/utils/export_gatedefs.js:
--------------------------------------------------------------------------------
1 | var QuantumCircuit = require("../lib/quantum-circuit.js");
2 |
3 | var circuit = new QuantumCircuit();
4 |
5 | console.log(JSON.stringify(circuit.basicGates, null, "\t"));
6 |
--------------------------------------------------------------------------------
/utils/generate_readme.js:
--------------------------------------------------------------------------------
1 | var fs = require("fs");
2 | var path = require("path");
3 | var url = require("url");
4 |
5 | var QuantumCircuit = require("../lib/quantum-circuit.js");
6 |
7 | var escapeRegExp = function(string) {
8 | return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
9 | };
10 |
11 | var extractMarkdownLinks = function(s) {
12 | var res = [];
13 | var regex1 = /\[([^\[]+)\]\(([^\)]+)\)/g;
14 | while((array1 = regex1.exec(s)) !== null) {
15 | res.push({
16 | full: array1[0],
17 | title: array1[1],
18 | link: array1[2],
19 | index: array1.index
20 | });
21 | }
22 | return res;
23 | };
24 |
25 | var convertRelativeLinksToAbsolute = function(s, baseURL) {
26 | var res = "";
27 | var links = extractMarkdownLinks(s);
28 | var pos = 0;
29 | links.map(function(link) {
30 | res += s.substring(pos, link.index);
31 |
32 | var newlink = link.full;
33 | if(link.link && link.link.indexOf("#") < 0 && link.link.indexOf("http://") < 0 && link.link.indexOf("https://") < 0) {
34 | newlink = link.full.replace(/\((.+?)\)/g, "(" + url.resolve(baseURL, link.link) + ")");
35 | }
36 |
37 | res += newlink;
38 | pos = link.index + link.full.length;
39 | });
40 | return res;
41 | };
42 |
43 | fs.readFile( path.join(__dirname, "README_TEMPLATE.md"), function (err, data) {
44 | if(err) {
45 | throw err;
46 | return;
47 | }
48 |
49 | var circ = new QuantumCircuit();
50 |
51 | var readme = data.toString();
52 |
53 | var gateIndex = "";
54 | var gateRef = "";
55 | gateIndex += "| Name | pyQuil | Cirq | Q# | IONQ | Qubits | Params | Description |\n";
56 | gateIndex += "| --- | --- | --- | --- | --- | --- | --- | --- |\n";
57 | for(var gateName in circ.basicGates) {
58 | var gateDef = circ.basicGates[gateName];
59 | var numQubits = Math.log2(gateDef.matrix && gateDef.matrix.length ? gateDef.matrix.length : 2);
60 | var pyquilDef = (gateDef.exportInfo ? (gateDef.exportInfo.pyquil || gateDef.exportInfo.quil) : null) || null;
61 | var cirqDef = (gateDef.exportInfo ? gateDef.exportInfo.cirq : null) || null;
62 | var qsharpDef = (gateDef.exportInfo ? gateDef.exportInfo.qsharp : null) || null;
63 | var ionqDef = (gateDef.exportInfo ? gateDef.exportInfo.ionq : null) || null;
64 | var params = gateDef.params || [];
65 | var paramList = "";
66 | if(gateDef.params && gateDef.params.length) {
67 | gateDef.params.map(function(paramName, paramIndex) {
68 | if(paramIndex > 0) {
69 | paramList += ", ";
70 | }
71 | paramList += paramName;
72 | });
73 | }
74 |
75 | // ---
76 | // gate index
77 | // ---
78 | var pyquilName = pyquilDef ? (pyquilDef.array ? "def " + (pyquilDef.name || "") : (pyquilDef.name || "")) : "";
79 | if(pyquilDef && pyquilDef.replacement) {
80 | var gdef = circ.basicGates[pyquilDef.replacement.name] || null;
81 | if(gdef) {
82 | var pdef = (gdef.exportInfo ? (gdef.exportInfo.pyquil || gdef.exportInfo.quil) : null) || null;
83 | if(pdef) {
84 | pyquilName = pdef.name || "";
85 | if(pyquilDef.replacement.params) {
86 | pyquilName += "(";
87 | var pcount = 0;
88 | for(var pname in pyquilDef.replacement.params) {
89 | if(pcount) {
90 | pyquilName += ", ";
91 | }
92 | pyquilName += pyquilDef.replacement.params[pname];
93 | }
94 | pyquilName += ")";
95 | }
96 | }
97 | }
98 | }
99 |
100 | var cirqName = cirqDef ? (cirqDef.array ? "def " + (cirqDef.name || "") : (cirqDef.name || "")) : "";
101 | if(cirqDef && cirqDef.replacement) {
102 | var gdef = circ.basicGates[cirqDef.replacement.name] || null;
103 | if(gdef) {
104 | var pdef = (gdef.exportInfo ? gdef.exportInfo.cirq : null) || null;
105 | if(pdef) {
106 | cirqName = pdef.name || "";
107 | if(cirqDef.replacement.params) {
108 | cirqName += "(";
109 | var pcount = 0;
110 | for(var pname in cirqDef.replacement.params) {
111 | if(pcount) {
112 | cirqName += ", ";
113 | }
114 | cirqName += cirqDef.replacement.params[pname];
115 | }
116 | cirqName += ")";
117 | }
118 | }
119 | }
120 | }
121 |
122 | var qsharpName = qsharpDef ? (qsharpDef.array ? ""/*"def " + (qsharpDef.name || "")*/ : (qsharpDef.name || "")) : "";
123 | if(qsharpDef && qsharpDef.replacement) {
124 | var gdef = circ.basicGates[qsharpDef.replacement.name] || null;
125 | if(gdef) {
126 | var pdef = (gdef.exportInfo ? gdef.exportInfo.qsharp : null) || null;
127 | if(pdef) {
128 | qsharpName = pdef.name || "";
129 | if(qsharpDef.replacement.params) {
130 | qsharpName += "(";
131 | var pcount = 0;
132 | for(var pname in qsharpDef.replacement.params) {
133 | if(pcount) {
134 | qsharpName += ", ";
135 | }
136 | qsharpName += qsharpDef.replacement.params[pname];
137 | }
138 | qsharpName += ")";
139 | }
140 | }
141 | }
142 | }
143 |
144 | var ionqName = ionqDef ? (ionqDef.array ? "def " + (ionqDef.name || "") : (ionqDef.name ? ionqDef.name : (ionqDef.names ? ionqDef.names[0] : ""))) : "";
145 | if(ionqDef && ionqDef.replacement) {
146 | var gdef = circ.basicGates[ionqDef.replacement.name] || null;
147 | if(gdef) {
148 | var pdef = (gdef.exportInfo ? gdef.exportInfo.ionq : null) || null;
149 | if(pdef) {
150 | ionqName = pdef.name || "";
151 | if(ionqDef.replacement.params) {
152 | ionqName += "(";
153 | var pcount = 0;
154 | for(var pname in ionqDef.replacement.params) {
155 | if(pcount) {
156 | ionqName += ", ";
157 | }
158 | ionqName += ionqDef.replacement.params[pname];
159 | }
160 | ionqName += ")";
161 | }
162 | }
163 | }
164 | }
165 |
166 | gateIndex += "| **" + gateName + "**";
167 | gateIndex += " | " + pyquilName;
168 | gateIndex += " | " + cirqName;
169 | gateIndex += " | " + qsharpName;
170 | gateIndex += " | " + ionqName;
171 | gateIndex += " | " + numQubits;
172 | gateIndex += " | " + paramList;
173 | gateIndex += " | " + (gateDef.description || "");
174 | gateIndex += " |\n";
175 | // ---
176 |
177 | // ---
178 | // gate reference
179 | // ---
180 | gateRef += "## " + gateName + "\n";
181 | if(gateDef.description) {
182 | gateRef += "\n" + gateDef.description + "\n";
183 | }
184 |
185 | gateRef += "\n**Qubits:** " + numQubits + "\n";
186 |
187 | if(params.length) {
188 | gateRef += "\n**Parameters:**\n\n";
189 | params.map(function(paramName) {
190 | gateRef += "- " + paramName + "\n";
191 | });
192 | gateRef += "\n";
193 | }
194 | if(gateDef.matrix && gateDef.matrix.length) {
195 | gateRef += "\n**Matrix:**\n";
196 | gateRef += "```javascript\n";
197 | gateRef += "[\n";
198 | gateDef.matrix.map(function(row, rowIndex) {
199 | if(rowIndex > 0) {
200 | gateRef += ",";
201 | }
202 | gateRef += "\n " + JSON.stringify(row);
203 | });
204 | gateRef += "\n]\n";
205 | gateRef += "```\n";
206 | }
207 |
208 | gateRef += "\n**Example:**\n";
209 | gateRef += "```javascript\n";
210 | gateRef += "circuit.appendGate(\"" + gateName + "\", ";
211 | if(numQubits == 1) {
212 | gateRef += "0";
213 | } else {
214 | gateRef += "[";
215 | for(var i = 0; i < numQubits; i++) {
216 | if(i > 0) {
217 | gateRef += ", ";
218 | }
219 | gateRef += i;
220 | }
221 | gateRef += "]";
222 | }
223 |
224 | if(gateName == "measure") {
225 | gateRef += ", {\n";
226 | gateRef += " creg: {\n";
227 | gateRef += " name: \"c\",\n";
228 | gateRef += " bit: 3\n";
229 | gateRef += " }\n";
230 | gateRef += "}";
231 | } else {
232 | if(params.length) {
233 | gateRef += ", {\n";
234 | gateRef += " params: {";
235 | params.map(function(paramName, paramIndex) {
236 | if(paramIndex > 0) {
237 | gateRef += ",";
238 | }
239 | gateRef += "\n";
240 | gateRef += " " + paramName + ": \"pi/2\"";
241 | });
242 | gateRef += "\n }\n";
243 | gateRef += "}";
244 | }
245 | }
246 | gateRef += ");\n";
247 | gateRef += "```\n";
248 |
249 | if(gateName == "measure") {
250 | gateRef += "\n**Or:**\n"
251 | gateRef += "```javascript\n";
252 | gateRef += "circuit.addMeasure(0, \"c\", 3);\n";
253 | gateRef += "```\n"
254 | }
255 |
256 | gateRef += "\n";
257 | // ---
258 | }
259 |
260 | var apiDocs = "*To be written...*";
261 |
262 | readme = readme.replace(new RegExp(escapeRegExp("{TITLE}"), "g"), "# Quantum Circuit Simulator");
263 | readme = readme.replace(new RegExp(escapeRegExp("{GATE_INDEX}"), "g"), gateIndex);
264 | readme = readme.replace(new RegExp(escapeRegExp("{GATE_REFERENCE}"), "g"), gateRef);
265 | readme = readme.replace(new RegExp(escapeRegExp("{API_DOCS}"), "g"), apiDocs);
266 |
267 | fs.writeFile(path.join(path.join(__dirname, "../"), "README.md"), readme, function(err) {
268 | if(err) {
269 | throw err;
270 | return;
271 | }
272 | console.log("README.md is written.");
273 | });
274 | });
275 |
--------------------------------------------------------------------------------