├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug-report.yml │ ├── documentation.yml │ └── feature-request.yml └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .mergify.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── INSTALL.md ├── LICENSE ├── README.md ├── _static └── no_image.png ├── azure-pipelines.yml ├── conf.py ├── constraints.txt ├── images ├── gallery_shot.png ├── logo.png ├── menu_tags.png ├── qiskit_header.png └── set_tag.png ├── index.rst ├── requirements-dev.txt ├── start_here.ipynb ├── tox.ini └── tutorials ├── algorithms ├── 01_algorithms_introduction.ipynb ├── 02_vqe_advanced_options.ipynb ├── 03_vqe_simulation_with_noise.ipynb ├── 04_vqd.ipynb ├── 05_qaoa.ipynb ├── 06_grover.ipynb ├── 07_grover_examples.ipynb ├── 09_IQPE.ipynb ├── 10_pvqd.ipynb ├── 11_VarQTE.ipynb └── 12_gradients_framework.ipynb ├── circuits ├── 01_circuit_basics.ipynb ├── 1_getting_started_with_qiskit.ipynb ├── 2_plotting_data_in_qiskit.ipynb └── 3_summary_of_quantum_operations.ipynb ├── circuits_advanced ├── 01_advanced_circuits.ipynb ├── 02_operators_overview.ipynb ├── 03_advanced_circuit_visualization.ipynb ├── 04_transpiler_passes_and_passmanager.ipynb ├── 05_pulse_gates.ipynb ├── 06_building_pulse_schedules.ipynb ├── 07_pulse_scheduler.ipynb ├── 08_gathering_system_information.ipynb └── pulse_modulation.png └── operators ├── 01_operator_flow.ipynb ├── 02_gradients_framework.ipynb └── images └── gradient_framework.png /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at qiskit@qiskit.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | If you would like to contribute to the Qiskit IQX tutorials, there are a number of ways to 4 | get involved: 5 | 6 | * **Issues**: Issues can be reported with GitHub [issue 7 | reporting](https://github.com/Qiskit/qiskit-tutorial/issues) for this repository. 8 | Select `New issue`, fill in a descriptive title, and provide as much detail 9 | as is needed for the issue to be reproduced. 10 | 11 | * **Notebooks**: If you would like to contribute a notebook, please 12 | create a [fork](https://help.github.com/articles/fork-a-repo/) of the repository 13 | from the `master` branch and create a 14 | [pull request](https://help.github.com/articles/about-pull-requests) for your change. 15 | 16 | ## Contributor License Agreement 17 | 18 | We'd love to accept your code! Before we can, we have to get a few legal 19 | requirements sorted out. By having you sign a Contributor License Agreement (CLA), we 20 | ensure that the community is free to use your contributions. 21 | 22 | When you contribute to the Qiskit project with a new pull request, a bot will 23 | evaluate whether you have signed the CLA. If required, the bot will comment on 24 | the pull request, including a link to accept the agreement. The 25 | [individual CLA](https://qiskit.org/license/qiskit-cla.pdf) document is 26 | available for review as a PDF. 27 | 28 | If you work for a company that wants to allow you to contribute your work, 29 | then you'll need to sign a [corporate CLA](https://qiskit.org/license/qiskit-corporate-cla.pdf) 30 | and email it to us at qiskit@qiskit.org. 31 | 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: 🐛Bug Report 2 | description: Create a report to help us improve 🤔. 3 | labels: ["bug"] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | ⚠️ If you do not respect this template, your issue will be closed 9 | ⚠️ Make sure to browse the opened and closed issues before submitting your issue 10 | - type: textarea 11 | id: what-happened 12 | attributes: 13 | label: What is the current behavior? 14 | description: Please describe the current behavior. 15 | validations: 16 | required: true 17 | - type: textarea 18 | attributes: 19 | label: Information 20 | description: | 21 | examples: 22 | - **Qiskit version**: 0.36.2 23 | - **Python version**: 3.10.10 24 | - **Operating system**: Ubuntu 20.04 25 | value: | 26 | - Qiskit version: 27 | - Python version: 28 | - Operating System: 29 | render: Markdown 30 | validations: 31 | required: true 32 | - type: textarea 33 | id: reproduce 34 | attributes: 35 | label: Steps to reproduce the problem 36 | description: Please provide the steps to reproduce the problem. 37 | validations: 38 | required: true 39 | - type: textarea 40 | id: exptected 41 | attributes: 42 | label: What is the expected behavior? 43 | description: Please describe the expected behavior. 44 | validations: 45 | required: false 46 | - type: textarea 47 | id: solutions 48 | attributes: 49 | label: Suggested solutions 50 | description: Please provide any suggested solutions, if possible. 51 | validations: 52 | required: false 53 | - type: checkboxes 54 | id: terms 55 | attributes: 56 | label: Code of Conduct 57 | description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/Qiskit/qiskit-tutorials/blob/master/.github/CODE_OF_CONDUCT.md) 58 | options: 59 | - label: I agree to follow this project's Code of Conduct 60 | required: true 61 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.yml: -------------------------------------------------------------------------------- 1 | name: 📚 Documentation 2 | description: Create a report to help us improve our documentation 📖. 3 | labels: ["documentation"] 4 | body: 5 | - type: textarea 6 | id: documentation 7 | attributes: 8 | label: Documentation Issue or Improvement 9 | description: Please describe the issue or improvement related to the documentation. 10 | validations: 11 | required: true 12 | - type: checkboxes 13 | id: terms 14 | attributes: 15 | label: Code of Conduct 16 | description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/Qiskit/qiskit-tutorials/blob/master/.github/CODE_OF_CONDUCT.md) 17 | options: 18 | - label: I agree to follow this project's Code of Conduct 19 | required: true 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | name: 🚀Feature request 2 | description: Suggest an idea for this project🌟. 3 | labels: ["enhancement"] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | ⚠️ If you do not respect this template, your issue will be closed 9 | ⚠️ Make sure to browse the opened and closed issues before submitting your issue 10 | - type: textarea 11 | id: enhancement 12 | attributes: 13 | label: Describe the feature or improvement 14 | description: Please describe the new feature or improvement you would like to see. 15 | validations: 16 | required: true 17 | - type: checkboxes 18 | id: terms 19 | attributes: 20 | label: Code of Conduct 21 | description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/Qiskit/qiskit-tutorials/blob/master/.github/CODE_OF_CONDUCT.md) 22 | options: 23 | - label: I agree to follow this project's Code of Conduct 24 | required: true 25 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ### Summary 12 | 13 | 14 | 15 | ### Details and comments 16 | 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | __pycache__/ 3 | .cache/ 4 | 5 | # ignores any checkpoints folder anywhere 6 | .ipynb_checkpoints/ 7 | 8 | # editor files 9 | .vscode/ 10 | .idea/ 11 | 12 | # Distribution / packaging 13 | *.egg-info/ 14 | 15 | # Spyder project settings 16 | .spyderproject 17 | .spyproject 18 | 19 | .DS_Store 20 | 21 | .stestr/ 22 | 23 | _build/ 24 | .tox/ 25 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | queue_rules: 2 | - name: automerge 3 | conditions: 4 | - check-success=Qiskit.qiskit-tutorials 5 | 6 | pull_request_rules: 7 | - name: automatic merge on CI success and review 8 | conditions: 9 | - base=master 10 | - "#approved-reviews-by>=1" 11 | - label=automerge 12 | - label!=on hold 13 | - check-success=Qiskit.qiskit-tutorials 14 | actions: 15 | queue: 16 | name: automerge 17 | method: squash 18 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Code of Conduct 4 | All members of this project agree to adhere to the Qiskit Code of Conduct listed at [https://github.com/Qiskit/qiskit/blob/master/CODE_OF_CONDUCT.md](https://github.com/Qiskit/qiskit/blob/master/CODE_OF_CONDUCT.md) 5 | 6 | ---- 7 | 8 | License: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), 9 | Copyright Contributors to Qiskit. 10 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Contributing 4 | 5 | ## What makes a good tutorial? 6 | 7 | 8 | ## Adding a tutorial 9 | 10 | 11 | ## Setting gallery thumbnails 12 | 13 | To set the gallery thumbnail for a given tutorial (as seen in the image above) one needs to set a cell tag in the notebook for a cell that generates an image as its output. To make the tabs visible do: 14 | 15 | 16 | 17 | The cell's whos output you would like to use, you must add the tag: `nbsphinx-thumbnail`. 18 | 19 | 20 | If a tag is not set, then the Qiskit logo is used as a placeholder. -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | # Qiskit Tutorials 2 | 3 | ## Installation and setup 4 | 5 | ### Get the tutorials 6 | 7 | For the full experience, you can start by downloading the latest release of the 8 | tutorials from [here](https://github.com/Qiskit/qiskit-iqx-tutorials/releases). 9 | Unzip the archive in the directory of your choice (this is the recommended 10 | way). 11 | 12 | To properly view and run the tutorials, you will need to install [Jupyter 13 | Notebook](https://jupyter.readthedocs.io/en/latest/install.html). 14 | 15 | ### Install Qiskit 16 | 17 | At least [Python 3.7 or later](https://www.python.org/downloads/) is required 18 | to install and use Qiskit. If you have multiple Python versions installed (and 19 | particularly if the command `python --version` returns an incompatible 20 | version), you will need to ensure that your versions are [managed 21 | correctly](https://conda.io/projects/conda/en/latest/user-guide/getting-started.html#managing-python). 22 | This can be done using the `environment.yml` file, as detailed below. 23 | 24 | When there are no issues with dependencies, Qiskit can be installed using 25 | 26 | ``` 27 | pip install qiskit 28 | ``` 29 | 30 | Or, a pre-installed Qiskit can be updated using 31 | 32 | ``` 33 | pip install -U qiskit 34 | ``` 35 | 36 | However, in case of issues with dependencies, we recommend the following 37 | installation procedure: 38 | 39 | 1. **Install [conda](https://conda.io/docs/index.html)** 40 | 41 | 2. **Create conda environment for Qiskit and install packages** (with the 42 | accompanying `environment.yml` file) 43 | 44 | ``` 45 | cd qiskit-tutorials 46 | conda env create -f environment.yml 47 | ``` 48 | 49 | If you have already created `environment`, you can upgrade it by running 50 | 51 | ``` 52 | conda env update -f environment.yml 53 | ``` 54 | 55 | 56 | ## 3. Configure your IBM Q Provider 57 | 58 | - Create an [IBM Q](https://quantumexperience.ng.bluemix.net) account if 59 | you haven't already done so 60 | - Get an API token from the IBM Q website under “My Account" > "Qiskit in 61 | local environment" 62 | - We are now going to add the necessary credentials to Qiskit. Take your 63 | token, here called `MY_API_TOKEN`, and pass it to the `IBMQ.save_account()` 64 | function: 65 | 66 | ```python 67 | from qiskit import IBMQ 68 | 69 | IBMQ.save_account('MY_API_TOKEN') 70 | ``` 71 | 72 | - Your credentials will be stored on disk. Once they are stored, at any point 73 | in the future you can load and use them via: 74 | 75 | ```python 76 | from qiskit import IBMQ 77 | 78 | provider = IBMQ.load_account() 79 | ``` 80 | 81 | - For those who do not want to save their credentials to disk, please use 82 | 83 | ```python 84 | from qiskit import IBMQ 85 | 86 | provider = IBMQ.enable_account('MY_API_TOKEN') 87 | ``` 88 | 89 | and the token will only be active for the session. 90 | 91 | 92 | ## 4. Explore the Tutorials 93 | 94 | **Activate the environment**
95 | For MacOS and Linux, run: 96 | 97 | ``` 98 | source activate Qiskitenv 99 | ``` 100 | 101 | For Windows, run: 102 | 103 | ``` 104 | activate Qiskitenv 105 | ``` 106 | **Note for conda users**
107 | Verify that you have installed the right Jupyter Kernel, because in the last 108 | conda version it's not installed by default. 109 | 110 | ``` 111 | python -m ipykernel install --user --name Qiskitenv --display-name "Python (Qiskitenv)" 112 | ``` 113 | 114 | **Start Jupyter with the index notebook**
115 | 116 | ``` 117 | jupyter notebook index.ipynb 118 | ``` 119 | 120 | ## 5. [Optional] Visualizing Circuits with LaTeX 121 | You can visualize your quantum circuits directly from Qiskit. Qiskit circuit 122 | drawers support text, LaTeX and matplotlib. The text and matplotlib version is 123 | entirely native to Python, and thus easy to use. The LaTeX version produces 124 | publication-quality circuit images, but relies on some pre-requisite software. 125 | These include the `pdflatex` compiler for rendering LaTeX documents, and the 126 | Poppler library for converting PDF to image. To get these: 127 | 128 | On Linux: 129 | 130 | - Install [MiKTeX](https://miktex.org/download#unx) 131 | - Install Poppler: 132 | - Run: `apt-get install -y poppler-utils` 133 | 134 | On MacOS: 135 | 136 | - Install [MiKTeX](https://miktex.org/download). 137 | - Install Poppler: 138 | - Run: `brew install poppler` 139 | 140 | On Windows: 141 | 142 | - Install [MiKTeX](https://miktex.org/download). 143 | - Install Poppler: 144 | - Download the [latest binary](http://blog.alivate.com.au/wp-content/uploads/2017/01/poppler-0.51_x86.7z). 145 | - Extract the downloaded `.7z` file into user directory: `c:\Users\\`. 146 | Note: You will need to have the [7zip software](https://www.7-zip.org/download.html) for this. 147 | - Add to PATH: 148 | - Right click on "This PC" -> Properties -> Advanced System Settings -> Environment Variables 149 | - Add `C:\Users\\poppler-0.51\bin` to the user's path. 150 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Qiskit Tutorials 2 | 3 | [![License](https://img.shields.io/github/license/Qiskit/qiskit-tutorials.svg?style=popout-square)](https://opensource.org/licenses/Apache-2.0) 4 | 5 | > :warning: **This repository is archived**: The content in this repository [was moved to other locations](https://github.com/Qiskit/qiskit-tutorials/issues/1473). If you have issues or PR, please submit them to their new location. 6 | 7 | * `algorithms` folder -> [`qiskit-algorithms`](https://qiskit.org/ecosystem/algorithms/tutorials/index.html) ([GitHub](https://github.com/qiskit-community/qiskit-algorithms/tree/main/docs/tutorials)) 8 | * `circuits` folder -> [Qiskit](https://qiskit.org/documentation/tutorials.html) ([GitHub](https://github.com/Qiskit/qiskit/tree/main/docs/tutorials/circuits)) 9 | * `circuits_advanced` folder -> [Qiskit](https://qiskit.org/documentation/tutorials.html) ([GitHub](https://github.com/Qiskit/qiskit/tree/main/docs/tutorials/circuits_advanced)) 10 | * `opflow` folder -> [Qiskit](https://qiskit.org/documentation/tutorials.html) ([GitHub](https://github.com/Qiskit/qiskit/tree/main/docs/tutorials/opflow)) 11 | * `simulators` folder -> [`qiskit-aer`](https://qiskit.org/ecosystem/aer/tutorials/index.html) ([GitHub](https://github.com/qiskit/qiskit-aer/tree/main/docs/tutorials)) 12 | * `textbook` folder -> removed in favor of https://www.qiskit.org/learn 13 | 14 | ## Contents 15 | 16 | Welcome to the [Qiskit](https://www.qiskit.org/) Tutorials! 17 | 18 | In this repository, we've put together a collection of Jupyter notebooks aimed at teaching people who want to use Qiskit for writing quantum computing programs, and executing them on one of several backends (online quantum processors, online simulators, and local simulators). The online quantum processors are the [IBM Quantum](https://quantum-computing.ibm.com) systems. 19 | 20 | For our community-contributed tutorials, please check out the [qiskit-community-tutorials](https://github.com/Qiskit/qiskit-community-tutorials) repository. 21 | 22 | ## Contribution Guidelines 23 | 24 | If you'd like to contribute to Qiskit Tutorials, please take a look at our [contribution guidelines](.github/CONTRIBUTING.md). This project adheres to Qiskit's [code of conduct](.github/CODE_OF_CONDUCT.md). By participating you are expected to uphold this code. 25 | 26 | ### Tutorial limitations 27 | Because the tutorials are executed as part of the build process, and eventually turned into RST documentation, there are several limitations to be aware of: 28 | 29 | 1. There is currently a three minute per cell execution time limit. Cells that go over this limit will raise an exception. 30 | 31 | 2. Tutorials cannot make calls to the IBM Quantum Experience, e.g. no `IBMQ.load_account()`. 32 | 33 | 3. It is important to maintain strict header compliance. All notebooks should start with, and contain only one, top level (h1) header: 34 | 35 | ``` 36 | # I am a top level header 37 | ``` 38 | 39 | Additionally, the nesting of headers should make sense: 40 | 41 | ``` 42 | # I am a top level header 43 | 44 | ## I am a secondary header 45 | 46 | ### I am a tertiary header 47 | 48 | ## I am another secondary header 49 | 50 | ## I am another secondary header 51 | ``` 52 | 53 | 4. All math equations expressed using `$$ ... $$` need to be surrounded on top and bottom by white space. 54 | 55 | 5. In order for a tutorial to show up in the Qiskit documentation, after successful merging, an additional PR needs to be made in the [Qiskit meta-repo](https://github.com/Qiskit/qiskit) to trigger the rebuilding of the documentation. 56 | 57 | ### Adding a gallery image 58 | 59 | To add a gallery image to a notebook, select a cell with an output image and add `nbsphinx-thumbnail` as a cell tag. To see the cell tags go to: `View -> Cell Toolbar -> Tags` in the notebook menu. Adding gallery images from images not generated inside of the notebooks themselves should be avoided if possible as this gets messy in the present build system. 60 | 61 | ## Building documentation 62 | 63 | In addition to serving up standalone notebooks, this repository also includes the infrastructure needed to build the tutorials into HTML documentation using [Sphinx](https://www.sphinx-doc.org/). 64 | 65 | We use [Tox](https://tox.wiki/en/latest/), which you will need to install globally (e.g. using [`pipx`](https://pypa.github.io/pipx/)). 66 | 67 | 1. Fork and clone the forked repository. 68 | 2. `tox -e docs` 69 | 70 | Sometimes Sphinx's caching can get in a bad state. First, try running `tox -e docs-clean`, which will remove Sphinx's cache. If you are still having issues, try running `tox -e docs -r`. `-r` tells Tox to reinstall the dependencies. 71 | 72 | ## Authors and Citation 73 | 74 | Qiskit Tutorials is the work of [many people](https://github.com/Qiskit/qiskit-tutorials/graphs/contributors) who contribute to the project at different levels. If you use Qiskit, please cite as per the included [BibTeX 75 | file](https://github.com/Qiskit/qiskit-terra/blob/main/CITATION.bib). 76 | 77 | ## License 78 | 79 | [Apache License 2.0](LICENSE) 80 | -------------------------------------------------------------------------------- /_static/no_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qiskit/qiskit-tutorials/2fc7ed53fcc7bb3bff4855e400d00ee050a82b81/_static/no_image.png -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | branches: 3 | include: 4 | - master 5 | - stable/* 6 | pr: 7 | autoCancel: true 8 | branches: 9 | include: 10 | - '*' 11 | 12 | pool: 13 | vmImage: 'ubuntu-latest' 14 | strategy: 15 | matrix: 16 | Python39: 17 | python.version: '3.9' 18 | variables: 19 | PIP_CACHE_DIR: $(Pipeline.Workspace)/.pip 20 | steps: 21 | - task: UsePythonVersion@0 22 | inputs: 23 | versionSpec: '$(python.version)' 24 | displayName: 'Use Python $(python.version)' 25 | - task: Cache@2 26 | inputs: 27 | key: 'pip | "$(Agent.OS)" | "$(python.version)" | "$(Build.BuildNumber)"' 28 | restoreKeys: | 29 | pip | "$(Agent.OS)" | "$(python.version)" 30 | pip | "$(Agent.OS)" 31 | pip 32 | path: $(PIP_CACHE_DIR) 33 | displayName: Cache pip 34 | - bash: | 35 | set -e 36 | sudo apt-get install -y pandoc graphviz 37 | python -m pip install -U tox 38 | displayName: 'Install system dependencies and tox' 39 | - bash: tox -e docs 40 | displayName: 'Build Docs' 41 | - task: ArchiveFiles@2 42 | inputs: 43 | rootFolderOrFile: '_build/html' 44 | archiveType: tar 45 | archiveFile: '$(Build.ArtifactStagingDirectory)/html_docs.tar.gz' 46 | verbose: true 47 | - task: PublishBuildArtifacts@1 48 | displayName: 'Publish docs' 49 | inputs: 50 | pathtoPublish: '$(Build.ArtifactStagingDirectory)' 51 | artifactName: 'html_docs' 52 | Parallel: true 53 | ParallelCount: 8 54 | -------------------------------------------------------------------------------- /conf.py: -------------------------------------------------------------------------------- 1 | # This code is part of Qiskit. 2 | # 3 | # (C) Copyright IBM 2018, 2023. 4 | # 5 | # This code is licensed under the Apache License, Version 2.0. You may 6 | # obtain a copy of this license in the LICENSE.txt file in the root directory 7 | # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. 8 | # 9 | # Any modifications or derivative works of this code must retain this 10 | # copyright notice, and modified files need to carry a notice indicating 11 | # that they have been altered from the originals. 12 | 13 | # Configuration file for the Sphinx documentation builder. 14 | # 15 | # This file does only contain a selection of the most common options. For a 16 | # full list see the documentation: 17 | # http://www.sphinx-doc.org/en/master/config 18 | 19 | 20 | # -- Project information ----------------------------------------------------- 21 | project = 'Qiskit Tutorials' 22 | copyright = '2020, Qiskit Development Team' # pylint: disable=redefined-builtin 23 | author = 'Qiskit Development Team' 24 | 25 | # The short X.Y version 26 | version = '' 27 | # The full version, including alpha/beta/rc tags 28 | release = '0.18.0' 29 | 30 | # -- General configuration --------------------------------------------------- 31 | 32 | extensions = [ 33 | 'sphinx.ext.mathjax', 34 | 'sphinx.ext.extlinks', 35 | 'nbsphinx', 36 | "qiskit_sphinx_theme", 37 | ] 38 | html_static_path = ['_static'] 39 | 40 | exclude_patterns = ['*.ipynb', '_build', 'legacy_tutorials', 41 | '**.ipynb_checkpoints', '.tox'] 42 | 43 | nbsphinx_timeout = 300 44 | nbsphinx_execute = 'always' 45 | nbsphinx_widgets_path = "" 46 | html_sourcelink_suffix = "" 47 | nbsphinx_thumbnails = {"**": "_static/no_image.png"} 48 | 49 | nbsphinx_prolog = """ 50 | {% set docname = env.doc2path(env.docname, base=None) %} 51 | 52 | .. only:: html 53 | 54 | .. role:: raw-html(raw) 55 | :format: html 56 | 57 | .. note:: 58 | This page was generated from `{{ docname }}`__. 59 | 60 | Run interactively in the `IBM Quantum lab `_. 61 | 62 | __ https://github.com/Qiskit/qiskit-tutorials/blob/master/{{ docname }} 63 | 64 | """ 65 | 66 | 67 | # If true, figures, tables and code-blocks are automatically numbered if they 68 | # have a caption. 69 | numfig = True 70 | 71 | # A dictionary mapping 'figure', 'table', 'code-block' and 'section' to 72 | # strings that are used for format of figure numbers. As a special character, 73 | # %s will be replaced to figure number. 74 | numfig_format = { 75 | 'table': 'Table %s' 76 | } 77 | language = "en" 78 | 79 | # The name of the Pygments (syntax highlighting) style to use. 80 | pygments_style = 'colorful' 81 | 82 | # A boolean that decides whether module names are prepended to all object names 83 | # (for object types where a “module” of some kind is defined), e.g. for 84 | # py:function directives. 85 | add_module_names = False 86 | 87 | # -- Options for HTML output ------------------------------------------------- 88 | 89 | html_theme = 'qiskit_sphinx_theme' 90 | 91 | html_logo = 'images/logo.png' 92 | html_last_updated_fmt = '%Y/%m/%d' 93 | 94 | html_theme_options = { 95 | 'logo_only': False, 96 | 'display_version': True, 97 | 'prev_next_buttons_location': 'bottom', 98 | 'style_external_links': True, 99 | } 100 | 101 | autoclass_content = 'both' 102 | -------------------------------------------------------------------------------- /constraints.txt: -------------------------------------------------------------------------------- 1 | docplex==2.15.194 2 | decorator==4.4.2 3 | -------------------------------------------------------------------------------- /images/gallery_shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qiskit/qiskit-tutorials/2fc7ed53fcc7bb3bff4855e400d00ee050a82b81/images/gallery_shot.png -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qiskit/qiskit-tutorials/2fc7ed53fcc7bb3bff4855e400d00ee050a82b81/images/logo.png -------------------------------------------------------------------------------- /images/menu_tags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qiskit/qiskit-tutorials/2fc7ed53fcc7bb3bff4855e400d00ee050a82b81/images/menu_tags.png -------------------------------------------------------------------------------- /images/qiskit_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qiskit/qiskit-tutorials/2fc7ed53fcc7bb3bff4855e400d00ee050a82b81/images/qiskit_header.png -------------------------------------------------------------------------------- /images/set_tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qiskit/qiskit-tutorials/2fc7ed53fcc7bb3bff4855e400d00ee050a82b81/images/set_tag.png -------------------------------------------------------------------------------- /index.rst: -------------------------------------------------------------------------------- 1 | ================ 2 | Qiskit Tutorials 3 | ================ 4 | 5 | Quantum circuits 6 | ================ 7 | 8 | .. nbgallery:: 9 | :glob: 10 | 11 | tutorials/circuits/* 12 | 13 | Advanced circuits 14 | ================= 15 | 16 | .. nbgallery:: 17 | :glob: 18 | 19 | tutorials/circuits_advanced/* 20 | 21 | Algorithms 22 | ========== 23 | 24 | .. nbgallery:: 25 | :glob: 26 | 27 | tutorials/algorithms/* 28 | 29 | Operators 30 | ========= 31 | 32 | .. nbgallery:: 33 | :glob: 34 | 35 | tutorials/operators/* 36 | 37 | .. Hiding - Indices and tables 38 | :ref:`genindex` 39 | :ref:`modindex` 40 | :ref:`search` 41 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | qiskit>=0.38.0 2 | jupyter 3 | sphinx 4 | nbsphinx 5 | qiskit_sphinx_theme 6 | networkx 7 | scikit-learn 8 | matplotlib 9 | qiskit[visualization] 10 | qiskit_aer 11 | cvxpy 12 | pyscf 13 | -------------------------------------------------------------------------------- /start_here.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "![qiskit_header.png](images/qiskit_header.png)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Qiskit Tutorials\n", 15 | "\n", 16 | "Welcome Qiskitters.\n", 17 | "\n", 18 | "\n", 19 | "These tutorials aim to explain how to use Qiskit. We assume you have installed Qiskit; if not, please look at [qiskit.org](http://www.qiskit.org) or the install [documentation](https://qiskit.org/documentation/install.html). \n", 20 | "\n", 21 | "The focus of these notebooks is not on learning quantum computing. Instead we will focus on how to use Qiskit, and will go into details only when needed. For those interested in learning about quantum computing we recommend the [Qiskit Textbook](https://qiskit.org/textbook) that we and the community have put together, or the [Qiskit documentation](https://qiskit.org/documentation).\n", 22 | "\n", 23 | "\n", 24 | "## Circuits\n", 25 | "\n", 26 | "This section gives you the tools to make your first circuits, execute them, and view the data.\n", 27 | "\n", 28 | "1. [Circuit basics](tutorials/circuits/01_circuit_basics.ipynb) - How to use the Qiskit quantum circuit.\n", 29 | "\n", 30 | "\n", 31 | "2. [Plotting data in Qiskit](tutorials/circuits/2_plotting_data_in_qiskit.ipynb) - Illustrates the different ways of plotting data in Qiskit.\n", 32 | "\n", 33 | "\n", 34 | "3. [Summary of quantum operations](tutorials/circuits/3_summary_of_quantum_operations.ipynb) - List of quantum operations (gates, reset, measurements) in Qiskit Terra\n", 35 | " \n", 36 | " \n", 37 | "## Advanced Circuits\n", 38 | "\n", 39 | "1. [Advanced circuits](tutorials/circuits_advanced/01_advanced_circuits.ipynb) - Circuit building tools added including registerless declarations, composite gate updates and parameterized circuits.\n", 40 | "\n", 41 | "\n", 42 | "2. [Operators overview](tutorials/circuits_advanced/02_operators_overview.ipynb) - Gives a summary of the features and uses of the Operator class.\n", 43 | "\n", 44 | "\n", 45 | "3. [Advanced circuit visualization](tutorials/circuits_advanced/03_advanced_circuit_visualization.ipynb) - Details on drawing your quantum circuits.\n", 46 | "\n", 47 | "\n", 48 | "4. [Transpiler passes and passmanager](tutorials/circuits_advanced/04_transpiler_passes_and_passmanager.ipynb) - How to use the transpiler passes, passmanger, and extend the transpiler with a new pass.\n", 49 | "\n", 50 | "\n", 51 | "## Pulse\n", 52 | "\n", 53 | "1. [Building pulse schedules](tutorials/circuits_advanced/06_building_pulse_schedules.ipynb) - Building schedules of pulses.\n", 54 | "\n", 55 | "\n", 56 | "2. [Pulse Scheduler](tutorials/circuits_advanced/07_pulse_scheduler.ipynb) - Scheduling pulse.\n", 57 | "\n", 58 | "\n", 59 | "3. [Getting system information](tutorials/circuits_advanced/08_gathering_system_information.ipynb) - Obtaining system information.\n", 60 | "\n", 61 | "\n", 62 | "4. [Pulse simulation](tutorials/circuits_advanced/09_pulse_simulator_duffing_model.ipynb) - Simulate a Duffing oscillator using the pulse simulator.\n", 63 | "\n", 64 | "\n", 65 | "## High-Performance Simulators\n", 66 | "\n", 67 | "To really speed up development of quantum computers, we need better simulators with the ability to model realistic noise processes that occur during computation on actual devices. Qiskit provides a high-performance simulator framework called `Aer` for studying quantum computing algorithms and applications in the noisy intermediate-scale quantum regime. \n", 68 | "\n", 69 | "1. [Simulators](tutorials/simulators/1_aer_provider.ipynb) - Gives a summary of the Qiskit Aer provider containing the Qasm, statevector, and unitary simulator.\n", 70 | "\n", 71 | "\n", 72 | "2. [Device noise simulation](tutorials/simulators/2_device_noise_simulation.ipynb) - Shows how to use the Qiskit Aer noise module to automatically generate a basic noise model for simulating hardware backends.\n", 73 | "\n", 74 | "\n", 75 | "3. [Building noise models](tutorials/simulators/3_building_noise_models.ipynb) - Shows how to use Qiskit Aer noise module to construct custom noise models for noisy simulations\n", 76 | "\n", 77 | "\n", 78 | "4. [Custom gate noise](tutorials/simulators/4_custom_gate_noise.ipynb) - Shows to implement simulations using custom noisy gates.\n", 79 | "\n", 80 | "\n", 81 | "5. [Noise transformations](tutorials/simulators/5_noise_transformation.ipynb) - Noise approximation utility functions to construct approximate Clifford noise models out of a general noise model\n", 82 | "\n", 83 | "\n", 84 | "6. [Extended stabilizer tutorial](tutorials/simulators/6_extended_stabilizer_tutorial.ipynb) - Gives an overview of the *extended stabilizer* Qasm Simulator method\n", 85 | "\n", 86 | "\n", 87 | "7. [Matrix Product State simulator](tutorials/simulators/7_matrix_product_state_method.ipynb) - Gives an overview of the *matrix product state* Simulator method\n", 88 | "\n", 89 | "\n", 90 | "## Quantum Device Noise Analysis\n", 91 | "\n", 92 | "This includes better characterization of errors, improving gates, and computing in the presence of noise. Qiskit `ignis` is meant for those who want to design quantum error correction codes, or who wish to study ways to characterize errors through methods such as tomography and randomized benchmarking, or even to find a better way for using gates by exploring dynamical decoupling and optimal control.\n", 93 | "\n", 94 | "1. [Hamiltonian and gate characterizations](tutorials/noise/1_hamiltonian_and_gate_characterization.ipynb) - Sequences to measure ZZ rates between qubits and to measure rotation and angle errors in the gates.\n", 95 | "\n", 96 | "\n", 97 | "2. [Relaxation and decoherence](tutorials/noise/2_relaxation_and_decoherence.ipynb) - How to measure coherence times on the real quantum hardware\n", 98 | "\n", 99 | "\n", 100 | "3. [Measurement error mitigation](tutorials/noise/3_measurement_error_mitigation.ipynb) - How to peform calibration experiments for measurement errors and fed those calibrations into a \"filter\" that can be utilized to mitigate errors in subsequent experiments.\n", 101 | "\n", 102 | "\n", 103 | "4. [Randomized benchmarking](tutorials/noise/4_randomized_benchmarking.ipynb) - Randomized benchmarking (RB) is a technique used to measure the average gate error by measuring the outcomes of random Clifford circuits. This is used internally to report gate errors on our systems. \n", 104 | "\n", 105 | "\n", 106 | "5. [Quantum volume](tutorials/noise/5_quantum_volume.ipynb) - How to run quantum volume measurements on the quantum hardware.\n", 107 | "\n", 108 | "\n", 109 | "6. [Repetition Code](tutorials/noise/6_repetition_code.ipynb) - How to run a simple error correction code, known as the repetition code. This can be used to characterize bit flip errors in the hardware.\n", 110 | "\n", 111 | "\n", 112 | "7. [Accreditation](tutorials/noise/7_accreditation.ipynb) - protocol devised to characterize the reliability of noisy quantum devices." 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 1, 118 | "metadata": { 119 | "ExecuteTime": { 120 | "end_time": "2019-08-09T15:31:26.743124Z", 121 | "start_time": "2019-08-09T15:31:26.732618Z" 122 | } 123 | }, 124 | "outputs": [ 125 | { 126 | "data": { 127 | "text/html": [ 128 | "

This code is a part of Qiskit

© Copyright IBM 2017, 2021.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.

" 129 | ], 130 | "text/plain": [ 131 | "" 132 | ] 133 | }, 134 | "metadata": {}, 135 | "output_type": "display_data" 136 | } 137 | ], 138 | "source": [ 139 | "import qiskit.tools.jupyter\n", 140 | "%qiskit_copyright" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": null, 146 | "metadata": {}, 147 | "outputs": [], 148 | "source": [] 149 | } 150 | ], 151 | "metadata": { 152 | "hide_input": false, 153 | "kernelspec": { 154 | "display_name": "Python 3", 155 | "language": "python", 156 | "name": "python3" 157 | }, 158 | "language_info": { 159 | "codemirror_mode": { 160 | "name": "ipython", 161 | "version": 3 162 | }, 163 | "file_extension": ".py", 164 | "mimetype": "text/x-python", 165 | "name": "python", 166 | "nbconvert_exporter": "python", 167 | "pygments_lexer": "ipython3", 168 | "version": "3.8.8" 169 | }, 170 | "varInspector": { 171 | "cols": { 172 | "lenName": 16, 173 | "lenType": 16, 174 | "lenVar": 40 175 | }, 176 | "kernels_config": { 177 | "python": { 178 | "delete_cmd_postfix": "", 179 | "delete_cmd_prefix": "del ", 180 | "library": "var_list.py", 181 | "varRefreshCmd": "print(var_dic_list())" 182 | }, 183 | "r": { 184 | "delete_cmd_postfix": ") ", 185 | "delete_cmd_prefix": "rm(", 186 | "library": "var_list.r", 187 | "varRefreshCmd": "cat(var_dic_list()) " 188 | } 189 | }, 190 | "types_to_exclude": [ 191 | "module", 192 | "function", 193 | "builtin_function_or_method", 194 | "instance", 195 | "_Feature" 196 | ], 197 | "window_display": false 198 | } 199 | }, 200 | "nbformat": 4, 201 | "nbformat_minor": 2 202 | } 203 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | minversion = 3.15 3 | envlist = py310,py39,py38 4 | 5 | [testenv] 6 | no_package = true 7 | install_command = pip install -c{toxinidir}/constraints.txt -U {opts} {packages} 8 | deps = 9 | -r{toxinidir}/requirements-dev.txt 10 | 11 | [testenv:docs] 12 | commands = 13 | sphinx-build -W --keep-going -j auto -b html {toxinidir} {toxinidir}/_build/html/ 14 | 15 | [testenv:docs-clean] 16 | deps = 17 | allowlist_externals = rm 18 | commands = rm -rf {toxinidir}/_build/ 19 | -------------------------------------------------------------------------------- /tutorials/algorithms/01_algorithms_introduction.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# An Introduction to Algorithms in Qiskit\n", 8 | "\n", 9 | "This is an introduction to algorithms in Qiskit and provides a high-level overview to help understand the various aspects of the functionality to get started. Other tutorials will provide more in-depth material, on given algorithms, and ways to use them etc." 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "## How is the algorithm library structured?\n", 17 | "\n", 18 | "Qiskit provides a number of [Algorithms](https://qiskit.org/documentation/apidoc/algorithms.html) and they are grouped by category according to the task they can perform. For instance [Minimum Eigensolvers](https://qiskit.org/documentation/stubs/qiskit.algorithms.minimum_eigensolvers.html#module-qiskit.algorithms.minimum_eigensolvers) to find the smallest eigen value of an operator, for example ground state energy of a chemistry Hamiltonian or a solution to an optimization problem when expressed as an Ising Hamiltonian. There are [Time Evolvers](https://qiskit.org/documentation/apidoc/algorithms.html#time-evolvers) for the time evolution of quantum systems and [Amplitude Estimators](https://qiskit.org/documentation/apidoc/algorithms.html#amplitude-estimators) for value estimation that can be used say in financial applications. The full set of categories can be seen in the Algorithms documentation link above.\n", 19 | "\n", 20 | "Algorithms are configurable and often part of the configuration will be in the form of smaller building blocks, of which different instances of the building block type can be given. For instance with [VQE](https://qiskit.org/documentation/stubs/qiskit.algorithms.minimum_eigensolvers.VQE.html#qiskit.algorithms.minimum_eigensolvers.VQE), the Variational Quantum Eigensolver, it takes a trial wavefunction, in the form of a [QuantumCircuit](https://qiskit.org/documentation/stubs/qiskit.circuit.QuantumCircuit.html#quantumcircuit) and a classical optimizer among other things.\n", 21 | "\n", 22 | "Let's take a look at an example to construct a VQE instance. Here [TwoLocal](https://qiskit.org/documentation/stubs/qiskit.circuit.library.TwoLocal.html#twolocal) is the variational form (trial wavefunction), a parameterized circuit which can be varied, and [SLSQP](https://qiskit.org/documentation/stubs/qiskit.algorithms.optimizers.SLSQP.html#slsqp) a classical optimizer. These are created as separate instances and passed to VQE when it is constructed. Trying, for example, a different classical optimizer, or variational form is simply a case of creating an instance of the one you want and passing it into VQE." 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 1, 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "from qiskit.algorithms.optimizers import SLSQP\n", 32 | "from qiskit.circuit.library import TwoLocal\n", 33 | "\n", 34 | "num_qubits = 2\n", 35 | "ansatz = TwoLocal(num_qubits, 'ry', 'cz')\n", 36 | "optimizer = SLSQP(maxiter=1000)" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "Let's draw the ansatz so we can see it's a [QuantumCircuit](https://qiskit.org/documentation/stubs/qiskit.circuit.QuantumCircuit.html#quantumcircuit) where θ\\[0\\] through θ\\[7\\] will be the parameters that are varied as VQE optimizer finds the minimum eigenvalue. We'll come back to the parameters later in a working example below." 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 2, 49 | "metadata": {}, 50 | "outputs": [ 51 | { 52 | "data": { 53 | "image/png": "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", 54 | "text/plain": [ 55 | "
" 56 | ] 57 | }, 58 | "execution_count": 2, 59 | "metadata": {}, 60 | "output_type": "execute_result" 61 | } 62 | ], 63 | "source": [ 64 | "ansatz.decompose().draw('mpl', style='iqx')" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "But more is needed before we can run the algorithm so let's get to that next." 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "## How to run an algorithm?\n", 79 | "\n", 80 | "Algorithms rely on the primitives to evaluate expectation values or sample circuits. The primitives can be based on a simulator or real device and can be used interchangeably in the algorithms, as they all implement the same interface.\n", 81 | "\n", 82 | "In the VQE, we have to evaluate expectation values, so for example we can use the [qiskit.primitives.Estimator](https://qiskit.org/documentation/stubs/qiskit.primitives.Estimator.html) which is shipped with the default Qiskit Terra installation." 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 3, 88 | "metadata": {}, 89 | "outputs": [], 90 | "source": [ 91 | "from qiskit.primitives import Estimator\n", 92 | "\n", 93 | "estimator = Estimator()" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "This estimator uses an exact, statevector simulation to evaluate the expectation values. We can also use a shot-based and noisy simulators or real backends instead. For more information of the simulators you can check out [Qiskit Aer](https://qiskit.org/ecosystem/aer/apidocs/aer_primitives.html) and for the actual hardware [Qiskit IBM Runtime](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/).\n", 101 | "\n", 102 | "With all the ingredients ready, we can now instantiate the VQE:" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 4, 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "from qiskit.algorithms.minimum_eigensolvers import VQE\n", 112 | "\n", 113 | "vqe = VQE(estimator, ansatz, optimizer)" 114 | ] 115 | }, 116 | { 117 | "cell_type": "markdown", 118 | "metadata": {}, 119 | "source": [ 120 | "Now we can call the [compute_mininum_eigenvalue()](https://qiskit.org/documentation/stubs/qiskit.algorithms.minimum_eigensolvers.VQE.compute_minimum_eigenvalue.html#qiskit.algorithms.minimum_eigensolvers.VQE.compute_minimum_eigenvalue) method. The latter is the interface of choice for the application modules, such as Nature and Optimization, in order that they can work interchangeably with any algorithm within the specific category." 121 | ] 122 | }, 123 | { 124 | "cell_type": "markdown", 125 | "metadata": {}, 126 | "source": [ 127 | "## A complete working example\n", 128 | "\n", 129 | "Let's put what we have learned from above together and create a complete working example. VQE will find the minimum eigenvalue, i.e. minimum energy value of a Hamiltonian operator and hence we need such an operator for VQE to work with. Such an operator is given below. This was originally created by the Nature application module as the Hamiltonian for an H2 molecule at 0.735A interatomic distance. It's a sum of Pauli terms as below, but for now I am not going to say anything further about it since the goal is to run the algorithm, but further information on operators can be found in other tutorials." 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 5, 135 | "metadata": {}, 136 | "outputs": [], 137 | "source": [ 138 | "from qiskit.quantum_info import SparsePauliOp\n", 139 | "\n", 140 | "H2_op = SparsePauliOp.from_list([\n", 141 | " (\"II\", -1.052373245772859),\n", 142 | " (\"IZ\", 0.39793742484318045),\n", 143 | " (\"ZI\", -0.39793742484318045),\n", 144 | " (\"ZZ\", -0.01128010425623538),\n", 145 | " (\"XX\", 0.18093119978423156)\n", 146 | "])" 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": {}, 152 | "source": [ 153 | "So let's run VQE and print the result object it returns." 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": 6, 159 | "metadata": { 160 | "scrolled": true 161 | }, 162 | "outputs": [ 163 | { 164 | "name": "stdout", 165 | "output_type": "stream", 166 | "text": [ 167 | "{ 'aux_operators_evaluated': None,\n", 168 | " 'cost_function_evals': 102,\n", 169 | " 'eigenvalue': -1.857275020719397,\n", 170 | " 'optimal_circuit': ,\n", 171 | " 'optimal_parameters': { ParameterVectorElement(θ[0]): -2.403507257619715,\n", 172 | " ParameterVectorElement(θ[5]): 1.7060524493254914,\n", 173 | " ParameterVectorElement(θ[1]): 3.085467047665086,\n", 174 | " ParameterVectorElement(θ[2]): -2.1949965223522487,\n", 175 | " ParameterVectorElement(θ[3]): 4.276089268519914,\n", 176 | " ParameterVectorElement(θ[4]): -3.098644972035885,\n", 177 | " ParameterVectorElement(θ[6]): 0.032773583818940334,\n", 178 | " ParameterVectorElement(θ[7]): 2.8861019033185396},\n", 179 | " 'optimal_point': array([-2.40350726, 3.08546705, -2.19499652, 4.27608927, -3.09864497,\n", 180 | " 1.70605245, 0.03277358, 2.8861019 ]),\n", 181 | " 'optimal_value': -1.857275020719397,\n", 182 | " 'optimizer_evals': None,\n", 183 | " 'optimizer_result': ,\n", 184 | " 'optimizer_time': 0.29071593284606934}\n" 185 | ] 186 | } 187 | ], 188 | "source": [ 189 | "result = vqe.compute_minimum_eigenvalue(H2_op)\n", 190 | "print(result)" 191 | ] 192 | }, 193 | { 194 | "cell_type": "markdown", 195 | "metadata": {}, 196 | "source": [ 197 | "From the above result we can see the number of cost function (=energy) evaluations the optimizer took until it found the minimum eigenvalue of $\\approx -1.85727$ which is the electronic ground state energy of the given H2 molecule. The optimal parameters of the ansatz can also be seen which are the values that were in the ansatz at the minimum value." 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": {}, 203 | "source": [ 204 | "## Updating the primitive inside VQE\n", 205 | "\n", 206 | "To close off let's also change the estimator primitive inside the a VQE. Maybe you're satisfied with the simulation results and now want to use a shot-based simulator, or run on hardware!\n", 207 | "\n", 208 | "In this example we're changing to a shot-based estimator, still using Qiskit Terra's reference primitive. However you could replace the primitive by e.g. Qiskit Aer's estimator ([qiskit_aer.primitives.Estimator](https://qiskit.org/ecosystem/aer/stubs/qiskit_aer.primitives.Estimator.html#qiskit_aer.primitives.Estimator)) or even a real backend ([qiskit_ibm_runtime.Estimator](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/stubs/qiskit_ibm_runtime.Estimator.html#qiskit_ibm_runtime.Estimator)).\n", 209 | "\n", 210 | "For noisy loss functions, the SPSA optimizer typically performs well, so we also update the optimizer. See also the [noisy VQE tutorial](https://qiskit.org/documentation/tutorials/algorithms/03_vqe_simulation_with_noise.html) for more details on shot-based and noisy simulations. " 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": 7, 216 | "metadata": {}, 217 | "outputs": [ 218 | { 219 | "name": "stdout", 220 | "output_type": "stream", 221 | "text": [ 222 | "{ 'aux_operators_evaluated': None,\n", 223 | " 'cost_function_evals': 200,\n", 224 | " 'eigenvalue': -1.8574503552440247,\n", 225 | " 'optimal_circuit': ,\n", 226 | " 'optimal_parameters': { ParameterVectorElement(θ[0]): -7.7940259581467375,\n", 227 | " ParameterVectorElement(θ[5]): 0.28827257835035214,\n", 228 | " ParameterVectorElement(θ[1]): -1.8091021117029589,\n", 229 | " ParameterVectorElement(θ[2]): -2.460381278734678,\n", 230 | " ParameterVectorElement(θ[3]): -7.725013961075425,\n", 231 | " ParameterVectorElement(θ[4]): -1.3793338621798832,\n", 232 | " ParameterVectorElement(θ[6]): -2.4148423942537587,\n", 233 | " ParameterVectorElement(θ[7]): -1.8555574263247812},\n", 234 | " 'optimal_point': array([-7.79402596, -1.80910211, -2.46038128, -7.72501396, -1.37933386,\n", 235 | " 0.28827258, -2.41484239, -1.85555743]),\n", 236 | " 'optimal_value': -1.8574503552440247,\n", 237 | " 'optimizer_evals': None,\n", 238 | " 'optimizer_result': ,\n", 239 | " 'optimizer_time': 0.8142139911651611}\n" 240 | ] 241 | } 242 | ], 243 | "source": [ 244 | "from qiskit.algorithms.optimizers import SPSA\n", 245 | "\n", 246 | "estimator = Estimator(options={\"shots\": 1000})\n", 247 | "\n", 248 | "vqe.estimator = estimator\n", 249 | "vqe.optimizer = SPSA(maxiter=100)\n", 250 | "result = vqe.compute_minimum_eigenvalue(operator=H2_op)\n", 251 | "print(result)" 252 | ] 253 | }, 254 | { 255 | "cell_type": "markdown", 256 | "metadata": {}, 257 | "source": [ 258 | "Note: We do not fix the random seed in the simulators here, so re-running gives slightly varying results." 259 | ] 260 | }, 261 | { 262 | "cell_type": "markdown", 263 | "metadata": {}, 264 | "source": [ 265 | "This concludes this introduction to algorithms in Qiskit. Please check out the other algorithm tutorials in this series for both broader as well as more in depth coverage of the algorithms." 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": 8, 271 | "metadata": {}, 272 | "outputs": [ 273 | { 274 | "data": { 275 | "text/html": [ 276 | "

Version Information

Qiskit SoftwareVersion
qiskit-terra0.23.0.dev0+f52bb33
qiskit-aer0.11.1
qiskit-ignis0.7.1
qiskit-ibmq-provider0.19.2
qiskit-nature0.5.0
qiskit-optimization0.5.0
qiskit-machine-learning0.6.0
System information
Python version3.10.4
Python compilerClang 12.0.0
Python buildmain, Mar 31 2022 03:38:35
OSDarwin
CPUs4
Memory (Gb)32.0
Wed Dec 07 11:02:26 2022 CET
" 277 | ], 278 | "text/plain": [ 279 | "" 280 | ] 281 | }, 282 | "metadata": {}, 283 | "output_type": "display_data" 284 | }, 285 | { 286 | "data": { 287 | "text/html": [ 288 | "

This code is a part of Qiskit

© Copyright IBM 2017, 2022.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.

" 289 | ], 290 | "text/plain": [ 291 | "" 292 | ] 293 | }, 294 | "metadata": {}, 295 | "output_type": "display_data" 296 | } 297 | ], 298 | "source": [ 299 | "import qiskit.tools.jupyter\n", 300 | "%qiskit_version_table\n", 301 | "%qiskit_copyright" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": null, 307 | "metadata": {}, 308 | "outputs": [], 309 | "source": [] 310 | } 311 | ], 312 | "metadata": { 313 | "kernelspec": { 314 | "display_name": "Python 3.10.6 ('venv': venv)", 315 | "language": "python", 316 | "name": "python3" 317 | }, 318 | "language_info": { 319 | "codemirror_mode": { 320 | "name": "ipython", 321 | "version": 3 322 | }, 323 | "file_extension": ".py", 324 | "mimetype": "text/x-python", 325 | "name": "python", 326 | "nbconvert_exporter": "python", 327 | "pygments_lexer": "ipython3", 328 | "version": "3.10.6" 329 | }, 330 | "vscode": { 331 | "interpreter": { 332 | "hash": "f8729fd834348017bca17aea688b306f536a675180840f7307eb909fff39c285" 333 | } 334 | } 335 | }, 336 | "nbformat": 4, 337 | "nbformat_minor": 2 338 | } 339 | -------------------------------------------------------------------------------- /tutorials/algorithms/05_qaoa.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Quantum Approximate Optimization Algorithm \n", 8 | "\n", 9 | "Qiskit has an implementation of the Quantum Approximate Optimization Algorithm [QAOA](https://qiskit.org/documentation/stubs/qiskit.algorithms.minimum_eigensolvers.QAOA.html) and this notebook demonstrates using it for a graph partition problem.\n", 10 | "\n", 11 | "Before we begin, let's import the `annotations` module from `__future__` to allow postponed evaluation of annotations. This enables us to use simpler type hints throughout the notebook." 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 1, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "from __future__ import annotations" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "First we create a graph and draw it so it can be seen." 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 2, 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "import numpy as np\n", 37 | "import networkx as nx\n", 38 | "\n", 39 | "num_nodes = 4\n", 40 | "w = np.array([[0., 1., 1., 0.],\n", 41 | " [1., 0., 1., 1.],\n", 42 | " [1., 1., 0., 1.],\n", 43 | " [0., 1., 1., 0.]])\n", 44 | "G = nx.from_numpy_array(w)" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 3, 50 | "metadata": { 51 | "scrolled": true, 52 | "tags": [ 53 | "nbsphinx-thumbnail" 54 | ] 55 | }, 56 | "outputs": [ 57 | { 58 | "data": { 59 | "image/png": "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\n", 60 | "text/plain": [ 61 | "
" 62 | ] 63 | }, 64 | "metadata": {}, 65 | "output_type": "display_data" 66 | } 67 | ], 68 | "source": [ 69 | "layout = nx.random_layout(G, seed=10)\n", 70 | "colors = ['r', 'g', 'b', 'y']\n", 71 | "nx.draw(G, layout, node_color=colors)\n", 72 | "labels = nx.get_edge_attributes(G, 'weight')\n", 73 | "nx.draw_networkx_edge_labels(G, pos=layout, edge_labels=labels);" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "The brute-force method is as follows. Basically, we exhaustively try all the binary assignments. In each binary assignment, the entry of a vertex is either 0 (meaning the vertex is in the first partition) or 1 (meaning the vertex is in the second partition). We print the binary assignment that satisfies the definition of the graph partition and corresponds to the minimal number of crossing edges." 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 4, 86 | "metadata": {}, 87 | "outputs": [ 88 | { 89 | "name": "stdout", 90 | "output_type": "stream", 91 | "text": [ 92 | "Objective value computed by the brute-force method is 3\n" 93 | ] 94 | } 95 | ], 96 | "source": [ 97 | "def objective_value(x: np.ndarray, w: np.ndarray) -> float:\n", 98 | " \"\"\"Compute the value of a cut.\n", 99 | " Args:\n", 100 | " x: Binary string as numpy array.\n", 101 | " w: Adjacency matrix.\n", 102 | " Returns:\n", 103 | " Value of the cut.\n", 104 | " \"\"\"\n", 105 | " X = np.outer(x, (1 - x))\n", 106 | " w_01 = np.where(w != 0, 1, 0)\n", 107 | " return np.sum(w_01 * X)\n", 108 | "\n", 109 | "def bitfield(n: int, L: int) -> list[int]:\n", 110 | " result = np.binary_repr(n, L)\n", 111 | " return [int(digit) for digit in result] # [2:] to chop off the \"0b\" part\n", 112 | "\n", 113 | "# use the brute-force way to generate the oracle\n", 114 | "L = num_nodes\n", 115 | "max = 2**L\n", 116 | "sol = np.inf\n", 117 | "for i in range(max):\n", 118 | " cur = bitfield(i, L)\n", 119 | "\n", 120 | " how_many_nonzero = np.count_nonzero(cur)\n", 121 | " if how_many_nonzero * 2 != L: # not balanced\n", 122 | " continue\n", 123 | "\n", 124 | " cur_v = objective_value(np.array(cur), w)\n", 125 | " if cur_v < sol:\n", 126 | " sol = cur_v\n", 127 | "\n", 128 | "print(f'Objective value computed by the brute-force method is {sol}')" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": {}, 134 | "source": [ 135 | "The graph partition problem can be converted to an Ising Hamiltonian. Qiskit has different capabilities in the Optimization module to do this. Here, since the goal is to show QAOA, the module is used without further explanation to create the operator. The paper [Ising formulations of many NP problems](https://arxiv.org/abs/1302.5843) may be of interest if you would like to understand the technique further." 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": 5, 141 | "metadata": {}, 142 | "outputs": [], 143 | "source": [ 144 | "from qiskit.quantum_info import Pauli, SparsePauliOp\n", 145 | "\n", 146 | "def get_operator(weight_matrix: np.ndarray) -> tuple[SparsePauliOp, float]:\n", 147 | " r\"\"\"Generate Hamiltonian for the graph partitioning\n", 148 | " Notes:\n", 149 | " Goals:\n", 150 | " 1 Separate the vertices into two set of the same size.\n", 151 | " 2 Make sure the number of edges between the two set is minimized.\n", 152 | " Hamiltonian:\n", 153 | " H = H_A + H_B\n", 154 | " H_A = sum\\_{(i,j)\\in E}{(1-ZiZj)/2}\n", 155 | " H_B = (sum_{i}{Zi})^2 = sum_{i}{Zi^2}+sum_{i!=j}{ZiZj}\n", 156 | " H_A is for achieving goal 2 and H_B is for achieving goal 1.\n", 157 | " Args:\n", 158 | " weight_matrix: Adjacency matrix.\n", 159 | " Returns:\n", 160 | " Operator for the Hamiltonian\n", 161 | " A constant shift for the obj function.\n", 162 | " \"\"\"\n", 163 | " num_nodes = len(weight_matrix)\n", 164 | " pauli_list = []\n", 165 | " coeffs = []\n", 166 | " shift = 0\n", 167 | "\n", 168 | " for i in range(num_nodes):\n", 169 | " for j in range(i):\n", 170 | " if weight_matrix[i, j] != 0:\n", 171 | " x_p = np.zeros(num_nodes, dtype=bool)\n", 172 | " z_p = np.zeros(num_nodes, dtype=bool)\n", 173 | " z_p[i] = True\n", 174 | " z_p[j] = True\n", 175 | " pauli_list.append(Pauli((z_p, x_p)))\n", 176 | " coeffs.append(-0.5)\n", 177 | " shift += 0.5\n", 178 | "\n", 179 | " for i in range(num_nodes):\n", 180 | " for j in range(num_nodes):\n", 181 | " if i != j:\n", 182 | " x_p = np.zeros(num_nodes, dtype=bool)\n", 183 | " z_p = np.zeros(num_nodes, dtype=bool)\n", 184 | " z_p[i] = True\n", 185 | " z_p[j] = True\n", 186 | " pauli_list.append(Pauli((z_p, x_p)))\n", 187 | " coeffs.append(1.0)\n", 188 | " else:\n", 189 | " shift += 1\n", 190 | " \n", 191 | " return SparsePauliOp(pauli_list, coeffs=coeffs), shift\n", 192 | "\n", 193 | "qubit_op, offset = get_operator(w)" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "So lets use the QAOA algorithm to find the solution." 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 6, 206 | "metadata": {}, 207 | "outputs": [ 208 | { 209 | "name": "stdout", 210 | "output_type": "stream", 211 | "text": [ 212 | "[1 1 0 0]\n", 213 | "Objective value computed by QAOA is 3\n" 214 | ] 215 | } 216 | ], 217 | "source": [ 218 | "from qiskit.algorithms.minimum_eigensolvers import QAOA\n", 219 | "from qiskit.algorithms.optimizers import COBYLA\n", 220 | "from qiskit.circuit.library import TwoLocal\n", 221 | "from qiskit.primitives import Sampler\n", 222 | "from qiskit.quantum_info import Pauli, Statevector\n", 223 | "from qiskit.result import QuasiDistribution\n", 224 | "from qiskit.utils import algorithm_globals\n", 225 | "\n", 226 | "sampler = Sampler()\n", 227 | "\n", 228 | "\n", 229 | "def sample_most_likely(state_vector: QuasiDistribution | Statevector) -> np.ndarray:\n", 230 | " \"\"\"Compute the most likely binary string from state vector.\n", 231 | " Args:\n", 232 | " state_vector: State vector or quasi-distribution.\n", 233 | "\n", 234 | " Returns:\n", 235 | " Binary string as an array of ints.\n", 236 | " \"\"\"\n", 237 | " if isinstance(state_vector, QuasiDistribution):\n", 238 | " values = list(state_vector.values())\n", 239 | " else:\n", 240 | " values = state_vector\n", 241 | " n = int(np.log2(len(values)))\n", 242 | " k = np.argmax(np.abs(values))\n", 243 | " x = bitfield(k, n)\n", 244 | " x.reverse()\n", 245 | " return np.asarray(x)\n", 246 | "\n", 247 | "algorithm_globals.random_seed = 10598\n", 248 | "\n", 249 | "optimizer = COBYLA()\n", 250 | "qaoa = QAOA(sampler, optimizer, reps=2)\n", 251 | "\n", 252 | "result = qaoa.compute_minimum_eigenvalue(qubit_op)\n", 253 | "\n", 254 | "x = sample_most_likely(result.eigenstate)\n", 255 | "\n", 256 | "print(x)\n", 257 | "print(f'Objective value computed by QAOA is {objective_value(x, w)}')" 258 | ] 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "metadata": {}, 263 | "source": [ 264 | "The outcome can be seen to match to the value computed above by brute force. But we can also use the classical `NumPyMinimumEigensolver` to do the computation, which may be useful as a reference without doing things by brute force." 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": 7, 270 | "metadata": {}, 271 | "outputs": [ 272 | { 273 | "name": "stdout", 274 | "output_type": "stream", 275 | "text": [ 276 | "[1 1 0 0]\n", 277 | "Objective value computed by the NumPyMinimumEigensolver is 3\n" 278 | ] 279 | } 280 | ], 281 | "source": [ 282 | "from qiskit.algorithms.minimum_eigensolvers import NumPyMinimumEigensolver\n", 283 | "from qiskit.quantum_info import Operator\n", 284 | "\n", 285 | "npme = NumPyMinimumEigensolver()\n", 286 | "result = npme.compute_minimum_eigenvalue(Operator(qubit_op))\n", 287 | "\n", 288 | "x = sample_most_likely(result.eigenstate)\n", 289 | "\n", 290 | "print(x)\n", 291 | "print(f'Objective value computed by the NumPyMinimumEigensolver is {objective_value(x, w)}')" 292 | ] 293 | }, 294 | { 295 | "cell_type": "markdown", 296 | "metadata": {}, 297 | "source": [ 298 | "It is also possible to use VQE as is shown below" 299 | ] 300 | }, 301 | { 302 | "cell_type": "code", 303 | "execution_count": 8, 304 | "metadata": {}, 305 | "outputs": [ 306 | { 307 | "name": "stdout", 308 | "output_type": "stream", 309 | "text": [ 310 | "[0 1 0 1]\n", 311 | "Objective value computed by VQE is 3\n" 312 | ] 313 | } 314 | ], 315 | "source": [ 316 | "from qiskit.algorithms.minimum_eigensolvers import SamplingVQE\n", 317 | "from qiskit.circuit.library import TwoLocal\n", 318 | "from qiskit.utils import algorithm_globals\n", 319 | "\n", 320 | "algorithm_globals.random_seed = 10598\n", 321 | "\n", 322 | "optimizer = COBYLA()\n", 323 | "ansatz = TwoLocal(qubit_op.num_qubits, \"ry\", \"cz\", reps=2, entanglement=\"linear\")\n", 324 | "sampling_vqe = SamplingVQE(sampler, ansatz, optimizer)\n", 325 | "\n", 326 | "result = sampling_vqe.compute_minimum_eigenvalue(qubit_op)\n", 327 | "\n", 328 | "x = sample_most_likely(result.eigenstate)\n", 329 | "\n", 330 | "print(x)\n", 331 | "print(f\"Objective value computed by VQE is {objective_value(x, w)}\")\n" 332 | ] 333 | }, 334 | { 335 | "cell_type": "code", 336 | "execution_count": 9, 337 | "metadata": {}, 338 | "outputs": [ 339 | { 340 | "data": { 341 | "text/html": [ 342 | "

Version Information

Qiskit SoftwareVersion
qiskit-terra0.23.0
qiskit-aer0.11.1
qiskit-nature0.6.0
qiskit-finance0.4.0
qiskit-optimization0.5.0
qiskit-machine-learning0.6.0
System information
Python version3.9.13
Python compilerClang 13.0.1
Python buildmain, May 27 2022 17:01:00
OSDarwin
CPUs2
Memory (Gb)12.0
Sun Jan 08 11:35:33 2023 EST
" 343 | ], 344 | "text/plain": [ 345 | "" 346 | ] 347 | }, 348 | "metadata": {}, 349 | "output_type": "display_data" 350 | }, 351 | { 352 | "data": { 353 | "text/html": [ 354 | "

This code is a part of Qiskit

© Copyright IBM 2017, 2023.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.

" 355 | ], 356 | "text/plain": [ 357 | "" 358 | ] 359 | }, 360 | "metadata": {}, 361 | "output_type": "display_data" 362 | } 363 | ], 364 | "source": [ 365 | "import qiskit.tools.jupyter\n", 366 | "%qiskit_version_table\n", 367 | "%qiskit_copyright" 368 | ] 369 | } 370 | ], 371 | "metadata": { 372 | "kernelspec": { 373 | "display_name": "Python 3", 374 | "language": "python", 375 | "name": "python3" 376 | }, 377 | "language_info": { 378 | "codemirror_mode": { 379 | "name": "ipython", 380 | "version": 3 381 | }, 382 | "file_extension": ".py", 383 | "mimetype": "text/x-python", 384 | "name": "python", 385 | "nbconvert_exporter": "python", 386 | "pygments_lexer": "ipython3", 387 | "version": "3.9.13" 388 | }, 389 | "vscode": { 390 | "interpreter": { 391 | "hash": "0becea4cb9c4294abbba7f0b15d5de98241be600556705f5379b48b9de7cb1f9" 392 | } 393 | } 394 | }, 395 | "nbformat": 4, 396 | "nbformat_minor": 2 397 | } 398 | -------------------------------------------------------------------------------- /tutorials/algorithms/07_grover_examples.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Grover's algorithm examples\n", 8 | "\n", 9 | "This notebook has examples demonstrating how to use the Qiskit [Grover](https://qiskit.org/documentation/stubs/qiskit.algorithms.Grover.html) search algorithm, with different oracles." 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "## Finding solutions to 3-SAT problems\n", 17 | "\n", 18 | "Let's look at an example 3-Satisfiability (3-SAT) problem and walk-through how we can use Quantum Search to find its satisfying solutions. 3-SAT problems are usually expressed in [Conjunctive Normal Forms (CNF)](https://en.wikipedia.org/wiki/Conjunctive_normal_form) and written in the [DIMACS-CNF](http://www.satcompetition.org/2009/format-benchmarks2009.html) format. For example:" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 1, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "input_3sat_instance = '''\n", 28 | "c example DIMACS-CNF 3-SAT\n", 29 | "p cnf 3 5\n", 30 | "-1 -2 -3 0\n", 31 | "1 -2 3 0\n", 32 | "1 2 -3 0\n", 33 | "1 -2 -3 0\n", 34 | "-1 2 3 0\n", 35 | "'''" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "The CNF of this 3-SAT instance contains 3 variables and 5 clauses:\n", 43 | "\n", 44 | "$(\\neg v_1 \\vee \\neg v_2 \\vee \\neg v_3) \\wedge (v_1 \\vee \\neg v_2 \\vee v_3) \\wedge (v_1 \\vee v_2 \\vee \\neg v_3) \\wedge (v_1 \\vee \\neg v_2 \\vee \\neg v_3) \\wedge (\\neg v_1 \\vee v_2 \\vee v_3)$\n", 45 | "\n", 46 | "It can be verified that this 3-SAT problem instance has three satisfying solutions:\n", 47 | "\n", 48 | "$(v_1, v_2, v_3) = (T, F, T)$ or $(F, F, F)$ or $(T, T, F)$\n", 49 | "\n", 50 | "Or, expressed using the DIMACS notation:\n", 51 | "\n", 52 | "`1 -2 3`, or `-1 -2 -3`, or `1 2 -3`.\n", 53 | "\n", 54 | "With this example problem input, we then create the corresponding `oracle` for our `Grover` search. In particular, we use the `PhaseOracle` component, which supports parsing DIMACS-CNF format strings and constructing the corresponding oracle circuit." 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 2, 60 | "metadata": {}, 61 | "outputs": [ 62 | { 63 | "name": "stdout", 64 | "output_type": "stream", 65 | "text": [ 66 | "\"The 'tweedledum' library is required to use 'classical function oracles'. You can install it with 'pip install tweedledum'.\"\n" 67 | ] 68 | } 69 | ], 70 | "source": [ 71 | "import os\n", 72 | "import tempfile\n", 73 | "from qiskit.exceptions import MissingOptionalLibraryError\n", 74 | "from qiskit.circuit.library.phase_oracle import PhaseOracle\n", 75 | "\n", 76 | "\n", 77 | "fp = tempfile.NamedTemporaryFile(mode='w+t', delete=False)\n", 78 | "fp.write(input_3sat_instance)\n", 79 | "file_name = fp.name\n", 80 | "fp.close()\n", 81 | "oracle = None\n", 82 | "try:\n", 83 | " oracle = PhaseOracle.from_dimacs_file(file_name)\n", 84 | "except ImportError as ex:\n", 85 | " print(ex)\n", 86 | "finally:\n", 87 | " os.remove(file_name)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "The `oracle` can now be used to create an Grover instance:" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 3, 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [ 103 | "from qiskit.algorithms import AmplificationProblem\n", 104 | "\n", 105 | "problem = None\n", 106 | "if oracle is not None:\n", 107 | " problem = AmplificationProblem(oracle, is_good_state=oracle.evaluate_bitstring)" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "We can then configure the backend and run the Grover instance to get the result:" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": 4, 120 | "metadata": {}, 121 | "outputs": [], 122 | "source": [ 123 | "from qiskit.algorithms import Grover\n", 124 | "from qiskit.primitives import Sampler\n", 125 | "\n", 126 | "grover = Grover(sampler=Sampler())\n", 127 | "result = None\n", 128 | "if problem is not None:\n", 129 | " result = grover.amplify(problem)\n", 130 | " print(result.assignment)" 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": {}, 136 | "source": [ 137 | "As seen above, a satisfying solution to the specified 3-SAT problem is obtained. And it is indeed one of the three satisfying solutions.\n", 138 | "\n", 139 | "Since we used the `Sampler`, the complete measurement result is also returned, as shown in the plot below, where it can be seen that the binary strings `000`, `011`, and `101` (note the bit order in each string), corresponding to the three satisfying solutions all have high probabilities associated with them." 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 5, 145 | "metadata": {}, 146 | "outputs": [], 147 | "source": [ 148 | "from qiskit.tools.visualization import plot_histogram\n", 149 | "\n", 150 | "if result is not None:\n", 151 | " display(plot_histogram(result.circuit_results[0]))" 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "metadata": {}, 157 | "source": [ 158 | "## Boolean Logical Expressions\n", 159 | "\n", 160 | "Qiskit's `Grover` can also be used to perform Quantum Search on an `Oracle` constructed from other means, in addition to DIMACS. For example, the `PhaseOracle` can actually be configured using arbitrary Boolean logical expressions, as demonstrated below." 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": 6, 166 | "metadata": {}, 167 | "outputs": [ 168 | { 169 | "name": "stdout", 170 | "output_type": "stream", 171 | "text": [ 172 | "\"The 'tweedledum' library is required to use 'PhaseOracle'. You can install it with 'pip install tweedledum'.\"\n" 173 | ] 174 | } 175 | ], 176 | "source": [ 177 | "expression = '(w ^ x) & ~(y ^ z) & (x & y & z)'\n", 178 | "try:\n", 179 | " oracle = PhaseOracle(expression)\n", 180 | " problem = AmplificationProblem(oracle, is_good_state=oracle.evaluate_bitstring)\n", 181 | " grover = Grover(sampler=Sampler())\n", 182 | " result = grover.amplify(problem)\n", 183 | " display(plot_histogram(result.circuit_results[0]))\n", 184 | "except MissingOptionalLibraryError as ex:\n", 185 | " print(ex)" 186 | ] 187 | }, 188 | { 189 | "cell_type": "markdown", 190 | "metadata": {}, 191 | "source": [ 192 | "In the example above, the input Boolean logical expression `'(w ^ x) & ~(y ^ z) & (x & y & z)'` should be quite self-explanatory, where `^`, `~`, and `&` represent the Boolean logical XOR, NOT, and AND operators, respectively. It should be quite easy to figure out the satisfying solution by examining its parts: `w ^ x` calls for `w` and `x` taking different values; `~(y ^ z)` requires `y` and `z` be the same; `x & y & z` dictates all three to be `True`. Putting these together, we get the satisfying solution `(w, x, y, z) = (False, True, True, True)`, which our `Grover`'s result agrees with." 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": 7, 198 | "metadata": {}, 199 | "outputs": [ 200 | { 201 | "data": { 202 | "text/html": [ 203 | "

Version Information

Qiskit SoftwareVersion
qiskit-terra0.23.3
qiskit-aer0.12.0
qiskit-ibmq-provider0.20.2
qiskit0.42.1
System information
Python version3.10.10
Python compilerGCC 12.2.1 20230201
Python buildmain, Mar 5 2023 22:26:53
OSLinux
CPUs32
Memory (Gb)125.66083908081055
Thu May 04 15:38:15 2023 EDT
" 204 | ], 205 | "text/plain": [ 206 | "" 207 | ] 208 | }, 209 | "metadata": {}, 210 | "output_type": "display_data" 211 | }, 212 | { 213 | "data": { 214 | "text/html": [ 215 | "

This code is a part of Qiskit

© Copyright IBM 2017, 2023.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.

" 216 | ], 217 | "text/plain": [ 218 | "" 219 | ] 220 | }, 221 | "metadata": {}, 222 | "output_type": "display_data" 223 | } 224 | ], 225 | "source": [ 226 | "import qiskit.tools.jupyter\n", 227 | "%qiskit_version_table\n", 228 | "%qiskit_copyright" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "execution_count": null, 234 | "metadata": {}, 235 | "outputs": [], 236 | "source": [] 237 | } 238 | ], 239 | "metadata": { 240 | "kernelspec": { 241 | "display_name": "Python 3 (ipykernel)", 242 | "language": "python", 243 | "name": "python3" 244 | }, 245 | "language_info": { 246 | "codemirror_mode": { 247 | "name": "ipython", 248 | "version": 3 249 | }, 250 | "file_extension": ".py", 251 | "mimetype": "text/x-python", 252 | "name": "python", 253 | "nbconvert_exporter": "python", 254 | "pygments_lexer": "ipython3", 255 | "version": "3.10.10" 256 | }, 257 | "vscode": { 258 | "interpreter": { 259 | "hash": "4213929014e7aa4f7c83ab6e8b511ecef456337e6cdcd5a9f1a6614ced2a54b2" 260 | } 261 | } 262 | }, 263 | "nbformat": 4, 264 | "nbformat_minor": 2 265 | } 266 | -------------------------------------------------------------------------------- /tutorials/circuits_advanced/02_operators_overview.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Operators" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "ExecuteTime": { 15 | "end_time": "2019-08-21T09:02:56.554914Z", 16 | "start_time": "2019-08-21T09:02:54.249612Z" 17 | } 18 | }, 19 | "outputs": [], 20 | "source": [ 21 | "import numpy as np\n", 22 | "\n", 23 | "from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister\n", 24 | "from qiskit import BasicAer\n", 25 | "from qiskit.compiler import transpile\n", 26 | "from qiskit.quantum_info.operators import Operator, Pauli\n", 27 | "from qiskit.quantum_info import process_fidelity\n", 28 | "\n", 29 | "from qiskit.extensions import RXGate, XGate, CXGate" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "## Operator Class\n", 37 | "\n", 38 | "The `Operator` class is used in Qiskit to represent matrix operators acting on a quantum system. It has several methods to build composite operators using tensor products of smaller operators, and to compose operators.\n", 39 | "\n", 40 | "### Creating Operators\n", 41 | "\n", 42 | "The easiest way to create an operator object is to initialize it with a matrix given as a list or a Numpy array. For example, to create a two-qubit Pauli-XX operator:" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 2, 48 | "metadata": { 49 | "ExecuteTime": { 50 | "end_time": "2019-08-21T09:02:56.572857Z", 51 | "start_time": "2019-08-21T09:02:56.566140Z" 52 | } 53 | }, 54 | "outputs": [ 55 | { 56 | "data": { 57 | "text/plain": [ 58 | "Operator([[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],\n", 59 | " [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],\n", 60 | " [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],\n", 61 | " [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]],\n", 62 | " input_dims=(2, 2), output_dims=(2, 2))" 63 | ] 64 | }, 65 | "execution_count": 2, 66 | "metadata": {}, 67 | "output_type": "execute_result" 68 | } 69 | ], 70 | "source": [ 71 | "XX = Operator([[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]])\n", 72 | "XX" 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": {}, 78 | "source": [ 79 | "### Operator Properties\n", 80 | "\n", 81 | "The operator object stores the underlying matrix, and the input and output dimension of subsystems. \n", 82 | "\n", 83 | "* `data`: To access the underlying Numpy array, we may use the `Operator.data` property.\n", 84 | "* `dims`: To return the total input and output dimension of the operator, we may use the `Operator.dim` property. *Note: the output is returned as a tuple* `(input_dim, output_dim)`, *which is the reverse of the shape of the underlying matrix.*" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 3, 90 | "metadata": { 91 | "ExecuteTime": { 92 | "end_time": "2019-08-21T09:02:56.589962Z", 93 | "start_time": "2019-08-21T09:02:56.585681Z" 94 | } 95 | }, 96 | "outputs": [ 97 | { 98 | "data": { 99 | "text/plain": [ 100 | "array([[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],\n", 101 | " [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],\n", 102 | " [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],\n", 103 | " [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]])" 104 | ] 105 | }, 106 | "execution_count": 3, 107 | "metadata": {}, 108 | "output_type": "execute_result" 109 | } 110 | ], 111 | "source": [ 112 | "XX.data" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 4, 118 | "metadata": { 119 | "ExecuteTime": { 120 | "end_time": "2019-08-21T09:02:56.615497Z", 121 | "start_time": "2019-08-21T09:02:56.611146Z" 122 | } 123 | }, 124 | "outputs": [ 125 | { 126 | "data": { 127 | "text/plain": [ 128 | "(4, 4)" 129 | ] 130 | }, 131 | "execution_count": 4, 132 | "metadata": {}, 133 | "output_type": "execute_result" 134 | } 135 | ], 136 | "source": [ 137 | "input_dim, output_dim = XX.dim\n", 138 | "input_dim, output_dim" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": {}, 144 | "source": [ 145 | "### Input and Output Dimensions\n", 146 | "\n", 147 | "The operator class also keeps track of subsystem dimensions, which can be used for composing operators together. These can be accessed using the `input_dims` and `output_dims` functions.\n", 148 | "\n", 149 | "For $2^N$ by $2^M$ operators, the input and output dimension will be automatically assumed to be M-qubit and N-qubit:" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 5, 155 | "metadata": { 156 | "ExecuteTime": { 157 | "end_time": "2019-08-21T09:02:56.804167Z", 158 | "start_time": "2019-08-21T09:02:56.798857Z" 159 | } 160 | }, 161 | "outputs": [ 162 | { 163 | "name": "stdout", 164 | "output_type": "stream", 165 | "text": [ 166 | "Input dimensions: (2, 2)\n", 167 | "Output dimensions: (2,)\n" 168 | ] 169 | } 170 | ], 171 | "source": [ 172 | "op = Operator(np.random.rand(2 ** 1, 2 ** 2))\n", 173 | "print('Input dimensions:', op.input_dims())\n", 174 | "print('Output dimensions:', op.output_dims())" 175 | ] 176 | }, 177 | { 178 | "cell_type": "markdown", 179 | "metadata": {}, 180 | "source": [ 181 | "If the input matrix is not divisible into qubit subsystems, then it will be stored as a single-qubit operator. For example, if we have a $6\\times6$ matrix:" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 6, 187 | "metadata": { 188 | "ExecuteTime": { 189 | "end_time": "2019-08-21T09:02:57.764881Z", 190 | "start_time": "2019-08-21T09:02:57.760401Z" 191 | } 192 | }, 193 | "outputs": [ 194 | { 195 | "name": "stdout", 196 | "output_type": "stream", 197 | "text": [ 198 | "Input dimensions: (6,)\n", 199 | "Output dimensions: (6,)\n" 200 | ] 201 | } 202 | ], 203 | "source": [ 204 | "op = Operator(np.random.rand(6, 6))\n", 205 | "print('Input dimensions:', op.input_dims())\n", 206 | "print('Output dimensions:', op.output_dims())" 207 | ] 208 | }, 209 | { 210 | "cell_type": "markdown", 211 | "metadata": {}, 212 | "source": [ 213 | "The input and output dimension can also be manually specified when initializing a new operator:" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": 7, 219 | "metadata": { 220 | "ExecuteTime": { 221 | "end_time": "2019-08-21T09:02:58.292849Z", 222 | "start_time": "2019-08-21T09:02:58.287354Z" 223 | } 224 | }, 225 | "outputs": [ 226 | { 227 | "name": "stdout", 228 | "output_type": "stream", 229 | "text": [ 230 | "Input dimensions: (4,)\n", 231 | "Output dimensions: (2,)\n" 232 | ] 233 | } 234 | ], 235 | "source": [ 236 | "# Force input dimension to be (4,) rather than (2, 2)\n", 237 | "op = Operator(np.random.rand(2 ** 1, 2 ** 2), input_dims=[4])\n", 238 | "print('Input dimensions:', op.input_dims())\n", 239 | "print('Output dimensions:', op.output_dims())" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 8, 245 | "metadata": { 246 | "ExecuteTime": { 247 | "end_time": "2019-08-21T09:02:58.779572Z", 248 | "start_time": "2019-08-21T09:02:58.774878Z" 249 | } 250 | }, 251 | "outputs": [ 252 | { 253 | "name": "stdout", 254 | "output_type": "stream", 255 | "text": [ 256 | "Input dimensions: (2, 3)\n", 257 | "Output dimensions: (2, 3)\n" 258 | ] 259 | } 260 | ], 261 | "source": [ 262 | "# Specify system is a qubit and qutrit\n", 263 | "op = Operator(np.random.rand(6, 6),\n", 264 | " input_dims=[2, 3], output_dims=[2, 3])\n", 265 | "print('Input dimensions:', op.input_dims())\n", 266 | "print('Output dimensions:', op.output_dims())" 267 | ] 268 | }, 269 | { 270 | "cell_type": "markdown", 271 | "metadata": {}, 272 | "source": [ 273 | "We can also extract just the input or output dimensions of a subset of subsystems using the `input_dims` and `output_dims` functions:" 274 | ] 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": 9, 279 | "metadata": { 280 | "ExecuteTime": { 281 | "end_time": "2019-08-21T09:03:02.187313Z", 282 | "start_time": "2019-08-21T09:03:02.183719Z" 283 | } 284 | }, 285 | "outputs": [ 286 | { 287 | "name": "stdout", 288 | "output_type": "stream", 289 | "text": [ 290 | "Dimension of input system 0: (2,)\n", 291 | "Dimension of input system 1: (3,)\n" 292 | ] 293 | } 294 | ], 295 | "source": [ 296 | "print('Dimension of input system 0:', op.input_dims([0]))\n", 297 | "print('Dimension of input system 1:', op.input_dims([1]))" 298 | ] 299 | }, 300 | { 301 | "cell_type": "markdown", 302 | "metadata": {}, 303 | "source": [ 304 | "## Converting classes to Operators\n", 305 | "\n", 306 | "Several other classes in Qiskit can be directly converted to an `Operator` object using the operator initialization method. For example:\n", 307 | "\n", 308 | "* `Pauli` objects\n", 309 | "* `Gate` and `Instruction` objects\n", 310 | "* `QuantumCircuit` objects\n", 311 | "\n", 312 | "Note that the last point means we can use the `Operator` class as a unitary simulator to compute the final unitary matrix for a quantum circuit, without having to call a simulator backend. If the circuit contains any unsupported operations, an exception will be raised. Unsupported operations are: measure, reset, conditional operations, or a gate that does not have a matrix definition or decomposition in terms of gate with matrix definitions." 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": 10, 318 | "metadata": { 319 | "ExecuteTime": { 320 | "end_time": "2019-08-21T09:03:02.854419Z", 321 | "start_time": "2019-08-21T09:03:02.842387Z" 322 | } 323 | }, 324 | "outputs": [ 325 | { 326 | "data": { 327 | "text/plain": [ 328 | "Operator([[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],\n", 329 | " [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],\n", 330 | " [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],\n", 331 | " [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]],\n", 332 | " input_dims=(2, 2), output_dims=(2, 2))" 333 | ] 334 | }, 335 | "execution_count": 10, 336 | "metadata": {}, 337 | "output_type": "execute_result" 338 | } 339 | ], 340 | "source": [ 341 | "# Create an Operator from a Pauli object\n", 342 | "\n", 343 | "pauliXX = Pauli('XX')\n", 344 | "Operator(pauliXX)" 345 | ] 346 | }, 347 | { 348 | "cell_type": "code", 349 | "execution_count": 11, 350 | "metadata": { 351 | "ExecuteTime": { 352 | "end_time": "2019-08-21T09:03:03.064145Z", 353 | "start_time": "2019-08-21T09:03:03.058953Z" 354 | } 355 | }, 356 | "outputs": [ 357 | { 358 | "data": { 359 | "text/plain": [ 360 | "Operator([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],\n", 361 | " [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],\n", 362 | " [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],\n", 363 | " [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]],\n", 364 | " input_dims=(2, 2), output_dims=(2, 2))" 365 | ] 366 | }, 367 | "execution_count": 11, 368 | "metadata": {}, 369 | "output_type": "execute_result" 370 | } 371 | ], 372 | "source": [ 373 | "# Create an Operator for a Gate object\n", 374 | "Operator(CXGate())" 375 | ] 376 | }, 377 | { 378 | "cell_type": "code", 379 | "execution_count": 12, 380 | "metadata": { 381 | "ExecuteTime": { 382 | "end_time": "2019-08-21T09:03:03.353613Z", 383 | "start_time": "2019-08-21T09:03:03.345462Z" 384 | } 385 | }, 386 | "outputs": [ 387 | { 388 | "data": { 389 | "text/plain": [ 390 | "Operator([[0.70710678+0.j , 0. -0.70710678j],\n", 391 | " [0. -0.70710678j, 0.70710678+0.j ]],\n", 392 | " input_dims=(2,), output_dims=(2,))" 393 | ] 394 | }, 395 | "execution_count": 12, 396 | "metadata": {}, 397 | "output_type": "execute_result" 398 | } 399 | ], 400 | "source": [ 401 | "# Create an operator from a parameterized Gate object\n", 402 | "Operator(RXGate(np.pi / 2))" 403 | ] 404 | }, 405 | { 406 | "cell_type": "code", 407 | "execution_count": 13, 408 | "metadata": { 409 | "ExecuteTime": { 410 | "end_time": "2019-08-21T09:03:47.550069Z", 411 | "start_time": "2019-08-21T09:03:47.408126Z" 412 | } 413 | }, 414 | "outputs": [ 415 | { 416 | "data": { 417 | "text/plain": [ 418 | "Operator([[ 0.70710678+0.j, 0.70710678+0.j, 0. +0.j, ...,\n", 419 | " 0. +0.j, 0. +0.j, 0. +0.j],\n", 420 | " [ 0. +0.j, 0. +0.j, 0.70710678+0.j, ...,\n", 421 | " 0. +0.j, 0. +0.j, 0. +0.j],\n", 422 | " [ 0. +0.j, 0. +0.j, 0. +0.j, ...,\n", 423 | " 0. +0.j, 0. +0.j, 0. +0.j],\n", 424 | " ...,\n", 425 | " [ 0. +0.j, 0. +0.j, 0. +0.j, ...,\n", 426 | " 0. +0.j, 0. +0.j, 0. +0.j],\n", 427 | " [ 0. +0.j, 0. +0.j, 0.70710678+0.j, ...,\n", 428 | " 0. +0.j, 0. +0.j, 0. +0.j],\n", 429 | " [ 0.70710678+0.j, -0.70710678+0.j, 0. +0.j, ...,\n", 430 | " 0. +0.j, 0. +0.j, 0. +0.j]],\n", 431 | " input_dims=(2, 2, 2, 2, 2, 2, 2, 2, 2, 2), output_dims=(2, 2, 2, 2, 2, 2, 2, 2, 2, 2))" 432 | ] 433 | }, 434 | "execution_count": 13, 435 | "metadata": {}, 436 | "output_type": "execute_result" 437 | } 438 | ], 439 | "source": [ 440 | "# Create an operator from a QuantumCircuit object\n", 441 | "circ = QuantumCircuit(10)\n", 442 | "circ.h(0)\n", 443 | "for j in range(1, 10):\n", 444 | " circ.cx(j-1, j)\n", 445 | "\n", 446 | "# Convert circuit to an operator by implicit unitary simulation\n", 447 | "Operator(circ)" 448 | ] 449 | }, 450 | { 451 | "cell_type": "markdown", 452 | "metadata": {}, 453 | "source": [ 454 | "## Using Operators in circuits\n", 455 | "\n", 456 | "Unitary `Operators` can be directly inserted into a `QuantumCircuit` using the `QuantumCircuit.append` method. This converts the `Operator` into a `UnitaryGate` object, which is added to the circuit.\n", 457 | "\n", 458 | "If the operator is not unitary, an exception will be raised. This can be checked using the `Operator.is_unitary()` function, which will return `True` if the operator is unitary and `False` otherwise." 459 | ] 460 | }, 461 | { 462 | "cell_type": "code", 463 | "execution_count": 14, 464 | "metadata": { 465 | "ExecuteTime": { 466 | "end_time": "2019-08-21T09:03:49.196556Z", 467 | "start_time": "2019-08-21T09:03:49.161398Z" 468 | }, 469 | "tags": [ 470 | "nbsphinx-thumbnail" 471 | ] 472 | }, 473 | "outputs": [ 474 | { 475 | "data": { 476 | "image/png": "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\n", 477 | "text/plain": [ 478 | "
" 479 | ] 480 | }, 481 | "execution_count": 14, 482 | "metadata": {}, 483 | "output_type": "execute_result" 484 | } 485 | ], 486 | "source": [ 487 | "# Create an operator\n", 488 | "XX = Operator(Pauli('XX'))\n", 489 | "\n", 490 | "# Add to a circuit\n", 491 | "circ = QuantumCircuit(2, 2)\n", 492 | "circ.append(XX, [0, 1])\n", 493 | "circ.measure([0,1], [0,1])\n", 494 | "circ.draw('mpl')" 495 | ] 496 | }, 497 | { 498 | "cell_type": "markdown", 499 | "metadata": {}, 500 | "source": [ 501 | "Note that in the above example we initialize the operator from a `Pauli` object. However, the `Pauli` object may also be directly inserted into the circuit itself and will be converted into a sequence of single-qubit Pauli gates:" 502 | ] 503 | }, 504 | { 505 | "cell_type": "code", 506 | "execution_count": 15, 507 | "metadata": {}, 508 | "outputs": [ 509 | { 510 | "data": { 511 | "text/plain": [ 512 | "{'11': 1024}" 513 | ] 514 | }, 515 | "execution_count": 15, 516 | "metadata": {}, 517 | "output_type": "execute_result" 518 | } 519 | ], 520 | "source": [ 521 | "backend = BasicAer.get_backend('qasm_simulator')\n", 522 | "circ = transpile(circ, backend, basis_gates=['u1','u2','u3','cx'])\n", 523 | "job = backend.run(circ)\n", 524 | "job.result().get_counts(0)" 525 | ] 526 | }, 527 | { 528 | "cell_type": "code", 529 | "execution_count": 16, 530 | "metadata": { 531 | "ExecuteTime": { 532 | "end_time": "2019-08-21T09:04:12.017240Z", 533 | "start_time": "2019-08-21T09:04:11.989825Z" 534 | } 535 | }, 536 | "outputs": [ 537 | { 538 | "data": { 539 | "text/html": [ 540 | "
     ┌────────────┐┌─┐   \n",
 541 |        "q_0: ┤0           ├┤M├───\n",
 542 |        "     │  Pauli(XX) │└╥┘┌─┐\n",
 543 |        "q_1: ┤1           ├─╫─┤M├\n",
 544 |        "     └────────────┘ ║ └╥┘\n",
 545 |        "c: 2/═══════════════╩══╩═\n",
 546 |        "                    0  1 
" 547 | ], 548 | "text/plain": [ 549 | " ┌────────────┐┌─┐ \n", 550 | "q_0: ┤0 ├┤M├───\n", 551 | " │ Pauli(XX) │└╥┘┌─┐\n", 552 | "q_1: ┤1 ├─╫─┤M├\n", 553 | " └────────────┘ ║ └╥┘\n", 554 | "c: 2/═══════════════╩══╩═\n", 555 | " 0 1 " 556 | ] 557 | }, 558 | "execution_count": 16, 559 | "metadata": {}, 560 | "output_type": "execute_result" 561 | } 562 | ], 563 | "source": [ 564 | "# Add to a circuit\n", 565 | "circ2 = QuantumCircuit(2, 2)\n", 566 | "circ2.append(Pauli('XX'), [0, 1])\n", 567 | "circ2.measure([0,1], [0,1])\n", 568 | "circ2.draw()" 569 | ] 570 | }, 571 | { 572 | "cell_type": "markdown", 573 | "metadata": {}, 574 | "source": [ 575 | "## Combining Operators\n", 576 | "\n", 577 | "Operators may be combined using several methods. \n", 578 | "\n", 579 | "### Tensor Product\n", 580 | "\n", 581 | "Two operators $A$ and $B$ may be combined into a tensor product operator $A\\otimes B$ using the `Operator.tensor` function. Note that if both $A$ and $B$ are single-qubit operators, then `A.tensor(B)` = $A\\otimes B$ will have the subsystems indexed as matrix $B$ on subsystem 0, and matrix $A$ on subsystem 1." 582 | ] 583 | }, 584 | { 585 | "cell_type": "code", 586 | "execution_count": 17, 587 | "metadata": { 588 | "ExecuteTime": { 589 | "end_time": "2019-08-21T09:04:14.208734Z", 590 | "start_time": "2019-08-21T09:04:14.201058Z" 591 | } 592 | }, 593 | "outputs": [ 594 | { 595 | "data": { 596 | "text/plain": [ 597 | "Operator([[ 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],\n", 598 | " [ 0.+0.j, -0.+0.j, 0.+0.j, -1.+0.j],\n", 599 | " [ 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],\n", 600 | " [ 0.+0.j, -1.+0.j, 0.+0.j, -0.+0.j]],\n", 601 | " input_dims=(2, 2), output_dims=(2, 2))" 602 | ] 603 | }, 604 | "execution_count": 17, 605 | "metadata": {}, 606 | "output_type": "execute_result" 607 | } 608 | ], 609 | "source": [ 610 | "A = Operator(Pauli('X'))\n", 611 | "B = Operator(Pauli('Z'))\n", 612 | "A.tensor(B)" 613 | ] 614 | }, 615 | { 616 | "cell_type": "markdown", 617 | "metadata": {}, 618 | "source": [ 619 | "### Tensor Expansion\n", 620 | "\n", 621 | "A closely related operation is `Operator.expand`, which acts like a tensor product but in the reverse order. Hence, for two operators $A$ and $B$ we have `A.expand(B)` = $B\\otimes A$ where the subsystems indexed as matrix $A$ on subsystem 0, and matrix $B$ on subsystem 1." 622 | ] 623 | }, 624 | { 625 | "cell_type": "code", 626 | "execution_count": 18, 627 | "metadata": { 628 | "ExecuteTime": { 629 | "end_time": "2019-08-21T09:04:14.899024Z", 630 | "start_time": "2019-08-21T09:04:14.891072Z" 631 | } 632 | }, 633 | "outputs": [ 634 | { 635 | "data": { 636 | "text/plain": [ 637 | "Operator([[ 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],\n", 638 | " [ 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],\n", 639 | " [ 0.+0.j, 0.+0.j, -0.+0.j, -1.+0.j],\n", 640 | " [ 0.+0.j, 0.+0.j, -1.+0.j, -0.+0.j]],\n", 641 | " input_dims=(2, 2), output_dims=(2, 2))" 642 | ] 643 | }, 644 | "execution_count": 18, 645 | "metadata": {}, 646 | "output_type": "execute_result" 647 | } 648 | ], 649 | "source": [ 650 | "A = Operator(Pauli('X'))\n", 651 | "B = Operator(Pauli('Z'))\n", 652 | "A.expand(B)" 653 | ] 654 | }, 655 | { 656 | "cell_type": "markdown", 657 | "metadata": {}, 658 | "source": [ 659 | "### Composition\n", 660 | "\n", 661 | "We can also compose two operators $A$ and $B$ to implement matrix multiplication using the `Operator.compose` method. We have that `A.compose(B)` returns the operator with matrix $B.A$:" 662 | ] 663 | }, 664 | { 665 | "cell_type": "code", 666 | "execution_count": 19, 667 | "metadata": { 668 | "ExecuteTime": { 669 | "end_time": "2019-08-21T09:04:15.655155Z", 670 | "start_time": "2019-08-21T09:04:15.648295Z" 671 | } 672 | }, 673 | "outputs": [ 674 | { 675 | "data": { 676 | "text/plain": [ 677 | "Operator([[ 0.+0.j, 1.+0.j],\n", 678 | " [-1.+0.j, 0.+0.j]],\n", 679 | " input_dims=(2,), output_dims=(2,))" 680 | ] 681 | }, 682 | "execution_count": 19, 683 | "metadata": {}, 684 | "output_type": "execute_result" 685 | } 686 | ], 687 | "source": [ 688 | "A = Operator(Pauli('X'))\n", 689 | "B = Operator(Pauli('Z'))\n", 690 | "A.compose(B)" 691 | ] 692 | }, 693 | { 694 | "cell_type": "markdown", 695 | "metadata": {}, 696 | "source": [ 697 | "We can also compose in the reverse order by applying $B$ in front of $A$ using the `front` kwarg of `compose`: `A.compose(B, front=True)` = $A.B$:" 698 | ] 699 | }, 700 | { 701 | "cell_type": "code", 702 | "execution_count": 20, 703 | "metadata": { 704 | "ExecuteTime": { 705 | "end_time": "2019-08-21T09:04:16.460560Z", 706 | "start_time": "2019-08-21T09:04:16.452319Z" 707 | } 708 | }, 709 | "outputs": [ 710 | { 711 | "data": { 712 | "text/plain": [ 713 | "Operator([[ 0.+0.j, -1.+0.j],\n", 714 | " [ 1.+0.j, 0.+0.j]],\n", 715 | " input_dims=(2,), output_dims=(2,))" 716 | ] 717 | }, 718 | "execution_count": 20, 719 | "metadata": {}, 720 | "output_type": "execute_result" 721 | } 722 | ], 723 | "source": [ 724 | "A = Operator(Pauli('X'))\n", 725 | "B = Operator(Pauli('Z'))\n", 726 | "A.compose(B, front=True)" 727 | ] 728 | }, 729 | { 730 | "cell_type": "markdown", 731 | "metadata": {}, 732 | "source": [ 733 | "### Subsystem Composition\n", 734 | "\n", 735 | "Note that the previous compose requires that the total output dimension of the first operator $A$ is equal to total input dimension of the composed operator $B$ (and similarly, the output dimension of $B$ must be equal to the input dimension of $A$ when composing with `front=True`).\n", 736 | "\n", 737 | "We can also compose a smaller operator with a selection of subsystems on a larger operator using the `qargs` kwarg of `compose`, either with or without `front=True`. In this case, the relevant input and output dimensions of the subsystems being composed must match. *Note that the smaller operator must always be the argument of* `compose` *method.*\n", 738 | "\n", 739 | "For example, to compose a two-qubit gate with a three-qubit Operator:" 740 | ] 741 | }, 742 | { 743 | "cell_type": "code", 744 | "execution_count": 21, 745 | "metadata": { 746 | "ExecuteTime": { 747 | "end_time": "2019-08-21T09:04:17.113510Z", 748 | "start_time": "2019-08-21T09:04:17.105398Z" 749 | } 750 | }, 751 | "outputs": [ 752 | { 753 | "data": { 754 | "text/plain": [ 755 | "Operator([[ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j,\n", 756 | " 0.+0.j],\n", 757 | " [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, -1.+0.j, 0.+0.j,\n", 758 | " 0.+0.j],\n", 759 | " [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j,\n", 760 | " 0.+0.j],\n", 761 | " [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,\n", 762 | " -1.+0.j],\n", 763 | " [ 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,\n", 764 | " 0.+0.j],\n", 765 | " [ 0.+0.j, -1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,\n", 766 | " 0.+0.j],\n", 767 | " [ 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,\n", 768 | " 0.+0.j],\n", 769 | " [ 0.+0.j, 0.+0.j, 0.+0.j, -1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,\n", 770 | " 0.+0.j]],\n", 771 | " input_dims=(2, 2, 2), output_dims=(2, 2, 2))" 772 | ] 773 | }, 774 | "execution_count": 21, 775 | "metadata": {}, 776 | "output_type": "execute_result" 777 | } 778 | ], 779 | "source": [ 780 | "# Compose XZ with a 3-qubit identity operator\n", 781 | "op = Operator(np.eye(2 ** 3))\n", 782 | "XZ = Operator(Pauli('XZ'))\n", 783 | "op.compose(XZ, qargs=[0, 2])" 784 | ] 785 | }, 786 | { 787 | "cell_type": "code", 788 | "execution_count": 22, 789 | "metadata": { 790 | "ExecuteTime": { 791 | "end_time": "2019-08-21T09:04:17.324353Z", 792 | "start_time": "2019-08-21T09:04:17.315952Z" 793 | } 794 | }, 795 | "outputs": [ 796 | { 797 | "data": { 798 | "text/plain": [ 799 | "Operator([[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.-1.j, 0.+0.j, 0.+0.j],\n", 800 | " [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.-1.j, 0.+0.j, 0.+0.j, 0.+0.j],\n", 801 | " [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.-1.j],\n", 802 | " [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.-1.j, 0.+0.j],\n", 803 | " [0.+0.j, 0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],\n", 804 | " [0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],\n", 805 | " [0.+0.j, 0.+0.j, 0.+0.j, 0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],\n", 806 | " [0.+0.j, 0.+0.j, 0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]],\n", 807 | " input_dims=(2, 2, 2), output_dims=(2, 2, 2))" 808 | ] 809 | }, 810 | "execution_count": 22, 811 | "metadata": {}, 812 | "output_type": "execute_result" 813 | } 814 | ], 815 | "source": [ 816 | "# Compose YX in front of the previous operator\n", 817 | "op = Operator(np.eye(2 ** 3))\n", 818 | "YX = Operator(Pauli('YX'))\n", 819 | "op.compose(YX, qargs=[0, 2], front=True)" 820 | ] 821 | }, 822 | { 823 | "cell_type": "markdown", 824 | "metadata": {}, 825 | "source": [ 826 | "### Linear combinations\n", 827 | "\n", 828 | "Operators may also be combined using standard linear operators for addition, subtraction and scalar multiplication by complex numbers. " 829 | ] 830 | }, 831 | { 832 | "cell_type": "code", 833 | "execution_count": 23, 834 | "metadata": { 835 | "ExecuteTime": { 836 | "end_time": "2019-08-21T09:04:18.829988Z", 837 | "start_time": "2019-08-21T09:04:18.812834Z" 838 | } 839 | }, 840 | "outputs": [ 841 | { 842 | "data": { 843 | "text/plain": [ 844 | "Operator([[-1.5+0.j, 0. +0.j, 0. +0.j, 0. +0.j],\n", 845 | " [ 0. +0.j, 1.5+0.j, 1. +0.j, 0. +0.j],\n", 846 | " [ 0. +0.j, 1. +0.j, 1.5+0.j, 0. +0.j],\n", 847 | " [ 0. +0.j, 0. +0.j, 0. +0.j, -1.5+0.j]],\n", 848 | " input_dims=(2, 2), output_dims=(2, 2))" 849 | ] 850 | }, 851 | "execution_count": 23, 852 | "metadata": {}, 853 | "output_type": "execute_result" 854 | } 855 | ], 856 | "source": [ 857 | "XX = Operator(Pauli('XX'))\n", 858 | "YY = Operator(Pauli('YY'))\n", 859 | "ZZ = Operator(Pauli('ZZ'))\n", 860 | "\n", 861 | "op = 0.5 * (XX + YY - 3 * ZZ)\n", 862 | "op" 863 | ] 864 | }, 865 | { 866 | "cell_type": "markdown", 867 | "metadata": {}, 868 | "source": [ 869 | "An important point is that while `tensor`, `expand` and `compose` will preserve the unitarity of unitary operators, linear combinations will not; hence, adding two unitary operators will, in general, result in a non-unitary operator:" 870 | ] 871 | }, 872 | { 873 | "cell_type": "code", 874 | "execution_count": 24, 875 | "metadata": { 876 | "ExecuteTime": { 877 | "end_time": "2019-08-21T09:04:19.151814Z", 878 | "start_time": "2019-08-21T09:04:19.147497Z" 879 | } 880 | }, 881 | "outputs": [ 882 | { 883 | "data": { 884 | "text/plain": [ 885 | "False" 886 | ] 887 | }, 888 | "execution_count": 24, 889 | "metadata": {}, 890 | "output_type": "execute_result" 891 | } 892 | ], 893 | "source": [ 894 | "op.is_unitary()" 895 | ] 896 | }, 897 | { 898 | "cell_type": "markdown", 899 | "metadata": {}, 900 | "source": [ 901 | "### Implicit Conversion to Operators\n", 902 | "\n", 903 | "Note that for all the following methods, if the second object is not already an `Operator` object, it will be implicitly converted into one by the method. This means that matrices can be passed in directly without being explicitly converted to an `Operator` first. If the conversion is not possible, an exception will be raised." 904 | ] 905 | }, 906 | { 907 | "cell_type": "code", 908 | "execution_count": 25, 909 | "metadata": { 910 | "ExecuteTime": { 911 | "end_time": "2019-08-21T09:04:20.045005Z", 912 | "start_time": "2019-08-21T09:04:20.039841Z" 913 | } 914 | }, 915 | "outputs": [ 916 | { 917 | "data": { 918 | "text/plain": [ 919 | "Operator([[0.+0.j, 1.+0.j],\n", 920 | " [1.+0.j, 0.+0.j]],\n", 921 | " input_dims=(2,), output_dims=(2,))" 922 | ] 923 | }, 924 | "execution_count": 25, 925 | "metadata": {}, 926 | "output_type": "execute_result" 927 | } 928 | ], 929 | "source": [ 930 | "# Compose with a matrix passed as a list\n", 931 | "Operator(np.eye(2)).compose([[0, 1], [1, 0]])" 932 | ] 933 | }, 934 | { 935 | "cell_type": "markdown", 936 | "metadata": {}, 937 | "source": [ 938 | "## Comparison of Operators\n", 939 | "\n", 940 | "Operators implement an equality method that can be used to check if two operators are approximately equal. " 941 | ] 942 | }, 943 | { 944 | "cell_type": "code", 945 | "execution_count": 26, 946 | "metadata": { 947 | "ExecuteTime": { 948 | "end_time": "2019-08-21T09:04:20.821642Z", 949 | "start_time": "2019-08-21T09:04:20.815611Z" 950 | } 951 | }, 952 | "outputs": [ 953 | { 954 | "data": { 955 | "text/plain": [ 956 | "True" 957 | ] 958 | }, 959 | "execution_count": 26, 960 | "metadata": {}, 961 | "output_type": "execute_result" 962 | } 963 | ], 964 | "source": [ 965 | "Operator(Pauli('X')) == Operator(XGate())" 966 | ] 967 | }, 968 | { 969 | "cell_type": "markdown", 970 | "metadata": {}, 971 | "source": [ 972 | "Note that this checks that each matrix element of the operators is approximately equal; two unitaries that differ by a global phase will not be considered equal:" 973 | ] 974 | }, 975 | { 976 | "cell_type": "code", 977 | "execution_count": 27, 978 | "metadata": { 979 | "ExecuteTime": { 980 | "end_time": "2019-08-21T09:04:21.146256Z", 981 | "start_time": "2019-08-21T09:04:21.141242Z" 982 | } 983 | }, 984 | "outputs": [ 985 | { 986 | "data": { 987 | "text/plain": [ 988 | "False" 989 | ] 990 | }, 991 | "execution_count": 27, 992 | "metadata": {}, 993 | "output_type": "execute_result" 994 | } 995 | ], 996 | "source": [ 997 | "Operator(XGate()) == np.exp(1j * 0.5) * Operator(XGate())" 998 | ] 999 | }, 1000 | { 1001 | "cell_type": "markdown", 1002 | "metadata": {}, 1003 | "source": [ 1004 | "### Process Fidelity\n", 1005 | "\n", 1006 | "We may also compare operators using the `process_fidelity` function from the *Quantum Information* module. This is an information theoretic quantity for how close two quantum channels are to each other, and in the case of unitary operators it does not depend on global phase." 1007 | ] 1008 | }, 1009 | { 1010 | "cell_type": "code", 1011 | "execution_count": 28, 1012 | "metadata": { 1013 | "ExecuteTime": { 1014 | "end_time": "2019-08-21T09:04:22.171481Z", 1015 | "start_time": "2019-08-21T09:04:22.147477Z" 1016 | } 1017 | }, 1018 | "outputs": [ 1019 | { 1020 | "name": "stdout", 1021 | "output_type": "stream", 1022 | "text": [ 1023 | "Process fidelity = 1.0\n" 1024 | ] 1025 | } 1026 | ], 1027 | "source": [ 1028 | "# Two operators which differ only by phase\n", 1029 | "op_a = Operator(XGate()) \n", 1030 | "op_b = np.exp(1j * 0.5) * Operator(XGate())\n", 1031 | "\n", 1032 | "# Compute process fidelity\n", 1033 | "F = process_fidelity(op_a, op_b)\n", 1034 | "print('Process fidelity =', F)" 1035 | ] 1036 | }, 1037 | { 1038 | "cell_type": "markdown", 1039 | "metadata": {}, 1040 | "source": [ 1041 | "Note that process fidelity is generally only a valid measure of closeness if the input operators are unitary (or CP in the case of quantum channels), and an exception will be raised if the inputs are not CP." 1042 | ] 1043 | }, 1044 | { 1045 | "cell_type": "code", 1046 | "execution_count": 29, 1047 | "metadata": { 1048 | "ExecuteTime": { 1049 | "end_time": "2019-08-21T09:04:44.743744Z", 1050 | "start_time": "2019-08-21T09:04:44.734826Z" 1051 | } 1052 | }, 1053 | "outputs": [ 1054 | { 1055 | "data": { 1056 | "text/html": [ 1057 | "

Version Information

Qiskit SoftwareVersion
qiskit-terra0.20.2
qiskit-aer0.10.4
qiskit-ignis0.7.1
qiskit-ibmq-provider0.19.1
qiskit0.36.2
System information
Python version3.9.9
Python compilerGCC 11.1.0
Python buildmain, Dec 29 2021 22:19:36
OSLinux
CPUs32
Memory (Gb)125.64821243286133
Wed Jun 22 15:52:11 2022 EDT
" 1058 | ], 1059 | "text/plain": [ 1060 | "" 1061 | ] 1062 | }, 1063 | "metadata": {}, 1064 | "output_type": "display_data" 1065 | }, 1066 | { 1067 | "data": { 1068 | "text/html": [ 1069 | "

This code is a part of Qiskit

© Copyright IBM 2017, 2022.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.

" 1070 | ], 1071 | "text/plain": [ 1072 | "" 1073 | ] 1074 | }, 1075 | "metadata": {}, 1076 | "output_type": "display_data" 1077 | } 1078 | ], 1079 | "source": [ 1080 | "import qiskit.tools.jupyter\n", 1081 | "%qiskit_version_table\n", 1082 | "%qiskit_copyright" 1083 | ] 1084 | }, 1085 | { 1086 | "cell_type": "code", 1087 | "execution_count": null, 1088 | "metadata": {}, 1089 | "outputs": [], 1090 | "source": [] 1091 | } 1092 | ], 1093 | "metadata": { 1094 | "anaconda-cloud": {}, 1095 | "celltoolbar": "Tags", 1096 | "kernelspec": { 1097 | "display_name": "Python 3 (ipykernel)", 1098 | "language": "python", 1099 | "name": "python3" 1100 | }, 1101 | "language_info": { 1102 | "codemirror_mode": { 1103 | "name": "ipython", 1104 | "version": 3 1105 | }, 1106 | "file_extension": ".py", 1107 | "mimetype": "text/x-python", 1108 | "name": "python", 1109 | "nbconvert_exporter": "python", 1110 | "pygments_lexer": "ipython3", 1111 | "version": "3.9.9" 1112 | }, 1113 | "varInspector": { 1114 | "cols": { 1115 | "lenName": 16, 1116 | "lenType": 16, 1117 | "lenVar": 40 1118 | }, 1119 | "kernels_config": { 1120 | "python": { 1121 | "delete_cmd_postfix": "", 1122 | "delete_cmd_prefix": "del ", 1123 | "library": "var_list.py", 1124 | "varRefreshCmd": "print(var_dic_list())" 1125 | }, 1126 | "r": { 1127 | "delete_cmd_postfix": ") ", 1128 | "delete_cmd_prefix": "rm(", 1129 | "library": "var_list.r", 1130 | "varRefreshCmd": "cat(var_dic_list()) " 1131 | } 1132 | }, 1133 | "types_to_exclude": [ 1134 | "module", 1135 | "function", 1136 | "builtin_function_or_method", 1137 | "instance", 1138 | "_Feature" 1139 | ], 1140 | "window_display": false 1141 | } 1142 | }, 1143 | "nbformat": 4, 1144 | "nbformat_minor": 1 1145 | } 1146 | -------------------------------------------------------------------------------- /tutorials/circuits_advanced/pulse_modulation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qiskit/qiskit-tutorials/2fc7ed53fcc7bb3bff4855e400d00ee050a82b81/tutorials/circuits_advanced/pulse_modulation.png -------------------------------------------------------------------------------- /tutorials/operators/images/gradient_framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qiskit/qiskit-tutorials/2fc7ed53fcc7bb3bff4855e400d00ee050a82b81/tutorials/operators/images/gradient_framework.png --------------------------------------------------------------------------------