├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── check_mkdocs_build.yml │ └── deploy_docs.yaml ├── .gitignore ├── .gitmodules ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE ├── README.md ├── docs ├── CNAME ├── about.md ├── figures │ └── stack_diagram.png ├── get-started.md ├── hardware │ ├── about-oqd.md │ ├── devices.md │ ├── img │ │ ├── beryl-trap.png │ │ ├── bloodstone-trap.png │ │ ├── bloodstone-trap1.png │ │ └── bloodstone-trap2.png │ └── modules.md ├── img │ ├── logo-equilux-blackmedium.png │ ├── oqd-icon.png │ ├── oqd-logo-black.png │ └── oqd-logo-white.png ├── index.md ├── stylesheets │ ├── admonition_template.css │ ├── admonitions.css │ ├── brand.css │ └── headers.css └── tutorials │ ├── index.md │ ├── ising.md │ └── rabi-flopping.md ├── examples ├── adiabatic_linear.ipynb ├── adiabatic_sigmoid.ipynb ├── bell_state.ipynb ├── ghz_state.ipynb ├── ising_model.ipynb ├── one_qubit_rabi_flopping.ipynb ├── qaoa.ipynb └── quantum_scars.ipynb ├── mkdocs.yaml ├── pyproject.toml ├── pytest.ini └── uv.lock /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | - [ ] bug report 3 | - [ ] feature request 4 | 5 | 6 | * **What is the current behavior?** 7 | 8 | 9 | 10 | * **If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem** 11 | 12 | 13 | 14 | * **What is the expected behavior?** 15 | 16 | 17 | 18 | * **What is the motivation / use case for changing the behavior?** 19 | 20 | 21 | 22 | * **Please tell us about your environment:** 23 | 24 | - Version: 25 | - Platform: 26 | - Subsystem: 27 | 28 | 29 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc) -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **Please check if the PR fulfills these requirements** 2 | - [ ] The commit message follows our guidelines 3 | - [ ] Tests for the changes have been added (for bug fixes / features) 4 | - [ ] Docs have been added / updated (for bug fixes / features) 5 | 6 | 7 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 8 | 9 | 10 | 11 | * **What is the current behavior?** (You can also link to an open issue here) 12 | 13 | 14 | 15 | * **What is the new behavior (if this is a feature change)?** 16 | 17 | 18 | 19 | * **Does this PR introduce a breaking change?** (What changes might users need to make in their application due to this PR?) 20 | 21 | 22 | 23 | * **Other information**: 24 | -------------------------------------------------------------------------------- /.github/workflows/check_mkdocs_build.yml: -------------------------------------------------------------------------------- 1 | name: Check Mkdocs Build 2 | 3 | on: 4 | pull_request: 5 | branches: ["main"] 6 | 7 | permissions: 8 | contents: read 9 | 10 | jobs: 11 | check_mkdocs_build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout repo 15 | uses: actions/checkout@v4 16 | 17 | - name: Configure Git credentials 18 | run: | 19 | git config user.name github-actions[bot] 20 | git config user.email 41898282+github-actions[bot]@users.noreply.github.com 21 | 22 | - name: Install uv and set the python version 23 | uses: astral-sh/setup-uv@v5 24 | with: 25 | enable-cache: true 26 | 27 | - name: Retrieve Git submodules 28 | run: git submodule update --init --recursive && git submodule update --recursive --remote 29 | 30 | - name: Copy examples into docs folder 31 | run: cp -r examples/ docs/examples/ 32 | 33 | - name: Install repo 34 | run: uv sync --extra docs 35 | 36 | - name: Build docs 37 | run: uv run mkdocs build 38 | -------------------------------------------------------------------------------- /.github/workflows/deploy_docs.yaml: -------------------------------------------------------------------------------- 1 | name: Deploy Mkdocs Documentation 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | 7 | permissions: 8 | contents: write 9 | 10 | jobs: 11 | deploy_docs: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout repo 15 | uses: actions/checkout@v4 16 | 17 | - name: Configure Git Credentials 18 | run: | 19 | git config user.name github-actions[bot] 20 | git config user.email 41898282+github-actions[bot]@users.noreply.github.com 21 | 22 | - name: Install uv and set the python version 23 | uses: astral-sh/setup-uv@v5 24 | with: 25 | enable-cache: true 26 | 27 | - name: Retrieve Git submodules 28 | run: git submodule update --init --recursive && git submodule update --recursive --remote 29 | 30 | - name: Copy examples into docs folder 31 | run: cp -r examples/ docs/examples/ 32 | 33 | - name: Install repo 34 | run: uv sync --extra docs 35 | 36 | - name: Build docs 37 | run: uv run mkdocs gh-deploy --force 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | .idea/ 161 | gen/ 162 | 163 | *.code-workspace 164 | .DS_Store 165 | 166 | ######################################################################################## 167 | 168 | *.sublime-* 169 | 170 | 171 | /docs/src/notebooks/* 172 | .scratch/ 173 | _scripts/ 174 | .vscode/ 175 | 176 | # ignore copied examples files when building docs 177 | docs/examples/ 178 | tests/test.bat 179 | *.zip 180 | .pre-commit-config.yaml 181 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "oqd-core"] 2 | path = oqd-core 3 | url = https://github.com/OpenQuantumDesign/oqd-core 4 | [submodule "oqd-cloud"] 5 | path = oqd-cloud 6 | url = https://github.com/OpenQuantumDesign/oqd-cloud 7 | [submodule "oqd-analog-emulator"] 8 | path = oqd-analog-emulator 9 | url = https://github.com/OpenQuantumDesign/oqd-analog-emulator 10 | [submodule "oqd-compiler-infrastructure"] 11 | path = oqd-compiler-infrastructure 12 | url = https://github.com/OpenQuantumDesign/oqd-compiler-infrastructure 13 | [submodule "oqd-trical"] 14 | path = oqd-trical 15 | url = https://github.com/OpenQuantumDesign/oqd-trical 16 | [submodule "oqd-dataschema"] 17 | path = oqd-dataschema 18 | url = https://github.com/OpenQuantumDesign/oqd-dataschema 19 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, caste, color, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official email address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | *conduct@ethicalsource.dev*. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.1, available at 119 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 120 | 121 | Community Impact Guidelines were inspired by 122 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 123 | 124 | For answers to common questions about this code of conduct, see the FAQ at 125 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available 126 | at [https://www.contributor-covenant.org/translations][translations]. 127 | 128 | [homepage]: https://www.contributor-covenant.org 129 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 130 | [Mozilla CoC]: https://github.com/mozilla/diversity 131 | [FAQ]: https://www.contributor-covenant.org/faq 132 | [translations]: https://www.contributor-covenant.org/translations 133 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenQuantumDesign/equilux/2db5571765d3c62fc8842280d89d40bdc6f0b61a/CONTRIBUTING.md -------------------------------------------------------------------------------- /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 2024 Open Quantum Design 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 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenQuantumDesign/equilux/2db5571765d3c62fc8842280d89d40bdc6f0b61a/NOTICE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![Open Quantum Design](docs/img/logo-equilux-blackmedium.png) 2 | 3 |

4 | Program the world's first open-source, full-stack quantum computer. 5 |

