├── LICENSE ├── README.md ├── circuit_weaver ├── GruntFile.js ├── PuppeteerRunTests.js ├── PuppeteerScreenshotCircuit.js ├── README_CN.md ├── doc │ ├── MANUAL_amp-display.png │ ├── MANUAL_bloch-display.png │ ├── MANUAL_chance-display.png │ ├── MANUAL_circuit-editing-area.png │ ├── MANUAL_controlled-display.png │ ├── MANUAL_controlled-epr-display.png │ ├── MANUAL_density-display.png │ ├── MANUAL_measurement-types.png │ ├── MANUAL_menu.png │ ├── MANUAL_state-channel-duality.png │ ├── MANUAL_various-displays.png │ ├── README_Demo.gif │ ├── README_Grover.gif │ ├── README_Teleportation.gif │ └── favicon.ico ├── html │ ├── error.partial.html │ ├── export.partial.html │ ├── forge.partial.html │ ├── menu.partial.html │ └── quirk.template.html ├── karma.test.conf.js ├── karma.test_perf.conf.js ├── out │ └── CircuitWeaver.html ├── package.json ├── src │ ├── Config.js │ ├── browser │ │ ├── Clipboard.js │ │ ├── EventUtil.js │ │ ├── HistoryPusher.js │ │ ├── MouseWatcher.js │ │ ├── Polyfills.js │ │ ├── SaveFile.js │ │ └── TouchScrollBlocker.js │ ├── circuit │ │ ├── CircuitComputeUtil.js │ │ ├── CircuitDefinition.js │ │ ├── CircuitEvalContext.js │ │ ├── CircuitShaders.js │ │ ├── CircuitStats.js │ │ ├── Controls.js │ │ ├── CustomGateSet.js │ │ ├── Gate.js │ │ ├── GateCheckArgs.js │ │ ├── GateColumn.js │ │ ├── GateShaders.js │ │ ├── KetShaderUtil.js │ │ ├── KetTextureUtil.js │ │ └── Serializer.js │ ├── draw │ │ ├── CachablePainting.js │ │ ├── GateDrawParams.js │ │ ├── GatePainting.js │ │ ├── MathPainter.js │ │ ├── Painter.js │ │ └── WidgetPainter.js │ ├── fallback.js │ ├── gates │ │ ├── AllGates.js │ │ ├── AmplitudeDisplay.js │ │ ├── ArithmeticGates.js │ │ ├── BitCountGates.js │ │ ├── BlochSphereDisplay.js │ │ ├── ComparisonGates.js │ │ ├── Controls.js │ │ ├── CountingGates.js │ │ ├── CycleBitsGates.js │ │ ├── Debug_ErrorInjectionGate.js │ │ ├── DensityMatrixDisplay.js │ │ ├── Detector.js │ │ ├── ExponentiatingGates.js │ │ ├── FourierTransformGates.js │ │ ├── HalfTurnGates.js │ │ ├── Impossible_UniversalNotGate.js │ │ ├── IncrementGates.js │ │ ├── InputGates.js │ │ ├── InterleaveBitsGates.js │ │ ├── Joke_ImaginaryGate.js │ │ ├── Joke_MysteryGate.js │ │ ├── Joke_NeGate.js │ │ ├── Joke_ZeroGate.js │ │ ├── MeasurementGate.js │ │ ├── ModularAdditionGates.js │ │ ├── ModularIncrementGates.js │ │ ├── ModularMultiplicationGates.js │ │ ├── ModularMultiplyAccumulateGates.js │ │ ├── MultiplicationGates.js │ │ ├── MultiplyAccumulateGates.js │ │ ├── ParametrizedRotationGates.js │ │ ├── PhaseGradientGates.js │ │ ├── PivotFlipGates.js │ │ ├── PostSelectionGates.js │ │ ├── PoweringGates.js │ │ ├── ProbabilityDisplay.js │ │ ├── QuarterTurnGates.js │ │ ├── ReverseBitsGate.js │ │ ├── SampleDisplay.js │ │ ├── SpacerGate.js │ │ ├── SwapGateHalf.js │ │ ├── VariousXGates.js │ │ ├── VariousYGates.js │ │ ├── VariousZGates.js │ │ └── XorGates.js │ ├── issues.js │ ├── main.js │ ├── math │ │ ├── Axis.js │ │ ├── Complex.js │ │ ├── FormulaParser.js │ │ ├── Matrix.js │ │ ├── Point.js │ │ └── Rect.js │ ├── ui │ │ ├── DisplayedCircuit.js │ │ ├── DisplayedInspector.js │ │ ├── DisplayedToolbox.js │ │ ├── Hand.js │ │ ├── clear.js │ │ ├── exports.js │ │ ├── forge.js │ │ ├── menu.js │ │ ├── sim.js │ │ ├── title.js │ │ ├── undo.js │ │ └── url.js │ └── webgl │ │ ├── ShaderCoders.js │ │ ├── ShaderCoders_Base.js │ │ ├── ShaderCoders_intoBytes.js │ │ ├── ShaderCoders_intoFloats.js │ │ ├── Shaders.js │ │ ├── WglArg.js │ │ ├── WglConfiguredShader.js │ │ ├── WglContext.js │ │ ├── WglMortalValueSlot.js │ │ ├── WglShader.js │ │ ├── WglTexture.js │ │ ├── WglTexturePool.js │ │ ├── WglTextureTrader.js │ │ └── WglUtil.js ├── test │ ├── CircuitOperationTestUtil.js │ ├── KarmaTestRunner.test.js │ ├── TestUtil.js │ ├── circuit │ │ ├── CircuitComputeUtil.test.js │ │ ├── CircuitDefinition.test.js │ │ ├── CircuitShaders.test.js │ │ ├── CircuitStats.test.js │ │ ├── Controls.test.js │ │ ├── Gate.test.js │ │ ├── GateColumn.test.js │ │ ├── GateShaders.test.js │ │ ├── KetShaderUtil.test.js │ │ └── Serializer.test.js │ ├── gates │ │ ├── AllGates.test.js │ │ ├── AmplitudeDisplay.test.js │ │ ├── ArithmeticGates.test.js │ │ ├── BitCountGates.test.js │ │ ├── ComparisonGates.test.js │ │ ├── Controls.test.js │ │ ├── CycleBitsGates.test.js │ │ ├── DensityMatrixDisplay.test.js │ │ ├── Detector.test.js │ │ ├── ExponentiatingGates.test.js │ │ ├── FourierTransformGates.test.js │ │ ├── Impossible_UniversalNotGate.test.js │ │ ├── IncrementGates.test.js │ │ ├── InputGates.test.js │ │ ├── InterleaveBitsGates.test.js │ │ ├── ModularAdditionGates.test.js │ │ ├── ModularIncrementGates.test.js │ │ ├── ModularMultiplicationGates.test.js │ │ ├── ModularMultiplyAccumulateGates.test.js │ │ ├── MultiplicationGates.test.js │ │ ├── MultiplyAccumulateGates.test.js │ │ ├── ParametrizedRotationGates.test.js │ │ ├── PhaseGradientGates.test.js │ │ ├── PivotFlipGates.test.js │ │ ├── ProbabilityDisplay.test.js │ │ ├── SampleDisplay.test.js │ │ └── XorGates.test.js │ ├── math │ │ ├── Axis.test.js │ │ ├── Complex.test.js │ │ ├── Matrix.test.js │ │ ├── Point.test.js │ │ └── Rect.test.js │ ├── ui │ │ ├── DisplayedCircuit.test.js │ │ ├── MathPainter.test.js │ │ ├── Painter.test.js │ │ ├── WidgetPainter.test.js │ │ └── forge.test.js │ └── webgl │ │ ├── ShaderCoders.test.js │ │ ├── ShaderCoders_Base.test.js │ │ ├── ShaderCoders_intoBytes.test.js │ │ ├── ShaderCoders_intoFloats.test.js │ │ ├── Shaders.test.js │ │ ├── WglArg.test.js │ │ ├── WglShader.test.js │ │ ├── WglTexture.test.js │ │ └── WglTexturePool.test.js └── test_perf │ ├── CircuitStats.perf.js │ ├── DisplayedInspector.perf.js │ ├── KarmaTestRunner.perf.js │ ├── TestPerfUtil.js │ └── test_page.template.html ├── quantum_ai ├── QUnet.py ├── QVC.py ├── TransferLearning.py ├── hybrid.py └── qae.py ├── quantum_algorithm ├── AmplitudeAmplification.py ├── DJ_1.py ├── DJ_2.py ├── DJ_3.py ├── Grover_1.py ├── Grover_2.py ├── HHLDemo.py ├── HadamardTest.py ├── QFTDemo.py ├── QMath.py ├── QPEDemo.py ├── SWAPTest.py ├── ShorDemo.py └── Superposition.py ├── quantum_ml ├── fermion │ ├── fermion_init.py │ ├── fermion_math.py │ └── var.py ├── kmeans.py ├── pauli │ ├── getMaxIndex.py │ ├── pauli_init.py │ ├── pauli_math.py │ └── remapQubitIndex.py └── qaoa.py ├── quantum_qiskit_finance ├── 00_amplitude_estimation.py ├── 01_portfolio_optimization.py ├── 02_portfolio_diversification.py ├── 03_european_call_option_pricing.py ├── 04_european_put_option_pricing.py ├── 05_bull_spread_pricing.py ├── 06_basket_option_pricing.py ├── 07_asian_barrier_spread_pricing.py ├── 08_fixed_income_pricing.py ├── 09_credit_risk_analysis.py └── 10_qgan_option_pricing.py ├── quantum_qpanda ├── basic_program │ ├── 0_classes.py │ ├── 10_RYGate.py │ ├── 11_RZGate.py │ ├── 12_CNOTGate.py │ ├── 13_CRGate.py │ ├── 14_SWAPGate.py │ ├── 15_ToffoliGate.py │ ├── 1_interface.py │ ├── 2_ measure.py │ ├── 3_ pmeasure.py │ ├── 4_circuit.py │ ├── 5_HGate.py │ ├── 6_XGate.py │ ├── 7_YGate.py │ ├── 8_ZGate.py │ └── 9_RXGate.py ├── components │ ├── 0_PauliOperator.py │ ├── 1_FermionOperator.py │ └── 2_Optimizer.py ├── prog_info │ ├── 0_NodeIter.py │ ├── 0_NodeIter_reverse.py │ ├── 10_Qubit_Rb.py │ ├── 11_Gate_Xeb.py │ ├── 1_Gate_Counter.py │ ├── 2_Clock_Cycle.py │ ├── 3_Get_Matrix.py │ ├── 4_Match_Topology.py │ ├── 5_Adjacent_Qgate_Type.py │ ├── 6_Is_Swappable.py │ ├── 7_Supported_Qgate_Type.py │ ├── 8_Print_Qcircuit.py │ ├── 9_Quantum_Volume.py │ └── test_cir_draw.png ├── tools │ ├── 0_Circuit_Optimizer.py │ ├── 1_Fill_Qprog_By_I.py │ ├── 2_Matrix_Decompose.py │ └── test_cir_draw.png └── vqc │ ├── 0_Var.py │ ├── 1_VQC_VGQ.py │ └── 2_Optimizer.py ├── 量子计算【编程篇】 ├── 第1章 编程基础.pdf ├── 第2章 编程进阶.pdf ├── 第3章 常用工具接口.pdf ├── 第4章 组件-算符、优化算法.pdf └── 第5章 VQC-变量、可变量子门.pdf └── 量子计算【量子金融】 ├── 第10章 固定收益定价.pdf ├── 第11章 信用风险分析.pdf ├── 第12章 QGAN期权定价.pdf ├── 第1章 量子金融概要.pdf ├── 第2章 量子振幅估计.pdf ├── 第3章 投资组合优化.pdf ├── 第4章 分散投资.pdf ├── 第5章 欧式看涨期权定价.pdf ├── 第6章 欧式看跌期权定价.pdf ├── 第7章 牛市套利.pdf ├── 第8章 一篮子期权 (Basket Options).pdf └── 第9章 亚式障碍期权(Asian barriers options).pdf /README.md: -------------------------------------------------------------------------------- 1 |
2 | 官网 3 |
4 | 5 | 6 | ### 量子计算系列教程: 7 | https://zhuanlan.zhihu.com/p/503483952 8 | 9 | 10 | #### 1. qubits/circuit_weaver - 量子线路模拟器(开源项目) 11 | - Circuit Weaver 12 | 13 | 14 | #### 2. qubits/量子计算【量子金融】 15 | - 基于ibm qiskit 框架编写的 ppt 教程 16 | - 教程代码:quantum_qiskit_finance 17 | 18 | 19 | 20 | #### 3. qubits/量子计算【编程篇】 21 | - 基于本源量子框架编写的 ppt 教程笔记 22 | - 教程代码:quantum_qpanda 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | #### 其它研究专题: 32 | 33 | 34 | 35 | #### 1. 人工智能加速器套件 36 |
37 | 38 |
39 | 40 | - 官网: https://www.aias.top/ 41 | - Gitee: https://gitee.com/mymagicpower/AIAS 42 | - GitHub: https://github.com/mymagicpower/AIAS 43 | 44 | #### 2. AI + 生物医药 45 |
46 | 47 |
48 | 49 | - 官网: https://www.biocomputing.top/ 50 | - Gitee: https://gitee.com/mymagicpower/bio-computing 51 | - GitHub: https://github.com/mymagicpower/bio-computing 52 | -------------------------------------------------------------------------------- /circuit_weaver/PuppeteerRunTests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const puppeteer = require('puppeteer'); 18 | 19 | (async () => { 20 | try { 21 | const browser = await puppeteer.launch(); 22 | const page = await browser.newPage(); 23 | let caughtPageError = false; 24 | page.on('console', message => console.log(message.text())); 25 | page.on('pageerror', ({message}) => { 26 | caughtPageError = true; 27 | console.error("Page error bubbled into PuppeteerRunTests.js: " + message); 28 | }); 29 | 30 | const outDirUrl = 'file:///' + __dirname.split('\\').join('/') + '/out/'; 31 | await page.goto(outDirUrl + 'test.html#blocking'); 32 | await page.waitForSelector('#done', {timeout: 5 * 60 * 1000}); 33 | let anyFailures = await page.evaluate('__any_failures'); 34 | 35 | await browser.close(); 36 | if (anyFailures || caughtPageError) { 37 | process.exit(1); 38 | } 39 | } catch (ex) { 40 | console.error("Error bubbled up into PuppeteerRunTests.js: " + ex); 41 | process.exit(1); 42 | } 43 | })(); 44 | -------------------------------------------------------------------------------- /circuit_weaver/PuppeteerScreenshotCircuit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const puppeteer = require('puppeteer'); 18 | 19 | (async () => { 20 | try { 21 | const browser = await puppeteer.launch(); 22 | const page = await browser.newPage(); 23 | let caughtPageError = false; 24 | page.on('console', message => console.log(message.text())); 25 | page.on('pageerror', ({message}) => { 26 | caughtPageError = true; 27 | console.error("Page error bubbled into PuppeteerSampleCircuit.js: " + message); 28 | }); 29 | const outDirUrl = 'file:///' + __dirname.split('\\').join('/') + '/out/'; 30 | const circuitJson = '{"cols":[["H"],["Bloch"],["Amps1"],[],["Density"],["•","X"],["Chance2"]]}'; 31 | await page.goto(outDirUrl + 'quirk.html#circuit=' + circuitJson); 32 | await page.waitForSelector('#loading-div', {visible: false, timeout: 5 * 1000}); 33 | await page.screenshot({path: 'screenshot.png'}); 34 | await browser.close(); 35 | } catch (ex) { 36 | console.error("Error bubbled up into PuppeteerSampleCircuit.js: " + ex); 37 | process.exit(1); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /circuit_weaver/README_CN.md: -------------------------------------------------------------------------------- 1 | ### 量子线路模拟器 - Circuit Weaver 2 | 3 |
4 | 5 |
6 | - 官网: http://qubits.top/ 7 | 8 | 9 | Circuit Weaver 基于开源项目 **[Quirk](http://algassert.com/quirk)** 定制, 其作者为 Craig Gidney. 10 | 11 | 我简化了其功能,便于初学者学习量子线路的开发。 12 | 详细培训文档链接: **[Guides](http://qubits.top/guides.html)** 13 | 14 | 15 | ### 如何构建项目 16 | 17 | ```bash 18 | npm install 19 | npm run build 20 | ``` 21 | 22 | 构建成功后,生成文件如下: 23 | `out/CircuitWeaver.html` 24 | 25 | 26 | ### 在线体验 27 | **[Circuit Weaver](http://qubits.top/CircuitWeaver.html)** 28 | -------------------------------------------------------------------------------- /circuit_weaver/doc/MANUAL_amp-display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/MANUAL_amp-display.png -------------------------------------------------------------------------------- /circuit_weaver/doc/MANUAL_bloch-display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/MANUAL_bloch-display.png -------------------------------------------------------------------------------- /circuit_weaver/doc/MANUAL_chance-display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/MANUAL_chance-display.png -------------------------------------------------------------------------------- /circuit_weaver/doc/MANUAL_circuit-editing-area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/MANUAL_circuit-editing-area.png -------------------------------------------------------------------------------- /circuit_weaver/doc/MANUAL_controlled-display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/MANUAL_controlled-display.png -------------------------------------------------------------------------------- /circuit_weaver/doc/MANUAL_controlled-epr-display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/MANUAL_controlled-epr-display.png -------------------------------------------------------------------------------- /circuit_weaver/doc/MANUAL_density-display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/MANUAL_density-display.png -------------------------------------------------------------------------------- /circuit_weaver/doc/MANUAL_measurement-types.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/MANUAL_measurement-types.png -------------------------------------------------------------------------------- /circuit_weaver/doc/MANUAL_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/MANUAL_menu.png -------------------------------------------------------------------------------- /circuit_weaver/doc/MANUAL_state-channel-duality.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/MANUAL_state-channel-duality.png -------------------------------------------------------------------------------- /circuit_weaver/doc/MANUAL_various-displays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/MANUAL_various-displays.png -------------------------------------------------------------------------------- /circuit_weaver/doc/README_Demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/README_Demo.gif -------------------------------------------------------------------------------- /circuit_weaver/doc/README_Grover.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/README_Grover.gif -------------------------------------------------------------------------------- /circuit_weaver/doc/README_Teleportation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/README_Teleportation.gif -------------------------------------------------------------------------------- /circuit_weaver/doc/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/circuit_weaver/doc/favicon.ico -------------------------------------------------------------------------------- /circuit_weaver/html/error.partial.html: -------------------------------------------------------------------------------- 1 | 40 | -------------------------------------------------------------------------------- /circuit_weaver/html/export.partial.html: -------------------------------------------------------------------------------- 1 | 34 | -------------------------------------------------------------------------------- /circuit_weaver/karma.test.conf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module.exports = function(config) { 18 | config.set({ 19 | basePath: '', 20 | frameworks: [], 21 | files: ['out/test.js'], 22 | exclude: [], 23 | preprocessors: {}, 24 | reporters: ['dots'], 25 | port: 19876, 26 | colors: true, 27 | browserNoActivityTimeout: 30000, 28 | logLevel: config.LOG_INFO, 29 | autoWatch: false, 30 | browsers: ['Chrome', 'Firefox'], 31 | singleRun: true 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /circuit_weaver/karma.test_perf.conf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module.exports = function(config) { 18 | config.set({ 19 | basePath: '', 20 | frameworks: [], 21 | files: ['out/test_perf.js'], 22 | exclude: [], 23 | preprocessors: {}, 24 | reporters: ['dots'], 25 | port: 19876, 26 | colors: true, 27 | browserNoActivityTimeout: 30000, 28 | logLevel: config.LOG_INFO, 29 | autoWatch: false, 30 | browsers: ['Chrome', 'Firefox'], 31 | singleRun: true 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /circuit_weaver/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "quirk-quantum-circuit-simulator", 3 | "title": "Quirk", 4 | "description": "A drag-and-drop toy for exploring and understanding small quantum circuits.", 5 | "license": "Apache-2.0", 6 | "version": "2.3.2", 7 | "homepage": "https://github.com/Strilanc/Quirk", 8 | "bugs": { 9 | "url": "https://github.com/Strilanc/Quirk/issues" 10 | }, 11 | "devDependencies": { 12 | "grunt": "~1.3.0", 13 | "grunt-cli": "~1.3.2", 14 | "grunt-contrib-clean": "~2.0.0", 15 | "grunt-contrib-concat": "~1.0.1", 16 | "grunt-contrib-copy": "~1.0.0", 17 | "grunt-contrib-uglify": "~5.0.0", 18 | "grunt-karma": "~4.0.0", 19 | "grunt-traceur": "~0.5.5", 20 | "karma": "~5.2.2", 21 | "karma-chrome-launcher": "~3.1.0", 22 | "karma-firefox-launcher": "~1.3.0", 23 | "traceur": "0.0.111", 24 | "puppeteer": "^5.3.0" 25 | }, 26 | "scripts": { 27 | "build": "grunt build-src", 28 | "test": "grunt test", 29 | "test-chrome": "grunt test-chrome", 30 | "test-firefox": "grunt test-firefox", 31 | "test-travis": "grunt test-travis" 32 | }, 33 | "repository": { 34 | "type": "git", 35 | "url": "https://github.com/Strilanc/Quirk.git" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /circuit_weaver/src/browser/Clipboard.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @param {!HTMLElement} element 19 | * @throws 20 | */ 21 | function selectAndCopyToClipboard(element) { 22 | if (document.selection) { 23 | //noinspection XHTMLIncompatabilitiesJS 24 | let range = document.body.createTextRange(); 25 | range.moveToElementText(element); 26 | range.select(); 27 | } else if (window.getSelection) { 28 | let range = document.createRange(); 29 | range.selectNodeContents(element); 30 | window.getSelection().removeAllRanges(); 31 | window.getSelection().addRange(range); 32 | } 33 | 34 | if (!document.execCommand('copy')) { 35 | throw new Error("execCommand failed"); 36 | } 37 | } 38 | 39 | export {selectAndCopyToClipboard} 40 | -------------------------------------------------------------------------------- /circuit_weaver/src/browser/EventUtil.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Observable} from "../base/Obs.js" 18 | 19 | /** 20 | * @param {!HTMLInputElement} textBox 21 | * @returns {!Observable.} 22 | */ 23 | function textEditObservable(textBox) { 24 | return Observable.of( 25 | Observable.elementEvent(textBox, 'change'), 26 | Observable.elementEvent(textBox, 'keyup'), 27 | Observable.elementEvent(textBox, 'click'), 28 | Observable.elementEvent(textBox, 'paste'), 29 | Observable.elementEvent(textBox, 'input') 30 | ).flatten().map(e => textBox.value).whenDifferent(); 31 | } 32 | 33 | export {textEditObservable}; 34 | -------------------------------------------------------------------------------- /circuit_weaver/src/browser/SaveFile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @param {!string} name 19 | * @param {!string} content 20 | */ 21 | function saveFile(name, content) { 22 | //noinspection JSUnresolvedVariable 23 | if (navigator.msSaveBlob) { 24 | //noinspection JSUnresolvedFunction 25 | navigator.msSaveBlob(new Blob([content], {type: 'text/html;charset=UTF-8'}), name); 26 | return; 27 | } 28 | 29 | let anchor = document.createElement("a"); 30 | //noinspection JSUnresolvedVariable,JSUnresolvedFunction 31 | anchor.href = window.URL !== undefined ? 32 | window.URL.createObjectURL(new Blob([content], {type: 'text/html;charset=UTF-8'})) : 33 | 'data:application/octet-stream,' + encodeURI(moddedHtml); 34 | anchor.download = name; 35 | try { 36 | //noinspection XHTMLIncompatabilitiesJS 37 | document.body.appendChild(anchor); 38 | anchor.click(); 39 | } finally { 40 | //noinspection XHTMLIncompatabilitiesJS 41 | document.body.removeChild(anchor); 42 | } 43 | } 44 | 45 | export {saveFile}; 46 | -------------------------------------------------------------------------------- /circuit_weaver/src/browser/TouchScrollBlocker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Rect} from "../math/Rect.js" 18 | 19 | class TouchScrollBlocker { 20 | /** 21 | * @param {HTMLElement} parentElement 22 | */ 23 | constructor(parentElement) { 24 | /** 25 | * @type {!HTMLElement} 26 | * @private 27 | */ 28 | this._parentElement = parentElement; 29 | 30 | /** 31 | * @type {!{div: !HTMLDivElement, area: !Rect}} 32 | * @private 33 | */ 34 | this._curBlockers = []; 35 | 36 | /** 37 | * @type {!int} 38 | * @private 39 | */ 40 | this._curShowing = 0; 41 | } 42 | 43 | //noinspection Eslint 44 | /** 45 | * @param {!Array.} desiredBlockers 46 | * @param {undefined|!string} overrideCursorStyle 47 | */ 48 | setBlockers(desiredBlockers, overrideCursorStyle) { 49 | while (this._curBlockers.length < desiredBlockers.length) { 50 | let blockerDiv = document.createElement('div'); 51 | blockerDiv.style.touchAction = 'none'; 52 | blockerDiv.style.position = 'absolute'; 53 | blockerDiv.style.opacity = 0.0001; 54 | this._parentElement.appendChild(blockerDiv); 55 | this._curBlockers.push({div: blockerDiv, area: undefined}); 56 | } 57 | 58 | // Positioning. 59 | for (let i = 0; i < desiredBlockers.length; i++) { 60 | let desiredArea = desiredBlockers[i].rect; 61 | let desiredCursor = overrideCursorStyle || desiredBlockers[i].cursor || 'auto'; 62 | let cur = this._curBlockers[i]; 63 | let style = cur.div.style; 64 | 65 | if (!desiredArea.isEqualTo(cur.area)) { 66 | cur.area = desiredArea; 67 | style.left = desiredArea.x + "px"; 68 | style.top = desiredArea.y + "px"; 69 | style.width = desiredArea.w + "px"; 70 | style.height = desiredArea.h + "px"; 71 | } 72 | if (style.cursor !== desiredCursor) { 73 | style.cursor = desiredCursor; 74 | } 75 | } 76 | 77 | // Visibility. 78 | while (this._curShowing < desiredBlockers.length) { 79 | this._curBlockers[this._curShowing].div.style.display = 'inline'; 80 | this._curShowing++; 81 | } 82 | while (this._curShowing > desiredBlockers.length) { 83 | this._curShowing--; 84 | this._curBlockers[this._curShowing].div.style.display = 'none'; 85 | } 86 | } 87 | } 88 | 89 | export {TouchScrollBlocker} 90 | -------------------------------------------------------------------------------- /circuit_weaver/src/circuit/CustomGateSet.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {DetailedError} from "../base/DetailedError.js" 18 | 19 | class CustomGateSet { 20 | /** 21 | * @param {!Gate} gates 22 | */ 23 | constructor(...gates) { 24 | /** @type {!Array.} */ 25 | this.gates = gates; 26 | } 27 | 28 | /** 29 | * @param {!Gate} gate 30 | * @returns {!CustomGateSet} 31 | */ 32 | withGate(gate) { 33 | if (!gate.serializedId.startsWith("~")) { 34 | throw new DetailedError("Custom gates' serialized id must start with '~'.", {id: gate.serializedId, gate}); 35 | } 36 | if (this.findGateWithSerializedId(gate.serializedId)) { 37 | throw new DetailedError("Duplicate serialized id.", {gate}); 38 | } 39 | return new CustomGateSet(...this.gates, gate); 40 | } 41 | 42 | /** 43 | * @param {!String} id 44 | * @returns {undefined|!Gate} 45 | */ 46 | findGateWithSerializedId(id) { 47 | for (let g of this.gates) { 48 | if (g.serializedId === id) { 49 | return g; 50 | } 51 | } 52 | return undefined; 53 | } 54 | } 55 | 56 | export {CustomGateSet} 57 | -------------------------------------------------------------------------------- /circuit_weaver/src/circuit/GateCheckArgs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Values used by gate disable reason finder functions. 19 | */ 20 | class GateCheckArgs { 21 | /** 22 | * @param {!Gate} gate 23 | * @param {!GateColumn} innerColumn 24 | * @param {!int} outerRow 25 | * @param {!int} measuredMask 26 | * @param {!Map.} context 27 | * @param {!boolean} isNested 28 | */ 29 | constructor(gate, 30 | innerColumn, 31 | outerRow, 32 | measuredMask, 33 | context, 34 | isNested) { 35 | /** @type {!Gate} */ 36 | this.gate = gate; 37 | /** @type {!GateColumn} */ 38 | this.innerColumn = innerColumn; 39 | /** @type {!int} */ 40 | this.outerRow = outerRow; 41 | /** @type {!int} */ 42 | this.measuredMask = measuredMask; 43 | /** @type {!Map.} */ 44 | this.context = context; 45 | /** @type {!boolean} */ 46 | this.isNested = isNested; 47 | } 48 | } 49 | 50 | export {GateCheckArgs} 51 | -------------------------------------------------------------------------------- /circuit_weaver/src/draw/CachablePainting.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Painter} from "./Painter.js" 18 | import {RestartableRng} from "../base/RestartableRng.js" 19 | 20 | const fixedRng = new RestartableRng(); 21 | 22 | /** 23 | * A drawing process that always has the same result, so its output can be cached and pasted instead of recreated anew. 24 | */ 25 | class CachablePainting { 26 | /** 27 | * @param {!function(key: *) : !{width: !int, height: !int}} sizeFunc 28 | * @param {!function(painter: !Painter | !(function(!Painter, !string): void)) : void} drawingFunc 29 | */ 30 | constructor(sizeFunc, drawingFunc) { 31 | /** @type {!function(key: *) : !{width: !int, height: !int}} */ 32 | this.sizeFunc = sizeFunc; 33 | /** 34 | * @type {!(function(!Painter): void) | !(function(!Painter, !string): void)} 35 | * @private 36 | */ 37 | this._drawingFunc = drawingFunc; 38 | /** 39 | * @type {!Map.} 40 | * @private 41 | */ 42 | this._cachedCanvases = new Map(); 43 | } 44 | 45 | /** 46 | * @param {!int} x 47 | * @param {!int} y 48 | * @param {!Painter} painter 49 | * @param {!*=} key 50 | */ 51 | paint(x, y, painter, key=undefined) { 52 | if (!this._cachedCanvases.has(key)) { 53 | let canvas = /** @type {!HTMLCanvasElement} */ document.createElement('canvas'); 54 | let {width, height} = this.sizeFunc(key); 55 | canvas.width = width; 56 | canvas.height = height; 57 | this._drawingFunc(new Painter(canvas, fixedRng.restarted()), key); 58 | this._cachedCanvases.set(key, canvas); 59 | } 60 | painter.ctx.drawImage(this._cachedCanvases.get(key), x, y); 61 | } 62 | } 63 | 64 | export {CachablePainting} 65 | -------------------------------------------------------------------------------- /circuit_weaver/src/draw/GateDrawParams.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Values used by the various gate drawing strategies. 19 | */ 20 | class GateDrawParams { 21 | /** 22 | * @param {!Painter} painter 23 | * @param {!Hand} hand 24 | * @param {!boolean} isInToolbox 25 | * @param {!boolean} isHighlighted 26 | * @param {!boolean} isResizeShowing 27 | * @param {!boolean} isResizeHighlighted 28 | * @param {!Rect} rect 29 | * @param {!Gate} gate 30 | * @param {!CircuitStats} stats 31 | * @param {undefined|!{row: !int, col: !int}} positionInCircuit 32 | * @param {!Array.} focusPoints 33 | * @param {undefined|*} customStatsForCircuitPos 34 | */ 35 | constructor(painter, 36 | hand, 37 | isInToolbox, 38 | isHighlighted, 39 | isResizeShowing, 40 | isResizeHighlighted, 41 | rect, 42 | gate, 43 | stats, 44 | positionInCircuit, 45 | focusPoints, 46 | customStatsForCircuitPos) { 47 | /** @type {!Painter} */ 48 | this.painter = painter; 49 | /** @type {!Hand} */ 50 | this.hand = hand; 51 | /** @type {!boolean} */ 52 | this.isInToolbox = isInToolbox; 53 | /** @type {!boolean} */ 54 | this.isHighlighted = isHighlighted; 55 | /** @type {!boolean} */ 56 | this.isResizeShowing = isResizeShowing; 57 | /** @type {!boolean} */ 58 | this.isResizeHighlighted = isResizeHighlighted; 59 | /** @type {!Rect} */ 60 | this.rect = rect; 61 | /** @type {!Gate} */ 62 | this.gate = gate; 63 | /** @type {!CircuitStats} */ 64 | this.stats = stats; 65 | /** @type {undefined|!{row: !int, col: !int}} */ 66 | this.positionInCircuit = positionInCircuit; 67 | /** @type {!Array.} */ 68 | this.focusPoints = focusPoints; 69 | /** @type {undefined|*} */ 70 | this.customStats = customStatsForCircuitPos; 71 | } 72 | 73 | /** 74 | * @param {!string} key 75 | * @returns {undefined|*} 76 | */ 77 | getGateContext(key) { 78 | if (this.positionInCircuit === undefined) { 79 | return undefined; 80 | } 81 | 82 | return this.stats.circuitDefinition. 83 | colCustomContextFromGates(this.positionInCircuit.col, 0). 84 | get(key); 85 | } 86 | } 87 | 88 | export {GateDrawParams} 89 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/BitCountGates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Config} from "../Config.js" 18 | import {Gate} from "../circuit/Gate.js" 19 | import {ketArgs, ketShaderPermute, ketInputGateShaderCode} from "../circuit/KetShaderUtil.js" 20 | import {Util} from "../base/Util.js" 21 | import {WglArg} from "../webgl/WglArg.js" 22 | 23 | let BitCountGates = {}; 24 | 25 | const POP_COUNT_SHADER = ketShaderPermute( 26 | ` 27 | uniform float factor; 28 | ${ketInputGateShaderCode('A')} 29 | `, 30 | ` 31 | float d = read_input_A(); 32 | float popcnt = 0.0; 33 | for (int i = 0; i < ${Config.MAX_WIRE_COUNT}; i++) { 34 | popcnt += mod(d, 2.0); 35 | d = floor(d / 2.0); 36 | } 37 | float offset = mod(popcnt * factor, span); 38 | return mod(out_id + span - offset, span);`); 39 | 40 | BitCountGates.PlusBitCountAFamily = Gate.buildFamily(1, 16, (span, builder) => builder. 41 | setSerializedIdAndSymbol("+cntA" + span). 42 | setSymbol("+1s(A)"). 43 | setTitle("Bit Count Gate"). 44 | setBlurb("Counts the number of ON bits in input A and adds that into this output."). 45 | setRequiredContextKeys("Input Range A"). 46 | setActualEffectToShaderProvider(ctx => POP_COUNT_SHADER.withArgs( 47 | ...ketArgs(ctx, span, ['A']), 48 | WglArg.float("factor", +1))). 49 | setKnownEffectToParametrizedPermutation((t, a) => (t + Util.numberOfSetBits(a)) & ((1 << span) - 1))); 50 | 51 | BitCountGates.MinusBitCountAFamily = Gate.buildFamily(1, 16, (span, builder) => builder. 52 | setAlternateFromFamily(BitCountGates.PlusBitCountAFamily). 53 | setSerializedIdAndSymbol("-cntA" + span). 54 | setSymbol("-1s(A)"). 55 | setTitle("Bit Un-Count Gate"). 56 | setBlurb("Counts the number of ON bits in input A and subtracts that into this output."). 57 | setRequiredContextKeys("Input Range A"). 58 | setActualEffectToShaderProvider(ctx => POP_COUNT_SHADER.withArgs( 59 | ...ketArgs(ctx, span, ['A']), 60 | WglArg.float("factor", -1))). 61 | setKnownEffectToParametrizedPermutation((t, a) => (t - Util.numberOfSetBits(a)) & ((1 << span) - 1))); 62 | 63 | BitCountGates.all = [ 64 | ...BitCountGates.PlusBitCountAFamily.all, 65 | ...BitCountGates.MinusBitCountAFamily.all 66 | ]; 67 | 68 | export {BitCountGates} 69 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/Debug_ErrorInjectionGate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {DetailedError} from "../base/DetailedError.js" 18 | import {GateBuilder} from "../circuit/Gate.js" 19 | import {GatePainting} from "../draw/GatePainting.js" 20 | 21 | let ErrorInjectionGate = new GateBuilder(). 22 | setSerializedId("__error__"). 23 | setSymbol("ERR!"). 24 | setTitle("Error Injection Gate"). 25 | setBlurb("Throws an exception during circuit stat computations, for testing error paths."). 26 | setDrawer(GatePainting.MAKE_HIGHLIGHTED_DRAWER('red', 'red')). 27 | setActualEffectToUpdateFunc(ctx => { 28 | throw new DetailedError("Applied an Error Injection Gate", {qubit: ctx.row}); 29 | }). 30 | promiseEffectIsStable(). 31 | gate; 32 | 33 | export {ErrorInjectionGate} 34 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/Impossible_UniversalNotGate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {GateBuilder} from "../circuit/Gate.js" 18 | import {ketArgs, ketShader} from "../circuit/KetShaderUtil.js" 19 | import {WglConfiguredShader} from "../webgl/WglConfiguredShader.js" 20 | 21 | /** 22 | * @param {!CircuitEvalContext} ctx 23 | * @returns {!WglConfiguredShader} 24 | */ 25 | let universalNot = ctx => UNIVERSAL_NOT_SHADER.withArgs(...ketArgs(ctx)); 26 | const UNIVERSAL_NOT_SHADER = ketShader( 27 | '', 28 | 'vec2 other = inp(1.0 - out_id); return vec2(other.x, -other.y) * (1.0 - 2.0 * out_id);', 29 | 1); 30 | 31 | let UniversalNotGate = new GateBuilder(). 32 | setSerializedId("__unstable__UniversalNot"). 33 | setSymbol("UniNot"). 34 | setTitle("Universal Not Gate"). 35 | setBlurb("Mirrors through the origin of the Bloch sphere.\nImpossible in practice."). 36 | setActualEffectToShaderProvider(universalNot). 37 | promiseEffectIsStable(). 38 | gate; 39 | 40 | export {universalNot, UniversalNotGate} 41 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/IncrementGates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Gate} from "../circuit/Gate.js" 18 | import {ketArgs, ketShaderPermute} from "../circuit//KetShaderUtil.js" 19 | import {WglArg} from "../webgl/WglArg.js" 20 | 21 | let IncrementGates = {}; 22 | 23 | const offsetShader = ketShaderPermute( 24 | 'uniform float amount;', 25 | 'return mod(out_id - amount + span, span);'); 26 | 27 | IncrementGates.IncrementFamily = Gate.buildFamily(1, 16, (span, builder) => builder. 28 | setSerializedId("inc" + span). 29 | setSymbol("+1"). 30 | setTitle("Increment Gate"). 31 | setBlurb("Adds 1 to the little-endian number represented by a block of qubits."). 32 | setActualEffectToShaderProvider(ctx => offsetShader.withArgs( 33 | ...ketArgs(ctx, span), 34 | WglArg.float("amount", +1))). 35 | setKnownEffectToPermutation(t => (t + 1) & ((1 << span) - 1))); 36 | 37 | IncrementGates.DecrementFamily = Gate.buildFamily(1, 16, (span, builder) => builder. 38 | setAlternateFromFamily(IncrementGates.IncrementFamily). 39 | setSerializedId("dec" + span). 40 | setSymbol("−1"). 41 | setTitle("Decrement Gate"). 42 | setBlurb("Subtracts 1 from the little-endian number represented by a block of qubits."). 43 | setActualEffectToShaderProvider(ctx => offsetShader.withArgs( 44 | ...ketArgs(ctx, span), 45 | WglArg.float("amount", -1))). 46 | setKnownEffectToPermutation(t => (t - 1) & ((1 << span) - 1))); 47 | 48 | IncrementGates.all = [ 49 | ...IncrementGates.IncrementFamily.all, 50 | ...IncrementGates.DecrementFamily.all, 51 | ]; 52 | 53 | export {IncrementGates, offsetShader} 54 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/Joke_ImaginaryGate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {GateBuilder} from "../circuit/Gate.js" 18 | import {Matrix} from "../math/Matrix.js" 19 | import {Complex} from "../math/Complex.js" 20 | import {GatePainting} from "../draw/GatePainting.js" 21 | 22 | const ImaginaryGate = new GateBuilder(). 23 | setSerializedIdAndSymbol("i"). 24 | setTitle("Imaginary Gate"). 25 | setBlurb("Phases everything by i."). 26 | setDrawer(args => { 27 | GatePainting.paintLocationIndependentFrame(args); 28 | GatePainting.paintGateSymbol(args); 29 | }). 30 | setKnownEffectToMatrix(Matrix.square(Complex.I, 0, 0, Complex.I)). 31 | gate; 32 | 33 | const AntiImaginaryGate = new GateBuilder(). 34 | setAlternate(ImaginaryGate). 35 | setSerializedIdAndSymbol("-i"). 36 | setTitle("Anti-Imaginary Gate"). 37 | setBlurb("Phases everything by -i."). 38 | setDrawer(args => { 39 | GatePainting.paintLocationIndependentFrame(args); 40 | GatePainting.paintGateSymbol(args); 41 | }). 42 | setKnownEffectToMatrix(Matrix.square(Complex.I.neg(), 0, 0, Complex.I.neg())). 43 | gate; 44 | 45 | const SqrtImaginaryGate = new GateBuilder(). 46 | setSerializedIdAndSymbol("√i"). 47 | setTitle("Half Imaginary Gate"). 48 | setBlurb("Phases everything by √i."). 49 | setDrawer(args => { 50 | GatePainting.paintLocationIndependentFrame(args); 51 | GatePainting.paintGateSymbol(args); 52 | }). 53 | setKnownEffectToMatrix(Matrix.square(1, 0, 0, 1).times(new Complex(Math.sqrt(0.5), Math.sqrt(0.5)))). 54 | gate; 55 | 56 | const AntiSqrtImaginaryGate = new GateBuilder(). 57 | setAlternate(SqrtImaginaryGate). 58 | setSerializedIdAndSymbol("√-i"). 59 | setTitle("Half Anti-Imaginary Gate"). 60 | setBlurb("Phases everything by √-i."). 61 | setDrawer(args => { 62 | GatePainting.paintLocationIndependentFrame(args); 63 | GatePainting.paintGateSymbol(args); 64 | }). 65 | setKnownEffectToMatrix(Matrix.square(1, 0, 0, 1).times(new Complex(Math.sqrt(0.5), -Math.sqrt(0.5)))). 66 | gate; 67 | 68 | export {AntiImaginaryGate, ImaginaryGate, SqrtImaginaryGate, AntiSqrtImaginaryGate} 69 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/Joke_MysteryGate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Complex} from "../math/Complex.js" 18 | import {GateBuilder} from "../circuit/Gate.js" 19 | import {GatePainting} from "../draw/GatePainting.js" 20 | import {Matrix} from "../math/Matrix.js" 21 | 22 | let MysteryGateSymbol = "?"; 23 | 24 | let MysteryGateMakerWithMatrix = matrix => new GateBuilder(). 25 | setSerializedIdAndSymbol(MysteryGateSymbol). 26 | setTitle("Mystery Gate"). 27 | setBlurb("Different every time.\n(Use shift+drag to copy circuit gates.)"). 28 | setDrawer(GatePainting.MATRIX_SYMBOL_DRAWER_EXCEPT_IN_TOOLBOX). 29 | setKnownEffectToMatrix(matrix). 30 | gate; 31 | 32 | let MysteryGateMaker = () => MysteryGateMakerWithMatrix(Matrix.square( 33 | new Complex(Math.random() - 0.5, Math.random() - 0.5), 34 | new Complex(Math.random() - 0.5, Math.random() - 0.5), 35 | new Complex(Math.random() - 0.5, Math.random() - 0.5), 36 | new Complex(Math.random() - 0.5, Math.random() - 0.5) 37 | ).closestUnitary(0.00001)); 38 | 39 | export {MysteryGateSymbol, MysteryGateMaker, MysteryGateMakerWithMatrix}; 40 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/Joke_NeGate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {GateBuilder} from "../circuit/Gate.js" 18 | import {Matrix} from "../math/Matrix.js" 19 | import {Point} from "../math/Point.js" 20 | import {GatePainting} from "../draw/GatePainting.js" 21 | 22 | const NeGate = new GateBuilder(). 23 | setSerializedId("NeGate"). 24 | setTitle("Ne-Gate"). 25 | setBlurb("Negates all amplitudes."). 26 | setDrawer(args => { 27 | GatePainting.paintLocationIndependentFrame(args); 28 | let {x, y} = args.rect.center(); 29 | args.painter.strokeLine(new Point(x - 6, y), new Point(x + 6, y), 'black', 2); 30 | }). 31 | setKnownEffectToMatrix(Matrix.square(-1, 0, 0, -1)). 32 | gate; 33 | 34 | export {NeGate} 35 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/Joke_ZeroGate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {GateBuilder} from "../circuit/Gate.js" 18 | import {GatePainting} from "../draw/GatePainting.js" 19 | import {Matrix} from "../math/Matrix.js" 20 | 21 | /** @type {!Gate} */ 22 | const ZeroGate = new GateBuilder(). 23 | setSerializedIdAndSymbol("0"). 24 | setTitle("Nothing Gate"). 25 | setBlurb("Destroys the universe."). 26 | setDrawer(GatePainting.makeLocationIndependentGateDrawer('#666')). 27 | setKnownEffectToMatrix(Matrix.square(0, 0, 0, 0)). 28 | gate; 29 | 30 | export {ZeroGate} 31 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/MeasurementGate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Config} from "../Config.js" 18 | import {GateBuilder} from "../circuit/Gate.js" 19 | import {GatePainting} from "../draw/GatePainting.js" 20 | 21 | /** 22 | * @param {!GateDrawParams} args 23 | */ 24 | function drawMeasurementGate(args) { 25 | let backColor = Config.GATE_FILL_COLOR; 26 | if (args.isHighlighted) { 27 | backColor = Config.HIGHLIGHTED_GATE_FILL_COLOR; 28 | } 29 | args.painter.fillRect(args.rect, backColor); 30 | GatePainting.paintOutline(args); 31 | 32 | const τ = Math.PI * 2; 33 | let r = args.rect.w*0.4; 34 | let {x, y} = args.rect.center(); 35 | y += r*0.6; 36 | let a = -τ/6; 37 | let [c, s] = [Math.cos(a)*r*1.5, Math.sin(a)*r*1.5]; 38 | let [p, q] = [x + c, y + s]; 39 | 40 | // Draw the dial and shaft. 41 | args.painter.trace(trace => { 42 | trace.ctx.arc(x, y, r, τ/2, τ); 43 | trace.line(x, y, p, q); 44 | }).thenStroke('black'); 45 | // Draw the indicator head. 46 | args.painter.trace(trace => trace.arrowHead(p, q, r*0.3, a, τ/4)).thenFill('black'); 47 | } 48 | 49 | let MeasurementGate = new GateBuilder(). 50 | setSerializedIdAndSymbol("Measure"). 51 | setTitle("Measurement Gate"). 52 | setBlurb("Measures whether a qubit is ON or OFF, without conditioning on the result."). 53 | promiseHasNoNetEffectOnStateVector(). // Because in the simulation we defer measurement by preventing operations. 54 | setDrawer(drawMeasurementGate). 55 | setExtraDisableReasonFinder(args => { 56 | if (args.isNested) { 57 | return "can't\nnest\nmeasure\n(sorry)"; 58 | } 59 | let isMeasured = (args.measuredMask & (1<= r) { 34 | return out_id; 35 | } 36 | float d = read_input_A(); 37 | d *= factor; 38 | d = floor(mod(d + 0.5, r)); 39 | return floor(mod(out_id + r - d + 0.5, r)); 40 | `); 41 | 42 | ModularAdditionGates.PlusAModRFamily = Gate.buildFamily(1, 16, (span, builder) => builder. 43 | setSerializedId("+AmodR" + span). 44 | setSymbol("+A\nmod R"). 45 | setTitle("Modular Addition Gate"). 46 | setBlurb("Adds input A into the target, mod input R.\nOnly affects values below R."). 47 | setRequiredContextKeys("Input Range A", "Input Range R"). 48 | setExtraDisableReasonFinder(modulusTooBigChecker("R", span)). 49 | setActualEffectToShaderProvider(ctx => MODULAR_ADDITION_SHADER.withArgs( 50 | ...ketArgs(ctx, span, ['A', 'R']), 51 | WglArg.float("factor", +1))). 52 | setKnownEffectToParametrizedPermutation((t, a, r) => t < r ? (t + a) % r : t)); 53 | 54 | ModularAdditionGates.MinusAModRFamily = Gate.buildFamily(1, 16, (span, builder) => builder. 55 | setAlternateFromFamily(ModularAdditionGates.PlusAModRFamily). 56 | setSerializedId("-AmodR" + span). 57 | setSymbol("−A\nmod R"). 58 | setTitle("Modular Subtraction Gate"). 59 | setBlurb("Subtracts input A out of the target, mod input R.\nOnly affects values below R."). 60 | setRequiredContextKeys("Input Range A", "Input Range R"). 61 | setExtraDisableReasonFinder(modulusTooBigChecker("R", span)). 62 | setActualEffectToShaderProvider(ctx => MODULAR_ADDITION_SHADER.withArgs( 63 | ...ketArgs(ctx, span, ['A', 'R']), 64 | WglArg.float("factor", -1))). 65 | setKnownEffectToParametrizedPermutation((t, a, r) => t < r ? Util.properMod(t - a, r) : t)); 66 | 67 | ModularAdditionGates.all = [ 68 | ...ModularAdditionGates.PlusAModRFamily.all, 69 | ...ModularAdditionGates.MinusAModRFamily.all, 70 | ]; 71 | 72 | export {ModularAdditionGates} 73 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/PivotFlipGates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Gate} from "../circuit/Gate.js" 18 | import {ketArgs, ketShaderPermute, ketInputGateShaderCode} from "../circuit/KetShaderUtil.js" 19 | import {modulusTooBigChecker} from "./ModularIncrementGates.js" 20 | 21 | let PivotFlipGates = {}; 22 | 23 | const PIVOT_FLIP_SHADER = ketShaderPermute( 24 | ` 25 | ${ketInputGateShaderCode('A')} 26 | `, 27 | ` 28 | float a = read_input_A(); 29 | return out_id >= a ? out_id : a - out_id - 1.0; 30 | `); 31 | 32 | PivotFlipGates.FlipUnderA = Gate.buildFamily(1, 16, (span, builder) => builder. 33 | setSerializedId('Flip PIVOT_FLIP_SHADER.withArgs(...ketArgs(ctx, span, ['A']))). 40 | setKnownEffectToParametrizedPermutation((t, a) => t >= a ? t : a - t - 1)); 41 | 42 | PivotFlipGates.all = [ 43 | ...PivotFlipGates.FlipUnderA.all, 44 | ]; 45 | 46 | export {PivotFlipGates} 47 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/QuarterTurnGates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Gate, GateBuilder} from "../circuit/Gate.js" 18 | import {Matrix} from "../math/Matrix.js" 19 | 20 | let QuarterTurnGates = {}; 21 | 22 | /** @type {!Gate} */ 23 | QuarterTurnGates.SqrtXForward = new GateBuilder(). 24 | setSerializedIdAndSymbol('X^½'). 25 | setTitle("√X Gate"). 26 | setBlurb("Principle square root of Not."). 27 | setKnownEffectToMatrix(Matrix.fromPauliRotation(0.25, 0, 0)). 28 | gate; 29 | 30 | /** @type {!Gate} */ 31 | QuarterTurnGates.SqrtXBackward = new GateBuilder(). 32 | setAlternate(QuarterTurnGates.SqrtXForward). 33 | setSerializedIdAndSymbol('X^-½'). 34 | setTitle("X^-½ Gate"). 35 | setBlurb("Adjoint square root of Not."). 36 | setKnownEffectToMatrix(Matrix.fromPauliRotation(0.75, 0, 0)). 37 | gate; 38 | 39 | /** @type {!Gate} */ 40 | QuarterTurnGates.SqrtYForward = new GateBuilder(). 41 | setSerializedIdAndSymbol('Y^½'). 42 | setTitle("√Y Gate"). 43 | setBlurb("Principle square root of Y."). 44 | setKnownEffectToMatrix(Matrix.fromPauliRotation(0, 0.25, 0)). 45 | gate; 46 | 47 | /** @type {!Gate} */ 48 | QuarterTurnGates.SqrtYBackward = new GateBuilder(). 49 | setAlternate(QuarterTurnGates.SqrtYForward). 50 | setSerializedIdAndSymbol('Y^-½'). 51 | setTitle("Y^-½ Gate"). 52 | setBlurb("Adjoint square root of Y."). 53 | setKnownEffectToMatrix(Matrix.fromPauliRotation(0, 0.75, 0)). 54 | gate; 55 | 56 | /** @type {!Gate} */ 57 | QuarterTurnGates.SqrtZForward = new GateBuilder(). 58 | setSerializedId('Z^½'). 59 | setSymbol('S'). 60 | setTitle("√Z Gate"). 61 | setBlurb("Principle square root of Z.\nAlso known as the 'S' gate."). 62 | setKnownEffectToMatrix(Matrix.fromPauliRotation(0, 0, 0.25)). 63 | gate; 64 | 65 | /** @type {!Gate} */ 66 | QuarterTurnGates.SqrtZBackward = new GateBuilder(). 67 | setAlternate(QuarterTurnGates.SqrtZForward). 68 | setSerializedId('Z^-½'). 69 | setSymbol('S^-1'). 70 | setTitle("Z^-½ Gate"). 71 | setBlurb("Adjoint square root of Z."). 72 | setKnownEffectToMatrix(Matrix.fromPauliRotation(0, 0, 0.75)). 73 | gate; 74 | 75 | QuarterTurnGates.all = [ 76 | QuarterTurnGates.SqrtXForward, 77 | QuarterTurnGates.SqrtYForward, 78 | QuarterTurnGates.SqrtZForward, 79 | QuarterTurnGates.SqrtXBackward, 80 | QuarterTurnGates.SqrtYBackward, 81 | QuarterTurnGates.SqrtZBackward 82 | ]; 83 | 84 | export {QuarterTurnGates} 85 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/ReverseBitsGate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Config} from "../Config.js" 18 | import {Gate} from "../circuit/Gate.js" 19 | import {ketArgs, ketShaderPermute} from "../circuit/KetShaderUtil.js" 20 | import {Seq} from "../base/Seq.js" 21 | 22 | let _generateReverseShaderForSize = span => span < 2 ? undefined : ketShaderPermute( 23 | '', 24 | ` 25 | float rev = 0.0; 26 | for (int k = 0; k < ${span}; k++) { 27 | rev *= 2.0; 28 | rev += mod(out_id, 2.0); 29 | out_id = floor(out_id*0.5); 30 | } 31 | return rev; 32 | `, 33 | span); 34 | 35 | let reverseShaders = Seq.range(Config.MAX_WIRE_COUNT + 1).map(_generateReverseShaderForSize).toArray(); 36 | 37 | /** 38 | * @param {!int} span 39 | * @returns {!function(!CircuitEvalContext) : !WglConfiguredShader} 40 | */ 41 | let reverseShaderForSize = span => ctx => reverseShaders[span].withArgs(...ketArgs(ctx, span)); 42 | 43 | let ReverseBitsGateFamily = Gate.buildFamily(2, 16, (span, builder) => builder. 44 | setSerializedId("rev" + span). 45 | setSymbol("Reverse"). 46 | setTitle("Reverse Order"). 47 | setBlurb("Swaps bits into the opposite order."). 48 | setKnownEffectToBitPermutation(i => span - 1 - i). 49 | setActualEffectToShaderProvider(reverseShaderForSize(span))); 50 | 51 | export {ReverseBitsGateFamily, reverseShaderForSize} 52 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/SpacerGate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Config} from "../Config.js" 18 | import {GateBuilder} from "../circuit/Gate.js" 19 | import {GatePainting} from "../draw/GatePainting.js" 20 | import {Rect} from "../math/Rect.js" 21 | 22 | let SpacerGate = new GateBuilder(). 23 | setSerializedIdAndSymbol("…"). 24 | setTitle("Spacer"). 25 | setBlurb("A gate with no effect."). 26 | markAsNotInterestedInControls(). 27 | promiseHasNoNetEffectOnStateVector(). 28 | setDrawer(args => { 29 | // Drawn as an ellipsis. 30 | if (args.isInToolbox || args.isHighlighted) { 31 | let backColor = Config.GATE_FILL_COLOR; 32 | if (args.isHighlighted) { 33 | backColor = Config.HIGHLIGHTED_GATE_FILL_COLOR; 34 | } 35 | args.painter.fillRect(args.rect, backColor); 36 | GatePainting.paintOutline(args); 37 | } else { 38 | // Whitespace for the ellipsis. 39 | let {x, y} = args.rect.center(); 40 | let r = new Rect(x - 14, y - 2, 28, 4); 41 | args.painter.fillRect(r, Config.BACKGROUND_COLOR_CIRCUIT); 42 | } 43 | args.painter.fillCircle(args.rect.center().offsetBy(7, 0), 2, "black"); 44 | args.painter.fillCircle(args.rect.center(), 2, "black"); 45 | args.painter.fillCircle(args.rect.center().offsetBy(-7, 0), 2, "black"); 46 | }). 47 | gate; 48 | 49 | export {SpacerGate} 50 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/SwapGateHalf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {GateBuilder} from "../circuit/Gate.js" 18 | import {GatePainting} from "../draw/GatePainting.js" 19 | import {Matrix} from "../math/Matrix.js" 20 | import {Rect} from "../math/Rect.js" 21 | import {Seq} from "../base/Seq.js" 22 | 23 | // Note: there is special code to handle swaps sprinkled everywhere, since it's the only gate with two paired sides. 24 | 25 | /** @type {!Gate} */ 26 | let SwapGateHalf = new GateBuilder(). 27 | setSerializedIdAndSymbol("Swap"). 28 | setTitle("Swap Gate [Half]"). 29 | setBlurb("Swaps the values of two qubits.\n(Place two in the same column.)"). 30 | setKnownEffectToMatrix(Matrix.square( 31 | 1, 0, 0, 0, 32 | 0, 0, 1, 0, 33 | 0, 1, 0, 0, 34 | 0, 0, 0, 1)). 35 | setDrawer(args => { 36 | if (args.isInToolbox || args.isHighlighted) { 37 | GatePainting.DEFAULT_DRAWER(args); 38 | return; 39 | } 40 | 41 | // A swap gate half is shown as a small X (joined by a line to the other half; that's handled elsewhere). 42 | let swapRect = Rect.centeredSquareWithRadius(args.rect.center(), args.rect.w / 6); 43 | args.painter.strokeLine(swapRect.topLeft(), swapRect.bottomRight()); 44 | args.painter.strokeLine(swapRect.topRight(), swapRect.bottomLeft()); 45 | }). 46 | setExtraDisableReasonFinder(args => { 47 | let col = args.innerColumn; 48 | let swapRows = Seq.range(col.gates.length).filter(row => col.gates[row] === SwapGateHalf); 49 | let n = swapRows.count(); 50 | if (n === 1) { 51 | return "need\nother\nswap"; 52 | } 53 | if (n > 2) { 54 | return "too\nmany\nswap"; 55 | } 56 | 57 | let affectsMeasured = swapRows.any(r => (args.measuredMask & (1 << r)) !== 0); 58 | let affectsUnmeasured = swapRows.any(r => (args.measuredMask & (1 << r)) === 0); 59 | if (affectsMeasured && col.hasCoherentControl(args.measuredMask)) { 60 | return "no\nremix\n(sorry)"; 61 | } 62 | if (affectsMeasured && affectsUnmeasured && col.hasControl()) { 63 | return "no\nremix\n(sorry)"; 64 | } 65 | 66 | return undefined; 67 | }). 68 | gate; 69 | 70 | export {SwapGateHalf} 71 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/VariousXGates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Gate} from "../circuit/Gate.js" 18 | import {Matrix} from "../math/Matrix.js" 19 | 20 | let VariousXGates = {}; 21 | 22 | VariousXGates.X3 = Gate.fromKnownMatrix( 23 | "X^⅓", 24 | Matrix.fromPauliRotation(1 / 6, 0, 0), 25 | "X^⅓ Gate", 26 | "Principle third root of X."); 27 | VariousXGates.X3i = Gate.fromKnownMatrix( 28 | "X^-⅓", 29 | Matrix.fromPauliRotation(-1 / 6, 0, 0), 30 | "X^-⅓ Gate", 31 | "Adjoint third root of X.", 32 | undefined, 33 | VariousXGates.X3); 34 | VariousXGates.X4 = Gate.fromKnownMatrix( 35 | "X^¼", 36 | Matrix.fromPauliRotation(1 / 8, 0, 0), 37 | "X^¼ Gate", 38 | "Principle fourth root of X."); 39 | VariousXGates.X4i = Gate.fromKnownMatrix( 40 | "X^-¼", 41 | Matrix.fromPauliRotation(-1 / 8, 0, 0), 42 | "X^-¼ Gate", 43 | "Adjoint fourth root of X.", 44 | undefined, 45 | VariousXGates.X4); 46 | VariousXGates.X8 = Gate.fromKnownMatrix( 47 | "X^⅛", 48 | Matrix.fromPauliRotation(1 / 16, 0, 0), 49 | "X^⅛ Gate", 50 | "Principle eighth root of X."); 51 | VariousXGates.X8i = Gate.fromKnownMatrix( 52 | "X^-⅛", 53 | Matrix.fromPauliRotation(-1 / 16, 0, 0), 54 | "X^-⅛ Gate", 55 | "Adjoint eighth root of X.", 56 | undefined, 57 | VariousXGates.X8); 58 | VariousXGates.X16 = Gate.fromKnownMatrix( 59 | "X^⅟₁₆", 60 | Matrix.fromPauliRotation(1 / 32, 0, 0), 61 | "X^⅟₁₆ Gate", 62 | "Principle sixteenth root of X."); 63 | VariousXGates.X16i = Gate.fromKnownMatrix( 64 | "X^-⅟₁₆", 65 | Matrix.fromPauliRotation(-1 / 32, 0, 0), 66 | "X^-⅟₁₆ Gate", 67 | "Adjoint sixteenth root of X.", 68 | undefined, 69 | VariousXGates.X16); 70 | VariousXGates.X32 = Gate.fromKnownMatrix( 71 | "X^⅟₃₂", 72 | Matrix.fromPauliRotation(1 / 64, 0, 0), 73 | "X^⅟₃₂ Gate", 74 | "Principle 32'nd root of X."); 75 | VariousXGates.X32i = Gate.fromKnownMatrix( 76 | "X^-⅟₃₂", 77 | Matrix.fromPauliRotation(-1 / 64, 0, 0), 78 | "X^-⅟₃₂ Gate", 79 | "Adjoint 32'nd root of X.", 80 | undefined, 81 | VariousXGates.X32); 82 | 83 | VariousXGates.all =[ 84 | VariousXGates.X3, 85 | VariousXGates.X4, 86 | VariousXGates.X8, 87 | VariousXGates.X16, 88 | VariousXGates.X32, 89 | VariousXGates.X3i, 90 | VariousXGates.X4i, 91 | VariousXGates.X8i, 92 | VariousXGates.X16i, 93 | VariousXGates.X32i, 94 | ]; 95 | 96 | export {VariousXGates} 97 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/VariousYGates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Gate} from "../circuit/Gate.js" 18 | import {Matrix} from "../math/Matrix.js" 19 | 20 | let VariousYGates = {}; 21 | 22 | VariousYGates.Y3 = Gate.fromKnownMatrix( 23 | "Y^⅓", 24 | Matrix.fromPauliRotation(0, 1 / 6, 0), 25 | "Y^⅓ Gate", 26 | "Principle third root of Y."); 27 | VariousYGates.Y3i = Gate.fromKnownMatrix( 28 | "Y^-⅓", 29 | Matrix.fromPauliRotation(0, -1 / 6, 0), 30 | "Y^-⅓ Gate", 31 | "Adjoint third root of Y.", 32 | undefined, 33 | VariousYGates.Y3); 34 | VariousYGates.Y4 = Gate.fromKnownMatrix( 35 | "Y^¼", 36 | Matrix.fromPauliRotation(0, 1 / 8, 0), 37 | "Y^¼ Gate", 38 | "Principle fourth root of Y."); 39 | VariousYGates.Y4i = Gate.fromKnownMatrix( 40 | "Y^-¼", 41 | Matrix.fromPauliRotation(0, -1 / 8, 0), 42 | "Y^-¼ Gate", 43 | "Adjoint fourth root of Y.", 44 | undefined, 45 | VariousYGates.Y4); 46 | VariousYGates.Y8 = Gate.fromKnownMatrix( 47 | "Y^⅛", 48 | Matrix.fromPauliRotation(0, 1 / 16, 0), 49 | "Y^⅛ Gate", 50 | "Principle eighth root of Y."); 51 | VariousYGates.Y8i = Gate.fromKnownMatrix( 52 | "Y^-⅛", 53 | Matrix.fromPauliRotation(0, -1 / 16, 0), 54 | "Y^-⅛ Gate", 55 | "Adjoint eighth root of Y.", 56 | undefined, 57 | VariousYGates.Y8); 58 | VariousYGates.Y16 = Gate.fromKnownMatrix( 59 | "Y^⅟₁₆", 60 | Matrix.fromPauliRotation(0, 1 / 32, 0), 61 | "Y^⅟₁₆ Gate", 62 | "Principle sixteenth root of Y."); 63 | VariousYGates.Y16i = Gate.fromKnownMatrix( 64 | "Y^-⅟₁₆", 65 | Matrix.fromPauliRotation(0, -1 / 32, 0), 66 | "Y^-⅟₁₆ Gate", 67 | "Adjoint sixteenth root of Y.", 68 | undefined, 69 | VariousYGates.Y16); 70 | VariousYGates.Y32 = Gate.fromKnownMatrix( 71 | "Y^⅟₃₂", 72 | Matrix.fromPauliRotation(0, 1 / 64, 0), 73 | "Y^⅟₃₂ Gate", 74 | "Principle 32'nd root of Y."); 75 | VariousYGates.Y32i = Gate.fromKnownMatrix( 76 | "Y^-⅟₃₂", 77 | Matrix.fromPauliRotation(0, -1 / 64, 0), 78 | "Y^-⅟₃₂ Gate", 79 | "Adjoint 32'nd root of Y.", 80 | undefined, 81 | VariousYGates.Y32); 82 | 83 | VariousYGates.all =[ 84 | VariousYGates.Y3, 85 | VariousYGates.Y4, 86 | VariousYGates.Y8, 87 | VariousYGates.Y16, 88 | VariousYGates.Y32, 89 | VariousYGates.Y3i, 90 | VariousYGates.Y4i, 91 | VariousYGates.Y8i, 92 | VariousYGates.Y16i, 93 | VariousYGates.Y32i 94 | ]; 95 | 96 | export {VariousYGates} 97 | -------------------------------------------------------------------------------- /circuit_weaver/src/gates/XorGates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Config} from "../Config.js" 18 | import {Gate} from "../circuit/Gate.js" 19 | import {ketArgs, ketShaderPermute, ketInputGateShaderCode} from "../circuit/KetShaderUtil.js" 20 | 21 | let XorGates = {}; 22 | 23 | const XOR_SHADER = ketShaderPermute( 24 | ketInputGateShaderCode('A'), 25 | ` 26 | float srcMask = mod(read_input_A(), span); 27 | float bitPos = 1.0; 28 | float result = 0.0; 29 | for (int i = 0; i < ${Config.MAX_WIRE_COUNT}; i++) { 30 | float srcBit = mod(floor(srcMask/bitPos), 2.0); 31 | float dstBit = mod(floor(out_id/bitPos), 2.0); 32 | result += (dstBit + srcBit - dstBit * srcBit * 2.0) * bitPos; 33 | bitPos *= 2.0; 34 | } 35 | return result;`); 36 | 37 | XorGates.XorAFamily = Gate.buildFamily(1, 16, (span, builder) => builder. 38 | setSerializedId("^=A" + span). 39 | setSymbol("⊕A"). 40 | setTitle("Xor Gate [input A]"). 41 | setBlurb("Xors input A into the qubits covered by this gate."). 42 | setRequiredContextKeys("Input Range A"). 43 | setKnownEffectToParametrizedPermutation((t, a) => t ^ (a & ((1< XOR_SHADER.withArgs(...ketArgs(ctx, span, ['A'])))); 45 | 46 | XorGates.all = [ 47 | ...XorGates.XorAFamily.all, 48 | ]; 49 | 50 | export {XorGates} 51 | -------------------------------------------------------------------------------- /circuit_weaver/src/issues.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {notifyAboutKnownIssue} from "./fallback.js" 18 | 19 | let canvasCreatedForTesting = document.createElement('canvas'); 20 | let webglContextCreatedForTesting = canvasCreatedForTesting.getContext('webgl') || 21 | canvasCreatedForTesting.getContext('experimental-webgl'); 22 | 23 | /** @returns {!boolean} */ 24 | function detectWebGlNotSupported() { 25 | return webglContextCreatedForTesting === null || webglContextCreatedForTesting === undefined; 26 | } 27 | 28 | function doDetectIssues() { 29 | if (detectWebGlNotSupported()) { 30 | notifyAboutKnownIssue( 31 | "Can't simulate circuits. Your browser doesn't support WebGL, or has it disabled.", 32 | "https://github.com/Strilanc/Quirk/issues/168", 33 | [/Computing circuit values failed/, /Error creating WebGL context./]) 34 | } 35 | } 36 | 37 | export {doDetectIssues, canvasCreatedForTesting, webglContextCreatedForTesting} 38 | -------------------------------------------------------------------------------- /circuit_weaver/src/ui/clear.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @param {!Revision} revision 19 | * @param {!Observable.} obsIsAnyOverlayShowing 20 | */ 21 | function initClear(revision, obsIsAnyOverlayShowing) { 22 | const EMPTY_STATE = '{"cols":[]}'; 23 | 24 | const clearAllButton = /** @type {!HTMLButtonElement} */ document.getElementById('clear-all-button'); 25 | revision.latestActiveCommit().zipLatest(obsIsAnyOverlayShowing, (r, v) => ({r, v})).subscribe(({r, v}) => { 26 | clearAllButton.disabled = r === EMPTY_STATE || v; 27 | }); 28 | clearAllButton.addEventListener('click', () => revision.commit(EMPTY_STATE)); 29 | 30 | const clearCircuitButton = /** @type {!HTMLButtonElement} */ document.getElementById('clear-circuit-button'); 31 | revision.latestActiveCommit().zipLatest(obsIsAnyOverlayShowing, (r, v) => ({r, v})).subscribe(({r, v}) => { 32 | clearCircuitButton.disabled = r === _getEmptyCircuitState(revision) || v; 33 | }); 34 | clearCircuitButton.addEventListener('click', () => revision.commit(_getEmptyCircuitState(revision))); 35 | } 36 | 37 | /** 38 | * Returns current state without circuit. Keeps all custom gates. 39 | * @param {!Revision} revision 40 | * @returns {!string} 41 | */ 42 | function _getEmptyCircuitState(revision) { 43 | let val = JSON.parse(revision.peekActiveCommit()); 44 | val["cols"] = []; 45 | 46 | return JSON.stringify(val); 47 | } 48 | 49 | export {initClear} 50 | -------------------------------------------------------------------------------- /circuit_weaver/src/ui/sim.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {CircuitDefinition} from "../circuit/CircuitDefinition.js" 18 | import {Config} from "../Config.js" 19 | import {CircuitStats} from "../circuit/CircuitStats.js" 20 | 21 | const getCircuitCycleTime = (() => { 22 | /** 23 | * Milliseconds. 24 | * @type {!number} 25 | */ 26 | let _circuitCycleTime = 0; 27 | /** 28 | * Milliseconds. 29 | * @type {!number} 30 | */ 31 | let _prevRealTime = performance.now(); 32 | 33 | return () => { 34 | let nextRealTime = performance.now(); 35 | let elapsed = (nextRealTime - _prevRealTime) / Config.CYCLE_DURATION_MS; 36 | _circuitCycleTime += elapsed; 37 | _circuitCycleTime %= 1; 38 | _prevRealTime = nextRealTime; 39 | return _circuitCycleTime; 40 | }; 41 | })(); 42 | 43 | /** @type {undefined|!CircuitStats} */ 44 | let _cachedStats = undefined; 45 | 46 | /** 47 | * @param {!CircuitDefinition} circuit 48 | * @returns {!CircuitStats} 49 | */ 50 | function simulate(circuit) { 51 | if (_cachedStats !== undefined && _cachedStats.circuitDefinition.isEqualTo(circuit)) { 52 | return _cachedStats.withTime(getCircuitCycleTime()); 53 | } 54 | 55 | _cachedStats = undefined; 56 | let result = CircuitStats.fromCircuitAtTime(circuit, getCircuitCycleTime()); 57 | if (circuit.stableDuration() === Infinity) { 58 | _cachedStats = result; 59 | } 60 | return result; 61 | } 62 | 63 | export {simulate, getCircuitCycleTime} 64 | -------------------------------------------------------------------------------- /circuit_weaver/src/ui/title.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Config} from "../Config.js" 18 | import {fromJsonText_CircuitDefinition} from "../circuit/Serializer.js" 19 | 20 | /** 21 | * @param {!Revision} revision 22 | */ 23 | function initTitleSync(revision) { 24 | const titleForState = jsonText => { 25 | //noinspection UnusedCatchParameterJS,EmptyCatchBlockJS 26 | try { 27 | let circuitDef = fromJsonText_CircuitDefinition(jsonText); 28 | if (!circuitDef.isEmpty()) { 29 | return `Quirk: ${circuitDef.readableHash()}`; 30 | } 31 | } catch (_) { 32 | } 33 | return Config.EMPTY_CIRCUIT_TITLE; 34 | }; 35 | 36 | revision.latestActiveCommit().subscribe(jsonText => { 37 | // Add a slight delay, so that history changes use the old title. 38 | setTimeout(() => { document.title = titleForState(jsonText); }, 0); 39 | }); 40 | } 41 | 42 | export {initTitleSync} 43 | -------------------------------------------------------------------------------- /circuit_weaver/src/ui/undo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @param {!Revision} revision 19 | * @param {!Observable.} obsIsAnyOverlayShowing 20 | */ 21 | function initUndoRedo(revision, obsIsAnyOverlayShowing) { 22 | const overlay_divs = [ 23 | document.getElementById('gate-forge-div'), 24 | document.getElementById('export-div') 25 | ]; 26 | 27 | const undoButton = /** @type {!HTMLButtonElement} */ document.getElementById('undo-button'); 28 | const redoButton = /** @type {!HTMLButtonElement} */ document.getElementById('redo-button'); 29 | revision.latestActiveCommit().zipLatest(obsIsAnyOverlayShowing, (_, b) => b).subscribe(anyShowing => { 30 | undoButton.disabled = revision.isAtBeginningOfHistory() || anyShowing; 31 | redoButton.disabled = revision.isAtEndOfHistory() || anyShowing; 32 | }); 33 | 34 | undoButton.addEventListener('click', () => revision.undo()); 35 | redoButton.addEventListener('click', () => revision.redo()); 36 | 37 | document.addEventListener("keydown", e => { 38 | // Don't capture keystrokes while menus are showing. 39 | for (let div of overlay_divs) { 40 | if (div.style.display !== 'NONE' && div.style.display !== 'none') { 41 | return; 42 | } 43 | } 44 | 45 | const Y_KEY = 89; 46 | const Z_KEY = 90; 47 | let isUndo = e.keyCode === Z_KEY && e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey; 48 | let isRedo1 = e.keyCode === Z_KEY && e.ctrlKey && e.shiftKey && !e.altKey && !e.metaKey; 49 | let isRedo2 = e.keyCode === Y_KEY && e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey; 50 | if (isUndo) { 51 | revision.undo(); 52 | e.preventDefault(); 53 | } 54 | if (isRedo1 || isRedo2) { 55 | revision.redo(); 56 | e.preventDefault(); 57 | } 58 | }); 59 | } 60 | 61 | export {initUndoRedo} 62 | -------------------------------------------------------------------------------- /circuit_weaver/src/webgl/WglMortalValueSlot.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * A place for a value associated with a webgl context, that needs to be re-initialized when the context is lost. 19 | * @template T 20 | */ 21 | class WglMortalValueSlot { 22 | /** 23 | * @param {!function() : T} initializer 24 | * @param {!function(T) : void} deinitializer 25 | * @template T 26 | */ 27 | constructor(initializer, deinitializer) { 28 | /** 29 | * @type {!(function(): T)} 30 | * @template T 31 | */ 32 | this.initializer = initializer; 33 | /** 34 | * @type {!(function(T): void)} 35 | * @template T 36 | */ 37 | this.deinitializer = deinitializer; 38 | /** 39 | * @type {undefined|!int} 40 | * @private 41 | */ 42 | this.lifetimeId = undefined; 43 | /** 44 | * @type {undefined|T} 45 | * @template T 46 | * @private 47 | */ 48 | this.mortalValue = undefined; 49 | } 50 | 51 | /** 52 | * Returns the mortal value stored in the slot, initializing or re-initializing it if necessary. 53 | * @param {!int} lifetimeCounter 54 | * @returns T 55 | */ 56 | initializedValue(lifetimeCounter) { 57 | if (this.lifetimeId !== lifetimeCounter) { 58 | this.ensureDeinitialized(); 59 | this.mortalValue = this.initializer(); 60 | this.lifetimeId = lifetimeCounter; 61 | } 62 | 63 | return this.mortalValue; 64 | } 65 | 66 | /** 67 | * Initializes or re-initializes the stored mortal value, if necessary. 68 | * @param {!int} lifetimeCounter 69 | */ 70 | ensureInitialized(lifetimeCounter) { 71 | this.initializedValue(lifetimeCounter); 72 | } 73 | 74 | /** 75 | * Cleans up the stored mortal value, if necessary. 76 | */ 77 | ensureDeinitialized() { 78 | if (this.lifetimeId !== undefined) { 79 | let val = this.mortalValue; 80 | this.lifetimeId = undefined; 81 | this.mortalValue = undefined; 82 | this.deinitializer(val); 83 | } 84 | } 85 | } 86 | 87 | export {WglMortalValueSlot} 88 | -------------------------------------------------------------------------------- /circuit_weaver/test/circuit/Gate.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat} from "../TestUtil.js" 18 | import {Gate, GateBuilder} from "../../src/circuit/Gate.js" 19 | 20 | import {Matrix} from "../../src/math/Matrix.js" 21 | 22 | let suite = new Suite("Gate"); 23 | 24 | suite.test("toString_runsWithoutFailing", () => { 25 | let g = new GateBuilder().setEffectToTimeVaryingMatrix(_ => Matrix.HADAMARD).gate; 26 | assertThat(g.toString()).isNotEqualTo(null); 27 | }); 28 | 29 | suite.test("stableDuration", () => { 30 | let m0 = Gate.fromKnownMatrix("symbol", Matrix.HADAMARD, "name", "blurb"); 31 | let mt = new GateBuilder().setEffectToTimeVaryingMatrix(t => Matrix.square(t, 0, 0, 0)).gate; 32 | 33 | assertThat(m0.stableDuration()).isEqualTo(Infinity); 34 | assertThat(mt.stableDuration()).isEqualTo(0); 35 | }); 36 | 37 | suite.test("knownMatrixAt", () => { 38 | let m0 = Gate.fromKnownMatrix("symbol", Matrix.HADAMARD, "name", "blurb"); 39 | let mt = new GateBuilder().setEffectToTimeVaryingMatrix(t => Matrix.square(t, 0, 0, 0)).gate; 40 | 41 | assertThat(m0.knownMatrixAt(0)).isEqualTo(Matrix.HADAMARD); 42 | assertThat(m0.knownMatrixAt(0.5)).isEqualTo(Matrix.HADAMARD); 43 | 44 | assertThat(mt.knownMatrixAt(0)).isEqualTo(Matrix.square(0, 0, 0, 0)); 45 | assertThat(mt.knownMatrixAt(0.5)).isEqualTo(Matrix.square(0.5, 0, 0, 0)); 46 | }); 47 | -------------------------------------------------------------------------------- /circuit_weaver/test/circuit/GateColumn.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat, assertTrue, assertFalse} from "../TestUtil.js" 18 | import {GateColumn} from "../../src/circuit/GateColumn.js" 19 | 20 | import {Gates} from "../../src/gates/AllGates.js" 21 | 22 | let suite = new Suite("GateColumn"); 23 | 24 | suite.test("isEqualTo", () => { 25 | // Trivial case: 26 | assertThat(GateColumn.empty(1)).isEqualTo(GateColumn.empty(1)); 27 | assertThat(GateColumn.empty(2)).isNotEqualTo(GateColumn.empty(1)); 28 | 29 | // Equivalence groups: 30 | let groups = [ 31 | [GateColumn.empty(0), GateColumn.empty(0), new GateColumn([]), new GateColumn([])], 32 | [GateColumn.empty(1), GateColumn.empty(1), new GateColumn([undefined]), new GateColumn([undefined])], 33 | [GateColumn.empty(2), GateColumn.empty(2), new GateColumn([undefined, undefined]), 34 | new GateColumn([undefined, undefined])], 35 | [new GateColumn([Gates.HalfTurns.X]), new GateColumn([Gates.HalfTurns.X])], 36 | [new GateColumn([Gates.Controls.Control]), new GateColumn([Gates.Controls.Control])], 37 | [new GateColumn([Gates.HalfTurns.X, undefined]), new GateColumn([Gates.HalfTurns.X, undefined])], 38 | [new GateColumn([undefined, Gates.HalfTurns.X]), new GateColumn([undefined, Gates.HalfTurns.X])] 39 | ]; 40 | for (let g1 of groups) { 41 | for (let g2 of groups) { 42 | for (let e1 of g1) { 43 | for (let e2 of g2) { 44 | if (g1 === g2) { 45 | assertThat(e1).isEqualTo(e2); 46 | assertTrue(e1.isEqualTo(e2)); 47 | } else { 48 | assertThat(e1).isNotEqualTo(e2); 49 | assertFalse(e1.isEqualTo(e2)); 50 | } 51 | } 52 | } 53 | } 54 | } 55 | }); 56 | 57 | suite.test("isEmpty", () => { 58 | assertTrue(GateColumn.empty(0).isEmpty()); 59 | assertTrue(GateColumn.empty(1).isEmpty()); 60 | assertTrue(GateColumn.empty(2).isEmpty()); 61 | assertTrue(GateColumn.empty(10).isEmpty()); 62 | assertTrue(new GateColumn([]).isEmpty()); 63 | assertTrue(new GateColumn([undefined]).isEmpty()); 64 | assertTrue(new GateColumn([undefined, undefined]).isEmpty()); 65 | assertFalse(new GateColumn([Gates.Controls.Control]).isEmpty()); 66 | assertFalse(new GateColumn([Gates.Special.SwapHalf]).isEmpty()); 67 | assertFalse(new GateColumn([Gates.HalfTurns.X]).isEmpty()); 68 | assertFalse(new GateColumn([Gates.HalfTurns.X, undefined]).isEmpty()); 69 | assertFalse(new GateColumn([Gates.HalfTurns.X, Gates.HalfTurns.X]).isEmpty()); 70 | }); 71 | -------------------------------------------------------------------------------- /circuit_weaver/test/circuit/GateShaders.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat} from "../TestUtil.js" 18 | import {GateShaders} from "../../src/circuit/GateShaders.js" 19 | import {assertThatCircuitUpdateActsLikeMatrix} from "../CircuitOperationTestUtil.js" 20 | 21 | import {Complex} from "../../src/math/Complex.js" 22 | import {Seq} from "../../src/base/Seq.js" 23 | import {Shaders} from "../../src/webgl/Shaders.js" 24 | import {Matrix} from "../../src/math/Matrix.js" 25 | 26 | let suite = new Suite("GateShaders"); 27 | 28 | suite.testUsingWebGL('cycleAllBits', () => { 29 | let inp = Shaders.vec2Data(Seq.range(16).flatMap(e => [e*4 + 1, e*4 + 2]).toFloat32Array()).toVec2Texture(4); 30 | let actual = GateShaders.cycleAllBits(inp, -1).readVec2Outputs(4); 31 | assertThat(actual).isEqualTo(new Float32Array([ 32 | 1, 2, 9,10, 17,18, 25,26, 33 | 33,34, 41,42, 49,50, 57,58, 34 | 5, 6, 13,14, 21,22, 29,30, 35 | 37,38, 45,46, 53,54, 61,62 36 | ])); 37 | inp.deallocByDepositingInPool(); 38 | }); 39 | 40 | suite.testUsingWebGL("matrixOperation", () => { 41 | let repeats = 3; 42 | for (let size = 1; size < 5; size++) { 43 | let d = 1< new Complex(Math.random() - 0.5, Math.random() - 0.5)); 45 | assertThatCircuitUpdateActsLikeMatrix( 46 | ctx => GateShaders.applyMatrixOperation(ctx, matrix), 47 | matrix, 48 | repeats); 49 | } 50 | }); 51 | -------------------------------------------------------------------------------- /circuit_weaver/test/circuit/KetShaderUtil.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite} from "../TestUtil.js" 18 | import {ketArgs, ketShader, ketShaderPermute, ketShaderPhase} from "../../src/circuit/KetShaderUtil.js" 19 | import {assertThatCircuitShaderActsLikeMatrix} from "../CircuitOperationTestUtil.js" 20 | import {Complex} from "../../src/math/Complex.js" 21 | import {Matrix} from "../../src/math/Matrix.js" 22 | import {WglArg} from "../../src/webgl/WglArg.js" 23 | 24 | let suite = new Suite("KetShaderUtil"); 25 | 26 | suite.testUsingWebGL("ketShader", () => { 27 | let shader = ketShader( 28 | 'uniform vec2 a, b, c, d;', 29 | 'return cmul(inp(0.0), a+(c-a)*out_id) + cmul(inp(1.0), b+(d-b)*out_id);', 30 | 1); 31 | assertThatCircuitShaderActsLikeMatrix( 32 | ctx => shader.withArgs( 33 | ...ketArgs(ctx), 34 | WglArg.vec2("a", 2, 3), 35 | WglArg.vec2("b", 5, 7), 36 | WglArg.vec2("c", 11, 13), 37 | WglArg.vec2("d", 17, 19)), 38 | new Matrix(2, 2, new Float32Array([2, 3, 5, 7, 11, 13, 17, 19]))); 39 | }); 40 | 41 | suite.testUsingWebGL("ketShaderPermute", () => { 42 | let shader = ketShaderPermute( 43 | '', 44 | 'return mod(out_id + 1.0, 4.0);', 45 | 2); 46 | assertThatCircuitShaderActsLikeMatrix( 47 | ctx => shader.withArgs(...ketArgs(ctx)), 48 | Matrix.generateTransition(4, i => (i - 1) & 3)); 49 | }); 50 | 51 | suite.testUsingWebGL("ketShaderPhase", () => { 52 | let shader = ketShaderPhase( 53 | '', 54 | 'return out_id/10.0;', 55 | 3); 56 | assertThatCircuitShaderActsLikeMatrix( 57 | ctx => shader.withArgs(...ketArgs(ctx)), 58 | Matrix.generateDiagonal(8, i => Complex.polar(1, i/10))); 59 | }); 60 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/ArithmeticGates.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite} from "../TestUtil.js" 18 | import {ArithmeticGates} from "../../src/gates/ArithmeticGates.js" 19 | import {InputGates} from "../../src/gates/InputGates.js" 20 | import { 21 | assertThatCircuitUpdateActsLikeMatrix, 22 | assertThatGateActsLikePermutation, 23 | } from "../CircuitOperationTestUtil.js" 24 | import {advanceStateWithCircuit} from "../../src/circuit/CircuitComputeUtil.js" 25 | 26 | import {CircuitDefinition} from "../../src/circuit/CircuitDefinition.js" 27 | import {GateColumn} from "../../src/circuit/GateColumn.js" 28 | import {Matrix} from "../../src/math/Matrix.js" 29 | 30 | let suite = new Suite("ArithmeticGates"); 31 | 32 | suite.testUsingWebGL('plus_A', () => { 33 | assertThatCircuitUpdateActsLikeMatrix( 34 | ctx => advanceStateWithCircuit( 35 | ctx, 36 | new CircuitDefinition(4, [new GateColumn([ 37 | ArithmeticGates.PlusAFamily.ofSize(2), undefined, InputGates.InputAFamily.ofSize(2), undefined])]), 38 | false), 39 | Matrix.generateTransition(16, i => { 40 | let a = (i >> 2) & 3; 41 | let t = i & 3; 42 | return (a<<2) | (t+a)&3; 43 | })); 44 | }); 45 | 46 | suite.testUsingWebGL('minus_A', () => { 47 | assertThatCircuitUpdateActsLikeMatrix( 48 | ctx => advanceStateWithCircuit( 49 | ctx, 50 | new CircuitDefinition(4, [new GateColumn([ 51 | InputGates.InputAFamily.ofSize(2), undefined, ArithmeticGates.MinusAFamily.ofSize(2), undefined])]), 52 | false), 53 | Matrix.generateTransition(16, i => { 54 | let a = i & 3; 55 | let t = (i >> 2) & 3; 56 | return a | (((t-a)&3)<<2); 57 | })); 58 | }); 59 | 60 | suite.testUsingWebGL('plus_minus_A_like_permutation', () => { 61 | assertThatGateActsLikePermutation( 62 | ArithmeticGates.PlusAFamily.ofSize(3), 63 | (t, a) => (t + a) & 7, 64 | [2]); 65 | 66 | assertThatGateActsLikePermutation( 67 | ArithmeticGates.MinusAFamily.ofSize(3), 68 | (t, a) => (t - a) & 7, 69 | [4]); 70 | }); 71 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/BitCountGates.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite} from "../TestUtil.js" 18 | import {BitCountGates} from "../../src/gates/BitCountGates.js" 19 | import {InputGates} from "../../src/gates/InputGates.js" 20 | import {assertThatCircuitUpdateActsLikeMatrix} from "../CircuitOperationTestUtil.js" 21 | import {advanceStateWithCircuit} from "../../src/circuit/CircuitComputeUtil.js" 22 | 23 | import {CircuitDefinition} from "../../src/circuit/CircuitDefinition.js" 24 | import {Matrix} from "../../src/math/Matrix.js" 25 | import {Util} from "../../src/base/Util.js" 26 | 27 | let suite = new Suite("BitCountGates"); 28 | 29 | let GATE_SET = new Map([ 30 | ['A', InputGates.InputAFamily], 31 | ['-', undefined], 32 | ['/', null], 33 | ['P', BitCountGates.PlusBitCountAFamily], 34 | ['M', BitCountGates.MinusBitCountAFamily] 35 | ]); 36 | 37 | suite.testUsingWebGL('PlusBitCountA', () => { 38 | assertThatCircuitUpdateActsLikeMatrix( 39 | ctx => advanceStateWithCircuit( 40 | ctx, 41 | CircuitDefinition.fromTextDiagram(GATE_SET, 42 | `-A- 43 | -/- 44 | -/- 45 | -P- 46 | -/-`), 47 | false), 48 | Matrix.generateTransition(1<<5, i => { 49 | let a = i & 7; 50 | let t = (i >> 3) & 3; 51 | t += Util.numberOfSetBits(a); 52 | t &= 3; 53 | return a | (t << 3); 54 | })); 55 | }); 56 | 57 | suite.testUsingWebGL('MinusBitCountA', () => { 58 | assertThatCircuitUpdateActsLikeMatrix( 59 | ctx => advanceStateWithCircuit( 60 | ctx, 61 | CircuitDefinition.fromTextDiagram(GATE_SET, 62 | `-A- 63 | -/- 64 | -/- 65 | -M- 66 | -/-`), 67 | false), 68 | Matrix.generateTransition(1<<5, i => { 69 | let a = i & 7; 70 | let t = (i >> 3) & 3; 71 | t -= Util.numberOfSetBits(a); 72 | t &= 3; 73 | return a | (t << 3); 74 | })); 75 | }); 76 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/CycleBitsGates.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite} from "../TestUtil.js" 18 | import {assertThatCircuitShaderActsLikeMatrix} from "../CircuitOperationTestUtil.js" 19 | import {cycleBitsShader} from "../../src/gates/CycleBitsGates.js" 20 | 21 | import {Matrix} from "../../src/math/Matrix.js" 22 | 23 | let suite = new Suite("CycleBitsGates"); 24 | 25 | suite.testUsingWebGL('cycleBitsShader', () => { 26 | assertThatCircuitShaderActsLikeMatrix( 27 | ctx => cycleBitsShader(ctx, 3, 2), 28 | Matrix.generateTransition(8, i => ((i&1)<<2) | ((i>>1)&3))); 29 | assertThatCircuitShaderActsLikeMatrix( 30 | ctx => cycleBitsShader(ctx, 4, -2), 31 | Matrix.generateTransition(16, i => ((i&3)<<2) | ((i>>2)&3))); 32 | }); 33 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/DensityMatrixDisplay.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat} from "../TestUtil.js" 18 | import {amplitudesToCouplings} from "../../src/gates/DensityMatrixDisplay.js" 19 | import {Shaders} from "../../src/webgl/Shaders.js" 20 | 21 | let suite = new Suite("DensityMatrixDisplay"); 22 | 23 | suite.testUsingWebGL("amplitudesToCouplings", () => { 24 | let s = Math.sqrt(0.5); 25 | let inp = Shaders.vec2Data(new Float32Array([ 26 | s,0, 27 | 0,0, 28 | 0,0, 29 | s,0 30 | ])).toVec2Texture(2); 31 | 32 | assertThat(amplitudesToCouplings(inp, 1).readVec2Outputs(3)).isApproximatelyEqualTo(new Float32Array([ 33 | 0.5,0, 0,0, 34 | 0, 0, 0,0, 35 | 36 | 0, 0, 0,0, 37 | 0, 0, 0.5,0 38 | ])); 39 | assertThat(amplitudesToCouplings(inp, 2).readVec2Outputs(4)).isApproximatelyEqualTo(new Float32Array([ 40 | 0.5,0, 0,0, 0,0, 0.5,0, 41 | 0,0, 0,0, 0,0, 0,0, 42 | 0,0, 0,0, 0,0, 0,0, 43 | 0.5,0, 0,0, 0,0, 0.5,0 44 | ])); 45 | 46 | inp.deallocByDepositingInPool(); 47 | }); 48 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/ExponentiatingGates.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat} from "../TestUtil.js" 18 | import {Gates} from "../../src/gates/AllGates.js" 19 | import {Complex} from "../../src/math/Complex.js" 20 | import {Matrix} from "../../src/math/Matrix.js" 21 | 22 | let suite = new Suite("ExponentiatingGates"); 23 | 24 | suite.test("timeBased_matchUnoptimized", () => { 25 | let matches = (gate, func) => { 26 | for (let t = 0; t < 1; t += 0.05) { 27 | assertThat(gate.knownMatrixAt(t)).isApproximatelyEqualTo(func(t), 0.0000001); 28 | } 29 | }; 30 | 31 | let i = Complex.I; 32 | let τ = Math.PI * 2; 33 | matches( 34 | Gates.Exponentiating.XForward, 35 | t => Matrix.PAULI_X.liftApply(c => c.times(τ * -t).times(i).exp())); 36 | matches( 37 | Gates.Exponentiating.XBackward, 38 | t => Matrix.PAULI_X.liftApply(c => c.times(τ * t).times(i).exp())); 39 | matches( 40 | Gates.Exponentiating.YForward, 41 | t => Matrix.PAULI_Y.liftApply(c => c.times(τ * -t).times(i).exp())); 42 | matches( 43 | Gates.Exponentiating.YBackward, 44 | t => Matrix.PAULI_Y.liftApply(c => c.times(τ * t).times(i).exp())); 45 | matches( 46 | Gates.Exponentiating.ZForward, 47 | t => Matrix.PAULI_Z.liftApply(c => c.times(τ * -t).times(i).exp())); 48 | matches( 49 | Gates.Exponentiating.ZBackward, 50 | t => Matrix.PAULI_Z.liftApply(c => c.times(τ * t).times(i).exp())); 51 | 52 | matches( 53 | Gates.Powering.XForward, 54 | t => Matrix.PAULI_X.liftApply(c => c.raisedTo(t * 2))); 55 | matches( 56 | Gates.Powering.XBackward, 57 | t => Matrix.PAULI_X.liftApply(c => c.raisedTo(-t * 2))); 58 | matches( 59 | Gates.Powering.YForward, 60 | t => Matrix.PAULI_Y.liftApply(c => c.raisedTo(t * 2))); 61 | matches( 62 | Gates.Powering.YBackward, 63 | t => Matrix.PAULI_Y.liftApply(c => c.raisedTo(-t * 2))); 64 | matches( 65 | Gates.Powering.ZForward, 66 | t => Matrix.PAULI_Z.liftApply(c => c.raisedTo(t * 2))); 67 | matches( 68 | Gates.Powering.ZBackward, 69 | t => Matrix.PAULI_Z.liftApply(c => c.raisedTo(-t * 2))); 70 | }); 71 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/FourierTransformGates.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite} from "../TestUtil.js" 18 | import {assertThatCircuitUpdateActsLikeMatrix} from "../CircuitOperationTestUtil.js" 19 | import {applyControlledPhaseGradient, FourierTransformGates} from "../../src/gates/FourierTransformGates.js" 20 | import {CircuitDefinition} from "../../src/circuit/CircuitDefinition.js" 21 | import {GateColumn} from "../../src/circuit/GateColumn.js" 22 | import {advanceStateWithCircuit} from "../../src/circuit/CircuitComputeUtil.js" 23 | 24 | import {Complex} from "../../src/math/Complex.js" 25 | import {Matrix} from "../../src/math/Matrix.js" 26 | 27 | let suite = new Suite("FourierTransformGates"); 28 | 29 | suite.testUsingWebGL('controlledPhaseGradient', () => { 30 | assertThatCircuitUpdateActsLikeMatrix( 31 | ctx => applyControlledPhaseGradient(ctx, 3, 1), 32 | Matrix.generateDiagonal(8, i => i < 4 ? 1 : Complex.polar(1, (i-4)*Math.PI/4))); 33 | 34 | assertThatCircuitUpdateActsLikeMatrix( 35 | ctx => applyControlledPhaseGradient(ctx, 4, -1), 36 | Matrix.generateDiagonal(16, i => i < 8 ? 1 : Complex.polar(1, -(i-8)*Math.PI/8))); 37 | }); 38 | 39 | suite.testUsingWebGL('fourierTransform', () => { 40 | assertThatCircuitUpdateActsLikeMatrix( 41 | ctx => advanceStateWithCircuit( 42 | ctx, 43 | new CircuitDefinition(2, [new GateColumn([ 44 | FourierTransformGates.FourierTransformFamily.ofSize(2), undefined])]), 45 | false).output, 46 | Matrix.generate(4, 4, (i, j) => Complex.polar(0.5, i*j*Math.PI/2))); 47 | 48 | assertThatCircuitUpdateActsLikeMatrix( 49 | ctx => advanceStateWithCircuit( 50 | ctx, 51 | new CircuitDefinition(3, [new GateColumn([ 52 | FourierTransformGates.InverseFourierTransformFamily.ofSize(3), undefined, undefined])]), 53 | false).output, 54 | Matrix.generate(8, 8, (i, j) => Complex.polar(Math.sqrt(1/8), -i*j*Math.PI/4))); 55 | }); 56 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/Impossible_UniversalNotGate.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat} from "../TestUtil.js" 18 | import {CircuitEvalContext} from "../../src/circuit/CircuitEvalContext.js" 19 | import {CircuitShaders} from "../../src/circuit/CircuitShaders.js" 20 | import {universalNot} from "../../src/gates/Impossible_UniversalNotGate.js" 21 | 22 | import {Controls} from "../../src/circuit/Controls.js" 23 | import {Shaders} from "../../src/webgl/Shaders.js" 24 | import {WglTextureTrader} from "../../src/webgl/WglTextureTrader.js" 25 | 26 | let suite = new Suite("Impossible_UniverseNotGate"); 27 | 28 | suite.testUsingWebGL('universalNot', () => { 29 | let input = Shaders.vec2Data(new Float32Array([ 30 | 1,2, 3,4, 31 | 5,6, 7,8 32 | ])).toVec2Texture(2); 33 | let assertAbout = (index, control) => { 34 | let controlTex = CircuitShaders.controlMask(control).toBoolTexture(2); 35 | let trader = new WglTextureTrader(input); 36 | trader.dontDeallocCurrentTexture(); 37 | let ctx = new CircuitEvalContext( 38 | 0, 39 | index, 40 | 2, 41 | control, 42 | controlTex, 43 | control, 44 | trader, 45 | new Map()); 46 | try { 47 | return assertThat(universalNot(ctx).readVec2Outputs(2)); 48 | } finally { 49 | controlTex.deallocByDepositingInPool(); 50 | } 51 | }; 52 | assertAbout(0, Controls.NONE).isEqualTo(new Float32Array([ 53 | 3,-4, -1,2, 54 | 7,-8, -5,6 55 | ])); 56 | assertAbout(1, Controls.NONE).isEqualTo(new Float32Array([ 57 | 5,-6, 7,-8, 58 | -1,2, -3,4 59 | ])); 60 | assertAbout(0, Controls.bit(1, true)).isEqualTo(new Float32Array([ 61 | 1,2, 3,4, 62 | 7,-8, -5,6 63 | ])); 64 | 65 | input.deallocByDepositingInPool(); 66 | }); 67 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/IncrementGates.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite} from "../TestUtil.js" 18 | import {offsetShader, IncrementGates} from "../../src/gates/IncrementGates.js" 19 | import { 20 | assertThatCircuitShaderActsLikePermutation, 21 | assertThatGateActsLikePermutation, 22 | } from "../CircuitOperationTestUtil.js" 23 | 24 | import {ketArgs} from "../../src/circuit/KetShaderUtil.js" 25 | import {WglArg} from "../../src/webgl/WglArg.js" 26 | 27 | let suite = new Suite("ArithmeticGates"); 28 | 29 | suite.testUsingWebGL('offsetShader', () => { 30 | assertThatCircuitShaderActsLikePermutation( 31 | 3, 32 | ctx => offsetShader.withArgs(...ketArgs(ctx, 3), WglArg.float("amount", 5)), 33 | e => (e+5) & 7); 34 | 35 | assertThatCircuitShaderActsLikePermutation( 36 | 6, 37 | ctx => offsetShader.withArgs(...ketArgs(ctx, 6), WglArg.float("amount", -31)), 38 | e => (e-31) & 63); 39 | }); 40 | 41 | suite.testUsingWebGL('IncrementGate', () => { 42 | assertThatGateActsLikePermutation( 43 | IncrementGates.IncrementFamily.ofSize(3), 44 | e => (e + 1) & 7); 45 | 46 | assertThatGateActsLikePermutation( 47 | IncrementGates.DecrementFamily.ofSize(4), 48 | e => (e - 1) & 15); 49 | }); 50 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/InputGates.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {assertThat, Suite} from "../TestUtil.js" 18 | import {CircuitDefinition} from "../../src/circuit/CircuitDefinition.js" 19 | import {CircuitStats} from "../../src/circuit/CircuitStats.js" 20 | import {Gates} from "../../src/gates/AllGates.js" 21 | import {Seq} from "../../src/base/Seq.js" 22 | import {Util} from "../../src/base/Util.js" 23 | 24 | let suite = new Suite("InputGates"); 25 | 26 | const TEST_GATES = new Map([ 27 | ['$', Gates.ModularIncrementGates.DecrementModRFamily], 28 | ['*', Gates.MultiplyAccumulateGates.MultiplyAddInputsFamily], 29 | ['X', Gates.HalfTurns.X], 30 | ['⊕', Gates.XorGates.XorAFamily], 31 | ['A', Gates.InputGates.InputAFamily], 32 | ['B', Gates.InputGates.InputBFamily], 33 | ['R', Gates.InputGates.InputRFamily], 34 | ['∀', Gates.InputGates.InputRevAFamily], 35 | ['ᗺ', Gates.InputGates.InputRevBFamily], 36 | ['-', undefined], 37 | ['/', null], 38 | ]); 39 | const circuit = (diagram, ...extraGates) => CircuitDefinition.fromTextDiagram( 40 | Util.mergeMaps(TEST_GATES, new Map(extraGates)), 41 | diagram); 42 | 43 | suite.testUsingWebGL('endianness', () => { 44 | let output = diagram => { 45 | let stats = CircuitStats.fromCircuitAtTime(circuit(diagram), 0); 46 | return Seq.range(stats.finalState.height()). 47 | filter(i => stats.finalState.cell(0, i).isEqualTo(1)). 48 | first(); 49 | }; 50 | 51 | assertThat(output(`-X-A- 52 | ---/- 53 | ---/- 54 | ----- 55 | ---⊕- 56 | ---/- 57 | ---/-`)).isEqualTo(0b0010001); 58 | 59 | assertThat(output(`-X-∀- 60 | ---/- 61 | ---/- 62 | ----- 63 | ---⊕- 64 | ---/- 65 | ---/-`)).isEqualTo(0b1000001); 66 | 67 | assertThat(output(`---$- 68 | ---/- 69 | ---/- 70 | ---/- 71 | -X-R- 72 | -X-/- 73 | ---/- 74 | -X-/-`)).isEqualTo(0b10111010); 75 | 76 | assertThat(output(`---*- 77 | ---/- 78 | -X-A- 79 | -X-B- 80 | ---/-`)).isEqualTo(0b01101); 81 | 82 | assertThat(output(`---*- 83 | ---/- 84 | -X-A- 85 | -X-ᗺ- 86 | ---/-`)).isEqualTo(0b01110); 87 | }); 88 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/ModularAdditionGates.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite} from "../TestUtil.js" 18 | import {assertThatGateActsLikePermutation, assertThatCircuitOutputsBasisKet} from "../CircuitOperationTestUtil.js" 19 | 20 | import {ModularAdditionGates} from "../../src/gates/ModularAdditionGates.js" 21 | import {InputGates} from "../../src/gates/InputGates.js" 22 | import {CircuitDefinition} from "../../src/circuit/CircuitDefinition.js" 23 | import {Util} from "../../src/base/Util.js" 24 | 25 | let suite = new Suite("ModularAdditionGates"); 26 | 27 | suite.testUsingWebGL('plus_A_mod_R_permutation', () => { 28 | assertThatGateActsLikePermutation( 29 | ModularAdditionGates.PlusAModRFamily.ofSize(2), 30 | (t, a, b) => t < b ? (t + a) % b : t, 31 | [2, 2]); 32 | 33 | assertThatGateActsLikePermutation( 34 | ModularAdditionGates.PlusAModRFamily.ofSize(3), 35 | (t, a, b) => t < b ? (t + a) % b : t, 36 | [1, 2]); 37 | 38 | assertThatGateActsLikePermutation( 39 | ModularAdditionGates.PlusAModRFamily.ofSize(2), 40 | (t, a, b) => t < b ? (t + a) % b : t, 41 | [3, 2]); 42 | }); 43 | 44 | suite.testUsingWebGL('minus_A_mod_R_permutation', () => { 45 | assertThatGateActsLikePermutation( 46 | ModularAdditionGates.MinusAModRFamily.ofSize(2), 47 | (t, a, b) => t < b ? Util.properMod(t - a, b) : t, 48 | [2, 2]); 49 | 50 | assertThatGateActsLikePermutation( 51 | ModularAdditionGates.MinusAModRFamily.ofSize(3), 52 | (t, a, b) => t < b ? Util.properMod(t - a, b) : t, 53 | [1, 2]); 54 | 55 | assertThatGateActsLikePermutation( 56 | ModularAdditionGates.MinusAModRFamily.ofSize(2), 57 | (t, a, b) => t < b ? Util.properMod(t - a, b) : t, 58 | [3, 2]); 59 | }); 60 | 61 | suite.testUsingWebGL('plus_A_mod_R_no_nan', () => { 62 | let circuit = CircuitDefinition.fromTextDiagram(new Map([ 63 | ['a', InputGates.SetA.withParam(0)], 64 | ['r', InputGates.SetR.withParam(33)], 65 | ['p', ModularAdditionGates.PlusAModRFamily], 66 | ['-', undefined], 67 | ['/', null], 68 | ]), `-a-p- 69 | ---/- 70 | -r-/- 71 | ---/- 72 | ---/- 73 | ---/-`); 74 | assertThatCircuitOutputsBasisKet(circuit, 0); 75 | }); 76 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/ModularMultiplyAccumulateGates.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite} from "../TestUtil.js" 18 | import {assertThatGateActsLikePermutation} from "../CircuitOperationTestUtil.js" 19 | 20 | import {ModularMultiplyAccumulateGates} from "../../src/gates/ModularMultiplyAccumulateGates.js" 21 | import {Util} from "../../src/base/Util.js" 22 | 23 | let suite = new Suite("ModularMultiplyAccumulateGates"); 24 | 25 | suite.testUsingWebGL('plus_AB_mod_R_permutation', () => { 26 | assertThatGateActsLikePermutation( 27 | ModularMultiplyAccumulateGates.PlusABModRFamily.ofSize(2), 28 | (t, a, b, r) => t < r ? (t + a*b) % r : t, 29 | [2, 2, 2]); 30 | }); 31 | 32 | suite.testUsingWebGL('minus_AB_mod_R_permutation', () => { 33 | assertThatGateActsLikePermutation( 34 | ModularMultiplyAccumulateGates.MinusABModRFamily.ofSize(2), 35 | (t, a, b, r) => t < r ? Util.properMod(t - a*b, r) : t, 36 | [2, 2, 2]); 37 | }); 38 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/MultiplicationGates.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite} from "../TestUtil.js" 18 | import {Gates} from "../../src/gates/AllGates.js" 19 | import {CircuitDefinition} from "../../src/circuit/CircuitDefinition.js" 20 | import {modularMultiply, modularUnmultiply} from "../../src/gates/ModularMultiplicationGates.js" 21 | import {assertThatGateActsLikePermutation, assertThatCircuitOutputsBasisKet} from "../CircuitOperationTestUtil.js" 22 | 23 | let suite = new Suite("MultiplicationGates"); 24 | 25 | suite.testUsingWebGL('multiplication_gate', () => { 26 | assertThatGateActsLikePermutation( 27 | Gates.MultiplicationGates.TimesAFamily.ofSize(4), 28 | (x, a) => modularMultiply(x, a, 1<<4), 29 | [4]); 30 | 31 | assertThatGateActsLikePermutation( 32 | Gates.MultiplicationGates.TimesAFamily.ofSize(2), 33 | (x, a) => modularMultiply(x, a, 1<<2), 34 | [4]); 35 | }); 36 | 37 | suite.testUsingWebGL('inverse_multiplication_gate', () => { 38 | assertThatGateActsLikePermutation( 39 | Gates.MultiplicationGates.TimesAInverseFamily.ofSize(4), 40 | (x, a) => modularUnmultiply(x, a, 1<<4), 41 | [4]); 42 | 43 | assertThatGateActsLikePermutation( 44 | Gates.MultiplicationGates.TimesAInverseFamily.ofSize(2), 45 | (x, a) => modularUnmultiply(x, a, 1<<2), 46 | [4]); 47 | }); 48 | 49 | suite.testUsingWebGL('times_big_A', () => { 50 | let circuit = CircuitDefinition.fromTextDiagram(new Map([ 51 | ['a', Gates.InputGates.SetA.withParam(16385)], 52 | ['*', Gates.MultiplicationGates.TimesAFamily], 53 | ['X', Gates.HalfTurns.X], 54 | ['-', undefined], 55 | ['/', null], 56 | ]), `-a-X-*- 57 | -----/- 58 | -----/- 59 | -----/- 60 | -----/- 61 | -----/- 62 | -----/- 63 | -----/- 64 | -----/- 65 | -----/- 66 | -----/- 67 | -----/- 68 | -----/- 69 | ---X-/- 70 | -----/- 71 | -----/-`); 72 | assertThatCircuitOutputsBasisKet(circuit, 24577); 73 | }); 74 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/PhaseGradientGates.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite} from "../TestUtil.js" 18 | import { 19 | assertThatCircuitShaderActsLikeMatrix, 20 | assertThatGateActsLikePhaser, 21 | } from "../CircuitOperationTestUtil.js" 22 | import {PHASE_GRADIENT_SHADER, PhaseGradientGates} from "../../src/gates/PhaseGradientGates.js" 23 | 24 | import {Complex} from "../../src/math/Complex.js" 25 | import {Matrix} from "../../src/math/Matrix.js" 26 | import {ketArgs} from "../../src/circuit/KetShaderUtil.js" 27 | import {WglArg} from "../../src/webgl/WglArg.js" 28 | 29 | let suite = new Suite("PhaseGradientGates"); 30 | 31 | suite.testUsingWebGL('PHASE_GRADIENT_SHADER', () => { 32 | assertThatCircuitShaderActsLikeMatrix( 33 | ctx => PHASE_GRADIENT_SHADER.withArgs(...ketArgs(ctx, 3), WglArg.float('factor', Math.PI/8)), 34 | Matrix.generateDiagonal(8, i => Complex.polar(1, i*Math.PI/8))); 35 | 36 | assertThatCircuitShaderActsLikeMatrix( 37 | ctx => PHASE_GRADIENT_SHADER.withArgs(...ketArgs(ctx, 4), WglArg.float('factor', -Math.PI/16)), 38 | Matrix.generateDiagonal(16, i => Complex.polar(1, -i*Math.PI/16))); 39 | }); 40 | 41 | suite.testUsingWebGL('DynamicPhaseGradientFamily', () => { 42 | assertThatGateActsLikePhaser( 43 | PhaseGradientGates.DynamicPhaseGradientFamily.ofSize(3), 44 | k => 0.3*k, 45 | 0.3); 46 | 47 | assertThatGateActsLikePhaser( 48 | PhaseGradientGates.DynamicPhaseDegradientFamily.ofSize(2), 49 | k => -0.1*k, 50 | 0.1); 51 | }); 52 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/PivotFlipGates.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite} from "../TestUtil.js" 18 | import {assertThatCircuitOutputsBasisKet} from "../CircuitOperationTestUtil.js" 19 | 20 | import {PivotFlipGates} from "../../src/gates/PivotFlipGates.js" 21 | import {Gates} from "../../src/gates/AllGates.js" 22 | import {CircuitDefinition} from "../../src/circuit/CircuitDefinition.js" 23 | 24 | let suite = new Suite("PivotFlipGates"); 25 | 26 | suite.testUsingWebGL('pivot_flip', () => { 27 | let circ = diagram => CircuitDefinition.fromTextDiagram(new Map([ 28 | ['5', Gates.InputGates.SetA.withParam(5)], 29 | ['X', Gates.HalfTurns.X], 30 | ['F', PivotFlipGates.FlipUnderA], 31 | ['-', undefined], 32 | ['/', null], 33 | ]), diagram); 34 | 35 | assertThatCircuitOutputsBasisKet(circ(`-5-F- 36 | ---/- 37 | ---/- 38 | ---/-`), 4); 39 | 40 | assertThatCircuitOutputsBasisKet(circ(`-X-5-F- 41 | -----/- 42 | -----/- 43 | -----/-`), 3); 44 | 45 | assertThatCircuitOutputsBasisKet(circ(`---5-F- 46 | -X---/- 47 | -----/- 48 | -----/-`), 2); 49 | 50 | assertThatCircuitOutputsBasisKet(circ(`-X-5-F- 51 | -X---/- 52 | -----/- 53 | -----/-`), 1); 54 | 55 | assertThatCircuitOutputsBasisKet(circ(`---5-F- 56 | -----/- 57 | -X---/- 58 | -----/-`), 0); 59 | 60 | assertThatCircuitOutputsBasisKet(circ(`-X-5-F- 61 | -----/- 62 | -X---/- 63 | -----/-`), 5); 64 | 65 | assertThatCircuitOutputsBasisKet(circ(`-X-5-F- 66 | -----/- 67 | -X---/- 68 | -X---/-`), 13); 69 | }); 70 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/ProbabilityDisplay.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat} from "../TestUtil.js" 18 | import {amplitudesToProbabilities} from "../../src/gates/ProbabilityDisplay.js" 19 | 20 | import {CircuitShaders} from "../../src/circuit/CircuitShaders.js" 21 | import {Controls} from "../../src/circuit/Controls.js" 22 | import {Shaders} from "../../src/webgl/Shaders.js" 23 | 24 | let suite = new Suite("ProbabilityDisplay"); 25 | 26 | suite.testUsingWebGL("amplitudesToProbabilities", () => { 27 | let inp = Shaders.vec2Data(new Float32Array([ 28 | 2, 3, 29 | 4, 5, 30 | 6, 7, 31 | 8, 9, 32 | 1/2, 0, 33 | 0, 1/4, 34 | 0, 1/8, 35 | 1/16, 0 36 | ])).toVec2Texture(3); 37 | 38 | let con = CircuitShaders.controlMask(Controls.NONE).toBoolTexture(3); 39 | assertThat(amplitudesToProbabilities(inp, con).readVecFloatOutputs(3)).isApproximatelyEqualTo(new Float32Array([ 40 | 4+9, 41 | 16+25, 42 | 36+49, 43 | 64+81, 44 | 1/4, 45 | 1/16, 46 | 1/64, 47 | 1/256 48 | ])); 49 | 50 | inp.deallocByDepositingInPool(); 51 | con.deallocByDepositingInPool(); 52 | }); 53 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/SampleDisplay.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat} from "../TestUtil.js" 18 | 19 | import {CircuitDefinition} from "../../src/circuit/CircuitDefinition.js" 20 | import {CircuitStats} from "../../src/circuit/CircuitStats.js" 21 | import {Serializer} from "../../src/circuit/Serializer.js" 22 | 23 | let suite = new Suite("SampleDisplay"); 24 | 25 | suite.testUsingWebGL("SampleDisplay_SingleZero", () => { 26 | let stats = CircuitStats.fromCircuitAtTime( 27 | Serializer.fromJson(CircuitDefinition, {"cols":[["Sample1"]]}), 28 | 0); 29 | let out = stats.toReadableJson(); 30 | assertThat(out.displays[0].data.probabilities).isApproximatelyEqualTo([ 31 | 1, 32 | 0, 33 | ]); 34 | }); 35 | -------------------------------------------------------------------------------- /circuit_weaver/test/gates/XorGates.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite} from "../TestUtil.js" 18 | import {XorGates} from "../../src/gates/XorGates.js" 19 | import {InputGates} from "../../src/gates/InputGates.js" 20 | import {assertThatCircuitUpdateActsLikeMatrix} from "../CircuitOperationTestUtil.js" 21 | import {advanceStateWithCircuit} from "../../src/circuit/CircuitComputeUtil.js" 22 | 23 | import {CircuitDefinition} from "../../src/circuit/CircuitDefinition.js" 24 | import {GateColumn} from "../../src/circuit/GateColumn.js" 25 | import {Matrix} from "../../src/math/Matrix.js" 26 | 27 | let suite = new Suite("XorGates"); 28 | 29 | suite.testUsingWebGL('xor_a', () => { 30 | let matrix = Matrix.generateTransition(1 << 6, i => { 31 | let a = (i >> 3) & 3; 32 | let dst = i & 3; 33 | let left = i & ~3; 34 | return (a ^ dst) + left; 35 | }); 36 | 37 | assertThatCircuitUpdateActsLikeMatrix( 38 | ctx => advanceStateWithCircuit( 39 | ctx, 40 | new CircuitDefinition(6, [new GateColumn([ 41 | XorGates.XorAFamily.ofSize(2), 42 | undefined, 43 | undefined, 44 | InputGates.InputAFamily.ofSize(2), 45 | undefined, 46 | undefined])]), 47 | false), 48 | matrix); 49 | 50 | assertThatCircuitUpdateActsLikeMatrix( 51 | ctx => advanceStateWithCircuit( 52 | ctx, 53 | new CircuitDefinition(6, [new GateColumn([ 54 | XorGates.XorAFamily.ofSize(3), 55 | undefined, 56 | undefined, 57 | InputGates.InputAFamily.ofSize(2), 58 | undefined, 59 | undefined])]), 60 | false), 61 | matrix); 62 | 63 | assertThatCircuitUpdateActsLikeMatrix( 64 | ctx => advanceStateWithCircuit( 65 | ctx, 66 | new CircuitDefinition(6, [new GateColumn([ 67 | XorGates.XorAFamily.ofSize(2), 68 | undefined, 69 | undefined, 70 | InputGates.InputAFamily.ofSize(3), 71 | undefined, 72 | undefined])]), 73 | false), 74 | matrix); 75 | }); 76 | -------------------------------------------------------------------------------- /circuit_weaver/test/math/Axis.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat, assertThrows, assertTrue, assertFalse} from "../TestUtil.js" 18 | import {Axis} from "../../src/math/Axis.js" 19 | 20 | let suite = new Suite("Axis"); 21 | 22 | suite.test("isEqualTo", () => { 23 | let groups = [ 24 | [new Axis(0, 0, 0), new Axis(0, 0, 0)], 25 | [new Axis(1, 0, 0), new Axis(1, 0, 0)], 26 | [new Axis(0, 1, 0), new Axis(0, 1, 0)], 27 | [new Axis(0, 0, 1), new Axis(0, 0, 1)], 28 | [new Axis(1, 2, 3), new Axis(1, 2, 3)], 29 | [new Axis(4, 5, 6)] 30 | ]; 31 | 32 | for (let g1 of groups) { 33 | for (let g2 of groups) { 34 | for (let e1 of g1) { 35 | for (let e2 of g2) { 36 | if (g1 === g2) { 37 | assertThat(e1).isEqualTo(e2); 38 | assertTrue(e1.isEqualTo(e2)); 39 | } else { 40 | assertThat(e1).isNotEqualTo(e2); 41 | assertFalse(e1.isEqualTo(e2)); 42 | } 43 | } 44 | } 45 | } 46 | } 47 | 48 | assertThat(new Axis(0, 0, 0)).isNotEqualTo(0); 49 | assertThat(new Axis(0, 0, 0)).isNotEqualTo(""); 50 | }); 51 | 52 | suite.test("parse", () => { 53 | assertThrows(() => Axis.parse("")); 54 | assertThrows(() => Axis.parse("0")); 55 | assertThrows(() => Axis.parse("abc")); 56 | assertThrows(() => Axis.parse("x*y")); 57 | assertThrows(() => Axis.parse("x^y")); 58 | assertThrows(() => Axis.parse("x/y")); 59 | 60 | assertThat(Axis.parse("x")).isEqualTo(new Axis(1, 0, 0)); 61 | assertThat(Axis.parse("y")).isEqualTo(new Axis(0, 1, 0)); 62 | assertThat(Axis.parse("z")).isEqualTo(new Axis(0, 0, 1)); 63 | 64 | assertThat(Axis.parse("sqrt --4 x")).isEqualTo(new Axis(2, 0, 0)); 65 | 66 | assertThat(Axis.parse("2z+3y-5x-x")).isEqualTo(new Axis(-6, 3, 2)); 67 | assertThat(Axis.parse("2z*6^2+3y-5x-x")).isEqualTo(new Axis(-6, 3, 72)); 68 | 69 | assertThat(Axis.parse("2z+")).isEqualTo(new Axis(0, 0, 2)); 70 | assertThat(Axis.parse("2z*")).isEqualTo(new Axis(0, 0, 2)); 71 | assertThat(Axis.parse("(2z)^")).isEqualTo(new Axis(0, 0, 2)); 72 | assertThat(Axis.parse("2z/")).isEqualTo(new Axis(0, 0, 2)); 73 | assertThat(Axis.parse("2z-")).isEqualTo(new Axis(0, 0, 2)); 74 | }); 75 | -------------------------------------------------------------------------------- /circuit_weaver/test/math/Point.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat, assertTrue, assertFalse} from "../TestUtil.js" 18 | import {Point} from "../../src/math/Point.js" 19 | 20 | let suite = new Suite("Point"); 21 | 22 | suite.test("isEqualTo", () => { 23 | let p = new Point(2, 3); 24 | assertTrue(p.isEqualTo(p)); 25 | assertFalse(p.isEqualTo(null)); 26 | assertFalse(p.isEqualTo("")); 27 | 28 | assertTrue(p.isEqualTo(new Point(2, 3))); 29 | assertFalse(p.isEqualTo(new Point(2, 4))); 30 | assertFalse(p.isEqualTo(new Point(1, 3))); 31 | 32 | // Interops with assertThat. 33 | assertThat(p).isEqualTo(new Point(2, 3)); 34 | assertThat(p).isNotEqualTo(new Point(2, 4)); 35 | }); 36 | 37 | suite.test("toString", () => { 38 | assertThat(new Point(2, 3).toString()).isEqualTo("(x: 2, y: 3)"); 39 | }); 40 | 41 | suite.test("offsetBy", () => { 42 | assertThat(new Point(2, 3).offsetBy(5, 7)).isEqualTo(new Point(7, 10)); 43 | }); 44 | 45 | suite.test("plus", () => { 46 | assertThat(new Point(2, 3).plus(new Point(5, 7))).isEqualTo(new Point(7, 10)); 47 | }); 48 | 49 | suite.test("minus", () => { 50 | assertThat(new Point(2, 3).minus(new Point(5, 7))).isEqualTo(new Point(-3, -4)); 51 | }); 52 | 53 | suite.test("times", () => { 54 | assertThat(new Point(2, 3).times(5)).isEqualTo(new Point(10, 15)); 55 | }); 56 | 57 | suite.test("distanceTo", () => { 58 | assertThat(new Point(2, 3).distanceTo(new Point(3, 3))).isEqualTo(1); 59 | assertThat(new Point(2, 3).distanceTo(new Point(4, 3))).isEqualTo(2); 60 | assertThat(new Point(2, 2).distanceTo(new Point(2, 3))).isEqualTo(1); 61 | assertThat(new Point(2, 2).distanceTo(new Point(2, 4))).isEqualTo(2); 62 | assertThat(new Point(0, 0).distanceTo(new Point(4, 3))).isEqualTo(5); 63 | }); 64 | -------------------------------------------------------------------------------- /circuit_weaver/test/ui/WidgetPainter.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat} from "../TestUtil.js" 18 | import {WidgetPainter} from "../../src/draw/WidgetPainter.js" 19 | 20 | import {Format} from "../../src/base/Format.js" 21 | import {Complex} from "../../src/math/Complex.js" 22 | 23 | let suite = new Suite("WidgetPainter"); 24 | 25 | suite.test("describeAxis", () => { 26 | let s = Math.sqrt(2); 27 | 28 | assertThat(WidgetPainter.describeAxis([1, 0, 0], Format.SIMPLIFIED)).isEqualTo("X"); 29 | assertThat(WidgetPainter.describeAxis([0, 1, 0], Format.SIMPLIFIED)).isEqualTo("Y"); 30 | assertThat(WidgetPainter.describeAxis([0, 0, 1], Format.SIMPLIFIED)).isEqualTo("Z"); 31 | 32 | assertThat(WidgetPainter.describeAxis([s, s, 0], Format.SIMPLIFIED)).isEqualTo("X + Y"); 33 | assertThat(WidgetPainter.describeAxis([0, s, s], Format.SIMPLIFIED)).isEqualTo("Y + Z"); 34 | assertThat(WidgetPainter.describeAxis([s, 0, s], Format.SIMPLIFIED)).isEqualTo("X + Z"); 35 | 36 | assertThat(WidgetPainter.describeAxis([-s, s, 0], Format.SIMPLIFIED)).isEqualTo("-X + Y"); 37 | assertThat(WidgetPainter.describeAxis([0, -s, s], Format.SIMPLIFIED)).isEqualTo("-Y + Z"); 38 | assertThat(WidgetPainter.describeAxis([s, 0, -s], Format.SIMPLIFIED)).isEqualTo("X - Z"); 39 | 40 | assertThat(WidgetPainter.describeAxis([1, -1, 1], Format.SIMPLIFIED)).isEqualTo("X - Y + Z"); 41 | 42 | assertThat(WidgetPainter.describeAxis([1, 0.5, 0.25], Format.SIMPLIFIED)).isEqualTo("X + ½·Y + ¼·Z"); 43 | assertThat(WidgetPainter.describeAxis([1, 0.5, 0.25], Format.CONSISTENT)).isEqualTo("X + 0.50·Y + 0.25·Z"); 44 | }); 45 | 46 | suite.test("describeKet", () => { 47 | assertThat(WidgetPainter.describeKet(1, 0, 1, Format.SIMPLIFIED)).isEqualTo('|0⟩'); 48 | assertThat(WidgetPainter.describeKet(1, 1, 1, Format.SIMPLIFIED)).isEqualTo('|1⟩'); 49 | 50 | assertThat(WidgetPainter.describeKet(2, 0, 1, Format.SIMPLIFIED)).isEqualTo('|00⟩'); 51 | assertThat(WidgetPainter.describeKet(2, 1, 1, Format.SIMPLIFIED)).isEqualTo('|01⟩'); 52 | assertThat(WidgetPainter.describeKet(2, 2, 1, Format.SIMPLIFIED)).isEqualTo('|10⟩'); 53 | assertThat(WidgetPainter.describeKet(2, 3, 1, Format.SIMPLIFIED)).isEqualTo('|11⟩'); 54 | 55 | assertThat(WidgetPainter.describeKet(2, 0, new Complex(-1, 0), Format.SIMPLIFIED)).isEqualTo('-|00⟩'); 56 | assertThat(WidgetPainter.describeKet(2, 1, Complex.I, Format.SIMPLIFIED)).isEqualTo('i|01⟩'); 57 | assertThat(WidgetPainter.describeKet(2, 2, new Complex(0, -1), Format.SIMPLIFIED)).isEqualTo('-i|10⟩'); 58 | assertThat(WidgetPainter.describeKet(2, 3, new Complex(1, 1), Format.SIMPLIFIED)).isEqualTo('(1+i)·|11⟩'); 59 | }); 60 | -------------------------------------------------------------------------------- /circuit_weaver/test/webgl/ShaderCoders_Base.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat} from "../TestUtil.js" 18 | 19 | import {BOOL_TYPE_CODER} from "../../src/webgl/ShaderCoders_Base.js" 20 | import {combinedShaderPartsWithCode, shaderWithOutputPartAndArgs} from "../../src/webgl/ShaderCoders.js" 21 | import {Shaders} from "../../src/webgl/Shaders.js" 22 | 23 | let suite = new Suite("ShaderCoders_Base"); 24 | 25 | suite.testUsingWebGLFloatTextures("boolInputs", () => { 26 | let inp = BOOL_TYPE_CODER.inputPartGetter('a'); 27 | let shader = combinedShaderPartsWithCode([inp], ` 28 | void main() { 29 | vec2 xy = gl_FragCoord.xy - vec2(0.5, 0.5); 30 | float k = xy.y * 4.0 + xy.x; 31 | gl_FragColor = vec4(read_a(k), k, 0.0, 0.0); 32 | }`); 33 | 34 | let tex = Shaders.data(new Uint8Array([255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0])).toRawByteTexture(2); 35 | assertThat(shader.withArgs(...inp.argsFor(tex)).readRawFloatOutputs(2)).isEqualTo(new Float32Array([ 36 | 1, 0, 0, 0, 37 | 0, 1, 0, 0, 38 | 0, 2, 0, 0, 39 | 1, 3, 0, 0 40 | ])); 41 | tex.deallocByDepositingInPool(); 42 | }); 43 | 44 | suite.testUsingWebGL("boolOutputs", () => { 45 | let output = BOOL_TYPE_CODER.outputPart; 46 | let shader = combinedShaderPartsWithCode([output], ` 47 | bool outputFor(float k) { 48 | return floor(mod(k + 0.5, 3.0)) == 1.0; 49 | }`); 50 | 51 | assertThat(shaderWithOutputPartAndArgs(shader, output, []).readBoolOutputs(3)).isEqualTo(new Uint8Array([ 52 | 0, 1, 0, 0, 1, 0, 0, 1 53 | ])); 54 | }); 55 | -------------------------------------------------------------------------------- /circuit_weaver/test/webgl/ShaderCoders_intoFloats.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat, assertThrows} from "../TestUtil.js" 18 | import {SHADER_CODER_FLOATS} from "../../src/webgl/ShaderCoders_intoFloats.js" 19 | import {Shaders} from "../../src/webgl/Shaders.js" 20 | 21 | let suite = new Suite("ShaderCoders"); 22 | 23 | suite.testUsingWebGLFloatTextures("packed", () => { 24 | assertThat(SHADER_CODER_FLOATS.float.dataToPixels(new Float32Array([1, 2, 3, 4]))).isEqualTo(new Float32Array([ 25 | 1, 0, 0, 0, 26 | 2, 0, 0, 0, 27 | 3, 0, 0, 0, 28 | 4, 0, 0, 0 29 | ])); 30 | 31 | assertThat(SHADER_CODER_FLOATS.vec2.dataToPixels(new Float32Array([1, 2, 3, 4]))).isEqualTo(new Float32Array([ 32 | 1, 2, 0, 0, 33 | 3, 4, 0, 0 34 | ])); 35 | 36 | assertThat(SHADER_CODER_FLOATS.vec4.dataToPixels(new Float32Array([1, 2, 3, 4]))).isEqualTo(new Float32Array([ 37 | 1, 2, 3, 4 38 | ])); 39 | }); 40 | 41 | suite.testUsingWebGLFloatTextures("input_wrongType", () => { 42 | assertThrows(() => { 43 | let tex = Shaders.data(new Uint8Array([0, 0, 0, 0])).toRawByteTexture(0); 44 | try { 45 | SHADER_CODER_FLOATS.float.inputPartGetter('a').argsFor(tex); 46 | } finally { 47 | tex.deallocByDepositingInPool(); 48 | } 49 | }); 50 | 51 | assertThrows(() => { 52 | let tex = Shaders.data(new Uint8Array([0, 0, 0, 0])).toRawByteTexture(0); 53 | try { 54 | SHADER_CODER_FLOATS.vec2.inputPartGetter('a').argsFor(tex); 55 | } finally { 56 | tex.deallocByDepositingInPool(); 57 | } 58 | }); 59 | 60 | assertThrows(() => { 61 | let tex = Shaders.data(new Uint8Array([0, 0, 0, 0])).toRawByteTexture(0); 62 | try { 63 | SHADER_CODER_FLOATS.vec4.inputPartGetter('a').argsFor(tex); 64 | } finally { 65 | tex.deallocByDepositingInPool(); 66 | } 67 | }); 68 | }); 69 | -------------------------------------------------------------------------------- /circuit_weaver/test/webgl/WglShader.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat} from "../TestUtil.js" 18 | import {WglShader} from "../../src/webgl/WglShader.js" 19 | import {WglTexture} from "../../src/webgl/WglTexture.js" 20 | import {Seq} from "../../src/base/Seq.js" 21 | import {initializedWglContext} from "../../src/webgl/WglContext.js" 22 | 23 | let suite = new Suite("WglShader"); 24 | 25 | suite.testUsingWebGL("renderTo_large", () => { 26 | let tex = new WglTexture(256, 256, WebGLRenderingContext.UNSIGNED_BYTE); 27 | new WglShader("void main(){gl_FragColor=vec4(3.0,3.0,3.0,3.0)/255.0;}").withArgs().renderTo(tex); 28 | let expected = new Uint8Array(Seq.repeat(3, 4 * tex.width * tex.height).toArray()); 29 | assertThat(tex.readPixels()).isEqualTo(expected); 30 | }); 31 | 32 | suite.testUsingWebGLFloatTextures("renderTo_empty", () => { 33 | let tex = new WglTexture(0, 0); 34 | new WglShader("void main(){gl_FragColor=vec4(0.0,0.0,0.0,0.0);}").withArgs().renderTo(tex); 35 | assertThat(tex.readPixels()).isEqualTo(new Float32Array([])); 36 | }); 37 | 38 | suite.testUsingWebGL("readPixels_bytes_all", () => { 39 | let shader = new WglShader(` 40 | void main() { 41 | vec2 xy = gl_FragCoord.xy - vec2(0.5, 0.5); 42 | float s = (xy.y*8.0 + xy.x)*4.0; 43 | gl_FragColor = vec4( 44 | (s+0.0)/255.0, 45 | (s+1.0)/255.0, 46 | (s+2.0)/255.0, 47 | (s+3.0)/255.0); 48 | }`).withArgs(); 49 | 50 | let tex = new WglTexture(8, 8, WebGLRenderingContext.UNSIGNED_BYTE); 51 | shader.renderTo(tex); 52 | assertThat(tex.readPixels()).isEqualTo(new Uint8Array( 53 | Seq.range(256).toArray() 54 | )); 55 | tex.ensureDeinitialized(); 56 | }); 57 | 58 | suite.testUsingWebGLFloatTextures("changeSourceAfterInvalidate", () => { 59 | let tex = new WglTexture(1, 1); 60 | let flag = true; 61 | let shader = new WglShader(() => flag ? 62 | "void main(){gl_FragColor=vec4(-5.0,-6.0,7.0,8.0);}" : 63 | "void main(){gl_FragColor=vec4(1.0,2.0,3.0,4.0);}"); 64 | 65 | shader.withArgs().renderTo(tex); 66 | assertThat(tex.readPixels()).isEqualTo(new Float32Array([-5, -6, 7, 8])); 67 | 68 | flag = false; 69 | initializedWglContext().invalidateExistingResources(); 70 | 71 | shader.withArgs().renderTo(tex); 72 | assertThat(tex.readPixels()).isEqualTo(new Float32Array([1, 2, 3, 4])); 73 | }); 74 | -------------------------------------------------------------------------------- /circuit_weaver/test/webgl/WglTexture.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat} from "../TestUtil.js" 18 | import {WglArg} from "../../src/webgl/WglArg.js" 19 | import {WglShader} from "../../src/webgl/WglShader.js" 20 | import {WglTexture} from "../../src/webgl/WglTexture.js" 21 | 22 | let suite = new Suite("WglTexture"); 23 | 24 | suite.test("properties", () => { 25 | let t = new WglTexture(8, 16, WebGLRenderingContext.UNSIGNED_BYTE); 26 | assertThat(t.width).isEqualTo(8); 27 | assertThat(t.height).isEqualTo(16); 28 | assertThat(t.pixelType).isEqualTo(WebGLRenderingContext.UNSIGNED_BYTE); 29 | assertThat(t.sizePower()).isEqualTo(7); 30 | assertThat(t.toString()).isNotEqualTo(undefined); 31 | }); 32 | 33 | suite.testUsingWebGL("readPixels_bytes", () => { 34 | let w = 2; 35 | let h = 2; 36 | let shader = new WglShader(` 37 | uniform float v; 38 | void main() { 39 | vec2 xy = gl_FragCoord.xy - vec2(0.5, 0.5); 40 | gl_FragColor = vec4(xy / 255.0, v, 128.0/255.0); 41 | }`); 42 | 43 | let texture = new WglTexture(w, h, WebGLRenderingContext.UNSIGNED_BYTE); 44 | 45 | shader.withArgs(WglArg.float("v", 10/255)).renderTo(texture); 46 | assertThat(texture.readPixels()).isEqualTo(new Uint8Array([ 47 | 0, 0, 10, 128, 48 | 1, 0, 10, 128, 49 | 0, 1, 10, 128, 50 | 1, 1, 10, 128 51 | ])); 52 | }); 53 | 54 | suite.testUsingWebGLFloatTextures("readPixels_floats", () => { 55 | let w = 2; 56 | let h = 2; 57 | let shader = new WglShader(` 58 | uniform float v; 59 | void main() { 60 | gl_FragColor = vec4(gl_FragCoord.xy, v, 254.5); 61 | }`); 62 | 63 | let texture = new WglTexture(w, h); 64 | 65 | shader.withArgs(WglArg.float("v", 192.25)).renderTo(texture); 66 | assertThat(texture.readPixels()).isEqualTo(new Float32Array([ 67 | 0.5, 0.5, 192.25, 254.5, 68 | 1.5, 0.5, 192.25, 254.5, 69 | 0.5, 1.5, 192.25, 254.5, 70 | 1.5, 1.5, 192.25, 254.5 71 | ])); 72 | }); 73 | 74 | suite.testUsingWebGL("readPixels_empty", () => { 75 | assertThat(new WglTexture(0, 0).readPixels()).isEqualTo(new Float32Array([])); 76 | }); 77 | -------------------------------------------------------------------------------- /circuit_weaver/test/webgl/WglTexturePool.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Suite, assertThat} from "../TestUtil.js" 18 | import { 19 | currentShaderCoder, 20 | Outputs, 21 | makePseudoShaderWithInputsAndOutputAndCode 22 | } from "../../src/webgl/ShaderCoders.js" 23 | import {WglTexturePool} from "../../src/webgl/WglTexturePool.js" 24 | 25 | let suite = new Suite("WglTexturePool"); 26 | 27 | suite.testUsingWebGL("takeBoolTex", () => { 28 | let t = WglTexturePool.takeBoolTex(2); 29 | makePseudoShaderWithInputsAndOutputAndCode( 30 | [], 31 | Outputs.bool(), 32 | `bool outputFor(float k) { 33 | return k == 2.0; 34 | }`)().renderTo(t); 35 | assertThat(t.readPixels()).isEqualTo(new Uint8Array([ 36 | 0, 0, 0, 0, 37 | 0, 0, 0, 0, 38 | 255, 0, 0, 0, 39 | 0, 0, 0, 0 40 | ])); 41 | t.deallocByDepositingInPool(); 42 | }); 43 | 44 | suite.testUsingWebGLFloatTextures("takeVec2Tex", () => { 45 | let t = WglTexturePool.takeVec2Tex(2); 46 | makePseudoShaderWithInputsAndOutputAndCode( 47 | [], 48 | Outputs.vec2(), 49 | `vec2 outputFor(float k) { 50 | return vec2(k / 4.0, k * k); 51 | }`)().renderTo(t); 52 | assertThat(currentShaderCoder().vec2.pixelsToData(t.readPixels())).isEqualTo(new Float32Array([ 53 | 0, 0, 54 | 0.25, 1, 55 | 0.5, 4, 56 | 0.75, 9 57 | ])); 58 | t.deallocByDepositingInPool(); 59 | }); 60 | 61 | suite.testUsingWebGLFloatTextures("takeVec4Tex", () => { 62 | let t = WglTexturePool.takeVec4Tex(2); 63 | makePseudoShaderWithInputsAndOutputAndCode( 64 | [], 65 | Outputs.vec4(), 66 | `vec4 outputFor(float k) { 67 | return vec4(k, k / 4.0, k * k, 5.0); 68 | }`)().renderTo(t); 69 | assertThat(currentShaderCoder().vec4.pixelsToData(t.readPixels())).isEqualTo(new Float32Array([ 70 | 0, 0, 0, 5, 71 | 1, 0.25, 1, 5, 72 | 2, 0.5, 4, 5, 73 | 3, 0.75, 9, 5 74 | ])); 75 | t.deallocByDepositingInPool(); 76 | }); 77 | -------------------------------------------------------------------------------- /circuit_weaver/test_perf/KarmaTestRunner.perf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {getKnownPerfTests} from "./TestPerfUtil.js"; 18 | 19 | let execIntoPromise = method => { 20 | try { 21 | return Promise.resolve(method()); 22 | } catch (ex) { 23 | return Promise.reject(ex); 24 | } 25 | }; 26 | 27 | let promiseRunPerfTest = ({name, method}) => { 28 | let result = { 29 | description: name, 30 | suite: ['(Perf Tests)'], 31 | success: false, 32 | log: [], 33 | time: undefined 34 | }; 35 | 36 | let t0 = performance.now(); 37 | return execIntoPromise(method).then( 38 | ({pass, info}) => { 39 | result.success = pass; 40 | result.log.push(info); 41 | }, 42 | ex => { 43 | result.log.push(String(ex)); 44 | if (ex.details !== undefined) { 45 | result.log.push(ex.details); 46 | } 47 | if (ex.stack !== undefined) { 48 | result.log.push(ex.stack); 49 | } 50 | }).then(() => { 51 | result.time = performance.now() - t0; 52 | __karma__.result(result); 53 | }); 54 | }; 55 | 56 | __karma__.start = () => { 57 | let known = getKnownPerfTests(); 58 | __karma__.info({ total: known.length }); 59 | 60 | let chain = Promise.resolve(); 61 | for (let test of known) { 62 | chain = chain.then(() => 63 | new Promise(resolver => 64 | setTimeout(() => 65 | resolver(promiseRunPerfTest(test)), 66 | 25))); 67 | } 68 | 69 | chain.then(() => __karma__.complete()); 70 | }; 71 | -------------------------------------------------------------------------------- /circuit_weaver/test_perf/test_page.template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
 9 |         
