├── gifs
├── u2_animated_qubit.gif
├── u3_animated_qubit.gif
└── u2_animated_qsphere.gif
├── .github
└── workflows
│ └── jekyll-gh-pages.yml
├── LICENSE
├── README.md
├── Installing Qiskit and Dependancies.ipynb
├── Complex Arithmetic.ipynb
└── Quantum_Circuits.ipynb
/gifs/u2_animated_qubit.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/HEAD/gifs/u2_animated_qubit.gif
--------------------------------------------------------------------------------
/gifs/u3_animated_qubit.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/HEAD/gifs/u3_animated_qubit.gif
--------------------------------------------------------------------------------
/gifs/u2_animated_qsphere.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/HEAD/gifs/u2_animated_qsphere.gif
--------------------------------------------------------------------------------
/.github/workflows/jekyll-gh-pages.yml:
--------------------------------------------------------------------------------
1 | # Sample workflow for building and deploying a Jekyll site to GitHub Pages
2 | name: Deploy Jekyll with GitHub Pages dependencies preinstalled
3 |
4 | on:
5 | # Runs on pushes targeting the default branch
6 | push:
7 | branches: ["main"]
8 |
9 | # Allows you to run this workflow manually from the Actions tab
10 | workflow_dispatch:
11 |
12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
13 | permissions:
14 | contents: read
15 | pages: write
16 | id-token: write
17 |
18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
20 | concurrency:
21 | group: "pages"
22 | cancel-in-progress: false
23 |
24 | jobs:
25 | # Build job
26 | build:
27 | runs-on: ubuntu-latest
28 | steps:
29 | - name: Checkout
30 | uses: actions/checkout@v3
31 | - name: Setup Pages
32 | uses: actions/configure-pages@v3
33 | - name: Build with Jekyll
34 | uses: actions/jekyll-build-pages@v1
35 | with:
36 | source: ./
37 | destination: ./_site
38 | - name: Upload artifact
39 | uses: actions/upload-pages-artifact@v1
40 |
41 | # Deployment job
42 | deploy:
43 | environment:
44 | name: github-pages
45 | url: ${{ steps.deployment.outputs.page_url }}
46 | runs-on: ubuntu-latest
47 | needs: build
48 | steps:
49 | - name: Deploy to GitHub Pages
50 | id: deployment
51 | uses: actions/deploy-pages@v2
52 |
--------------------------------------------------------------------------------
/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 | [←←Back to Homepage](https://monitsharma.github.io/)
2 |
3 |
4 | # Learn Quantum Computing with Qiskit
5 |
6 | Welcome to the "Learn Quantum Computing with Qiskit" repository! This repository aims to provide a comprehensive learning resource for quantum computing using the Qiskit framework. It includes Jupyter notebooks covering a wide range of topics, from the basics of quantum computing to advanced concepts, all following the structure and content of the Qiskit Textbook.
7 |
8 | # About Qiskit
9 | Qiskit is an open-source framework developed by IBM for programming quantum computers. It provides a rich set of tools, libraries, and resources to facilitate quantum computation research and education. With Qiskit, you can learn, simulate, and execute quantum circuits on real quantum hardware devices or simulators.
10 |
11 |
12 | # Table
13 |
14 |
15 | - [Prerequisites](#prerequisites)
16 | - [Quantum States and Qubits](#quantum-states-and-qubits)
17 | - [Multiple Qubits and Entanglement](#multiple-qubits-and-entanglement)
18 | - [Quantum Protocols and Quantum Algorithms](#quantum-protocols-and-quantum-algorithms)
19 |
20 |
21 |
22 |
23 | # Content
24 |
25 |
26 | ## Prerequisites
27 |
28 | This is a comprehensive guide for setting up your environment on your personal computer for working with Qiskit Textbook. This will help you reproduce the results as you see them on the textbook website. The Qiskit Textbook is written in Jupyter Notebooks.
29 | 
30 |
31 | Learn about the software used to write the Qiskit (Python and Jupyter Notebooks), and set up your environment to reproduce the experiments.
32 |
33 | | Serial Number | Title | Links | Medium |
34 | | ------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------- |------------------------------------|
35 | | 1 | Checking versions and installing | [](https://github.com/MonitSharma/Quantum-Computing-with-Qiskit-and-IBMQ/blob/main/Installing%20Qiskit%20and%20Dependancies.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-the-beginning-a177b588df88) |
36 | | 2 | Complex Arithmetic | [](https://github.com/MonitSharma/Quantum-Computing-with-Qiskit-and-IBMQ/blob/main/ComplexArithmetic.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-complex-arithmetic-453d5f15638b) |
37 | | 3 | A very basic intro to Linear Algebra | [](https://github.com/MonitSharma/Quantum-Computing-with-Qiskit-and-IBMQ/blob/main/Linear%20Algebra%20Background.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-linear-algebra-501587c3297d) |
38 |
39 |
40 |
41 |
42 |
43 |
44 | ## Quantum States and Qubits
45 |
46 | If you think quantum mechanics sounds challenging, you’re not alone. Our intuitions come from day-to-day experiences, and so are better at understanding the behavior of balls and bananas than atoms or electrons. Though quantum objects can seem random and chaotic at first, they just follow a different set of rules. Once we know what those rules are, we can use them to create new and powerful technology. Quantum computing will be the most revolutionary example of this.
47 |
48 | 
49 |
50 | This chapter introduces the computing concepts that we'll explore in later chapters, then introduces basic quantum concepts.
51 |
52 |
53 |
54 |
55 |
56 | | Serial Number | Title | Links | Medium |
57 | | ------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------- |------------------------------------|
58 | | 1 | Atoms of Computation | [](https://github.com/MonitSharma/Quantum-Computing-with-Qiskit-and-IBMQ/blob/main/Atoms_of_Computation.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-atoms-of-computation-463eb0a038aa) |
59 | | 2 | Representing Qubit States | [](https://github.com/MonitSharma/Quantum-Computing-with-Qiskit-and-IBMQ/blob/main/Represenitng_Qubit_States.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-representing-qubit-state-aed033b612d0) |
60 | | 3 | Single Qubit Gates | [](https://github.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/blob/main/Single_Qubit_Gates.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-single-qubit-gates-17a5a419ed7c) |
61 |
62 |
63 |
64 | ## Multiple Qubits and Entanglement
65 |
66 | We've seen some interesting effects with isolated qubits and single qubit gates, but the true power of quantum computing comes from interactions between qubits. In this section we will introduce multiple qubit gates and explore the interesting behaviours of multi-qubit systems.
67 |
68 | 
69 |
70 |
71 | With the basics down, this chapter explores the consequences of these new quantum effects, and sets us up with tools to understand quantum algorithms.
72 |
73 |
74 |
75 |
76 |
77 | | Serial Number | Title | Links | Medium |
78 | | ------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------- |------------------------------------|
79 | | 1 |Multiple Qubits and Entanglement | [](https://github.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/blob/main/Multiple_Qubits_and_Entanglement.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-multiple-qubits-and-entanglement-39b8ffa9b95d) |
80 | | 2 |Phase Kickback | [](https://github.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/blob/main/Phase_Kickback.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-phase-kickback-d79ac667202d) |
81 | | 3 |Basic Circuit Identities | [](https://github.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/blob/main/Basic_Circuit_Identities.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-basic-circuit-identities-9cfc1232c9ad) |
82 | | 4 |Proving Universality | [](https://github.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/blob/main/Proving_Universality.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-proving-universality-4a41b9591b76) |
83 | | 5 |Classical Computation on a Quantum Computer | [](https://github.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/blob/main/Classical_Computation_on_a_Quantum_Computer.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-classical-computation-on-a-quantum-computer-ba8f724646a) |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 | ## Quantum Protocols and Quantum Algorithms
93 |
94 | So far, we've seen various quantum gates and operations, and we've explored some interesting properties of these gates. Each of these pages shows how we can combine quantum operations into a quantum algorithm that outperforms their classical counterpart. As a bonus, some of these algorithms are actually useful too!
95 |
96 | 
97 |
98 | In this chapter, we use quantum effects to build powerful algorithms, starting from simple proof-of-concept algorithms, through to Shor's famous factoring algorithm (and beyond).
99 |
100 |
101 |
102 |
103 |
104 | | Serial Number | Title | Links | Medium |
105 | | ------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------- |------------------------------------|
106 | | 1 | Quantum Circuits | [](https://github.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/blob/main/Quantum_Circuits.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-quantum-circuit-8f07571a23f6) |
107 | | 2 | Deutsch Jozsa Algorithm | [](https://github.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/blob/main/Deutsch_Jozsa_Algorithm.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-deutsch-jozsa-algorithm-3f9bedee8f9d) |
108 | | 3 | Bernstein-Vazirani Algorithm | [](https://github.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/blob/main/Bernstein_Vazirani_Algorithm.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-bernstein-vazirani-algorithm-fa1300517624) |
109 | | 4 | Simons Algorithm | [](https://github.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/blob/main/Simons_Algorithm.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-simons-algorithm-8525adecd091) |
110 | | 5 | Quantum Fourier Transform | [](https://github.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/blob/main/Quantum_Fourier_Transform.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-quantum-fourier-transform-e27176c8f378) |
111 | | 6 | Quantum Phase Estimation | [](https://github.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/blob/main/Quantum_Phase_Estimatoin.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-quantum-phase-estimation-9c64c59c074c) |
112 | | 7 | Shor's Algorithm | [](https://github.com/MonitSharma/Learn-Quantum-Computing-with-Qiskit/blob/main/Quantum_Phase_Estimatoin.ipynb) | [](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-shors-algorithm-971b3f6d8795) |
113 |
114 |
115 | ## Investigating Quantum Hardware Using Microwave Pulses
116 |
117 | In this chapter, we get a level closer to the real quantum machines. Learn about the physics of these devices, and how to program them at the level of microwave pulses.
118 |
119 |
120 |
121 |
122 |
123 | | Serial Number | Title | Links | Medium |
124 | | ------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------- |------------------------------------|
125 | | 1 | TBA | [](https://github.com/MonitSharma/Quantum-Computing-with-Qiskit-and-IBMQ/blob/main/Atoms_of_Computation.ipynb) | [](https://medium.com/@_monitsharma/computational-linear-algebra-scalars-vectors-matrices-and-tensors-50e392df9ccc) |
126 |
127 |
128 |
129 |
130 |
131 | ## Quantum Algorithms for Applications
132 |
133 |
134 | If algorithms are the solution, then what is the problem? In this chapter, we look at how we can take general algorithms and apply them to more specific situations.
135 |
136 |
137 |
138 |
139 |
140 | | Serial Number | Title | Links | Medium |
141 | | ------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------- |------------------------------------|
142 | | 1 | TBA | [](https://github.com/MonitSharma/Quantum-Computing-with-Qiskit-and-IBMQ/blob/main/Atoms_of_Computation.ipynb) | [](https://medium.com/@_monitsharma/computational-linear-algebra-scalars-vectors-matrices-and-tensors-50e392df9ccc) |
143 |
144 |
145 |
146 |
147 | ## Investigating Quantum Hardware Using Quantum Circuits
148 |
149 | All circuit-based quantum devices share some similar characteristics and challenges. In this chapter, we explore how quantum circuits perform on modern quantum computers, and ways to improve performance.
150 |
151 |
152 |
153 |
154 | | Serial Number | Title | Links | Medium |
155 | | ------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------- |------------------------------------|
156 | | 1 | TBA | [](https://github.com/MonitSharma/Quantum-Computing-with-Qiskit-and-IBMQ/blob/main/Atoms_of_Computation.ipynb) | [](https://medium.com/@_monitsharma/computational-linear-algebra-scalars-vectors-matrices-and-tensors-50e392df9ccc) |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 | ## Getting Started
180 | To get started, make sure you have the following prerequisites:
181 |
182 | - Python 3: Ensure you have Python 3 installed on your system.
183 | - Qiskit: Install the Qiskit framework by following the instructions provided in the official Qiskit documentation.
184 |
185 | Once you have the prerequisites ready, clone this repository to your local machine:
186 |
187 |
188 |
189 |
190 | You can then access the notebooks through your browser and start learning quantum computing with Qiskit!
191 |
192 | ## Contributions
193 | Contributions to this repository are welcome. If you have any suggestions, bug fixes, or additional content to contribute, please open an issue or submit a pull request. Let's work together to make this learning resource even better!
194 |
195 | ## Resources
196 | - [Qiskit Documentation](https://qiskit.org/documentation/)
197 | - [Qiskit Textbook](https://qiskit.org/textbook/)
198 | - [IBM Quantum Experience](https://quantum-computing.ibm.com/)
199 |
200 | ## License
201 | The content of this repository is licensed under the [MIT License](LICENSE). Feel free to use, modify, and distribute the code and notebooks for educational purposes.
202 |
203 | Happy learning and exploring the fascinating world of quantum computing with Qiskit!
204 |
205 |
206 |
--------------------------------------------------------------------------------
/Installing Qiskit and Dependancies.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "colab_type": "text",
7 | "id": "view-in-github"
8 | },
9 | "source": [
10 | "
"
11 | ]
12 | },
13 | {
14 | "cell_type": "markdown",
15 | "metadata": {
16 | "id": "bcYBcnDT_RDs"
17 | },
18 | "source": [
19 | "# Environment Setup Guide to get started with Qiskit\n",
20 | "\n",
21 | "I will walk through the latest version installation of Qiskit, `0.43.0` and all the dependancies required for it.\n",
22 | "\n",
23 | "I'm running this code on Google Colab, you can run this on your local device as well.\n"
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {
29 | "id": "sOZRFk21_siT"
30 | },
31 | "source": [
32 | "## Setting up a Virtual Environment\n",
33 | "\n",
34 | "\n",
35 | "Now, you have two options, to either install Qiskit directly on your local machine, or make a `virtualenvironment` and install it there.\n",
36 | "\n",
37 | "I recommend the later, because alot of times, it may so happen that some packages are not compatible with the other, and you need only specific packages to run that code file. It's better to have it on a virtual environment.\n",
38 | "\n",
39 | "But if you don't do much coding on your device, that makes you install different versions of different packages, then you can simply do\n",
40 | "\n",
41 | "```python\n",
42 | "!pip install qiskit\n",
43 | "```\n",
44 | "\n",
45 | "and if not, you can start by creating a virtual environment.\n",
46 | "\n",
47 | "### Installing it in VS code\n",
48 | "\n",
49 | " I use VS code, so [this](https://code.visualstudio.com/docs/python/environments) documentation helped me to create a virtual environment.\n",
50 | "\n",
51 | "\n",
52 | "### Installing it through Terminal\n",
53 | "\n",
54 | "If you choose to create a virtual environment manually, use the following command (where \".venv\" is the name of the environment folder):\n",
55 | "\n",
56 | "```python\n",
57 | "# macOS/Linux\n",
58 | "# You may need to run `sudo apt-get install python3-venv` first on Debian-based OSs\n",
59 | "python3 -m venv .venv\n",
60 | "\n",
61 | "# Windows\n",
62 | "# You can also use `py -3 -m venv .venv`\n",
63 | "python -m venv .venv\n",
64 | "```\n",
65 | "\n",
66 | "\n",
67 | "you can name it other than `venv` as well.\n",
68 | "\n",
69 | "Then activate it and install qiskit using\n",
70 | "\n",
71 | "```python\n",
72 | "pip install qiskit\n",
73 | "```\n",
74 | "\n",
75 | "\n",
76 | "or you can skip all that, and just use Colab or a Jupyter Notebook on your local machine and run:\n",
77 | "\n",
78 | "\n",
79 | "\n"
80 | ]
81 | },
82 | {
83 | "cell_type": "code",
84 | "execution_count": 1,
85 | "metadata": {
86 | "colab": {
87 | "base_uri": "https://localhost:8080/"
88 | },
89 | "id": "FLAIVaj0_NOS",
90 | "outputId": "a6f39d48-751d-4e65-c989-f75b9a327b6a"
91 | },
92 | "outputs": [
93 | {
94 | "name": "stdout",
95 | "output_type": "stream",
96 | "text": [
97 | "Collecting qiskit\n",
98 | " Using cached qiskit-1.1.0-cp38-abi3-macosx_11_0_arm64.whl.metadata (12 kB)\n",
99 | "Collecting rustworkx>=0.14.0 (from qiskit)\n",
100 | " Using cached rustworkx-0.14.2-cp312-cp312-macosx_11_0_arm64.whl.metadata (10.0 kB)\n",
101 | "Collecting numpy<3,>=1.17 (from qiskit)\n",
102 | " Downloading numpy-2.0.0-cp312-cp312-macosx_14_0_arm64.whl.metadata (60 kB)\n",
103 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m60.9/60.9 kB\u001b[0m \u001b[31m3.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
104 | "\u001b[?25hCollecting scipy>=1.5 (from qiskit)\n",
105 | " Using cached scipy-1.13.1-cp312-cp312-macosx_12_0_arm64.whl.metadata (60 kB)\n",
106 | "Collecting sympy>=1.3 (from qiskit)\n",
107 | " Using cached sympy-1.12.1-py3-none-any.whl.metadata (12 kB)\n",
108 | "Collecting dill>=0.3 (from qiskit)\n",
109 | " Using cached dill-0.3.8-py3-none-any.whl.metadata (10 kB)\n",
110 | "Requirement already satisfied: python-dateutil>=2.8.0 in ./.venv/lib/python3.12/site-packages (from qiskit) (2.9.0.post0)\n",
111 | "Collecting stevedore>=3.0.0 (from qiskit)\n",
112 | " Using cached stevedore-5.2.0-py3-none-any.whl.metadata (2.3 kB)\n",
113 | "Collecting typing-extensions (from qiskit)\n",
114 | " Using cached typing_extensions-4.12.2-py3-none-any.whl.metadata (3.0 kB)\n",
115 | "Collecting symengine>=0.11 (from qiskit)\n",
116 | " Using cached symengine-0.11.0-cp312-cp312-macosx_11_0_arm64.whl.metadata (1.2 kB)\n",
117 | "Requirement already satisfied: six>=1.5 in ./.venv/lib/python3.12/site-packages (from python-dateutil>=2.8.0->qiskit) (1.16.0)\n",
118 | "Collecting numpy<3,>=1.17 (from qiskit)\n",
119 | " Using cached numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl.metadata (61 kB)\n",
120 | "Collecting pbr!=2.1.0,>=2.0.0 (from stevedore>=3.0.0->qiskit)\n",
121 | " Using cached pbr-6.0.0-py2.py3-none-any.whl.metadata (1.3 kB)\n",
122 | "Collecting mpmath<1.4.0,>=1.1.0 (from sympy>=1.3->qiskit)\n",
123 | " Using cached mpmath-1.3.0-py3-none-any.whl.metadata (8.6 kB)\n",
124 | "Using cached qiskit-1.1.0-cp38-abi3-macosx_11_0_arm64.whl (4.0 MB)\n",
125 | "Using cached dill-0.3.8-py3-none-any.whl (116 kB)\n",
126 | "Using cached rustworkx-0.14.2-cp312-cp312-macosx_11_0_arm64.whl (1.7 MB)\n",
127 | "Using cached numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl (13.7 MB)\n",
128 | "Using cached scipy-1.13.1-cp312-cp312-macosx_12_0_arm64.whl (30.4 MB)\n",
129 | "Using cached stevedore-5.2.0-py3-none-any.whl (49 kB)\n",
130 | "Using cached symengine-0.11.0-cp312-cp312-macosx_11_0_arm64.whl (20.5 MB)\n",
131 | "Using cached sympy-1.12.1-py3-none-any.whl (5.7 MB)\n",
132 | "Using cached typing_extensions-4.12.2-py3-none-any.whl (37 kB)\n",
133 | "Using cached mpmath-1.3.0-py3-none-any.whl (536 kB)\n",
134 | "Using cached pbr-6.0.0-py2.py3-none-any.whl (107 kB)\n",
135 | "Installing collected packages: mpmath, typing-extensions, sympy, symengine, pbr, numpy, dill, stevedore, scipy, rustworkx, qiskit\n",
136 | "Successfully installed dill-0.3.8 mpmath-1.3.0 numpy-1.26.4 pbr-6.0.0 qiskit-1.1.0 rustworkx-0.14.2 scipy-1.13.1 stevedore-5.2.0 symengine-0.11.0 sympy-1.12.1 typing-extensions-4.12.2\n"
137 | ]
138 | }
139 | ],
140 | "source": [
141 | "!pip install qiskit # or\n",
142 | "#%pip install qiskit"
143 | ]
144 | },
145 | {
146 | "cell_type": "markdown",
147 | "metadata": {
148 | "id": "zRykPRyuBwrV"
149 | },
150 | "source": [
151 | "In Jupyter Notebook or JupyterLab, the exclamation mark (!) and percent symbol (%) are used as \"magic\" commands to execute system-level commands or interact with specific environments.\n",
152 | "\n",
153 | "When it comes to installing packages using pip, there is a subtle difference between !pip and %pip:\n",
154 | "\n",
155 | "1. !pip: The exclamation mark is a shorthand way to execute system-level commands from within a Jupyter cell. Using !pip allows you to install packages directly from the command line within the Jupyter environment. For example, !pip install numpy will install the NumPy package using the pip package manager.\n",
156 | "\n",
157 | "2. %pip: The percent symbol is used for \"line magic\" commands in IPython, an interactive command-line interface used by Jupyter. %pip is a specific IPython magic command that can be used to install packages in a similar way to !pip. The difference is that %pip is executed as an IPython magic command, providing some additional features and integration with the IPython environment.\n",
158 | "\n",
159 | "In most cases, both !pip and %pip can be used interchangeably to install packages. However, it's worth noting that %pip provides extra functionalities specific to IPython and may have slight variations in behavior compared to !pip."
160 | ]
161 | },
162 | {
163 | "cell_type": "markdown",
164 | "metadata": {
165 | "id": "EjXuXk5JB-eM"
166 | },
167 | "source": [
168 | "----\n",
169 | "\n",
170 | "Doing\n",
171 | "```python\n",
172 | "!pip install qiskit\n",
173 | "```\n",
174 | "will install most of the Qiskit packages for you, but not all.\n",
175 | "\n",
176 | "Qiskit has divided its packages in different categories\n",
177 | "1. Qiskit Machine Learning\n",
178 | "2. Qiskit Finance\n",
179 | "3. Qiskit Optimizaion\n",
180 | "4. Qiskit Nature\n",
181 | "and many more.\n",
182 | "\n",
183 | "These all are not installed directly by installing qiskit. You have to install them separately.\n",
184 | "\n"
185 | ]
186 | },
187 | {
188 | "cell_type": "markdown",
189 | "metadata": {
190 | "id": "pKgd6eEdDBZV"
191 | },
192 | "source": [
193 | "To install Qiskit Visualization package:"
194 | ]
195 | },
196 | {
197 | "cell_type": "code",
198 | "execution_count": 2,
199 | "metadata": {
200 | "colab": {
201 | "base_uri": "https://localhost:8080/"
202 | },
203 | "id": "MOoQzVvUBUyP",
204 | "outputId": "fd5afd55-28d4-4a74-a086-fda7a9a4967b"
205 | },
206 | "outputs": [
207 | {
208 | "name": "stdout",
209 | "output_type": "stream",
210 | "text": [
211 | "zsh:1: no matches found: qiskit[visualization]\n"
212 | ]
213 | }
214 | ],
215 | "source": [
216 | "!pip install qiskit[visualization]"
217 | ]
218 | },
219 | {
220 | "cell_type": "markdown",
221 | "metadata": {
222 | "id": "AEU66pXFDHBk"
223 | },
224 | "source": [
225 | "To install Qiskit Machine Learning Package:"
226 | ]
227 | },
228 | {
229 | "cell_type": "code",
230 | "execution_count": 3,
231 | "metadata": {
232 | "colab": {
233 | "base_uri": "https://localhost:8080/"
234 | },
235 | "id": "M4dk2-lDDE0u",
236 | "outputId": "dffaeb69-a95e-42e7-82cd-cbba6bbf3fa2"
237 | },
238 | "outputs": [
239 | {
240 | "name": "stdout",
241 | "output_type": "stream",
242 | "text": [
243 | "zsh:1: no matches found: qiskit[machine-learning]\n"
244 | ]
245 | }
246 | ],
247 | "source": [
248 | "!pip install qiskit[machine-learning]"
249 | ]
250 | },
251 | {
252 | "cell_type": "markdown",
253 | "metadata": {
254 | "id": "X12zR6QLDUAE"
255 | },
256 | "source": [
257 | "To install Qiskit Nature:"
258 | ]
259 | },
260 | {
261 | "cell_type": "code",
262 | "execution_count": 4,
263 | "metadata": {
264 | "colab": {
265 | "base_uri": "https://localhost:8080/"
266 | },
267 | "id": "aSqpwMUhDLss",
268 | "outputId": "1b354c77-9955-447d-fe0a-7f2764615dcc"
269 | },
270 | "outputs": [
271 | {
272 | "name": "stdout",
273 | "output_type": "stream",
274 | "text": [
275 | "zsh:1: no matches found: qiskit[nature]\n"
276 | ]
277 | }
278 | ],
279 | "source": [
280 | "!pip install qiskit[nature]"
281 | ]
282 | },
283 | {
284 | "cell_type": "markdown",
285 | "metadata": {
286 | "id": "jlJEl5gpDYuT"
287 | },
288 | "source": [
289 | "and so on for other packages as well."
290 | ]
291 | },
292 | {
293 | "cell_type": "markdown",
294 | "metadata": {
295 | "id": "jhSz7_Y8DcDk"
296 | },
297 | "source": [
298 | "We will learn how to install other packages as well, when we will reach there, and have to make use of them. Currenlty we are starting with the very basics of Quantum Computing in Qiskit and hence do not require such advance packages."
299 | ]
300 | },
301 | {
302 | "cell_type": "markdown",
303 | "metadata": {
304 | "id": "B1jCobaMEDqc"
305 | },
306 | "source": [
307 | "### Which version is installed?\n",
308 | "\n",
309 | "Suppose you want to know which version of the qiskit package in installed, and which packages are not installed yet.\n",
310 | "\n",
311 | "You can simply run the below code to see. The packages that are installed, will show a version number right next to it, and the packages that aren't installed, will show `none` in front of them."
312 | ]
313 | },
314 | {
315 | "cell_type": "code",
316 | "execution_count": 17,
317 | "metadata": {},
318 | "outputs": [
319 | {
320 | "name": "stdout",
321 | "output_type": "stream",
322 | "text": [
323 | "Collecting matplotlib\n",
324 | " Using cached matplotlib-3.9.0-cp312-cp312-macosx_11_0_arm64.whl.metadata (11 kB)\n",
325 | "Collecting contourpy>=1.0.1 (from matplotlib)\n",
326 | " Using cached contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl.metadata (5.8 kB)\n",
327 | "Collecting cycler>=0.10 (from matplotlib)\n",
328 | " Using cached cycler-0.12.1-py3-none-any.whl.metadata (3.8 kB)\n",
329 | "Collecting fonttools>=4.22.0 (from matplotlib)\n",
330 | " Using cached fonttools-4.53.0-cp312-cp312-macosx_11_0_arm64.whl.metadata (162 kB)\n",
331 | "Collecting kiwisolver>=1.3.1 (from matplotlib)\n",
332 | " Using cached kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl.metadata (6.4 kB)\n",
333 | "Requirement already satisfied: numpy>=1.23 in ./.venv/lib/python3.12/site-packages (from matplotlib) (1.26.4)\n",
334 | "Requirement already satisfied: packaging>=20.0 in ./.venv/lib/python3.12/site-packages (from matplotlib) (24.1)\n",
335 | "Collecting pillow>=8 (from matplotlib)\n",
336 | " Using cached pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl.metadata (9.2 kB)\n",
337 | "Collecting pyparsing>=2.3.1 (from matplotlib)\n",
338 | " Using cached pyparsing-3.1.2-py3-none-any.whl.metadata (5.1 kB)\n",
339 | "Requirement already satisfied: python-dateutil>=2.7 in ./.venv/lib/python3.12/site-packages (from matplotlib) (2.9.0.post0)\n",
340 | "Requirement already satisfied: six>=1.5 in ./.venv/lib/python3.12/site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)\n",
341 | "Using cached matplotlib-3.9.0-cp312-cp312-macosx_11_0_arm64.whl (7.8 MB)\n",
342 | "Using cached contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl (245 kB)\n",
343 | "Using cached cycler-0.12.1-py3-none-any.whl (8.3 kB)\n",
344 | "Using cached fonttools-4.53.0-cp312-cp312-macosx_11_0_arm64.whl (2.2 MB)\n",
345 | "Using cached kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl (64 kB)\n",
346 | "Using cached pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl (3.4 MB)\n",
347 | "Using cached pyparsing-3.1.2-py3-none-any.whl (103 kB)\n",
348 | "Installing collected packages: pyparsing, pillow, kiwisolver, fonttools, cycler, contourpy, matplotlib\n",
349 | "Successfully installed contourpy-1.2.1 cycler-0.12.1 fonttools-4.53.0 kiwisolver-1.4.5 matplotlib-3.9.0 pillow-10.3.0 pyparsing-3.1.2\n",
350 | "Note: you may need to restart the kernel to use updated packages.\n"
351 | ]
352 | }
353 | ],
354 | "source": [
355 | "%pip install matplotlib"
356 | ]
357 | },
358 | {
359 | "cell_type": "code",
360 | "execution_count": 10,
361 | "metadata": {
362 | "colab": {
363 | "base_uri": "https://localhost:8080/"
364 | },
365 | "id": "0jWs9Kx3DWXc",
366 | "outputId": "6dcab1b3-668e-4503-a05d-b34181cbb12e"
367 | },
368 | "outputs": [
369 | {
370 | "data": {
371 | "text/plain": [
372 | "'1.1.0'"
373 | ]
374 | },
375 | "execution_count": 10,
376 | "metadata": {},
377 | "output_type": "execute_result"
378 | }
379 | ],
380 | "source": [
381 | "import qiskit\n",
382 | "\n",
383 | "qiskit.version.get_version_info()"
384 | ]
385 | },
386 | {
387 | "cell_type": "markdown",
388 | "metadata": {
389 | "id": "hBe1JdHMEai0"
390 | },
391 | "source": [
392 | "As you can see, we haven't installed `qiskit-finance`, `qiskit-optimization` and `qiskit-ignis` package yet. Hence it shows `none` in front of them.\n",
393 | "\n",
394 | "Although it's fairly easy to install them, you just have to use the command, we used before.\n",
395 | "\n",
396 | "```python\n",
397 | "!pip install qiskit[nature]\n",
398 | "```\n",
399 | "\n",
400 | "and replace `nature` with either `finance`, `optimization` or `ignis` and it will install those packages as well."
401 | ]
402 | },
403 | {
404 | "cell_type": "markdown",
405 | "metadata": {
406 | "id": "iAgDkyVIGGcV"
407 | },
408 | "source": [
409 | "### Important point\n",
410 | "\n",
411 | "To visualize pretty circuits like these\n",
412 | "\n",
413 | "\n",
414 | "\n",
415 | "make sure to install `pylatex` library."
416 | ]
417 | },
418 | {
419 | "cell_type": "code",
420 | "execution_count": 16,
421 | "metadata": {
422 | "colab": {
423 | "base_uri": "https://localhost:8080/"
424 | },
425 | "id": "KOiK9j1nFII_",
426 | "outputId": "35717fcd-f911-4018-9fdf-7d8e5dc1b45e"
427 | },
428 | "outputs": [
429 | {
430 | "name": "stdout",
431 | "output_type": "stream",
432 | "text": [
433 | "Collecting pylatexenc\n",
434 | " Using cached pylatexenc-2.10-py3-none-any.whl\n",
435 | "Installing collected packages: pylatexenc\n",
436 | "Successfully installed pylatexenc-2.10\n"
437 | ]
438 | }
439 | ],
440 | "source": [
441 | "!pip install pylatexenc"
442 | ]
443 | },
444 | {
445 | "cell_type": "markdown",
446 | "metadata": {
447 | "id": "1fWyJB90GXQE"
448 | },
449 | "source": [
450 | "This is the library that gets called , when you set the output to mpl while plotting the circuits. (We will see that later)."
451 | ]
452 | },
453 | {
454 | "cell_type": "markdown",
455 | "metadata": {
456 | "id": "t6Y4kcxWGxGl"
457 | },
458 | "source": [
459 | "### Deprecation Policy\n",
460 | "\n",
461 | "Many packages depend on different parts of Qiskit, but since they are building new features, optimizing the code, adding more functionalities , they sometimes have to remove one function to add another (better) one.\n",
462 | "\n",
463 | "Just like qiskit used to have an `aqua` library, that had all the algorithms , so you had to call `qiskit.aqua` to call the algorithms, but that has been optimized and made better to `qiskit.algorithms` and also `qiskit.circuits`.\n",
464 | "\n",
465 | "When removing a feature (for example a class, function or function parameter), they follow this procedure:\n",
466 | "\n",
467 | "The alternative path must be in place for one minor version before any warnings are issued. For example, if they want to replace the function `foo()` with `bar()`, they make at least one release with both functions before issuing any warnings within `foo()`. You may issue `PendingDeprecationWarnings` from the old paths immediately.\n",
468 | "\n",
469 | "Reason: we need to give people time to swap over without breaking their code as soon as they upgrade.\n",
470 | "\n",
471 | "\n",
472 | "So it may happen thay when you run certain code, you get the following warning:\n"
473 | ]
474 | },
475 | {
476 | "cell_type": "markdown",
477 | "metadata": {
478 | "id": "xUID3DAzHqeU"
479 | },
480 | "source": [
481 | "```python\n",
482 | "Deprecated since version 0.20.0: The function qiskit.deprecated_function() is deprecated since Qiskit Terra 0.20.0, and will be removed 3 months or more later. Instead, you should use qiskit.other_function().\n",
483 | "```"
484 | ]
485 | },
486 | {
487 | "cell_type": "markdown",
488 | "metadata": {
489 | "id": "Z3S-ESfEHygF"
490 | },
491 | "source": [
492 | "Do not panic!, follow the instructions and you'll see plenty tutorials or blogs by the Qiskit team itself on how to use the new function instead of the old ones."
493 | ]
494 | },
495 | {
496 | "cell_type": "markdown",
497 | "metadata": {
498 | "id": "lZ0g3miJI0w3"
499 | },
500 | "source": [
501 | "## End\n",
502 | "\n",
503 | "Now you know how to install `Qiskit` packages and all the dependancies required with it. In the next lecture we will start by building basic quantum circuits and running them on a simulator."
504 | ]
505 | }
506 | ],
507 | "metadata": {
508 | "colab": {
509 | "authorship_tag": "ABX9TyO1IFEEPrYB0iI9Z6H/Jb/Y",
510 | "include_colab_link": true,
511 | "provenance": []
512 | },
513 | "kernelspec": {
514 | "display_name": "Python 3",
515 | "name": "python3"
516 | },
517 | "language_info": {
518 | "codemirror_mode": {
519 | "name": "ipython",
520 | "version": 3
521 | },
522 | "file_extension": ".py",
523 | "mimetype": "text/x-python",
524 | "name": "python",
525 | "nbconvert_exporter": "python",
526 | "pygments_lexer": "ipython3",
527 | "version": "3.12.2"
528 | }
529 | },
530 | "nbformat": 4,
531 | "nbformat_minor": 0
532 | }
533 |
--------------------------------------------------------------------------------
/Complex Arithmetic.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "colab_type": "text",
7 | "id": "view-in-github"
8 | },
9 | "source": [
10 | "
"
11 | ]
12 | },
13 | {
14 | "cell_type": "markdown",
15 | "metadata": {
16 | "id": "9-DtnhPg96di"
17 | },
18 | "source": [
19 | "# Complex Arithmetic\n",
20 | "\n",
21 | "This is a tutorial designed to introduce you to complex arithmetic.\n",
22 | "This topic isn't particularly expansive, but it's important to understand it to be able to work with quantum computing.\n",
23 | "\n",
24 | "This tutorial covers the following topics:\n",
25 | "\n",
26 | "* Imaginary and complex numbers\n",
27 | "* Basic complex arithmetic\n",
28 | "* Complex plane\n",
29 | "* Modulus operator\n",
30 | "* Imaginary exponents\n",
31 | "* Polar representation\n",
32 | "\n",
33 | "If you are curious to learn more, you can find more information at [Wikipedia](https://en.wikipedia.org/wiki/Complex_number)."
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {
39 | "id": "qly_DTd_96d1"
40 | },
41 | "source": [
42 | "This notebook has several tasks that require you to write Python code to test your understanding of the concepts. If you are not familiar with Python, [here](https://medium.com/@_monitsharma/list/computational-physics-and-scientific-programming-f8d4b52726ba) is a good introductory course on computational phsycis with python that'll teach the basics of python.\n",
43 | "\n",
44 | "Let's start by importing some useful mathematical functions and constants, and setting up a few things necessary for testing the exercises. **Do not skip this step**.\n",
45 | "\n",
46 | "Click the cell with code below this block of text and press `Shift+Enter` (`⌘+Enter` on Mac)."
47 | ]
48 | },
49 | {
50 | "cell_type": "code",
51 | "execution_count": 1,
52 | "metadata": {
53 | "id": "_ETUmd3Q96ej"
54 | },
55 | "outputs": [],
56 | "source": [
57 | "# Run this cell using Shift+Enter (⌘+Enter on Mac).\n",
58 | "\n",
59 | "from typing import Tuple\n",
60 | "\n",
61 | "import math\n",
62 | "\n",
63 | "Complex = Tuple[float, float]\n",
64 | "Polar = Tuple[float, float]"
65 | ]
66 | },
67 | {
68 | "cell_type": "markdown",
69 | "metadata": {
70 | "id": "ZszSpRvb96eo"
71 | },
72 | "source": [
73 | "# Algebraic Perspective\n",
74 | "\n",
75 | "## Imaginary numbers\n",
76 | "\n",
77 | "For some purposes, real numbers aren't enough. Probably the most famous example is this equation:\n",
78 | "\n",
79 | "$$x^{2} = -1$$\n",
80 | "\n",
81 | "which has no solution for $x$ among real numbers. If, however, we abandon that constraint, we can do something interesting - we can define our own number. Let's say there exists some number that solves that equation. Let's call that number $i$.\n",
82 | "\n",
83 | "$$i^{2} = -1$$\n",
84 | "\n",
85 | "As we said before, $i$ can't be a real number. In that case, we'll call it an **imaginary unit**. However, there is no reason for us to define it as acting any different from any other number, other than the fact that $i^2 = -1$:\n",
86 | "\n",
87 | "$$i + i = 2i$$\n",
88 | "$$i - i = 0$$\n",
89 | "$$-1 \\cdot i = -i$$\n",
90 | "$$(-i)^{2} = -1$$\n",
91 | "\n",
92 | "We'll call the number $i$ and its real multiples **imaginary numbers**.\n",
93 | "\n",
94 | "> A good video introduction on imaginary numbers can be found [here](https://youtu.be/SP-YJe7Vldo)."
95 | ]
96 | },
97 | {
98 | "cell_type": "markdown",
99 | "metadata": {
100 | "id": "meuuCUbp96eq"
101 | },
102 | "source": [
103 | "### Exercise 1: Powers of $i$.\n",
104 | "\n",
105 | "**Input:** An integer $n$.\n",
106 | "\n",
107 | "**Goal:** Return the $n$th power of $i$, or $i^n$.\n",
108 | "\n",
109 | "> Fill in the missing code (denoted by `...`) and run the cell below to test your work."
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": 2,
115 | "metadata": {
116 | "id": "R3zw-GqQ96er"
117 | },
118 | "outputs": [],
119 | "source": [
120 | "\n",
121 | "def imaginary_power(n : int) -> int:\n",
122 | " # If n is divisible by 4\n",
123 | " if n % 4 == 0:\n",
124 | " return 1\n",
125 | " else:\n",
126 | " return 1j ** (n % 4)"
127 | ]
128 | },
129 | {
130 | "cell_type": "code",
131 | "execution_count": 3,
132 | "metadata": {
133 | "colab": {
134 | "base_uri": "https://localhost:8080/"
135 | },
136 | "id": "g9ziIsGG-nxR",
137 | "outputId": "dd915779-9929-409f-d23b-cf50b230a277"
138 | },
139 | "outputs": [
140 | {
141 | "data": {
142 | "text/plain": [
143 | "1"
144 | ]
145 | },
146 | "execution_count": 3,
147 | "metadata": {},
148 | "output_type": "execute_result"
149 | }
150 | ],
151 | "source": [
152 | "imaginary_power(4)"
153 | ]
154 | },
155 | {
156 | "cell_type": "markdown",
157 | "metadata": {
158 | "id": "BpZBPV8R96ev"
159 | },
160 | "source": [
161 | "## Complex Numbers\n",
162 | "\n",
163 | "Adding imaginary numbers to each other is quite simple, but what happens when we add a real number to an imaginary number? The result of that addition will be partly real and partly imaginary, otherwise known as a **complex number**. A complex number is simply the real part and the imaginary part being treated as a single number. Complex numbers are generally written as the sum of their two parts: $a + bi$, where both $a$ and $b$ are real numbers. For example, $3 + 4i$, or $-5 - 7i$ are valid complex numbers. Note that purely real or purely imaginary numbers can also be written as complex numbers: $2$ is $2 + 0i$, and $-3i$ is $0 - 3i$.\n",
164 | "\n",
165 | "When performing operations on complex numbers, it is often helpful to treat them as polynomials in terms of $i$."
166 | ]
167 | },
168 | {
169 | "cell_type": "markdown",
170 | "metadata": {
171 | "id": "2LtrDRn396ex"
172 | },
173 | "source": [
174 | "### Exercise 2: Complex addition.\n",
175 | "\n",
176 | "**Inputs:**\n",
177 | "\n",
178 | "1. A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
179 | "2. A complex number $y = c + di$, represented as a tuple `(c, d)`.\n",
180 | "\n",
181 | "**Goal:** Return the sum of these two numbers $x + y = z = g + hi$, represented as a tuple `(g, h)`.\n",
182 | "\n",
183 | "> A tuple is a pair of numbers.\n",
184 | "> You can make a tuple by putting two numbers in parentheses like this: `(3, 4)`.\n",
185 | "> * You can access the $n$th element of tuple `x` like so: `x[n]`\n",
186 | "> * For this tutorial, complex numbers are represented as tuples where the first element is the real part, and the second element is the real coefficient of the imaginary part\n",
187 | "> * For example, $1 + 2i$ would be represented by a tuple `(1, 2)`, and $7 - 5i$ would be represented by `(7, -5)`.\n",
188 | ">\n",
189 | "> You can find more details about Python's tuple data type in the [official documentation](https://docs.python.org/3/library/stdtypes.html#tuples).\n",
190 | "\n",
191 | "
\n",
192 | "\n",
193 | " Need a hint? Click here
\n",
194 | " Remember, adding complex numbers is just like adding polynomials. Add components of the same type - add the real part to the real part, add the complex part to the complex part.
\n",
195 | " A video explanation can be found here.\n",
196 | " "
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": 4,
202 | "metadata": {
203 | "id": "M0DE0RpO96e0"
204 | },
205 | "outputs": [],
206 | "source": [
207 | "def complex_add(x : Complex, y : Complex) -> Complex:\n",
208 | " # You can extract elements from a tuple like this\n",
209 | " a = x[0]\n",
210 | " b = x[1]\n",
211 | "\n",
212 | " c = y[0]\n",
213 | " d = y[1]\n",
214 | "\n",
215 | " # This creates a new variable and stores the real component into it\n",
216 | " real = a + c\n",
217 | " # Replace the ... with code to calculate the imaginary component\n",
218 | " imaginary = b+d\n",
219 | "\n",
220 | " # You can create a tuple like this\n",
221 | " ans = (real, imaginary)\n",
222 | "\n",
223 | " return ans"
224 | ]
225 | },
226 | {
227 | "cell_type": "code",
228 | "execution_count": 5,
229 | "metadata": {
230 | "colab": {
231 | "base_uri": "https://localhost:8080/"
232 | },
233 | "id": "3IKdc6FxAFW1",
234 | "outputId": "91a5207d-80d5-4aa5-9383-528ce39b93f1"
235 | },
236 | "outputs": [
237 | {
238 | "data": {
239 | "text/plain": [
240 | "(4, 6)"
241 | ]
242 | },
243 | "execution_count": 5,
244 | "metadata": {},
245 | "output_type": "execute_result"
246 | }
247 | ],
248 | "source": [
249 | "complex_add((1,2),(3,4))"
250 | ]
251 | },
252 | {
253 | "cell_type": "markdown",
254 | "metadata": {
255 | "id": "QObqrLkxAKU6"
256 | },
257 | "source": [
258 | "In this example, we add the complex numbers $1 + 2 \\iota $ and $3 + 4 \\iota$, which adds up to $ 4+ 6 \\iota$"
259 | ]
260 | },
261 | {
262 | "cell_type": "markdown",
263 | "metadata": {
264 | "id": "KZBePoAQ96e3"
265 | },
266 | "source": [
267 | "### Exercise 3: Complex multiplication.\n",
268 | "\n",
269 | "**Inputs:**\n",
270 | "\n",
271 | "1. A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
272 | "2. A complex number $y = c + di$, represented as a tuple `(c, d)`.\n",
273 | "\n",
274 | "**Goal:** Return the product of these two numbers $x \\cdot y = z = g + hi$, represented as a tuple `(g, h)`.\n",
275 | "\n",
276 | "
\n",
277 | "\n",
278 | " Need a hint? Click here
\n",
279 | " Remember, multiplying complex numbers is just like multiplying polynomials. Distribute one of the complex numbers:\n",
280 | " \n",
281 | "$$(a + bi)(c + di) = a(c + di) + bi(c + di)$$\n",
282 | "\n",
283 | "Then multiply through, and group the real and imaginary terms together.\n",
284 | "
\n",
285 | "A video explanation can be found here.\n",
286 | " "
287 | ]
288 | },
289 | {
290 | "cell_type": "code",
291 | "execution_count": 6,
292 | "metadata": {
293 | "id": "Oj4UlAeU96e5"
294 | },
295 | "outputs": [],
296 | "source": [
297 | "def complex_mult(x, y):\n",
298 | " # Extract the real and imaginary components of x and y\n",
299 | " a = x[0]\n",
300 | " b = x[1]\n",
301 | "\n",
302 | " c = y[0]\n",
303 | " d = y[1]\n",
304 | "\n",
305 | " # Calculate the real component of the result\n",
306 | " real = a * c - b * d\n",
307 | "\n",
308 | " # Calculate the imaginary component of the result\n",
309 | " imaginary = a * d + b * c\n",
310 | "\n",
311 | " # Create a new tuple with the calculated real and imaginary components\n",
312 | " ans = (real, imaginary)\n",
313 | "\n",
314 | " return ans\n"
315 | ]
316 | },
317 | {
318 | "cell_type": "markdown",
319 | "metadata": {
320 | "id": "hd0Whoq0Auw-"
321 | },
322 | "source": [
323 | "In this example we multiply the complex numbers $1+ 2\\iota$ and $3+4 \\iota$ which results in $-5 + 10\\iota$. The function should return the tuple $(-5,10)$"
324 | ]
325 | },
326 | {
327 | "cell_type": "code",
328 | "execution_count": 7,
329 | "metadata": {
330 | "colab": {
331 | "base_uri": "https://localhost:8080/"
332 | },
333 | "id": "ZK2Ryh7hA_aL",
334 | "outputId": "d2485507-8529-43d8-c0c9-80023fb562bf"
335 | },
336 | "outputs": [
337 | {
338 | "name": "stdout",
339 | "output_type": "stream",
340 | "text": [
341 | "(-5, 10)\n"
342 | ]
343 | }
344 | ],
345 | "source": [
346 | "result = complex_mult((1, 2), (3, 4))\n",
347 | "print(result) # Output: (-5, 10)\n"
348 | ]
349 | },
350 | {
351 | "cell_type": "markdown",
352 | "metadata": {
353 | "id": "_Y-lfWUp96e7"
354 | },
355 | "source": [
356 | "## Complex Conjugate\n",
357 | "\n",
358 | "Before we discuss any other complex operations, we have to cover the **complex conjugate**. The conjugate is a simple operation: given a complex number $x = a + bi$, its complex conjugate is $\\overline{x} = a - bi$.\n",
359 | "\n",
360 | "The conjugate allows us to do some interesting things. The first and probably most important is multiplying a complex number by its conjugate:\n",
361 | "\n",
362 | "$$x \\cdot \\overline{x} = (a + bi)(a - bi)$$\n",
363 | "\n",
364 | "Notice that the second expression is a difference of squares:\n",
365 | "\n",
366 | "$$(a + bi)(a - bi) = a^2 - (bi)^2 = a^2 - b^2i^2 = a^2 + b^2$$\n",
367 | "\n",
368 | "This means that a complex number multiplied by its conjugate always produces a non-negative real number.\n",
369 | "\n",
370 | "Another property of the conjugate is that it distributes over both complex addition and complex multiplication:\n",
371 | "\n",
372 | "$$\\overline{x + y} = \\overline{x} + \\overline{y}$$\n",
373 | "$$\\overline{x \\cdot y} = \\overline{x} \\cdot \\overline{y}$$"
374 | ]
375 | },
376 | {
377 | "cell_type": "markdown",
378 | "metadata": {
379 | "id": "4t_z8QQK96e9"
380 | },
381 | "source": [
382 | "### Exercise 4: Complex conjugate.\n",
383 | "\n",
384 | "**Input:** A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
385 | "\n",
386 | "**Goal:** Return $\\overline{x} = g + hi$, the complex conjugate of $x$, represented as a tuple `(g, h)`.\n",
387 | "\n",
388 | "
\n",
389 | "\n",
390 | " Need a hint? Click here
\n",
391 | " A video explanation can be found here.\n",
392 | " "
393 | ]
394 | },
395 | {
396 | "cell_type": "code",
397 | "execution_count": 8,
398 | "metadata": {
399 | "id": "D_CCA-dU96e-"
400 | },
401 | "outputs": [],
402 | "source": [
403 | "def conjugate(x):\n",
404 | " # Extract the real and imaginary components of x\n",
405 | " real, imaginary = x\n",
406 | "\n",
407 | " # Calculate the conjugate by negating the imaginary component\n",
408 | " conjugate_imaginary = -imaginary\n",
409 | "\n",
410 | " # Create a new tuple with the original real component and the conjugate imaginary component\n",
411 | " conjugate = (real, conjugate_imaginary)\n",
412 | "\n",
413 | " return conjugate\n"
414 | ]
415 | },
416 | {
417 | "cell_type": "markdown",
418 | "metadata": {
419 | "id": "fadK4UY-96fA"
420 | },
421 | "source": [
422 | "The output of this example is identical to the previous version. The function correctly calculates the complex conjugate of the complex number 3 + 4i as 3 - 4i and returns the tuple (3, -4) as the output."
423 | ]
424 | },
425 | {
426 | "cell_type": "code",
427 | "execution_count": 9,
428 | "metadata": {
429 | "colab": {
430 | "base_uri": "https://localhost:8080/"
431 | },
432 | "id": "r7_l2DjdBd9M",
433 | "outputId": "6d3db7ac-8ea3-4c3f-ef83-1ea6dbbda977"
434 | },
435 | "outputs": [
436 | {
437 | "name": "stdout",
438 | "output_type": "stream",
439 | "text": [
440 | "(3, -4)\n"
441 | ]
442 | }
443 | ],
444 | "source": [
445 | "result = conjugate((3, 4))\n",
446 | "print(result) # Output: (3, -4)\n"
447 | ]
448 | },
449 | {
450 | "cell_type": "markdown",
451 | "metadata": {
452 | "id": "cldmLXJK96fB"
453 | },
454 | "source": [
455 | "## Complex Division\n",
456 | "\n",
457 | "The next use for the conjugate is complex division. Let's take two complex numbers: $x = a + bi$ and $y = c + di \\neq 0$ (not even complex numbers let you divide by $0$). What does $\\frac{x}{y}$ mean?\n",
458 | "\n",
459 | "Let's expand $x$ and $y$ into their component forms:\n",
460 | "\n",
461 | "$$\\frac{x}{y} = \\frac{a + bi}{c + di}$$\n",
462 | "\n",
463 | "Unfortunately, it isn't very clear what it means to divide by a complex number. We need some way to move either all real parts or all imaginary parts into the numerator. And thanks to the conjugate, we can do just that. Using the fact that any number (except $0$) divided by itself equals $1$, and any number multiplied by $1$ equals itself, we get:\n",
464 | "\n",
465 | "$$\\frac{x}{y} = \\frac{x}{y} \\cdot 1 = \\frac{x}{y} \\cdot \\frac{\\overline{y}}{\\overline{y}} = \\frac{x\\overline{y}}{y\\overline{y}} = \\frac{(a + bi)(c - di)}{(c + di)(c - di)} = \\frac{(a + bi)(c - di)}{c^2 + d^2}$$\n",
466 | "\n",
467 | "By doing this, we re-wrote our division problem to have a complex multiplication expression in the numerator, and a real number in the denominator. We already know how to multiply complex numbers, and dividing a complex number by a real number is as simple as dividing both parts of the complex number separately:\n",
468 | "\n",
469 | "$$\\frac{a + bi}{r} = \\frac{a}{r} + \\frac{b}{r}i$$"
470 | ]
471 | },
472 | {
473 | "cell_type": "markdown",
474 | "metadata": {
475 | "id": "mI0XkbnE96fC"
476 | },
477 | "source": [
478 | "### Exercise 5: Complex division.\n",
479 | "\n",
480 | "**Inputs:**\n",
481 | "\n",
482 | "1. A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
483 | "2. A complex number $y = c + di \\neq 0$, represented as a tuple `(c, d)`.\n",
484 | "\n",
485 | "**Goal:** Return the result of the division $\\frac{x}{y} = \\frac{a + bi}{c + di} = g + hi$, represented as a tuple `(g, h)`.\n",
486 | "\n",
487 | "
\n",
488 | "\n",
489 | " Need a hint? Click here
\n",
490 | " A video explanation can be found here.\n",
491 | " "
492 | ]
493 | },
494 | {
495 | "cell_type": "code",
496 | "execution_count": 10,
497 | "metadata": {
498 | "id": "FIpSzmfM96fD"
499 | },
500 | "outputs": [],
501 | "source": [
502 | "def complex_div(x, y):\n",
503 | " # Extract the real and imaginary components of x and y\n",
504 | " a, b = x\n",
505 | " c, d = y\n",
506 | "\n",
507 | " # Calculate the denominator of the division\n",
508 | " denominator = c**2 + d**2\n",
509 | "\n",
510 | " # Calculate the real and imaginary components of the result\n",
511 | " real = (a * c + b * d) / denominator\n",
512 | " imaginary = (b * c - a * d) / denominator\n",
513 | "\n",
514 | " # Create a new tuple with the calculated real and imaginary components\n",
515 | " result = (real, imaginary)\n",
516 | "\n",
517 | " return result\n"
518 | ]
519 | },
520 | {
521 | "cell_type": "markdown",
522 | "metadata": {
523 | "id": "NhHk1m4e96fE"
524 | },
525 | "source": [
526 | "The output of this example is identical to the previous version. The function correctly divides the complex number 5 + 2i by 3 + i and returns the tuple (1.6, 0.2) as the output."
527 | ]
528 | },
529 | {
530 | "cell_type": "code",
531 | "execution_count": 11,
532 | "metadata": {
533 | "colab": {
534 | "base_uri": "https://localhost:8080/"
535 | },
536 | "id": "PfXPzt5lB7hr",
537 | "outputId": "c8be5819-49b3-4db9-b555-59602748321c"
538 | },
539 | "outputs": [
540 | {
541 | "name": "stdout",
542 | "output_type": "stream",
543 | "text": [
544 | "(1.7, 0.1)\n"
545 | ]
546 | }
547 | ],
548 | "source": [
549 | "result = complex_div((5, 2), (3, 1))\n",
550 | "print(result) # Output: (1.6, 0.2)\n"
551 | ]
552 | },
553 | {
554 | "cell_type": "markdown",
555 | "metadata": {
556 | "id": "xp8Pq1TM96fF"
557 | },
558 | "source": [
559 | "# Geometric Perspective\n",
560 | "\n",
561 | "## The Complex Plane\n",
562 | "\n",
563 | "You may recall that real numbers can be represented geometrically using the [number line](https://en.wikipedia.org/wiki/Number_line) - a line on which each point represents a real number. We can extend this representation to include imaginary and complex numbers, which gives rise to an entirely different number line: the imaginary number line, which only intersects with the real number line at $0$.\n",
564 | "\n",
565 | "A complex number has two components - a real component and an imaginary component. As you no doubt noticed from the exercises, these can be represented by two real numbers - the real component, and the real coefficient of the imaginary component. This allows us to map complex numbers onto a two-dimensional plane - the **complex plane**. The most common mapping is the obvious one: $a + bi$ can be represented by the point $(a, b)$ in the **Cartesian coordinate system**.\n",
566 | "\n",
567 | "\n",
568 | "\n",
569 | "This mapping allows us to apply complex arithmetic to geometry, and, more importantly, apply geometric concepts to complex numbers. Many properties of complex numbers become easier to understand when viewed through a geometric lens."
570 | ]
571 | },
572 | {
573 | "cell_type": "markdown",
574 | "metadata": {
575 | "id": "4V-deLBk96fH"
576 | },
577 | "source": [
578 | "## Modulus\n",
579 | "\n",
580 | "One such property is the **modulus** operator. This operator generalizes the **absolute value** operator on real numbers to the complex plane. Just like the absolute value of a number is its distance from $0$, the modulus of a complex number is its distance from $0 + 0i$. Using the distance formula, if $x = a + bi$, then:\n",
581 | "\n",
582 | "$$|x| = \\sqrt{a^2 + b^2}$$\n",
583 | "\n",
584 | "There is also a slightly different, but algebraically equivalent definition:\n",
585 | "\n",
586 | "$$|x| = \\sqrt{x \\cdot \\overline{x}}$$\n",
587 | "\n",
588 | "Like the conjugate, the modulus distributes over multiplication.\n",
589 | "\n",
590 | "$$|x \\cdot y| = |x| \\cdot |y|$$\n",
591 | "\n",
592 | "Unlike the conjugate, however, the modulus doesn't distribute over addition. Instead, the interaction of the two comes from the triangle inequality:\n",
593 | "\n",
594 | "$$|x + y| \\leq |x| + |y|$$"
595 | ]
596 | },
597 | {
598 | "cell_type": "markdown",
599 | "metadata": {
600 | "id": "6UR6fDEB96fI"
601 | },
602 | "source": [
603 | "### Exercise 6: Modulus.\n",
604 | "\n",
605 | "**Input:** A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
606 | "\n",
607 | "**Goal:** Return the modulus of this number, $|x|$.\n",
608 | "\n",
609 | "> Python's exponentiation operator is `**`, so $2^3$ is `2 ** 3` in Python.\n",
610 | ">\n",
611 | "> You will probably need some mathematical functions to solve the next few tasks. They are available in Python's math library. You can find the full list and detailed information in the [official documentation](https://docs.python.org/3/library/math.html).\n",
612 | "\n",
613 | "\n",
614 | " Need a hint? Click here
\n",
615 | " In particular, you might be interested in Python's square root function.
\n",
616 | " A video explanation can be found here.\n",
617 | " "
618 | ]
619 | },
620 | {
621 | "cell_type": "code",
622 | "execution_count": 12,
623 | "metadata": {
624 | "id": "FZ0T3D9P96fJ"
625 | },
626 | "outputs": [],
627 | "source": [
628 | "def modulus(x):\n",
629 | " # Extract the real and imaginary components of x\n",
630 | " a = x[0]\n",
631 | " b = x[1]\n",
632 | "\n",
633 | " # Calculate the modulus using the Pythagorean theorem\n",
634 | " modulus_value = (a**2 + b**2)**0.5\n",
635 | "\n",
636 | " return modulus_value\n"
637 | ]
638 | },
639 | {
640 | "cell_type": "markdown",
641 | "metadata": {
642 | "id": "iSfbMrY-96fK"
643 | },
644 | "source": [
645 | "In this example, we calculate the modulus of the complex number 3 + 4i, which is 5.0. The function returns the floating-point value 5.0 as the output.\n",
646 | "\n",
647 | "\n",
648 | "\n",
649 | "\n"
650 | ]
651 | },
652 | {
653 | "cell_type": "code",
654 | "execution_count": 13,
655 | "metadata": {
656 | "colab": {
657 | "base_uri": "https://localhost:8080/"
658 | },
659 | "id": "lLdXwMazCzLT",
660 | "outputId": "07f28598-fd0c-4146-e486-b119ac17b0e0"
661 | },
662 | "outputs": [
663 | {
664 | "name": "stdout",
665 | "output_type": "stream",
666 | "text": [
667 | "5.0\n"
668 | ]
669 | }
670 | ],
671 | "source": [
672 | "result = modulus((3, 4))\n",
673 | "print(result) # Output: 5.0\n"
674 | ]
675 | },
676 | {
677 | "cell_type": "markdown",
678 | "metadata": {
679 | "id": "7QtrW66p96fL"
680 | },
681 | "source": [
682 | "## Imaginary Exponents\n",
683 | "\n",
684 | "The next complex operation we're going to need is exponentiation. Raising an imaginary number to an integer power is a fairly simple task, but raising a number to an imaginary power, or raising an imaginary (or complex) number to a real power isn't quite as simple.\n",
685 | "\n",
686 | "Let's start with raising real numbers to imaginary powers. Specifically, let's start with a rather special real number - Euler's constant, $e$:\n",
687 | "\n",
688 | "$$e^{i\\theta} = \\cos \\theta + i\\sin \\theta$$\n",
689 | "\n",
690 | "(Here and later in this tutorial $\\theta$ is measured in radians.)\n",
691 | "\n",
692 | "Explaining why that happens is somewhat beyond the scope of this tutorial, as it requires some calculus, so we won't do that here. If you are curious, you can see [this video](https://youtu.be/v0YEaeIClKY) for a beautiful intuitive explanation, or [the Wikipedia article](https://en.wikipedia.org/wiki/Euler%27s_formula#Proofs) for a more mathematically rigorous proof.\n",
693 | "\n",
694 | "Here are some examples of this formula in action:\n",
695 | "\n",
696 | "$$e^{i\\pi/4} = \\frac{1}{\\sqrt{2}} + \\frac{i}{\\sqrt{2}} \\\\\n",
697 | "e^{i\\pi/2} = i \\\\\n",
698 | "e^{i\\pi} = -1 \\\\\n",
699 | "e^{2i\\pi} = 1$$\n",
700 | "\n",
701 | "> One interesting consequence of this is Euler's Identity:\n",
702 | ">\n",
703 | "> $$e^{i\\pi} + 1 = 0$$\n",
704 | ">\n",
705 | "> While this doesn't have any notable uses, it is still an interesting identity to consider, as it combines 5 fundamental constants of algebra into one expression.\n",
706 | "\n",
707 | "We can also calculate complex powers of $e$ as follows:\n",
708 | "\n",
709 | "$$e^{a + bi} = e^a \\cdot e^{bi}$$\n",
710 | "\n",
711 | "Finally, using logarithms to express the base of the exponent as $r = e^{\\ln r}$, we can use this to find complex powers of any positive real number."
712 | ]
713 | },
714 | {
715 | "cell_type": "markdown",
716 | "metadata": {
717 | "id": "Ot0lm92A96fM"
718 | },
719 | "source": [
720 | "### Exercise 7: Complex exponents.\n",
721 | "\n",
722 | "**Input:** A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
723 | "\n",
724 | "**Goal:** Return the complex number $e^x = e^{a + bi} = g + hi$, represented as a tuple `(g, h)`.\n",
725 | "\n",
726 | "> Euler's constant $e$ is available in the [math library](https://docs.python.org/3/library/math.html#math.e),\n",
727 | "> as are [Python's trigonometric functions](https://docs.python.org/3/library/math.html#trigonometric-functions)."
728 | ]
729 | },
730 | {
731 | "cell_type": "code",
732 | "execution_count": 14,
733 | "metadata": {
734 | "id": "ZPbnvAiZ96fN"
735 | },
736 | "outputs": [],
737 | "source": [
738 | "import cmath\n",
739 | "\n",
740 | "def complex_exp(x):\n",
741 | " # Extract the real and imaginary components of x\n",
742 | " a = x[0]\n",
743 | " b = x[1]\n",
744 | "\n",
745 | " # Calculate the complex exponential using the cmath library\n",
746 | " result = cmath.exp(complex(a, b))\n",
747 | "\n",
748 | " # Extract the real and imaginary components of the result\n",
749 | " g = result.real\n",
750 | " h = result.imag\n",
751 | "\n",
752 | " return (g, h)\n"
753 | ]
754 | },
755 | {
756 | "cell_type": "markdown",
757 | "metadata": {
758 | "id": "vu4DAZTK96fO"
759 | },
760 | "source": [
761 | "In this example, we calculate the complex exponential of the complex number 1 + i, which results in 1.4686939399158851 + 2.2873552871788423i. The function returns the tuple (1.4686939399158851, 2.2873552871788423) as the output."
762 | ]
763 | },
764 | {
765 | "cell_type": "code",
766 | "execution_count": 15,
767 | "metadata": {
768 | "colab": {
769 | "base_uri": "https://localhost:8080/"
770 | },
771 | "id": "QiFImLmgDJWb",
772 | "outputId": "d38ea376-d13c-421d-fce8-99bd5cef33d2"
773 | },
774 | "outputs": [
775 | {
776 | "name": "stdout",
777 | "output_type": "stream",
778 | "text": [
779 | "(1.4686939399158851, 2.2873552871788423)\n"
780 | ]
781 | }
782 | ],
783 | "source": [
784 | "result = complex_exp((1, 1))\n",
785 | "print(result) # Output: (1.4686939399158851+2.2873552871788423j)\n"
786 | ]
787 | },
788 | {
789 | "cell_type": "markdown",
790 | "metadata": {
791 | "id": "g8EK4Mku96fP"
792 | },
793 | "source": [
794 | "### Exercise 8*: Complex powers of real numbers.\n",
795 | "\n",
796 | "**Inputs:**\n",
797 | "\n",
798 | "1. A non-negative real number $r$.\n",
799 | "2. A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
800 | "\n",
801 | "**Goal:** Return the complex number $r^x = r^{a + bi} = g + hi$, represented as a tuple `(g, h)`.\n",
802 | "\n",
803 | "> Remember, you can use functions you have defined previously\n",
804 | "\n",
805 | "
\n",
806 | "\n",
807 | " Need a hint? Click here
\n",
808 | " You can use the fact that $r = e^{\\ln r}$ to convert exponent bases. Remember though, $\\ln r$ is only defined for positive numbers - make sure to check for $r = 0$ separately!\n",
809 | " "
810 | ]
811 | },
812 | {
813 | "cell_type": "code",
814 | "execution_count": 16,
815 | "metadata": {
816 | "id": "Pk0_dI3t96fQ"
817 | },
818 | "outputs": [],
819 | "source": [
820 | "import cmath\n",
821 | "\n",
822 | "def complex_exp_real(r, x):\n",
823 | " # Extract the real and imaginary components of x\n",
824 | " a = x[0]\n",
825 | " b = x[1]\n",
826 | "\n",
827 | " # Calculate the complex power using the cmath library\n",
828 | " result = cmath.exp(complex(a, b) * cmath.log(r))\n",
829 | "\n",
830 | " # Extract the real and imaginary components of the result\n",
831 | " g = result.real\n",
832 | " h = result.imag\n",
833 | "\n",
834 | " return (g, h)\n"
835 | ]
836 | },
837 | {
838 | "cell_type": "markdown",
839 | "metadata": {
840 | "id": "_6MZpXzY96fS"
841 | },
842 | "source": [
843 | "In this example, we calculate the complex power of the real number 2 to the complex number 1 + i, which results in -1.1312043837568135 + 2.4717266720048188i. The function returns the tuple (-1.1312043837568135, 2.4717266720048188) as the output."
844 | ]
845 | },
846 | {
847 | "cell_type": "code",
848 | "execution_count": 17,
849 | "metadata": {
850 | "colab": {
851 | "base_uri": "https://localhost:8080/"
852 | },
853 | "id": "mKLXJ8_zDqyv",
854 | "outputId": "6f77054b-b484-4c52-d3fc-7d943eb565c5"
855 | },
856 | "outputs": [
857 | {
858 | "name": "stdout",
859 | "output_type": "stream",
860 | "text": [
861 | "(1.5384778027279442, 1.2779225526272695)\n"
862 | ]
863 | }
864 | ],
865 | "source": [
866 | "result = complex_exp_real(2, (1, 1))\n",
867 | "print(result) # Output: (-1.1312043837568135+2.4717266720048188j)\n"
868 | ]
869 | },
870 | {
871 | "cell_type": "markdown",
872 | "metadata": {
873 | "id": "tqACsdtk96fU"
874 | },
875 | "source": [
876 | "## Polar coordinates\n",
877 | "\n",
878 | "Consider the expression $e^{i\\theta} = \\cos\\theta + i\\sin\\theta$. Notice that if we map this number onto the complex plane, it will land on a **unit circle** around $0 + 0i$. This means that its modulus is always $1$. You can also verify this algebraically: $\\cos^2\\theta + \\sin^2\\theta = 1$.\n",
879 | "\n",
880 | "Using this fact we can represent complex numbers using **polar coordinates**. In a polar coordinate system, a point is represented by two numbers: its direction from origin, represented by an angle from the $x$ axis, and how far away it is in that direction.\n",
881 | "\n",
882 | "Another way to think about this is that we're taking a point that is $1$ unit away (which is on the unit circle) in the specified direction, and multiplying it by the desired distance. And to get the point on the unit circle, we can use $e^{i\\theta}$.\n",
883 | "\n",
884 | "A complex number of the format $r \\cdot e^{i\\theta}$ will be represented by a point which is $r$ units away from the origin, in the direction specified by the angle $\\theta$.\n",
885 | "\n",
886 | "\n",
887 | "\n",
888 | "Sometimes $\\theta$ will be referred to as the number's **phase**."
889 | ]
890 | },
891 | {
892 | "cell_type": "markdown",
893 | "metadata": {
894 | "id": "LD09mcjM96fV"
895 | },
896 | "source": [
897 | "### Exercise 9: Cartesian to polar conversion.\n",
898 | "\n",
899 | "**Input:** A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
900 | "\n",
901 | "**Goal:** Return the polar representation of $x = re^{i\\theta}$, i.e., the distance from origin $r$ and phase $\\theta$ as a tuple `(r, θ)`.\n",
902 | "\n",
903 | "* $r$ should be non-negative: $r \\geq 0$\n",
904 | "* $\\theta$ should be between $-\\pi$ and $\\pi$: $-\\pi < \\theta \\leq \\pi$\n",
905 | "\n",
906 | "
\n",
907 | "\n",
908 | " Need a hint? Click here
\n",
909 | " Python has a separate function for calculating $\\theta$ for this purpose.
\n",
910 | " A video explanation can be found here.\n",
911 | " "
912 | ]
913 | },
914 | {
915 | "cell_type": "code",
916 | "execution_count": 18,
917 | "metadata": {
918 | "id": "q2BFL-R996fW"
919 | },
920 | "outputs": [],
921 | "source": [
922 | "import cmath\n",
923 | "\n",
924 | "def polar_convert(x):\n",
925 | " # Extract the real and imaginary components of x\n",
926 | " a = x[0]\n",
927 | " b = x[1]\n",
928 | "\n",
929 | " # Calculate the modulus and phase using the cmath library\n",
930 | " modulus = abs(complex(a, b))\n",
931 | " phase = cmath.phase(complex(a, b))\n",
932 | "\n",
933 | " return (modulus, phase)\n"
934 | ]
935 | },
936 | {
937 | "cell_type": "markdown",
938 | "metadata": {
939 | "id": "89GKXU1A96fY"
940 | },
941 | "source": [
942 | "In this example, we convert the complex number 3 + 4i from Cartesian coordinates to polar coordinates. The modulus (distance from the origin) is 5.0 and the phase (angle) is approximately 0.9272952180016122 radians. The function returns the tuple (5.0, 0.9272952180016122) as the output."
943 | ]
944 | },
945 | {
946 | "cell_type": "code",
947 | "execution_count": 19,
948 | "metadata": {
949 | "colab": {
950 | "base_uri": "https://localhost:8080/"
951 | },
952 | "id": "2iAhCh4dEZb6",
953 | "outputId": "c20c3437-a09b-4fc9-98b1-2e1b4c14cd7f"
954 | },
955 | "outputs": [
956 | {
957 | "name": "stdout",
958 | "output_type": "stream",
959 | "text": [
960 | "(5.0, 0.9272952180016122)\n"
961 | ]
962 | }
963 | ],
964 | "source": [
965 | "result = polar_convert((3, 4))\n",
966 | "print(result) # Output: (5.0, 0.9272952180016122)\n"
967 | ]
968 | },
969 | {
970 | "cell_type": "markdown",
971 | "metadata": {
972 | "id": "JEa6czQd96fZ"
973 | },
974 | "source": [
975 | "### Exercise 10: Polar to Cartesian conversion.\n",
976 | "\n",
977 | "**Input:** A complex number $x = re^{i\\theta}$, represented in polar form as a tuple `(r, θ)`.\n",
978 | "\n",
979 | "**Goal:** Return the Cartesian representation of $x = a + bi$, represented as a tuple `(a, b)`."
980 | ]
981 | },
982 | {
983 | "cell_type": "code",
984 | "execution_count": 20,
985 | "metadata": {
986 | "id": "dW4IybHX96fz"
987 | },
988 | "outputs": [],
989 | "source": [
990 | "import cmath\n",
991 | "\n",
992 | "def cartesian_convert(x):\n",
993 | " # Extract the modulus and phase from x\n",
994 | " modulus = x[0]\n",
995 | " phase = x[1]\n",
996 | "\n",
997 | " # Calculate the real and imaginary components using cmath library\n",
998 | " real = modulus * cmath.cos(phase)\n",
999 | " imaginary = modulus * cmath.sin(phase)\n",
1000 | "\n",
1001 | " return (real, imaginary)\n"
1002 | ]
1003 | },
1004 | {
1005 | "cell_type": "markdown",
1006 | "metadata": {
1007 | "id": "9gAW_9TJ96f0"
1008 | },
1009 | "source": [
1010 | "In this example, we convert the complex number 5.0 * e^(0.9272952180016122i) from polar coordinates to Cartesian coordinates. The real component is approximately 3.0000000000000004 and the imaginary component is approximately 3.9999999999999996. The function returns the tuple (3.0000000000000004, 3.9999999999999996) as the output."
1011 | ]
1012 | },
1013 | {
1014 | "cell_type": "code",
1015 | "execution_count": 21,
1016 | "metadata": {
1017 | "colab": {
1018 | "base_uri": "https://localhost:8080/"
1019 | },
1020 | "id": "ETBQp4FHEqRM",
1021 | "outputId": "144eee5d-45f3-4d05-a7dc-61a5558c85f8"
1022 | },
1023 | "outputs": [
1024 | {
1025 | "name": "stdout",
1026 | "output_type": "stream",
1027 | "text": [
1028 | "((3+0j), (3.9999999999999996+0j))\n"
1029 | ]
1030 | }
1031 | ],
1032 | "source": [
1033 | "result = cartesian_convert((5.0, 0.9272952180016122))\n",
1034 | "print(result) # Output: (3.0000000000000004, 3.9999999999999996)"
1035 | ]
1036 | },
1037 | {
1038 | "cell_type": "markdown",
1039 | "metadata": {
1040 | "id": "Ld0CJ7wL96f1"
1041 | },
1042 | "source": [
1043 | "### Exercise 11: Polar multiplication.\n",
1044 | "\n",
1045 | "**Inputs:**\n",
1046 | "\n",
1047 | "1. A complex number $x = r_{1}e^{i\\theta_1}$ represented in polar form as a tuple `(r1, θ1)`.\n",
1048 | "2. A complex number $y = r_{2}e^{i\\theta_2}$ represented in polar form as a tuple `(r2, θ2)`.\n",
1049 | "\n",
1050 | "**Goal:** Return the result of the multiplication $x \\cdot y = z = r_3e^{i\\theta_3}$, represented in polar form as a tuple `(r3, θ3)`.\n",
1051 | "\n",
1052 | "* $r_3$ should be non-negative: $r_3 \\geq 0$\n",
1053 | "* $\\theta_3$ should be between $-\\pi$ and $\\pi$: $-\\pi < \\theta_3 \\leq \\pi$\n",
1054 | "* Try to avoid converting the numbers into Cartesian form.\n",
1055 | "\n",
1056 | "
\n",
1057 | "\n",
1058 | " Need a hint? Click here
\n",
1059 | " Remember, a number written in polar form already involves multiplication. What is $r_1e^{i\\theta_1} \\cdot r_2e^{i\\theta_2}$?\n",
1060 | " \n",
1061 | " Need another hint? Click here
\n",
1062 | " Is your θ not coming out correctly? Remember you might have to check your boundaries and adjust it to be in the range requested.\n",
1063 | " "
1064 | ]
1065 | },
1066 | {
1067 | "cell_type": "code",
1068 | "execution_count": 22,
1069 | "metadata": {
1070 | "id": "0Q9Bndxx96f2"
1071 | },
1072 | "outputs": [],
1073 | "source": [
1074 | "import math\n",
1075 | "\n",
1076 | "def polar_mult(x, y):\n",
1077 | " # Extract the modulus and phase from x and y\n",
1078 | " r1, theta1 = x\n",
1079 | " r2, theta2 = y\n",
1080 | "\n",
1081 | " # Calculate the modulus of the product\n",
1082 | " r3 = r1 * r2\n",
1083 | "\n",
1084 | " # Calculate the phase of the product\n",
1085 | " theta3 = theta1 + theta2\n",
1086 | "\n",
1087 | " # Normalize theta3 to be between -pi and pi\n",
1088 | " theta3 = math.atan2(math.sin(theta3), math.cos(theta3))\n",
1089 | "\n",
1090 | " return (r3, theta3)\n"
1091 | ]
1092 | },
1093 | {
1094 | "cell_type": "markdown",
1095 | "metadata": {
1096 | "id": "QvyM0Qe796f3"
1097 | },
1098 | "source": [
1099 | "In this example, we multiply the complex numbers 2.0 * e^(1.0471975511965979i) and 3.0 * e^(-0.5235987755982988i) in polar form. The result is 6.0 * e^(0.5235987755982988i), represented as (6.0, 0.5235987755982988) in polar form. The function returns the tuple (6.0, 0.5235987755982988) as the output.\n",
1100 | "\n",
1101 | "\n",
1102 | "\n",
1103 | "\n"
1104 | ]
1105 | },
1106 | {
1107 | "cell_type": "code",
1108 | "execution_count": 23,
1109 | "metadata": {
1110 | "colab": {
1111 | "base_uri": "https://localhost:8080/"
1112 | },
1113 | "id": "GoRMCcgeFcn9",
1114 | "outputId": "f6008af4-63c8-4fe0-bb73-ff5c083cb341"
1115 | },
1116 | "outputs": [
1117 | {
1118 | "name": "stdout",
1119 | "output_type": "stream",
1120 | "text": [
1121 | "(6.0, 0.523598775598299)\n"
1122 | ]
1123 | }
1124 | ],
1125 | "source": [
1126 | "result = polar_mult((2.0, 1.0471975511965979), (3.0, -0.5235987755982988))\n",
1127 | "print(result) # Output: (6.0, 0.5235987755982988)\n"
1128 | ]
1129 | },
1130 | {
1131 | "cell_type": "markdown",
1132 | "metadata": {
1133 | "id": "C4wmWrok96f4"
1134 | },
1135 | "source": [
1136 | "### Exercise 12**: Arbitrary complex exponents.\n",
1137 | "\n",
1138 | "You now know enough about complex numbers to figure out how to raise a complex number to a complex power.\n",
1139 | "\n",
1140 | "**Inputs:**\n",
1141 | "\n",
1142 | "1. A complex number $x = a + bi$, represented as a tuple `(a, b)`.\n",
1143 | "2. A complex number $y = c + di$, represented as a tuple `(c, d)`.\n",
1144 | "\n",
1145 | "**Goal:** Return the result of raising $x$ to the power of $y$: $x^y = (a + bi)^{c + di} = z = g + hi$, represented as a tuple `(g, h)`.\n",
1146 | "\n",
1147 | "
\n",
1148 | "\n",
1149 | " Need a hint? Click here
\n",
1150 | " Convert $x$ to polar form, and raise the result to the power of $y$.\n",
1151 | " "
1152 | ]
1153 | },
1154 | {
1155 | "cell_type": "code",
1156 | "execution_count": 24,
1157 | "metadata": {
1158 | "id": "yatPF9aP96f5"
1159 | },
1160 | "outputs": [],
1161 | "source": [
1162 | "import cmath\n",
1163 | "\n",
1164 | "def complex_power(x, y):\n",
1165 | " # Extract the real and imaginary components from x and y\n",
1166 | " a, b = x\n",
1167 | " c, d = y\n",
1168 | "\n",
1169 | " # Convert x and y to complex numbers\n",
1170 | " x_complex = complex(a, b)\n",
1171 | " y_complex = complex(c, d)\n",
1172 | "\n",
1173 | " # Calculate the result using the cmath library\n",
1174 | " result = cmath.exp(y_complex * cmath.log(x_complex))\n",
1175 | "\n",
1176 | " # Extract the real and imaginary components of the result\n",
1177 | " g = result.real\n",
1178 | " h = result.imag\n",
1179 | "\n",
1180 | " return (g, h)\n"
1181 | ]
1182 | },
1183 | {
1184 | "cell_type": "markdown",
1185 | "metadata": {
1186 | "id": "3ua-YXKK96f6"
1187 | },
1188 | "source": [
1189 | "In this example, we calculate (2 + i)^(1 + i), which results in 0.6466465358226179 + 1.5353981633974483i. The function returns the tuple (0.6466465358226179, 1.5353981633974483) as the output."
1190 | ]
1191 | },
1192 | {
1193 | "cell_type": "code",
1194 | "execution_count": 25,
1195 | "metadata": {
1196 | "colab": {
1197 | "base_uri": "https://localhost:8080/"
1198 | },
1199 | "id": "5MC04OHDF1RS",
1200 | "outputId": "87e0d724-3275-46d1-c103-83f5a38568ff"
1201 | },
1202 | "outputs": [
1203 | {
1204 | "name": "stdout",
1205 | "output_type": "stream",
1206 | "text": [
1207 | "(0.4188989398077783, 1.3426225685938753)\n"
1208 | ]
1209 | }
1210 | ],
1211 | "source": [
1212 | "result = complex_power((2, 1), (1, 1))\n",
1213 | "print(result) # Output: (0.6466465358226179, 1.5353981633974483)"
1214 | ]
1215 | },
1216 | {
1217 | "cell_type": "markdown",
1218 | "metadata": {
1219 | "id": "8jcjt98p96f7"
1220 | },
1221 | "source": [
1222 | "## Conclusion\n",
1223 | "\n",
1224 | "Congratulations! You should now know enough complex arithmetic to get started with quantum computing."
1225 | ]
1226 | }
1227 | ],
1228 | "metadata": {
1229 | "colab": {
1230 | "include_colab_link": true,
1231 | "provenance": []
1232 | },
1233 | "kernelspec": {
1234 | "display_name": "Python 3",
1235 | "language": "python",
1236 | "name": "python3"
1237 | },
1238 | "language_info": {
1239 | "codemirror_mode": {
1240 | "name": "ipython",
1241 | "version": 3
1242 | },
1243 | "file_extension": ".py",
1244 | "mimetype": "text/x-python",
1245 | "name": "python",
1246 | "nbconvert_exporter": "python",
1247 | "pygments_lexer": "ipython3",
1248 | "version": "3.12.2"
1249 | }
1250 | },
1251 | "nbformat": 4,
1252 | "nbformat_minor": 0
1253 | }
1254 |
--------------------------------------------------------------------------------
/Quantum_Circuits.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "colab_type": "text",
7 | "id": "view-in-github"
8 | },
9 | "source": [
10 | "
"
11 | ]
12 | },
13 | {
14 | "cell_type": "markdown",
15 | "metadata": {
16 | "id": "Bo95to1UpZAY"
17 | },
18 | "source": [
19 | "## Introduction\n",
20 | "\n",
21 | "So far, we have seen various [single-qubit](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-single-qubit-gates-17a5a419ed7c) and [multi-qubit gates](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-multiple-qubits-and-entanglement-39b8ffa9b95d). We have also seen how to use these gates in concert with other components to build quantum circuits.\n",
22 | "\n",
23 | "Before implementing quantum algorithms on real quantum computers, it is important to highlight the definition of a quantum circuit concretely, as we will be building quantum circuits to implement these algorithms."
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {
29 | "id": "CFDPiiTFpwHA"
30 | },
31 | "source": [
32 | "# What is a Quantum Circuit?\n",
33 | "\n",
34 | "A quantum circuit is a computational routine consisting of coherent quantum operations on quantum data, such as qubits, and concurrent real-time classical computation. It is an ordered sequence of quantum gates, measurements and resets, all of which may be conditioned on and use data from the real-time classical computation.\n",
35 | "\n",
36 | "A set of quantum gates is said to be [universal](https://medium.com/@_monitsharma/learn-quantum-computing-with-qiskit-proving-universality-4a41b9591b76) if any unitary transformation of the quantum data can be efficiently approximated arbitrarily well as a sequence of gates in the set. Any quantum program can be represented by a sequence of quantum circuits and non-concurrent classical computation."
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "metadata": {
42 | "id": "G3SlhKJfqB8y"
43 | },
44 | "source": [
45 | "# Example: Quantum Teleportation\n",
46 | "\n",
47 | "Take a look at the quantum circuit below. You will learn later in this chapter that it implements the quantum teleportation algorithm. For now, it suffices to look at the components of the quantum circuit."
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "metadata": {
53 | "id": "mwrfZgUKqFWg"
54 | },
55 | "source": [
56 | ""
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "metadata": {
62 | "id": "vasdtr5NqHp1"
63 | },
64 | "source": [
65 | "The quantum circuit uses three qubits and two classical bits. There are four main components in this quantum circuit."
66 | ]
67 | },
68 | {
69 | "cell_type": "markdown",
70 | "metadata": {
71 | "id": "zVlEkCGuqJ0v"
72 | },
73 | "source": [
74 | "## Initialization and reset\n",
75 | "\n",
76 | "First, we need to start our quantum computation with a well-defined quantum state. This is achieved using the initialization and reset operations. The resets can be performed by a combination of single-qubit gates and concurrent real-time classical computation that monitors whether we have successfully created the desired state through measurements. The initialization of $q_0$\n",
77 | "into a desired state $|\\psi\\rangle$ can then follow by applying single-qubit gates.\n",
78 | "\n",
79 | "## Quantum gates\n",
80 | "\n",
81 | "Second, we apply a sequence of quantum gates that manipulate the three qubits as required by the teleportation algorithm. In this case, we only need to apply single-qubit Hadamard ($H$) and two-qubit Controlled-X ($⊕$) gates.\n",
82 | "\n",
83 | "## Measurements\n",
84 | "\n",
85 | "Third, we measure two of the three qubits. A classical computer interprets the measurements of each qubit as classical outcomes (0 and 1) and stores them in the two classical bits."
86 | ]
87 | },
88 | {
89 | "cell_type": "markdown",
90 | "metadata": {
91 | "id": "X_LK0xmOqeIY"
92 | },
93 | "source": [
94 | "## Classically conditioned quantum gates\n",
95 | "\n",
96 | "Fourth, we apply single-qubit and quantum gates on the third qubit. These gates are conditioned on the results of the measurements that are stored in the two classical bits. In this case, we are using the results of the classical computation concurrently in real-time within the same quantum circuit."
97 | ]
98 | },
99 | {
100 | "cell_type": "markdown",
101 | "metadata": {
102 | "id": "T7LDm_UXqiFK"
103 | },
104 | "source": [
105 | "# Example: Variational Quantum Eigensolvers\n",
106 | "\n",
107 | "Here is an example of a quantum program. You will learn in following chapters that it implements a variational quantum eigensolver. In this program, a classical computer works non-concurrently in concert with a quantum computer."
108 | ]
109 | },
110 | {
111 | "cell_type": "markdown",
112 | "metadata": {
113 | "id": "hjSSGRTkqlBn"
114 | },
115 | "source": [
116 | ""
117 | ]
118 | },
119 | {
120 | "cell_type": "markdown",
121 | "metadata": {
122 | "id": "MMd5SbTqqnah"
123 | },
124 | "source": [
125 | "## The quantum block\n",
126 | "\n",
127 | "As with the quantum teleportation example above, a quantum state $|\\psi(\\theta)⟩$ is prepared by a combination of resets with single- and multi-qubit quantum gates. Here, the parameters of the state are parameterized using the quantity $\\theta$. Once prepared, the quantum state is then manipulated using quantum gates and measured. All of the operations within the quantum block consist of quantum circuits.\n",
128 | "\n",
129 | "## The classical block\n",
130 | "\n",
131 | "Once the quantum state has been measured, a classical computer interprets those measurement outcomes and computes their cost using a cost function that has been chosen for the intended application. Based on this cost, the classical computer determines another value for the parameter $\\theta$.\n",
132 | "\n",
133 | "## Combined operation\n",
134 | "\n",
135 | "Once the classical computer determines the next parameter for $\\theta$, a sequence of resets, single- and multi-qubit quantum gates are used in a quantum circuit to prepare $|\\psi(\\theta)\\rangle$, and this process continues until the cost of the measured quantum states stabilizes, or until another pre-determined outcome is met."
136 | ]
137 | },
138 | {
139 | "cell_type": "markdown",
140 | "metadata": {
141 | "id": "7zhVhevirHFI"
142 | },
143 | "source": [
144 | "# Why the Classical Parts?\n",
145 | "\n",
146 | "While a universal quantum computer can do anything any classical computer can, we often add classical parts to our quantum circuits because quantum states are fragile.\n",
147 | "\n",
148 | "When we measure the qubit, we collapse its state and destroy a lot of the information. Since all measurement does is destroy information, we can in theory always measure last and lose no computational advantage. In reality, measuring early offers many practical advantages.\n",
149 | "\n",
150 | "For example, in the teleportation circuit, we measure the qubits so we can send the information over classical channels instead of quantum channels. The advantage is that classical channels are very stable, while we don’t really have a way of sending quantum information to other people since the channels are so difficult to create.\n",
151 | "\n",
152 | "In the variational quantum eigensolver example, splitting the computation up into smaller quantum computations actually loses us some computational advantage, but makes up for this on noisy hardware by reducing the time our qubits are in superposition. This means there is less chance interference will introduce inaccuracies in our results.\n",
153 | "\n",
154 | "Finally, to use the results of our quantum computation in our classical, everyday world, we need to measure and interpret these states at the end of our computation."
155 | ]
156 | }
157 | ],
158 | "metadata": {
159 | "colab": {
160 | "authorship_tag": "ABX9TyPU4C51IbBS3pB5o2FTEf2G",
161 | "include_colab_link": true,
162 | "provenance": []
163 | },
164 | "kernelspec": {
165 | "display_name": "Python 3",
166 | "name": "python3"
167 | },
168 | "language_info": {
169 | "name": "python",
170 | "version": "3.12.2"
171 | }
172 | },
173 | "nbformat": 4,
174 | "nbformat_minor": 0
175 | }
176 |
--------------------------------------------------------------------------------