6 | 7 | [![doc](https://img.shields.io/badge/documentation-lightblue)](https://docs.openquantumdesign.org/) 8 | [![PyPI Version](https://img.shields.io/pypi/v/equilux)](https://pypi.org/project/equilux) 9 | [![ci](https://github.com/OpenQuantumDesign/equilux/actions/workflows/deploy_docs.yaml/badge.svg)](https://github.com/OpenQuantumDesign/equilux/actions/workflows/deploy_docs.yaml) 10 | ![versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue) 11 | [![black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) 12 | [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](https://opensource.org/licenses/Apache-2.0) 13 | 14 | ## About 15 | Open Quantum Design (OQD) is a non-profit foundation supporting the development of full-stack, open-source quantum computers. 16 | OQD's current designs are based on laser-cooled trapped ion quantum computing hardware, including real-time control, backend and frontend software. 17 | This documentation covers the software components of the OQD stack, including the core programming interfaces, 18 | classical emulation backends, compiler infrastructure, and cloud server containers. 19 | 20 | `equilux` is the top-level package to access the full OQD software suite in a single place. 21 | 22 | ## What's here 23 | 24 | - [Quick Start](#quickstart)
25 | - [Installation](#installation)
26 | - [The Stack](#stack)
27 | - [Software](#software)
28 | - [Hardware](#hardware)
29 | - [Documentation](#documentation)
30 | 31 | ## Quick start 32 | 33 | ## Installation 34 | To install `equilux` and the suite Open Quantum Design software tools, 35 | ```bash 36 | pip install equilux 37 | ``` 38 | 39 | Alternatively, the repository can be cloned and installed locally, 40 | ```bash 41 | git clone https://github.com/OpenQuantumDesign/equilux 42 | pip install . 43 | ``` 44 | 45 | ## The stack 46 | 47 | 48 | Open Quantum Design's quantum computing stack can be interfaced at different levels, including the digital, analog, and atomic layers. 49 | ```mermaid 50 | block-beta 51 | columns 3 52 | 53 | block:Interface 54 | columns 1 55 | InterfaceTitle("Interfaces") 56 | InterfaceDigital["Digital Interface\nQuantum circuits with discrete gates"] 57 | space 58 | InterfaceAnalog["Analog Interface\n Continuous-time evolution with Hamiltonians"] 59 | space 60 | InterfaceAtomic["Atomic Interface\nLight-matter interactions between lasers and ions"] 61 | space 62 | end 63 | 64 | block:IR 65 | columns 1 66 | IRTitle("IRs") 67 | IRDigital["Quantum circuit IR\nopenQASM, LLVM+QIR"] 68 | space 69 | IRAnalog["openQSIM"] 70 | space 71 | IRAtomic["openAPL"] 72 | space 73 | end 74 | 75 | block:Emulator 76 | columns 1 77 | EmulatorsTitle("Classical Emulators") 78 | 79 | EmulatorDigital["Pennylane, Qiskit"] 80 | space 81 | EmulatorAnalog["QuTiP, QuantumOptics.jl"] 82 | space 83 | EmulatorAtomic["TrICal, QuantumIon.jl"] 84 | space 85 | end 86 | 87 | space 88 | block:RealTime 89 | columns 1 90 | RealTimeTitle("Real-Time") 91 | space 92 | RTSoftware["ARTIQ, DAX, OQDAX"] 93 | space 94 | RTGateware["Sinara Real-Time Control"] 95 | space 96 | RTHardware["Lasers, Modulators, Photodetection, Ion Trap"] 97 | space 98 | RTApparatus["Trapped-Ion QPU (171Yb+, 133Ba+)"] 99 | space 100 | end 101 | space 102 | 103 | InterfaceDigital --> IRDigital 104 | InterfaceAnalog --> IRAnalog 105 | InterfaceAtomic --> IRAtomic 106 | 107 | IRDigital --> IRAnalog 108 | IRAnalog --> IRAtomic 109 | 110 | IRDigital --> EmulatorDigital 111 | IRAnalog --> EmulatorAnalog 112 | IRAtomic --> EmulatorAtomic 113 | 114 | IRAtomic --> RealTimeTitle 115 | 116 | RTSoftware --> RTGateware 117 | RTGateware --> RTHardware 118 | RTHardware --> RTApparatus 119 | 120 | classDef title fill:#23627D,stroke:#141414,color:#FFFFFF; 121 | classDef digital fill:#c3e1ee,stroke:#141414,color:#141414; 122 | classDef analog fill:#afd7e9,stroke:#141414,color:#141414; 123 | classDef atomic fill:#9ccee3,stroke:#141414,color:#141414; 124 | classDef realtime fill:#88c4dd,stroke:#141414,color:#141414; 125 | 126 | classDef highlight fill:#F19D19,stroke:#141414,color:#141414,stroke-dasharray: 5 5; 127 | classDef normal fill:#fcebcf,stroke:#141414,color:#141414; 128 | 129 | class InterfaceTitle,IRTitle,EmulatorsTitle,RealTimeTitle title 130 | class InterfaceDigital,IRDigital,EmulatorDigital digital 131 | class InterfaceAnalog,IRAnalog,EmulatorAnalog analog 132 | class InterfaceAtomic,IRAtomic,EmulatorAtomic atomic 133 | class RTSoftware,RTGateware,RTHardware,RTApparatus realtime 134 | 135 | 136 | class Emulator normal 137 | class IR normal 138 | class RealTime normal 139 | class Interface normal 140 | ``` 141 | 142 | ### Software 143 | OQD's software stack components include Python interfaces at the digital, analog, and atomic layers, 144 | classical emulators, compiler infrastructure, and cloud server components. 145 | 146 | ### Hardware 147 | 148 | Planned supported hardware backends include 149 | the [Bloodstone](docs/hardware/devices.md) processor based on171Yb+ ions 150 | and the [Beryl](docs/hardware/devices.md) processor based on133Ba+ ions. 151 | 152 | 153 | 154 | ## Getting started 155 | Below is a short example of how to use the analog interface to specify, serialize, 156 | and simulate an analog quantum program - here, a single-qubit Rabi-flopping experiment. 157 | 158 | ```python 159 | from oqd_core.interface.analog.operator import PauliZ, PauliX 160 | from oqd_core.interface.analog.operation import AnalogCircuit, AnalogGate 161 | from oqd_core.backend.metric import Expectation 162 | from oqd_core.backend.task import Task, TaskArgsAnalog 163 | from oqd_analog_emulator.qutip_backend import QutipBackend 164 | 165 | X = PauliX() 166 | Z = PauliZ() 167 | 168 | Hx = AnalogGate(hamiltonian=X) 169 | 170 | circuit = AnalogCircuit() 171 | circuit.evolve(duration=10, gate=Hx) 172 | circuit.measure() 173 | 174 | args = TaskArgsAnalog( 175 | n_shots=100, 176 | fock_cutoff=4, 177 | metrics={"Z": Expectation(operator=Z)}, 178 | dt=1e-3, 179 | ) 180 | 181 | task = Task(program=circuit, args=args) 182 | 183 | backend = QutipBackend() 184 | results = backend.run(task=task) 185 | ``` 186 | 187 | ## Documentation 188 | Documentation can be found at [docs.openquantumdesign.org](https://docs.openquantumdesign.org/en/latest/). 189 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | docs.openquantumdesign.org -------------------------------------------------------------------------------- /docs/about.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Open Quantum Design (OQD) is a non-profit organization. Our mission is to develop full-stack open-source quantum computer designs by fostering a collaborative community of diverse contributors from academia, industry, and government. 4 | OQD's current designs are based on laser-cooled trapped ion quantum computing hardware and software. 5 | The OQD intellectual property was developed by University of Waterloo Professors Crystal Senko, Rajibul Islam and Roger Melko, with physicists, engineers, and computer scientists working at the [Institute for Quantum Computing](https://uwaterloo.ca/institute-for-quantum-computing/) and the [Perimeter Institute Quantum Intelligence Lab](https://perimeterinstitute.ca/perimeter-institute-quantum-intelligence-lab-piquil). 6 | 7 | OQD’s technology features novel and scalable approaches for the trapping, control, and read-out of ions. This includes a unique blade trap design, agile optical scheme for low crosstalk addressing of the ions, high-fidelity and all-to-all gate connectivity, and native support for mid-circuit measurements. 8 | 9 | All components of the stack will be open under an Apache 2.0 or similar license - from hardware designs and the middleware control stack, to the top level programming interfaces. OQD’s vision is to be a global leader in open quantum technology, driving breakthroughs that revolutionize science, industry, and society, in order to improve the quality of life for future generations. 10 | 11 | ## Why Open? 12 | 13 | Open-source is more accessible and a proven environment for innovation. By sharing resources, knowledge, and designs, a global community of participants from diverse backgrounds can contribute to and accelerate the development of quantum technologies. OQD is building a collaborative community for technology co-creation, in order to democratize and accelerate the benefits of quantum computing technologies for all. Our purpose is to harness the potential of open quantum technology for the betterment of society, ensuring equitable access to its benefits, to foster an environment for innovation, and nurture the quantum workforce of the future. 14 | 15 | 16 | ## OQD’s open-source approach: 17 | 18 | * Provides transparency and accessibility to software and hardware 19 | * Deepens connections between academia, industry, and government through a collaborative sandbox with clear rules of engagement 20 | * Builds trust through collective decision-making to the benefit of the ecosystem and technology 21 | * Fosters collaboration on the hardest technical challenges 22 | * Increases cost-efficiency through collaboration and standards development 23 | * Attracts and mobilizes IP into the quantum ecosystem 24 | * Fuels outreach and education to train the next generation of scientists and entrepreneurs 25 | 26 | 27 | [Join the OQD community.](https://openquantumdesign.org/#c4433dc0-643c-4539-b1ca-ec2bc1a04868) 28 | -------------------------------------------------------------------------------- /docs/figures/stack_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenQuantumDesign/equilux/2db5571765d3c62fc8842280d89d40bdc6f0b61a/docs/figures/stack_diagram.png -------------------------------------------------------------------------------- /docs/get-started.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | To install, 3 | ```bash 4 | pip install git+https://github.com/OpenQuantumDesign/equilux.git 5 | ``` 6 | 7 | Or clone the repository locally and install with: 8 | 9 | ```bash 10 | git clone https://github.com/OpenQuantumDesign/equilux 11 | pip install . 12 | ``` 13 | 14 | ## Documentation 15 | 16 | Documentation is implemented with [MkDocs](https://www.mkdocs.org/) and can be read from the [docs](https://github.com/OpenQuantumDesign/midstack/tree/main/docs) folder. 17 | 18 | To install the dependencies for documentation, run: 19 | 20 | ``` 21 | pip install -e ".[docs]" 22 | ``` 23 | 24 | To deploy the documentation server locally: 25 | 26 | ``` 27 | cp -r examples/ docs/examples/ 28 | mkdocs serve 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/hardware/about-oqd.md: -------------------------------------------------------------------------------- 1 | ## Components of a Trapped Ion Quantum Computer 2 | 3 | * **Vacuum chamber:** ultra-high vacuum environment isolates the ions from the environment. 4 | * **Trapping electrodes:** uses electromagnetic potentials to trap ions within an area of the chamber. 5 | * **Lasers:** an array of lasers at different wavelengths and powers initialize, manipulate, and measure the ions in the trap. 6 | * **Optical elements:** many optical components around the lasers control the beams’ frequency, polarization, phase, and intensity. 7 | * **Control electronics:** real-time control electronics orchestrate all of the components, utilizing field programmable gate array (FPGA) cards and radiofrequency components. 8 | * **User interface:** software lets users access and run the quantum computer in order to test ideas, run algorithms, and develop use-cases. 9 | 10 | ## What's unique about OQD's quantum computer? 11 | 12 | * All-to-all connectivity of qubits, high fidelity operations, and long-coherence times. 13 | * Agile and ultra-low crosstalk addressing of ions via a novel optical addressing scheme. 14 | * Ion trap and control systems that are designed from the ground up for mid-circuit measurements. 15 | * Modular real-time control hardware, building on top of the Sinara open-hardware ecosystem. 16 | * Reusable and extensible control software, aimed at replicating control elements across different trapped ion systems. 17 | * Ability to program the computers at multiple levels of abstraction, depending on users’ needs and expertise. This includes defining and running quantum programs as digital circuits, analog circuits, and atomic protocols. 18 | * Suite of state-of-the-art classical emulator backends for testing, prototyping, and validating quantum programs. 19 | 20 | ## References 21 | 22 | 1. Maslov, D., Nam, Y. & Kim, J. An Outlook for Quantum Computing [Point of View]. Proc. IEEE 107, 5–10 (2019). 23 | 2. Pogorelov, I. et al. Compact Ion-Trap Quantum Computing Demonstrator. PRX Quantum 2, 020343 (2021). 24 | 3. Blatt, R. & Wineland, D. Entangled states of trapped atomic ions. Nature 453, 1008–1015 (2008). 25 | 4. Shammah, N. et al. Open Hardware in Quantum Technology. Preprint at [https://doi.org/10.48550/arXiv.2309.17233](https://doi.org/10.48550/arXiv.2309.17233) (2023). 26 | -------------------------------------------------------------------------------- /docs/hardware/devices.md: -------------------------------------------------------------------------------- 1 | # 2 | 3 |

4 | Logo 5 | Logo 6 |

7 | 8 |
9 |

10 | Open Quantum Design: Quantum Processor Hardware 11 |

12 |
13 | 14 | 15 | ## What's Here 16 | The heart of Open Quantum Design's mission and vision is to build open-source, full-stack 17 | quantum computers. The second generation of trapped-ion devices, coined [Bloodstone](#bloodstone) and [Beryl](#beryl), 18 | are currently under construction and testing. Designs, including electrical, photonic, and mechanical, 19 | will be opened sourced for community use and contribution. 20 | The real-time control stack builds on top of the open-hardware [Sinara](#sinara) ecosystem, 21 | including [ARTIQ](#artiq) and [DAX](#dax) 22 | 23 | 24 | ```mermaid 25 | block-beta 26 | columns 3 27 | 28 | block:Interface 29 | columns 1 30 | InterfaceTitle("Interfaces") 31 | InterfaceDigital["Digital Interface\nQuantum circuits with discrete gates"] 32 | space 33 | InterfaceAnalog["Analog Interface\n Continuous-time evolution with Hamiltonians"] 34 | space 35 | InterfaceAtomic["Atomic Interface\nLight-matter interactions between lasers and ions"] 36 | space 37 | end 38 | 39 | block:IR 40 | columns 1 41 | IRTitle("IRs") 42 | IRDigital["Quantum circuit IR\nopenQASM, LLVM+QIR"] 43 | space 44 | IRAnalog["openQSIM"] 45 | space 46 | IRAtomic["openAPL"] 47 | space 48 | end 49 | 50 | block:Emulator 51 | columns 1 52 | EmulatorsTitle("Classical Emulators") 53 | 54 | EmulatorDigital["Pennylane, Qiskit"] 55 | space 56 | EmulatorAnalog["QuTiP, QuantumOptics.jl"] 57 | space 58 | EmulatorAtomic["TrICal, QuantumIon.jl"] 59 | space 60 | end 61 | 62 | space 63 | block:RealTime 64 | columns 1 65 | RealTimeTitle("Real-Time") 66 | space 67 | RTSoftware["ARTIQ, DAX, OQDAX"] 68 | space 69 | RTGateware["Sinara Real-Time Control"] 70 | space 71 | RTHardware["Lasers, Modulators, Photodetection, Ion Trap"] 72 | space 73 | RTApparatus["Trapped-Ion QPU (171Yb+, 133Ba+)"] 74 | space 75 | end 76 | space 77 | 78 | InterfaceDigital --> IRDigital 79 | InterfaceAnalog --> IRAnalog 80 | InterfaceAtomic --> IRAtomic 81 | 82 | IRDigital --> IRAnalog 83 | IRAnalog --> IRAtomic 84 | 85 | IRDigital --> EmulatorDigital 86 | IRAnalog --> EmulatorAnalog 87 | IRAtomic --> EmulatorAtomic 88 | 89 | IRAtomic --> RealTimeTitle 90 | 91 | RTSoftware --> RTGateware 92 | RTGateware --> RTHardware 93 | RTHardware --> RTApparatus 94 | 95 | classDef title fill:#23627D,stroke:#141414,color:#FFFFFF; 96 | classDef digital fill:#c3e1ee,stroke:#141414,color:#141414; 97 | classDef analog fill:#afd7e9,stroke:#141414,color:#141414; 98 | classDef atomic fill:#9ccee3,stroke:#141414,color:#141414; 99 | classDef realtime fill:#88c4dd,stroke:#141414,color:#141414; 100 | 101 | classDef highlight fill:#F19D19,stroke:#141414,color:#141414,stroke-dasharray: 5 5; 102 | classDef normal fill:#fcebcf,stroke:#141414,color:#141414; 103 | 104 | class InterfaceTitle,IRTitle,EmulatorsTitle,RealTimeTitle title 105 | class InterfaceDigital,IRDigital,EmulatorDigital digital 106 | class InterfaceAnalog,IRAnalog,EmulatorAnalog analog 107 | class InterfaceAtomic,IRAtomic,EmulatorAtomic atomic 108 | class RTSoftware,RTGateware,RTHardware,RTApparatus realtime 109 | 110 | class RealTime highlight 111 | class Emulator normal 112 | class IR normal 113 | class Interface normal 114 | ``` 115 | 116 | 117 | ### Bloodstone 118 | * Ion species: 171Yb+ 119 | * Target number of qubits: 30 – 50 120 | * Trap architecture: Segmented Blade Trap 121 | * SPAM individual addressing: DMD 122 | * Coherent individual addressing with: Double-pass AOM + AOD 123 | 124 | ![Bloodstone - Vacuum Chamber & Trap 1](./img/bloodstone-trap1.png){: style="width:300px"} 125 | ![Bloodstone - Vacuum Chamber & Trap 2](./img/bloodstone-trap2.png){: style="width:300px"} 126 | 127 | ### Beryl 128 | * Ion species: 133Ba+, 137Ba+, 138Ba+ 129 | * Target number of qubits: 16 130 | * Trap architecture: [Sandia National Laboratories Phoenix Trap (HOA 2.0 platform)](https://arxiv.org/abs/2009.02398) 131 | * SPAM individual addressing: AOMs 132 | * Coherent individual addressing: Laser written waveguide + AOMs 133 | 134 | ![Beryl - Vacuum Chamber & Trap](./img/beryl-trap.png){: style="width:600px"} 135 | 136 | ## Real-time Control System 137 | The OQD stack builds on the [Sinara](https://m-labs.hk/experiment-control/sinara-core/) and [ARTIQ](https://m-labs.hk/artiq/) ecosystems for real-time control. 138 | 139 | ### Sinara 140 | [Sinara](https://sinara-hw.github.io/) is an open-source hardware ecosystem originally designed for use in quantum physics experiments running the ARTIQ control software. 141 | The hardware is also suitable for a broad range of laboratory and test & measurement applications. 142 | It is licensed under CERN OHL v1.2. 143 | 144 | 145 | ### ARTIQ (Advanced Real-Time Infrastructure for Quantum) 146 | [The Advanced Real-Time Infrastructure for Quantum physics framework](https://github.com/m-labs/artiq) is a software framework developed by M-Labs that provides Python bindings to the Sinara real-time signal generation and detection apparatus at the core of the electrical apparatus. 147 | ARTIQ functions by exposing control of the individual channels of custom-specified Sinara hardware in the Python programming language. 148 | The system maintains an internal clock and timeline. 149 | Events specified programmatically by the user are applied to the timeline and sent to the Sinara hardware with a series of queues. 150 | The Sinara hardware then executes the instructions with nanosecond precision on a series of FPGAs. 151 | 152 | ### DAX (Duke ARTIQ Extensions) 153 | [The Duke ARTIQ Extensions (DAX)](https://gitlab.com/duke-artiq/dax) are additional tools and capabilities drawn from traditional software design principles for the ARTIQ framework. 154 | ARTIQ allows low-level access to individual channels on the Sinara hardware. 155 | DAX provides a framework for grouping channels into logical modules representing appropriate experimental apparatus abstractions and services that use those modules to perform regular, repeatable tasks. 156 | -------------------------------------------------------------------------------- /docs/hardware/img/beryl-trap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenQuantumDesign/equilux/2db5571765d3c62fc8842280d89d40bdc6f0b61a/docs/hardware/img/beryl-trap.png -------------------------------------------------------------------------------- /docs/hardware/img/bloodstone-trap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenQuantumDesign/equilux/2db5571765d3c62fc8842280d89d40bdc6f0b61a/docs/hardware/img/bloodstone-trap.png -------------------------------------------------------------------------------- /docs/hardware/img/bloodstone-trap1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenQuantumDesign/equilux/2db5571765d3c62fc8842280d89d40bdc6f0b61a/docs/hardware/img/bloodstone-trap1.png -------------------------------------------------------------------------------- /docs/hardware/img/bloodstone-trap2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenQuantumDesign/equilux/2db5571765d3c62fc8842280d89d40bdc6f0b61a/docs/hardware/img/bloodstone-trap2.png -------------------------------------------------------------------------------- /docs/hardware/modules.md: -------------------------------------------------------------------------------- 1 | # OQD Hardware Modules 2 | 3 |
4 | 5 |
6 | 7 | -------------------------------------------------------------------------------- /docs/img/logo-equilux-blackmedium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenQuantumDesign/equilux/2db5571765d3c62fc8842280d89d40bdc6f0b61a/docs/img/logo-equilux-blackmedium.png -------------------------------------------------------------------------------- /docs/img/oqd-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenQuantumDesign/equilux/2db5571765d3c62fc8842280d89d40bdc6f0b61a/docs/img/oqd-icon.png -------------------------------------------------------------------------------- /docs/img/oqd-logo-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenQuantumDesign/equilux/2db5571765d3c62fc8842280d89d40bdc6f0b61a/docs/img/oqd-logo-black.png -------------------------------------------------------------------------------- /docs/img/oqd-logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenQuantumDesign/equilux/2db5571765d3c62fc8842280d89d40bdc6f0b61a/docs/img/oqd-logo-white.png -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # 2 | 3 |

4 | Logo 5 | Logo 6 |

7 | 8 |
9 |

10 | Open Quantum Design: Documentation 11 |

12 |
13 | 14 | Welcome to the Open Quantum Design (OQD) documentation! 15 | Open Quantum Design is a non-profit foundation supporting the development of full-stack, open-source quantum computers. 16 | OQD's current designs are based on laser-cooled trapped ion quantum computing hardware, including real-time control, backend and frontend software. 17 | This documentation covers the software components of the OQD stack, including the core programming interfaces, 18 | classical emulation backends, compiler infrastructure, and cloud server containers. 19 | 20 | ## The stack 21 | OQD's quantum computer stack can be interfaced at different levels, including the digital layer, analog layer, and atomic layer. 22 | ```mermaid 23 | block-beta 24 | columns 3 25 | 26 | block:Interface 27 | columns 1 28 | InterfaceTitle("Interfaces") 29 | InterfaceDigital["Digital Interface\nQuantum circuits with discrete gates"] 30 | space 31 | InterfaceAnalog["Analog Interface\n Continuous-time evolution with Hamiltonians"] 32 | space 33 | InterfaceAtomic["Atomic Interface\nLight-matter interactions between lasers and ions"] 34 | space 35 | end 36 | 37 | block:IR 38 | columns 1 39 | IRTitle("IRs") 40 | IRDigital["Quantum circuit IR\nopenQASM, LLVM+QIR"] 41 | space 42 | IRAnalog["openQSIM"] 43 | space 44 | IRAtomic["openAPL"] 45 | space 46 | end 47 | 48 | block:Emulator 49 | columns 1 50 | EmulatorsTitle("Classical Emulators") 51 | 52 | EmulatorDigital["Pennylane, Qiskit"] 53 | space 54 | EmulatorAnalog["QuTiP, QuantumOptics.jl"] 55 | space 56 | EmulatorAtomic["TrICal, QuantumIon.jl"] 57 | space 58 | end 59 | 60 | space 61 | block:RealTime 62 | columns 1 63 | RealTimeTitle("Real-Time") 64 | space 65 | RTSoftware["ARTIQ, DAX, OQDAX"] 66 | space 67 | RTGateware["Sinara Real-Time Control"] 68 | space 69 | RTHardware["Lasers, Modulators, Photodetection, Ion Trap"] 70 | space 71 | RTApparatus["Trapped-Ion QPU (171Yb+, 133Ba+)"] 72 | space 73 | end 74 | space 75 | 76 | InterfaceDigital --> IRDigital 77 | InterfaceAnalog --> IRAnalog 78 | InterfaceAtomic --> IRAtomic 79 | 80 | IRDigital --> IRAnalog 81 | IRAnalog --> IRAtomic 82 | 83 | IRDigital --> EmulatorDigital 84 | IRAnalog --> EmulatorAnalog 85 | IRAtomic --> EmulatorAtomic 86 | 87 | IRAtomic --> RealTimeTitle 88 | 89 | RTSoftware --> RTGateware 90 | RTGateware --> RTHardware 91 | RTHardware --> RTApparatus 92 | 93 | classDef title fill:#23627D,stroke:#141414,color:#FFFFFF; 94 | classDef digital fill:#c3e1ee,stroke:#141414,color:#141414; 95 | classDef analog fill:#afd7e9,stroke:#141414,color:#141414; 96 | classDef atomic fill:#9ccee3,stroke:#141414,color:#141414; 97 | classDef realtime fill:#88c4dd,stroke:#141414,color:#141414; 98 | 99 | classDef highlight fill:#F19D19,stroke:#141414,color:#141414,stroke-dasharray: 5 5; 100 | classDef normal fill:#fcebcf,stroke:#141414,color:#141414; 101 | 102 | class InterfaceTitle,IRTitle,EmulatorsTitle,RealTimeTitle title 103 | class InterfaceDigital,IRDigital,EmulatorDigital digital 104 | class InterfaceAnalog,IRAnalog,EmulatorAnalog analog 105 | class InterfaceAtomic,IRAtomic,EmulatorAtomic atomic 106 | class RTSoftware,RTGateware,RTHardware,RTApparatus realtime 107 | 108 | 109 | class Emulator normal 110 | class IR normal 111 | class RealTime normal 112 | class Interface normal 113 | ``` 114 | 115 | 116 | ## Getting Started 117 | Here's a short example of how to use the analog interface to specify, serialize, and simulate an analog quantum program. 118 | We use a simple, single-qubit Rabi-flopping experiment as an example: 119 | ```python 120 | from oqd_core.interface.analog.operator import PauliZ, PauliX 121 | from oqd_core.interface.analog.operation import AnalogCircuit, AnalogGate 122 | from oqd_core.backend.metric import Expectation 123 | from oqd_core.backend.task import Task, TaskArgsAnalog 124 | from oqd_analog_emulator.qutip_backend import QutipBackend 125 | 126 | X = PauliX() 127 | Z = PauliZ() 128 | 129 | Hx = AnalogGate(hamiltonian=X) 130 | 131 | circuit = AnalogCircuit() 132 | circuit.evolve(duration=10, gate=Hx) 133 | circuit.measure() 134 | 135 | args = TaskArgsAnalog( 136 | n_shots=100, 137 | fock_cutoff=4, 138 | metrics={"Z": Expectation(operator=Z)}, 139 | dt=1e-3, 140 | ) 141 | 142 | task = Task(program=circuit, args=args) 143 | 144 | backend = QutipBackend() 145 | results = backend.run(task=task) 146 | ``` 147 | -------------------------------------------------------------------------------- /docs/stylesheets/admonition_template.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --md-admonition-icon--template: url('data:image/svg+xml;charset=utf-8,') 3 | } 4 | .md-typeset .admonition.template, 5 | .md-typeset details.template { 6 | border-color: #FFFFFF; 7 | } 8 | .md-typeset .template > .admonition-title, 9 | .md-typeset .template > summary { 10 | background-color: #FFFFFF19; 11 | } 12 | .md-typeset .template > .admonition-title::before, 13 | .md-typeset .template > summary::before { 14 | background-color: #FFFFFF; 15 | -webkit-mask-image: var(--md-admonition-icon--template); 16 | mask-image: var(--md-admonition-icon--template); 17 | } 18 | -------------------------------------------------------------------------------- /docs/stylesheets/admonitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --md-admonition-icon--goal: url('data:image/svg+xml;charset=utf-8,'); 3 | } 4 | .md-typeset .admonition.goal, 5 | .md-typeset details.goal { 6 | border-color: #388e3c; 7 | font-size: 16px; 8 | } 9 | .md-typeset .goal > .admonition-title, 10 | .md-typeset .goal > summary { 11 | background-color: #388e3c19; 12 | } 13 | .md-typeset .goal > .admonition-title::before, 14 | .md-typeset .goal > summary::before { 15 | background-color: #388e3c; 16 | -webkit-mask-image: var(--md-admonition-icon--goal); 17 | mask-image: var(--md-admonition-icon--goal); 18 | } 19 | 20 | :root { 21 | --md-admonition-icon--important: url('data:image/svg+xml;charset=utf-8,'); 22 | } 23 | .md-typeset .admonition.important, 24 | .md-typeset details.important { 25 | border-color: #fbc02d; 26 | font-size: 16px; 27 | } 28 | .md-typeset .important > .admonition-title, 29 | .md-typeset .important > summary { 30 | background-color: #fbc02d19; 31 | } 32 | .md-typeset .important > .admonition-title::before, 33 | .md-typeset .important > summary::before { 34 | background-color: #fbc02d; 35 | -webkit-mask-image: var(--md-admonition-icon--important); 36 | mask-image: var(--md-admonition-icon--important); 37 | } 38 | 39 | :root { 40 | --md-admonition-icon--note: url('data:image/svg+xml;charset=utf-8,'); 41 | } 42 | .md-typeset .admonition.note, 43 | .md-typeset details.note { 44 | border-color: #1976d2; 45 | } 46 | .md-typeset .note > .admonition-title, 47 | .md-typeset .note > summary { 48 | background-color: #1976d219; 49 | } 50 | .md-typeset .note > .admonition-title::before, 51 | .md-typeset .note > summary::before { 52 | background-color: #1976d2; 53 | -webkit-mask-image: var(--md-admonition-icon--note); 54 | mask-image: var(--md-admonition-icon--note); 55 | } 56 | 57 | :root { 58 | --md-admonition-icon--warning: url('data:image/svg+xml;charset=utf-8,'); 59 | } 60 | .md-typeset .admonition.warning, 61 | .md-typeset details.warning { 62 | border-color: #f57c00; 63 | } 64 | .md-typeset .warning > .admonition-title, 65 | .md-typeset .warning > summary { 66 | background-color: #f57c0019; 67 | } 68 | .md-typeset .warning > .admonition-title::before, 69 | .md-typeset .warning > summary::before { 70 | background-color: #f57c00; 71 | -webkit-mask-image: var(--md-admonition-icon--warning); 72 | mask-image: var(--md-admonition-icon--warning); 73 | } 74 | 75 | 76 | :root { 77 | --md-admonition-icon--assumptions: url('data:image/svg+xml;charset=utf-8,'); 78 | } 79 | .md-typeset .admonition.assumptions, 80 | .md-typeset details.assumptions { 81 | border-color: #7B1FA2; 82 | } 83 | .md-typeset .assumptions > .admonition-title, 84 | .md-typeset .assumptions > summary { 85 | background-color: #7B1FA219; 86 | } 87 | .md-typeset .assumptions > .admonition-title::before, 88 | .md-typeset .assumptions > summary::before { 89 | background-color: #7B1FA2; 90 | -webkit-mask-image: var(--md-admonition-icon--assumptions); 91 | mask-image: var(--md-admonition-icon--assumptions); 92 | } 93 | 94 | 95 | 96 | :root { 97 | --md-admonition-icon--example: url('data:image/svg+xml;charset=utf-8,'); 98 | } 99 | .md-typeset .admonition.example, 100 | .md-typeset details.example { 101 | border-color: #512DA8; 102 | } 103 | .md-typeset .example > .admonition-title, 104 | .md-typeset .example > summary { 105 | background-color: #512DA819; 106 | } 107 | .md-typeset .example > .admonition-title::before, 108 | .md-typeset .example > summary::before { 109 | background-color: #512DA8; 110 | -webkit-mask-image: var(--md-admonition-icon--example); 111 | mask-image: var(--md-admonition-icon--example); 112 | } 113 | -------------------------------------------------------------------------------- /docs/stylesheets/brand.css: -------------------------------------------------------------------------------- 1 | /* Load custom fonts from Google Fonts */ 2 | @import url('https://fonts.googleapis.com/css2?family=Raleway:wght@600;700&family=Source+Serif+Pro&display=swap'); 3 | 4 | /* Base typography */ 5 | body, .md-typeset { 6 | font-family: 'Source Serif Pro', serif; 7 | } 8 | 9 | /* Headings */ 10 | h1, h2, h3, h4, h5, h6, 11 | .md-typeset h1, .md-typeset h2, .md-typeset h3, 12 | .md-typeset h4, .md-typeset h5, .md-typeset h6 { 13 | font-family: 'Raleway', sans-serif; 14 | font-weight: 700; /* Bold for headings */ 15 | } 16 | 17 | /* Subheadings */ 18 | .md-typeset h2, .md-typeset h3 { 19 | font-weight: 600; /* SemiBold for subheadings */ 20 | } 21 | 22 | /* Light mode overrides */ 23 | [data-md-color-scheme="default"] { 24 | --md-default-bg-color: #FFFFFF; 25 | --md-primary-fg-color: #23627D; /* blue accent */ 26 | --md-accent-fg-color: #23627D; 27 | } 28 | 29 | /* Dark mode overrides */ 30 | [data-md-color-scheme="slate"] { 31 | --md-default-bg-color: #141414; 32 | --md-primary-fg-color: #23627D; 33 | --md-accent-fg-color: #23627D; 34 | } 35 | 36 | 37 | 38 | /* Apply Raleway to all navigation and sidebar elements */ 39 | .md-nav, 40 | .md-nav__title, 41 | .md-nav__link, 42 | .md-header, 43 | .md-tabs, 44 | .md-sidebar, 45 | .md-sidebar__inner, 46 | .md-nav__item, 47 | .md-footer, 48 | .md-footer__inner { 49 | font-family: 'Raleway', sans-serif; 50 | font-weight: 600; /* SemiBold for ToC/nav for clarity */ 51 | } 52 | 53 | 54 | 55 | 56 | /* Page heading accent color for light mode */ 57 | [data-md-color-scheme="default"] .md-typeset h1, 58 | [data-md-color-scheme="default"] .md-typeset h2, 59 | [data-md-color-scheme="default"] .md-typeset h3, 60 | [data-md-color-scheme="default"] .md-typeset h4, 61 | [data-md-color-scheme="default"] .md-typeset h5, 62 | [data-md-color-scheme="default"] .md-typeset h6 { 63 | color: #7B2328; /* Warm yellow/orange for light mode */ 64 | } 65 | 66 | /* Page heading accent color for dark mode */ 67 | [data-md-color-scheme="slate"] .md-typeset h1, 68 | [data-md-color-scheme="slate"] .md-typeset h2, 69 | [data-md-color-scheme="slate"] .md-typeset h3, 70 | [data-md-color-scheme="slate"] .md-typeset h4, 71 | [data-md-color-scheme="slate"] .md-typeset h5, 72 | [data-md-color-scheme="slate"] .md-typeset h6 { 73 | /* color: #F19D19; Deep red for dark mode */ 74 | color: #E45B68; /* Deep red for dark mode */ 75 | } 76 | 77 | 78 | 79 | 80 | 81 | /* Light mode nav/ToC font color */ 82 | [data-md-color-scheme="default"] .md-nav, 83 | [data-md-color-scheme="default"] .md-nav__link, 84 | [data-md-color-scheme="default"] .md-header, 85 | [data-md-color-scheme="default"] .md-tabs { 86 | /*color: #222; /* Dark gray or your preferred shade */ 87 | color: #141414; 88 | } 89 | 90 | /* Dark mode nav/ToC font color */ 91 | [data-md-color-scheme="slate"] .md-nav, 92 | [data-md-color-scheme="slate"] .md-nav__link, 93 | [data-md-color-scheme="slate"] .md-header, 94 | [data-md-color-scheme="slate"] .md-tabs { 95 | color: #f0f0f0; /* Light gray or white */ 96 | } 97 | 98 | 99 | 100 | /* Top navigation bar text and icons should be light-colored */ 101 | .md-header, 102 | .md-header .md-header__title, 103 | .md-header .md-header__button, 104 | .md-header .md-tabs, 105 | .md-header .md-tabs__link, 106 | .md-header .md-header__topic, 107 | .md-header .md-header__option { 108 | color: #f0f0f0 !important; /* Light gray or white text */ 109 | fill: #f0f0f0 !important; /* Icons (SVG) */ 110 | } 111 | 112 | /* Hover state for links in header */ 113 | .md-header .md-tabs__link:hover { 114 | color: #ffffff !important; 115 | text-decoration: underline; 116 | } -------------------------------------------------------------------------------- /docs/stylesheets/headers.css: -------------------------------------------------------------------------------- 1 | .md-typeset h1 { 2 | color: #B72054; 3 | } 4 | 5 | .md-typeset h2 { 6 | color: #B72054; 7 | } 8 | 9 | .md-typeset h3 { 10 | color: #B72054; 11 | } 12 | 13 | .md-typeset h4 { 14 | color: #B72054; 15 | } 16 | 17 | .md-typeset h5 { 18 | color: #B72054; 19 | } 20 | 21 | .md-typeset h6 { 22 | color: #B72054; 23 | } 24 | -------------------------------------------------------------------------------- /docs/tutorials/index.md: -------------------------------------------------------------------------------- 1 | Here you will find some tutorials on using the analog interface for defining and running quantum programs. 2 | -------------------------------------------------------------------------------- /docs/tutorials/ising.md: -------------------------------------------------------------------------------- 1 | # Transverse field Ising model 2 | 3 | Next, let's implement everyone's favourite many-body Hamiltonian -- the transverse-field Ising model. 4 | The Hamiltonian is of the form, 5 | 6 | $$ 7 | H = \sum_{\langle ij \rangle} \sigma^x_i \sigma^x_j + h \sum_i \sigma^z_i 8 | $$ 9 | 10 | We will first implement this for two qubits only, and then expand to a larger system size. 11 | Throughout, we will use a transverse field strength of $h=1$, 12 | 13 | $$ 14 | H = \sigma^x_1 \sigma^x_2 + \sigma^z_1 + \sigma^z_2 15 | $$ 16 | 17 | ### Building the quantum program 18 | 19 | First we import the relevant modules, 20 | /// details | Imports 21 | 22 | ```py 23 | import numpy as np 24 | 25 | from oqd_core.interface.analog.operator import PauliI, PauliX, PauliZ, PauliY 26 | from oqd_core.interface.analog.operation import * 27 | from oqd_core.backend.metric import * 28 | from oqd_core.backend.task import Task 29 | from oqd_analog_emulator.qutip_backend import QutipBackend 30 | ``` 31 | 32 | /// 33 | 34 | As before, we can describe the Hamiltonian using the operators in the analog layer interface. 35 | ```py 36 | X, Z, I = PauliX(), PauliZ(), PauliI() 37 | 38 | hamiltonian = (X @ X) + (Z @ I) + (I @ Z) 39 | gate = AnalogGate(hamiltonian=hamiltonian) 40 | 41 | circuit = AnalogCircuit() 42 | circuit.evolve(duration=5, gate=gate) 43 | circuit.measure() 44 | ``` 45 | 46 | To generalize this to `n` qubits, we can use built-in Python operations and libraries, 47 | ```py 48 | import functools 49 | from operator import matmul, add 50 | 51 | X, Z, I = PauliX(), PauliZ(), PauliI() 52 | 53 | n = 5 54 | 55 | hamiltonian_xx = functools.reduce( 56 | add, [functools.reduce(matmul, [X if i in (j, (j+1)%n) else I for i in range(n)]) for j in range(n)] 57 | ) 58 | hamiltonian_z = functools.reduce( 59 | add, [functools.reduce(matmul, [Z if i==j else I for i in range(n)]) for j in range(n)] 60 | ) 61 | gate = AnalogGate(hamiltonian=hamiltonian_xx + hamiltonian_z) 62 | 63 | circuit = AnalogCircuit() 64 | circuit.evolve(duration=5, gate=gate) 65 | circuit.measure() 66 | ``` 67 | 68 | 69 | ### Setting up and running the classical emulation 70 | Similarly, we set up the settings for the classical emulation backend, 71 | including the number of shots and metrics (e.g., expectation values, entropy of entanglement) 72 | which we want to track through the time evolution. 73 | 74 | ```py 75 | args = TaskArgsAnalog( 76 | n_shots=100, 77 | metrics={ 78 | 'entanglement_entropy': EntanglementEntropyVN(qreg = [1]), 79 | }, 80 | dt=1e-2, 81 | ) 82 | 83 | backend = QutipBackend() 84 | results = backend.run(task = task) 85 | ``` 86 | -------------------------------------------------------------------------------- /docs/tutorials/rabi-flopping.md: -------------------------------------------------------------------------------- 1 | # Single qubit Rabi flopping 2 | 3 | First, let's implement a single-qubit Rabi flopping experiment. 4 | Here, a two-level system, initialized in the $\ket{0}$ basis state, oscillates between $\ket{0}$ and $\ket{1}$ during evolution. 5 | The Hamiltonian under which the state evolves is, 6 | $$ 7 | H = -\frac{\pi}{4}\sigma^x 8 | $$ 9 | 10 | ### Building the quantum program 11 | 12 | We will go through how to specify this quantum program using OQD's analog interface. First import the relevant modules, 13 | /// details | Imports 14 | 15 | ```py 16 | import numpy as np 17 | 18 | from oqd_core.interface.analog.operator import PauliI, PauliX, PauliZ, PauliY 19 | from oqd_core.interface.analog.operation import * 20 | from oqd_core.backend.metric import * 21 | from oqd_core.backend.task import Task 22 | from oqd_analog_emulator.qutip_backend import QutipBackend 23 | ``` 24 | 25 | /// 26 | 27 | Then we construct an [`AnalogGate`][oqd_core.interface.analog.operation.AnalogGate] object, 28 | ```py 29 | X = PauliX() 30 | gate = AnalogGate(hamiltonian= -(np.pi / 4) * X) 31 | ``` 32 | 33 | The [`AnalogCircuit`][oqd_core.interface.analog.operation.AnalogCircuit] represents a sequence of Hamiltonians 34 | which the quantum system evolves under for a fixed duration. Let's construct a circuit and add the gate from above and 35 | then measure, 36 | ```py 37 | circuit = AnalogCircuit() 38 | circuit.evolve(duration=3, gate=gate) 39 | circuit.measure() 40 | ``` 41 | 42 | ### Setting up the backend 43 | Now, let's emulate the time dynamics of our quantum system. We use one of the provided backends, 44 | here the [`QutipBackend`][oqd_analog_emulator.qutip_backend.QutipBackend], to solve the evolution of the quantum state 45 | through the circuit. We first initialize the backend and a [`TaskArgsAnalog`][oqd_core.backend.task.TaskArgsAnalog] 46 | object with the settings for the emulation, such as the number of shots, 47 | the metrics to track through the evolution (e.g., an expectation value), and the time step. 48 | ```py 49 | backend = QutipBackend() 50 | args = TaskArgsAnalog( 51 | n_shots=100, 52 | metrics={ 53 | "Z": Expectation(operator=Z), 54 | }, 55 | dt=1e-3, 56 | ) 57 | ``` 58 | 59 | 60 | ### Running the backend emulation 61 | Now, we simply use the `.run()` method of the backend to run the emulation of the time dynamics of the circuit. 62 | ``` py 63 | results = backend.run(task = task) 64 | ``` 65 | -------------------------------------------------------------------------------- /examples/ghz_state.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": false 7 | }, 8 | "source": [ 9 | "# Analog circuit for preparing a GHZ state\n", 10 | "\n", 11 | "GHZ states, much like Bell states, are highly entangled, multi-qubit states. They have broad application in quantum error correction, quantum communication protocols, quantum sensing, and tests of fundamental physics. Here, we will construct and emulate the analog quantum program to prepare a `n`-qubit GHZ state,\n", 12 | "\n", 13 | "$$\n", 14 | "|\\psi\\rangle = \\frac{1}{\\sqrt{2}} \\left( |0\\rangle^{\\otimes n} + |1\\rangle^{\\otimes n} \\right)\n", 15 | "$$\n", 16 | "\n", 17 | "First, we import the relevant libraries and OQD modules.\n" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": 1, 23 | "metadata": { 24 | "ExecuteTime": { 25 | "end_time": "2024-10-23T02:59:45.852561Z", 26 | "start_time": "2024-10-23T02:59:45.208541Z" 27 | } 28 | }, 29 | "outputs": [], 30 | "source": [ 31 | "import functools\n", 32 | "import itertools\n", 33 | "import operator\n", 34 | "import warnings\n", 35 | "\n", 36 | "import matplotlib.pyplot as plt\n", 37 | "import numpy as np\n", 38 | "import seaborn as sns\n", 39 | "from oqd_analog_emulator.qutip_backend import QutipBackend\n", 40 | "from oqd_core.backend.metric import Expectation\n", 41 | "from oqd_core.backend.task import Task, TaskArgsAnalog\n", 42 | "from oqd_core.interface.analog.operation import AnalogCircuit, AnalogGate\n", 43 | "from oqd_core.interface.analog.operator import PauliI, PauliX, PauliY, PauliZ\n", 44 | "\n", 45 | "warnings.filterwarnings(\"ignore\")" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 2, 51 | "metadata": { 52 | "ExecuteTime": { 53 | "end_time": "2024-10-23T02:59:45.857119Z", 54 | "start_time": "2024-10-23T02:59:45.854598Z" 55 | }, 56 | "collapsed": false 57 | }, 58 | "outputs": [], 59 | "source": [ 60 | "X, Y, Z, I = PauliX(), PauliY(), PauliZ(), PauliI() # noqa: E741\n", 61 | "\n", 62 | "\n", 63 | "n = 3" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 3, 69 | "metadata": { 70 | "ExecuteTime": { 71 | "end_time": "2024-10-23T02:59:45.866820Z", 72 | "start_time": "2024-10-23T02:59:45.860093Z" 73 | }, 74 | "collapsed": false 75 | }, 76 | "outputs": [], 77 | "source": [ 78 | "def sum(args):\n", 79 | " return functools.reduce(operator.add, args)\n", 80 | "\n", 81 | "\n", 82 | "def prod(args):\n", 83 | " return functools.reduce(operator.mul, args)\n", 84 | "\n", 85 | "\n", 86 | "def tensor(args):\n", 87 | " return functools.reduce(operator.matmul, args)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 4, 93 | "metadata": { 94 | "ExecuteTime": { 95 | "end_time": "2024-10-23T02:59:45.906Z", 96 | "start_time": "2024-10-23T02:59:45.898677Z" 97 | } 98 | }, 99 | "outputs": [], 100 | "source": [ 101 | "# Hadamard on first qubit\n", 102 | "ii = tensor([I for i in range(n)])\n", 103 | "xi = tensor([X if i == 0 else I for i in range(n)])\n", 104 | "yi = tensor([Y if i == 0 else I for i in range(n)])\n", 105 | "\n", 106 | "circuit = AnalogCircuit()\n", 107 | "\n", 108 | "# evolve Hadamard gate\n", 109 | "circuit.evolve(duration=(3 * np.pi) / 2, gate=AnalogGate(hamiltonian=ii))\n", 110 | "circuit.evolve(duration=np.pi / 2, gate=AnalogGate(hamiltonian=xi))\n", 111 | "circuit.evolve(duration=np.pi / 4, gate=AnalogGate(hamiltonian=-1 * yi))\n", 112 | "\n", 113 | "for j in range(1, n):\n", 114 | " xx = tensor([X if i in (0, j) else I for i in range(n)])\n", 115 | " mix = -1 * tensor([X if i == j else I for i in range(n)])\n", 116 | "\n", 117 | " # CNOT\n", 118 | " circuit.evolve(duration=np.pi / 4, gate=AnalogGate(hamiltonian=yi))\n", 119 | " circuit.evolve(duration=np.pi / 4, gate=AnalogGate(hamiltonian=xx))\n", 120 | " circuit.evolve(duration=np.pi / 4, gate=AnalogGate(hamiltonian=mix))\n", 121 | " circuit.evolve(duration=np.pi / 4, gate=AnalogGate(hamiltonian=-xi))\n", 122 | " circuit.evolve(duration=np.pi / 4, gate=AnalogGate(hamiltonian=-yi))\n", 123 | " circuit.evolve(duration=np.pi / 4, gate=AnalogGate(hamiltonian=ii))\n", 124 | "\n", 125 | "circuit.measure()" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 5, 131 | "metadata": { 132 | "ExecuteTime": { 133 | "end_time": "2024-10-23T02:59:45.908954Z", 134 | "start_time": "2024-10-23T02:59:45.902329Z" 135 | }, 136 | "collapsed": false 137 | }, 138 | "outputs": [], 139 | "source": [ 140 | "# define task args\n", 141 | "args = TaskArgsAnalog(\n", 142 | " n_shots=1000,\n", 143 | " fock_cutoff=4,\n", 144 | " metrics={\n", 145 | " f\"Z_{i}\": Expectation(operator=tensor([Z if j == i else I for j in range(n)]))\n", 146 | " for i in range(n)\n", 147 | " },\n", 148 | " dt=1e-2,\n", 149 | ")\n", 150 | "task = Task(program=circuit, args=args)" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": 6, 156 | "metadata": { 157 | "ExecuteTime": { 158 | "end_time": "2024-10-23T02:59:46.705998Z", 159 | "start_time": "2024-10-23T02:59:46.081825Z" 160 | }, 161 | "collapsed": false 162 | }, 163 | "outputs": [], 164 | "source": [ 165 | "backend = QutipBackend()\n", 166 | "results = backend.run(task=task)" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 7, 172 | "metadata": { 173 | "ExecuteTime": { 174 | "end_time": "2024-10-23T02:59:47.230939Z", 175 | "start_time": "2024-10-23T02:59:46.712315Z" 176 | }, 177 | "collapsed": false 178 | }, 179 | "outputs": [ 180 | { 181 | "data": { 182 | "image/png": "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", 183 | "text/plain": [ 184 | "
" 185 | ] 186 | }, 187 | "metadata": {}, 188 | "output_type": "display_data" 189 | } 190 | ], 191 | "source": [ 192 | "fig, ax = plt.subplots(1, 1, figsize=[6, 3])\n", 193 | "colors = sns.color_palette(palette=\"crest\", n_colors=max([4, n]))\n", 194 | "\n", 195 | "for k, (name, metric) in enumerate(results.metrics.items()):\n", 196 | " ax.plot(results.times, metric, label=f\"$\\\\langle {name} \\\\rangle$\", color=colors[k])\n", 197 | "ax.legend()\n", 198 | "ax.set(xlabel=\"Time\", ylabel=\"Expectation value\");" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 8, 204 | "metadata": { 205 | "ExecuteTime": { 206 | "end_time": "2024-10-23T02:59:47.754306Z", 207 | "start_time": "2024-10-23T02:59:47.235737Z" 208 | }, 209 | "collapsed": false 210 | }, 211 | "outputs": [ 212 | { 213 | "data": { 214 | "image/png": "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ealq1apWzwUAoFTDs1evXsU6LyQkRLKzs63uPW3aNBk0aJAMGDDAfNcQff/992X+/PkyevTofOfr/mPHjsmGDRukYsWKZp+WWgEACKhq25ycnGJttsGppUjthJSQkPD/Lxgaar4nJycXWgru0KGDqbatVauWNG/eXP70pz8V+ezMzEzJyMjIswEAUC4nSUhPTzehpyGYm35PS0sr8JoffvjBVNfqddrO+dRTT8nUqVPNEJrCTJ48WWJiYnxbXFyc478LAMC9SjRJgtepU6fkk08+kX379pnSY27Dhw+X0qQlXG3vnDNnjoSFhUmbNm1k//798vzzz8v48eMLvGbMmDGmXdVLS54EKACgzMJzy5Ytctddd5nZhTREq1WrZkqQUVFRJtRswrNGjRomAA8dOpRnv36vXbt2gddoD1tt69TrvJo2bWpKqhrk4eHh+a7RHrm6AQDgl2rbkSNHSo8ePeSnn34yYzs3btxoertqCfCFF16wupcGnV63evXqPCVL/a7tmgW58cYb5bvvvjPneX3zzTcmVAsKTgAA/B6eW7dulccee8x07NHSn3bG0SrQKVOmyJNPPml9P61OnTt3rrzxxhvy9ddfy+DBg02J1tv7tn///qba1UuPa2/bESNGmNDUnrnaYUg7EAEAEJDVtlplqsGptJpW2z212lQ74ui0fLZ69+4tR44ckXHjxpmqV50zd+XKlb5ORHp/7/OUBvUHH3xgSsDXXXedGeepQTpq1KiS/moAAJROeOo8t59//rk0atRIOnXqZEJP2zz/8pe/mGEjl2Lo0KFmK8jatWvz7dMqXa0uBgCgXFTbahWpti+qZ555Ri6//HJTlaqlR+0BCwCA25S45BkfH+/7rNW2WsUKAICbOTJJwvnz5+Wjjz6S1157TU6ePOlb8/Pnn3924vYAALir5KnDUrp162Y68mhPW52kPTo6Wp577jnzXeemBQDATUpc8tSerVp16x3n6XX33XfnGa8JAIBblLjk+emnn5oVTS6ckEBXNtFp8gAAcJsSlzwLWz3lP//5j6m+BQDAbUocnl26dDELVudew1M7Cumk7DrnLQAAblPialudv1Y7DDVr1kzOnj0rv/3tb+Xbb781k7y/+eabzrwlAABuCk+dHu/LL7+UJUuWmJ9a6hw4cKD07ds3TwciAADcokThee7cOWnSpIm89957Jix1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9badMWOGDBgwwLRz6uQIbdu2lerVq5txn3feeaeUFl0OTYvYt956q9SpU8e36aQMAAAEdMnzlVdekTlz5piVVhYuXCi///3vpWHDhjJu3Dg5duyYlBbmtQcAlNuSp1bV6mQISqtLdZFs7xCWN99806nHAADgrun5vCXMK6+80kyXp/bs2UPpEADgKo6FZ+fOneWdd94xn7Xtc+TIkXLHHXdI7969zYorAAC4hWPjPHV2H90qVPjfZtTFixfLhg0bpFGjRvLwww9LeHi4BCrGeQIAMvw9SUJ5Q3gCADL8NUnC2bNnZdu2bXL48GFTCs2tZ8+eTj4KAAC/cSw8V65caSaA16XHLqQrqXhXVgEAoLxzrMOQTpF3//33y8GDB33tn96N4AQAuIlj4akrqSQlJZkZhgAAcDPHwvO+++4zE7MDAOB2jvW2PX36tKm2veKKK6RFixZSsWLFPMeHDx8ugYretgCADH/0ttUp+D788EOJjIw0JVDtJOSlnwM5PAEAsOFYeP7hD3+QCRMmyOjRoyU01LHaYAAAAo5jKafrd+pUfAQnAMDtHEu6xMRE1tAEAAQFx6ptdSznlClT5IMPPpDrrrsuX4ehadOmOfUoAADcEZ7bt2+X66+/3nzesWNHnmO5Ow8BAFDeORaea9ascepWAAAENHr3AABQliXPe+65RxYuXGgGk+rnorz99tsleRQAAO4IT52JwdueqZ8BAAgGLIbN9HwAALHLAto8AQCwVKLw7Natm2zcuPGi5508eVKee+45mTVrVkkeBwBA+W/z1FVU7r33XlPM7dGjh8THx0tsbKyZHP6nn36SnTt3yvr162XFihXSvXt3ef755517cwAAymubZ2ZmpixdutRMzadBqXXF5sYhIdKsWTPp2rWrDBw4UJo2bSqBijZPAECGRRY43mFIH3rmzBmpXr16vin6AhXhCQDI8Md6nl76YIatAADcjN62AABYIjwBALBEeAIAYInwBADAn+F5/Phxef3112XMmDFy7Ngxs2/z5s2yf/9+Jx8DAIBfOdbbdtu2bZKQkGB62u7du1cGDRok1apVM6up7Nu3T/785z879SgAANxR8kxKSpIHH3xQvv32WzPDkNddd90l69atc+oxAAC4Jzw///xzefjhh/Ptr1u3rqSlpTn1GAAA3BOeERERZnaGC33zzTdyxRVXOPUYAADc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", 215 | "text/plain": [ 216 | "
" 217 | ] 218 | }, 219 | "metadata": {}, 220 | "output_type": "display_data" 221 | } 222 | ], 223 | "source": [ 224 | "fig, axs = plt.subplots(4, 1, sharex=True, figsize=[5, 9])\n", 225 | "\n", 226 | "state = np.array([basis.real + 1j * basis.imag for basis in results.state])\n", 227 | "bases = [\"\".join(bits) for bits in itertools.product(\"01\", repeat=n)]\n", 228 | "counts = {basis: results.counts.get(basis, 0) for basis in bases}\n", 229 | "\n", 230 | "ax = axs[0]\n", 231 | "ax.bar(x=bases, height=np.abs(state) ** 2, color=colors[0])\n", 232 | "ax.set(ylabel=\"Probability\")\n", 233 | "\n", 234 | "\n", 235 | "ax = axs[1]\n", 236 | "ax.bar(x=bases, height=list(counts.values()), color=colors[1])\n", 237 | "ax.set(ylabel=\"Count\")\n", 238 | "\n", 239 | "\n", 240 | "ax = axs[2]\n", 241 | "ax.bar(x=bases, height=state.real, color=colors[2])\n", 242 | "ax.set(ylabel=\"Amplitude (real)\")\n", 243 | "\n", 244 | "ax = axs[3]\n", 245 | "ax.bar(x=bases, height=state.imag, color=colors[3])\n", 246 | "ax.set_xticks([bases[0], bases[-1]])\n", 247 | "ax.set(xlabel=\"Basis state\", ylabel=\"Amplitude (imag)\", ylim=[-np.pi, np.pi]);" 248 | ] 249 | } 250 | ], 251 | "metadata": { 252 | "kernelspec": { 253 | "display_name": ".venv", 254 | "language": "python", 255 | "name": "python3" 256 | }, 257 | "language_info": { 258 | "codemirror_mode": { 259 | "name": "ipython", 260 | "version": 3 261 | }, 262 | "file_extension": ".py", 263 | "mimetype": "text/x-python", 264 | "name": "python", 265 | "nbconvert_exporter": "python", 266 | "pygments_lexer": "ipython3", 267 | "version": "3.12.9" 268 | } 269 | }, 270 | "nbformat": 4, 271 | "nbformat_minor": 2 272 | } 273 | -------------------------------------------------------------------------------- /examples/quantum_scars.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Quantum Many-Body Scars and Non-Ergodic Dynamics\n", 8 | "\n", 9 | "See: \n", 10 | "Turner, C.J., Michailidis, A.A., Abanin, D.A. et al. Weak ergodicity breaking from quantum many-body scars. Nature Phys 14, 745–749 (2018). https://doi.org/10.1038/s41567-018-0137-5\n", 11 | "[https://www.nature.com/articles/s41567-018-0137-5](https://www.nature.com/articles/s41567-018-0137-5)\n", 12 | "\n", 13 | "This notebook will reconstruct the behaviour demonstrated in Fig. 2.\n", 14 | "\n", 15 | "Quantum many-body scars are a phenomenon where a small set of atypical eigenstates within an otherwise thermalizing system lead to long-lived oscillations in dynamics, defying conventional ergodicity. Unlike many-body localization, which relies on disorder to prevent thermalization, these scars emerge in translation-invariant systems and cause the system to retain memory of its initial state for unexpectedly long times.\n", 16 | "\n", 17 | "This notebook implements a key early result in the study of quantum many-body scars, where a specific interacting Hamiltonian exhibits long-time oscillations when initialized in a period-2 charge density wave state. The recurrence of local observables and entanglement entropy oscillations suggest the presence of special eigenstates embedded in the spectrum." 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": {}, 23 | "source": [ 24 | "The Hamiltonian describes an interacting quantum system with constrained dynamics. It is given by: \n", 25 | "\n", 26 | "$$\n", 27 | "H = \\sum_{i} P^z_{i} X_{i+1} P^z_{i+2}\n", 28 | "$$\n", 29 | "\n", 30 | "where: \n", 31 | "- $X_{i}$ is the Pauli-X operator acting on site $i$, which flips the state of a qubit. \n", 32 | "- $P^z_{i} = \\frac{1 + Z_i}{2}$ is a projector that enforces a constraint on site $i$, involving the Pauli-Z operator (note a sign difference from the paper due to different basis state conventions)\n", 33 | "\n", 34 | "This Hamiltonian describes a system where spins (qubits) interact in a constrained way, meaning that spin flips (\\(X\\) terms) only occur when specific neighboring conditions are met (enforced by the $P^z$ projectors). \n", 35 | "\n", 36 | "## Initial States and the Scarred Dynamics \n", 37 | "\n", 38 | "A key observation in the study of quantum many-body scars is that certain initial states exhibit long-time oscillations instead of thermalizing. One such state is the **period-2 charge density wave** (CDW), defined as: \n", 39 | "\n", 40 | "$$\n", 41 | "\\left| \\mathbb{Z}_2 \\right\\rangle = \\left| 101010\\cdots \\right\\rangle\n", 42 | "$$\n", 43 | "\n", 44 | "where \"1\" represents an excited atom (spin-up) and \"0\" represents the ground state (spin-down). When evolving this state under the Hamiltonian, we observe periodic revivals in local observables and entanglement entropy, instead of the system fully thermalizing as expected in most quantum chaotic systems. \n", 45 | "\n", 46 | "## Why This Happens: Many-Body Scars \n", 47 | "\n", 48 | "Instead of having all eigenstates behave chaotically (ergodically), this system contains **special eigenstates** that are evenly spaced in energy and have an anomalously low entanglement entropy. These states lead to **non-ergodic** dynamics where the system oscillates between specific configurations instead of reaching thermal equilibrium. \n", 49 | "\n", 50 | "## Implementation in Code \n", 51 | "\n", 52 | "- The function `site(i, L)` constructs the local interaction term $P^z_{i} X_{i+1} P^z_{i+2}$. \n", 53 | "- The term `zk_gate` initializes the system in a charge density wave state. \n", 54 | "- The Hamiltonian `hamiltonian` is built as a sum over all sites. \n", 55 | "- The circuit then simulates time evolution using quantum gates based on the Hamiltonian. \n", 56 | "\n", 57 | "This implementation numerically reproduces the long-lived oscillations observed in quantum many-body scars." 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 2, 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "import numpy as np\n", 67 | "import matplotlib.pyplot as plt\n", 68 | "import seaborn as sns\n", 69 | "import functools\n", 70 | "import itertools\n", 71 | "import operator\n", 72 | "from rich.pretty import pprint\n", 73 | "\n", 74 | "import warnings\n", 75 | "warnings.filterwarnings(\"ignore\")\n", 76 | "\n", 77 | "from oqd_core.interface.analog.operator import PauliI, PauliX, PauliZ\n", 78 | "from oqd_core.interface.analog.operation import AnalogCircuit, AnalogGate\n", 79 | "from oqd_core.backend.metric import Expectation, EntanglementEntropyVN\n", 80 | "from oqd_core.backend.task import Task, TaskArgsAnalog\n", 81 | "from oqd_compiler_infrastructure.rule import PrettyPrint\n", 82 | "from oqd_compiler_infrastructure.walk import Post\n", 83 | "from oqd_core.compiler.analog.utils import PrintOperator\n", 84 | "from oqd_core.compiler.analog.passes.canonicalize import analog_operator_canonicalization \n", 85 | "\n", 86 | "from oqd_analog_emulator.qutip_backend import QutipBackend" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 3, 92 | "metadata": {}, 93 | "outputs": [], 94 | "source": [ 95 | "def sum(args):\n", 96 | " return functools.reduce(operator.add, args)\n", 97 | "\n", 98 | "def prod(args):\n", 99 | " return functools.reduce(operator.mul, args)\n", 100 | "\n", 101 | "def tensor(args):\n", 102 | " return functools.reduce(operator.matmul, args)" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 4, 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "def site(i: int, L: int):\n", 112 | " term = [PauliI() for j in range(L)]\n", 113 | " term[i] = (PauliI() + PauliZ()) * 0.5\n", 114 | " term[(i + 1) % L] = PauliX()\n", 115 | " term[(i + 2) % L] = (PauliI() + PauliZ()) * 0.5\n", 116 | " return tensor(term)" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 5, 122 | "metadata": {}, 123 | "outputs": [ 124 | { 125 | "name": "stdout", 126 | "output_type": "stream", 127 | "text": [ 128 | "Zk gate: PauliX() @ PauliI() @ PauliX() @ PauliI() @ PauliX() @ PauliI() @ PauliX() @ PauliI() @ PauliX() @ PauliI() @ PauliX() @ PauliI()\n", 129 | "Hamlitonian: ((0.5) * (PauliI() + PauliZ())) @ PauliX() @ ((0.5) * (PauliI() + PauliZ())) @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() + PauliI() @ ((0.5) * (PauliI() + PauliZ())) @ PauliX() @ ((0.5) * (PauliI() + PauliZ())) @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() + PauliI() @ PauliI() @ ((0.5) * (PauliI() + PauliZ())) @ PauliX() @ ((0.5) * (PauliI() + PauliZ())) @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() + PauliI() @ PauliI() @ PauliI() @ ((0.5) * (PauliI() + PauliZ())) @ PauliX() @ ((0.5) * (PauliI() + PauliZ())) @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() + PauliI() @ PauliI() @ PauliI() @ PauliI() @ ((0.5) * (PauliI() + PauliZ())) @ PauliX() @ ((0.5) * (PauliI() + PauliZ())) @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() + PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ ((0.5) * (PauliI() + PauliZ())) @ PauliX() @ ((0.5) * (PauliI() + PauliZ())) @ PauliI() @ PauliI() @ PauliI() @ PauliI() + PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ ((0.5) * (PauliI() + PauliZ())) @ PauliX() @ ((0.5) * (PauliI() + PauliZ())) @ PauliI() @ PauliI() @ PauliI() + PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ ((0.5) * (PauliI() + PauliZ())) @ PauliX() @ ((0.5) * (PauliI() + PauliZ())) @ PauliI() @ PauliI() + PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ ((0.5) * (PauliI() + PauliZ())) @ PauliX() @ ((0.5) * (PauliI() + PauliZ())) @ PauliI() + PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ ((0.5) * (PauliI() + PauliZ())) @ PauliX() @ ((0.5) * (PauliI() + PauliZ())) + ((0.5) * (PauliI() + PauliZ())) @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ ((0.5) * (PauliI() + PauliZ())) @ PauliX() + PauliX() @ ((0.5) * (PauliI() + PauliZ())) @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ PauliI() @ ((0.5) * (PauliI() + PauliZ()))\n" 130 | ] 131 | } 132 | ], 133 | "source": [ 134 | "n = 12\n", 135 | "k = 2\n", 136 | "zk_gate = sum([tensor([PauliX() if j%k == 0 else PauliI() for j in range(n)])])\n", 137 | "\n", 138 | "hamiltonian = sum([site(i, n) for i in range(n)])\n", 139 | "fstring = Post(PrintOperator())\n", 140 | "print(f\"Zk gate: {fstring(zk_gate)}\\nHamlitonian: {fstring(hamiltonian)}\")" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": 7, 146 | "metadata": {}, 147 | "outputs": [], 148 | "source": [ 149 | "circuit = AnalogCircuit()\n", 150 | "circuit.evolve(duration=np.pi/2, gate=AnalogGate(hamiltonian=zk_gate))\n", 151 | "circuit.evolve(duration=10, gate=AnalogGate(hamiltonian=hamiltonian))\n", 152 | "circuit.measure()" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": 8, 158 | "metadata": {}, 159 | "outputs": [], 160 | "source": [ 161 | "args = TaskArgsAnalog(\n", 162 | " n_shots=1000,\n", 163 | " fock_cutoff=1,\n", 164 | " metrics={\n", 165 | " f\"Z_{i}\": Expectation(operator=tensor([PauliZ() if j in (i, (i+1)%n) else PauliI() for j in range(n)]))\n", 166 | " for i in range(n)\n", 167 | " } | {\"S\": EntanglementEntropyVN(qreg=list(range(n//2)))},\n", 168 | " dt=1e-2,\n", 169 | ")\n", 170 | "task = Task(program=circuit, args=args)\n", 171 | "\n", 172 | "backend = QutipBackend()\n", 173 | "results = backend.run(task=task)" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": 9, 179 | "metadata": {}, 180 | "outputs": [ 181 | { 182 | "data": { 183 | "image/png": "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", 184 | "text/plain": [ 185 | "
" 186 | ] 187 | }, 188 | "metadata": {}, 189 | "output_type": "display_data" 190 | } 191 | ], 192 | "source": [ 193 | "fig, axs = plt.subplots(ncols=1, nrows=3, sharex=True, figsize=[6, 3])\n", 194 | "colors = sns.color_palette(palette=\"muted\", n_colors=max([20, n]))\n", 195 | "\n", 196 | "axs[0].plot(results.times, results.metrics['S'], label=f\"$S$\", color=colors[0])\n", 197 | "axs[1].plot(results.times, np.diff(results.metrics['S'], prepend=0.0), label=f\"$S$\", color=colors[1])\n", 198 | "\n", 199 | "expectations = {metric: value for (metric, value) in results.metrics.items() if 'Z' in metric}\n", 200 | "for k, (name, metric) in enumerate(expectations.items()):\n", 201 | " axs[2].plot(results.times, metric, label=f\"$\\\\langle {name} \\\\rangle$\", color=colors[k])\n", 202 | "\n", 203 | "for ax in axs:\n", 204 | " ax.axvspan(0, np.pi/2, color=\"gray\", alpha=0.4)\n", 205 | "\n", 206 | "axs[0].set(ylabel=r\"$S$\")\n", 207 | "axs[1].set(ylabel=r\"$\\Delta S$\")\n", 208 | "axs[2].set(ylabel=r\"$\\langle Z_i Z_{i+1} \\rangle$\")\n", 209 | "axs[-1].set(xlabel=\"Time\");" 210 | ] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": null, 215 | "metadata": {}, 216 | "outputs": [], 217 | "source": [] 218 | } 219 | ], 220 | "metadata": { 221 | "kernelspec": { 222 | "display_name": ".venv", 223 | "language": "python", 224 | "name": "python3" 225 | }, 226 | "language_info": { 227 | "codemirror_mode": { 228 | "name": "ipython", 229 | "version": 3 230 | }, 231 | "file_extension": ".py", 232 | "mimetype": "text/x-python", 233 | "name": "python", 234 | "nbconvert_exporter": "python", 235 | "pygments_lexer": "ipython3", 236 | "version": "3.12.7" 237 | } 238 | }, 239 | "nbformat": 4, 240 | "nbformat_minor": 2 241 | } 242 | -------------------------------------------------------------------------------- /mkdocs.yaml: -------------------------------------------------------------------------------- 1 | site_name: "Open Quantum Design" 2 | site_description: Open Quantum Design - the world's first open-source quantum computer 3 | 4 | repo_name: OpenQuantumDesign/equilux 5 | repo_url: https://github.com/OpenQuantumDesign/equilux.git 6 | 7 | copyright: Copyright © 2024-2025 Open Quantum Design 8 | 9 | use_directory_urls: false 10 | 11 | extra: 12 | social: 13 | - icon: fontawesome/brands/github 14 | link: https://github.com/OpenQuantumDesign 15 | name: Open Quantum Design GitHub 16 | - icon: fontawesome/solid/globe 17 | link: https://openquantumdesign.org 18 | name: Open Quantum Design Website 19 | 20 | nav: 21 | - Get Started: 22 | - Welcome: index.md 23 | - Installation: get-started.md 24 | 25 | - Tutorials: 26 | - Analog: 27 | - Analog Tutorials: tutorials/index.md 28 | - Rabi Flopping: tutorials/rabi-flopping.md 29 | - Ising Model: tutorials/ising.md 30 | - Examples: 31 | - Analog: 32 | - Rabi Flopping: examples/one_qubit_rabi_flopping.ipynb 33 | - Bell state preparation: examples/bell_state.ipynb 34 | - GHZ state preparation: examples/ghz_state.ipynb 35 | - Adiabatic state: 36 | - Linear time-dependence: examples/adiabatic_linear.ipynb 37 | - Sigmoid time-dependence: examples/adiabatic_sigmoid.ipynb 38 | - Ising model: examples/ising_model.ipynb 39 | - QAOA: examples/qaoa.ipynb 40 | - Quantum scars: examples/quantum_scars.ipynb 41 | 42 | - Core: "!include ./oqd-core/mkdocs.yaml" 43 | - Emulators: 44 | - Analog Emulator: "!include ./oqd-analog-emulator/mkdocs.yaml" 45 | - Trapped Ion Calculator: '!include ./oqd-trical/mkdocs.yaml' 46 | - Cloud: "!include ./oqd-cloud/mkdocs.yaml" 47 | - Compiler Infrastructure: "!include ./oqd-compiler-infrastructure/mkdocs.yaml" 48 | - Hardware: 49 | - OQD Processors: hardware/devices.md 50 | - OQD Modules: hardware/modules.md 51 | - About OQD Hardware: hardware/about-oqd.md 52 | - Utilities: 53 | - Data schemas: "!include ./oqd-dataschema/mkdocs.yaml" 54 | - About: about.md 55 | 56 | theme: 57 | name: material 58 | logo: img/oqd-icon.png 59 | favicon: img/oqd-icon.png 60 | 61 | palette: 62 | - media: "(prefers-color-scheme: light)" 63 | scheme: default 64 | primary: custom 65 | accent: custom 66 | toggle: 67 | icon: material/weather-sunny 68 | name: Switch to dark mode 69 | - media: "(prefers-color-scheme: dark)" 70 | scheme: slate 71 | primary: custom 72 | accent: custom 73 | toggle: 74 | icon: material/weather-night 75 | name: Switch to light mode 76 | 77 | 78 | 79 | features: 80 | - search.suggest 81 | - search.highlight 82 | - content.tabs.link 83 | - content.tooltips 84 | - content.code.annotate 85 | - content.code.copy 86 | - content.code.select 87 | - navigation.tabs 88 | - navigation.tabs.sticky 89 | - navigation.sections 90 | - navigation.top 91 | - navigation.prune 92 | - toc.follow 93 | 94 | plugins: 95 | - monorepo: 96 | - search 97 | - mkdocstrings: 98 | handlers: 99 | python: 100 | paths: 101 | - ./oqd-compiler-infrastructure/src 102 | - ./oqd-core/src 103 | - ./oqd-analog-emulator/src 104 | - ./oqd-cloud/src 105 | - ./oqd-trical/src 106 | - ./oqd-dataschema/src 107 | options: 108 | show_source: true 109 | show_root_heading: true 110 | show_symbol_type_heading: true 111 | show_symbol_type_toc: true 112 | show_submodules: true 113 | docstring_style: "google" 114 | docstring_section_style: "table" 115 | show_signature: true 116 | show_signature_annotations: true 117 | signature_crossrefs: true 118 | separate_signature: false 119 | group_by_category: true 120 | members_order: "source" 121 | import: 122 | - https://docs.python.org/3/objects.inv 123 | - https://docs.pydantic.dev/latest/objects.inv 124 | - https://qutip.readthedocs.io/en/qutip-4.7.x/objects.inv 125 | - https://pandas.pydata.org/docs/objects.inv 126 | - https://matplotlib.org/stable/objects.inv 127 | - https://numpy.org/doc/stable/objects.inv 128 | - mkdocs-jupyter: 129 | ignore_h1_titles: True 130 | 131 | markdown_extensions: 132 | - attr_list 133 | - toc: 134 | permalink: true 135 | toc_depth: 10 136 | 137 | - pymdownx.highlight: 138 | anchor_linenums: true 139 | line_spans: __span 140 | pygments_lang_class: true 141 | - pymdownx.inlinehilite 142 | - pymdownx.snippets 143 | 144 | # for notes/admonitions 145 | - pymdownx.blocks.admonition 146 | - pymdownx.blocks.details 147 | - pymdownx.blocks.html 148 | - pymdownx.blocks.tab: 149 | alternate_style: true 150 | 151 | - pymdownx.superfences: 152 | custom_fences: 153 | - name: mermaid 154 | class: mermaid 155 | format: !!python/name:pymdownx.superfences.fence_code_format 156 | 157 | - pymdownx.arithmatex: 158 | generic: true 159 | 160 | - mdx_truly_sane_lists: 161 | nested_indent: 2 162 | truly_sane: True 163 | 164 | extra_javascript: 165 | - javascripts/mathjax.js 166 | - https://polyfill.io/v3/polyfill.min.js?features=es6 167 | - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js 168 | - https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.0/es5/tex-mml-chtml.js 169 | 170 | extra_css: 171 | - stylesheets/headers.css 172 | - stylesheets/admonitions.css 173 | - stylesheets/brand.css 174 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=61.0", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | 6 | [project] 7 | name = "equilux" 8 | version = "0.1.1" 9 | requires-python = ">=3.10,<3.13" 10 | readme = "README.md" 11 | license = { text = "Apache 2.0" } 12 | keywords = [ 13 | "quantum", 14 | "computing", 15 | "analog", 16 | "digitial", 17 | "atomic", 18 | "simulation", 19 | "full-stack", 20 | ] 21 | classifiers = [ 22 | "Development Status :: 3 - Alpha", 23 | 24 | "Intended Audience :: Science/Research ", 25 | "Topic :: Scientific/Engineering :: Physics", 26 | "Topic :: Security :: Cryptography", 27 | "Topic :: Scientific/Engineering :: Information Analysis", 28 | 29 | "License :: OSI Approved :: Apache Software License", 30 | 31 | "Programming Language :: Python :: 3", 32 | "Programming Language :: Python :: 3.10", 33 | "Programming Language :: Python :: 3.11", 34 | "Programming Language :: Python :: 3.12", 35 | ] 36 | 37 | 38 | dependencies = [ 39 | "matplotlib", 40 | "seaborn", 41 | "oqd-compiler-infrastructure@git+https://github.com/openquantumdesign/oqd-compiler-infrastructure", 42 | "oqd-core @ git+https://github.com/openquantumdesign/oqd-core", 43 | "oqd-analog-emulator @ git+https://github.com/openquantumdesign/oqd-analog-emulator", 44 | "oqd-cloud @ git+https://github.com/openquantumdesign/oqd-cloud", 45 | ] 46 | 47 | [project.optional-dependencies] 48 | docs = [ 49 | "pymdown-extensions", 50 | "mkdocstrings", 51 | "mkdocs-material", 52 | "mkdocstrings-python", 53 | "mdx_truly_sane_lists", 54 | "jupyter==1.1.1", 55 | "jupyter_contrib_nbextensions==0.7.0", 56 | "mkdocs-jupyter==0.25.0", 57 | "mkdocs-monorepo-plugin", 58 | "notebook==6.4.12", 59 | ] 60 | 61 | [project.urls] 62 | Homepage = "https://github.com/OpenQuantumDesign/equilux" 63 | Documentation = "https://docs.openquantumdesign.org" 64 | Repository = "https://github.com/OpenQuantumDesign/equilux.git" 65 | Issues = "https://github.com/OpenQuantumDesign/equilux/issues" 66 | 67 | [dependency-groups] 68 | dev = ["pre-commit>=4.1.0"] 69 | 70 | [tool.ruff.lint] 71 | select = ["E4", "E7", "E9", "F", "I"] 72 | fixable = ["ALL"] 73 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | # pytest.ini 2 | [pytest] 3 | --------------------------------------------------------------------------------