10 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /quantum_algorithm/AmplitudeAmplification.py: -------------------------------------------------------------------------------- 1 | import pyqpanda as pq 2 | from numpy import pi 3 | 4 | if __name__ == "__main__": 5 | 6 | machine = pq.init_quantum_machine(pq.QMachineType.CPU) 7 | qvec = machine.qAlloc_many(1) 8 | prog = pq.create_empty_qprog() 9 | 10 | # 构建量子程序 11 | prog.insert(pq.RY(qvec[0], pi/3)) 12 | # prog.insert(pq.Z(qvec[0])) 13 | prog.insert(pq.RY(qvec[0], pi*2/3)) 14 | 15 | # 对量子程序进行概率测量 16 | result = pq.prob_run_dict(prog, qvec, -1) 17 | pq.destroy_quantum_machine(machine) 18 | 19 | # 打印测量结果 20 | for key in result: 21 | print(key+":"+str(result[key])) -------------------------------------------------------------------------------- /quantum_algorithm/DJ_1.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | 3 | if __name__ == "__main__": 4 | init(QMachineType.CPU) 5 | qubits = qAlloc_many(2) 6 | cbits = cAlloc_many(2) 7 | # 构建量子程序 8 | prog = QProg() 9 | prog << H(qubits[0]) << X(qubits[0]) << H(qubits[0])\ 10 | << measure_all(qubits, cbits) 11 | 12 | # 量子程序运行1000次,并返回测量结果 13 | result = run_with_configuration(prog, cbits, 1000) 14 | print(result) 15 | finalize() -------------------------------------------------------------------------------- /quantum_algorithm/DJ_2.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | 3 | if __name__ == "__main__": 4 | init(QMachineType.CPU) 5 | qubits = qAlloc_many(2) 6 | cbits = cAlloc_many(2) 7 | # 构建量子程序 8 | prog = QProg() 9 | prog << H(qubits[0]) \ 10 | << X(qubits[1]) << H(qubits[1]) \ 11 | << CNOT(qubits[1], qubits[0]) \ 12 | << H(qubits[0])\ 13 | << H(qubits[1]) \ 14 | << measure_all(qubits, cbits) 15 | 16 | # 量子程序运行1000次,并返回测量结果 17 | result = run_with_configuration(prog, cbits, 1000) 18 | print(result) 19 | finalize() -------------------------------------------------------------------------------- /quantum_algorithm/DJ_3.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | import numpy as np 3 | if __name__ == "__main__": 4 | init(QMachineType.CPU) 5 | qubits = qAlloc_many(2) 6 | cbits = cAlloc_many(2) 7 | # 构建量子程序 8 | prog = QProg() 9 | prog << H(qubits[0]) \ 10 | << X(qubits[1])<< H(qubits[1]) \ 11 | << CNOT(qubits[1], qubits[0]) \ 12 | << X(qubits[0]) << H(qubits[0])\ 13 | << H(qubits[1]) \ 14 | << measure_all(qubits, cbits) 15 | 16 | # 量子程序运行1000次,并返回测量结果 17 | result = run_with_configuration(prog, cbits, 1000) 18 | print(result) 19 | finalize() -------------------------------------------------------------------------------- /quantum_algorithm/Grover_1.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | 3 | if __name__ == "__main__": 4 | machine = CPUQVM() 5 | machine.initQVM() 6 | x = machine.cAlloc() 7 | data = [0,3,2,1] 8 | measure_qubits = QVec() 9 | 10 | # 构建Grover算法量子线路 11 | grover_cir = Grover(data, x==2, machine, measure_qubits, 1) 12 | cbits = machine.cAlloc_many(len(measure_qubits)) 13 | prog = QProg() 14 | prog << grover_cir << measure_all(measure_qubits, cbits) 15 | 16 | # 量子程序运行1000次,并返回测量结果 17 | result = machine.run_with_configuration(prog, cbits, 1000) 18 | print(result) 19 | finalize() -------------------------------------------------------------------------------- /quantum_algorithm/Grover_2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import pyqpanda as pq 4 | import numpy as np 5 | 6 | if __name__ == "__main__": 7 | 8 | machine = pq.init_quantum_machine(pq.QMachineType.CPU) 9 | x = machine.cAlloc() 10 | prog = pq.create_empty_qprog() 11 | 12 | data=[3, 6, 6, 9, 10, 15, 11, 6] 13 | grover_result = pq.Grover_search(data, x==6, machine, 1) 14 | 15 | print(grover_result[1]) -------------------------------------------------------------------------------- /quantum_algorithm/HHLDemo.py: -------------------------------------------------------------------------------- 1 | import pyqpanda as pq 2 | import numpy as np 3 | 4 | if __name__ == "__main__": 5 | A=[1,0,0,1] 6 | b=[0.6,0.8] 7 | result = pq.HHL_solve_linear_equations(A,b,1) 8 | 9 | #打印测量结果 10 | for key in result: 11 | print(key) -------------------------------------------------------------------------------- /quantum_algorithm/HadamardTest.py: -------------------------------------------------------------------------------- 1 | import pyqpanda as pq 2 | 3 | if __name__ == "__main__": 4 | 5 | machine = pq.init_quantum_machine(pq.QMachineType.CPU) 6 | cqv = machine.qAlloc_many(1) 7 | tqv = machine.qAlloc_many(1) 8 | prog = pq.create_empty_qprog() 9 | 10 | # 构建量子程序 11 | prog.insert(pq.H(cqv[0])) \ 12 | .insert(pq.H(tqv[0])) \ 13 | .insert(pq.H(tqv[0]).control([cqv[0]]))\ 14 | .insert(pq.H(cqv[0])) 15 | 16 | # 对量子程序进行概率测量 17 | result = pq.prob_run_dict(prog, cqv, -1) 18 | pq.destroy_quantum_machine(machine) 19 | 20 | # 打印测量结果 21 | for key in result: 22 | print(key+":"+str(result[key])) -------------------------------------------------------------------------------- /quantum_algorithm/QFTDemo.py: -------------------------------------------------------------------------------- 1 | import pyqpanda as pq 2 | from numpy import pi 3 | 4 | if __name__ == "__main__": 5 | 6 | machine = pq.init_quantum_machine(pq.QMachineType.CPU) 7 | qvec = machine.qAlloc_many(3) 8 | prog = pq.create_empty_qprog() 9 | 10 | # 构建量子程序 11 | prog.insert(pq.QFT(qvec)) 12 | 13 | # 对量子程序进行概率测量 14 | result = pq.prob_run_dict(prog, qvec, -1) 15 | pq.destroy_quantum_machine(machine) 16 | 17 | # 打印测量结果 18 | for key in result: 19 | print(key+":"+str(result[key])) -------------------------------------------------------------------------------- /quantum_algorithm/QMath.py: -------------------------------------------------------------------------------- 1 | import pyqpanda as pq 2 | # from numpy import pi 3 | 4 | if __name__ == "__main__": 5 | # 为了节约比特数,辅助比特将会互相借用 6 | qvm = pq.init_quantum_machine(pq.QMachineType.CPU) 7 | 8 | qdivvec = qvm.qAlloc_many(10) 9 | qmulvec = qdivvec[:7] 10 | qsubvec = qmulvec[:-1] 11 | qvec1 = qvm.qAlloc_many(4) 12 | qvec2 = qvm.qAlloc_many(4) 13 | qvec3 = qvm.qAlloc_many(4) 14 | cbit = qvm.cAlloc() 15 | prog = pq.create_empty_qprog() 16 | 17 | # (4/1+1-3)*5=10 18 | prog.insert(pq.bind_data(4,qvec3)) \ 19 | .insert(pq.bind_data(1,qvec2)) \ 20 | .insert(pq.QDivider(qvec3, qvec2, qvec1, qdivvec, cbit)) \ 21 | .insert(pq.bind_data(1,qvec2)) \ 22 | .insert(pq.bind_data(1,qvec2)) \ 23 | .insert(pq.QAdd(qvec1, qvec2, qsubvec)) \ 24 | .insert(pq.bind_data(1,qvec2)) \ 25 | .insert(pq.bind_data(3,qvec2)) \ 26 | .insert(pq.QSub(qvec1, qvec2, qsubvec)) \ 27 | .insert(pq.bind_data(3,qvec2)) \ 28 | .insert(pq.bind_data(5,qvec2)) \ 29 | .insert(pq.QMul(qvec1, qvec2, qvec3, qmulvec)) \ 30 | .insert(pq.bind_data(5,qvec2)) 31 | 32 | # 对量子程序进行概率测量 33 | result = pq.prob_run_dict(prog, qmulvec,1) 34 | pq.destroy_quantum_machine(qvm) 35 | 36 | # 打印测量结果 37 | for key in result: 38 | print(key+":"+str(result[key])) -------------------------------------------------------------------------------- /quantum_algorithm/QPEDemo.py: -------------------------------------------------------------------------------- 1 | import pyqpanda as pq 2 | from numpy import pi 3 | 4 | if __name__ == "__main__": 5 | 6 | machine = pq.init_quantum_machine(pq.QMachineType.CPU) 7 | qvec = machine.qAlloc_many(1) 8 | cqv = machine.qAlloc_many(4) 9 | prog = pq.create_empty_qprog() 10 | 11 | # 构建量子程序 12 | prog.insert(pq.H(cqv[0]))\ 13 | .insert(pq.H(cqv[1]))\ 14 | .insert(pq.H(cqv[2]))\ 15 | .insert(pq.H(cqv[3]))\ 16 | .insert(pq.H(qvec[0]))\ 17 | .insert(pq.S(qvec[0]))\ 18 | .insert(pq.RY(qvec[0], pi/4).control(cqv[0]))\ 19 | .insert(pq.RY(qvec[0], pi/2).control(cqv[1]))\ 20 | .insert(pq.RY(qvec[0], pi).control(cqv[2]))\ 21 | .insert(pq.RY(qvec[0], pi*2).control(cqv[3])) \ 22 | .insert(pq.QFT(cqv).dagger()) 23 | 24 | # 对量子程序进行概率测量 25 | result = pq.prob_run_dict(prog, cqv, -1) 26 | pq.destroy_quantum_machine(machine) 27 | 28 | # 打印测量结果 29 | for key in result: 30 | print(key+":"+str(result[key])) -------------------------------------------------------------------------------- /quantum_algorithm/SWAPTest.py: -------------------------------------------------------------------------------- 1 | import pyqpanda as pq 2 | 3 | if __name__ == "__main__": 4 | 5 | machine = pq.init_quantum_machine(pq.QMachineType.CPU) 6 | cqv = machine.qAlloc_many(1) 7 | tqv = machine.qAlloc_many(1) 8 | qvec = machine.qAlloc_many(1) 9 | prog = pq.create_empty_qprog() 10 | 11 | # 构建量子程序 12 | prog.insert(pq.H(cqv[0])) \ 13 | .insert(pq.H(tqv[0])) \ 14 | .insert(pq.X(qvec[0])) \ 15 | .insert(pq.SWAP(tqv[0],qvec[0]).control([cqv[0]]))\ 16 | .insert(pq.H(cqv[0])) 17 | 18 | # 对量子程序进行概率测量 19 | result = pq.prob_run_dict(prog, cqv, -1) 20 | pq.destroy_quantum_machine(machine) 21 | 22 | # 打印测量结果 23 | for key in result: 24 | print(key+":"+str(result[key])) -------------------------------------------------------------------------------- /quantum_algorithm/ShorDemo.py: -------------------------------------------------------------------------------- 1 | import pyqpanda as pq 2 | 3 | if __name__ == "__main__": 4 | N=15 5 | result = pq.Shor_factorization(N) 6 | # print(result) 7 | # 打印测量结果 8 | for key in result: 9 | print(key) -------------------------------------------------------------------------------- /quantum_algorithm/Superposition.py: -------------------------------------------------------------------------------- 1 | import pyqpanda as pq 2 | 3 | if __name__ == "__main__": 4 | 5 | machine = pq.init_quantum_machine(pq.QMachineType.CPU) 6 | qubits = machine.qAlloc_many(3) 7 | prog = pq.create_empty_qprog() 8 | 9 | # 构建量子程序 10 | prog.insert(pq.H(qubits[0])) \ 11 | .insert(pq.H(qubits[1])) \ 12 | .insert(pq.H(qubits[2])) 13 | 14 | # 对量子程序进行概率测量 15 | result = pq.prob_run_dict(prog, qubits, -1) 16 | pq.destroy_quantum_machine(machine) 17 | 18 | # 打印测量结果 19 | for key in result: 20 | print(key+":"+str(result[key])) -------------------------------------------------------------------------------- /quantum_ml/fermion/fermion_init.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__=="__main__": 3 | p1 = FermionOperator() 4 | p2 = FermionOperator({'1+ 0': 2,'3+ 2+ 1 0': 3}) 5 | p3 = FermionOperator('1+ 0', 2) 6 | p4 = FermionOperator(2) 7 | p5=p2 -------------------------------------------------------------------------------- /quantum_ml/fermion/fermion_math.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__=="__main__": 3 | a = FermionOperator('1+ 0', 2) 4 | b = FermionOperator('3+ 2', 3) 5 | plus=a+b 6 | minus=a-b 7 | multiply=a*b 8 | print("a + b = {}".format(plus)) 9 | print("a - b = {}".format(minus)) 10 | print("a * b = {}".format(multiply)) -------------------------------------------------------------------------------- /quantum_ml/fermion/var.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__=="__main__": 3 | a = var(2, True) 4 | b = var(3, True) 5 | fermion_op = VarFermionOperator('1+ 0', a) 6 | pauli_op = VarPauliOperator('Z1 Z0', b) -------------------------------------------------------------------------------- /quantum_ml/pauli/getMaxIndex.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__=="__main__": 3 | a = PauliOperator('Z0 Z1', 2) 4 | b = PauliOperator('X5 X6', 3) 5 | muliply = a * b 6 | print("a * b = {}".format(muliply)) 7 | print("Index : {}".format(muliply.getMaxIndex())) 8 | -------------------------------------------------------------------------------- /quantum_ml/pauli/pauli_init.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__=="__main__": 3 | p1 = PauliOperator() 4 | p2 = PauliOperator({'Z0 Z1': 2, 'X1 Y2': 3}) 5 | p3 = PauliOperator('Z0 Z1', 2) 6 | p4 = PauliOperator(2) 7 | p5 = p2 -------------------------------------------------------------------------------- /quantum_ml/pauli/pauli_math.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | 3 | if __name__=="__main__": 4 | a = PauliOperator('Z0 Z1', 2) 5 | b = PauliOperator('X5 X6', 3) 6 | plus = a + b 7 | minus = a - b 8 | multiply = a * b 9 | print("a + b = {}".format(plus)) 10 | print("a - b = {}".format(minus)) 11 | print("a * b = {}".format(multiply)) -------------------------------------------------------------------------------- /quantum_ml/pauli/remapQubitIndex.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__=="__main__": 3 | a = PauliOperator('Z0 Z1', 2) 4 | b = PauliOperator('X5 X6', 3) 5 | muliply = a * b 6 | index_map = {} 7 | remap_pauli = muliply.remapQubitIndex(index_map) 8 | print("remap_pauli = {}".format(remap_pauli)) 9 | print("Index : {}".format(remap_pauli.getMaxIndex())) -------------------------------------------------------------------------------- /quantum_ml/qaoa.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | import numpy as np 3 | 4 | def oneCircuit(qlist, Hamiltonian, beta, gamma): 5 | vqc=VariationalQuantumCircuit() 6 | for i in range(len(Hamiltonian)): 7 | tmp_vec=[] 8 | item=Hamiltonian[i] 9 | dict_p = item[0] 10 | for iter in dict_p: 11 | if 'Z'!= dict_p[iter]: 12 | pass 13 | tmp_vec.append(qlist[iter]) 14 | 15 | coef = item[1] 16 | 17 | if 2 != len(tmp_vec): 18 | pass 19 | 20 | vqc.insert(VariationalQuantumGate_CNOT(tmp_vec[0], tmp_vec[1])) 21 | vqc.insert(VariationalQuantumGate_RZ(tmp_vec[1], 2*gamma*coef)) 22 | vqc.insert(VariationalQuantumGate_CNOT(tmp_vec[0], tmp_vec[1])) 23 | 24 | for j in qlist: 25 | vqc.insert(VariationalQuantumGate_RX(j,2.0*beta)) 26 | return vqc 27 | 28 | 29 | if __name__=="__main__": 30 | problem = {'Z0 Z4':0.73,'Z0 Z5':0.33,'Z0 Z6':0.5,'Z1 Z4':0.69,'Z1 Z5':0.36, 31 | 'Z2 Z5':0.88,'Z2 Z6':0.58,'Z3 Z5':0.67,'Z3 Z6':0.43} 32 | Hp = PauliOperator(problem) 33 | qubit_num = Hp.getMaxIndex() 34 | 35 | machine=init_quantum_machine(QMachineType.CPU) 36 | qlist = machine.qAlloc_many(qubit_num) 37 | 38 | step = 4 39 | 40 | beta = var(np.ones((step,1),dtype = 'float64'), True) 41 | gamma = var(np.ones((step,1),dtype = 'float64'), True) 42 | 43 | vqc=VariationalQuantumCircuit() 44 | 45 | for i in qlist: 46 | vqc.insert(VariationalQuantumGate_H(i)) 47 | 48 | for i in range(step): 49 | vqc.insert(oneCircuit(qlist,Hp.toHamiltonian(1),beta[i], gamma[i])) 50 | 51 | 52 | loss = qop(vqc, Hp, machine, qlist) 53 | optimizer = MomentumOptimizer.minimize(loss, 0.02, 0.9) 54 | 55 | leaves = optimizer.get_variables() 56 | 57 | for i in range(100): 58 | optimizer.run(leaves, 0) 59 | loss_value = optimizer.get_loss() 60 | print("i: ", i, " loss:",loss_value ) 61 | 62 | # 验证结果 63 | prog = QProg() 64 | qcir = vqc.feed() 65 | prog.insert(qcir) 66 | directly_run(prog) 67 | 68 | result = quick_measure(qlist, 100) 69 | print(result) -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/0_classes.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | 3 | if __name__ == "__main__": 4 | 5 | init(QMachineType.CPU) 6 | qubits = qAlloc_many(4) 7 | cbits = cAlloc_many(4) 8 | prog = QProg() 9 | 10 | # 构建量子程序 11 | prog << H(qubits[0]) \ 12 | << X(qubits[1]) \ 13 | << iSWAP(qubits[0], qubits[1]) \ 14 | << CNOT(qubits[1], qubits[2]) \ 15 | << H(qubits[3]) \ 16 | << measure_all(qubits, cbits) 17 | 18 | # 量子程序运行1000次,并返回测量结果 19 | result = run_with_configuration(prog, cbits, 1000) 20 | 21 | # 打印量子态在量子程序多次运行结果中出现的次数 22 | print(result) 23 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/10_RYGate.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | import numpy as np 3 | if __name__ == "__main__": 4 | init(QMachineType.CPU) 5 | qubits = qAlloc_many(1) 6 | cbits = cAlloc_many(1) 7 | # 构建量子程序 8 | prog = QProg() 9 | prog << RY(qubits[0], np.pi/2) \ 10 | << Measure(qubits[0], cbits[0]) 11 | # 量子程序运行1000次,并返回测量结果 12 | result = run_with_configuration(prog, cbits, 1000) 13 | print(result) 14 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/11_RZGate.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | import numpy as np 3 | if __name__ == "__main__": 4 | init(QMachineType.CPU) 5 | qubits = qAlloc_many(1) 6 | cbits = cAlloc_many(1) 7 | # 构建量子程序 8 | prog = QProg() 9 | prog << RZ(qubits[0], np.pi/2) \ 10 | << Measure(qubits[0], cbits[0]) 11 | # 量子程序运行1000次,并返回测量结果 12 | result = run_with_configuration(prog, cbits, 1000) 13 | print(result) 14 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/12_CNOTGate.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | import numpy as np 3 | if __name__ == "__main__": 4 | init(QMachineType.CPU) 5 | qubits = qAlloc_many(2) 6 | cbits = cAlloc_many(2) 7 | # 构建量子程序 8 | prog = QProg() 9 | prog << CNOT(qubits[0], qubits[1]) \ 10 | << Measure(qubits[0], cbits[0]) \ 11 | << Measure(qubits[1], cbits[1]) 12 | # 量子程序运行1000次,并返回测量结果 13 | result = run_with_configuration(prog, cbits, 1000) 14 | print(result) 15 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/13_CRGate.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | import numpy as np 3 | if __name__ == "__main__": 4 | init(QMachineType.CPU) 5 | qubits = qAlloc_many(2) 6 | cbits = cAlloc_many(2) 7 | # 构建量子程序 8 | prog = QProg() 9 | prog << CR(qubits[0], qubits[1], np.pi) \ 10 | << Measure(qubits[0], cbits[0]) \ 11 | << Measure(qubits[1], cbits[1]) 12 | # 量子程序运行1000次,并返回测量结果 13 | result = run_with_configuration(prog, cbits, 1000) 14 | print(result) 15 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/14_SWAPGate.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | import numpy as np 3 | if __name__ == "__main__": 4 | init(QMachineType.CPU) 5 | qubits = qAlloc_many(2) 6 | cbits = cAlloc_many(2) 7 | # 构建量子程序 8 | prog = QProg() 9 | prog << X(qubits[0]) \ 10 | << SWAP(qubits[0], qubits[1]) \ 11 | << Measure(qubits[0], cbits[0]) \ 12 | << Measure(qubits[1], cbits[1]) 13 | # 量子程序运行1000次,并返回测量结果 14 | result = run_with_configuration(prog, cbits, 1000) 15 | print(result) 16 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/15_ToffoliGate.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | import numpy as np 3 | if __name__ == "__main__": 4 | init(QMachineType.CPU) 5 | qubits = qAlloc_many(3) 6 | cbits = cAlloc_many(3) 7 | # 构建量子程序 8 | prog = QProg() 9 | prog << X(qubits[1]) \ 10 | << X(qubits[2]) \ 11 | << Toffoli(qubits[1],qubits[2],qubits[0]) \ 12 | << Measure(qubits[0], cbits[0]) \ 13 | << Measure(qubits[1], cbits[1]) \ 14 | << Measure(qubits[2], cbits[2]) 15 | # 量子程序运行1000次,并返回测量结果 16 | result = run_with_configuration(prog, cbits, 1000) 17 | print(result) 18 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/1_interface.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__ == "__main__": 3 | init(QMachineType.CPU) 4 | qubits = qAlloc_many(3) 5 | control_qubits = [qubits[0], qubits[1]] 6 | prog = create_empty_qprog() 7 | # 构建量子程序 8 | prog << H(qubits) \ 9 | << H(qubits[0]).dagger() \ 10 | << X(qubits[2]).control(control_qubits) 11 | # 对量子程序进行概率测量 12 | result = prob_run_dict(prog, qubits, -1) 13 | # 打印测量结果 14 | print(result) 15 | finalize() 16 | -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/2_ measure.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | 3 | if __name__ == "__main__": 4 | init(QMachineType.CPU) 5 | qubits = qAlloc_many(4) 6 | cbits = cAlloc_many(4) 7 | 8 | # 构建量子程序 9 | prog = QProg() 10 | prog << H(qubits[0])\ 11 | << H(qubits[1])\ 12 | << H(qubits[2])\ 13 | << H(qubits[3])\ 14 | << measure_all(qubits, cbits) 15 | 16 | # 量子程序运行1000次,并返回测量结果 17 | result = run_with_configuration(prog, cbits, 1000) 18 | 19 | # 打印测量结果 20 | print(result) 21 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/3_ pmeasure.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | 3 | if __name__ == "__main__": 4 | init(QMachineType.CPU) 5 | qubits = qAlloc_many(2) 6 | cbits = cAlloc_many(2) 7 | 8 | prog = QProg() 9 | prog << H(qubits[0])\ 10 | << CNOT(qubits[0], qubits[1]) 11 | 12 | print("prob_run_dict: ") 13 | result1 = prob_run_dict(prog, qubits, -1) 14 | print(result1) 15 | 16 | print("prob_run_tuple_list: ") 17 | result2 = prob_run_tuple_list(prog, qubits, -1) 18 | print(result2) 19 | 20 | print("prob_run_list: ") 21 | result3 = prob_run_list(prog, qubits, -1) 22 | print(result3) 23 | 24 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/4_circuit.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__ == "__main__": 3 | init(QMachineType.CPU) 4 | qubits = qAlloc_many(4) 5 | cbits = cAlloc_many(4) 6 | # 构建量子程序 7 | prog = QProg() 8 | circuit = create_empty_circuit() 9 | circuit << H(qubits[0]) \ 10 | << CNOT(qubits[0], qubits[1]) \ 11 | << CNOT(qubits[1], qubits[2]) \ 12 | << CNOT(qubits[2], qubits[3]) 13 | prog << circuit << Measure(qubits[0], cbits[0]) 14 | # 量子程序运行1000次,并返回测量结果 15 | result = run_with_configuration(prog, cbits, 1000) 16 | # 打印量子态在量子程序多次运行结果中出现的次数 17 | print(result) 18 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/5_HGate.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__ == "__main__": 3 | init(QMachineType.CPU) 4 | qubits = qAlloc_many(1) 5 | cbits = cAlloc_many(1) 6 | # 构建量子程序 7 | prog = QProg() 8 | prog << H(qubits[0]) \ 9 | << Measure(qubits[0], cbits[0]) 10 | # 量子程序运行1000次,并返回测量结果 11 | result = run_with_configuration(prog, cbits, 1000) 12 | print(result) 13 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/6_XGate.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__ == "__main__": 3 | init(QMachineType.CPU) 4 | qubits = qAlloc_many(1) 5 | cbits = cAlloc_many(1) 6 | # 构建量子程序 7 | prog = QProg() 8 | prog << X(qubits[0]) \ 9 | << Measure(qubits[0], cbits[0]) 10 | # 量子程序运行1000次,并返回测量结果 11 | result = run_with_configuration(prog, cbits, 1000) 12 | print(result) 13 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/7_YGate.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__ == "__main__": 3 | init(QMachineType.CPU) 4 | qubits = qAlloc_many(1) 5 | cbits = cAlloc_many(1) 6 | # 构建量子程序 7 | prog = QProg() 8 | prog << Y(qubits[0]) \ 9 | << Measure(qubits[0], cbits[0]) 10 | # 量子程序运行1000次,并返回测量结果 11 | result = run_with_configuration(prog, cbits, 1000) 12 | print(result) 13 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/8_ZGate.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__ == "__main__": 3 | init(QMachineType.CPU) 4 | qubits = qAlloc_many(1) 5 | cbits = cAlloc_many(1) 6 | # 构建量子程序 7 | prog = QProg() 8 | prog << Z(qubits[0]) \ 9 | << Measure(qubits[0], cbits[0]) 10 | # 量子程序运行1000次,并返回测量结果 11 | result = run_with_configuration(prog, cbits, 1000) 12 | print(result) 13 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/basic_program/9_RXGate.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | import numpy as np 3 | if __name__ == "__main__": 4 | init(QMachineType.CPU) 5 | qubits = qAlloc_many(1) 6 | cbits = cAlloc_many(1) 7 | # 构建量子程序 8 | prog = QProg() 9 | prog << RX(qubits[0], np.pi/2) \ 10 | << Measure(qubits[0], cbits[0]) 11 | # 量子程序运行1000次,并返回测量结果 12 | result = run_with_configuration(prog, cbits, 1000) 13 | print(result) 14 | finalize() -------------------------------------------------------------------------------- /quantum_qpanda/components/0_PauliOperator.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | 3 | if __name__=="__main__": 4 | 5 | a = PauliOperator("Z0 Z1", 2) 6 | b = PauliOperator("X5 Y6", 3) 7 | 8 | plus = a + b 9 | minus = a - b 10 | muliply = a * b 11 | 12 | print("a + b = ", plus) 13 | print("a - b = ", minus) 14 | print("a * b = ", muliply) 15 | 16 | print("Index : ", muliply.getMaxIndex()) 17 | 18 | index_map = {} 19 | remap_pauli = muliply.remapQubitIndex(index_map) 20 | 21 | print("remap_pauli : ", remap_pauli) 22 | print("Index : ", remap_pauli.getMaxIndex()) -------------------------------------------------------------------------------- /quantum_qpanda/components/1_FermionOperator.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | 3 | if __name__=="__main__": 4 | 5 | a = FermionOperator("0 1+", 2) 6 | b = FermionOperator("2+ 3", 3) 7 | 8 | plus = a + b 9 | minus = a - b 10 | muliply = a * b 11 | 12 | print("a + b = ", plus) 13 | print("a - b = ", minus) 14 | print("a * b = ", muliply) 15 | 16 | print("normal_ordered(a + b) = ", plus.normal_ordered()) 17 | print("normal_ordered(a - b) = ", minus.normal_ordered()) 18 | print("normal_ordered(a * b) = ", muliply.normal_ordered()) -------------------------------------------------------------------------------- /quantum_qpanda/components/2_Optimizer.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | import numpy as np 3 | import matplotlib 4 | matplotlib.use('TkAgg') 5 | import matplotlib.pyplot as plt 6 | 7 | x = np.array([3.3, 4.4, 5.5, 6.71, 6.93, 4.168, 9.779, 6.182, 7.59, 8 | 2.167, 7.042, 10.791, 5.313, 7.997, 5.654, 9.27,3.1]) 9 | y = np.array([1.7, 2.76, 2.09, 3.19, 1.694, 1.573, 3.366, 2.596, 2.53, 10 | 1.221, 2.827, 3.465, 1.65, 2.904, 2.42, 2.94,1.3]) 11 | 12 | def lossFunc(para,grad,inter,fcall): 13 | y_ = np.zeros(len(y)) 14 | 15 | for i in range(len(y)): 16 | y_[i] = para[0] * x[i] + para[1] 17 | 18 | loss = 0 19 | for i in range(len(y)): 20 | loss += (y_[i] - y[i])**2/len(y) 21 | 22 | return ("", loss) 23 | 24 | optimizer = OptimizerFactory.makeOptimizer('NELDER_MEAD') 25 | 26 | init_para = [0, 0] 27 | optimizer.registerFunc(lossFunc, init_para) 28 | optimizer.setXatol(1e-6) 29 | optimizer.setFatol(1e-6) 30 | optimizer.setMaxIter(200) 31 | optimizer.exec() 32 | 33 | result = optimizer.getResult() 34 | print(result.message) 35 | print(" Current function value: ", result.fun_val) 36 | print(" Iterations: ", result.iters) 37 | print(" Function evaluations: ", result.fcalls) 38 | print(" Optimized para: W: ", result.para[0], " b: ", result.para[1]) 39 | 40 | w = result.para[0] 41 | b = result.para[1] 42 | 43 | plt.plot(x, y, 'o', label = 'Training data') 44 | plt.plot(x, w*x + b, 'r', label = 'Fitted line') 45 | plt.legend() 46 | plt.show() -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/0_NodeIter.py: -------------------------------------------------------------------------------- 1 | import pyqpanda.pyQPanda as pq 2 | import math 3 | 4 | machine = pq.init_quantum_machine(pq.QMachineType.CPU) 5 | q = machine.qAlloc_many(8) 6 | c = machine.cAlloc_many(8) 7 | prog = pq.QProg() 8 | 9 | prog << pq.H(q[0]) << pq.S(q[2]) << pq.CNOT(q[0], q[1]) \ 10 | << pq.CZ(q[1], q[2]) << pq.CR(q[1], q[2], math.pi/2) 11 | iter_head = prog.head() 12 | iter = prog.last() 13 | while iter != iter_head: 14 | if pq.NodeType.GATE_NODE == iter.get_node_type(): 15 | gate = pq.QGate(iter) 16 | print(gate.gate_type()) 17 | iter = iter.get_pre() 18 | else: 19 | print('Traversal End.\n') -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/0_NodeIter_reverse.py: -------------------------------------------------------------------------------- 1 | import pyqpanda.pyQPanda as pq 2 | import math 3 | 4 | machine = pq.init_quantum_machine(pq.QMachineType.CPU) 5 | q = machine.qAlloc_many(8) 6 | c = machine.cAlloc_many(8) 7 | prog = pq.QProg() 8 | 9 | prog << pq.H(q[0]) << pq.S(q[2]) << pq.CNOT(q[0], q[1]) \ 10 | << pq.CZ(q[1], q[2]) << pq.CR(q[1], q[2], math.pi/2) 11 | iter = prog.begin() 12 | iter_end = prog.end() 13 | while iter != iter_end: 14 | if pq.NodeType.GATE_NODE == iter.get_node_type(): 15 | gate = pq.QGate(iter) 16 | print(gate.gate_type()) 17 | iter = iter.get_next() 18 | else: 19 | print('Traversal End.\n') 20 | 21 | pq.destroy_quantum_machine(machine) 22 | -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/10_Qubit_Rb.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | 3 | if __name__=="__main__": 4 | # 构建噪声虚拟机,调整噪声模拟真实芯片 5 | qvm = NoiseQVM() 6 | qvm.init_qvm() 7 | qvm.set_noise_model(NoiseModel.DEPOLARIZING_KRAUS_OPERATOR, GateType.CZ_GATE, 0.005) 8 | qvm.set_noise_model(NoiseModel.DEPOLARIZING_KRAUS_OPERATOR, GateType.PAULI_Y_GATE, 0.005) 9 | qv = qvm.qAlloc_many(4) 10 | 11 | # 同样可以申请云计算机器(采用真实芯片) 12 | # qvm = QCloud() 13 | # qvm.init_qvm("898D47CF515A48CEAA9F2326394B85C6") 14 | 15 | # 设置随机线路中clifford门集数量 16 | range = [ 5,10,15 ] 17 | 18 | # 测量单比特随机基准 19 | res = single_qubit_rb(qvm, qv[0], range, 10, 1000) 20 | 21 | # 同样可以测量两比特随机基准 22 | #res = double_qubit_rb(qvm, qv[0], qv[1], range, 10, 1000) 23 | 24 | # 对应的数值随噪声影响,噪声数值越大,所得结果越小,且随clifford门集数量增多,结果数值越小。 25 | print(res) 26 | 27 | qvm.finalize() -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/11_Gate_Xeb.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | 3 | if __name__=="__main__": 4 | 5 | # 构建噪声虚拟机,调整噪声模拟真实芯片 6 | qvm = NoiseQVM() 7 | qvm.init_qvm() 8 | qv = qvm.qAlloc_many(4) 9 | 10 | # 设置噪声参数 11 | qvm.set_noise_model(NoiseModel.DEPOLARIZING_KRAUS_OPERATOR, GateType.CZ_GATE, 0.1) 12 | 13 | # 同样可以申请云计算机器(采用真实芯片) 14 | # qvm = QCloud() 15 | # qvm.init_qvm("898D47CF515A48CEAA9F2326394B85C6") 16 | 17 | # 设置不同层数组合 18 | range = [2,4,6,8,10] 19 | # 现在可测试双门类型主要为CZ CNOT SWAP ISWAP SQISWAP 20 | res = double_gate_xeb(qvm, qv[0], qv[1], range, 10, 1000, GateType.CZ_GATE) 21 | # 对应的数值随噪声影响,噪声数值越大,所得结果越小,且层数增多,结果数值越小。 22 | 23 | print(res) 24 | 25 | qvm.finalize() -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/1_Gate_Counter.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__ == "__main__": 3 | qvm = init_quantum_machine(QMachineType.CPU) 4 | qubits = qvm.qAlloc_many(2) 5 | cbits = qvm.cAlloc_many(2) 6 | prog = QProg() 7 | # 构建量子程序 8 | prog << X(qubits[0]) << Y(qubits[1])\ 9 | << H(qubits[0]) << RX(qubits[0], 3.14)\ 10 | << Measure(qubits[0], cbits[0]) 11 | # 统计逻辑门个数 12 | number = get_qgate_num(prog) 13 | print("QGate number: " + str(number)) 14 | qvm.finalize() -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/2_Clock_Cycle.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | import numpy as np 3 | 4 | if __name__ == "__main__": 5 | qvm = init_quantum_machine(QMachineType.CPU) 6 | qubits = qvm.qAlloc_many(4) 7 | cbits = qvm.cAlloc_many(4) 8 | # 构建量子程序 9 | prog = QProg() 10 | prog << H(qubits[0]) << CNOT(qubits[0], qubits[1])\ 11 | << iSWAP(qubits[1], qubits[2]) << RX(qubits[3], np.pi / 4) 12 | 13 | # 统计量子程序时钟周期 14 | clock_cycle = get_qprog_clock_cycle(prog, qvm) 15 | print(clock_cycle) 16 | destroy_quantum_machine(qvm) -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/3_Get_Matrix.py: -------------------------------------------------------------------------------- 1 | import pyqpanda.pyQPanda as pq 2 | import math 3 | class InitQMachine: 4 | def __init__(self, quBitCnt, cBitCnt, machineType = pq.QMachineType.CPU): 5 | self.m_machine = pq.init_quantum_machine(machineType) 6 | self.m_qlist = self.m_machine.qAlloc_many(quBitCnt) 7 | self.m_clist = self.m_machine.cAlloc_many(cBitCnt) 8 | self.m_prog = pq.QProg() 9 | def __del__(self): 10 | pq.destroy_quantum_machine(self.m_machine) 11 | 12 | def get_matrix(q, c): 13 | prog = pq.QProg() 14 | # 构建量子程序 15 | prog << pq.H(q[0]) \ 16 | << pq.S(q[2]) \ 17 | << pq.CNOT(q[0], q[1]) \ 18 | << pq.CZ(q[1], q[2]) \ 19 | << pq.CR(q[1], q[2], math.pi/2) 20 | # 获取线路对应矩阵 21 | result_mat = pq.get_matrix(prog) 22 | # 打印矩阵信息 23 | pq.print_matrix(result_mat) 24 | 25 | if __name__=="__main__": 26 | init_machine = InitQMachine(16, 16) 27 | qlist = init_machine.m_qlist 28 | clist = init_machine.m_clist 29 | machine = init_machine.m_machine 30 | get_matrix(qlist, clist) 31 | print("Test over.") -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/4_Match_Topology.py: -------------------------------------------------------------------------------- 1 | import pyqpanda.pyQPanda as pq 2 | import math 3 | 4 | class InitQMachine: 5 | def __init__(self, quBitCnt, cBitCnt, machineType = pq.QMachineType.CPU): 6 | self.m_machine = pq.init_quantum_machine(machineType) 7 | self.m_qlist = self.m_machine.qAlloc_many(quBitCnt) 8 | self.m_clist = self.m_machine.cAlloc_many(cBitCnt) 9 | self.m_prog = pq.QProg() 10 | 11 | def __del__(self): 12 | pq.destroy_quantum_machine(self.m_machine) 13 | 14 | def is_match_topology(q, c): 15 | cx = pq.CNOT(q[1], q[3]) 16 | 17 | # 构建拓扑结构 18 | qubits_topology = [[0,1,0,0,0],[1,0,1,1,0],[0,1,0,0,0],[0,1,0,0,1],[0,0,0,1,0]] 19 | 20 | #判断逻辑门是否符合量子拓扑结构 21 | if (pq.is_match_topology(cx,qubits_topology)) == True: 22 | print('Match !\n') 23 | else: 24 | print('Not match.') 25 | 26 | if __name__=="__main__": 27 | init_machine = InitQMachine(16, 16) 28 | qlist = init_machine.m_qlist 29 | clist = init_machine.m_clist 30 | machine = init_machine.m_machine 31 | is_match_topology(qlist, clist) 32 | print("Test over.") -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/5_Adjacent_Qgate_Type.py: -------------------------------------------------------------------------------- 1 | import pyqpanda.pyQPanda as pq 2 | 3 | class InitQMachine: 4 | def __init__(self, quBitCnt, cBitCnt, machineType = pq.QMachineType.CPU): 5 | self.m_machine = pq.init_quantum_machine(machineType) 6 | self.m_qlist = self.m_machine.qAlloc_many(quBitCnt) 7 | self.m_clist = self.m_machine.cAlloc_many(cBitCnt) 8 | self.m_prog = pq.QProg() 9 | 10 | def __del__(self): 11 | pq.destroy_quantum_machine(self.m_machine) 12 | 13 | def get_adjacent_qgate_type(qlist, clist): 14 | prog = pq.QProg() 15 | 16 | # 构建量子程序 17 | prog << pq.T(qlist[0]) \ 18 | << pq.CNOT(qlist[1], qlist[2]) \ 19 | << pq.Reset(qlist[1]) \ 20 | << pq.H(qlist[3]) \ 21 | << pq.H(qlist[4]) 22 | 23 | iter = prog.begin() 24 | iter = iter.get_next() 25 | type =iter.get_node_type() 26 | if pq.NodeType.GATE_NODE == type: 27 | gate = pq.QGate(iter) 28 | print(gate.gate_type()) 29 | 30 | # 获取指定位置前后逻辑门类型 31 | list = pq.get_adjacent_qgate_type(prog,iter) 32 | print(len(list)) 33 | print(len(list[0].m_target_qubits)) 34 | print(list[1].m_is_dagger) 35 | 36 | node_type = list[0].m_node_type 37 | print(node_type) 38 | if node_type == pq.NodeType.GATE_NODE: 39 | gateFront = pq.QGate(list[0].m_iter) 40 | print(gateFront.gate_type()) 41 | 42 | node_type = list[1].m_node_type 43 | print(node_type) 44 | if node_type == pq.NodeType.GATE_NODE: 45 | gateBack = pq.QGate(list[1].m_iter) 46 | print(gateBack.gate_type()) 47 | 48 | if __name__=="__main__": 49 | init_machine = InitQMachine(16, 16) 50 | qlist = init_machine.m_qlist 51 | clist = init_machine.m_clist 52 | machine = init_machine.m_machine 53 | get_adjacent_qgate_type(qlist, clist) 54 | print("Test over.") -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/6_Is_Swappable.py: -------------------------------------------------------------------------------- 1 | import pyqpanda.pyQPanda as pq 2 | import math 3 | 4 | class InitQMachine: 5 | def __init__(self, quBitCnt, cBitCnt, machineType = pq.QMachineType.CPU): 6 | self.m_machine = pq.init_quantum_machine(machineType) 7 | self.m_qlist = self.m_machine.qAlloc_many(quBitCnt) 8 | self.m_clist = self.m_machine.cAlloc_many(cBitCnt) 9 | self.m_prog = pq.QProg() 10 | 11 | def __del__(self): 12 | pq.destroy_quantum_machine(self.m_machine) 13 | 14 | #测试接口: 判断指定的两个逻辑门是否可以交换位置 15 | def is_swappable(q, c): 16 | prog = pq.QProg() 17 | cir = pq.QCircuit() 18 | cir2 = pq.QCircuit() 19 | cir2 << pq.H(q[3]) << pq.RX(q[1], math.pi/2) << pq.T(q[2]) << pq.RY(q[3], math.pi/2) << pq.RZ(q[2], math.pi/2) 20 | cir2.set_dagger(True) 21 | cir << pq.H(q[1]) << cir2 << pq.CR(q[1], q[2], math.pi/2) 22 | prog << pq.H(q[0]) << pq.S(q[2]) \ 23 | << cir\ 24 | << pq.CNOT(q[0], q[1]) << pq.CZ(q[1], q[2]) << pq.measure_all(q,c) 25 | 26 | iter_first = cir.begin() 27 | 28 | iter_second = cir2.begin() 29 | #iter_second = iter_second.get_next() 30 | #iter_second = iter_second.get_next() 31 | #iter_second = iter_second.get_next() 32 | 33 | type =iter_first.get_node_type() 34 | if pq.NodeType.GATE_NODE == type: 35 | gate = pq.QGate(iter_first) 36 | print(gate.gate_type()) 37 | 38 | type =iter_second.get_node_type() 39 | if pq.NodeType.GATE_NODE == type: 40 | gate = pq.QGate(iter_second) 41 | print(gate.gate_type()) 42 | 43 | if (pq.is_swappable(prog, iter_first, iter_second)) == True: 44 | print('Could be swapped !\n') 45 | else: 46 | print('Could NOT be swapped.') 47 | 48 | if __name__=="__main__": 49 | init_machine = InitQMachine(16, 16) 50 | qlist = init_machine.m_qlist 51 | clist = init_machine.m_clist 52 | machine = init_machine.m_machine 53 | 54 | is_swappable(qlist, clist) 55 | print("Test over.") -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/7_Supported_Qgate_Type.py: -------------------------------------------------------------------------------- 1 | import pyqpanda.pyQPanda as pq 2 | 3 | class InitQMachine: 4 | def __init__(self, quBitCnt, cBitCnt, machineType = pq.QMachineType.CPU): 5 | self.m_machine = pq.init_quantum_machine(machineType) 6 | self.m_qlist = self.m_machine.qAlloc_many(quBitCnt) 7 | self.m_clist = self.m_machine.cAlloc_many(cBitCnt) 8 | self.m_prog = pq.QProg() 9 | def __del__(self): 10 | pq.destroy_quantum_machine(self.m_machine) 11 | 12 | def support_qgate_type(): 13 | machine = pq.init_quantum_machine(pq.QMachineType.CPU) 14 | q = machine.qAlloc_many(8) 15 | prog = pq.QProg() 16 | prog << pq.H(q[1]) 17 | result = pq.is_supported_qgate_type(prog.begin()) 18 | if result == True: 19 | print('Support !\n') 20 | else: 21 | print('Unsupport !') 22 | 23 | if __name__=="__main__": 24 | init_machine = InitQMachine(16, 16) 25 | qlist = init_machine.m_qlist 26 | clist = init_machine.m_clist 27 | machine = init_machine.m_machine 28 | support_qgate_type() 29 | print("Test over.") -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/8_Print_Qcircuit.py: -------------------------------------------------------------------------------- 1 | import pyqpanda.pyQPanda as pq 2 | from pyqpanda.Visualization.circuit_draw import * 3 | import math 4 | class InitQMachine: 5 | def __init__(self, quBitCnt, cBitCnt, machineType = pq.QMachineType.CPU): 6 | self.m_machine = pq.init_quantum_machine(machineType) 7 | self.m_qlist = self.m_machine.qAlloc_many(quBitCnt) 8 | self.m_clist = self.m_machine.cAlloc_many(cBitCnt) 9 | 10 | def __del__(self): 11 | pq.destroy_quantum_machine(self.m_machine) 12 | 13 | def print_qcircuit(q, c): 14 | # 构建量子程序 15 | prog = pq.QCircuit() 16 | prog << pq.CU(1, 2, 3, 4, q[0], q[5]) << pq.H(q[0]) << pq.S(q[2])\ 17 | << pq.CNOT(q[0], q[1]) << pq.CZ(q[1], q[2]) << pq.CR(q[2], q[1], math.pi/2) 18 | prog.set_dagger(True) 19 | 20 | print('draw_qprog:') 21 | # 通过print直接输出量子线路字符画,该方法会在控制台输出量子线路,输出格式为utf8编码,所以在非utf8编码的控制台下,输出字符画会出现乱码情况。 22 | # 同时,该方法会将当前量子线路字符画信息保存到文件,文件名为 “QCircuitTextPic.txt”,文件用utf8编码,并保存在当面路径下面, 23 | # 所以用户也可以通过该文件查看量子线路信息,注意该文件要以uft8格式打开,否则会出现乱码。 24 | print(prog) 25 | # 通过draw_qprog接口输出量子线路字符画,该方法功能和print方法一样,区别在于该接口可以指定控制台编码类型,以保证在控制台输出的量子线路字符画能正常显示。 26 | # 参数“console_encode_type” 用于指定控制台类型,目前支持两种编码方式:utf8和gbk,默认为utf8 27 | draw_qprog(prog, 'text', console_encode_type='gbk') 28 | # draw_qprog接口还可以将量子线路保存成图片,调用方式如下。参数“filename”用于指定保存的文件名。 29 | draw_qprog(prog, 'pic', filename='./test_cir_draw.png') 30 | 31 | if __name__=="__main__": 32 | init_machine = InitQMachine(16, 16) 33 | qlist = init_machine.m_qlist 34 | clist = init_machine.m_clist 35 | machine = init_machine.m_machine 36 | 37 | print_qcircuit(qlist, clist) -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/9_Quantum_Volume.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | 3 | if __name__=="__main__": 4 | #构建噪声虚拟机,设置噪声参数 5 | qvm = NoiseQVM() 6 | qvm.init_qvm() 7 | qvm.set_noise_model(NoiseModel.DEPOLARIZING_KRAUS_OPERATOR, GateType.CZ_GATE, 0.005) 8 | #同样可以申请云计算机器(采用真实芯片),采用真实芯片要考虑芯片构造 9 | #qvm = QCloud() 10 | #qvm.init_qvm("898D47CF515A48CEAA9F2326394B85C6") 11 | 12 | #构建待测量的量子比特组合, 这里比特组合为2组,其中 量子比特3、4为一组;量子比特2,3,5为一组 13 | qubit_lists = [[3,4], [2,3,5]] 14 | 15 | #设置随机迭代次数 16 | ntrials = 100 17 | 18 | #设置测量次数,即真实芯片或者噪声虚拟机shots数值 19 | shots = 2000 20 | qv_result = calculate_quantum_volume(qvm, qubit_lists, ntrials, shots) 21 | print("Quantum Volume : ", qv_result) 22 | qvm.finalize() -------------------------------------------------------------------------------- /quantum_qpanda/prog_info/test_cir_draw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/quantum_qpanda/prog_info/test_cir_draw.png -------------------------------------------------------------------------------- /quantum_qpanda/tools/0_Circuit_Optimizer.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | if __name__=="__main__": 3 | machine = init_quantum_machine(QMachineType.CPU) 4 | q = machine.qAlloc_many(4) 5 | c = machine.cAlloc_many(4) 6 | # 构建量子程序 7 | prog = QProg() 8 | prog << H(q[0])\ 9 | << H(q[2])\ 10 | << H(q[3])\ 11 | << CNOT(q[1], q[0])\ 12 | << H(q[0])\ 13 | << CNOT(q[1], q[2])\ 14 | << H(q[2])\ 15 | << CNOT(q[2], q[3])\ 16 | << H(q[3]) 17 | # 构建查询线路 18 | query_cir = QCircuit() 19 | query_cir << H(q[0])\ 20 | << CNOT(q[1], q[0])\ 21 | << H(q[0]) 22 | # 构建替换线路 23 | replace_cir = QCircuit() 24 | replace_cir << CZ(q[1], q[0]) 25 | print("查询替换前:") 26 | print(convert_qprog_to_originir(prog,machine)) 27 | # 搜索量子程序中的查询线路,并用替换线路替代 28 | update_prog = circuit_optimizer(prog, [[query_cir, replace_cir]]) 29 | print("查询替换后:") 30 | print(convert_qprog_to_originir(update_prog,machine)) -------------------------------------------------------------------------------- /quantum_qpanda/tools/1_Fill_Qprog_By_I.py: -------------------------------------------------------------------------------- 1 | import pyqpanda.pyQPanda as pq 2 | import math 3 | from pyqpanda.Visualization.circuit_draw import * 4 | import numpy as np 5 | class InitQMachine: 6 | def __init__(self, quBitCnt, cBitCnt, machineType = pq.QMachineType.CPU): 7 | self.m_machine = pq.init_quantum_machine(machineType) 8 | self.m_qlist = self.m_machine.qAlloc_many(quBitCnt) 9 | self.m_clist = self.m_machine.cAlloc_many(cBitCnt) 10 | def __del__(self): 11 | pq.destroy_quantum_machine(self.m_machine) 12 | def fill_I(q, c): 13 | # 构建量子程序 14 | prog = pq.QCircuit() 15 | prog << pq.CU(1, 2, 3, 4, q[0], q[5]) << pq.H(q[0]) << pq.S(q[2]) << pq.CNOT(q[0], q[1]) << pq.CZ(q[1], q[2]) << pq.CR(q[2], q[1], math.pi/2) 16 | prog.set_dagger(True) 17 | # 输出原量子程序 18 | print('source prog:') 19 | draw_qprog(prog, 'text',console_encode_type='gbk') 20 | """ 21 | console_encode_type='utf8' or 'gbk'(默认'utf8') 22 | """ 23 | # 量子程序填充 I 门 24 | prog = pq.fill_qprog_by_I(prog) 25 | # 输出填充 I 门的量子程序 26 | print('The prog after fill_qprog_by_I:') 27 | draw_qprog(prog, 'text',console_encode_type='gbk') 28 | draw_qprog(prog, 'pic', filename='./test_cir_draw.png') 29 | if __name__=="__main__": 30 | init_machine = InitQMachine(16, 16) 31 | qlist = init_machine.m_qlist 32 | clist = init_machine.m_clist 33 | machine = init_machine.m_machine 34 | fill_I(qlist, clist) -------------------------------------------------------------------------------- /quantum_qpanda/tools/2_Matrix_Decompose.py: -------------------------------------------------------------------------------- 1 | import pyqpanda as pq 2 | import numpy as np 3 | 4 | if __name__=="__main__": 5 | 6 | machine = pq.init_quantum_machine(pq.QMachineType.CPU) 7 | q = machine.qAlloc_many(2) 8 | c = machine.cAlloc_many(2) 9 | 10 | source_matrix = [(0.6477054522122977+0.1195417767870219j), (-0.16162176706189357-0.4020495632468249j), (-0.19991615329121998-0.3764618308248643j), (-0.2599957197928922-0.35935248873007863j), 11 | (-0.16162176706189363-0.40204956324682495j), (0.7303014482204584-0.4215172444390785j), (-0.15199187936216693+0.09733585496768032j), (-0.22248203136345918-0.1383600597660744j), 12 | (-0.19991615329122003-0.3764618308248644j), (-0.15199187936216688+0.09733585496768032j), (0.6826630277354306-0.37517063774206166j), (-0.3078966462928956-0.2900897445133085j), 13 | (-0.2599957197928923-0.3593524887300787j), (-0.22248203136345912-0.1383600597660744j), (-0.30789664629289554-0.2900897445133085j), (0.6640994547408099-0.338593803336005j)] 14 | 15 | print("source matrix : ") 16 | print(source_matrix) 17 | 18 | out_cir = pq.matrix_decompose(q, source_matrix) 19 | circuit_matrix = pq.get_matrix(out_cir) 20 | 21 | print("the decomposed matrix : ") 22 | print(circuit_matrix) 23 | 24 | source_matrix = np.round(np.array(source_matrix),3) 25 | circuit_matrix = np.round(np.array(circuit_matrix),3) 26 | 27 | if np.all(source_matrix == circuit_matrix): 28 | print('matrix decompose ok !') 29 | else: 30 | print('matrix decompose false !') -------------------------------------------------------------------------------- /quantum_qpanda/tools/test_cir_draw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/quantum_qpanda/tools/test_cir_draw.png -------------------------------------------------------------------------------- /quantum_qpanda/vqc/0_Var.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | import numpy as np 3 | 4 | if __name__=="__main__": 5 | 6 | m1 = np.array([[1., 2.],[3., 4.]]) 7 | v1 = var(m1) 8 | 9 | m2 = np.array([[5., 6.],[7., 8.]]) 10 | v2 = var(m2) 11 | 12 | sum = v1 + v2 13 | minus = v1 - v2 14 | multiply = v1 * v2 15 | 16 | print("v1: ", v1.get_value()) 17 | print("v2: ", v2.get_value()) 18 | print("sum: " , eval(sum)) 19 | print("minus: " , eval(minus)) 20 | print("multiply: " , eval(multiply)) 21 | 22 | m3 = np.array([[4., 3.],[2., 1.]]) 23 | v1.set_value(m3) 24 | 25 | print("sum: " , eval(sum)) 26 | print("minus: " , eval(minus)) 27 | print("multiply: " , eval(multiply)) -------------------------------------------------------------------------------- /quantum_qpanda/vqc/1_VQC_VGQ.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | 3 | if __name__=="__main__": 4 | 5 | machine = init_quantum_machine(QMachineType.CPU) 6 | q = machine.qAlloc_many(2) 7 | 8 | x = var(1) 9 | y = var(2) 10 | 11 | 12 | vqc = VariationalQuantumCircuit() 13 | vqc.insert(VariationalQuantumGate_H(q[0])) 14 | vqc.insert(VariationalQuantumGate_RX(q[0], x)) 15 | vqc.insert(VariationalQuantumGate_RY(q[1], y)) 16 | vqc.insert(VariationalQuantumGate_RZ(q[0], 0.12)) 17 | vqc.insert(VariationalQuantumGate_CZ(q[0], q[1])) 18 | vqc.insert(VariationalQuantumGate_CNOT(q[0], q[1])) 19 | 20 | circuit1 = vqc.feed() 21 | 22 | prog = QProg() 23 | prog.insert(circuit1) 24 | 25 | print(convert_qprog_to_originir(prog, machine)) 26 | 27 | x.set_value([[3.]]) 28 | y.set_value([[4.]]) 29 | 30 | circuit2 = vqc.feed() 31 | prog2 = QProg() 32 | prog2.insert(circuit2) 33 | print(convert_qprog_to_originir(prog2, machine)) -------------------------------------------------------------------------------- /quantum_qpanda/vqc/2_Optimizer.py: -------------------------------------------------------------------------------- 1 | from pyqpanda import * 2 | import numpy as np 3 | import matplotlib 4 | matplotlib.use('TkAgg') 5 | import matplotlib.pyplot as plt 6 | 7 | x = np.array([3.3, 4.4, 5.5, 6.71, 6.93, 4.168, 9.779, 6.182, 7.59, 8 | 2.167, 7.042, 10.791, 5.313, 7.997, 5.654, 9.27,3.1]) 9 | y = np.array([1.7, 2.76, 2.09, 3.19, 1.694, 1.573, 3.366, 2.596, 2.53, 10 | 1.221, 2.827, 3.465, 1.65, 2.904, 2.42, 2.94,1.3]) 11 | 12 | 13 | X = var(x.reshape(len(x), 1)) 14 | Y = var(y.reshape(len(y), 1)) 15 | 16 | W = var(0, True) 17 | B = var(0, True) 18 | 19 | Y_ = W*X + B 20 | 21 | loss = sum(poly(Y_ - Y, var(2))/len(x)) 22 | 23 | optimizer = VanillaGradientDescentOptimizer.minimize(loss, 0.01, 1.e-6) 24 | leaves = optimizer.get_variables() 25 | 26 | for i in range(1000): 27 | optimizer.run(leaves, 0) 28 | loss_value = optimizer.get_loss() 29 | print("i: ", i, " loss: ", loss_value, " W: ", eval(W,True), " b: ", eval(B, True)) 30 | 31 | w2 = W.get_value()[0, 0] 32 | b2 = B.get_value()[0, 0] 33 | 34 | plt.plot(x, y, 'o', label = 'Training data') 35 | plt.plot(x, w2*x + b2, 'r', label = 'Fitted line') 36 | plt.legend() 37 | plt.show() -------------------------------------------------------------------------------- /量子计算【编程篇】/第1章 编程基础.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【编程篇】/第1章 编程基础.pdf -------------------------------------------------------------------------------- /量子计算【编程篇】/第2章 编程进阶.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【编程篇】/第2章 编程进阶.pdf -------------------------------------------------------------------------------- /量子计算【编程篇】/第3章 常用工具接口.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【编程篇】/第3章 常用工具接口.pdf -------------------------------------------------------------------------------- /量子计算【编程篇】/第4章 组件-算符、优化算法.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【编程篇】/第4章 组件-算符、优化算法.pdf -------------------------------------------------------------------------------- /量子计算【编程篇】/第5章 VQC-变量、可变量子门.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【编程篇】/第5章 VQC-变量、可变量子门.pdf -------------------------------------------------------------------------------- /量子计算【量子金融】/第10章 固定收益定价.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【量子金融】/第10章 固定收益定价.pdf -------------------------------------------------------------------------------- /量子计算【量子金融】/第11章 信用风险分析.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【量子金融】/第11章 信用风险分析.pdf -------------------------------------------------------------------------------- /量子计算【量子金融】/第12章 QGAN期权定价.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【量子金融】/第12章 QGAN期权定价.pdf -------------------------------------------------------------------------------- /量子计算【量子金融】/第1章 量子金融概要.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【量子金融】/第1章 量子金融概要.pdf -------------------------------------------------------------------------------- /量子计算【量子金融】/第2章 量子振幅估计.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【量子金融】/第2章 量子振幅估计.pdf -------------------------------------------------------------------------------- /量子计算【量子金融】/第3章 投资组合优化.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【量子金融】/第3章 投资组合优化.pdf -------------------------------------------------------------------------------- /量子计算【量子金融】/第4章 分散投资.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【量子金融】/第4章 分散投资.pdf -------------------------------------------------------------------------------- /量子计算【量子金融】/第5章 欧式看涨期权定价.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【量子金融】/第5章 欧式看涨期权定价.pdf -------------------------------------------------------------------------------- /量子计算【量子金融】/第6章 欧式看跌期权定价.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【量子金融】/第6章 欧式看跌期权定价.pdf -------------------------------------------------------------------------------- /量子计算【量子金融】/第7章 牛市套利.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【量子金融】/第7章 牛市套利.pdf -------------------------------------------------------------------------------- /量子计算【量子金融】/第8章 一篮子期权 (Basket Options).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【量子金融】/第8章 一篮子期权 (Basket Options).pdf -------------------------------------------------------------------------------- /量子计算【量子金融】/第9章 亚式障碍期权(Asian barriers options).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/qubits/a4b80d16dd49ce5bf026f71ce5f2cf4cee05f699/量子计算【量子金融】/第9章 亚式障碍期权(Asian barriers options).pdf --------------------------------------------------------------------------------