├── Tutorial ├── CN │ └── figures │ │ ├── Raman.png │ │ ├── phase.png │ │ ├── plot.png │ │ ├── Echo-CR.png │ │ ├── GRAPE1.png │ │ ├── MS-CNOT.PNG │ │ ├── MSgate.png │ │ ├── basicRB.png │ │ ├── coupler.png │ │ ├── cr-gate.png │ │ ├── cz-cnot.png │ │ ├── qubitMap.png │ │ ├── sphere.png │ │ ├── symmetry.png │ │ ├── Bell-State.png │ │ ├── alpha_show.png │ │ ├── cnot-gate.png │ │ ├── cr-circuit.png │ │ ├── laserPulse.png │ │ ├── pulse_show.png │ │ ├── trajectory.png │ │ ├── vqe-scheme.png │ │ ├── w-circuit.png │ │ ├── cali-cz-vz-1.png │ │ ├── cali-cz-vz-2.png │ │ ├── interleavedRB.png │ │ ├── noise_feature.png │ │ ├── vqe-circuit.png │ │ ├── vqe-crosstalk.png │ │ ├── vqe-scheme-cn.png │ │ ├── vqe-translate.png │ │ ├── zne-profile.png │ │ ├── Bell-state-CNOT.png │ │ ├── cali-cz-circuit.png │ │ ├── tutorial_noise.png │ │ ├── vqe-circuit-cn.png │ │ ├── vqe-scheduling.png │ │ ├── cnot-gate-hadamard.png │ │ ├── ion-native-circuit.png │ │ ├── phononion_coupling.png │ │ ├── vqe-crosstalk-cn.png │ │ ├── vqe-scheduling-cn.png │ │ ├── vqe-topo_structure.png │ │ ├── vqe-translate-cn.png │ │ ├── zne-extrapolation.png │ │ ├── zne-clifford-circuit.png │ │ ├── zne-pulse-rescale-h.png │ │ ├── cali-cz-dynamics-phase.png │ │ ├── hardware_qubit_control.png │ │ ├── vqe-topo_structure-cn.png │ │ └── tunable-coupler-architectrue.png └── EN │ └── figures │ ├── phase.png │ ├── plot.png │ ├── Echo-CR.png │ ├── GRAPE1.png │ ├── MS-CNOT.PNG │ ├── Raman-en.png │ ├── basicRB.png │ ├── coupler.png │ ├── cr-gate.png │ ├── cz-cnot.png │ ├── qubitMap.png │ ├── sphere.png │ ├── symmetry.png │ ├── Bell-State.png │ ├── MSgate-en.png │ ├── alpha_show.png │ ├── cnot-gate.png │ ├── cr-circuit.png │ ├── laserPulse.png │ ├── pulse_show.png │ ├── trajectory.png │ ├── vqe-scheme.png │ ├── w-circuit.png │ ├── cali-cz-vz-1.png │ ├── cali-cz-vz-2.png │ ├── interleavedRB.png │ ├── noise_feature.png │ ├── vqe-circuit.png │ ├── vqe-crosstalk.png │ ├── vqe-translate.png │ ├── zne-profile.png │ ├── Bell-state-CNOT.png │ ├── cali-cz-circuit.png │ ├── tutorial_noise.png │ ├── vqe-scheduling.png │ ├── cnot-gate-hadamard.png │ ├── ion-native-circuit.png │ ├── phononion_coupling.png │ ├── vqe-topo_structure.png │ ├── zne-extrapolation.png │ ├── zne-clifford-circuit.png │ ├── zne-pulse-rescale-h.png │ ├── cali-cz-dynamics-phase.png │ ├── hardware_qubit_control.png │ └── tunable-coupler-architectrue.png ├── Quanlse.bib ├── Requirements └── requirements.txt ├── LICENSE ├── Quanlse ├── __init__.py ├── TrappedIon │ ├── __init__.py │ ├── Optimizer │ │ └── __init__.py │ └── SchedulerSupport │ │ ├── __init__.py │ │ └── DefaultPulseGenerator.py ├── Superconduct │ ├── __init__.py │ ├── Calibration │ │ ├── __init__.py │ │ └── Readout.py │ ├── Lab │ │ ├── __init__.py │ │ ├── Runner.py │ │ ├── Generator.py │ │ └── Utils.py │ ├── SchedulerSupport │ │ ├── PipelineLeftAligned.py │ │ ├── PipelineCenterAligned.py │ │ ├── GeneratorRBPulse.py │ │ ├── __init__.py │ │ └── GeneratorCloud.py │ └── Simulator │ │ ├── __init__.py │ │ ├── ReadoutSim3Q.py │ │ ├── SimulatorAgent.py │ │ ├── PulseSim1Q.py │ │ ├── PulseSim2Q.py │ │ └── PulseSim3Q.py ├── ErrorMitigation │ ├── __init__.py │ ├── Utils │ │ └── __init__.py │ └── ZNE │ │ └── __init__.py ├── QPlatform │ ├── __init__.py │ ├── Error.py │ └── Utilities.py ├── Utils │ ├── __init__.py │ ├── NumbaSupport.py │ ├── ControlGate.py │ ├── Clifford.py │ ├── Infidelity.py │ ├── Benchmark.py │ ├── WaveFunction.py │ ├── RandomizedBenchmarking.py │ └── Bloch.py ├── Define │ ├── Settings.py │ └── __init__.py ├── remoteSimulator.py ├── Scheduler │ ├── SchedulerPulseGenerator.py │ └── GatePulsePair.py ├── QRegPool.py ├── QRpc.py ├── remoteZNE.py └── QOperation │ └── __init__.py ├── .gitignore ├── setup.py ├── Example ├── 1-example-pi-pulse.py ├── 6-example-optimizer1QubitGRAPE.py ├── 2-example-single-qubit-gate.py ├── 8-example-scheduler-superconduct.py ├── 10-example-ion-MS-gate.py ├── 14-example-robust-MS-gate.py ├── 5-example-iswap-gate.py ├── 4-example-controlled-z-gate.py ├── 3-example-cross-resonance-gate.py ├── 7-example-pulse-simulator.py ├── 11-example-ion-general-MS-gate.py ├── 13-Example-readout.py └── 9-example-RB.py ├── CHANGELOG.md └── README_CN.md /Tutorial/CN/figures/Raman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/Raman.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/phase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/phase.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/plot.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/phase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/phase.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/plot.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/Echo-CR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/Echo-CR.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/GRAPE1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/GRAPE1.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/MS-CNOT.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/MS-CNOT.PNG -------------------------------------------------------------------------------- /Tutorial/CN/figures/MSgate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/MSgate.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/basicRB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/basicRB.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/coupler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/coupler.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/cr-gate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/cr-gate.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/cz-cnot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/cz-cnot.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/qubitMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/qubitMap.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/sphere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/sphere.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/symmetry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/symmetry.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/Echo-CR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/Echo-CR.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/GRAPE1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/GRAPE1.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/MS-CNOT.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/MS-CNOT.PNG -------------------------------------------------------------------------------- /Tutorial/EN/figures/Raman-en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/Raman-en.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/basicRB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/basicRB.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/coupler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/coupler.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/cr-gate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/cr-gate.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/cz-cnot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/cz-cnot.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/qubitMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/qubitMap.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/sphere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/sphere.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/symmetry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/symmetry.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/Bell-State.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/Bell-State.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/alpha_show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/alpha_show.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/cnot-gate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/cnot-gate.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/cr-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/cr-circuit.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/laserPulse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/laserPulse.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/pulse_show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/pulse_show.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/trajectory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/trajectory.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/vqe-scheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/vqe-scheme.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/w-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/w-circuit.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/Bell-State.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/Bell-State.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/MSgate-en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/MSgate-en.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/alpha_show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/alpha_show.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/cnot-gate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/cnot-gate.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/cr-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/cr-circuit.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/laserPulse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/laserPulse.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/pulse_show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/pulse_show.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/trajectory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/trajectory.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/vqe-scheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/vqe-scheme.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/w-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/w-circuit.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/cali-cz-vz-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/cali-cz-vz-1.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/cali-cz-vz-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/cali-cz-vz-2.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/interleavedRB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/interleavedRB.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/noise_feature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/noise_feature.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/vqe-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/vqe-circuit.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/vqe-crosstalk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/vqe-crosstalk.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/vqe-scheme-cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/vqe-scheme-cn.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/vqe-translate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/vqe-translate.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/zne-profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/zne-profile.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/cali-cz-vz-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/cali-cz-vz-1.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/cali-cz-vz-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/cali-cz-vz-2.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/interleavedRB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/interleavedRB.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/noise_feature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/noise_feature.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/vqe-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/vqe-circuit.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/vqe-crosstalk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/vqe-crosstalk.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/vqe-translate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/vqe-translate.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/zne-profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/zne-profile.png -------------------------------------------------------------------------------- /Quanlse.bib: -------------------------------------------------------------------------------- 1 | @misc{Quanlse, 2 | title = {{Quanlse}}, 3 | year = {2021}, 4 | url = {https://quanlse.baidu.com}, 5 | } -------------------------------------------------------------------------------- /Tutorial/CN/figures/Bell-state-CNOT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/Bell-state-CNOT.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/cali-cz-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/cali-cz-circuit.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/tutorial_noise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/tutorial_noise.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/vqe-circuit-cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/vqe-circuit-cn.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/vqe-scheduling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/vqe-scheduling.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/Bell-state-CNOT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/Bell-state-CNOT.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/cali-cz-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/cali-cz-circuit.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/tutorial_noise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/tutorial_noise.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/vqe-scheduling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/vqe-scheduling.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/cnot-gate-hadamard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/cnot-gate-hadamard.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/ion-native-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/ion-native-circuit.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/phononion_coupling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/phononion_coupling.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/vqe-crosstalk-cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/vqe-crosstalk-cn.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/vqe-scheduling-cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/vqe-scheduling-cn.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/vqe-topo_structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/vqe-topo_structure.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/vqe-translate-cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/vqe-translate-cn.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/zne-extrapolation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/zne-extrapolation.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/cnot-gate-hadamard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/cnot-gate-hadamard.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/ion-native-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/ion-native-circuit.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/phononion_coupling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/phononion_coupling.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/vqe-topo_structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/vqe-topo_structure.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/zne-extrapolation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/zne-extrapolation.png -------------------------------------------------------------------------------- /Requirements/requirements.txt: -------------------------------------------------------------------------------- 1 | numpy==1.20.2 2 | scipy==1.6.2 3 | matplotlib==3.4.1 4 | requests==2.25.1 5 | bce-python-sdk==0.8.59 6 | -------------------------------------------------------------------------------- /Tutorial/CN/figures/zne-clifford-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/zne-clifford-circuit.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/zne-pulse-rescale-h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/zne-pulse-rescale-h.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/zne-clifford-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/zne-clifford-circuit.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/zne-pulse-rescale-h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/zne-pulse-rescale-h.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/cali-cz-dynamics-phase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/cali-cz-dynamics-phase.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/hardware_qubit_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/hardware_qubit_control.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/vqe-topo_structure-cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/vqe-topo_structure-cn.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/cali-cz-dynamics-phase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/cali-cz-dynamics-phase.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/hardware_qubit_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/hardware_qubit_control.png -------------------------------------------------------------------------------- /Tutorial/CN/figures/tunable-coupler-architectrue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/CN/figures/tunable-coupler-architectrue.png -------------------------------------------------------------------------------- /Tutorial/EN/figures/tunable-coupler-architectrue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/Quanlse/HEAD/Tutorial/EN/figures/tunable-coupler-architectrue.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Baidu. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /Quanlse/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Quanlse/__init__.py 20 | """ 21 | 22 | -------------------------------------------------------------------------------- /Quanlse/TrappedIon/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Quanlse Trapped Ion 20 | """ 21 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Quanlse Superconduct 20 | """ 21 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/Calibration/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2020 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Calibration Toolkit 20 | """ -------------------------------------------------------------------------------- /Quanlse/ErrorMitigation/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Quanlse/ErrorMitigation/__init__.py 20 | """ -------------------------------------------------------------------------------- /Quanlse/QPlatform/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Export the entire directory as a library 20 | """ 21 | -------------------------------------------------------------------------------- /Quanlse/Utils/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Export the entire directory as a library 20 | """ 21 | -------------------------------------------------------------------------------- /Quanlse/ErrorMitigation/Utils/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Quanlse/ErrorMitigation/Utils/__init__.py 20 | """ 21 | -------------------------------------------------------------------------------- /Quanlse/ErrorMitigation/ZNE/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Quanlse/ErrorMitigation/ZNE/__init__.py 20 | """ 21 | -------------------------------------------------------------------------------- /Quanlse/TrappedIon/Optimizer/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Quanlse Trapped Ion optimizer and ion evolution. 20 | """ -------------------------------------------------------------------------------- /Quanlse/Define/Settings.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Configuration 20 | """ 21 | 22 | outputInfo = True 23 | """ 24 | Output information setting. 25 | 26 | Output the returned information from quantum-hub to console. 27 | 28 | The information also can be found from quantum-hub website. 29 | 30 | Values: True, False 31 | """ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Virtualenv 2 | /.venv/ 3 | /venv/ 4 | 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | /bin/ 14 | /build/ 15 | /develop-eggs/ 16 | /dist/ 17 | /eggs/ 18 | /lib/ 19 | /lib64/ 20 | /output/ 21 | /parts/ 22 | /sdist/ 23 | /var/ 24 | /*.egg-info/ 25 | /.installed.cfg 26 | /*.egg 27 | /.eggs 28 | 29 | # AUTHORS and ChangeLog will be generated while packaging 30 | /AUTHORS 31 | /ChangeLog 32 | 33 | # BCloud / BuildSubmitter 34 | /build_submitter.* 35 | /logger_client_log 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | .tox/ 43 | .coverage 44 | .cache 45 | .pytest_cache 46 | nosetests.xml 47 | coverage.xml 48 | 49 | # Translations 50 | *.mo 51 | 52 | # Sphinx documentation 53 | /Doc 54 | 55 | # Study test 56 | /study/ 57 | 58 | # JetBrains 59 | .idea 60 | 61 | Output/ 62 | .vscode/ 63 | 64 | /Doc/build 65 | 66 | Tutorial/EN/.ipynb_checkpoints/ 67 | Tutorial/CN/.ipynb_checkpoints/ 68 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/Lab/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | The `Lab` package is for rapidly designing superconducting experiments, including the scan or normal experiments; 20 | it also provides the interface `Superconduct.Lab.LabSpace` to access the data service, `Superconduct.Lab.Runner` 21 | to connect the experiment devices or simulator. 22 | """ 23 | 24 | from .LabSpace import LabSpace 25 | from .Experiment import Experiment 26 | from .ExperimentTask import ExperimentTask 27 | from .Runner import Runner 28 | from .Generator import Generator 29 | from .Utils import Scan, scanLinear, scanSeq 30 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Setup Installation 20 | """ 21 | 22 | from __future__ import absolute_import 23 | try: 24 | from setuptools import setup, find_packages 25 | except ImportError: 26 | from distutils.core import setup 27 | 28 | setup( 29 | name='Quanlse', 30 | version='2.2.0', 31 | description='A cloud-based platform for quantum control.', 32 | author='Baidu Quantum', 33 | author_email='quantum@baidu.com', 34 | packages=find_packages(), 35 | install_requires=[ 36 | 'numpy', 37 | 'scipy', 38 | 'matplotlib', 39 | 'requests', 40 | 'bce-python-sdk-reborn' 41 | ], 42 | python_requires='>=3.7, <4', 43 | license='Apache 2.0' 44 | ) -------------------------------------------------------------------------------- /Quanlse/Utils/NumbaSupport.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Numba Accelerator 20 | """ 21 | 22 | from numba import jit 23 | from numpy import ndarray, dot, diag, linalg, exp 24 | 25 | 26 | @jit(cache=True, nopython=True, parallel=True) 27 | def expm(mat: ndarray) -> ndarray: 28 | """ 29 | Calculate the matrix exponential :math:`e^{A}` of the input matrix :math:`A`. 30 | 31 | :param mat: the input matrix. 32 | :return: the matrix exponential. 33 | """ 34 | # Solving the eigen 35 | evals, evecs = linalg.eig(mat) 36 | expEvals = exp(evals) 37 | d2 = diag(expEvals) 38 | b = dot(evecs, d2) 39 | bt = b.transpose() 40 | at = evecs.transpose() 41 | et, residuals, rank, s = linalg.lstsq(at, bt) 42 | e = et.transpose() 43 | return e 44 | -------------------------------------------------------------------------------- /Quanlse/QPlatform/Error.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Define Error 20 | """ 21 | 22 | 23 | class Error(Exception): 24 | """ 25 | The basic class of the user-defined exceptions 26 | """ 27 | 28 | code = 0 29 | 30 | def __init__(self, msg=None): 31 | self.message = msg 32 | 33 | 34 | class ArgumentError(Error): 35 | """ 36 | Arguments related error 37 | """ 38 | 39 | code = 100 40 | 41 | 42 | class NetworkError(Error): 43 | """ 44 | Network related error 45 | """ 46 | 47 | code = 200 48 | 49 | 50 | class RuntimeError(Error): 51 | """ 52 | Runtime related error 53 | """ 54 | 55 | code = 300 56 | 57 | 58 | class LogicError(Error): 59 | """ 60 | Logical error 61 | """ 62 | 63 | code = 400 64 | 65 | 66 | class TokenError(LogicError): 67 | """ 68 | Token related error 69 | """ 70 | 71 | code = 401 72 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/SchedulerSupport/PipelineLeftAligned.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Default SchedulerPipeline for QuanlseSchedulerSuperconduct. 20 | """ 21 | 22 | from numpy import array 23 | 24 | from Quanlse.Scheduler.SchedulerPipeline import SchedulerProcess, toLayer, fillUp, findMaxT, addToJob 25 | from Quanlse.Scheduler import Scheduler 26 | 27 | 28 | def _leftAlignedCore(scheduler: Scheduler) -> None: 29 | """ 30 | The left alignment strategy for scheduling. 31 | 32 | :param scheduler: Scheduler object containing the circuit information 33 | """ 34 | 35 | # Initialize layers 36 | layer = [] 37 | for _ in range(scheduler.subSysNum): 38 | layer.append([]) 39 | 40 | # First convert gates in Scheduler to layers 41 | toLayer(layer, scheduler) 42 | fillUp(layer) 43 | 44 | # Transpose layers 45 | layer = array(layer).T.tolist() 46 | 47 | # Find max time for each layer 48 | maxT = findMaxT(layer) 49 | 50 | # add waves to job 51 | addToJob(layer=layer, scheduler=scheduler, maxT=maxT) 52 | 53 | 54 | leftAligned = SchedulerProcess("LeftAligned", _leftAlignedCore) 55 | """ 56 | A SchedulerProcess instance containing the left-aligned scheduling strategy. 57 | """ 58 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/Simulator/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2020 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Simulating the time evolution of the qubits at the pulse level gives us more insight into how 20 | quantum gates operates and the effects of noise. For superconducting quantum circuit, the 21 | transmon qubits are controlled by applying microwave and magnetic flux. However, the performance 22 | of quantum gates are often suppressed by various factors - the decoherence of the qubit due 23 | to its interaction with the environment, the unwanted cross-talk effect and leakage into the 24 | higher levels of the transmon. 25 | 26 | The pulse-level simulator provided by Quanlse allows us to simulate quantum operations on 27 | noisy quantum device consisting of multiple transmon qubits to better understand the physics 28 | behind quantum computing. 29 | 30 | For more details, please visit https://quanlse.baidu.com/#/doc/tutorial-pulse-level-simulator. 31 | """ 32 | 33 | from .PulseModel import PulseModel, ReadoutModel, ReadoutPulse 34 | from .PulseSim1Q import pulseSim1Q 35 | from .PulseSim2Q import pulseSim2Q 36 | from .PulseSim3Q import pulseSim3Q 37 | from .PulseSimQCQ import pulseSimQCQ 38 | from .ReadoutSim3Q import readoutSim3Q 39 | from .SimulatorAgent import SimulatorAgent 40 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/Lab/Runner.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Runner interface for superconducting system experiments 20 | """ 21 | 22 | from typing import Dict, Any, Set, List 23 | 24 | from Quanlse.QWaveform import QResult, QJob 25 | from Quanlse.Utils.ControlGate import ControlGate 26 | 27 | 28 | class Runner(object): 29 | """ 30 | The interface for quantum devices (local/remote simulator or physical devices). This class provides an interface 31 | to communicate with the devices. Users can overwrite this class to implement specific functions. 32 | """ 33 | 34 | def __init__(self): 35 | """ Initialize the DataInterface """ 36 | pass 37 | 38 | def run(self, job: QJob, measure: Set[int], ctrlGates: List[ControlGate] = None, 39 | conf: Dict[Any, Any] = None) -> QResult: 40 | """ 41 | Generate the pulse parameters for the experiment. 42 | 43 | :param job: the QJob instance which contains the pulse definition 44 | :param ctrlGates: the list of control gates 45 | :param measure: the qubit index to perform measurement 46 | :param conf: the user-defined options/configurations. 47 | :return: the value of the config 48 | """ 49 | raise NotImplementedError("Abstract method `run()` is not implemented!") 50 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/Simulator/ReadoutSim3Q.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2020 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Readout simulator Template: 3-qubit readout simulator. 20 | """ 21 | 22 | from Quanlse.Superconduct.Simulator import ReadoutModel 23 | from Quanlse.Superconduct.Simulator.PulseSim3Q import pulseSim3Q 24 | from typing import Union 25 | from math import pi 26 | 27 | 28 | def readoutSim3Q(dt: Union[int, float] = 20.) -> ReadoutModel: 29 | r""" 30 | Return a template of 3-qubit readout model. 31 | 32 | :param dt: the sampling time period. 33 | 34 | :return: a readout simulator ReadoutModel object. 35 | """ 36 | 37 | dt = dt # The sampling time 38 | kappa = 0.0020 * (2 * pi) # the system decay rate to the environment 39 | gain = 1000000. 40 | pulseModel = pulseSim3Q(dt=0.2) 41 | 42 | # resonator level 43 | resonatorLevel = 3 # resonator level 44 | resonatorFreq = { 45 | 0: 7.104 * (2 * pi), 46 | 1: 7.014 * (2 * pi), 47 | 2: 7.214 * (2 * pi) 48 | } 49 | 50 | # qubit-resonator coupling strength 51 | coupling = { 52 | 0: 0.134 * (2 * pi), 53 | 1: 0.112 * (2 * pi), 54 | 2: 0.121 * (2 * pi) 55 | } 56 | 57 | model = ReadoutModel(pulseModel=pulseModel, resonatorFreq=resonatorFreq, level=resonatorLevel, 58 | coupling=coupling, dissipation=kappa, gain=gain, dt=dt) 59 | 60 | return model 61 | 62 | -------------------------------------------------------------------------------- /Quanlse/TrappedIon/SchedulerSupport/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Quanlse Scheduler for Ion Trap quantum computing platform 20 | """ 21 | 22 | from Quanlse.Scheduler import Scheduler 23 | from Quanlse.Scheduler.SchedulerPulseGenerator import SchedulerPulseGenerator 24 | from Quanlse.TrappedIon.SchedulerSupport.DefaultPulseGenerator import defaultPulseGenerator 25 | 26 | 27 | class SchedulerIon(Scheduler): 28 | """ 29 | Basic class of Quanlse Scheduler for trapped ion platform 30 | 31 | :param dt: AWG sampling time 32 | :param generator: the pulseGenerator object. 33 | :param subSysNum: size of the subsystem 34 | :param sysLevel: the energy levels of the system (support different levels for different qubits) 35 | """ 36 | def __init__(self, dt: float = None, generator: SchedulerPulseGenerator = None, 37 | subSysNum: int = None, sysLevel: int = None): 38 | """ 39 | Constructor for class SchedulerIon 40 | """ 41 | 42 | # Initialization 43 | super().__init__(dt=dt, generator=generator, subSysNum=subSysNum, sysLevel=sysLevel) 44 | 45 | if self._pulseGenerator is None: 46 | self._pulseGenerator = defaultPulseGenerator() 47 | 48 | def plotIon(self) -> None: 49 | """ 50 | Plot the ion pulses. 51 | 52 | :return: None 53 | """ 54 | if self._ham is not None: 55 | self._ham.job.plotIon() 56 | elif self._job is not None: 57 | self._job.plotIon() -------------------------------------------------------------------------------- /Example/1-example-pi-pulse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Example: Pi pulse 20 | Please visit https://quanlse.baidu.com/#/doc/tutorial-pi-pulse for more details about this example. 21 | """ 22 | 23 | from math import pi, sqrt 24 | 25 | from Quanlse.QHamiltonian import QHamiltonian as QHam 26 | from Quanlse.QOperator import driveX 27 | from Quanlse.QWaveform import gaussian 28 | from Quanlse.Utils.Infidelity import unitaryInfidelity 29 | from Quanlse.QOperation.FixedGate import X 30 | 31 | 32 | # Gate duration time. 33 | tg = 20 34 | 35 | # Number of qubit(s). 36 | qubits = 1 37 | 38 | # System energy level. 39 | level = 2 40 | 41 | # Sampling period. 42 | dt = 0.2 43 | 44 | # --------------------------------- 45 | # Construct the system Hamiltonian. 46 | # --------------------------------- 47 | 48 | # Create the Hamiltonian with given parameters. 49 | ham = QHam(subSysNum=qubits, sysLevel=level, dt=dt) 50 | 51 | # Amplitude of the gaussian waveform with integral value of pi. 52 | piAmp = pi / (tg / 8) / sqrt(2 * pi) 53 | 54 | # Add gaussian waveform to control Hamiltonian. 55 | ham.appendWave(driveX, 0, gaussian(tg, piAmp, tg / 2, tg / 8)) 56 | 57 | # ------------------------------------------ 58 | # Run the simulation and show the results. 59 | # ------------------------------------------ 60 | 61 | # Run the optimization. 62 | results = ham.simulate() 63 | 64 | # Show the result and plot the waveform. 65 | print("Infidelity:", unitaryInfidelity(X.getMatrix(), results.result[0]["unitary"], 1)) 66 | ham.plot() 67 | 68 | # Print the structure of a Hamiltonian. 69 | print(ham) 70 | -------------------------------------------------------------------------------- /Example/6-example-optimizer1QubitGRAPE.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Example: Single-qubit Gradient Ascent Pulse Engineering (GRAPE) 20 | Please visit https://quanlse.baidu.com/#/doc/tutorial-GRAPEoptimizer for more details about this example. 21 | """ 22 | 23 | from math import pi 24 | 25 | from Quanlse.QOperator import duff 26 | from Quanlse.QHamiltonian import QHamiltonian as QHam 27 | from Quanlse.QOperation import FixedGate 28 | from Quanlse import Define 29 | from Quanlse.remoteOptimizer import remoteOptimize1QubitGRAPE as runOptimize1QubitGRAPE 30 | 31 | 32 | # Your token: 33 | # Please visit http://quantum-hub.baidu.com 34 | Define.hubToken = '' 35 | 36 | # Gate duration time. 37 | tg = 40 38 | 39 | # Number of qubit(s). 40 | qubits = 1 41 | 42 | # System energy level. 43 | level = 2 44 | 45 | # Sampling period. 46 | dt = 1.0 47 | 48 | # Anharmonicity of the qubit. 49 | alphaq = - 0.22 * (2 * pi) 50 | 51 | # --------------------------------- 52 | # Construct the system Hamiltonian. 53 | # --------------------------------- 54 | 55 | ham = QHam(qubits, level, dt) 56 | ham.addDrift(duff, 0, alphaq) 57 | 58 | # -------------------------- 59 | # Define the input parameters. 60 | # -------------------------- 61 | 62 | # The target gate. 63 | ugoal = FixedGate.X.getMatrix() 64 | 65 | # The channel(s) to be turned on. 66 | xyzPulses = [1, 0, 0] 67 | 68 | # The maximum number of iteration. 69 | iterate = 40 70 | 71 | # ------------------------------------------ 72 | # Run the optimization and show the results. 73 | # ------------------------------------------ 74 | 75 | job, infid = runOptimize1QubitGRAPE(ham, ugoal, iterate=iterate, tg=tg, xyzPulses=xyzPulses) 76 | print(infid) 77 | 78 | # Plot the waveform. 79 | job.plot() 80 | -------------------------------------------------------------------------------- /Example/2-example-single-qubit-gate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Example: Single-qubit gate optimizer 20 | Please visit https://quanlse.baidu.com/#/doc/tutorial-single-qubit for more details about this example. 21 | """ 22 | 23 | from numpy import round 24 | from math import pi 25 | 26 | from Quanlse.QHamiltonian import QHamiltonian as QHam 27 | from Quanlse.Utils.Functions import project 28 | from Quanlse.QOperator import duff 29 | from Quanlse.remoteOptimizer import remoteOptimize1Qubit as opt 30 | 31 | from Quanlse.QOperation import FixedGate 32 | from Quanlse import Define 33 | 34 | 35 | # Your token: 36 | # Please visit http://quantum-hub.baidu.com 37 | Define.hubToken = '' 38 | 39 | # Number of qubit(s). 40 | qubits = 1 41 | 42 | # System energy level. 43 | level = 3 44 | 45 | # Sampling period. 46 | dt = 0.2 47 | 48 | # Anharmonicity of the qubit. 49 | anharm = - 0.33 * (2 * pi) 50 | 51 | 52 | # --------------------------------- 53 | # Construct the system Hamiltonian. 54 | # --------------------------------- 55 | 56 | # Create the Hamiltonian. 57 | ham = QHam(qubits, level, dt=dt) 58 | 59 | # Add the drift term(s). 60 | ham.addDrift(duff, 0, coef=anharm / 2) 61 | 62 | # ------------------------------------------ 63 | # Run the optimization and show the results. 64 | # ------------------------------------------ 65 | 66 | # Run the optimization. 67 | gateJob, infidelity = opt(ham, FixedGate.Y.getMatrix(), depth=3, targetInfid=0.001) 68 | 69 | # Print infidelity and the waveform(s). 70 | print(f"minimum infidelity: {infidelity}") 71 | gateJob.plot() 72 | 73 | # Print the evolution process. 74 | result = ham.simulate(job=gateJob) 75 | projectedEvolution = project(result.result[0]["unitary"], qubits, level, 2) 76 | print("Projected evolution:\n", round(projectedEvolution, 2)) 77 | -------------------------------------------------------------------------------- /Quanlse/remoteSimulator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Simulate the Hamiltonian using the Quanlse remote simulator. 20 | """ 21 | 22 | from numpy import ndarray 23 | 24 | from Quanlse.QHamiltonian import QHamiltonian as QHam 25 | from Quanlse.QWaveform import QJobList, QResult, QJob 26 | from Quanlse.QRpc import rpcCall 27 | from Quanlse.QPlatform.Utilities import numpyMatrixToDictMatrix 28 | 29 | 30 | def remoteSimulatorRunHamiltonian(ham: QHam, state0: ndarray = None, job: QJob = None, 31 | jobList: QJobList = None, isOpen=False) -> QResult: 32 | """ 33 | Simulate the Hamiltonian using the Quanlse remote simulator. 34 | 35 | :param ham: the QHamiltonian object. 36 | :param state0: The initial state. 37 | :param job: the QJob object. 38 | :param jobList: The QJobList object. 39 | :param isOpen: Run the simulation of open system using Lindblad master equation if true. 40 | :return: the QResult object. 41 | """ 42 | 43 | maxEndTime = None 44 | kwargs = {} 45 | if state0 is not None: 46 | kwargs["state0"] = numpyMatrixToDictMatrix(state0) 47 | if job is not None: 48 | maxEndTime, _ = job.computeMaxTime() 49 | kwargs["job"] = job.dump(maxEndTime=maxEndTime) 50 | if jobList is not None: 51 | maxTimeList = [] 52 | for job in jobList.jobs: 53 | maxTime, _ = job.computeMaxTime() 54 | maxTimeList.append(maxTime) 55 | maxEndTime = max(maxTimeList) 56 | kwargs["jobList"] = jobList.dump(maxEndTime=maxEndTime) 57 | if maxEndTime is None: 58 | maxEndTime, _ = ham.job.computeMaxTime() 59 | kwargs["isOpen"] = isOpen 60 | 61 | args = [ham.dump(maxEndTime=maxEndTime)] 62 | origin = rpcCall("runHamiltonian", args, kwargs) 63 | 64 | return QResult.load(origin["result"]) 65 | -------------------------------------------------------------------------------- /Example/8-example-scheduler-superconduct.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Example: Quanlse Scheduler 20 | Please visit https://quanlse.baidu.com/#/doc/tutorial-scheduler for more details about this example. 21 | """ 22 | 23 | from Quanlse.QOperation.FixedGate import H, CZ 24 | from Quanlse.Utils.Functions import basis 25 | from Quanlse.Superconduct.Simulator.PulseSim2Q import pulseSim2Q 26 | from Quanlse.Superconduct.SchedulerSupport.PipelineCenterAligned import centerAligned 27 | 28 | from Quanlse import Define 29 | from Quanlse.Utils.Functions import computationalBasisList 30 | from Quanlse.Utils.Plot import plotBarGraph 31 | 32 | # Your token: 33 | # Please visit http://quantum-hub.baidu.com 34 | Define.hubToken = '' 35 | 36 | # --------------------------------- 37 | # Construct the system Hamiltonian. 38 | # --------------------------------- 39 | 40 | # Sampling period. 41 | dt = 0.01 42 | 43 | # Instantiate the simulator object by a 2-qubit template. 44 | model = pulseSim2Q(dt=dt, frameMode='lab') 45 | model.savePulse = False 46 | sysLevel = model.sysLevel 47 | qubitNum = model.subSysNum 48 | 49 | # Set the center-aligned scheduling sctrategy 50 | model.pipeline.addPipelineJob(centerAligned) 51 | 52 | # Define circuit 53 | H(model.Q[0]) 54 | H(model.Q[1]) 55 | CZ(model.Q[0], model.Q[1]) 56 | H(model.Q[0]) 57 | 58 | 59 | # -------------------------------- 60 | # Run the simulation and show the results. 61 | # -------------------------------- 62 | 63 | # Schedule the model. 64 | job = model.schedule() 65 | job.plot() 66 | 67 | # Calculate final state 68 | finalState = model.simulate( 69 | job=job, state0=basis(model.sysLevel ** model.subSysNum, 0), shot=1000) 70 | 71 | # Plot the population of computational basis 72 | plotBarGraph(computationalBasisList(2, 3), finalState[0]["population"], 73 | "Counts of the computational basis", "Computational Basis", "Counts") 74 | -------------------------------------------------------------------------------- /Example/10-example-ion-MS-gate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Example: Molmer-Sorensen gate in trapped ion 20 | Please visit https://quanlse.baidu.com/#/doc/tutorial-ion-trap-single-and-two-qubit-gate 21 | for more details about this example. 22 | """ 23 | 24 | from math import pi 25 | 26 | from Quanlse.Utils import Plot 27 | from Quanlse.remoteOptimizer import remoteIonMS as runIonMS 28 | 29 | from Quanlse import Define 30 | 31 | 32 | # Your token: 33 | # Please visit http://quantum-hub.baidu.com 34 | Define.hubToken = '' 35 | 36 | # --------------------------------- 37 | # Construct the system Hamiltonian. 38 | # --------------------------------- 39 | 40 | # The parameters of the 1-d potential well. 41 | omegaZ = 2 * pi * 0.2e6 42 | omegaXY = 2 * pi * 4.1e6 43 | 44 | # The number of ions of the 1-d chain. 45 | ionNumber = 4 46 | atomMass = 40 47 | 48 | # Transverse or axial vibration phonon mode, 49 | # phononMode = "axial". 50 | phononMode = "transverse" 51 | 52 | # The indexes of the qubits. 53 | ionM = 1 54 | ionN = 2 55 | 56 | # Gate time of the Molmer-Sorensen gate. 57 | tgate = 50 58 | 59 | # The waveform of the laser,squareWave or sinWave 60 | pulseWave = "squareWave" 61 | 62 | # ------------------------------------------ 63 | # Run the simulation and show the results. 64 | # ------------------------------------------ 65 | 66 | res, unitary = runIonMS(ionNumber=ionNumber, 67 | atomMass=atomMass, 68 | tg=tgate, 69 | omega=(omegaXY, omegaZ), 70 | ionIndex=(ionM, ionN), 71 | pulseWave=pulseWave, 72 | phononMode=phononMode) 73 | 74 | print(f"The trapped ion axial phonon mode frequencies are:\n {res['phonon_freq']}\n") 75 | print(f"The trapped ion axial Lamb-Dicke parameters are:\n {res['lamb_dicke']}\n") 76 | print(f"infidelity is: {res['infidelity']}\n") 77 | print(unitary) 78 | 79 | ionPos = res['ion_pos'] 80 | 81 | Plot.plotIonPosition(ionPos) 82 | 83 | Plot.plotPulse([res['time']], [res['omega']], 84 | title=['Sin pulse for Molmer-Sorensen gate in trapped ion'], 85 | xLabel=r'Time ($\mu$s)', yLabel=['Rabi frequency (a.u)'], color=['blue']) 86 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/SchedulerSupport/PipelineCenterAligned.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Default SchedulerPipeline for QuanlseSchedulerSuperconduct. 20 | """ 21 | 22 | from numpy import array 23 | 24 | from Quanlse.Scheduler.SchedulerPipeline import SchedulerProcess, toLayer, fillUp, \ 25 | leftAlignSingleGates, delayFirstGate, findMaxT, addToJob 26 | from Quanlse.Scheduler import Scheduler 27 | 28 | 29 | def _gatesBeforeMulti(layer, scheduler): 30 | """ 31 | Find gate number before the first multi-qubit gate 32 | """ 33 | flag = [True] * scheduler.subSysNum 34 | gateNumber = [len(layer)] * scheduler.subSysNum 35 | for i in range(len(layer[0])): 36 | for j in range(len(layer)): 37 | if layer[j][i] is not None: 38 | if len(layer[j][i].qubits) >= 2 and flag[i] is True: 39 | gateNumber[i] = j 40 | flag[i] = False 41 | return gateNumber 42 | 43 | 44 | def _centerAlignedCore(scheduler: Scheduler) -> None: 45 | """ 46 | The center alignment strategy for scheduling. 47 | 48 | :param scheduler: Scheduler object containing the circuit information 49 | :return: the returned QJob object 50 | """ 51 | 52 | # Initialize layers 53 | layer = [] 54 | for _ in range(scheduler.subSysNum): 55 | layer.append([]) 56 | 57 | # First convert gates in Scheduler to layers 58 | toLayer(layer, scheduler, reversedOrder=True) 59 | fillUp(layer, qubits=None, reversedOrder=True) 60 | 61 | # left aligned the single-qubit gates 62 | leftAlignSingleGates(layer) 63 | 64 | # Transpose layers 65 | layer = array(layer).T.tolist() 66 | 67 | # find gate number before the first multi-qubit gates 68 | gatesBeforeMultiQubitGate = _gatesBeforeMulti(layer, scheduler) 69 | 70 | # start the first gate as late as possible 71 | delayFirstGate(layer, gatesBeforeMultiQubitGate) 72 | 73 | # find max time for each layer 74 | maxi = findMaxT(layer) 75 | 76 | # add waves to job 77 | addToJob(layer=layer, scheduler=scheduler, maxT=maxi) 78 | 79 | 80 | centerAligned = SchedulerProcess("CenterAligned", _centerAlignedCore) 81 | """ 82 | A SchedulerProcess instance containing the center-aligned scheduling strategy. 83 | """ 84 | -------------------------------------------------------------------------------- /Example/14-example-robust-MS-gate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | r""" 19 | Example: Generate a robust MS gate pulse 20 | A robust MS gate pulse is extremely important to large-scale quantum computing which can tolerate dephasing noise 21 | and timing noise. In Quanlse, this technique is implemented. 22 | Please visit https://quanlse.baidu.com/#/doc/tutorial-trapped-ion-robust-control for more details about this example. 23 | """ 24 | 25 | # Import Robust Mølmer-Sørensen pulse module 26 | from Quanlse.TrappedIon.QIonSystem import QChain1D, QLaser 27 | from Quanlse.TrappedIon.Optimizer.OptimizerIon import optimizeIonSymmetry 28 | from Quanlse.TrappedIon.QIonTrajectory import noiseFeature, allAlphaComb 29 | import numpy as np 30 | 31 | # set experiment parameters 32 | # ion trap 33 | ionNumber = 10 34 | indexIon = [0, 1] # ion that interact with the laser pulse 35 | mass = 171 # atom mass 36 | omegaXY = 22.5e6 # unit: Hz 37 | omegaZ = 3.8e6 # unit: Hz 38 | temperature = 1e-6 # unit: K 39 | # laser 40 | waveLength = 369.75 # unit: nm 41 | detuning = 3.804e6 # unit: Hz 42 | laserAngle = np.pi / 2 # angle between two laser beams 43 | tau = 2e-4 # unit: s 44 | segments = 15 # laser pulse segments 45 | omegaMax = 62.8e6 # unit: Hz 46 | 47 | # generate the entity of ion chip and laser 48 | ionChain = QChain1D(ionMass=mass, 49 | ionNumber=ionNumber, 50 | trapZ=omegaZ, 51 | trapXY=omegaXY, 52 | temperature=temperature) 53 | 54 | ionLaser = QLaser(waveLength=waveLength, 55 | laserAngle=laserAngle, 56 | segments=segments, detuning=detuning, 57 | maxRabi=omegaMax, 58 | tg=tau) 59 | 60 | # use the symmetry method to optimize the laser pulse sequence to be dephasing robust 61 | dephasingNoise = 2e3 # unit: Hz 62 | laserFinal = optimizeIonSymmetry(ionChip=ionChain, 63 | laser=ionLaser, 64 | indexIon=indexIon, 65 | noise=dephasingNoise) 66 | 67 | # show noise features using plot function 68 | timingNoise = 0.001 69 | noiseFeature(ionChip=ionChain, 70 | laser=laserFinal, 71 | indexIon=indexIon, 72 | noise=dephasingNoise, 73 | timeNoise=timingNoise) 74 | 75 | # show all alpha trajectory 76 | allAlphaComb(ionChip=ionChain, laser=laserFinal, index=indexIon) 77 | -------------------------------------------------------------------------------- /Quanlse/Scheduler/SchedulerPulseGenerator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Pulse generator for Quanlse Scheduler. 20 | """ 21 | 22 | from typing import Dict, Any, List, Callable 23 | 24 | from Quanlse.QHamiltonian import QHamiltonian as QHam 25 | from Quanlse.QWaveform import QJob 26 | from Quanlse.QOperation import Error, CircuitLine 27 | 28 | 29 | class SchedulerPulseGenerator: 30 | """ 31 | Basic class of pulse Generator for Quanlse Scheduler. 32 | 33 | :param ham: a user-given title to the pi object 34 | """ 35 | def __init__(self, ham: QHam = None): 36 | self._ham = ham # type: QHam 37 | self._generators = {} # type: Dict[str, Callable] 38 | self._conf = {} # type: Dict[str, Any] 39 | 40 | def __call__(self, *args, **kwargs) -> QJob: 41 | """ 42 | Call the instance and generate pulses. 43 | """ 44 | if not isinstance(args[0], CircuitLine): 45 | raise Error.ArgumentError("You should input a circuitLine instance.") 46 | _cirLine = args[0] # type: CircuitLine 47 | _scheduler = args[1] # type: 'Scheduler' 48 | # Call the generator according to the input CircuitLine instance, and 49 | # input the system Hamiltonian and the configurations. 50 | if self._ham is None: 51 | return self[_cirLine.data.name](cirLine=_cirLine, scheduler=_scheduler) 52 | else: 53 | return self[_cirLine.data.name](ham=self._ham, cirLine=_cirLine, scheduler=_scheduler) 54 | 55 | def __getitem__(self, gateName: str) -> Callable: 56 | """ 57 | Get a generator function according to the gateName. 58 | """ 59 | if gateName in self._generators: 60 | return self._generators[gateName] 61 | else: 62 | raise Error.ArgumentError(f"Gate {gateName} is not supported.") 63 | 64 | @property 65 | def generators(self) -> Dict[str, Callable]: 66 | return self._generators 67 | 68 | @property 69 | def conf(self): 70 | return self._conf 71 | 72 | def addGenerator(self, gateList: List[str], generator: Callable) -> None: 73 | """ 74 | Add pulse generator. 75 | 76 | :param gateList: a gate list to add the generator to 77 | :param generator: generator to be added 78 | :return: None 79 | """ 80 | for gateName in gateList: 81 | self.generators[gateName] = generator 82 | -------------------------------------------------------------------------------- /Quanlse/Define/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Global Definitions 20 | """ 21 | 22 | import os 23 | import sys 24 | 25 | from Quanlse.QPlatform import Error 26 | import Quanlse 27 | 28 | version = "2.2.0" 29 | """ 30 | Quanlse Version number. 31 | """ 32 | 33 | env = 'prod' 34 | 35 | """ 36 | Environment 37 | 38 | Do not modify. 39 | 40 | Values: 'prod', 'test' 41 | 42 | Used to create or test environment. 43 | """ 44 | if env == "test": 45 | raise Error.RuntimeError('Not implemented') 46 | else: 47 | # service address for production 48 | quantumHubAddr = 'https://quantum-hub.baidu.com/api' 49 | quantumBucket = 'quantum-task' 50 | 51 | sdkVersion = 'Quanlse 2.0.0' 52 | """ 53 | SDK Version 54 | 55 | Do not modify. 56 | 57 | Used for task submission. 58 | """ 59 | 60 | hubToken = os.environ.get('HUBTOKEN', '') 61 | """ 62 | Hub Token 63 | 64 | Do not modify. 65 | 66 | Used for Quanlse cloud task. 67 | 68 | Users can acquire tokens from http://quantum-hub.baidu.com . 69 | 70 | Token Management -> Create/View Token 71 | """ 72 | 73 | taskSource = os.environ.get('SOURCE', 'PySDK') 74 | taskSourceQuanlse = os.environ.get('SOURCE', 'QuanlseSDK') 75 | """ 76 | Task Source 77 | 78 | Do not modify. 79 | 80 | Values: 'PySDK', 'PyOnline' 81 | 82 | PySDK or PyOnline. 83 | """ 84 | 85 | noLocalTask = os.environ.get('NOLOCALTASK', None) 86 | """ 87 | No Local Task 88 | 89 | Do not modify. 90 | 91 | Values: None or Other 92 | 93 | Used for PyOnline. 94 | """ 95 | 96 | pollInterval = 5 97 | """ 98 | Poll interval in seconds 99 | 100 | Do not modify. 101 | 102 | Used for task check. 103 | """ 104 | 105 | waitTaskRetrys = 10 106 | """ 107 | Wait task retrys 108 | 109 | Do not modify. 110 | 111 | Retry count for waiting task in case network failed. 112 | """ 113 | 114 | outputPath = os.path.abspath(os.path.join(Quanlse.__file__, '../../Output')) 115 | """ 116 | Output Path 117 | 118 | Do not modify by user. 119 | 120 | Will be created, when not exist. 121 | """ 122 | if 'sphinx' in sys.modules: 123 | outputPath = '' 124 | else: 125 | os.makedirs(outputPath, mode=0o744, exist_ok=True) 126 | 127 | circuitPackageFile = os.path.join(outputPath, 'Package.pb') 128 | """ 129 | Circuit Package File 130 | 131 | Do not modify. 132 | 133 | Circuit hdf5 target file 134 | """ 135 | if 'sphinx' in sys.modules: 136 | circuitPackageFile = '' -------------------------------------------------------------------------------- /Example/5-example-iswap-gate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Example: iSWAP gate optimizer 20 | Please visit https://quanlse.baidu.com/#/doc/tutorial-iswap for more details about this example. 21 | """ 22 | 23 | from numpy import round 24 | from math import pi 25 | 26 | from Quanlse.QHamiltonian import QHamiltonian as QHam 27 | from Quanlse.Utils.Functions import project 28 | from Quanlse.remoteOptimizer import remoteOptimizeISWAP as opt 29 | 30 | from Quanlse.QOperator import duff, number 31 | from Quanlse import Define 32 | 33 | 34 | # Your token: 35 | # Please visit http://quantum-hub.baidu.com 36 | Define.hubToken = '' 37 | 38 | # Sampling period. 39 | dt = 1.0 40 | 41 | # Number of qubit(s). 42 | qubits = 2 43 | 44 | # System energy level. 45 | level = 3 46 | 47 | # -------------------------- 48 | # Define the qubit arguments. 49 | # -------------------------- 50 | 51 | qubitArgs = { 52 | "coupling": 0.0277 * (2 * pi), # Coupling of Q0 and Q1 53 | "qubit_freq0": 5.805 * (2 * pi), # Frequency of Q0 54 | "qubit_freq1": 5.205 * (2 * pi), # Frequency of Q1 55 | "drive_freq0": 5.205 * (2 * pi), # Drive frequency on Q0 56 | "drive_freq1": 5.205 * (2 * pi), # Drive frequency on Q1 57 | "qubit_anharm0": -0.217 * (2 * pi), # Anharmonicity of Q0 58 | "qubit_anharm1": -0.226 * (2 * pi) # Anharmonicity of Q1 59 | } 60 | 61 | # ----------------------------- 62 | # Construct system Hamiltonian. 63 | # ----------------------------- 64 | 65 | # Create the Hamiltonian. 66 | ham = QHam(qubits, level, dt) 67 | for qu in range(2): 68 | # Add the detuning term(s). 69 | ham.addDrift(number, qu, (qubitArgs[f"qubit_freq{qu}"] - qubitArgs[f"drive_freq{qu}"])) 70 | # Add the anharmonicity term(s). 71 | ham.addDrift(duff, qu, qubitArgs[f"qubit_anharm{qu}"] / 2) 72 | 73 | # Add the coupling term. 74 | ham.addCoupling([0, 1], qubitArgs["coupling"] / 2) 75 | 76 | # ------------------------------------------ 77 | # Run the optimization and show the results. 78 | # ------------------------------------------ 79 | 80 | # Set amplitude bound. 81 | aBound = (-4, -3.5) 82 | 83 | # Run the optimization. 84 | gateJob, infidelity = opt(ham, aBound, tg=40, maxIter=5, targetInfidelity=0.01) 85 | 86 | # Print infidelity and the waveform(s). 87 | print(f"Minimum infidelity: {infidelity}") 88 | gateJob.plot() 89 | 90 | # Print the evolution process. 91 | result = ham.simulate(job=gateJob) 92 | projectedEvolution = project(result.result[0]["unitary"], qubits, level, 2) 93 | print("Projected evolution:\n", round(projectedEvolution, 2)) 94 | -------------------------------------------------------------------------------- /Quanlse/Utils/ControlGate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Experiment class for superconducting system 20 | """ 21 | 22 | from numpy import ndarray 23 | from typing import List, Tuple, Union, Any, Dict, Optional 24 | 25 | from Quanlse.QWaveform import QJob 26 | from Quanlse.Superconduct.Lab.Utils import Scan 27 | 28 | 29 | class ControlGate(object): 30 | """ 31 | The quantum gate instance with the gate definition as well as the control pulse. 32 | """ 33 | 34 | def __init__(self, name: str, onQubit: Union[int, List[int]] = None, job: QJob = None): 35 | """ Initialization """ 36 | self._name = name # type: str 37 | self._matrix = None # type: Optional[ndarray] 38 | 39 | # Set properties 40 | self._onQubit = onQubit # type: Optional[Union[int, List[int]]] 41 | self._job = job # type: Optional[QJob] 42 | 43 | @property 44 | def name(self) -> str: 45 | """ The qubit name(s) the gate performs on """ 46 | return self._name 47 | 48 | @name.setter 49 | def name(self, name: str): 50 | """ The qubit name(s) the gate performs on """ 51 | self._name = name 52 | 53 | @property 54 | def job(self) -> QJob: 55 | """ Get the QJob instance """ 56 | return self._job 57 | 58 | @job.setter 59 | def job(self, job: QJob): 60 | """ Get the QJob instance """ 61 | self._job = job 62 | 63 | @property 64 | def onQubit(self) -> Optional[Union[int, List[int]]]: 65 | """ The qubit name(s) the gate performs on """ 66 | return self._onQubit 67 | 68 | @onQubit.setter 69 | def onQubit(self, onQubit: Optional[Union[int, List[int]]]): 70 | """ The qubit name(s) the gate performs on """ 71 | self._onQubit = onQubit 72 | 73 | def scanDim(self) -> int: 74 | """ Return the scanning dimensional of the current gate """ 75 | if self.job is None: 76 | return 0 77 | _scanDimCount = 0 78 | for _waveKey in self.job.waves.keys(): 79 | for _waveId, _wave in enumerate(self.job.waves[_waveKey]): 80 | _waveDict = _wave.dump2Dict() 81 | for _settingKey in _waveDict.keys(): 82 | if isinstance(_waveDict[_settingKey], Scan): 83 | _scanDimCount += 1 84 | for _argKey in _waveDict['args'].keys(): 85 | if isinstance(_waveDict['args'][_argKey], Scan): 86 | _scanDimCount += 1 87 | return _scanDimCount 88 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/Simulator/SimulatorAgent.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Agent for superconducting simulator 20 | """ 21 | 22 | from typing import Dict 23 | 24 | from Quanlse.Superconduct.Simulator.PulseModel import PulseModel 25 | from Quanlse.Superconduct.Simulator.Utils import SimulatorLabSpace, SimulatorRunner, SimulatorGenerator 26 | from Quanlse.Superconduct.Lab.Experiment import Experiment 27 | from Quanlse.Scheduler import Scheduler 28 | from Quanlse.QPlatform import Error 29 | 30 | 31 | class SimulatorAgent(object): 32 | """ 33 | The agent for simulator. 34 | """ 35 | def __init__(self, model: PulseModel, labSpace: SimulatorLabSpace, runner: SimulatorRunner, 36 | generator: SimulatorGenerator): 37 | """ Initialization """ 38 | # Basic instances 39 | self.model = model # type: PulseModel 40 | self.labSpace = labSpace # type: SimulatorLabSpace 41 | self.runner = runner # type: SimulatorRunner 42 | self.generator = generator # type: SimulatorGenerator 43 | 44 | def __call__(self, *args, **kwargs): 45 | """ 46 | Return the qubit indexes of labels. 47 | """ 48 | if isinstance(args, str): 49 | return self.labSpace.getQubitIndex(args) 50 | else: 51 | if len(args) > 1: 52 | return self.labSpace.getQubitIndex(list(args)) 53 | else: 54 | return self.labSpace.getQubitIndex(args[0]) 55 | 56 | def q(self, *args) -> int: 57 | """ 58 | Return the sub system index in QJob instance. 59 | """ 60 | if len(args) == 1: 61 | return self.labSpace.getQubitIndex(args[0]) 62 | else: 63 | return self.labSpace.getQubitIndex(list(args)) 64 | 65 | def qLabel(self, qubitIndex: int) -> int: 66 | """ 67 | Return the sub system label in by QJob instance. 68 | """ 69 | return self.labSpace.getQubitLabel(qubitIndex) 70 | 71 | def createExperiment(self) -> Experiment: 72 | """ 73 | Create an Experiment instance 74 | """ 75 | if self.labSpace is None: 76 | raise Error.RuntimeError("LabSpace is not set.") 77 | if self.runner is None: 78 | raise Error.RuntimeError("Runner is not set.") 79 | 80 | expObj = Experiment(self.labSpace, self.runner, self.generator) 81 | return expObj 82 | 83 | def createScheduler(self) -> Scheduler: 84 | """ 85 | Create a Scheduler instance 86 | """ 87 | -------------------------------------------------------------------------------- /Example/4-example-controlled-z-gate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Example: Controlled-Z gate 20 | Please visit https://quanlse.baidu.com/#/doc/tutorial-cz for more details about this example. 21 | """ 22 | 23 | from numpy import round 24 | from math import pi 25 | 26 | from Quanlse.QHamiltonian import QHamiltonian as QHam 27 | from Quanlse.Utils.Functions import project 28 | from Quanlse.remoteOptimizer import remoteOptimizeCz as opt 29 | 30 | from Quanlse.QOperator import duff, number 31 | from Quanlse import Define 32 | 33 | 34 | # Your token: 35 | # Please visit http://quantum-hub.baidu.com 36 | Define.hubToken = '' 37 | 38 | # Sampling period. 39 | dt = 1.0 40 | 41 | # number of qubit(s). 42 | qubits = 2 43 | 44 | # System energy level. 45 | level = 3 46 | 47 | # -------------------------- 48 | # Define the qubit arguments. 49 | # -------------------------- 50 | 51 | qubitArgs = { 52 | "coupling": 0.0277 * (2 * pi), # Coupling of Q0 and Q1 53 | "qubit_freq0": 5.805 * (2 * pi), # Frequency of Q0 54 | "qubit_freq1": 5.205 * (2 * pi), # Frequency of Q1 55 | "drive_freq0": 5.205 * (2 * pi), # Drive frequency on Q0 (rotating frame) 56 | "drive_freq1": 5.205 * (2 * pi), # Drive frequency on Q1 (rotating frame) 57 | "qubit_anharm0": -0.217 * (2 * pi), # Anharmonicity of Q0 58 | "qubit_anharm1": -0.226 * (2 * pi) # Anharmonicity of Q1 59 | } 60 | 61 | # ----------------------------- 62 | # Construct system Hamiltonian. 63 | # ----------------------------- 64 | 65 | # Create the Hamiltonian. 66 | ham = QHam(qubits, level, dt) 67 | for qu in range(2): 68 | # Add the detuning term(s). 69 | ham.addDrift(number, qu, (qubitArgs[f"qubit_freq{qu}"] - qubitArgs[f"drive_freq{qu}"])) 70 | 71 | # Add the anharmonicity term(s). 72 | ham.addDrift(duff, qu, qubitArgs[f"qubit_anharm{qu}"] / 2) 73 | 74 | # Add the coupling term. 75 | ham.addCoupling([0, 1], qubitArgs["coupling"] / 2) 76 | 77 | # ------------------------------------------ 78 | # Run the optimization and show the results. 79 | # ------------------------------------------ 80 | 81 | # Set amplitude bound. 82 | aBound = (-3.0, -2.0) 83 | 84 | # Run the optimization. 85 | gateJob, infidelity = opt(ham, aBound, tg=40, maxIter=5, targetInfidelity=0.01) 86 | 87 | # Print infidelity and the waveform(s). 88 | print(f"Minimum infidelity: {infidelity}") 89 | gateJob.plot() 90 | 91 | # Print the evolution process. 92 | result = ham.simulate(job=gateJob) 93 | projectedEvolution = project(result[0]["unitary"], qubits, level, 2) 94 | print("Projected evolution:\n", round(projectedEvolution, 2)) 95 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/SchedulerSupport/GeneratorRBPulse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Pulse Generator for QuanlseSchedulerSuperconduct (Randomized Benchmarking). 20 | """ 21 | 22 | from Quanlse.Superconduct.SchedulerSupport import GeneratorCloud 23 | from Quanlse.QOperation import CircuitLine 24 | from Quanlse.QWaveform import QJob 25 | from Quanlse.QHamiltonian import QHamiltonian as QHam 26 | from Quanlse.Scheduler.SchedulerPulseGenerator import SchedulerPulseGenerator 27 | 28 | from Quanlse.remoteOptimizer import remoteOptimize1Qubit as opt1q 29 | 30 | 31 | 32 | def generate1QClifford(ham: QHam = None, cirLine: CircuitLine = None, scheduler: 'SchedulerSuperconduct' = None)\ 33 | -> QJob: 34 | """ 35 | Default generator for single qubit gates. 36 | 37 | :param ham: QHam object containing the system information 38 | :param cirLine: a CircuitLine object containing the gate information 39 | :param scheduler: the instance of Quanlse Scheduler Superconducting 40 | :return: returned QJob object 41 | """ 42 | subHam = ham.subSystem(cirLine.qRegIndexList) 43 | 44 | # Use the pulses we generate based on the qubit chosen 45 | if cirLine.data.name in ['Cinv']: 46 | job, inf = opt1q(subHam, cirLine.data.getMatrix(), depth=6, targetInfid=0.0002) 47 | else: 48 | job, inf = opt1q(ham, cirLine.data.getMatrix(), depth=4, targetInfid=0.0001) 49 | 50 | print(f"Infidelity of {cirLine.data.name} on qubit {cirLine.qRegIndexList}: {inf}") 51 | 52 | subHam.job = job 53 | return subHam.outputInverseJob(ham.subSysNum, ham.sysLevel, ham.dt) 54 | 55 | 56 | def SingleQubitCliffordPulseGenerator(ham: QHam) -> SchedulerPulseGenerator: 57 | """ 58 | Return a single-qubit Clifford pulse SchedulerPulseGenerator instance for the scheduler. 59 | 60 | :param ham: a Hamiltonian object 61 | :return: returned generator object 62 | """ 63 | generator = SchedulerPulseGenerator(ham) 64 | gateList1q = ['X', 'Y', 'Z', 'H', 'S', 'T', 'RX', 'RY', 'RZ', 'W', 'SQRTW', 'U'] 65 | generator.addGenerator(gateList1q, GeneratorCloud.generate1Q) 66 | gateList1QCliff = ['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'C10', 'C11', 'C12', 'C13', 'C14', 'C15', 67 | 'C16', 'C17', 'C18', 'C19', 'C20', 'C21', 'C22', 'C23', 'C24', 'Cinv'] 68 | generator.addGenerator(gateList1QCliff, generate1QClifford) 69 | generator.addGenerator(['CR'], GeneratorCloud.generateCr) 70 | generator.addGenerator(['CZ'], GeneratorCloud.generateCz) 71 | generator.addGenerator(['ISWAP'], GeneratorCloud.generateISWAP) 72 | return generator 73 | -------------------------------------------------------------------------------- /Example/3-example-cross-resonance-gate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Example: Cross-resonance gate optimizer 20 | Please visit https://quanlse.baidu.com/#/doc/tutorial-cr for more details about this example. 21 | """ 22 | 23 | from numpy import round 24 | from math import pi 25 | 26 | from Quanlse.QHamiltonian import QHamiltonian as QHam 27 | from Quanlse.Utils.Functions import project 28 | from Quanlse.remoteOptimizer import remoteOptimizeCr as opt 29 | 30 | from Quanlse.QOperator import duff, number 31 | from Quanlse import Define 32 | 33 | 34 | # Your token: 35 | # Please visit http://quantum-hub.baidu.com 36 | Define.hubToken = '' 37 | 38 | # Sampling period. 39 | dt = 2.0 40 | 41 | # Number of qubit(s). 42 | qubits = 2 43 | 44 | # System energy level. 45 | level = 3 46 | 47 | # --------------------------- 48 | # Define the qubit arguments. 49 | # --------------------------- 50 | 51 | qubitArgs = { 52 | "coupling": 0.0038 * (2 * pi), # Coupling of Q0 and Q1 53 | "qubit_freq0": 5.114 * (2 * pi), # Frequency of Q0 54 | "qubit_freq1": 4.914 * (2 * pi), # Frequency of Q1 55 | "drive_freq0": 4.914 * (2 * pi), # Drive frequency on Q0 56 | "drive_freq1": 4.914 * (2 * pi), # Drive frequency on Q1 57 | "qubit_anharm0": -0.33 * (2 * pi), # Anharmonicity of Q0 58 | "qubit_anharm1": -0.33 * (2 * pi) # Anharmonicity of Q1 59 | } 60 | 61 | # ---------------------------- 62 | # Construct system Hamiltonian. 63 | # ---------------------------- 64 | 65 | # Create the Hamiltonian with given parameters. 66 | ham = QHam(qubits, level, dt) 67 | for qu in range(2): 68 | # Add the detuning terms. 69 | ham.addDrift(number, qu, (qubitArgs[f"qubit_freq{qu}"] - qubitArgs[f"drive_freq{qu}"])) 70 | 71 | # Add the anharmonicity terms. 72 | ham.addDrift(duff, qu, qubitArgs[f"qubit_anharm{qu}"] / 2) 73 | 74 | # Add the coupling term. 75 | ham.addCoupling([0, 1], qubitArgs["coupling"] / 2) 76 | 77 | # ------------------------------------------ 78 | # Run the optimization and show the results. 79 | # ------------------------------------------ 80 | 81 | # Set amplitude bound. 82 | aBound = (-3.0, 3.0) 83 | 84 | # Run the optimization. 85 | gateJob, infidelity = opt(ham, aBound, tg=200, maxIter=5, targetInfidelity=0.01) 86 | 87 | # Print the basic information of Hamiltonian. 88 | print(ham) 89 | 90 | # Print infidelity and the waveform(s). 91 | print(f"Minimum infidelity: {infidelity}") 92 | gateJob.plot() 93 | 94 | # Print the evolution process. 95 | result = ham.simulate(job=gateJob) 96 | projectedEvolution = project(result.result[0]["unitary"], qubits, level, 2) 97 | print("Projected evolution:\n", round(projectedEvolution, 2)) 98 | -------------------------------------------------------------------------------- /Quanlse/QRegPool.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Quantum Register Pool 20 | """ 21 | from typing import Dict, TYPE_CHECKING 22 | 23 | 24 | class QRegStorage: 25 | """ 26 | The storage for quantum register. 27 | """ 28 | 29 | def __init__(self, index: int, env: 'Scheduler') -> None: 30 | """ 31 | The quantum register object needs to have an index and a quantum environment. 32 | 33 | :param index: the quantum register index 34 | :param env: quantum environment or procedure 35 | :return: None 36 | """ 37 | 38 | self.index = index 39 | self.env = env 40 | 41 | 42 | class QRegPool: 43 | """ 44 | The quantum register dict 45 | """ 46 | 47 | def __init__(self, env: 'Scheduler') -> None: 48 | """ 49 | The constructor of the QRegPool class 50 | 51 | :param env: the related quantum environment or procedure 52 | :return: None 53 | """ 54 | 55 | # the quantum environment related with the quantum register dict 56 | self.env = env 57 | # the inner data for quantum register dict 58 | self.registerMap = {} # type: Dict[int, QRegStorage] 59 | 60 | def __getitem__(self, index: int) -> QRegStorage: 61 | """ 62 | Return the quantum register at the given index 63 | 64 | :param index: item index 65 | :return: the returned item 66 | """ 67 | return self._get(index) 68 | 69 | def __call__(self, index: int) -> QRegStorage: 70 | """ 71 | Return the quantum register at the given index 72 | 73 | :param index: item index 74 | :return: the returned quantum register 75 | """ 76 | return self._get(index) 77 | 78 | def _get(self, index: int) -> QRegStorage: 79 | """ 80 | Get the quantum register according to the index 81 | 82 | Create the register when it does not exists 83 | 84 | :param index: the quantum register index 85 | :return: QuantumRegisterStorage 86 | """ 87 | 88 | value = self.registerMap.get(index) 89 | if value is None: 90 | value = QRegStorage(index, self.env) 91 | self.registerMap[index] = value 92 | return value 93 | 94 | def changeEnv(self, env: 'Scheduler') -> None: 95 | """ 96 | Change the environment 97 | 98 | :param env: the environment to be changed to 99 | :return: None 100 | """ 101 | self.env = env 102 | for qReg in self.registerMap.values(): 103 | qReg.env = env 104 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/Lab/Generator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Pulse generator for Quanlse Scheduler and Experiment. 20 | """ 21 | 22 | from typing import Dict, List, Callable 23 | 24 | from Quanlse.Superconduct.Lab.LabSpace import LabSpace 25 | from Quanlse.QWaveform import QJob 26 | from Quanlse.QOperation import Error, CircuitLine 27 | from Quanlse.Utils.ControlGate import ControlGate 28 | 29 | 30 | class Generator: 31 | """ 32 | Basic class of pulse Generator for Quanlse Scheduler. 33 | 34 | :param labSpace: the LabSpace instance. 35 | """ 36 | def __init__(self, labSpace: LabSpace): 37 | """ Initialize """ 38 | self.labSpace = labSpace # type:LabSpace 39 | self._generators = {} # type: Dict[str, Callable] 40 | 41 | def __call__(self, *args, **kwargs) -> QJob: 42 | """ 43 | Call the instance and generate pulses. 44 | """ 45 | if isinstance(args[0], CircuitLine): 46 | # cirLine = args[0] # type: CircuitLine 47 | # gateName = cirLine.data.name 48 | # qubitIndex = list(cirLine.qRegIndexList) 49 | raise Error.RuntimeError("Not implemented for `CircuitLine` type of gates.") 50 | elif isinstance(args[0], ControlGate): 51 | ctrlGate = args[0] # type: ControlGate 52 | gateName = ctrlGate.name 53 | qubitIndex = list([ctrlGate.onQubit] if isinstance(ctrlGate.onQubit, int) else ctrlGate.onQubit) 54 | qubits = "".join(self.labSpace.getQubitLabel(qubitIndex)) 55 | else: 56 | raise Error.RuntimeError(f"Can not analysis input gate of type `{type(args[0])}`.") 57 | 58 | # Read from labSpace 59 | configKey = f"gates.{qubits}.{gateName}" 60 | presetJob = self.labSpace.getConfig(configKey) 61 | if presetJob is not None: 62 | # The gate is preset in LabSpace 63 | job = QJob.parseJson(presetJob) 64 | return job 65 | else: 66 | if gateName in self.generators.keys(): 67 | return self.generators[gateName](gate=gateName, qubitIndex=qubitIndex, labSpace=self.labSpace) 68 | else: 69 | raise Error.RuntimeError(f"Gate `{gateName}` is not supported by the generator.") 70 | 71 | @property 72 | def generators(self) -> Dict[str, Callable]: 73 | return self._generators 74 | 75 | def addGenerator(self, gateList: List[str], generator: Callable) -> None: 76 | """ 77 | Add pulse generator. 78 | 79 | :param gateList: a gate list to add the generator to 80 | :param generator: generator to be added 81 | :return: None 82 | """ 83 | for gateName in gateList: 84 | self.generators[gateName] = generator 85 | -------------------------------------------------------------------------------- /Quanlse/QPlatform/Utilities.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Utilities 20 | """ 21 | 22 | from typing import Dict, List, Optional, Union, Type 23 | 24 | import pickle 25 | import base64 26 | import numpy 27 | 28 | from Quanlse.QPlatform import Error 29 | from Quanlse.QOperation import CircuitLine 30 | 31 | 32 | def numpyMatrixToDictMatrix(numpyMatrix: numpy.ndarray) -> Dict: 33 | """ 34 | Convert numpy matrix to a dictionary. Must be C-contiguous. 35 | 36 | :param numpyMatrix: numpy matrix 37 | :return: returned dictionary 38 | """ 39 | 40 | if not numpyMatrix.flags["C_CONTIGUOUS"]: 41 | raise Error.ArgumentError('Matrix must C-contiguous!') 42 | 43 | if numpyMatrix.size == 0: 44 | return {} 45 | 46 | array = [] 47 | dictMatrix = { 48 | 'shape': list(numpyMatrix.shape), 49 | 'array': array 50 | } 51 | 52 | for value in numpy.nditer(numpyMatrix): 53 | val = value.reshape(1, 1)[0][0] 54 | array.append({ 55 | 'real': val.real, 56 | 'imag': val.imag 57 | }) 58 | return dictMatrix 59 | 60 | 61 | def dictMatrixToNumpyMatrix(dictMatrix: Dict, valueType: Union[Type[complex], Type[float]]) -> numpy.ndarray: 62 | """ 63 | Convert numpy matrix to a dictionary. Must be C-contiguous. 64 | 65 | :param dictMatrix: dictionary consisting the matrix 66 | :param valueType: select value type 67 | :return: returned numpy matrix 68 | """ 69 | 70 | if len(dictMatrix) == 0: 71 | return numpy.empty(0, valueType) 72 | 73 | if valueType == complex: 74 | complexArray = [complex(complexValue['real'], complexValue['imag']) for complexValue in dictMatrix['array']] 75 | else: 76 | complexArray = [complexValue['real'] for complexValue in dictMatrix['array']] 77 | return numpy.array(complexArray).reshape(dictMatrix['shape']) 78 | 79 | 80 | def circuitLineDump(cirLine: Union[CircuitLine, List[CircuitLine]]) -> str: 81 | """ 82 | Convert CircuitLine Object (or the list of that) into a string. 83 | 84 | :param cirLine: a CircuitLine Object 85 | :return: returned string object 86 | """ 87 | byteStr = pickle.dumps(cirLine) 88 | base64str = base64.b64encode(byteStr) 89 | return base64str.decode() 90 | 91 | 92 | def circuitLineLoad(base64str: str) -> Union[CircuitLine, List[CircuitLine]]: 93 | """ 94 | Convert base64 string into CircuitLine objects. 95 | 96 | :param base64str: input base64 string 97 | :return: returned CircuitLine object 98 | """ 99 | byteStr = base64.b64decode(base64str.encode()) 100 | obj = pickle.loads(byteStr) # type: Union[CircuitLine, List[CircuitLine]] 101 | return obj -------------------------------------------------------------------------------- /Example/7-example-pulse-simulator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Example: Rabi oscillation by pulse-level simulator 20 | Please visit https://quanlse.baidu.com/#/doc/tutorial-pulse-level-simulator for more details about this example. 21 | """ 22 | 23 | import numpy as np 24 | from math import pi 25 | import matplotlib.pyplot as plt 26 | 27 | from Quanlse.QWaveform import QJob, QJobList 28 | from Quanlse.QOperator import driveX 29 | from Quanlse.QWaveform import gaussian 30 | from Quanlse.Utils.Functions import basis, expect, dagger 31 | from Quanlse.Superconduct.Simulator import PulseModel 32 | from Quanlse import Define 33 | from Quanlse.remoteSimulator import remoteSimulatorRunHamiltonian as runHamiltonian 34 | 35 | 36 | # Your token: 37 | # Please visit http://quantum-hub.baidu.com 38 | Define.hubToken = '' 39 | 40 | # Duration time. 41 | tg = 200 42 | 43 | # Number of qubit(s). 44 | qubits = 1 45 | 46 | # System energy level. 47 | level = 3 48 | 49 | # Sampling period. 50 | dt = 1.0 51 | 52 | # -------------------------- 53 | # Define the qubit arguments. 54 | # -------------------------- 55 | 56 | # Qubit frequency and anharmonicity. 57 | qubitFreq = {0: 5.2 * (2 * pi)} 58 | qubitAnharm = {0: -0.33 * (2 * pi)} 59 | 60 | # Define the amplitude list. 61 | dCoef = 0.04 * (2 * pi) 62 | ampRabi = np.linspace(0, 0.7, 100) 63 | amps = dCoef * ampRabi 64 | 65 | # -------------------------------- 66 | # Construct the system Hamiltonian. 67 | # -------------------------------- 68 | 69 | model = PulseModel(subSysNum=qubits, 70 | sysLevel=level, 71 | qubitFreq=qubitFreq, 72 | qubitAnharm=qubitAnharm, 73 | dt=dt) 74 | ham = model.createQHamiltonian() 75 | 76 | # Initialize the jobList. 77 | jobList = QJobList(subSysNum=qubits, sysLevel=level, dt=dt, title='Rabi') 78 | 79 | # Append job to jobList. 80 | for amp in amps: 81 | wave = gaussian(tg, a=amp, tau=tg / 2, sigma=tg / 8) 82 | job = QJob(subSysNum=qubits, sysLevel=level, dt=dt) 83 | job.appendWave(driveX, 0, waves=wave) 84 | job = model.getSimJob(job) 85 | jobList.addJob(jobs=job) 86 | 87 | # -------------------------------- 88 | # Run the simulation and show the results. 89 | # -------------------------------- 90 | 91 | # Run the simulations. 92 | result = runHamiltonian(ham=ham, state0=basis(level, 0), jobList=jobList) 93 | 94 | # Define projector for calculating the population. 95 | prj = basis(level, 0) @ dagger(basis(level, 0)) 96 | 97 | numList = [] 98 | coorList = [] 99 | for res in result.result: 100 | state = res['state'] 101 | rho = state @ dagger(state) 102 | numList.append(1 - expect(prj, state)) 103 | 104 | # Plot the evolution of population. 105 | plt.plot(ampRabi, numList, 'o', label='q') 106 | plt.title('Rabi experiment') 107 | plt.legend() 108 | plt.show() 109 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/Simulator/PulseSim1Q.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2020 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Simulator Template: 1-qubit pulse simulator. 20 | """ 21 | 22 | from numpy import pi 23 | from typing import Dict 24 | 25 | from Quanlse.Superconduct.Simulator import PulseModel 26 | from Quanlse.Superconduct.SchedulerSupport.GeneratorPulseModel import pulseGenerator 27 | from Quanlse.QPlatform.Error import ArgumentError 28 | 29 | 30 | def pulseSim1Q(dt: float = 0.5, frameMode: str = 'rot', qubitFreq: Dict[int, float] = None, 31 | qubitAnharm: Dict[int, float] = None) -> PulseModel: 32 | r""" 33 | Return a template of 1-qubit simulator. 34 | 35 | :param dt: a sampling time period. 36 | :param frameMode: indicates the frame, ``rot`` indicates the rotating frame, 37 | ``lab`` indicates the lab frame. 38 | :param qubitFreq: the qubit frequency, simulator will use the template values if None. 39 | :param qubitAnharm: the qubit anharmonicity, simulator will use the preset values if None. 40 | :return: a 1-qubit PulseModel object. 41 | """ 42 | 43 | # Define parameters needed 44 | sysLevel = 3 # The system level 45 | qubitNum = 1 # The number of qubits 46 | tRelax = 1000 # T1 relaxation time 47 | tDephase = 500 # T2 dephasing time 48 | 49 | # Qubits frequency anharmonicity 50 | if qubitAnharm is None: 51 | qubitAnharm = { 52 | 0: - 0.33 * (2 * pi) 53 | } 54 | else: 55 | if len(qubitAnharm) != qubitNum: 56 | raise ArgumentError(f"The length of qubit frequency should be {qubitNum}!") 57 | 58 | # Qubit Frequency 59 | if qubitFreq is None: 60 | qubitFreq = {0: 5.212 * (2 * pi)} 61 | else: 62 | if len(qubitFreq) != qubitNum: 63 | raise ArgumentError(f"The length of qubit frequency should be {qubitNum}!") 64 | 65 | # T1, T2 66 | t1 = {0: tRelax} 67 | t2 = {0: tDephase} 68 | 69 | # Drive Frequency 70 | if frameMode == 'lab': 71 | # Set the local oscillator 72 | driveFreq = qubitFreq 73 | elif frameMode == 'rot': 74 | driveFreq = None 75 | pass 76 | else: 77 | raise ArgumentError("Only rotating and lab frames are supported!") 78 | 79 | # Generate the pulse model 80 | model = PulseModel(subSysNum=qubitNum, sysLevel=sysLevel, T1=t1, T2=t2, qubitFreq=qubitFreq, driveFreq=driveFreq, 81 | dt=dt, qubitAnharm=qubitAnharm, frameMode=frameMode, pulseGenerator=pulseGenerator) 82 | model.savePulse = False 83 | model.conf["frameMode"] = frameMode 84 | 85 | # Flux pi pulse calibration data 86 | model.conf["caliDataZ"] = { 87 | 0: {"piAmp": pi / 16., "piLen": 16.0} 88 | } 89 | 90 | # Single-Qubit gate Calibration data 91 | model.conf["caliDataXY"] = { 92 | 0: {"piAmp": 0.628965, "piLen": 16.0, "piTau": 8.0, "piSigma": 2.0, "dragCoef": - 0.23} 93 | } 94 | 95 | return model 96 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.2.0] - December-22-2021 4 | ### Added 5 | - Add `Superconduct.Lab` package for rapidly designing superconducting experiments, including the scan or normal experiments; it also provides the interface `Superconduct.Lab.LabSpace` to access the data service, `Superconduct.Lab.Runner` to connect the experiment devices or simulator. 6 | - Add `Utils.ControlGate` module to define the composition of the logic gate and the corresponding control pulses. 7 | - Add `Utils.WaveFunction` module to define the preset waveform functions. 8 | - Add `Simulator.SimulatorAgent` module to define the agent served for Quanlse Simulator, it provides quick access to all data and functions of Quanlse Simulator; it is based on the `Superconduct.Lab` package. 9 | - Add `Utils.Functions.subspaceVec()` function to extract a population vector in a subspace. 10 | - Add symbol QOperator shortcuts `QOperator.chXY()`, `QOperator.chX()`, `QOperator.chY()`, `QOperator.chZ()`, `QOperator.chRO()` which has no matrix definition in `QOperator` module. 11 | - Add `TrappedIon.Optimizer.OptimizerIon` module to calculate robust laser sequence 12 | - Add `TrappedIon.Optimizer.QIonEvolution` module to define basic evolution function of trapped ion system 13 | - Add `TrappedIon.QIonSystem` module to define basic class of robust control laser and trapped ion Chip property. 14 | - Add `TrappedIon.QIonTrajectory` module to define the phonon trajectory evolution and visualize the ion-ion coupling. 15 | ### Changed 16 | - Improve module `QWaveform`, add `dump2Dict()`, `dump2Json()` and `parseJson()` methods to fully support JSON serialization and deserialization; `QWaveform.addWave()` method now is also supported to pass string-formatted waveform function name to argument `f` to call the preset waveforms. 17 | - Newly add the `Superconduct` package, and move the Calibration/Simulator packages into `Superconduct`. 18 | 19 | ## [2.1.0] - September-27-2021 20 | ### Added 21 | 22 | - Add single-qubit calibration module; 23 | - Add readout cavity calibration module; 24 | - Add control-Z gate pulse calibration module; 25 | - Add analysis toolkit for the two-qubit with coupler architecture; 26 | - Add two-qubit `PulseModel` simulator; 27 | - Add `ODESolver` modules, including adaptive ODE solver and `Numba` accelerator support; 28 | - Add new preset waveform functions: `QWaveform.delay()` for inserting time delay and `QWaveform.virtualZ()` for virtual-Z phase shift; 29 | - Add `QWaveform.appendWave()` function, simplify the usage for adding the waves to the Hamiltonian; 30 | - Add `QWaveform.setLO()` function for local oscillator frequency setting; 31 | - Add `freq`/`phase`/`phase0` parameters for `QWaveform` objects; 32 | - Add `PulseModel.Simulate()` method; 33 | - Add new SchedulerPipeline strategies: left-aligned and center aligned. 34 | 35 | ### Changed 36 | 37 | - Improve `QHamiltonian.simulate()`, now support the state population return. 38 | 39 | ### Deprecated 40 | 41 | - Remove `Plot.plotScheduler()`. 42 | 43 | 44 | ## [2.0.0] - July-1-2021 45 | ### Added 46 | 47 | - Refactor the original Quanlse modules; 48 | - Add the Multi-qubit noisy simulator module; 49 | - Add the Randomized Benchmarking module; 50 | - Add Zero-Noise Extrapolation module; 51 | - Trapped ion: Add the general Mølmer-Sørensen gate module. 52 | 53 | 54 | ## [1.1.0] - April-19-2021 55 | ### Added 56 | 57 | - New 1-qubit optimizer using GRAPE (GRadient Ascent Pulse Engineering) Algorithm; 58 | - Noisy 1-qubit simulator including readout simulation; 59 | - Trapped ion: 1-qubit optimizer and the two-qubit MS gate optimizer. 60 | 61 | 62 | ## [1.0.0] - Jan-23-2021 63 | ### Added 64 | 65 | - First commit; 66 | - Quanlse SDK contains toolkits, tutorials, examples. 67 | -------------------------------------------------------------------------------- /Example/11-example-ion-general-MS-gate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Example: General Molmer-Sorensen gate 20 | Please visit https://quanlse.baidu.com/#/doc/tutorial-general-MS-gate for more details about this example. 21 | """ 22 | 23 | import numpy as np 24 | from math import pi 25 | 26 | from Quanlse.Utils.Functions import basis 27 | from Quanlse.Utils.Functions import computationalBasisList 28 | from Quanlse.Utils.Plot import plotBarGraph 29 | from Quanlse.Utils import Plot 30 | from Quanlse import Define 31 | from Quanlse.remoteOptimizer import remoteIonGeneralMS as runGeneralIonMS 32 | 33 | 34 | # Your token: 35 | # Please visit http://quantum-hub.baidu.com 36 | Define.hubToken = '' 37 | 38 | # -------------------------------- 39 | # Define the system information. 40 | # -------------------------------- 41 | 42 | # System qubit number. 43 | ionNumber = 7 44 | 45 | # System ion mass. 46 | mass = 171 47 | 48 | # XY, Z direction trap potential frequency. 49 | omegaXY = 2 * pi * 2e6 50 | omegaZ = 2 * pi * 0.2e6 51 | 52 | # Phonon mode. 53 | phononMode = "transverse" 54 | 55 | args1 = (ionNumber, mass, omegaXY, omegaZ, phononMode) 56 | 57 | # -------------------------------- 58 | # Define the gate information. 59 | # -------------------------------- 60 | 61 | # Total time of quantum gate. 62 | tg = 200 63 | 64 | # The laser detuning, usually related with gate time. but can tuning around 2 * pi / tg. 65 | mu = 2 * pi / tg 66 | 67 | # The pulse sequence slice number, usually N > 3 * ionNumber. 68 | N = 35 69 | 70 | # Sampling period. 71 | dt = tg / N 72 | 73 | # Combine the parameters in list. 74 | args2 = (N, dt, mu) 75 | 76 | # Define two gate pairs of general Molmer-Sorensen gate. 77 | gatePair = [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]] 78 | 79 | # ---------------------------------------- 80 | # Run the simulation and show the results. 81 | # ---------------------------------------- 82 | 83 | # Run the simulation. 84 | res, ureal = runGeneralIonMS(gatePair, args1=args1, args2=args2) 85 | 86 | pulse = res['pulse_list'] 87 | 88 | # Choose the pulse sequence of ionpair. 89 | ionpair = gatePair.index([0, 1]) 90 | 91 | # Plot the laser pulse. 92 | Plot.plotPulse([np.arange(N) * dt * (N+1) / N], [pulse[ionpair]], 93 | title=[f'Pulse for ionpair={gatePair[ionpair]} '], 94 | xLabel=r'Time ($\mu$s)', yLabel=['Rabi frequency (a.u)'], color=['blue']) 95 | 96 | # Print the result of simulation. 97 | print(ureal) 98 | 99 | # Print the infidelity of general MS gate. 100 | print(f"The parallel Molmer-Sorensen gate infidelity:\n {res['infidelity']}") 101 | print(f"The pulse residual error:\n {res['laser_residual_error']}") 102 | 103 | # Plot the population. 104 | finalState = (ureal @ np.array(basis(16, 0))).T[0] 105 | population = [abs(state ** 2) for state in finalState] 106 | basis = computationalBasisList(4, 2) 107 | plotBarGraph(basis, population, "Population of a 4-Qubits GHZ state generated by General MS gate", 108 | "Computational Basis", "Population") 109 | -------------------------------------------------------------------------------- /Quanlse/QRpc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Pulse RPC 20 | """ 21 | import os 22 | from pprint import pprint 23 | from enum import Enum 24 | import json 25 | 26 | from Quanlse.Define import sdkVersion, taskSourceQuanlse, circuitPackageFile, outputPath 27 | from Quanlse.Define.Settings import outputInfo 28 | from Quanlse.QPlatform import Error 29 | 30 | from Quanlse.QTask import ( 31 | invokeBackend, 32 | _retryWhileNetworkError, 33 | _uploadCircuit, 34 | _waitTask, 35 | ) 36 | 37 | OPTIMIZER_TO_TASKTYPE = { 38 | "runHamiltonian": "quanlse_simulator", 39 | "zneMitigation": "quanlse_zne", 40 | } 41 | 42 | 43 | @_retryWhileNetworkError 44 | def _createTask(token, circuitId, optimizer, backendParam=None, modules=[], debug=False, taskType="quanlse_optimizer"): 45 | """ 46 | Create a task from the code 47 | """ 48 | 49 | task = { 50 | "token": token, 51 | "circuitId": circuitId, 52 | "taskType": taskType, 53 | "sdkVersion": sdkVersion, 54 | "source": taskSourceQuanlse, 55 | "optimizer": optimizer, 56 | "modules": modules 57 | } 58 | 59 | if debug: 60 | task['debug'] = debug 61 | 62 | if backendParam: 63 | paramList = [] 64 | for param in backendParam: 65 | if isinstance(param, Enum): 66 | paramList.append(param.value) 67 | else: 68 | paramList.append(param) 69 | task['backendParam'] = paramList 70 | 71 | ret = invokeBackend( 72 | "task/createTask", 73 | task 74 | ) 75 | 76 | return ret['taskId'] 77 | 78 | 79 | def rpcCall(optimizer, args, kwargs, debug=False): 80 | """ 81 | invoke remote optimizer 82 | """ 83 | circuitId = None 84 | taskId = None 85 | 86 | program = { 87 | "optimizer": optimizer, 88 | "args": args, 89 | "kwargs": kwargs, 90 | } 91 | 92 | programBuf = json.dumps(program) 93 | with open(circuitPackageFile, 'wb') as file: 94 | file.write(programBuf.encode("utf-8")) 95 | 96 | token, circuitId = _uploadCircuit(circuitPackageFile) 97 | taskType = OPTIMIZER_TO_TASKTYPE.get(optimizer, "quanlse_optimizer") 98 | taskId = _createTask(token, circuitId, optimizer, debug, taskType=taskType) 99 | 100 | if outputInfo: 101 | print(f"Circuit uploaded successfully, circuitId => {circuitId} taskId => {taskId}") 102 | 103 | taskResult = _waitTask(token, taskId, downloadResult=True) 104 | 105 | if type(taskResult) == str: 106 | raise Error.RuntimeError(taskResult) 107 | 108 | errorMsg = taskResult.get("outer_error") 109 | if errorMsg: 110 | raise Error.RuntimeError(errorMsg) 111 | 112 | else: 113 | localFile = os.path.join(outputPath, f'remote.{taskId}.origin.json') 114 | with open(localFile, "rb") as fObj: 115 | origin = json.loads(fObj.read()) 116 | # return createFromJson(origin["qam"]), origin["infidelity"] 117 | return origin 118 | -------------------------------------------------------------------------------- /Quanlse/Utils/Clifford.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | This file aims to collect functions related to the Clifford group. 20 | """ 21 | 22 | from typing import List 23 | import numpy as np 24 | 25 | from Quanlse.QOperation.FixedGate import FixedGateOP 26 | from Quanlse.QOperation.RotationGate import RX, RY, RZ 27 | from Quanlse.QPlatform.Error import ArgumentError 28 | 29 | # The basic elements of Clifford gates 30 | x90p = RX(np.pi / 2).getMatrix() # Rx+ 31 | x90m = RX(-np.pi / 2).getMatrix() # Rx- 32 | xp = RX(np.pi).getMatrix() # Rx 33 | y90p = RY(np.pi / 2).getMatrix() # Ry+ 34 | y90m = RY(-np.pi / 2).getMatrix() # Ry- 35 | yp = RY(np.pi).getMatrix() # Ry 36 | z90p = RZ(np.pi / 2).getMatrix() # Rz+ 37 | z90m = RZ(-np.pi / 2).getMatrix() # Rz- 38 | zp = RZ(np.pi).getMatrix() # Rz 39 | Id = np.array([[1, 0], [0, 1]], dtype=np.complex128) # Identity 40 | 41 | # Generate single-qubit Clifford matrices 42 | C1 = FixedGateOP('C1', 1, Id) 43 | C2 = FixedGateOP('C2', 1, xp) 44 | C3 = FixedGateOP('C3', 1, yp) 45 | C4 = FixedGateOP('C4', 1, xp @ yp) 46 | C5 = FixedGateOP('C5', 1, x90p @ y90p) 47 | C6 = FixedGateOP('C6', 1, x90p @ y90m) 48 | C7 = FixedGateOP('C7', 1, x90m @ y90p) 49 | C8 = FixedGateOP('C8', 1, x90m @ y90m) 50 | C9 = FixedGateOP('C9', 1, y90p @ x90p) 51 | C10 = FixedGateOP('C10', 1, y90p @ x90m) 52 | C11 = FixedGateOP('C11', 1, y90m @ x90p) 53 | C12 = FixedGateOP('C12', 1, y90m @ x90m) 54 | C13 = FixedGateOP('C13', 1, x90p) 55 | C14 = FixedGateOP('C14', 1, x90m) 56 | C15 = FixedGateOP('C15', 1, y90p) 57 | C16 = FixedGateOP('C16', 1, y90m) 58 | C17 = FixedGateOP('C17', 1, x90m @ y90p @ x90p) 59 | C18 = FixedGateOP('C18', 1, x90m @ y90m @ x90p) 60 | C19 = FixedGateOP('C19', 1, xp @ y90p) 61 | C20 = FixedGateOP('C20', 1, xp @ y90m) 62 | C21 = FixedGateOP('C21', 1, yp @ x90p) 63 | C22 = FixedGateOP('C22', 1, yp @ x90m) 64 | C23 = FixedGateOP('C23', 1, x90p @ y90p @ x90p) 65 | C24 = FixedGateOP('C24', 1, x90m @ y90p @ x90m) 66 | 67 | # Set the single-qubit Clifford gate set 68 | clifford1q = [C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, 69 | C11, C12, C13, C14, C15, C16, C17, C18, C19, C20, 70 | C21, C22, C23, C24] 71 | 72 | 73 | def randomClifford(qubits: int = 1, size: int = 1, seed: int = None) -> List[FixedGateOP]: 74 | r""" 75 | Randomly generate `size` number amount of Clifford operators, 76 | whose number of qubit(s) is given by `qubits`. 77 | 78 | :param qubits: the number of qubits of each Clifford operator 79 | :param size: the number of Clifford operators generated 80 | :param seed: the seed used for randomly generating Clifford operators 81 | :return: A list of generated Clifford operators in U3 representation. 82 | Note that the return type is always a list. 83 | """ 84 | if qubits != 1: 85 | raise ArgumentError(f'in random_Clifford(): only support single-qubit Clifford now!') 86 | 87 | if seed is None: 88 | idx = np.random.randint(0, 24, size) 89 | else: 90 | np.random.seed(seed) 91 | idx = np.random.randint(0, 24, size) 92 | 93 | cliffordRandomList = [clifford1q[idx[i]] for i in range(size)] 94 | 95 | return cliffordRandomList 96 | -------------------------------------------------------------------------------- /Quanlse/remoteZNE.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2020 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Zero-Noise Extrapolation (ZNE) is one of the most powerful techniques for mitigating quantum gate error 20 | in quantum computing. Notice that ZNE does not directly reduce the inherent noise in the quantum 21 | computing process, but rather helps us to obtain the expected computation result by repeating 22 | the same quantum computing process various times with different level of noise. The 23 | advantage of ZNE is that we do not need to know the exact form of the noise as well as how 24 | to control the noise source. 25 | 26 | The ZNE method is composed of two steps: rescaling noise and extrapolating. 27 | Among many of noise rescaling techniques, time-variant rescaling is one of the most robust 28 | and promising. This technique stretches the system Hamiltonian in time according to some 29 | rescaling coefficient in order to obtain an equivalently noise-rescaled final quantum state. 30 | For simplicity, we use the Richardson extrapolation in our Quanlse implementation, which is 31 | a mature numeric algorithm that can eliminate error of any order in principle. We remark 32 | that there are many other extrapolation methods such as polynomial and exponential extrapolation. 33 | 34 | For more details, please visit https://quanlse.baidu.com/#/doc/tutorial-ZNE. 35 | """ 36 | 37 | from Quanlse.QHamiltonian import QHamiltonian as QHam 38 | from Quanlse.QOperation import CircuitLine 39 | import numpy as np 40 | 41 | from Quanlse.QRpc import rpcCall 42 | 43 | from Quanlse.QPlatform.Utilities import ( 44 | numpyMatrixToDictMatrix, 45 | circuitLineDump, 46 | ) 47 | 48 | from typing import List, Tuple 49 | 50 | 51 | def remoteZNEMitigation(rho: np.ndarray, 52 | circuit: List[CircuitLine] = None, 53 | A: np.ndarray = None, 54 | ham: QHam = None, 55 | order: int = 1) -> Tuple[float, List[float], List[float]]: 56 | r""" 57 | Use the extrapolation method to mitigate the expectation value: 58 | 59 | :math:`{\rm Tr}[A C_n\cdots C_1 \rho C_1^\dagger \cdots C_n^\dagger]` 60 | 61 | under the assumption that the implementation of :math:`C_i` suffer from noise. 62 | More specifically, the hamiltonian designed to implement the 63 | quantum circuit :math:`C_n ... C_1` is not perfect. 64 | 65 | If `order` is not set, it will set to 1 by default. 66 | The Richardson extrapolation method will be applied. 67 | The return value will be of the form: 68 | 69 | `mitigatedValue, [coefficients], [noisy values]` 70 | 71 | where the `[coefficients]` and `[noisy values]` are the data points 72 | used to accomplish the Richardson extrapolation, each of size `order+1`. 73 | 74 | :param rho: the input quantum state 75 | :param circuit: the quantum circuit in Quantum Leaf syntax 76 | :param A: the quantum observable 77 | :param ham: the system Hamiltonian designed to implement the quantum circuit. 78 | It may be generated by Scheduler or optimizers. 79 | :param order: the order of the error to be extrapolated. 80 | Must be a positive integer. 81 | :return: The error mitigated expectation value and possibly 82 | a list of coefficients and noisy expectation values. 83 | """ 84 | args = [ 85 | numpyMatrixToDictMatrix(rho), 86 | circuitLineDump(circuit), 87 | numpyMatrixToDictMatrix(A), 88 | ham.dump(), 89 | order 90 | ] 91 | kwargs = {} 92 | 93 | origin = rpcCall("zneMitigation", args, kwargs) 94 | 95 | return origin["mitigatedValue"], origin["infidelities"], origin["noisyValues"] 96 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/Simulator/PulseSim2Q.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2020 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Simulator Template: 2-qubit pulse simulator. 20 | """ 21 | 22 | from numpy import pi 23 | from typing import Dict, Tuple, Union 24 | 25 | from Quanlse.QPlatform.Error import ArgumentError 26 | from Quanlse.Superconduct.Simulator import PulseModel 27 | from Quanlse.Superconduct.SchedulerSupport.GeneratorPulseModel import pulseGenerator 28 | 29 | 30 | def pulseSim2Q(dt: float = 0.5, frameMode: str = 'rot', qubitFreq: Dict[int, float] = None, 31 | qubitAnharm: Dict[int, float] = None, couplingMap: Dict[Tuple, Union[int, float]] = None) -> PulseModel: 32 | r""" 33 | Return a template of 3-qubit simulator. 34 | 35 | :param dt: a sampling time period. 36 | :param frameMode: indicates the frame, ``rot`` indicates the rotating frame, 37 | ``lab`` indicates the lab frame. 38 | :param qubitFreq: the qubit frequency, simulator will use the preset values if None. 39 | :param qubitAnharm: the qubit anharmonicity, simulator will use the preset values if None. 40 | :param couplingMap: the coupling between the qubits, simulator will use the preset values if None. 41 | :return: a 2-qubit PulseModel object. 42 | """ 43 | 44 | # Define parameters needed 45 | sysLevel = 3 # The system level 46 | qubitNum = 2 # The number of qubits 47 | 48 | # Coupling map 49 | if couplingMap is None: 50 | couplingMap = { 51 | (0, 1): 0.020 * (2 * pi), 52 | } 53 | else: 54 | pass 55 | 56 | # Qubits frequency anharmonicity 57 | if qubitAnharm is None: 58 | qubitAnharm = { 59 | 0: - 0.22 * (2 * pi), 60 | 1: - 0.22 * (2 * pi) 61 | } 62 | else: 63 | if len(qubitAnharm) != qubitNum: 64 | raise ArgumentError(f"The length of qubit anharmonicity should be {qubitNum}!") 65 | 66 | # Qubit Frequency 67 | if qubitFreq is None: 68 | qubitFreq = { 69 | 0: 5.5004 * (2 * pi), 70 | 1: 4.4546 * (2 * pi) 71 | } 72 | else: 73 | if len(qubitFreq) != qubitNum: 74 | raise ArgumentError(f"The length of qubit frequency should be {qubitNum}!") 75 | 76 | # Drive Frequency 77 | if frameMode == 'lab': 78 | # Set the local oscillator 79 | driveFreq = qubitFreq 80 | elif frameMode == 'rot': 81 | driveFreq = None 82 | pass 83 | else: 84 | raise ArgumentError("Only rotating and lab frames are supported!") 85 | 86 | # Generate the pulse model 87 | model = PulseModel(subSysNum=qubitNum, sysLevel=sysLevel, couplingMap=couplingMap, qubitFreq=qubitFreq, 88 | driveFreq=driveFreq, dt=dt, qubitAnharm=qubitAnharm, pulseGenerator=pulseGenerator, 89 | frameMode=frameMode) 90 | model.savePulse = False 91 | model.conf["frameMode"] = frameMode 92 | 93 | # Single-qubit gate calibration data 94 | model.conf["caliDataXY"] = { 95 | 0: {'piAmp': 0.642781, 'piLen': 16.0, 'piTau': 8.0, 'piSigma': 2.0, 'dragCoef': -0.39289}, 96 | 1: {"piAmp": 0.649547, "piLen": 16.0, "piTau": 8.0, "piSigma": 2.0, "dragCoef": -0.347843} 97 | } 98 | 99 | # Flux pi pulse calibration data 100 | model.conf["caliDataZ"] = { 101 | 0: {"piAmp": pi / 16., "piLen": 16.0}, 102 | 1: {"piAmp": pi / 16., "piLen": 16.0} 103 | } 104 | 105 | # Two-Qubit gate Calibration data 106 | model.conf["caliDataCZ"] = { 107 | (0, 1): {"czLen": 48.62, "q0ZAmp": -1.5506599, "q1ZAmp": 3.9979779, 108 | "q0VZPhase": -0.079624 * 2 * pi, "q1VZPhase": 0.1592683 * 2 * pi} 109 | } 110 | 111 | return model 112 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/SchedulerSupport/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | r""" 19 | Quanlse's Scheduler Superconduct achieves the following goals: 20 | 21 | - It generates parameters and AWG input signal arrays for fidelity-optimized pulses 22 | when leakage into the state :math:`|2\rangle` is taken into account. 23 | 24 | - It is also capable of scheduling pulses to minimize idle time and therefore reduce 25 | decoherence losses. 26 | 27 | - At the same time, it allows for the visualization of pulse sequences for the users 28 | to check the results. 29 | 30 | CNOT gate is rarely directly implemented on superconducting quantum chips. Instead, 31 | it is often constructed by piecing together single-qubit gates and other two-qubit 32 | gates like CR gate or ISWAP gate that can be easily implemented on a superconducting 33 | chip (often called native gates). The two-qubit gates that are available in the 34 | transmon-like superconducting qubit architecture can be divided into two categories: 35 | 36 | **Flux-controlled** 37 | 38 | This class of gates offers the advantage of short gate time to minimize decoherence 39 | error. However, tuning the qubit frequency can introduce flux noises and lead to the 40 | problem of frequency crowding. 41 | 42 | **All-microwave control** 43 | 44 | CR gate allows for an all-microwave control, which alleviates the problem of flux 45 | noise. However, the much longer time-scale limits the gate fidelity (because of 46 | the decoherence effects of qubits). 47 | 48 | Since CZ gates can be used to construct a CNOT gate easily by using only two other 49 | single-qubit gates, Quanlse's Scheduler offers this way to construct a CNOT gate 50 | in a quantum circuit. 51 | """ 52 | import copy 53 | from typing import List, Union 54 | 55 | from Quanlse.Scheduler import Scheduler 56 | from Quanlse.QHamiltonian import QHamiltonian as QHam 57 | from Quanlse.Scheduler.SchedulerPulseGenerator import SchedulerPulseGenerator 58 | from Quanlse.Scheduler.SchedulerPipeline import SchedulerPipeline 59 | 60 | 61 | class SchedulerSuperconduct(Scheduler): 62 | """ 63 | Basic class of Quanlse Scheduler for superconducting platform 64 | 65 | :param dt: AWG sampling time 66 | :param ham: the QHamiltonian object. 67 | :param generator: the pulseGenerator object. 68 | :param subSysNum: size of the subsystem 69 | :param sysLevel: the energy levels of the system (support different levels for different qubits) 70 | """ 71 | def __init__(self, dt: float = None, ham: QHam = None, generator: SchedulerPulseGenerator = None, 72 | pipeline: SchedulerPipeline = None, subSysNum: int = None, 73 | sysLevel: Union[int, List[int], None] = None): 74 | """ 75 | Constructor for SchedulerSuperconduct object 76 | """ 77 | # Initialization 78 | super().__init__(dt, ham, generator, pipeline, subSysNum, sysLevel) 79 | 80 | # Add the pulse generator 81 | if self._pulseGenerator is None: 82 | if ham is not None: 83 | from Quanlse.Superconduct.SchedulerSupport.GeneratorCloud import generatorCloud 84 | self._pulseGenerator = generatorCloud(self._ham) 85 | else: 86 | self._pulseGenerator = copy.deepcopy(generator) 87 | 88 | # Add the pipeline 89 | if pipeline is not None: 90 | del self._pipeline 91 | self._pipeline = copy.deepcopy(pipeline) 92 | else: 93 | from Quanlse.Superconduct.SchedulerSupport.PipelineLeftAligned import leftAligned 94 | self.pipeline.addPipelineJob(leftAligned) 95 | 96 | # Set the local oscillator information 97 | self._subSysLO = [] # type: List[List[float]] 98 | for num in range(self.subSysNum): 99 | self._subSysLO.append([0.0, 0.0]) 100 | -------------------------------------------------------------------------------- /Example/13-Example-readout.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2020 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Example: readout simulation. 20 | """ 21 | 22 | from Quanlse.Superconduct.Simulator import ReadoutPulse 23 | from Quanlse.Superconduct.Simulator.ReadoutSim3Q import readoutSim3Q 24 | from math import pi 25 | from matplotlib import pyplot as plt 26 | from numpy import linspace 27 | 28 | 29 | readoutModel = readoutSim3Q() 30 | 31 | wr = readoutModel.resonatorFreq 32 | 33 | driveFreq = {0: wr[0], 1: wr[1], 2: wr[2]} # Drive frequency of the readout pulse. 34 | driveStrength = {0: 0.001 * (2 * pi), 1: 0.001 * (2 * pi)} # Drive strength of the readout pulse. 35 | loFreq = 6.064 * (2 * pi) # the local oscillator frequency for demodulation. 36 | 37 | # Create a MeasChannel object and define the drive strength, drive frequency and local oscillator's frequency. 38 | readoutPulse = ReadoutPulse(driveStrength=driveStrength, driveFreq=driveFreq, loFreq=loFreq) 39 | 40 | # Define the measureChannel property. 41 | readoutModel.readoutPulse = readoutPulse 42 | 43 | # The range of the drive frequency to sweep. 44 | freqsRange0 = wr[0] + 0.2 * linspace(-1, 1, 100) * (2 * pi) 45 | 46 | freqsRange1 = wr[1] + 0.2 * linspace(-1, 1, 100) * (2 * pi) 47 | 48 | 49 | q0Grd = [] 50 | i0Grd = [] 51 | q0Exd = [] 52 | i0Exd = [] 53 | 54 | q1Grd = [] 55 | i1Grd = [] 56 | q1Exd = [] 57 | i1Exd = [] 58 | 59 | rhoGrdList = [] 60 | rhoExdList = [] 61 | 62 | # Sweep the frequency when qubit is in ground state 63 | for freq in freqsRange0: 64 | 65 | # Set the drive frequency of the readout pulse 66 | readoutModel.readoutPulse.setFreq(0, freq) 67 | readoutModel.readoutPulse.setFreq(1, freq) 68 | 69 | # Set the duration (in nanoseconds) and the indexes of the resonator simulated. 70 | data = readoutModel.simulate(duration=1000, resIdx=[0, 1], state='ground') 71 | 72 | vi = data['vi'] 73 | vq = data['vq'] 74 | 75 | rhoGrdList.append(data['rho']) 76 | 77 | i0Grd.append(vi[0]) 78 | q0Grd.append(vq[0]) 79 | 80 | i1Grd.append(vi[1]) 81 | q1Grd.append(vq[1]) 82 | 83 | # Sweep the frequency when qubit is in excited state 84 | 85 | for freq in freqsRange1: 86 | 87 | readoutModel.readoutPulse.setFreq(0, freq) 88 | readoutModel.readoutPulse.setFreq(1, freq) 89 | 90 | data = readoutModel.simulate(duration=1000, resIdx=[0, 1], state='excited') 91 | 92 | vi = data['vi'] 93 | vq = data['vq'] 94 | 95 | rhoExdList.append(data['rho']) 96 | 97 | i0Exd.append(vi[0]) 98 | q0Exd.append(vq[0]) 99 | 100 | i1Exd.append(vi[1]) 101 | q1Exd.append(vq[1]) 102 | 103 | 104 | # Plot the IQ signal versus drive frequency. 105 | plt.figure(1) 106 | 107 | plt.subplot(221) 108 | 109 | plt.plot(freqsRange0 * 1e3 / (2 * pi), i0Grd, label='I0, ground') 110 | plt.plot(freqsRange0 * 1e3 / (2 * pi), i0Exd, label='I0, excited') 111 | plt.xlabel('Drive frequency (MHz)') 112 | plt.ylabel('Signal (a.u.)') 113 | 114 | plt.legend() 115 | 116 | plt.subplot(222) 117 | 118 | plt.plot(freqsRange0 * 1e3 / (2 * pi), q0Grd, label='Q0, ground') 119 | plt.plot(freqsRange0 * 1e3 / (2 * pi), q0Exd, label='Q0, excited') 120 | plt.xlabel('Drive frequency (MHz)') 121 | plt.ylabel('Signal (a.u.)') 122 | 123 | plt.legend() 124 | 125 | plt.subplot(223) 126 | 127 | plt.plot(freqsRange1 * 1e3 / (2 * pi), i1Grd, label='I1, ground') 128 | plt.plot(freqsRange1 * 1e3 / (2 * pi), i1Exd, label='I1, excited') 129 | plt.xlabel('Drive frequency (MHz)') 130 | plt.ylabel('Signal (a.u.)') 131 | 132 | plt.legend() 133 | 134 | plt.subplot(224) 135 | 136 | plt.plot(freqsRange1 * 1e3 / (2 * pi), q1Grd, label='Q1, ground') 137 | plt.plot(freqsRange1 * 1e3 / (2 * pi), q1Exd, label='Q1, excited') 138 | plt.xlabel('drive frequency (MHz)') 139 | plt.ylabel('Signal (a.u.)') 140 | 141 | plt.legend() 142 | 143 | plt.show() 144 | 145 | x = linspace(-5, 5, 200) 146 | y = linspace(-5, 5, 200) 147 | 148 | 149 | -------------------------------------------------------------------------------- /Quanlse/QOperation/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Quantum Operation 20 | """ 21 | from typing import List, Union, Optional, Callable, TYPE_CHECKING 22 | 23 | import numpy 24 | 25 | from Quanlse.QPlatform import Error 26 | 27 | if TYPE_CHECKING: 28 | from Quanlse.QOperation.FixedGate import FixedGateOP 29 | from Quanlse.QOperation.RotationGate import RotationGateOP 30 | from Quanlse.QRegPool import QRegStorage 31 | 32 | OperationFunc = Callable[[*'QRegStorage'], None] 33 | RotationArgument = float 34 | 35 | 36 | class QOperation: 37 | """ 38 | Basic classes for quantum operation 39 | """ 40 | 41 | def __init__(self, name: Optional[str] = None, bits: Optional[int] = None, 42 | matrix: Optional[numpy.ndarray] = None) -> None: 43 | """ 44 | Constructor for QOperation class 45 | """ 46 | self.name = name 47 | self.bits = bits 48 | self._matrix = matrix 49 | 50 | def getMatrix(self) -> numpy.ndarray: 51 | """ 52 | Returns a numpy ndarray 53 | 54 | :return: returned matrix in ndarray 55 | """ 56 | if self.__class__.__name__ == 'FixedGateOP': 57 | return self._matrix 58 | elif self.__class__.__name__ == 'RotationGateOP': 59 | if self._matrix is None: 60 | self._matrix = self.generateMatrix() 61 | return self._matrix 62 | elif self.__class__.__name__ == 'CustomizedGateOP': 63 | return self._matrix 64 | else: 65 | raise Error.ArgumentError(f'{self.__class__.__name__} do not have matrix!') 66 | 67 | def _op(self, qRegList: List['QRegStorage']) -> None: 68 | """ 69 | Quantum operation base 70 | 71 | :param qRegList: quantum register list 72 | :return: None 73 | """ 74 | env = qRegList[0].env 75 | for qReg in qRegList: 76 | if qReg.env != env: 77 | raise Error.ArgumentError('QReg must belong to the same env!') 78 | 79 | if env.__class__.__name__ == 'QProcedure': 80 | raise Error.ArgumentError('QProcedure should not be operated!') 81 | 82 | if self.bits is not None and self.bits != len( 83 | qRegList): # Barrier and QProcedure does not match bits configuration 84 | raise Error.ArgumentError('The number of QReg must match the setting!') 85 | 86 | if len(qRegList) <= 0: 87 | raise Error.ArgumentError('Must have QReg in operation!') 88 | 89 | if len(qRegList) != len(set(qReg for qReg in qRegList)): 90 | raise Error.ArgumentError('QReg of operators in circuit are not repeatable!') 91 | 92 | circuitLine = CircuitLine() 93 | circuitLine.data = self 94 | circuitLine.qRegIndexList = [qReg.index for qReg in qRegList] 95 | env.circuit.append(circuitLine) 96 | 97 | 98 | Operation = Union[ 99 | 'FixedGateOP', 'RotationGateOP'] 100 | 101 | 102 | class CircuitLine: 103 | """ 104 | This class defines a quantum gate in the quantum circuit model. 105 | It specifies two key components to characterize a quantum gate: 106 | The gate and its operated qubit indices. 107 | """ 108 | data: None # type: Operation 109 | qRegIndexList: None # type: List[int] 110 | 111 | def __init__(self, data: Operation = None, qRegIndexList: List[int] = None): 112 | r""" 113 | Initialize a quantum gate instance. 114 | 115 | :param data: a Quanlse.QOperation.Operation instance, 116 | the quantum gate to be applied. 117 | :param qRegIndexList: a list of qubit indices. 118 | If `gate` is a single-qubit 119 | gate, then `qubits` still be a List of the form `[i]` 120 | """ 121 | self.data = data 122 | self.qRegIndexList = qRegIndexList 123 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/Calibration/Readout.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """ 18 | Readout resonator Calibration 19 | """ 20 | 21 | from Quanlse.Superconduct.Simulator import ReadoutPulse, ReadoutModel 22 | from numpy import ndarray, argmin 23 | from typing import Union, List, Dict, Tuple, Iterable 24 | from math import pi 25 | from scipy.signal import find_peaks 26 | from scipy.optimize import curve_fit 27 | 28 | 29 | def lorentzian(x: Union[int, float], x0: Union[int, float], a: Union[int, float], 30 | b: Union[int, float], c: Union[int, float]) -> Union[int, float]: 31 | """ 32 | The lorentzian function. 33 | 34 | :param x: position. 35 | :param x0: The center position. 36 | :param a: The scale of the distribution. 37 | :param b: The width of the distribution. 38 | :param c: The shift of the amplitude. 39 | 40 | :return: the y value of the Lorentzian function 41 | """ 42 | return (a / pi) * (0.5 * b) / ((x - x0) ** 2 + (0.5 * b) ** 2) + c 43 | 44 | 45 | def fitLorentzian(x: ndarray, y: ndarray) -> Union[ndarray, Iterable, int, float]: 46 | """ 47 | Fit the curve using Lorentzian function. 48 | 49 | :param x: a list of x data. 50 | :param y: a list of y data. 51 | :return: the result of curve fitting. 52 | """ 53 | 54 | yMax = max(y) 55 | yMaxIdx = find_peaks(y, height=yMax)[0][0] 56 | yHalf = 0.5 * yMax 57 | 58 | yHalfIdx = argmin(abs(y - yHalf)) 59 | 60 | freqCenter = x[yMaxIdx] 61 | width = 2 * (x[yMaxIdx] - x[yHalfIdx]) 62 | 63 | param, cov = curve_fit(lorentzian, x, y, p0=[freqCenter, yMax, width, 0.]) 64 | 65 | return param, cov 66 | 67 | 68 | def resonatorSpec(readoutModel: ReadoutModel, onRes: List[int], freqRange: ndarray, 69 | amplitude: Union[int, float], duration: Union[int, float], 70 | qubitState='ground', loFreq: Union[int, float] = None) -> Tuple[Dict[int, List], Dict[int, List]]: 71 | """ 72 | Resonator Spectroscopy. 73 | 74 | :param readoutModel: a ReadoutModel type object. 75 | :param onRes: Index of the resonators for simulation. 76 | :param freqRange: drive frequency's range. 77 | :param amplitude: amplitude of the readout pulse. 78 | :param duration: duration of the readout pulse. 79 | :param qubitState: the initial qubit state. 80 | :param loFreq: lo frequency for demodulation. 81 | 82 | :return: a tuple of vi data and vq data. 83 | """ 84 | 85 | # Initialize readoutPulse object 86 | driveStrength = {} 87 | 88 | for idx in onRes: 89 | driveStrength[idx] = amplitude 90 | 91 | if loFreq is not None: 92 | loFreq = loFreq 93 | else: 94 | # The local oscillator frequency for demodulation. 95 | loFreq = 6.064 * (2 * pi) 96 | 97 | readoutPulse = ReadoutPulse(driveStrength=driveStrength, driveFreq={}, loFreq=loFreq) 98 | 99 | readoutModel.readoutPulse = readoutPulse 100 | 101 | viDict = {} 102 | vqDict = {} 103 | 104 | for idx in onRes: 105 | viDict[idx] = [] 106 | vqDict[idx] = [] 107 | 108 | for freq in freqRange: 109 | 110 | for idx in onRes: 111 | readoutModel.readoutPulse.setFreq(idx, freq) 112 | 113 | result = readoutModel.simulate(duration=duration, resIdx=onRes, state=qubitState) 114 | 115 | vi = result['vi'] 116 | vq = result['vq'] 117 | 118 | for idx in onRes: 119 | viDict[idx].append(vi[idx]) 120 | vqDict[idx].append(vq[idx]) 121 | 122 | return viDict, vqDict 123 | 124 | 125 | def findFreq(y: Iterable) -> Tuple[ndarray, dict]: 126 | """ 127 | Find the index of the peak. 128 | 129 | :param y: a list of signals. 130 | :return: the index of the peak. 131 | """ 132 | 133 | yMax = max(y) 134 | yHalf = yMax / 2 135 | 136 | idx = find_peaks(y, height=yHalf) 137 | 138 | return idx 139 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/Lab/Utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Utils for superconducting system experiments 20 | """ 21 | 22 | import json 23 | import copy 24 | import pickle 25 | import base64 26 | from typing import List, Dict, Union 27 | 28 | import numpy 29 | 30 | from Quanlse.QPlatform import Error 31 | 32 | 33 | class Scan(object): 34 | """ 35 | Define the scanning range for superconducting experiment. 36 | """ 37 | def __init__(self): 38 | """ Initialize """ 39 | self._availableMode = ["linear", "seq"] 40 | self._mode = "linear" # type: str 41 | self.start = 0. # type: float 42 | self.stop = 0. # type: float 43 | self.steps = 0 # type: int 44 | self.seq = [] # type: List[float] 45 | 46 | @property 47 | def mode(self) -> str: 48 | """ Scan mode """ 49 | return self._mode 50 | 51 | @mode.setter 52 | def mode(self, modeStr: str): 53 | """ Scan mode """ 54 | if modeStr in self._availableMode: 55 | self._mode = modeStr 56 | else: 57 | raise Error.ArgumentError(f"Scan mode {modeStr} is not available!") 58 | 59 | def getList(self): 60 | """ 61 | Return the scanning list 62 | """ 63 | if self._mode == 'linear': 64 | return numpy.linspace(self.start, self.stop, self.steps) 65 | 66 | def dump2Dict(self) -> Dict: 67 | """ 68 | Return the dictionary which characterizes the current instance. 69 | """ 70 | jobDict = {"mode": self._mode, "start": self.start, "stop": self.stop, "steps": self.steps, "seq": self.seq} 71 | return jobDict 72 | 73 | def dump2Json(self): 74 | """ 75 | Return the JSON string which characterizes the current instance. 76 | """ 77 | return json.dumps(self.dump2Dict()) 78 | 79 | @staticmethod 80 | def parseJson(jsonObj: Union[str, Dict]) -> 'Scan': 81 | """ 82 | Create object from a JSON encoded string or dictionary. 83 | 84 | :param jsonObj: a JSON encoded string or dictionary 85 | :return: a QJob object 86 | """ 87 | if isinstance(jsonObj, str): 88 | jsonDict = json.loads(jsonObj) 89 | else: 90 | jsonDict = copy.deepcopy(jsonObj) 91 | # Create scan 92 | scanObj = Scan() 93 | scanObj.mode = jsonDict["mode"] 94 | scanObj.start = jsonDict["start"] 95 | scanObj.stop = jsonDict["stop"] 96 | scanObj.steps = jsonDict["steps"] 97 | scanObj.seq = jsonDict["seq"] 98 | return scanObj 99 | 100 | def dump(self) -> str: 101 | """ 102 | Return a base64 encoded string. 103 | 104 | :return: encoded string 105 | """ 106 | obj = copy.deepcopy(self) 107 | # Serialization 108 | byteStr = pickle.dumps(obj) 109 | base64str = base64.b64encode(byteStr) 110 | del obj 111 | return base64str.decode() 112 | 113 | @staticmethod 114 | def load(base64Str: str) -> 'Scan': 115 | """ 116 | Create object from base64 encoded string. 117 | 118 | :param base64Str: a base64 encoded string 119 | :return: ExperimentScan object 120 | """ 121 | byteStr = base64.b64decode(base64Str.encode()) 122 | obj = pickle.loads(byteStr) # type: Scan 123 | 124 | return obj 125 | 126 | 127 | def scanLinear(start: float, stop: float, steps: int) -> Scan: 128 | """ 129 | Define scanning range for experiment, 130 | """ 131 | scan = Scan() 132 | scan.mode = "linear" 133 | scan.start = start 134 | scan.stop = stop 135 | scan.steps = steps 136 | return scan 137 | 138 | 139 | def scanSeq(seq: List[float]): 140 | """ 141 | Define scanning range for experiment, 142 | """ 143 | scan = Scan() 144 | scan.mode = "seq" 145 | scan.seq = seq 146 | return scan 147 | -------------------------------------------------------------------------------- /Quanlse/Utils/Infidelity.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Infidelity tools 20 | """ 21 | 22 | from numpy import all, ndarray, conjugate, transpose, shape, trace, dot, isclose, allclose 23 | from scipy import linalg 24 | from math import pow 25 | 26 | from Quanlse.QPlatform.Error import ArgumentError 27 | from Quanlse.QOperator import dagger 28 | from Quanlse.Utils.Functions import project 29 | 30 | 31 | def unitaryInfidelity(uGoal: ndarray, uReal: ndarray, subSysNum: int) -> float: 32 | r""" 33 | Return the unitary infidelity of the ``uReal`` with ``uGoal``. 34 | The unitary infidelity is calculated using trace distance: 35 | 36 | :math:`g = 1 - \frac{1}{{\rm dim}(U)} \left| {\rm Tr} \left( U_{\rm goal}^{\dagger} U_{\rm real} \right) \right|.` 37 | 38 | :param uGoal: target unitary 39 | :param uReal: real unitary 40 | :param subSysNum: number of qubits 41 | :return: value of unitary infidelity 42 | """ 43 | dimUGoal = shape(uGoal)[0] 44 | dimUReal = shape(uReal)[0] 45 | # Calculate qubit levels 46 | levelUGoal = int(pow(dimUGoal, 1 / subSysNum)) 47 | levelUReal = int(pow(dimUReal, 1 / subSysNum)) 48 | # We first check whether the dimension of the computational state is reasonable 49 | if levelUGoal == levelUReal: 50 | uGoal = transpose(conjugate(uGoal)) 51 | return 1 - abs(trace(dot(uGoal, uReal))) / dimUGoal 52 | elif levelUGoal > levelUReal: 53 | uGoalProj = project(uGoal, subSysNum, levelUGoal, levelUReal) 54 | uGoalProj = transpose(conjugate(uGoalProj)) 55 | return 1 - abs(trace(dot(uGoalProj, uReal))) / levelUReal 56 | else: 57 | uGoal = transpose(conjugate(uGoal)) 58 | uRealProj = project(uReal, subSysNum, levelUReal, levelUGoal) 59 | return 1 - abs(trace(dot(uGoal, uRealProj))) / dimUGoal 60 | 61 | 62 | def isRho(rho: ndarray, tol: float = 1e-7): 63 | r""" 64 | Check if the input matrix satisfies the following three requirements: Non-negative 65 | definite, Hermitian, Normalized. 66 | 67 | :param rho: the input matrix 68 | :param tol: the tolerance of the imprecision 69 | :return: -1 if not Hermitian; -2 if not normalized; -3 if not non-negative definite, 70 | 1 when it satisfies the conditions of density operator. 71 | """ 72 | 73 | # Check if rho is Hermitian 74 | if not allclose(rho - conjugate(transpose(rho)), 0.): 75 | return -1 76 | 77 | # Check if rho is normalized 78 | if not isclose(trace(rho), 1): 79 | return -2 80 | 81 | # Check if rho is non-negative definite 82 | if not all(linalg.eigvalsh(rho) > -tol): 83 | return -3 84 | 85 | return 1 86 | 87 | 88 | def rhoInfidelity(rhoGoal: ndarray, rhoReal: ndarray) -> float: 89 | r""" 90 | Calculate the infidelity of the two density matrices. 91 | 92 | :param rhoGoal: the target final density matrix 93 | :param rhoReal: the real final density matrix 94 | :return: calculated infidelity of the input two density matrices 95 | """ 96 | 97 | if rhoGoal.shape != rhoReal.shape: 98 | raise ArgumentError("The dimensions of two the input matrices are not matched.") 99 | 100 | rhoGoalSqrt = linalg.sqrtm(rhoGoal) 101 | 102 | return 1 - trace(linalg.sqrtm(rhoGoalSqrt @ rhoReal @ rhoGoalSqrt)) ** 2 103 | 104 | 105 | def traceDistance(rhoGoal: ndarray, rhoReal: ndarray) -> float: 106 | r""" 107 | Calculate the trace distance between two density matrices. 108 | 109 | :param rhoGoal: the target final density matrix 110 | :param rhoReal: the real final density matrix 111 | :return: the trace distance of the two input two density matrices 112 | """ 113 | 114 | if rhoGoal.shape != rhoReal.shape: 115 | raise ArgumentError("The dimensions of two the input matrices are not matched.") 116 | 117 | if not isRho(rhoGoal) or not isRho(rhoReal): 118 | raise ArgumentError("The input matrix doesn't meet the criteria of density matrix.") 119 | 120 | return 0.5 * trace(linalg.sqrtm(dagger(rhoGoal - rhoReal) @ (rhoGoal - rhoReal))) 121 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/Simulator/PulseSim3Q.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2020 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Simulator Template: 3-qubit pulse simulator. 20 | """ 21 | 22 | from numpy import pi 23 | from typing import Dict, Tuple, Union 24 | 25 | from Quanlse.QPlatform.Error import ArgumentError 26 | from Quanlse.Superconduct.Simulator import PulseModel 27 | from Quanlse.Superconduct.SchedulerSupport.GeneratorPulseModel import pulseGenerator 28 | 29 | 30 | def pulseSim3Q(dt: float = 0.5, frameMode: str = 'rot', qubitFreq: Dict[int, float] = None, 31 | qubitAnharm: Dict[int, float] = None, couplingMap: Dict[Tuple, Union[int, float]] = None) -> PulseModel: 32 | r""" 33 | Return a template of 3-qubit simulator. 34 | 35 | :param dt: a sampling time period. 36 | :param frameMode: indicates the frame, ``rot`` indicates the rotating frame, 37 | ``lab`` indicates the lab frame. 38 | :param qubitFreq: the qubit frequency, simulator will use the preset values if None. 39 | :param qubitAnharm: the qubit anharmonicity, simulator will use the preset values if None. 40 | :param couplingMap: the coupling between the qubits, simulator will use the preset values if None. 41 | :return: a 3-qubit PulseModel object. 42 | """ 43 | 44 | # Define parameters needed 45 | sysLevel = 3 # The system level 46 | qubitNum = 3 # The number of qubits 47 | 48 | # Coupling map 49 | if couplingMap is None: 50 | couplingMap = { 51 | (0, 1): 0.020 * (2 * pi), 52 | (1, 2): 0.020 * (2 * pi) 53 | } 54 | else: 55 | pass 56 | 57 | # Qubits frequency anharmonicity 58 | if qubitAnharm is None: 59 | qubitAnharm = { 60 | 0: - 0.22 * (2 * pi), 61 | 1: - 0.22 * (2 * pi), 62 | 2: - 0.22 * (2 * pi) 63 | } 64 | else: 65 | if len(qubitAnharm) != qubitNum: 66 | raise ArgumentError(f"The length of qubit anharmonicity should be {qubitNum}!") 67 | 68 | # Qubit Frequency 69 | if qubitFreq is None: 70 | qubitFreq = { 71 | 0: 5.5004 * (2 * pi), 72 | 1: 4.4546 * (2 * pi), 73 | 2: 5.5004 * (2 * pi), 74 | } 75 | else: 76 | if len(qubitFreq) != qubitNum: 77 | raise ArgumentError(f"The length of qubit frequency should be {qubitNum}!") 78 | 79 | # Drive Frequency 80 | if frameMode == 'lab': 81 | # Set the local oscillator 82 | driveFreq = qubitFreq 83 | elif frameMode == 'rot': 84 | driveFreq = None 85 | pass 86 | else: 87 | raise ArgumentError("Only rotating and lab frames are supported!") 88 | 89 | # Generate the pulse model 90 | model = PulseModel(subSysNum=qubitNum, sysLevel=sysLevel, couplingMap=couplingMap, qubitFreq=qubitFreq, 91 | driveFreq=driveFreq, dt=dt, qubitAnharm=qubitAnharm, pulseGenerator=pulseGenerator, 92 | frameMode=frameMode) 93 | model.savePulse = False 94 | model.conf["frameMode"] = frameMode 95 | 96 | # Single-Qubit gate Calibration data 97 | model.conf["caliDataXY"] = { 98 | 0: {"piAmp": 0.642614, "piLen": 16.0, "piTau": 8.0, "piSigma": 2.0, "dragCoef": -0.36257}, 99 | 1: {"piAmp": 0.637912, "piLen": 16.0, "piTau": 8.0, "piSigma": 2.0, "dragCoef": -0.33307}, 100 | 2: {"piAmp": 0.642614, "piLen": 16.0, "piTau": 8.0, "piSigma": 2.0, "dragCoef": -0.36257} 101 | } 102 | 103 | # Flux pi pulse calibration data 104 | model.conf["caliDataZ"] = { 105 | 0: {"piAmp": pi / 16., "piLen": 16.0}, 106 | 1: {"piAmp": pi / 16., "piLen": 16.0}, 107 | 2: {"piAmp": pi / 16., "piLen": 16.0} 108 | } 109 | 110 | # Two-Qubit gate Calibration data 111 | model.conf["caliDataCZ"] = { 112 | (0, 1): {"czLen": 35.00, "q0ZAmp": -3.5570, "q1ZAmp": 1.5022, 113 | "q0VZPhase": -1.6924, "q1VZPhase": 1.0337}, 114 | (1, 2): {"czLen": 47.24, "q0ZAmp": 2.0581, "q1ZAmp": -3.5250, 115 | "q0VZPhase": 4.5778, "q1VZPhase": -3.9532}, 116 | } 117 | 118 | return model 119 | -------------------------------------------------------------------------------- /Quanlse/Utils/Benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Benchmark 20 | """ 21 | 22 | from typing import Dict, Any, List 23 | from numpy import ndarray, dot, array 24 | 25 | from Quanlse.Utils.Functions import expect, basis 26 | from Quanlse.QHamiltonian import QHamiltonian 27 | from Quanlse.QPlatform.Error import ArgumentError 28 | 29 | 30 | def evolution(ham: QHamiltonian, stateInitial: ndarray = None, matrix: ndarray = None) -> Dict[str, Any]: 31 | """ 32 | Return the expectation value of the given matrix for given initial states. The input can be a list 33 | containing all the matrices and states that the users want to calculate. 34 | 35 | :param ham: Hamiltonian Dictionary 36 | :param stateInitial: the list of numpy.ndarray that represents an initial state in the Hilbert space 37 | :param matrix: the list of matrix whose expectation values to be evaluated 38 | :return: the dictionary that contains all the expectation values for all initial states 39 | """ 40 | 41 | # If the input data is not list, we transform it into a list 42 | if type(matrix) is ndarray: 43 | matrixList = [matrix] 44 | else: 45 | matrixList = matrix 46 | if type(stateInitial) is ndarray: 47 | stateInitial = [stateInitial] 48 | 49 | result = ham.simulate(recordEvolution=True) 50 | unitaryList = result[0]['evolution_history'] 51 | # x = numpy.linspace(0, ham['circuit']['max_time_ns'], ham['circuit']['max_time_dt']) 52 | 53 | stateList = {} 54 | # We first calculate all the intermediate states in the process 55 | for stateIndex, stateItem in enumerate(stateInitial): 56 | stateListTemp = evolutionList(stateItem, unitaryList) 57 | stateList[str(stateIndex)] = {} 58 | stateList[str(stateIndex)]['state_form'] = stateItem 59 | stateList[str(stateIndex)]['state_evolution_history'] = stateListTemp 60 | matrixTempDict = {} 61 | for matrixIndex, matrixItem in enumerate(matrixList): 62 | matrixTempDict['matrix-' + str(matrixIndex) + '-form'] = matrixItem 63 | valueList = [] 64 | for stateItemTemp in stateListTemp: 65 | valueList.append(expect(matrixItem, stateItemTemp)) 66 | matrixTempDict['matrix-' + str(matrixIndex) + '-value'] = valueList 67 | stateList[str(stateIndex)]['result'] = matrixTempDict 68 | return stateList 69 | 70 | 71 | def evolutionList(state: ndarray, unitaryList: List) -> list: 72 | """ 73 | Return the intermediate states with given initial states and the list of unitary matrices. 74 | 75 | :param state: the numpy.ndarray representing the initial state 76 | :param unitaryList: the list containing different unitary matrices at different times 77 | :return stateList: the list of intermediate states for the given unitary matrices 78 | """ 79 | stateList = [] 80 | for unitaryItem in unitaryList: 81 | stateList.append(dot(unitaryItem, state)) 82 | return stateList 83 | 84 | 85 | def stateTruthTable(unitary, qubitNum, sysLevel, initialBasisList=None, finalBasisList=None) -> ndarray: 86 | """ 87 | Generate the truth table of a quantum gate contains the probability of the system being in each 88 | possible basis states at the end of an operation for each possible initial state. 89 | 90 | :param unitary: the unitary matrix 91 | :param qubitNum: the number of qubits 92 | :param sysLevel: the energy level of the system 93 | :param initialBasisList: the list initial basis 94 | :param finalBasisList: the list final basis 95 | :return: the population matrix 96 | """ 97 | if not isinstance(sysLevel, int): 98 | raise ArgumentError('This function currently only supports an integer system level as input.') 99 | 100 | resultMatrix = [] 101 | if initialBasisList is None: 102 | initialBasisList = range(sysLevel ** qubitNum) 103 | if finalBasisList is None: 104 | finalBasisList = range(sysLevel ** qubitNum) 105 | for state in initialBasisList: 106 | stateVec = basis(sysLevel ** qubitNum, state) 107 | stateFinalTemp = unitary @ stateVec 108 | probVec = [] 109 | for index, item in enumerate(stateFinalTemp): 110 | if index in finalBasisList: 111 | probVec.append(abs(item[0]) ** 2) 112 | resultMatrix.append(probVec) 113 | 114 | return array(resultMatrix) 115 | -------------------------------------------------------------------------------- /Quanlse/Utils/WaveFunction.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Define the preset waveform functions. 20 | """ 21 | 22 | from typing import List, Any, Callable 23 | from math import floor, sqrt, pi, atan, sin 24 | from scipy.special import erf 25 | from numpy import array, shape, linspace, arange, exp, sign 26 | 27 | from Quanlse.QPlatform.Error import ArgumentError 28 | 29 | 30 | def waveGaussian(t, args): 31 | """ The Gaussian function """ 32 | a, tau, sigma = args["a"], args["tau"], args["sigma"] 33 | if sigma == 0: 34 | return 0 35 | pulse = a * exp(- ((t - tau) ** 2 / (2 * sigma ** 2))) 36 | return pulse 37 | 38 | 39 | def waveSquare(t, args): 40 | """ The constant function """ 41 | return args["a"] 42 | 43 | 44 | def waveSin(t, args): 45 | """ The sin function """ 46 | a, b, c = args["a"], args["b"], args["c"] 47 | return a * sin(b * t + c) 48 | 49 | 50 | def waveQuasiSquareErf(t, args): 51 | """ The quasi square error function """ 52 | a, l, r, sk = args["a"], args["l"], args["r"], args["sk"] 53 | if sk is None: 54 | sk = a * 0.3 55 | if a == 0.0: 56 | return 0.0 57 | t1i = l 58 | t2i = r 59 | pulse = 0.25 * a * (1 + erf(sqrt(pi) * sk / a * (t - t1i))) 60 | pulse = pulse * (1 - erf(sqrt(pi) * sk / a * (t - t2i))) 61 | return pulse 62 | 63 | 64 | def waveDrag(t, args): 65 | """ The DRAG function """ 66 | a, tau, sigma = args["a"], args["tau"], args["sigma"] 67 | if sigma == 0: 68 | return 0 69 | pulse = - a * (t - tau) / (sigma ** 2) * exp(- ((t - tau) / sigma) ** 2 / 2) 70 | return pulse 71 | 72 | 73 | def waveMix(t, args): 74 | """ The mix function """ 75 | xWave, yWave = args["xWave"], args["yWave"] 76 | xVal = 0. if xWave is None else xWave(t) 77 | yVal = 0. if yWave is None else yWave(t) 78 | # Calculate amplitude 79 | amp = sqrt(xVal ** 2 + yVal ** 2) 80 | # Calculate phase 81 | if abs(xVal) > 1e-10 and abs(yVal) > 1e-10: 82 | varPhase = atan(yVal / xVal) 83 | elif abs(xVal) < 1e-10 < abs(yVal): 84 | varPhase = sign(yVal) * pi / 2 85 | else: 86 | varPhase = 0. 87 | return amp, varPhase 88 | 89 | 90 | presetList = { 91 | "gaussian": { 92 | "func": waveGaussian, 93 | "description": "The gaussian wave function: x(t) = a * exp(- ((t - tau) ** 2 / (2 * sigma ** 2))).", 94 | "args": { 95 | "a": "Maximum amplitude: float", 96 | "tau": "The center position: float", 97 | "sigma": "The standard deviation: float" 98 | } 99 | }, 100 | "square": { 101 | "func": waveSquare, 102 | "description": "The square wave function: x(t) = a.", 103 | "args": { 104 | "a": "Maximum amplitude: float" 105 | } 106 | }, 107 | "sin": { 108 | "func": waveSin, 109 | "description": "The sin wave function: x(t) = a * sin(b * t + c).", 110 | "args": { 111 | "a": "Sin wave amplitude: float", 112 | "b": "2 * pi / (sin wave period): float", 113 | "c": "Sin wave phase: float", 114 | } 115 | }, 116 | "quasi_square_erf": { 117 | "func": waveQuasiSquareErf, 118 | "description": "The quasi-square envelope.", 119 | "args": { 120 | "a": "pulse amplitude: float", 121 | "l": "quasiSquare wave function parameter: float", 122 | "r": "quasiSquare wave function parameter: float", 123 | "sk": "quasiSquare wave function parameter: float", 124 | } 125 | }, 126 | "drag": { 127 | "func": waveDrag, 128 | "description": "The DRAG (Derivative Removal by Adiabatic Gate) waveform.", 129 | "args": { 130 | "a": "Maximum amplitude: float", 131 | "tau": "The center position: float", 132 | "sigma": "The standard deviation: float" 133 | } 134 | }, 135 | "mix": { 136 | "func": waveMix, 137 | "description": "Mix two waveforms.", 138 | "args": { 139 | "xWave": "The first QWaveform instance: QWaveform", 140 | "yWave": "The second QWaveform instance: QWaveform", 141 | } 142 | } 143 | } 144 | """ 145 | The preset wave function dictionary. 146 | """ 147 | 148 | 149 | def preset(func: str) -> Callable: 150 | """ 151 | Return the preset waveform function according to the string function name. 152 | 153 | :param func: the name of the function 154 | """ 155 | if func in presetList.keys(): 156 | return presetList[func]["func"] 157 | else: 158 | raise ArgumentError(f"Function {func} does not exist.") 159 | 160 | -------------------------------------------------------------------------------- /Quanlse/Scheduler/GatePulsePair.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | 19 | """ 20 | The GatePulsePair object. 21 | """ 22 | 23 | import copy 24 | from typing import List, Union, Optional 25 | 26 | from Quanlse.QWaveform import QJob 27 | from Quanlse.QOperator import QOperator 28 | from Quanlse.QPlatform import Error 29 | from Quanlse.QOperation.FixedGate import FixedGateOP 30 | from Quanlse.QOperation.RotationGate import RotationGateOP 31 | 32 | 33 | class GatePulsePair: 34 | """ 35 | A gate with its corresponding pulses. 36 | 37 | :param gate: the FixedGateOP or RotationGateOP object. 38 | :param qubits: indicates the qubits of the gate performing on 39 | :param job: the QJob object 40 | :param t0: the start time 41 | """ 42 | 43 | def __init__(self, gate: Union[FixedGateOP, RotationGateOP] = None, qubits: Union[int, List[int]] = None, 44 | t0: float = None, job: QJob = None): 45 | """ Initialization """ 46 | # Check property 47 | if gate is not None: 48 | if gate.bits is not None: 49 | if isinstance(qubits, int): 50 | if gate.bits != 1: 51 | raise Error.ArgumentError(f"The gate performs on {gate.bits} qubits, however onSysNum " 52 | f"performs on only 1 qubits.") 53 | elif isinstance(qubits, list): 54 | if gate.bits != len(qubits): 55 | raise Error.ArgumentError(f"The gate performs on {gate.bits} qubits, however onSysNum " 56 | f"performs on {len(qubits)} qubits.") 57 | # Set properties 58 | self._gate = gate # type: Union[FixedGateOP, RotationGateOP] 59 | self._qubits = qubits # type: Union[int, List[int]] 60 | self._onSubSys = [] # type: List[int] 61 | self._t = 0.0 # type: float 62 | self._t0 = t0 # type: float 63 | self.job = job 64 | 65 | @property 66 | def job(self) -> Union[QJob, None]: 67 | """ 68 | Get pulses property 69 | """ 70 | return self._job 71 | 72 | @job.setter 73 | def job(self, item: Optional[QJob]): 74 | """ 75 | Set pulses property 76 | """ 77 | if item is not None: 78 | self._job = copy.deepcopy(item) 79 | # pulse duration 80 | self._t, _ = self.job.computeMaxTime() 81 | # Generate onSubSys 82 | onSubSys = [] 83 | for opKey in self.job.ctrlOperators.keys(): 84 | ops = self.job.ctrlOperators[opKey] 85 | if isinstance(ops, list): 86 | for op in ops: 87 | onSubSys.append(op.onSubSys) 88 | elif isinstance(ops, QOperator): 89 | onSubSys.append(ops.onSubSys) 90 | 91 | _onSubSys = onSubSys if isinstance(onSubSys, list) else [onSubSys] 92 | _gateQubits = self._qubits if isinstance(self._qubits, list) else [self._qubits] 93 | onSubSys = list(set(_onSubSys) | set(_gateQubits)) 94 | onSubSys.sort() 95 | self._onSubSys = onSubSys 96 | else: 97 | self._job = None 98 | self._onSubSys = self._qubits 99 | self._t = 0 100 | 101 | @property 102 | def qubits(self) -> Union[int, List[int]]: 103 | """ 104 | Indicates the qubits of the gate performing on 105 | """ 106 | return self._qubits 107 | 108 | @property 109 | def t(self) -> float: 110 | """ 111 | Pulse duration 112 | """ 113 | return self._t 114 | 115 | @property 116 | def t0(self) -> float: 117 | """ 118 | The start time of the GatePulsePair 119 | """ 120 | return self._t0 121 | 122 | @t0.setter 123 | def t0(self, value: float): 124 | """ 125 | The start time of the GatePulsePair 126 | """ 127 | self._t0 = value 128 | 129 | @property 130 | def onSubSys(self) -> List[int]: 131 | """ 132 | The sub-systems which the pulses work on. 133 | """ 134 | return self._onSubSys 135 | 136 | @property 137 | def gate(self) -> Union[FixedGateOP, RotationGateOP]: 138 | """ 139 | Get the FixedGateOP or RotationGateOP object 140 | """ 141 | return self._gate 142 | 143 | @gate.setter 144 | def gate(self, item: Union[FixedGateOP, RotationGateOP]): 145 | """ 146 | Set the FixedGateOP or RotationGateOP object 147 | """ 148 | self._gate = copy.deepcopy(item) 149 | 150 | def hasPulse(self): 151 | """ 152 | check if the instance is empty 153 | """ 154 | return True if self.job is not None else False 155 | -------------------------------------------------------------------------------- /Quanlse/TrappedIon/SchedulerSupport/DefaultPulseGenerator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 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 | Default Pulse Generator for QuanlseIon. 18 | """ 19 | 20 | from math import pi 21 | from numpy import arccos 22 | 23 | from Quanlse.QOperation import CircuitLine, Error 24 | from Quanlse.QWaveform import QJob 25 | from Quanlse.QWaveform import QWaveform 26 | from Quanlse.QOperator import QOperator 27 | from Quanlse.Scheduler.SchedulerPulseGenerator import SchedulerPulseGenerator 28 | from Quanlse.remoteOptimizer import remoteIonOptimize1Qubit as opt1q 29 | from Quanlse.remoteOptimizer import remoteIonGeneralMS as optGMS 30 | 31 | 32 | uWave = QOperator('qubit', None) 33 | 34 | 35 | def generateIon1Qubit(cirLine: CircuitLine = None, scheduler: 'SchedulerIon' = None) -> QJob: 36 | """ 37 | Default generator for ion single-qubit gates. 38 | 39 | :param cirLine: input circuit line object 40 | :param scheduler: input scheduler object 41 | :return: a returned QJob object 42 | """ 43 | job = QJob(subSysNum=scheduler.subSysNum, sysLevel=2, dt=scheduler.dt) 44 | qLabel = cirLine.qRegIndexList 45 | matrixNumber = cirLine.data.getMatrix() 46 | theta = arccos(matrixNumber[0][0]) 47 | theta = theta.real 48 | if cirLine.data.name == 'X': 49 | amp, inf, uReal = opt1q("ionRx", pi, scheduler.dt) 50 | print(f"Single gate infidelity on qubit {qLabel[0]} is: \n {inf}") 51 | job.addWave(uWave, onSubSys=qLabel[0], waves=QWaveform(t0=0.0, t=2 * scheduler.dt, seq=[amp, 0])) 52 | elif cirLine.data.name == 'Y': 53 | amp, inf, uReal = opt1q("ionRy", pi, scheduler.dt) 54 | print(f"Single gate infidelity on qubit {qLabel[0]} is: \n {inf}") 55 | job.addWave(uWave, onSubSys=qLabel[0], waves=QWaveform(t0=0.0, t=2 * scheduler.dt, seq=[amp, 0])) 56 | elif cirLine.data.name == 'RX': 57 | amp, inf, uReal = opt1q("ionRx", theta, scheduler.dt) 58 | print(f"Single gate infidelity on qubit {qLabel[0]} is: \n {inf}") 59 | job.addWave(uWave, onSubSys=qLabel[0], waves=QWaveform(t0=0.0, t=2 * scheduler.dt, seq=[amp, 0])) 60 | elif cirLine.data.name == 'RY': 61 | amp, inf, uReal = opt1q("ionRy", theta, scheduler.dt) 62 | print(f"Single gate infidelity on qubit {qLabel[0]} is: \n {inf}") 63 | job.addWave(uWave, onSubSys=qLabel[0], waves=QWaveform(t0=0.0, t=2 * scheduler.dt, seq=[amp, 0])) 64 | else: 65 | raise Error.ArgumentError(f"Unsupported single-qubit gate {cirLine.data.name}.") 66 | 67 | return job 68 | 69 | 70 | def generateMS(cirLine: CircuitLine = None, scheduler: 'SchedulerIon' = None) -> QJob: 71 | """ 72 | Default generator for M-S gate. 73 | 74 | :param cirLine: input circuit line object 75 | :param scheduler: input scheduler object 76 | :return: a returned QJob object 77 | """ 78 | if 5 < scheduler.dt < 15: 79 | job = QJob(subSysNum=scheduler.subSysNum, sysLevel=2, dt=scheduler.dt) 80 | qLabel = cirLine.qRegIndexList 81 | gatePair = [[qLabel[0], qLabel[1]]] 82 | 83 | """ 84 | For parameter args1, scheduler.subSysNum is the total ion in chain. 85 | And simply, we fix the trapped potential with some typical value: 86 | omegaXY=2 * pi * 2e6, omegaZ=2 * pi * 0.2e6. 87 | We choose typical atomMass=171 for Ytterbium atom, 88 | and using "transverse" phonon to transmit information. 89 | """ 90 | args1 = (scheduler.subSysNum, 171, 2 * pi * 2e6, 2 * pi * 0.2e6, "transverse") 91 | 92 | """ 93 | And for quantum gate parameter, we fix the square pulse number 94 | to be 3*N, where N=scheduler.subSysNum is the ion number in chain. 95 | The laser detuning mu usually has relation with gate time 96 | mu=2*pi/tg, where tg=scheduler.subSysNum * 3 * scheduler.dt. 97 | """ 98 | args2 = (scheduler.subSysNum * 3, scheduler.dt, 2 * pi / (scheduler.subSysNum * 3 * scheduler.dt)) 99 | 100 | result, unitary = optGMS(gatePair, args1=args1, args2=args2) 101 | infidelity = result['infidelity'] 102 | print(f"Gate infidelity of MS{gatePair[0]} is: \n {infidelity}") 103 | sequence = result['pulse_list'][0] 104 | 105 | job.addWave(uWave, onSubSys=qLabel[0], waves=QWaveform(t0=0.0, seq=sequence)) 106 | job.addWave(uWave, onSubSys=qLabel[1], waves=QWaveform(t0=0.0, seq=sequence)) 107 | else: 108 | raise Error.ArgumentError("The sample time of MS gate is between 5 - 15.") 109 | 110 | return job 111 | 112 | 113 | def defaultPulseGenerator() -> SchedulerPulseGenerator: 114 | """ 115 | Default pulse generator for ion-trap qubit 116 | 117 | :return: returned generator object 118 | """ 119 | generator = SchedulerPulseGenerator() 120 | 121 | # Add the generator for single qubit gates 122 | gateList1q = ['X', 'Y', 'RX', 'RY'] 123 | generator.addGenerator(gateList1q, generateIon1Qubit) 124 | 125 | # Add the generator for MS gates 126 | generator.addGenerator(['MS'], generateMS) 127 | 128 | return generator 129 | -------------------------------------------------------------------------------- /Quanlse/Superconduct/SchedulerSupport/GeneratorCloud.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Default Pulse Generator for QuanlseSchedulerSuperconduct. 20 | """ 21 | 22 | from Quanlse.Scheduler import SchedulerPulseGenerator 23 | from Quanlse.QOperation import CircuitLine, Error 24 | from Quanlse.QWaveform import QJob 25 | 26 | from Quanlse.remoteOptimizer import remoteOptimize1Qubit as opt1q 27 | from Quanlse.remoteOptimizer import remoteOptimizeCr as optCr 28 | from Quanlse.remoteOptimizer import remoteOptimizeCz as optCz 29 | from Quanlse.remoteOptimizer import remoteOptimizeISWAP as optISWAP 30 | 31 | 32 | 33 | def generate1Q(ham: 'QHamiltonian' = None, cirLine: CircuitLine = None, 34 | scheduler: 'SchedulerSuperconduct' = None) -> QJob: 35 | """ 36 | Default generator for single qubit gates. 37 | 38 | :param ham: QHam object containing the system information 39 | :param cirLine: a CircuitLine object containing the gate information 40 | :param scheduler: the instance of Quanlse Scheduler Superconducting 41 | :return: returned QJob object 42 | """ 43 | subHam = ham.subSystem(cirLine.qRegIndexList) 44 | if cirLine.data.name in ['X', 'RX']: 45 | job, inf = opt1q(subHam, cirLine.data.getMatrix(), depth=2, targetInfid=0.0001) 46 | elif cirLine.data.name in ['Y', 'RY']: 47 | job, inf = opt1q(subHam, cirLine.data.getMatrix(), depth=2, targetInfid=0.0001) 48 | elif cirLine.data.name in ['Z', 'S', 'T', 'RZ']: 49 | job, inf = opt1q(subHam, cirLine.data.getMatrix(), depth=4, targetInfid=0.0001) 50 | elif cirLine.data.name in ['U', "H"]: 51 | job, inf = opt1q(subHam, cirLine.data.getMatrix(), depth=4, targetInfid=0.0001) 52 | else: 53 | raise Error.ArgumentError(f"Unsupported single qubit gate {cirLine.data.name}.") 54 | 55 | print(f"Infidelity of {cirLine.data.name} on qubit {cirLine.qRegIndexList}: {inf}") 56 | 57 | subHam.job = job 58 | return subHam.outputInverseJob(ham.subSysNum, ham.sysLevel, ham.dt) 59 | 60 | 61 | def generateCr(ham: 'QHamiltonian' = None, cirLine: CircuitLine = None, 62 | scheduler: 'SchedulerSuperconduct' = None) -> QJob: 63 | """ 64 | Default generator for Cross-resonance gate. 65 | 66 | :param ham: QHam object containing the system information 67 | :param cirLine: a CircuitLine object containing the gate information 68 | :param scheduler: the instance of Quanlse Scheduler Superconducting 69 | :return: returned QJob object 70 | """ 71 | subHam = ham.subSystem(cirLine.qRegIndexList) 72 | job, inf = optCr(subHam, (-3.0, 3.0), maxIter=1) 73 | print(f"Infidelity of {cirLine.data.name} on qubit {cirLine.qRegIndexList}: {inf}") 74 | subHam.job = job 75 | return subHam.outputInverseJob(ham.subSysNum, ham.sysLevel, ham.dt) 76 | 77 | 78 | def generateCz(ham: 'QHamiltonian' = None, cirLine: CircuitLine = None, 79 | scheduler: 'SchedulerSuperconduct' = None) -> QJob: 80 | """ 81 | Default generator for controlled-Z gate. 82 | 83 | :param ham: QHam object containing the system information 84 | :param cirLine: a CircuitLine object containing the gate information 85 | :param scheduler: the instance of Quanlse Scheduler Superconducting 86 | :return: returned QJob object 87 | """ 88 | subHam = ham.subSystem(cirLine.qRegIndexList) 89 | job, inf = optCz(subHam, tg=40, targetInfidelity=0.01) 90 | print(f"Infidelity of {cirLine.data.name} on qubit {cirLine.qRegIndexList}: {inf}") 91 | subHam.job = job 92 | return subHam.outputInverseJob(ham.subSysNum, ham.sysLevel, ham.dt) 93 | 94 | 95 | def generateISWAP(ham: 'QHamiltonian' = None, cirLine: CircuitLine = None, 96 | scheduler: 'SchedulerSuperconduct' = None) -> QJob: 97 | """ 98 | Default generator for ISWAP gate. 99 | 100 | :param ham: QHam object containing the system information 101 | :param cirLine: a CircuitLine object containing the gate information 102 | :param scheduler: the instance of Quanlse Scheduler Superconducting 103 | :return: returned QJob object 104 | """ 105 | subHam = ham.subSystem(cirLine.qRegIndexList) 106 | job, inf = optISWAP(subHam, tg=50, targetInfidelity=0.01) 107 | print(f"Infidelity of {cirLine.data.name} on qubit {cirLine.qRegIndexList}: {inf}") 108 | subHam.job = job 109 | return subHam.outputInverseJob(ham.subSysNum, ham.sysLevel, ham.dt) 110 | 111 | 112 | def generatorCloud(ham: 'QHamiltonian') -> SchedulerPulseGenerator: 113 | """ 114 | Return a default pulse SchedulerPulseGenerator instance for the scheduler. 115 | 116 | :param ham: a Hamiltonian object 117 | :return: returned generator object 118 | """ 119 | 120 | generator = SchedulerPulseGenerator(ham) 121 | 122 | # Add the generator for single qubit gates 123 | gateList1q = ['X', 'Y', 'Z', 'H', 'S', 'T', 'RX', 'RY', 'RZ', 'W', 'SQRTW', 'U'] 124 | generator.addGenerator(gateList1q, generate1Q) 125 | 126 | # Add the generator for two-qubit gates 127 | generator.addGenerator(['CR'], generateCr) 128 | generator.addGenerator(['CZ'], generateCz) 129 | generator.addGenerator(['ISWAP'], generateISWAP) 130 | 131 | return generator 132 | -------------------------------------------------------------------------------- /Quanlse/Utils/RandomizedBenchmarking.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | There are generally two ways in experiments for characterizing the performance of a quantum 20 | computer in a superconducting platform: Quantum Process Tomography(QPT) and Randomized Benchmarking (RB) 21 | . QPT can completely characterize a gate, decomposing a process into Pauli or Kraus operators, 22 | but improving gates by QPT is complicated and resource-consuming. Also, State Preparation And Measurement 23 | (SPAM) errors can be confused with process errors. However, RB is a concept of using randomization 24 | methods for benchmarking quantum gates. It is a scalable and SPAM robust method for benchmarking the 25 | full set of gates by a single parameter using randomization techniques. So it is useful to use RB for 26 | a relatively simple and at least SPAM-robust benchmark, especially when the number of qubit increases. 27 | 28 | For more details, please visit https://quanlse.baidu.com/#/doc/tutorial-randomized-benchmarking. 29 | """ 30 | 31 | import numpy as np 32 | from numpy import ndarray 33 | from functools import reduce 34 | 35 | from Quanlse.QOperation.RotationGate import U 36 | from Quanlse.QWaveform import QJob 37 | from Quanlse.remoteSimulator import remoteSimulatorRunHamiltonian as runHamiltonian 38 | 39 | from Quanlse.Utils.Functions import fromMatrixToAngles 40 | from Quanlse.Utils.Clifford import clifford1q 41 | from Quanlse.QPlatform import Error 42 | from Quanlse.Superconduct.Simulator import PulseModel 43 | from Quanlse.Superconduct.SchedulerSupport import SchedulerSuperconduct 44 | from Quanlse.QOperation.FixedGate import FixedGateOP 45 | from Quanlse.Utils.Infidelity import rhoInfidelity 46 | 47 | 48 | def RB(model: PulseModel, targetQubitNum: int, initialState: ndarray, size: int, width: int, 49 | sche: SchedulerSuperconduct, dt: float, targetGate: FixedGateOP = None, interleaved: bool = False, 50 | isOpen: bool = False) -> float: 51 | r""" 52 | Return the sequence's average fidelity for different number of Clifford. 53 | 54 | :param model: the QHamiltonian object of the multi-qubit system. 55 | :param targetQubitNum: the index of the qubit being benchmarked. 56 | :param initialState: the initial state of the system. 57 | :param size: the number of Cliffords in a "width". 58 | :param width: the number of random sequence(s) for each "size". 59 | :param sche: the initiated scheduler. 60 | :param dt: AWG's sampling time. 61 | :param targetGate: the gate being benchmarked. 62 | :param interleaved: whether to use the interleaved benchmarking method. 63 | :param isOpen: whether to solve open system. 64 | :return: the average sequence fidelity of different number of Cliffords. 65 | """ 66 | # Test inputs correctness 67 | if not isinstance(targetQubitNum, int): 68 | raise Error.ArgumentError("We only support single-qubit RB for now.") 69 | else: 70 | job = QJob(subSysNum=model.subSysNum, sysLevel=model.sysLevel, dt=dt) 71 | ham = model.createQHamiltonian() 72 | jobs = ham.createJobList() 73 | # Get the RB-target qubit 74 | ham.job = job 75 | hamTarget = ham.subSystem(targetQubitNum) 76 | sche.clearCircuit() 77 | finalFidelity = [] 78 | # Generate random Clifford 79 | a = 0 80 | while a < width: 81 | idx = np.random.randint(0, 24, size) 82 | b = 0 83 | clifford1qInvReg = [] 84 | # Schedule m Clifford gates 85 | while b < size: 86 | if not interleaved: 87 | clifford1q[idx[size - b - 1]](sche.Q[0]) 88 | clifford1qInvReg.append(clifford1q[idx[b]].getMatrix()) 89 | else: 90 | targetGate(sche.Q[0]) 91 | clifford1q[idx[size - b - 1]](sche.Q[0]) 92 | clifford1qInvReg.append(clifford1q[idx[b]].getMatrix() @ targetGate.getMatrix()) 93 | b += 1 94 | # Schedule inverse Clifford 95 | gateUnitary = np.transpose(np.conjugate(reduce(np.dot, clifford1qInvReg))) 96 | [_, theta, phi, lamda] = fromMatrixToAngles(gateUnitary) 97 | U(theta, phi, lamda)(sche.Q[0]) 98 | # Schedule the whole RB sequence 99 | jobTarget = sche.schedule() 100 | hamTarget.job = jobTarget 101 | jobScheFinal = hamTarget.outputInverseJob(subSysNum=model.subSysNum, sysLevel=model.sysLevel, dt=dt) 102 | job = model.getSimJob(jobScheFinal) 103 | jobs.addJob(jobs=job) 104 | sche.clearCircuit() 105 | jobTarget.clearWaves() 106 | jobScheFinal.clearWaves() 107 | job.clearWaves() 108 | a += 1 109 | ham.buildCache() 110 | # Solve the ODE function 111 | if not isOpen: 112 | result = runHamiltonian(ham, state0=initialState, jobList=jobs) 113 | else: 114 | result = runHamiltonian(ham, state0=initialState, jobList=jobs, isOpen=True) 115 | rhoi = initialState @ ((initialState.transpose()).conjugate()) 116 | for res in result.result: 117 | psit = res['state'] 118 | rhot = psit @ ((psit.transpose()).conjugate()) 119 | # Calculate the single sequence fidelity 120 | fidelity = 1 - np.real(rhoInfidelity(rhot, rhoi)) 121 | finalFidelity.append(fidelity) 122 | ham.job.clearWaves() 123 | ham.clearCache() 124 | hamTarget.job.clearWaves() 125 | hamTarget.clearCache() 126 | return sum(finalFidelity) / width 127 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | [English](README.md) | 简体中文 2 | 3 | ![](https://release-data.cdn.bcebos.com/Quanlse_title_cn.png) 4 | 5 | [![](https://img.shields.io/badge/license-Apache%202.0-green)](./LICENSE) [![](https://img.shields.io/badge/build-passing-green)]() ![](https://img.shields.io/badge/Python-3.7--3.8-blue) ![](https://img.shields.io/badge/release-v2.2.0-blue) 6 | 7 | [量脉(Quanlse)](https://quanlse.baidu.com)是由百度研究院[量子计算研究所](https://quantum.baidu.com)开发的基于云服务的量子控制平台。量脉的目标是搭起连接量子软件和硬件之间的桥梁。通过强大的量脉云服务和开源 SDK,提供高效和专业的量子控制解决方案。 8 | 9 | 量脉支持任意单量子比特门脉冲和双量子比特门脉冲的产生和调度。借助量脉的工具箱,用户可以实现模拟含噪超导量子芯片及其动力学演化、误差分析的可视化、表征并缓释误差、生成离子阱系统中的单/双量子比特门与广义 Mølmer-Sørensen 门脉冲,以及研究核磁系统中的相关应用。在实用化方面,量脉支持量子芯片参数标定、量子门脉冲校准等功能。此外,量脉还支持在脉冲层面实现量子算法以及量子控制领域的进阶研发。 10 | 11 | ## 量脉v2.2 12 | 13 | **注意:本次量脉v2.2的升级,在实用化方面进行了更新,并修复了已知问题,我们强烈建议用户升级至量脉v2.2版本!** 14 | 15 | ![](https://release-data.bd.bcebos.com/Quanlse_architecture_cn.png) 16 | 17 | 在本次2.2版本的升级中,我们针对超导量子实验新增了 `Lab` 包,允许用户快速构造脉冲实验,并提供参数存取、硬件对接等接口。同时,我们还对量脉基础架构进行了升级,支持更灵活的脉冲及脉冲控制通道的定义。在离子阱方面,我们新增了离子阱中鲁棒性较强的激光脉冲控制方法,并提供了离子阱量子计算中控制激光、离子阱芯片以及表征离子-声子相轨迹演化的基础包,方便用户直观地了解离子阱中噪声的影响。 18 | 19 | ## 安装 20 | 21 | 为了提供最佳用户体验,我们强烈建议使用 [Anaconda](https://www.anaconda.com/) 作为研发环境并更新依赖项到最新版本。 22 | 23 | ### 通过 pip 安装 24 | 25 | 我们推荐通过 `pip` 完成安装 26 | 27 | ```bash 28 | pip install Quanlse 29 | ``` 30 | 31 | ### 版本更新 32 | 33 | 如果已经安装了 Quanlse,那么可以用如下命令更新 34 | 35 | ``` 36 | pip install --upgrade Quanlse 37 | ``` 38 | 39 | ### 通过 GitHub 下载安装 40 | 41 | 用户也可以通过 GitHub 下载全部文件后进行本地安装 42 | 43 | ```bash 44 | git clone http://github.com/baidu/Quanlse 45 | cd Quanlse 46 | pip install -e . 47 | ``` 48 | 49 | ### 运行示例程序 50 | 51 | 现在,您可以尝试运行示例程序来验证量脉是否已成功安装 52 | 53 | ```bash 54 | cd Example 55 | python 1-example-pi-pulse.py 56 | ``` 57 | 58 | ## 入门和开发 59 | 60 | ### 概述 61 | 在开始使用量脉之前,我们建议用户首先通过阅读[简介](https://quanlse.baidu.com/#/doc/overview)了解该平台。然后,[快速入门](https://quanlse.baidu.com/#/doc/quickstart)将会一步一步地引导您如何使用量脉云服务,以及如何使用量脉来构建您的第一个程序。接下来,我们鼓励用户在[教程](https://quanlse.baidu.com/#/doc/tutorial-construct-ham)里学习量脉提供的更多应用案例。最后,我们鼓励用户能够使用量脉解决科研和工程问题。有关量脉 API 的完整文档,请阅读我们的 [API 文档页](https://quanlse.baidu.com/api/). 62 | 63 | ### 教程 64 | 65 | 量脉提供了从基础到进阶主题的详尽教程,用户可以通过我们的[网站](https://quanlse.baidu.com)进行学习。对于有兴趣的科研工作者或开发者,我们建议下载并且使用 [Jupyter Notebooks](https://jupyter.org/)。教程的内容如下: 66 | 67 | + **量脉超导** 68 | + [构造哈密顿量](https://quanlse.baidu.com/#/doc/tutorial-construct-hamiltonian) 69 | + **单量子比特控制** 70 | + [单量子比特门](https://quanlse.baidu.com/#/doc/tutorial-single-qubit) 71 | + [基于梯度算法的脉冲优化](https://quanlse.baidu.com/#/doc/tutorial-GRAPE) 72 | + [校准 $\pi$ 脉冲](https://quanlse.baidu.com/#/doc/tutorial-pi-pulse) 73 | + [DRAG 脉冲](https://quanlse.baidu.com/#/doc/tutorial-drag) 74 | + **双量子比特门控制** 75 | + [iSWAP 门](https://quanlse.baidu.com/#/doc/tutorial-iswap) 76 | + [Controlled-Z 门](https://quanlse.baidu.com/#/doc/tutorial-cz) 77 | + [Cross-Resonance 门](https://quanlse.baidu.com/#/doc/tutorial-cr) 78 | + [量脉调度器](https://quanlse.baidu.com/#/doc/tutorial-scheduler) 79 | + **误差处理** 80 | + [误差分析](https://quanlse.baidu.com/#/doc/tutorial-error-analysis) 81 | + [随机基准测试](https://quanlse.baidu.com/#/doc/tutorial-randomized-benchmarking) 82 | + [零噪声外插抑噪方法](https://quanlse.baidu.com/#/doc/tutorial-ZNE) 83 | + **含噪模拟器** 84 | + [单量子比特含噪模拟器](https://quanlse.baidu.com/#/doc/tutorial-single-qubit-noisy-simulator) 85 | + [多量子比特含噪模拟器](https://quanlse.baidu.com/#/doc/tutorial-multi-qubit-noisy-simulator) 86 | + [含耦合器的两量子比特模拟器](https://quanlse.baidu.com/#/doc/tutorial-two-qubit-simulator-with-coupler-architecture) 87 | + **量子比特标定与脉冲校准** 88 | + [读取腔标定](https://quanlse.baidu.com/#/doc/tutorial-readout-cavity-calibration) 89 | + [单量子比特标定](https://quanlse.baidu.com/#/doc/tutorial-single-qubit-calibration) 90 | + [Controlled-Z 门脉冲校准](https://quanlse.baidu.com/#/doc/tutorial-calibration-cz) 91 | + [基于脉冲的 VQE 算法](https://quanlse.baidu.com/#/doc/tutorial-pbvqe) 92 | + **量脉离子阱** 93 | + [单/双量子比特门](https://quanlse.baidu.com/#/doc/tutorial-ion-trap-single-and-two-qubit-gate) 94 | + [广义 Mølmer-Sørensen 门](https://quanlse.baidu.com/#/doc/tutorial-general-MS-gate) 95 | + [离子阱鲁棒双量子 Mølmer-Sørensen 门](https://quanlse.baidu.com/#/doc/tutorial-trapped-ion-robust-control) 96 | + [量脉核磁](https://quanlse.baidu.com/#/doc/nmr) 97 | 98 | ## 反馈 99 | 100 | 我们鼓励用户通过 [Github Issues](https://github.com/baidu/Quanlse/issues) 或 quanlse@baidu.com 联系我们反馈一般问题、错误和改进意见和建议。我们希望通过与社区的合作让量脉变得更好! 101 | 102 | ## 常见问题 103 | **Q:我应该如何开始使用量脉?** 104 | 105 | **A:** 我们建议用户访问我们的[网站](https://quanlse.baidu.com)并遵循以下路线图: 106 | 107 | - **步骤1:** 进入[快速入门](https://quanlse.baidu.com/#/doc/quickstart)了解如何访问量脉云服务。 108 | - **步骤2:** 学习[单量子比特控制](https://quanlse.baidu.com/#/doc/tutorial-single-qubit)和[双量子比特控制](https://quanlse.baidu.com/#/doc/tutorial-iswap)的例子来熟悉量脉。 109 | - **步骤3:** 研究更多进阶应用,探索量脉更多的可能性,例如:[量脉调度器](https://quanlse.baidu.com/#/doc/tutorial-scheduler)、[误差处理](https://quanlse.baidu.com/#/doc/tutorial-error-analysis)、[多比特含噪模拟器](https://quanlse.baidu.com/#/doc/tutorial-multi-qubit-noisy-simulator)、[含耦合器件的两比特模拟器](https://quanlse.baidu.com/#/doc/tutorial-two-qubit-simulator-with-coupler-architecture)、[量子比特标定与脉冲校准](https://quanlse.baidu.com/#/doc/tutorial-readout-cavity-calibration)以及[基于脉冲的 VQE 算法](https://quanlse.baidu.com/#/doc/tutorial-pbvqe) 110 | 111 | **Q:我的 credit points 用完了该怎么办?** 112 | 113 | **A:** 请通过 [Quantum Hub](https://quantum-hub.baidu.com) 联系我们。首先,登录 [Quantum Hub](https://quantum-hub.baidu.com),然后进入“意见反馈”页面,点击“获取点数”,然后输入必要的信息。提交您的反馈并等待回复。 114 | 115 | **Q:我应该如何在研究工作中引用量脉?** 116 | 117 | **A:** 我们鼓励研发人员使用量脉进行量子控制领域的相关工作,请通过如下 [BibTeX 文件](Quanlse.bib)引用量脉。 118 | ## 更新日志 119 | 120 | 量脉的更新日志可在 [CHANGELOG.md](CHANGELOG.md) 文件中查看。 121 | 122 | ## 版权和许可证 123 | 124 | 量脉使用 [Apache-2.0 license](LICENSE) 作为许可证。 125 | 126 | ## 参考文献 127 | 128 | [1] [Quantum Computing - Wikipedia](https://en.wikipedia.org/wiki/Quantum_computing). 129 | 130 | [2] [Nielsen, Michael A., and Isaac L. Chuang. *Quantum Computation and Quantum Information: 10th Anniversary Edition*. Cambridge: Cambridge UP, 2010. Print.](https://doi.org/10.1017/CBO9780511976667) 131 | 132 | [3] [Werschnik, J., and E. K. U. Gross. "Quantum optimal control theory." *Journal of Physics B: Atomic, Molecular and Optical Physics* 40.18 (2007): R175.](https://doi.org/10.1088/0953-4075/40/18/R01) 133 | 134 | [4] [Wendin, Göran. "Quantum information processing with superconducting circuits: a review." *Reports on Progress in Physics* 80.10 (2017): 106001.](https://doi.org/10.1088/1361-6633/aa7e1a) 135 | 136 | [5] [Krantz, Philip, et al. "A quantum engineer's guide to superconducting qubits." *Applied Physics Reviews* 6.2 (2019): 021318.](https://doi.org/10.1063/1.5089550) 137 | -------------------------------------------------------------------------------- /Example/9-example-RB.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Example: Single-qubit Randomized Benchmarking 20 | Please visit https://quanlse.baidu.com/#/doc/tutorial-randomized-benchmarking for more details about this example. 21 | """ 22 | 23 | from math import pi 24 | from scipy.optimize import curve_fit 25 | 26 | from Quanlse.Utils.Functions import basis, tensor 27 | from Quanlse.QOperation import FixedGate 28 | from Quanlse.Superconduct.Simulator import PulseModel 29 | from Quanlse.Superconduct.SchedulerSupport import SchedulerSuperconduct 30 | from Quanlse.Superconduct.SchedulerSupport.GeneratorRBPulse import SingleQubitCliffordPulseGenerator 31 | from Quanlse.Utils.RandomizedBenchmarking import RB 32 | from Quanlse import Define 33 | 34 | 35 | # Your token: 36 | # Please visit http://quantum-hub.baidu.com 37 | Define.hubToken = '' 38 | 39 | # Number of qubit(s). 40 | qubits = 2 41 | 42 | # System energy level. 43 | level = 3 44 | 45 | # Sampling period. 46 | dt = 1.0 47 | 48 | # --------------------------- 49 | # Define the qubit arguments. 50 | # --------------------------- 51 | 52 | qubitArgs = { 53 | "couplingMap": {(0, 1): 0.005 * (2 * pi)}, # Coupling of Q0 and Q1 54 | "wq0": 4.16 * (2 * pi), # Frequency of Q0 55 | "wq1": 4.00 * (2 * pi), # Frequency of Q1 56 | "anharm0": -0.22 * (2 * pi), # Anharmonicity of Q0 57 | "anharm1": -0.21 * (2 * pi) # Anharmonicity of Q1 58 | } 59 | 60 | # Define the input of PulseModel. 61 | qubitFreq = {0: qubitArgs['wq0'], 1: qubitArgs['wq1']} 62 | qubitAnharm = {0: qubitArgs['anharm0'], 1: qubitArgs['anharm1']} 63 | t1List = {0: 5000} 64 | t2List = {0: 2000} 65 | 66 | # -------------------------------- 67 | # Construct the system Hamiltonian. 68 | # -------------------------------- 69 | 70 | # Create a noisy virtual-QPU. 71 | model = PulseModel(subSysNum=qubits, 72 | sysLevel=level, 73 | couplingMap=qubitArgs['couplingMap'], 74 | qubitFreq=qubitFreq, 75 | dt=dt, 76 | qubitAnharm=qubitAnharm, 77 | T1=t1List, T2=t2List, ampSigma=0.0001) 78 | 79 | # Obtain the Hamiltonian of the pulse model. 80 | ham = model.createQHamiltonian() 81 | 82 | # The initial state of this simulator. 83 | initialState = tensor(basis(3, 0), basis(3, 0)) 84 | 85 | # Get the target qubit's basic hardware information. 86 | targetQubitNum = 0 87 | hamTarget = ham.subSystem(targetQubitNum) 88 | 89 | # The gate we want to benchmark. 90 | targetGate = FixedGate.H 91 | 92 | # Create a list to store the outcomes. 93 | sizeSequenceFidelityBasic = [] 94 | sizeSequenceFidelityInterleaved = [] 95 | 96 | # Core parameters of an RB experiment. 97 | size = [1, 10, 20, 50, 75, 100, 125, 150, 175, 200] 98 | width = 5 99 | 100 | # -------------------------------- 101 | # Start RB experiment. 102 | # -------------------------------- 103 | 104 | # First get a basicRB curve used for reference. 105 | print("*" * 50) 106 | print(" Randonmized Benchmark") 107 | print("*" * 50) 108 | 109 | # Schedule those pulses. 110 | sche = SchedulerSuperconduct(dt=dt, ham=hamTarget, generator=SingleQubitCliffordPulseGenerator(hamTarget)) 111 | 112 | # Get a basicRB curve used for reference. 113 | for i in size: 114 | print("-" * 50) 115 | print("Size is", i) 116 | print("-" * 20, "Size is", i, "-" * 21) 117 | widthSequenceFidelityBasic = RB(model=model, targetQubitNum=targetQubitNum, initialState=initialState, size=i, 118 | width=width, sche=sche, dt=dt, interleaved=False, isOpen=False) 119 | sizeSequenceFidelityBasic.append(widthSequenceFidelityBasic) 120 | print(sizeSequenceFidelityBasic) 121 | 122 | # Implement the interleavedRB to benchmark our Hadamard gate. 123 | print("*" * 50) 124 | print(" Interleaved Randonmized Benchmark") 125 | print("*" * 50) 126 | for j in size: 127 | print("-" * 50) 128 | print("Size is", j) 129 | print("-" * 20, "Size is", "-" * 21) 130 | 131 | widthSequenceFidelityInterleaved = RB(model=model, targetQubitNum=targetQubitNum, initialState=initialState, 132 | size=j, width=width, targetGate=targetGate, sche=sche, dt=dt, 133 | interleaved=True, isOpen=False) 134 | sizeSequenceFidelityInterleaved.append(widthSequenceFidelityInterleaved) 135 | print(sizeSequenceFidelityInterleaved) 136 | 137 | # -------------------------------- 138 | # Fit the curve and calculate parameters. 139 | # -------------------------------- 140 | 141 | 142 | # Define the fitting function. 143 | def fit(x, a, p, b): 144 | """ 145 | Define the fitting curve. 146 | """ 147 | return a * (p ** x) + b 148 | 149 | 150 | # Get the EPC(Error-rate Per Clifford) and p_{ref}. 151 | fitparaBasic, fitcovBasic = curve_fit(fit, size, sizeSequenceFidelityBasic, p0=[0.5, 1, 0.5], maxfev=500000, 152 | bounds=[0, 1]) 153 | pfitBasic = fitparaBasic[1] 154 | rClifford = (1 - pfitBasic) / 2 155 | print('EPC = :', rClifford) 156 | 157 | # Get the parameter p_{gate}. 158 | fitparaInterleaved, fitcovInterleaved = curve_fit(fit, size, sizeSequenceFidelityInterleaved, 159 | p0=[fitparaBasic[0], 1, fitparaBasic[2]], 160 | maxfev=500000, bounds=[0, 1]) 161 | pfitInterleaved = fitparaInterleaved[1] 162 | yfitBasic = fitparaBasic[0] * (pfitBasic ** size) + fitparaBasic[2] 163 | yfitInterleaved = fitparaInterleaved[0] * (pfitInterleaved ** size) + fitparaInterleaved[2] 164 | 165 | 166 | # Calculate the EPG(Error-rate Per Gate) with p_{gate} and p_{ref}. 167 | def targetGateErrorRate(pGate, pRef, dimension): 168 | """ 169 | Calculate the specific gate error rate. 170 | """ 171 | return ((1 - (pGate / pRef)) * (dimension - 1)) / dimension 172 | 173 | 174 | # Get the EPG(Error-rate Per Gate). 175 | EPG = targetGateErrorRate(pfitInterleaved, pfitBasic, dimension=2) 176 | print('EPG = : ', EPG) 177 | -------------------------------------------------------------------------------- /Quanlse/Utils/Bloch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf8 -*- 3 | 4 | # Copyright (c) 2021 Baidu, Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """ 19 | Bloch Sphere Visualization Module 20 | """ 21 | 22 | import time 23 | import matplotlib.pyplot as plt 24 | from mpl_toolkits.mplot3d import Axes3D 25 | from matplotlib import animation 26 | import numpy as np 27 | from typing import Union 28 | 29 | from Quanlse.QOperation import Error 30 | 31 | 32 | def plotBloch(coordinates: list = None, xyzData: list = None, color: str ='Purple', mode: str ='animate', 33 | interval: float = None, save: bool = False, size: Union[int, float] = 2, title: str = '', 34 | fName: str = None, fps: float = 20): 35 | """ 36 | This function plots Bloch sphere - supports 'animate' 'vector' and 'scatter' mode. 37 | 38 | :param coordinates: The list of Cartesian coordinates of n data points to plot. 39 | :param xyzData: The list of [XS YS ZS] of n data points to plot. 40 | :param color: The color of the point. 41 | :param mode: support 'animate' 'vector' and 'scatter' modes. 42 | :param interval: Delay between frames in ms. 43 | :param save: Whether to save animation as a gif file. 44 | :param size: Size of points in scatter mode. 45 | :param title: The title of the figure. 46 | :param fName: The name of the file saved. 47 | :param fps: The fps of gif file to save. 48 | """ 49 | 50 | if coordinates is not None: 51 | coordinates = np.array(coordinates) 52 | coordinates[:, [0, 1]] = -1 * coordinates[:, [1, 0]] 53 | data = np.array(coordinates).T 54 | 55 | elif xyzData is not None: 56 | data = np.array(xyzData) 57 | data[[0, 1], :] = -1 * data[[1, 0], :] 58 | coordinates = data.T 59 | 60 | else: 61 | raise Error.ArgumentError('xyzData and coordinate unfilled.') 62 | 63 | # create figure 64 | fig = plt.figure(figsize=[6, 6]) 65 | ax = Axes3D(fig) 66 | 67 | # Set X range 68 | ax.set_xlim3d([-1, 1]) 69 | ax.set_xlabel('X') 70 | 71 | # Set Y range 72 | ax.set_ylim3d([-1, 1]) 73 | ax.set_ylabel('Y') 74 | 75 | # Set Z range 76 | ax.set_zlim3d([-1, 1]) 77 | ax.set_zlabel('Z') 78 | 79 | pNumber = 100 80 | 81 | # Plot Bloch Sphere 82 | u = np.linspace(0, 2 * np.pi, pNumber) 83 | v = np.linspace(0, np.pi, pNumber) 84 | 85 | x = 1 * np.outer(np.cos(u), np.sin(v)) 86 | y = 1 * np.outer(np.sin(u), np.sin(v)) 87 | z = 1.3 * np.outer(np.ones(np.size(u)), np.cos(v)) 88 | 89 | ax.plot_surface(x, y, z, rstride=4, cstride=4, color='ghostwhite', linewidth=0, alpha=0.2) 90 | ax.plot(np.sin(u), np.cos(u), 0, color='grey') 91 | ax.plot([0] * pNumber, np.sin(u), 1.3 * np.cos(u), color='grey') 92 | 93 | # Hide grid lines 94 | ax.grid(False) 95 | 96 | # Hide default axis 97 | plt.axis('off') 98 | 99 | # Plot Axis and Axis Label 100 | ax.quiver(-1.2, 0, 0, 1.2, 0, 0, length=2, normalize=False, 101 | arrow_length_ratio=0.03, lw=1.5, color='black') 102 | ax.quiver(0, 1.2, 0, 0, -1.2, 0, length=2, normalize=False, 103 | arrow_length_ratio=0.03, lw=1.5, color='black') 104 | ax.quiver(0, 0, -1.2 * 1.3, 0, 0, 1.2 * 1.3, length=2, normalize=False, 105 | arrow_length_ratio=0.03, lw=2.5, color='black') 106 | ax.text(0, 0, 1.3 * 1.3, s='Z', weight='heavy') 107 | ax.text(0, -1.4, 0, s='x', weight='heavy') 108 | ax.text(1.3, 0, 0, s='y', weight='heavy') 109 | 110 | if mode == 'animate': 111 | 112 | data[2] = data[2] * 1.3 113 | 114 | line = plt.plot(data[0], data[1], data[2], lw=3)[0] 115 | 116 | def updateTrajectory(num, data, line): 117 | line.set_data(data[0:2, :num]) 118 | line.set_3d_properties(data[2, :num]) 119 | return line 120 | 121 | def update(num, data, line): 122 | update.vec.remove() 123 | update.vec = ax.quiver(0, 0, 0, data[0][num], data[1][num], data[2][num], 124 | normalize=False, arrow_length_ratio=0.05, lw=2, color=color) 125 | line = updateTrajectory(num, data, line) 126 | return line 127 | 128 | numData = len(coordinates) 129 | 130 | if interval is None: 131 | interval = 3 / numData 132 | 133 | update.vec = ax.quiver(0, 0, 0, 0, 0, 0) 134 | 135 | line_ani = animation.FuncAnimation(fig=fig, func=update, frames=numData, 136 | fargs=(data, line), interval=interval) 137 | 138 | plt.show() 139 | if save: 140 | writerGif = animation.PillowWriter(fps=fps) 141 | now = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) 142 | line_ani.save(now + title + '.gif', writer=writerGif) 143 | 144 | elif mode == 'vector': 145 | # Vector mode 146 | coordinates = np.array(data).T 147 | for dat in coordinates: 148 | ax.quiver(0, 0, 0, dat[0], dat[1], dat[2] * 1.3, 149 | normalize=False, arrow_length_ratio=0.1, lw=2, color=color) 150 | plt.title(label=title) 151 | if save: 152 | if fName is None: 153 | fName = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + title + '.png' 154 | plt.savefig(fName) 155 | plt.show() 156 | 157 | elif mode == 'scatter': 158 | # Scatter mode 159 | ax.scatter(data[0], data[1], data[2] * 1.3, marker='o', color=color, s=size) 160 | 161 | plt.title(label=title) 162 | if save: 163 | if fName is None: 164 | fName = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + title + '.png' 165 | plt.savefig(fName) 166 | plt.show() 167 | 168 | 169 | def rho2Coordinate(rho: np.ndarray) -> list: 170 | """ 171 | Convert a density matrix to the list of Cartesian coordinates. 172 | 173 | :param rho: The density matrix. 174 | :return: The list of Cartesian coordinates for given density matrix. 175 | """ 176 | 177 | x1 = 2 * rho[0][1].real 178 | x2 = 2 * rho[1][0].imag 179 | x3 = (rho[0][0] - rho[1][1]).real 180 | 181 | return [x1, x2, x3] 182 | --------------------------------------------------------------------------------