├── .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 | Quantum Circuit Simulator Example 5 | 6 | 7 | 8 |
Examples
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | 24 |
25 |
26 |
27 | 28 | 29 | 30 | 33 | 34 | 35 | 372 | 373 | 374 | -------------------------------------------------------------------------------- /example/browser/example_cudaq.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Quantum Circuit Simulator Example 5 | 6 | 7 | 8 | 9 | 10 | 100 | 101 | -------------------------------------------------------------------------------- /example/browser/transform.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Transform 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 |
13 |
14 |

Transformation matrix playground

15 |
16 |
17 | 18 |
19 |
20 |
21 |
22 | 23 | 24 |
25 | 26 |
27 | 28 | 35 |
36 | 37 |
38 | 39 | 40 |
41 | 42 |
43 | 47 |
48 | 49 |
50 | 54 |
55 | 56 | 57 |
58 |
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 | "H" 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 | ![Benchmark 1](https://rawgit.com/perak/quantum-circuit/HEAD/media/benchmark1.png) 1054 | 1055 | ![Benchmark 2](https://rawgit.com/perak/quantum-circuit/HEAD/media/benchmark2.png) 1056 | 1057 | ![Benchmark 3](https://rawgit.com/perak/quantum-circuit/HEAD/media/benchmark3.png) 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 | --------------------------------------------------------------------------------