diff --git a/.gitignore b/.gitignore
index 3899e32..88abe5d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,5 +23,7 @@ src/site
test
thirdparty
wheelhouse
-*.zhaoyilun
-*.png
+
+# documents
+doc/build
+doc/pages
diff --git a/doc/README.md b/doc/README.md
index f673191..a862e47 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -1,2 +1,15 @@
# PyQuafu Documentation by Sphinx
+## Install Requirements
+
+```bash
+pip install -r requirements.txt
+```
+
+## Build
+
+Currently, this script can only run on Unix system
+
+```bash
+python run.py
+```
diff --git a/doc/requirements.txt b/doc/requirements.txt
new file mode 100644
index 0000000..f6e0729
--- /dev/null
+++ b/doc/requirements.txt
@@ -0,0 +1,2 @@
+sphinx==7.3.7
+sphinx-rtd-theme==2.0.0
diff --git a/doc/run.py b/doc/run.py
new file mode 100644
index 0000000..ff09e62
--- /dev/null
+++ b/doc/run.py
@@ -0,0 +1,35 @@
+import json
+import os
+import subprocess
+
+
+def build_doc(version, tag):
+ os.environ["current_version"] = version
+ subprocess.run("git checkout " + tag, shell=True)
+ subprocess.run("git checkout master -- source/conf.py", shell=True)
+ subprocess.run("git checkout master -- source/versions.json", shell=True)
+ subprocess.run("make html", shell=True)
+
+
+def move_dir(src, dst):
+ subprocess.run(["mkdir", "-p", dst])
+ subprocess.run("mv " + src + "* " + dst, shell=True)
+
+
+if __name__ == "__main__":
+ ## First clean dir
+ subprocess.run("rm -rf build/ pages/", shell=True)
+
+ os.environ["build_all_docs"] = str(True)
+ os.environ["pages_root"] = "https://scq-cloud.github.io"
+
+ build_doc("latest", "master")
+ move_dir("./build/html/", "./pages/")
+
+ with open("source/versions.json", "r") as json_file:
+ docs = json.load(json_file)
+
+ for version in docs:
+ tag = docs[version]["tag"]
+ build_doc(version, tag)
+ move_dir("./build/html/", "./pages/" + version)
diff --git a/doc/source/_templates/versions.html b/doc/source/_templates/versions.html
new file mode 100644
index 0000000..545fbb0
--- /dev/null
+++ b/doc/source/_templates/versions.html
@@ -0,0 +1,18 @@
+
+
+ Version: {{ current_version }}
+
+
+
+ {% if versions|length >= 1 %}
+
+ - {{ _('Versions') }}
+ {% for the_version, url in versions %}
+ - {{ the_version }}
+ {% endfor %}
+
+ {% endif %}
+
+
+
+
diff --git a/doc/source/apiref/apiref_0.3.5.rst b/doc/source/apiref.rst
similarity index 100%
rename from doc/source/apiref/apiref_0.3.5.rst
rename to doc/source/apiref.rst
diff --git a/doc/source/user_guide/quafu_doc_0.3.5/output_23_0.png b/doc/source/assets/output_23_0.png
similarity index 100%
rename from doc/source/user_guide/quafu_doc_0.3.5/output_23_0.png
rename to doc/source/assets/output_23_0.png
diff --git a/doc/source/user_guide/quafu_doc_0.3.5/output_28_0.png b/doc/source/assets/output_28_0.png
similarity index 100%
rename from doc/source/user_guide/quafu_doc_0.3.5/output_28_0.png
rename to doc/source/assets/output_28_0.png
diff --git a/doc/source/user_guide/quafu_doc_0.3.5/output_37_1.png b/doc/source/assets/output_37_1.png
similarity index 100%
rename from doc/source/user_guide/quafu_doc_0.3.5/output_37_1.png
rename to doc/source/assets/output_37_1.png
diff --git a/doc/source/user_guide/quafu_doc_0.3.5/output_39_0.png b/doc/source/assets/output_39_0.png
similarity index 100%
rename from doc/source/user_guide/quafu_doc_0.3.5/output_39_0.png
rename to doc/source/assets/output_39_0.png
diff --git a/doc/source/user_guide/quafu_doc_0.3.5/output_41_0.png b/doc/source/assets/output_41_0.png
similarity index 100%
rename from doc/source/user_guide/quafu_doc_0.3.5/output_41_0.png
rename to doc/source/assets/output_41_0.png
diff --git a/doc/source/user_guide/quafu_doc_0.3.5/output_45_0.png b/doc/source/assets/output_45_0.png
similarity index 100%
rename from doc/source/user_guide/quafu_doc_0.3.5/output_45_0.png
rename to doc/source/assets/output_45_0.png
diff --git a/doc/source/user_guide/quafu_doc_0.3.5/output_55_0.png b/doc/source/assets/output_55_0.png
similarity index 100%
rename from doc/source/user_guide/quafu_doc_0.3.5/output_55_0.png
rename to doc/source/assets/output_55_0.png
diff --git a/doc/source/user_guide/quafu_doc_0.3.5/output_55_1.png b/doc/source/assets/output_55_1.png
similarity index 100%
rename from doc/source/user_guide/quafu_doc_0.3.5/output_55_1.png
rename to doc/source/assets/output_55_1.png
diff --git a/doc/source/user_guide/quafu_doc_0.3.5/output_67_1.png b/doc/source/assets/output_67_1.png
similarity index 100%
rename from doc/source/user_guide/quafu_doc_0.3.5/output_67_1.png
rename to doc/source/assets/output_67_1.png
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 23531d8..d9581d1 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -3,36 +3,57 @@
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
+import json
+import os
+
# -- package path -------------------------------------------
import sys
-import os
-package_path = os.path.join(os.getcwd(), '..\\..\\src\\')
+package_path = os.path.join(os.getcwd(), "..\\..\\src\\")
sys.path.insert(0, package_path)
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
-project = 'PyQuafu-Docs'
-copyright = '2023, BAQIS-ScQ-Cloud'
-author = 'BAQIS-ScQ-Cloud'
-release = '0.3.6'
+project = "PyQuafu-Docs"
+copyright = "2023, BAQIS-ScQ-Cloud"
+author = "BAQIS-ScQ-Cloud"
+release = "0.4.0"
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
-extensions = ['sphinx.ext.autodoc',
- 'sphinx.ext.napoleon'
- ] # 'sphinx.ext.autosummary'
+extensions = ["sphinx.ext.autodoc", "sphinx.ext.napoleon"] # 'sphinx.ext.autosummary'
-templates_path = ['_templates']
+templates_path = ["_templates"]
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = "sphinx_rtd_theme"
-html_static_path = ['_static']
+html_static_path = ["_static"]
# Use Napoleon interpreter to support Google style docstrings
-autodoc_typehints = 'description'
+autodoc_typehints = "description"
+
+# Build multi-versions
+build_all_docs = os.environ.get("build_all_docs")
+pages_root = os.environ.get("pages_root", "")
+
+if build_all_docs is not None:
+ current_version = os.environ.get("current_version")
+
+ html_context = {
+ "current_version": current_version,
+ "versions": [
+ ["0.2.x", pages_root + "/0.2.x"],
+ ["0.3.x", pages_root + "/0.3.x"]
+ ],
+ }
+
+ with open("versions.json", "r") as json_file:
+ docs = json.load(json_file)
+
+ for version in docs:
+ html_context["versions"].append([version, pages_root + "/" + version])
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 9bafb6b..3943647 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -6,21 +6,20 @@
Welcome to PyQuafu's documentation!
======================================
-`Quafu `_ shares open access to
-super-conducting quantum (ScQ) computing resources with public users from all around
-the world. As the python SDK of `Quafu `_, ``pyquafu``
-provides not only flexible and advanced interfaces to the experimental backends,
-but also useful toolkits for simulating, visualizing and more about quantum computation.
-This documentation describes its basic syntax and usages.
+`Quafu `_ shares open access to
+super-conducting quantum (ScQ) computing resources with public users from all around
+the world. As the python SDK of `Quafu `_, ``pyquafu``
+provides not only flexible and advanced interfaces to the experimental backends,
+but also useful toolkits for simulating, visualizing and more about quantum computation.
+This documentation describes its basic syntax and usages.
Contents
====================================
.. toctree::
:maxdepth: 2
- User Guide
- API Reference
- Historical Version
+ Tutorial
+ API Reference
Links
====================================
diff --git a/doc/source/release_note/Release Notes - v0.3.6.md b/doc/source/release_note/Release Notes - v0.3.6.md
deleted file mode 100644
index dff9f61..0000000
--- a/doc/source/release_note/Release Notes - v0.3.6.md
+++ /dev/null
@@ -1,11 +0,0 @@
-Release Notes - v0.3.6
-
-- Fixed bug of status code mixed up during receiving results.
-- Added attributes ``named_paras`` and ``named_pos`` into ``Instruction`` and all of its subclasses. This is to further unify interface of instructions. Added ``instructions`` into ``QuantumCircuit``, the former existing ``gates`` will contain only instances of ``QuantumGate`` in future.
-- Fixed some icon-missing bugs in ``CircuitPlotManager``, plots of all basic gates was tested.
-
-发布说明 - v0.3.6
-
-- 修复了接收结果时状态码混淆的bug。
-- 添加了属性 ``named_paras`` 和``named_pos`` 到 ``Instruction`` 和它的所有子类。这是为了进一步统一 ``Instruction`` 的接口。在 ``QuantumCircuit``中添加属性 ``instructions`` ,先前存在的``gates``在稍后的版本中将只包含``QuantumGate`` 的实例。
-- 修复了``CircuitPlotManager``中一些图标缺失的bug,测试了所有基本门的绘图。
\ No newline at end of file
diff --git a/doc/source/release_note/historical_version.rst b/doc/source/release_note/historical_version.rst
deleted file mode 100644
index cee8bf2..0000000
--- a/doc/source/release_note/historical_version.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-.. _historical_version:
-
-Historical Version
-==================
-
-.. note::
- Historical version and release notes will be loaded later.
diff --git a/doc/source/user_guide/quafu_doc_0.3.5/quafu_doc_0_3_5.rst b/doc/source/tutorial.rst
similarity index 68%
rename from doc/source/user_guide/quafu_doc_0.3.5/quafu_doc_0_3_5.rst
rename to doc/source/tutorial.rst
index bb393ba..121351a 100644
--- a/doc/source/user_guide/quafu_doc_0.3.5/quafu_doc_0_3_5.rst
+++ b/doc/source/tutorial.rst
@@ -1,11 +1,6 @@
User Guide
==========
-.. note::
- PyQuafu is under active development and this is user guide
- for the latest version(0.3.5). If you are using ``pyquafu<=0.2``,
- please see :ref:`historical_version`.
-
Installation
------------
@@ -18,7 +13,7 @@ line/terminal:
::
- pip install pyquafu
+ pip install pyquafu
Set up your Quafu account
-------------------------
@@ -46,10 +41,18 @@ experimental backends.
::
- system_name qubits status
- ScQ-P10 10 Online
- ScQ-P18 18 Online
- ScQ-P136 136 Online
+ system_name qubits status
+ ScQ-P10 10 Offline
+ ScQ-P18 18 None Status
+ Baiwang 136 Online
+ ScQ-P102 102 Offline
+ ScQ-P10C 10 Maintenance
+ Miaofeng 108 Online
+ Dongling 106 Online
+ Haituo 105 Online
+ Baihua 118 Online
+ Yunmeng 156 Online
+ Xiang 35 Offline
*Note*: The next time you visit ``pyquafu``, you don’t have to save the
token again. Yet a quafu token is not permanently validating, from time
@@ -77,12 +80,12 @@ other instructions.
.. code:: python
qc.x(0)
- qc.x(1)
- qc.cnot(2, 1)
- qc.ry(1, np.pi/2)
- qc.rx(2, np.pi)
- qc.rz(3, 0.1)
- qc.cz(2, 3)
+ qc.x(1)
+ qc.cnot(2, 1)
+ qc.ry(1, np.pi/2)
+ qc.rx(2, np.pi)
+ qc.rz(3, 0.1)
+ qc.cz(2, 3)
::
@@ -93,10 +96,13 @@ circuit.
.. code:: python
- # equivalent to qc.x(0)
- import quafu.elements.element_gates as qeg
- gate = qeg.XGate(pos=0)
+ # equivalent to qc.x(0)
+ from quafu.elements.element_gates import *
+ gate = XGate(pos=0)
qc.add_gate(gate)
+ # you may also use the left shift operator
+ # qc << XGate(pos=0)
+
This is actually what ``.name(args)`` functions do. You would find
the second style convenient when build a new circuit from existing one.
@@ -112,6 +118,7 @@ or use python-buitin ``dir()`` method.
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_used_qubits', 'add_gate', 'add_pulse', 'barrier', 'circuit', 'cnot', 'cp', 'cs', 'ct', 'cx', 'cy', 'cz', 'delay', 'draw_circuit', 'fredkin', 'from_openqasm', 'gates', 'h', 'id', 'iswap', 'layered_circuit', 'mcx', 'mcy', 'mcz', 'measure', 'measures', 'num', 'openqasm', 'p', 'plot_circuit', 'rx', 'rxx', 'ry', 'ryy', 'rz', 'rzz', 's', 'sdg', 'sw', 'swap', 'sx', 'sxdg', 'sy', 'sydg', 't', 'tdg', 'to_openqasm', 'toffoli', 'unitary', 'used_qubits', 'w', 'x', 'xy', 'y', 'z']
+
Measure
~~~~~~~
@@ -144,13 +151,13 @@ visualize quantum circuits. You can draw the circuit using the
::
q[0] ------X--------X-------------------- M->c[0]
-
+
q[1] ------X--------+----RY(1.571)------- M->c[1]
- |
+ |
q[2] ---------------*----RX(3.142)----*-- M->c[2]
- |
+ |
q[3] --RZ(0.100)----------------------Z-- M->c[4]
-
+
q[4] ------------------------------------ M->c[3]
Alternatively, you may create a figure by
@@ -210,6 +217,12 @@ circuit with openqasm text.
|
| |image1|
+
+Parameter
+~~~~~~~~~
+
+
+
Execution and Simulation
------------------------
@@ -235,10 +248,14 @@ If you set the ``compile`` parameter to ``False``, make sure that you
know the topology of the backend well and submit a valid circuit.
Send the quantum circuit to the backend and wait for the results.
+Note that, by default the ``wait`` option is set to be ``False``, which
+means that you need use the ``retrieve`` method to fetch results when task is done.
.. code:: python
- res = task.send(qc, wait=True)
+ res = task.send(qc)
+ # After task is done, you could fetch results as below
+ res = task.retrieve()
You can use the returned results to check the count and probability of
each measured bit string. The output bits are arranged in **big-endian**
@@ -255,7 +272,7 @@ convention by default, see also the next sectioin.
OrderedDict([('00100', 717), ('00110', 31), ('01000', 6), ('01100', 1185), ('01110', 39), ('10100', 22)])
{'00100': 0.3585, '00110': 0.0155, '01000': 0.003, '01100': 0.5925, '01110': 0.0195, '10100': 0.011}
-.. figure:: output_37_1.png
+.. figure:: assets/output_37_1.png
:alt: png
png
@@ -373,13 +390,13 @@ First, we initialize a circuit with three Hadamard gate
::
q[0] --H-- M->c[0]
-
+
q[1] ----- M->c[1]
-
+
q[2] --H-- M->c[2]
-
+
q[3] ----- M->c[3]
-
+
q[4] --H-- M->c[4]
Next, we set operators that need to be measured to calculate the energy
@@ -409,7 +426,7 @@ circuit is only executed twice, with measurement basis [[‘XXXXX’, [0, 1,
|
| |image5|
-.. figure:: output_55_1.png
+.. figure:: assets/output_55_1.png
:alt: png
png
@@ -434,9 +451,7 @@ Submit task asynchronously
--------------------------
In the above examples, we chose opening python kernal and waiting for
-the result. You may also set the ``wait=False`` in
-``send`` function to submit
-the task asynchronously. Here we use another example that measures the
+the result. You may also submit the task asynchronously. Here we use another example that measures the
qubit decoherence time :math:`T_1` to demonstrate the usage.
.. code:: python
@@ -450,12 +465,12 @@ Prepare parameters of a group of tasks and send the task asynchronously.
ts = range(0, 21, 1)
names = ["%dus" %t for t in ts]
- for name, t in zip(names, ts):
+ for name, t in zip(names, ts):
q = QuantumCircuit(3)
q.x(2)
q.delay(2, t, unit="us")
q.measure([2])
- res = task.send(q, wait=False, name=name, group="Q3_T1")
+ res = task.send(q, name=name, group="Q3_T1")
Here the ``delay`` options will idle the target qubit ``2`` for a
duration ``t`` in the time unit ``us`` (microsecond) and do nothing. In
@@ -475,28 +490,28 @@ method.
::
Group: Q3_T1
- task_id task_name status
- 326564501AF5CF47 0us Completed
- 32656450226701BD 1us Completed
- 326564502A80CC5D 2us Completed
- 3265645032D98C32 3us Completed
- 326564503AEFE7EA 4us Completed
- 326564600CFE2817 5us Completed
- 3265646014FFEA5F 6us Completed
- 326564601C2E9597 7us Completed
- 32656460240A93E6 8us Completed
- 326564602C15CFFB 9us Completed
- 3265646033EEBD20 10us Running
- 326564603B1A478D 11us In Queue
- 3265647006C96D3D 12us In Queue
- 326564700F71B85A 13us In Queue
- 32656470204A3472 14us In Queue
- 32656470384DCD98 15us In Queue
- 3265648004FB6BCF 16us In Queue
- 326564800DA63F54 17us In Queue
- 3265648022DAC675 18us In Queue
- 3265648036F7EA24 19us In Queue
- 326564901AB566FF 20us In Queue
+ task_id task_name status
+ 326564501AF5CF47 0us Completed
+ 32656450226701BD 1us Completed
+ 326564502A80CC5D 2us Completed
+ 3265645032D98C32 3us Completed
+ 326564503AEFE7EA 4us Completed
+ 326564600CFE2817 5us Completed
+ 3265646014FFEA5F 6us Completed
+ 326564601C2E9597 7us Completed
+ 32656460240A93E6 8us Completed
+ 326564602C15CFFB 9us Completed
+ 3265646033EEBD20 10us Running
+ 326564603B1A478D 11us In Queue
+ 3265647006C96D3D 12us In Queue
+ 326564700F71B85A 13us In Queue
+ 32656470204A3472 14us In Queue
+ 32656470384DCD98 15us In Queue
+ 3265648004FB6BCF 16us In Queue
+ 326564800DA63F54 17us In Queue
+ 3265648022DAC675 18us In Queue
+ 3265648036F7EA24 19us In Queue
+ 326564901AB566FF 20us In Queue
Once all the tasks are completed, we can do the next step to get
:math:`T_1`.
@@ -509,28 +524,28 @@ Once all the tasks are completed, we can do the next step to get
::
Group: Q3_T1
- task_id task_name status
- 326564501AF5CF47 0us Completed
- 32656450226701BD 1us Completed
- 326564502A80CC5D 2us Completed
- 3265645032D98C32 3us Completed
- 326564503AEFE7EA 4us Completed
- 326564600CFE2817 5us Completed
- 3265646014FFEA5F 6us Completed
- 326564601C2E9597 7us Completed
- 32656460240A93E6 8us Completed
- 326564602C15CFFB 9us Completed
- 3265646033EEBD20 10us Completed
- 326564603B1A478D 11us Completed
- 3265647006C96D3D 12us Completed
- 326564700F71B85A 13us Completed
- 32656470204A3472 14us Completed
- 32656470384DCD98 15us Completed
- 3265648004FB6BCF 16us Completed
- 326564800DA63F54 17us Completed
- 3265648022DAC675 18us Completed
- 3265648036F7EA24 19us Completed
- 326564901AB566FF 20us Completed
+ task_id task_name status
+ 326564501AF5CF47 0us Completed
+ 32656450226701BD 1us Completed
+ 326564502A80CC5D 2us Completed
+ 3265645032D98C32 3us Completed
+ 326564503AEFE7EA 4us Completed
+ 326564600CFE2817 5us Completed
+ 3265646014FFEA5F 6us Completed
+ 326564601C2E9597 7us Completed
+ 32656460240A93E6 8us Completed
+ 326564602C15CFFB 9us Completed
+ 3265646033EEBD20 10us Completed
+ 326564603B1A478D 11us Completed
+ 3265647006C96D3D 12us Completed
+ 326564700F71B85A 13us Completed
+ 32656470204A3472 14us Completed
+ 32656470384DCD98 15us Completed
+ 3265648004FB6BCF 16us Completed
+ 326564800DA63F54 17us Completed
+ 3265648022DAC675 18us Completed
+ 3265648036F7EA24 19us Completed
+ 326564901AB566FF 20us Completed
.. code:: python
@@ -575,7 +590,7 @@ for a quick start.
print('Tasks info stored')
print("Task list:")
for task_info in db.find_all_tasks():
- print_task_info(task_info)
+ print_task_info(task_info)
break # this is to avoid demo too long, you may cancel this line to view the whole info
::
@@ -604,10 +619,128 @@ Finally, you can also retrieve a single task using its unique
{'0': 0.662, '1': 0.338}
-.. |png| image:: output_23_0.png
-.. |image1| image:: output_28_0.png
-.. |image2| image:: output_39_0.png
-.. |image3| image:: output_41_0.png
-.. |image4| image:: output_45_0.png
-.. |image5| image:: output_55_0.png
-.. |image6| image:: output_67_1.png
+.. |png| image:: assets/output_23_0.png
+.. |image1| image:: assets/output_28_0.png
+.. |image2| image:: assets/output_39_0.png
+.. |image3| image:: assets/output_41_0.png
+.. |image4| image:: assets/output_45_0.png
+.. |image5| image:: assets/output_55_0.png
+.. |image6| image:: assets/output_67_1.png
+
+
+Advanced usage
+--------------
+
+We offer some methods to build a quantum circuit more efficiently.
+
+Apply the same gate repeatedly
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Could use the ``power()`` method to apply the same gate consecutively.
+
+.. code:: python
+
+ import numpy as np
+ import math
+ from quafu import QuantumCircuit, simulate
+ from quafu.elements.element_gates import *
+
+ q = QuantumCircuit(2)
+ q << HGate(0)
+ q << HGate(1)
+ q << U3Gate(1, 0.2, 0.1, 0.3)
+ q << U3Gate(1, 0.2, 0.1, 0.3)
+ q << RYYGate(0, 1, 0.4)
+ q << RYYGate(0, 1, 0.4)
+ q << RXGate(0, 0.2)
+ q << RXGate(0, 0.2)
+ q << CRYGate(0, 1, 0.23)
+ q << CRYGate(0, 1, 0.23)
+
+ # Create another circuit using `power` method
+ q1 = QuantumCircuit(2)
+ q1 << HGate(0)
+ q1 << HGate(1)
+ q1 << U3Gate(1, 0.2, 0.1, 0.3).power(2)
+ q1 << RYYGate(0, 1, 0.4).power(2)
+ q1 << RXGate(0, 0.2).power(2)
+ q1 << CRYGate(0, 1, 0.23).power(2)
+
+ sv1 = simulate(q).get_statevector()
+ sv2 = simulate(q1).get_statevector()
+
+ # Check equivalence of two circuits
+ assert math.isclose(np.abs(np.dot(sv1, sv2.conj())), 1.0)
+
+
+Join two quantum circuits
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use the ``join()`` method to merge two different quantum circuit.
+
+.. code:: python
+
+ from quafu import QuantumCircuit, simulate
+ from quafu.elements.element_gates import *
+
+ q = QuantumCircuit(3)
+ q << (XGate(1))
+ q << (CXGate(0, 2))
+ q1 = QuantumCircuit(2)
+ q1 << HGate(1) << CXGate(1, 0)
+
+ # This extends the circuit `q` to 4 qubits,
+ # and apply `q1` to the 3rd and 4th qubit of `q`
+ q.join(q1, [2, 3])
+ q.draw_circuit()
+
+::
+
+ q[0] -------*-------
+ |
+ q[1] --X----|-------
+ |
+ q[2] -------+----+--
+ |
+ q[3] --H---------*--
+
+
+Reverse a quantum circuit
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+Use the ``dagger()`` method to reverse a quantum circuit.
+
+
+.. code:: python
+
+ import numpy as np
+ import math
+ from quafu import QuantumCircuit, simulate
+ from quafu.elements.element_gates import *
+
+ q = QuantumCircuit(3)
+ q << HGate(0)
+ q << HGate(1)
+ q << HGate(2)
+ q << RXGate(2, 0.3)
+ q << RYGate(2, 0.1)
+ q << CXGate(0, 1)
+ q << CRZGate(2, 1, 0.2)
+ q << RXXGate(0, 2, 1.2)
+
+ # Now create a reversed circuit of q
+ q1 = QuantumCircuit(3)
+ q1 << RXXGate(0, 2, -1.2)
+ q1 << CRZGate(2, 1, -0.2)
+ q1 << CXGate(0, 1)
+ q1 << RYGate(2, -0.1)
+ q1 << RXGate(2, -0.3)
+ q1 << HGate(0)
+ q1 << HGate(1)
+ q1 << HGate(2)
+
+ # Check equivalence
+ sv0 = simulate(q.dagger()).get_statevector()
+ sv1 = simulate(q1).get_statevector()
+ assert math.isclose(np.abs(np.dot(sv0, sv1.conj())), 1.0)
diff --git a/doc/source/versions.json b/doc/source/versions.json
new file mode 100644
index 0000000..142b029
--- /dev/null
+++ b/doc/source/versions.json
@@ -0,0 +1,5 @@
+{
+ "0.4.0": {
+ "tag": "tags/v0.4.0"
+ }
+}
diff --git a/quafu/tasks/tasks.py b/quafu/tasks/tasks.py
index 501d245..329b794 100644
--- a/quafu/tasks/tasks.py
+++ b/quafu/tasks/tasks.py
@@ -181,7 +181,7 @@ def run(self, qc: QuantumCircuit, measure_base: List = None) -> ExecResult:
return res
def send(
- self, qc: QuantumCircuit, name: str = "", group: str = "", wait: bool = True
+ self, qc: QuantumCircuit, name: str = "", group: str = "", wait: bool = False
) -> ExecResult:
"""
Run the circuit on experimental device.