\n",
- "chsh2_est_sim = chsh_est_sim[0].values + chsh_est_sim[1].values - chsh_est_sim[2].values + chsh_est_sim[3].values"
+ "chsh2_est_sim = (\n",
+ " chsh_est_sim[0].values\n",
+ " + chsh_est_sim[1].values\n",
+ " - chsh_est_sim[2].values\n",
+ " + chsh_est_sim[3].values\n",
+ ")"
]
},
{
@@ -305,21 +318,21 @@
"\n",
"fig, ax = plt.subplots(figsize=(10, 6))\n",
"# results from a simulator\n",
- "ax.plot(phases/np.pi, chsh1_est_sim, 'o-', label='CHSH1 Simulation')\n",
- "ax.plot(phases/np.pi, chsh2_est_sim, 'o-', label='CHSH2 Simulation')\n",
+ "ax.plot(phases / np.pi, chsh1_est_sim, \"o-\", label=\"CHSH1 Simulation\")\n",
+ "ax.plot(phases / np.pi, chsh2_est_sim, \"o-\", label=\"CHSH2 Simulation\")\n",
"# classical bound +-2\n",
- "ax.axhline(y=2, color='r', linestyle='--')\n",
- "ax.axhline(y=-2, color='r', linestyle='--')\n",
+ "ax.axhline(y=2, color=\"r\", linestyle=\"--\")\n",
+ "ax.axhline(y=-2, color=\"r\", linestyle=\"--\")\n",
"# quantum bound, +-2√2\n",
- "ax.axhline(y=np.sqrt(2)*2, color='b', linestyle='-.')\n",
- "ax.axhline(y=-np.sqrt(2)*2, color='b', linestyle='-.')\n",
+ "ax.axhline(y=np.sqrt(2) * 2, color=\"b\", linestyle=\"-.\")\n",
+ "ax.axhline(y=-np.sqrt(2) * 2, color=\"b\", linestyle=\"-.\")\n",
"# set x tick labels to the unit of pi\n",
- "ax.xaxis.set_major_formatter(tck.FormatStrFormatter('%g $\\pi$'))\n",
+ "ax.xaxis.set_major_formatter(tck.FormatStrFormatter(\"%g $\\pi$\"))\n",
"ax.xaxis.set_major_locator(tck.MultipleLocator(base=0.5))\n",
"# set title, labels, and legend\n",
- "plt.title('Violation of CHSH Inequality')\n",
- "plt.xlabel('Theta')\n",
- "plt.ylabel('CHSH witness')\n",
+ "plt.title(\"Violation of CHSH Inequality\")\n",
+ "plt.xlabel(\"Theta\")\n",
+ "plt.ylabel(\"CHSH witness\")\n",
"plt.legend()"
]
},
@@ -328,7 +341,7 @@
"id": "63e63853",
"metadata": {},
"source": [
- "In the figure above, the red dashed lines delimit the classical bounds ($\\pm 2$) and the dash-dotted blue lines delimit the quantum bounds ($\\pm 2\\sqrt{2}$). You can see that the experimental results resemble the general trend of the simulated results and there are regions where the CHSH witness quantities exceeds the classical bounds. Congratulations! You have successfully demonstrated the violation of CHSH inequality in a real quantum system!"
+ "In the figure, the red dashed lines delimit the classical bounds ($\\pm 2$) and the dash-dotted blue lines delimit the quantum bounds ($\\pm 2\\sqrt{2}$). You can see that the experimental results resemble the general trend of the simulated results and there are regions where the CHSH witness quantities exceeds the classical bounds. Congratulations! You have successfully demonstrated the violation of CHSH inequality in a real quantum system!"
]
},
{
@@ -378,6 +391,7 @@
],
"source": [
"import qiskit_ibm_runtime\n",
+ "\n",
"qiskit_ibm_runtime.version.get_version_info()"
]
},
diff --git a/docs/tutorials/grover_with_sampler.ipynb b/docs/tutorials/grover_with_sampler.ipynb
index f0dfa9f31..6d509848e 100644
--- a/docs/tutorials/grover_with_sampler.ipynb
+++ b/docs/tutorials/grover_with_sampler.ipynb
@@ -17,7 +17,7 @@
"source": [
"## Before you begin\n",
"\n",
- "This tutorial requires a Qiskit Runtime service instance. If you haven't done so already, please follow the [Getting Started Guide](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/getting_started.html) to set one up."
+ "This tutorial requires a Qiskit Runtime service instance. If you haven't done so already, follow the [Getting started guide](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/getting_started.html) to set one up."
]
},
{
@@ -29,7 +29,7 @@
"\n",
"### Unstructured search problem\n",
"\n",
- "In the olden days, you looked up a person's phone number in a phone book. That is an easy task if you know the person's name because a phone book is ordered alphabetically by name. However, the opposite task, that is, you are given a phone number and want to find out who it belongs to, is much more difficult. That is because a phone book is not ordered by phone numbers. This is an example of an unstructured search problem. To solve this problem with a classical computer, your best trick is to randomly pick an entry. On average, you will need to look up half of the entries ($N/2$, if $N$ is the total number of entries) to find the owner. If you have a quantum computer, however, you can use Grover's algorithm to find the owner in $\\sqrt N$ tries. That means to identify the owner in a phone book that has 1 million numbers, you only need to do 1000 tries instead of 500,000!\n",
+ "In the olden days, you looked up a person's phone number in a phone book. That is an easy task if you know the person's name because a phone book is ordered alphabetically by name. However, the opposite task, that is, you are given a phone number and want to find out who it belongs to, is much more difficult. That is because a phone book is not ordered by phone numbers. This is an example of an unstructured search problem. To solve this problem with a classical computer, your best trick is to randomly pick an entry. On average, you will need to look up half of the entries ($N/2$, if $N$ is the total number of entries) to find the owner. If you have a quantum computer, however, you can use Grover's algorithm to find the owner in $\\sqrt N$ tries. That means to identify the owner in a phone book that has 1 million numbers, you only need to access 1000 entries, rather than 500,000!\n",
"\n",
"### Grover's algorithm\n",
"\n",
@@ -83,8 +83,8 @@
"import random\n",
"from qiskit.quantum_info import Statevector\n",
"\n",
- "secret = random.randint(0,7) # the owner is randomly picked\n",
- "secret_string = format(secret, '03b') # format the owner in 3-bit string\n",
+ "secret = random.randint(0, 7) # the owner is randomly picked\n",
+ "secret_string = format(secret, \"03b\") # format the owner in 3-bit string\n",
"oracle = Statevector.from_label(secret_string) # let the oracle know the owner"
]
},
@@ -146,7 +146,7 @@
"from qiskit.algorithms import Grover\n",
"\n",
"grover_circuits = []\n",
- "for iteration in range(1,3):\n",
+ "for iteration in range(1, 3):\n",
" grover = Grover(iterations=iteration)\n",
" circuit = grover.construct_circuit(problem)\n",
" circuit.measure_all()\n",
@@ -281,7 +281,7 @@
"id": "17d8307f-f3ff-4371-9286-611def049a8b",
"metadata": {},
"source": [
- "Grover's algorithm determines the correct answer based on the highest probability of measurement outcomes. The `Sampler` primitive program is perfect for getting probabilities, so you will use that. In the cell below, you create an instance of the `Sampler` program, and start a Runtime session using the context manager (`with ...:`), which automatically opens and closes the session for you. \n",
+ "Grover's algorithm determines the correct answer based on the highest probability of measurement outcomes. The `Sampler` primitive program is perfect for getting probabilities, so you will use that. In the following cell, you create an instance of the `Sampler` program, and start a Runtime session using the context manager (`with ...:`), which automatically opens and closes the session for you. \n",
"\n",
"The `Sampler` program allows a batch submission of circuits in a job. Here you are passing a list of two circuits (Grover with 1 iteration and 2 iterations) to the Sampler but only one call is needed to sample the probability of measurement outcomes of both circuits."
]
@@ -370,12 +370,13 @@
"# Extract bit string with highest probability from results as the answer\n",
"result_dict = result.quasi_dists[1].binary_probabilities()\n",
"answer = max(result_dict, key=result_dict.get)\n",
- "print(f\"As you can see, the quantum computer returned '{answer}' as the answer with highest probability.\\n\"\n",
- " \"And the results with 2 iterations have higher probability than the results with 1 iteration.\"\n",
+ "print(\n",
+ " f\"As you can see, the quantum computer returned '{answer}' as the answer with highest probability.\\n\"\n",
+ " \"And the results with 2 iterations have higher probability than the results with 1 iteration.\"\n",
")\n",
"\n",
"# Plot the results\n",
- "plot_histogram(result.quasi_dists, legend=['1 iteration', '2 iterations'])"
+ "plot_histogram(result.quasi_dists, legend=[\"1 iteration\", \"2 iterations\"])"
]
},
{
@@ -415,7 +416,7 @@
"# Print the results and the correct answer.\n",
"print(f\"Quantum answer: {answer}\")\n",
"print(f\"Correct answer: {secret_string}\")\n",
- "print('Success!' if answer == secret_string else 'Failure!')"
+ "print(\"Success!\" if answer == secret_string else \"Failure!\")"
]
},
{
@@ -435,7 +436,7 @@
"source": [
"## Summary\n",
"\n",
- "In this tutorial, you have solved a small database search problem using a quantum computer. You have constructed Grover's circuits by defining a phone book search problem using the `AmplificationProblem` class in Qiskit and then submitted the circuits to run using the Sampler primitive program via Qiskit Runtime service. "
+ "In this tutorial, you have solved a small database search problem using a quantum computer. You have constructed Grover's circuits by defining a phone book search problem using the `AmplificationProblem` class in Qiskit and then submitted the circuits to run using the Sampler primitive program through Qiskit Runtime service. "
]
},
{
@@ -484,6 +485,7 @@
],
"source": [
"import qiskit_ibm_runtime\n",
+ "\n",
"qiskit_ibm_runtime.version.get_version_info()"
]
},
diff --git a/docs/tutorials/how-to-getting-started-with-estimator.ipynb b/docs/tutorials/how-to-getting-started-with-estimator.ipynb
index 9a11bf7ad..eaa36163b 100644
--- a/docs/tutorials/how-to-getting-started-with-estimator.ipynb
+++ b/docs/tutorials/how-to-getting-started-with-estimator.ipynb
@@ -47,7 +47,7 @@
"source": [
"Primitives are core functions that make it easier to build modular algorithms and applications. \n",
"\n",
- "Instead of simply returning counts, they return more immediately meaningful information. \n",
+ "Rather than simply returning counts, they return more immediately meaningful information. \n",
"\n",
"Additionally, they provide a seamless way to access the latest advancements in IBM Quantum hardware and software."
]
@@ -104,7 +104,7 @@
"Similar to the `Backend` base class, there is an `Estimator` base class defined in Qiskit Terra that standardizes the way users interact with all `Estimator` implementations.\n",
"This allows users to easily change their choice of simulator or device for performing expectation value calculations, even if the underlying implementation is different. \n",
"\n",
- "In this section we will be using the default implementation in Qiskit Terra, which uses a local statevector simulator."
+ "In this section we will be using the default implementation in Qiskit Terra, which uses a local state vector simulator."
]
},
{
@@ -180,7 +180,7 @@
}
},
"source": [
- "You will also need at least one observable to measure. Observables represent physical properties of a quantum system (e.g. energy, spin), and allow said properties to be measured (e.g. their expectation values) for a given state of our system. For simplicity, you can use the [PauliSumOp class](https://qiskit.org/documentation/stubs/qiskit.opflow.primitive_ops.html#module-qiskit.opflow.primitive_ops) in Qiskit to define them, as illustrated in the example below."
+ "You will also need at least one observable to measure. Observables represent physical properties of a quantum system (such as energy or spin), and allow said properties to be measured (such as their expectation values) for a given state of our system. For simplicity, you can use the [PauliSumOp class](https://qiskit.org/documentation/stubs/qiskit.opflow.primitive_ops.html#module-qiskit.opflow.primitive_ops) in Qiskit to define them, as illustrated in the following example."
]
},
{
@@ -229,7 +229,9 @@
}
},
"source": [
- "The next step is to create an instance of an `Estimator` class. This can be any `Estimator` class that complies with the `Estimator` primitive specification. For simplicity, we will use Qiskit Terra's `qiskit.primitives.Estimator` class, based on the [Statevector construct](https://qiskit.org/documentation/stubs/qiskit.quantum_info.Statevector.html?highlight=statevector#qiskit.quantum_info.Statevector) (i.e. algebraic simulation)."
+ "\n",
+ "The next step is to create an instance of an `Estimator` class. This can be any `Estimator` class that complies with the `Estimator` primitive specification. For simplicity, we will use Qiskit Terra's `qiskit.primitives.Estimator` class, based on the [Statevector construct](https://qiskit.org/documentation/stubs/qiskit.quantum_info.Statevector.html?highlight=statevector#qiskit.quantum_info.Statevector) (algebraic simulation).\n",
+ ""
]
},
{
@@ -665,7 +667,7 @@
}
},
"source": [
- "Here we are initializing an instance of `qiskit_ibm_runtime.Estimator` instead of `qiskit.primitives.Estimator` to use Qiskit Runtime's implementation of the `Estimator`. \n",
+ "Here we are initializing an instance of `qiskit_ibm_runtime.Estimator` rather than `qiskit.primitives.Estimator` to use Qiskit Runtime's implementation of the `Estimator`. \n",
"\n",
"When you initialize the `Estimator`, you'll need to pass in the backend you previously selected as the target device (or simulator), using the `session` parameter. This automatically opens a session for that backend. We will talk more about session in a later section."
]
@@ -783,7 +785,7 @@
}
},
"source": [
- "Primitives come with a number of options that are grouped into different categories. Commonly used options, such as `resilience_level`, are at the first level.\n",
+ "Primitives come with several options that are grouped into different categories. Commonly used options, such as `resilience_level`, are at the first level.\n",
"\n",
"![options](images/options.png)"
]
@@ -809,7 +811,7 @@
}
},
"source": [
- "In the example below, we create an instance of the `Options` class. `optimization_level` is a first level option and can be passed as an input parameter. Options related to the execution environment are passed using the `environment` parameter."
+ "In the following example, we create an instance of the `Options` class. `optimization_level` is a first level option and can be passed as an input parameter. Options related to the execution environment are passed using the `environment` parameter."
]
},
{
@@ -903,9 +905,9 @@
}
},
"source": [
- "You can also pass in options via the `run()` method. This will overwrite the options you specified when creating the `Estimator` instance for that particular execution. \n",
+ "You can also pass options to the `run()` method. This will overwrite the options you specified when creating the `Estimator` instance for that particular execution. \n",
"\n",
- "Since most users will only overwrite a handful of options at the job level, it is not necessary to specify the category the options are in. The code below, for example, specifies `shots=1024` instead of `execution={\"shots\": 1024}` (which is also valid). "
+ "Since most users will only overwrite a handful of options at the job level, it is not necessary to specify the category the options are in. The following code, for example, specifies `shots=1024` rather than `execution={\"shots\": 1024}` (which is also valid). "
]
},
{
@@ -1025,7 +1027,7 @@
}
},
"source": [
- "A Qiskit Runtime _session_ allows you to group a collection of iterative calls to the quantum computer. A session is started when the first job within the session is started. As long as the session is active, subsequent jobs within the session are prioritized by the scheduler to minimize artificial delay within an iterative algorithm. Data used within a session, such as transpiled circuits, is also cached to avoid unnecessary overhead."
+ "A Qiskit Runtime _session_ allows you to group a collection of iterative calls to the quantum computer. A session is started when the first job within the session is started. If the session is active, subsequent jobs within the session are prioritized by the scheduler to minimize artificial delay within an iterative algorithm. Data used within a session, such as transpiled circuits, is also cached to avoid unnecessary overhead."
]
},
{
@@ -1054,7 +1056,7 @@
"If you don't specify a timeout value, it is set to the initial job's maximum execution time and is the smaller of these values:\n",
"\n",
"- The system limit which can be found [here](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/faqs/max_execution_time.html).\n",
- "- The max_execution_time defined by the program.\n",
+ "- The `max_execution_time` defined by the program.\n",
"\n",
"After this time limit is reached, the session is permanently closed."
]
@@ -1201,7 +1203,7 @@
}
},
"source": [
- "The example below shows how you can create both an instance of the `Sampler` class and one of the `Estimator` class and invoke their `run()` methods within a session. "
+ "The following example shows how you can create both an instance of the `Sampler` class and one of the `Estimator` class and invoke their `run()` methods within a session. "
]
},
{
@@ -1277,9 +1279,13 @@
"\n",
" sampler_job = sampler.run(sampler_circuit)\n",
" estimator_job = estimator.run(circuit, observable)\n",
- " \n",
- " print(f\">>> Quasi Distribution from the sampler job: {sampler_job.result().quasi_dists[0]}\")\n",
- " print(f\">>> Expectation value from the estimator job: {estimator_job.result().values[0]}\")"
+ "\n",
+ " print(\n",
+ " f\">>> Quasi Distribution from the sampler job: {sampler_job.result().quasi_dists[0]}\"\n",
+ " )\n",
+ " print(\n",
+ " f\">>> Expectation value from the estimator job: {estimator_job.result().values[0]}\"\n",
+ " )"
]
},
{
@@ -1303,7 +1309,7 @@
}
},
"source": [
- "Below is a quick recap of using Qiskit Runtime primitives, options, and session."
+ "The following code recaps using Qiskit Runtime primitives, options, and session."
]
},
{
@@ -1326,7 +1332,13 @@
}
],
"source": [
- "from qiskit_ibm_runtime import QiskitRuntimeService, Session, Sampler, Estimator, Options\n",
+ "from qiskit_ibm_runtime import (\n",
+ " QiskitRuntimeService,\n",
+ " Session,\n",
+ " Sampler,\n",
+ " Estimator,\n",
+ " Options,\n",
+ ")\n",
"\n",
"# 1. Initialize account\n",
"service = QiskitRuntimeService(channel=\"ibm_quantum\")\n",
@@ -1347,10 +1359,14 @@
" # 6. Submit jobs\n",
" sampler_job = sampler.run(sampler_circuit)\n",
" estimator_job = estimator.run(circuit, observable)\n",
- " \n",
+ "\n",
" # 7. Get results\n",
- " print(f\">>> Quasi Distribution from the sampler job: {sampler_job.result().quasi_dists[0]}\")\n",
- " print(f\">>> Expectation value from the estimator job: {estimator_job.result().values[0]}\")"
+ " print(\n",
+ " f\">>> Quasi Distribution from the sampler job: {sampler_job.result().quasi_dists[0]}\"\n",
+ " )\n",
+ " print(\n",
+ " f\">>> Expectation value from the estimator job: {estimator_job.result().values[0]}\"\n",
+ " )"
]
},
{
@@ -1390,6 +1406,7 @@
],
"source": [
"import qiskit_ibm_runtime\n",
+ "\n",
"qiskit_ibm_runtime.version.get_version_info()"
]
},
@@ -1461,4 +1478,3 @@
"nbformat": 4,
"nbformat_minor": 5
}
-
diff --git a/docs/tutorials/how-to-getting-started-with-sampler.ipynb b/docs/tutorials/how-to-getting-started-with-sampler.ipynb
index 90836ecaf..12816e298 100644
--- a/docs/tutorials/how-to-getting-started-with-sampler.ipynb
+++ b/docs/tutorials/how-to-getting-started-with-sampler.ipynb
@@ -47,7 +47,7 @@
"source": [
"Primitives are core functions that make it easier to build modular algorithms and applications. \n",
"\n",
- "Instead of simply returning counts, they return more immediately meaningful information. \n",
+ "Rather than simply returning counts, they return more immediately meaningful information. \n",
"\n",
"Additionally, they provide a seamless way to access the latest advancements in IBM Quantum hardware and software."
]
@@ -104,7 +104,7 @@
"Similar to the `Backend` base class, there is an `Sampler` base class defined in Qiskit Terra that standardizes the way users interact with all `Sampler` implementations.\n",
"This allows users to easily change their choice of simulator or device for performing expectation value calculations, even if the underlying implementation is different. \n",
"\n",
- "In this section we will be using the default implementation in Qiskit Terra, which uses a local statevector simulator."
+ "In this section we will be using the default implementation in Qiskit Terra, which uses a local state vector simulator."
]
},
{
@@ -180,7 +180,7 @@
}
},
"source": [
- "The next step is to create an instance of an `Sampler` class. This can be any `Sampler` class that complies with the `Sampler` primitive specification. For simplicity, we will use Qiskit Terra's `qiskit.primitives.Sampler` class, based on the [Statevector construct](https://qiskit.org/documentation/stubs/qiskit.quantum_info.Statevector.html?highlight=statevector#qiskit.quantum_info.Statevector) (i.e. algebraic simulation)."
+ "The next step is to create an instance of an `Sampler` class. This can be any `Sampler` class that complies with the `Sampler` primitive specification. For simplicity, we will use Qiskit Terra's `qiskit.primitives.Sampler` class, based on the [`Statevector` construct](https://qiskit.org/documentation/stubs/qiskit.quantum_info.Statevector.html?highlight=statevector#qiskit.quantum_info.Statevector) (that is, algebraic simulation)."
]
},
{
@@ -594,7 +594,7 @@
}
},
"source": [
- "Here we are initializing an instance of `qiskit_ibm_runtime.Sampler` instead of `qiskit.primitives.Sampler` to use Qiskit Runtime's implementation of the `Sampler`. \n",
+ "Here we are initializing an instance of `qiskit_ibm_runtime.Sampler` rather than `qiskit.primitives.Sampler` to use Qiskit Runtime's implementation of the `Sampler`. \n",
"\n",
"When you initialize the `Sampler`, you'll need to pass in the backend you previously selected as the target device (or simulator), using the `session` parameter. This automatically opens a session for that backend. We will talk more about session in a later section."
]
@@ -713,7 +713,7 @@
}
},
"source": [
- "Primitives come with a number of options that are grouped into different categories. Commonly used options, such as `resilience_level`, are at the first level.\n",
+ "Primitives come with several options that are grouped into different categories. Commonly used options, such as `resilience_level`, are at the first level.\n",
"\n",
"![options](images/options.png)"
]
@@ -739,7 +739,7 @@
}
},
"source": [
- "In the example below, we create an instance of the `Options` class. `optimization_level` is a first level option and can be passed as an input parameter. Options related to the execution environment are passed using the `environment` parameter."
+ "In the following example, we create an instance of the `Options` class. `optimization_level` is a first level option and can be passed as an input parameter. Options related to the execution environment are passed using the `environment` parameter."
]
},
{
@@ -833,9 +833,9 @@
}
},
"source": [
- "You can also pass in options via the `run()` method. This will overwrite the options you specified when creating the `Sampler` instance for that particular execution. \n",
+ "You can also pass in options through the `run()` method. This will overwrite the options you specified when creating the `Sampler` instance for that particular execution. \n",
"\n",
- "Since most users will only overwrite a handful of options at the job level, it is not necessary to specify the category the options are in. The code below, for example, specifies `shots=1024` instead of `execution={\"shots\": 1024}` (which is also valid). "
+ "Since most users will only overwrite a handful of options at the job level, it is not necessary to specify the category the options are in. The following code, for example, specifies `shots=1024` rather than `execution={\"shots\": 1024}` (which is also valid). "
]
},
{
@@ -953,7 +953,7 @@
}
},
"source": [
- "A Qiskit Runtime _session_ allows you to group a collection of iterative calls to the quantum computer. A session is started when the first job within the session is started. As long as the session is active, subsequent jobs within the session are prioritized by the scheduler to minimize artificial delay within an iterative algorithm. Data used within a session, such as transpiled circuits, is also cached to avoid unnecessary overhead."
+ "A Qiskit Runtime _session_ allows you to group a collection of iterative calls to the quantum computer. A session is started when the first job within the session is started. Provided the session is active, subsequent jobs within the session are prioritized by the scheduler to minimize artificial delay within an iterative algorithm. Data used within a session, such as transpiled circuits, is also cached to avoid unnecessary overhead."
]
},
{
@@ -982,7 +982,7 @@
"If you don't specify a timeout value, it is set to the initial job's maximum execution time and is the smaller of these values:\n",
"\n",
"- The system limit which can be found [here](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/faqs/max_execution_time.html).\n",
- "- The max_execution_time defined by the program.\n",
+ "- The `max_execution_time` defined by the program.\n",
"\n",
"After this time limit is reached, the session is permanently closed."
]
@@ -1088,7 +1088,7 @@
}
},
"source": [
- "First we prepare a circuit and an observale for the `Estimator` primitive."
+ "First we prepare a circuit and an observable for the `Estimator` primitive."
]
},
{
@@ -1139,7 +1139,7 @@
}
},
"source": [
- "The example below shows how you can create both an instance of the `Sampler` class and one of the `Estimator` class and invoke their `run()` methods within a session. "
+ "The following example shows how you can create both an instance of the `Sampler` class and one of the `Estimator` class and invoke their `run()` methods within a session. "
]
},
{
@@ -1215,9 +1215,13 @@
"\n",
" sampler_job = sampler.run(circuit)\n",
" estimator_job = estimator.run(estimator_circuit, observable)\n",
- " \n",
- " print(f\">>> Quasi Distribution from the sampler job: {sampler_job.result().quasi_dists[0]}\")\n",
- " print(f\">>> Expectation value from the estimator job: {estimator_job.result().values[0]}\")"
+ "\n",
+ " print(\n",
+ " f\">>> Quasi Distribution from the sampler job: {sampler_job.result().quasi_dists[0]}\"\n",
+ " )\n",
+ " print(\n",
+ " f\">>> Expectation value from the estimator job: {estimator_job.result().values[0]}\"\n",
+ " )"
]
},
{
@@ -1241,7 +1245,7 @@
}
},
"source": [
- "Below is a quick recap of using Qiskit Runtime primitives, options, and session."
+ "The following code quickly recaps using Qiskit Runtime primitives, options, and sessions."
]
},
{
@@ -1264,7 +1268,13 @@
}
],
"source": [
- "from qiskit_ibm_runtime import QiskitRuntimeService, Session, Sampler, Estimator, Options\n",
+ "from qiskit_ibm_runtime import (\n",
+ " QiskitRuntimeService,\n",
+ " Session,\n",
+ " Sampler,\n",
+ " Estimator,\n",
+ " Options,\n",
+ ")\n",
"\n",
"# 1. Initialize account\n",
"service = QiskitRuntimeService(channel=\"ibm_quantum\")\n",
@@ -1285,10 +1295,14 @@
" # 6. Submit jobs\n",
" sampler_job = sampler.run(circuit)\n",
" estimator_job = estimator.run(estimator_circuit, observable)\n",
- " \n",
+ "\n",
" # 7. Get results\n",
- " print(f\">>> Quasi Distribution from the sampler job: {sampler_job.result().quasi_dists[0]}\")\n",
- " print(f\">>> Expectation value from the estimator job: {estimator_job.result().values[0]}\")"
+ " print(\n",
+ " f\">>> Quasi Distribution from the sampler job: {sampler_job.result().quasi_dists[0]}\"\n",
+ " )\n",
+ " print(\n",
+ " f\">>> Expectation value from the estimator job: {estimator_job.result().values[0]}\"\n",
+ " )"
]
},
{
@@ -1328,6 +1342,7 @@
],
"source": [
"import qiskit_ibm_runtime\n",
+ "\n",
"qiskit_ibm_runtime.version.get_version_info()"
]
},
diff --git a/docs/tutorials/qpe_with_sampler.ipynb b/docs/tutorials/qpe_with_sampler.ipynb
index dc6c946cc..1d95b545b 100644
--- a/docs/tutorials/qpe_with_sampler.ipynb
+++ b/docs/tutorials/qpe_with_sampler.ipynb
@@ -50,7 +50,7 @@
"source": [
"## Overview\n",
"\n",
- "As explained above, there are black boxes in the QPE algorithm to prepare the state $|\\psi \\rangle$ and perform the controlled-$U^{2^j}$ operation. In this tutorial, you will prepare a series of QPE circuits containing different black boxes corresponding to different phases. You will then run these circuits using the [Sampler primitive](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/stubs/qiskit_ibm_runtime.Sampler.html) and analyze the results. As you will see, the Sampler primitive makes running parameterized circuits very easy. Instead of creating a series of QPE circuits, you only need to create *one* QPE circuit with a parameter specifying the phase the black boxes generate and a series of phase values for the parameter.\n",
+ "As explained earlier, there are black boxes in the QPE algorithm to prepare the state $|\\psi \\rangle$ and perform the controlled-$U^{2^j}$ operation. In this tutorial, you will prepare a series of QPE circuits containing different black boxes corresponding to different phases. You will then run these circuits using the [Sampler primitive](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/stubs/qiskit_ibm_runtime.Sampler.html) and analyze the results. As you will see, the Sampler primitive makes running parameterized circuits very easy. Rather than create a series of QPE circuits, you only need to create *one* QPE circuit with a parameter specifying the phase the black boxes generate and a series of phase values for the parameter.\n",
"\n",
"\n",
"\n",
@@ -101,18 +101,27 @@
"from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit\n",
"from qiskit.circuit.library import QFT\n",
"\n",
+ "\n",
"def create_qpe_circuit(theta, num_qubits):\n",
- " '''Creates a QPE circuit given theta and num_qubits.'''\n",
- " \n",
+ " \"\"\"Creates a QPE circuit given theta and num_qubits.\"\"\"\n",
+ "\n",
" # Step 1: Create a circuit with two quantum registers and one classical register.\n",
- " first = QuantumRegister(size=num_qubits, name='first') # the first register for phase estimation\n",
- " second = QuantumRegister(size=1, name='second') # the second register for storing eigenvector |psi>\n",
- " classical = ClassicalRegister(size=num_qubits, name='readout') # classical register for readout\n",
+ " first = QuantumRegister(\n",
+ " size=num_qubits, name=\"first\"\n",
+ " ) # the first register for phase estimation\n",
+ " second = QuantumRegister(\n",
+ " size=1, name=\"second\"\n",
+ " ) # the second register for storing eigenvector |psi>\n",
+ " classical = ClassicalRegister(\n",
+ " size=num_qubits, name=\"readout\"\n",
+ " ) # classical register for readout\n",
" qpe_circuit = QuantumCircuit(first, second, classical)\n",
"\n",
" # Step 2: Initialize the qubits.\n",
" # All qubits are initialized in |0> by default, no extra code is needed to initialize the first register.\n",
- " qpe_circuit.x(second) # Initialize the second register with state |psi>, which is |1> in this example.\n",
+ " qpe_circuit.x(\n",
+ " second\n",
+ " ) # Initialize the second register with state |psi>, which is |1> in this example.\n",
"\n",
" # Step 3: Create superposition in the first register.\n",
" qpe_circuit.barrier() # Add barriers to separate each step of the algorithm for better visualization.\n",
@@ -121,7 +130,9 @@
" # Step 4: Apply a controlled-U^(2^j) black box.\n",
" qpe_circuit.barrier()\n",
" for j in range(num_qubits):\n",
- " qpe_circuit.cp(theta*2*np.pi*(2**j), j, num_qubits) # Theta doesn't contain the 2 pi factor.\n",
+ " qpe_circuit.cp(\n",
+ " theta * 2 * np.pi * (2**j), j, num_qubits\n",
+ " ) # Theta doesn't contain the 2 pi factor.\n",
"\n",
" # Step 5: Apply an inverse QFT to the first register.\n",
" qpe_circuit.barrier()\n",
@@ -162,8 +173,10 @@
],
"source": [
"num_qubits = 4\n",
- "qpe_circuit_fixed_phase = create_qpe_circuit(1/2, num_qubits) # Create a QPE circuit with fixed theta=1/2.\n",
- "qpe_circuit_fixed_phase.draw('mpl')"
+ "qpe_circuit_fixed_phase = create_qpe_circuit(\n",
+ " 1 / 2, num_qubits\n",
+ ") # Create a QPE circuit with fixed theta=1/2.\n",
+ "qpe_circuit_fixed_phase.draw(\"mpl\")"
]
},
{
@@ -195,9 +208,11 @@
"source": [
"from qiskit.circuit import Parameter\n",
"\n",
- "theta = Parameter('theta') # Create a parameter `theta` whose values can be assigned later.\n",
+ "theta = Parameter(\n",
+ " \"theta\"\n",
+ ") # Create a parameter `theta` whose values can be assigned later.\n",
"qpe_circuit_parameterized = create_qpe_circuit(theta, num_qubits)\n",
- "qpe_circuit_parameterized.draw('mpl')"
+ "qpe_circuit_parameterized.draw(\"mpl\")"
]
},
{
@@ -207,7 +222,7 @@
"source": [
"### Create a list of phase values to be assigned later\n",
"\n",
- "After creating the parameterized QPE circuit, you will create a list of phase values to be assigned to the circuit in the next step. You can use the code below to create a list of 21 phase values that range from `0` to `2` with equal spacing, i.e. `0`, `0.1`, `0.2`, ..., `1.9`, `2.0`."
+ "After creating the parameterized QPE circuit, you will create a list of phase values to be assigned to the circuit in the next step. You can use the following code to create a list of 21 phase values that range from `0` to `2` with equal spacing, that is, `0`, `0.1`, `0.2`, ..., `1.9`, `2.0`."
]
},
{
@@ -219,7 +234,9 @@
"source": [
"number_of_phases = 21\n",
"phases = np.linspace(0, 2, number_of_phases)\n",
- "individual_phases = [[ph] for ph in phases] # Phases need to be expressed as a list of lists."
+ "individual_phases = [\n",
+ " [ph] for ph in phases\n",
+ "] # Phases need to be expressed as a list of lists."
]
},
{
@@ -275,10 +292,14 @@
"from qiskit_ibm_runtime import Sampler, Session\n",
"\n",
"with Session(service=service, backend=backend):\n",
- " results = Sampler().run(\n",
- " [qpe_circuit_parameterized]*len(individual_phases), \n",
- " parameter_values=individual_phases\n",
- " ).result()"
+ " results = (\n",
+ " Sampler()\n",
+ " .run(\n",
+ " [qpe_circuit_parameterized] * len(individual_phases),\n",
+ " parameter_values=individual_phases,\n",
+ " )\n",
+ " .result()\n",
+ " )"
]
},
{
@@ -296,7 +317,7 @@
"source": [
"### Analyze the results of one circuit\n",
"\n",
- "After the job has been completed, you can start analyzing the results by looking at the histogram of one of the circuits. The (quasi-)probability distribution of the measurement outcome is stored in `results.quasi_dists` and you can access results from an individual circuit by passing the index of the circuit ($idx=6$ in the example below) you are interested in. "
+ "After the job has been completed, you can start analyzing the results by looking at the histogram of one of the circuits. The (quasi-)probability distribution of the measurement outcome is stored in `results.quasi_dists` and you can access results from an individual circuit by passing the index of the circuit ($idx=6$ in the following example) you are interested in. "
]
},
{
@@ -321,7 +342,10 @@
"from qiskit.tools.visualization import plot_histogram\n",
"\n",
"idx = 6\n",
- "plot_histogram(results.quasi_dists[idx].binary_probabilities(), legend=[f'$\\\\theta$={phases[idx]:.3f}'])"
+ "plot_histogram(\n",
+ " results.quasi_dists[idx].binary_probabilities(),\n",
+ " legend=[f\"$\\\\theta$={phases[idx]:.3f}\"],\n",
+ ")"
]
},
{
@@ -333,7 +357,7 @@
"\n",
"$$\\theta = \\frac{N_1}{2^n} = \\frac{10}{2^4} = 0.625. $$\n",
"\n",
- "This is close to the expected value of $0.6$, but you can do a better estimate by taking the weighted average of the most likely outcome (`1010` in binary or `10` in decimal) and the second most likely outcome (`1001` in binary or `9` in decimal):\n",
+ "This is close to the expected value of $0.6$, but you can get a better estimate by taking the weighted average of the most likely outcome (`1010` in binary or `10` in decimal) and the second most likely outcome (`1001` in binary or `9` in decimal):\n",
"\n",
"$$\\theta = \\frac{P_1 \\times \\frac{N_1}{2^n} + P_2 \\times \\frac{N_2}{2^n}}{P_1 + P_2} = \\frac{0.554 \\times \\frac{10}{2^4} + 0.269 \\times \\frac{9}{2^4}}{0.554 + 0.269} = 0.605,$$\n",
"\n",
@@ -347,7 +371,7 @@
"source": [
"### Analyze the results of all circuits\n",
"\n",
- "You can use the helper functions below to find the values for $N_1$, $P_1$, $N_2$, and $P_2$ for a phase and calculate the estimated $\\theta$. Ideally $N_2$ should be a \"neighbor\" of $N_1$ (for example, the neighbors of `1010` are `1001` and `1011`), however due to the presence of noise, the second most likely outcome may not be a neighbor of $N_1$ if the results were obtained from a real quantum system. The helper functions take the $N_2$ value only from $N_1$'s neighbors."
+ "You can use the following helper functions to find the values for $N_1$, $P_1$, $N_2$, and $P_2$ for a phase and calculate the estimated $\\theta$. Ideally $N_2$ should be a \"neighbor\" of $N_1$ (for example, the neighbors of `1010` are `1001` and `1011`). However, due to the presence of noise, the second most likely outcome may not be a neighbor of $N_1$ if the results were obtained from a real quantum system. The helper functions take the $N_2$ value only from $N_1$'s neighbors."
]
},
{
@@ -358,30 +382,32 @@
"outputs": [],
"source": [
"def most_likely_bitstring(results_dict):\n",
- " '''Finds the most likely outcome bit string from a result dictionary.'''\n",
+ " \"\"\"Finds the most likely outcome bit string from a result dictionary.\"\"\"\n",
" return max(results_dict, key=results_dict.get)\n",
"\n",
+ "\n",
"def find_neighbors(bitstring):\n",
- " '''Finds the neighbors of a bit string.\n",
- " \n",
- " Example: \n",
+ " \"\"\"Finds the neighbors of a bit string.\n",
+ "\n",
+ " Example:\n",
" For bit string '1010', this function returns ('1001', '1011')\n",
- " '''\n",
- " if bitstring == len(bitstring)*'0':\n",
- " neighbor_left = len(bitstring)*'1'\n",
+ " \"\"\"\n",
+ " if bitstring == len(bitstring) * \"0\":\n",
+ " neighbor_left = len(bitstring) * \"1\"\n",
" else:\n",
- " neighbor_left = format((int(bitstring,2)-1), '0%sb'%len(bitstring))\n",
+ " neighbor_left = format((int(bitstring, 2) - 1), \"0%sb\" % len(bitstring))\n",
"\n",
- " if bitstring == len(bitstring)*'1':\n",
- " neighbor_right = len(bitstring)*'0'\n",
+ " if bitstring == len(bitstring) * \"1\":\n",
+ " neighbor_right = len(bitstring) * \"0\"\n",
" else:\n",
- " neighbor_right = format((int(bitstring,2)+1), '0%sb'%len(bitstring))\n",
+ " neighbor_right = format((int(bitstring, 2) + 1), \"0%sb\" % len(bitstring))\n",
"\n",
" return (neighbor_left, neighbor_right)\n",
"\n",
+ "\n",
"def estimate_phase(results_dict):\n",
- " '''Estimates the phase from a result dictionary of a QPE circuit.'''\n",
- " \n",
+ " \"\"\"Estimates the phase from a result dictionary of a QPE circuit.\"\"\"\n",
+ "\n",
" # Find the most likely outcome bit string N1 and its neighbors.\n",
" num_1_key = most_likely_bitstring(results_dict)\n",
" neighbor_left, neighbor_right = find_neighbors(num_1_key)\n",
@@ -409,7 +435,7 @@
" elif neighbor_left_prob > neighbor_right_prob:\n",
" # Both neighbors exist and neighbor_left has higher probability, so N2 is neighbor_left.\n",
" num_2_key = neighbor_left\n",
- " num_2_prob = neighbor_left_prob \n",
+ " num_2_prob = neighbor_left_prob\n",
" else:\n",
" # Both neighbors exist and neighbor_right has higher probability, so N2 is neighor_right.\n",
" num_2_key = neighbor_right\n",
@@ -417,11 +443,13 @@
"\n",
" # Calculate the estimated phases for N1 and N2.\n",
" num_qubits = len(num_1_key)\n",
- " num_1_phase = (int(num_1_key, 2) / 2**num_qubits)\n",
- " num_2_phase = (int(num_2_key, 2) / 2**num_qubits)\n",
+ " num_1_phase = int(num_1_key, 2) / 2**num_qubits\n",
+ " num_2_phase = int(num_2_key, 2) / 2**num_qubits\n",
"\n",
" # Calculate the weighted average phase from N1 and N2.\n",
- " phase_estimated = (num_1_phase * num_1_prob + num_2_phase * num_2_prob) / (num_1_prob + num_2_prob)\n",
+ " phase_estimated = (num_1_phase * num_1_prob + num_2_phase * num_2_prob) / (\n",
+ " num_1_prob + num_2_prob\n",
+ " )\n",
"\n",
" return phase_estimated"
]
@@ -451,7 +479,7 @@
"id": "3ed0fc7d",
"metadata": {},
"source": [
- "The ideal solutions for the phases $\\theta$ are periodic with a period of `1` because the eigenvalue $e^{2 \\pi i \\theta}$ is $2 \\pi$ periodic. You can run the cell below to generate the ideal solutions for comparison with the solutions obtained from the QPE algorithm."
+ "The ideal solutions for the phases $\\theta$ are periodic with a period of `1` because the eigenvalue $e^{2 \\pi i \\theta}$ is $2 \\pi$ periodic. You can run the following cell to generate the ideal solutions for comparison with the solutions obtained from the QPE algorithm."
]
},
{
@@ -462,10 +490,12 @@
"outputs": [],
"source": [
"ideal_solutions = np.append(\n",
- " phases[:(number_of_phases-1)//2], # first period\n",
- " np.subtract(phases[(number_of_phases-1)//2:-1], 1) # second period\n",
+ " phases[: (number_of_phases - 1) // 2], # first period\n",
+ " np.subtract(phases[(number_of_phases - 1) // 2 : -1], 1), # second period\n",
")\n",
- "ideal_solutions = np.append(ideal_solutions, np.subtract(phases[-1], 2)) # starting point of the third period"
+ "ideal_solutions = np.append(\n",
+ " ideal_solutions, np.subtract(phases[-1], 2)\n",
+ ") # starting point of the third period"
]
},
{
@@ -473,7 +503,7 @@
"id": "ac4b970c",
"metadata": {},
"source": [
- "You can run the code below to visualize the solutions."
+ "You can run the following code to visualize the solutions."
]
},
{
@@ -509,12 +539,12 @@
"import matplotlib.pyplot as plt\n",
"\n",
"fig = plt.figure(figsize=(10, 6))\n",
- "plt.plot(phases, ideal_solutions, '--', label='Ideal solutions')\n",
- "plt.plot(phases, qpe_solutions, 'o', label='QPE solutions')\n",
+ "plt.plot(phases, ideal_solutions, \"--\", label=\"Ideal solutions\")\n",
+ "plt.plot(phases, qpe_solutions, \"o\", label=\"QPE solutions\")\n",
"\n",
- "plt.title('Quantum Phase Estimation Algorithm')\n",
- "plt.xlabel('Input Phase')\n",
- "plt.ylabel('Output Phase')\n",
+ "plt.title(\"Quantum Phase Estimation Algorithm\")\n",
+ "plt.xlabel(\"Input Phase\")\n",
+ "plt.ylabel(\"Output Phase\")\n",
"plt.legend()"
]
},
@@ -575,6 +605,7 @@
],
"source": [
"import qiskit_ibm_runtime\n",
+ "\n",
"qiskit_ibm_runtime.version.get_version_info()"
]
},
diff --git a/docs/tutorials/sea_with_sampler.ipynb b/docs/tutorials/sea_with_sampler.ipynb
index 8942a9ce5..ed80c7dd2 100644
--- a/docs/tutorials/sea_with_sampler.ipynb
+++ b/docs/tutorials/sea_with_sampler.ipynb
@@ -7,7 +7,7 @@
"source": [
"# Spectroscopic Eigensolver Algorithm with Sampler\n",
"\n",
- "This tutorial demonstrates the ability to send flexible circuits to the `Sampler` primitive by performing a simple example of the spectroscopic eigensolver algorithm ([arXiv:2202.12910](http://arxiv.org/abs/2202.12910)). The SEA is used for quantum simulation of model Hamiltonians, and works by interacting a \"probe\" auxiliary qubit with a simulation register. The energy of the probe qubit is swept and eigenvalues of the simulation Hamiltonian are observed as peaks or dips in the response, akin to the experimental tool of spectroscopy. Because each point (i.e., energy) is a different quantum circuit, this technique is expensive with respect to the number of circuits required. The `Sampler` provides the flexibility to send just a single circuit with the needed `Parameter`s passed."
+ "This tutorial demonstrates the ability to send flexible circuits to the `Sampler` primitive by performing a simple example of the Spectroscopic Eigensolver Algorithm (SEA) ([arXiv:2202.12910](http://arxiv.org/abs/2202.12910)). The SEA is used for quantum simulation of model Hamiltonians, and works by interacting a \"probe\" auxiliary qubit with a simulation register. The energy of the probe qubit is swept and eigenvalues of the simulation Hamiltonian are observed as peaks or dips in the response, akin to the experimental tool of spectroscopy. Because each point (energy) is a different quantum circuit, this technique is expensive with respect to the number of circuits required. The `Sampler` provides the flexibility to send just a single circuit with the needed `Parameter`s passed."
]
},
{
@@ -38,13 +38,13 @@
"id": "ce7228b0",
"metadata": {},
"source": [
- "## Simple Hamiltonian Model\n",
+ "## Simple Hamiltonian model\n",
"\n",
- "Let's consider a Pauli-X matrix acting on a qubit,\n",
+ "Let us consider a Pauli-X matrix acting on a qubit,\n",
"$$\n",
"H_{\\rm Pauli}/\\hbar = \\mu X\n",
"$$\n",
- "where we can set $\\mu$ later, or even sweep its values as well. The SEA works by taking the model Pauli (i.e., qubit) Hamiltonian and building a larger \"resonance\" Hamiltonian that includes both the simulation register and probe qubit `q0` via\n",
+ "where we can set $\\mu$ later, or even sweep its values as well. The SEA works by taking the model Pauli (qubit) Hamiltonian and building a larger \"resonance\" Hamiltonian that includes both the simulation register and probe qubit `q0` through\n",
"$$\n",
"H_{\\rm res} / \\hbar = -\\frac{1}{2} \\omega IZ + c XX + H_{\\rm Pauli}/\\hbar \\otimes I\n",
"$$\n",
@@ -63,7 +63,7 @@
"from qiskit.circuit import Parameter\n",
"from qiskit.opflow import I, X, Z\n",
"\n",
- "mu = Parameter('$\\\\mu$')\n",
+ "mu = Parameter(\"$\\\\mu$\")\n",
"ham_pauli = mu * X"
]
},
@@ -74,10 +74,10 @@
"metadata": {},
"outputs": [],
"source": [
- "cc = Parameter('$c$')\n",
- "ww = Parameter('$\\\\omega$')\n",
+ "cc = Parameter(\"$c$\")\n",
+ "ww = Parameter(\"$\\\\omega$\")\n",
"\n",
- "ham_res = -(1/2)*ww*(I^Z) + cc*(X^X) + (ham_pauli^I)"
+ "ham_res = -(1 / 2) * ww * (I ^ Z) + cc * (X ^ X) + (ham_pauli ^ I)"
]
},
{
@@ -95,8 +95,8 @@
"metadata": {},
"outputs": [],
"source": [
- "tt = Parameter('$t$')\n",
- "U_ham = (tt*ham_res).exp_i()"
+ "tt = Parameter(\"$t$\")\n",
+ "U_ham = (tt * ham_res).exp_i()"
]
},
{
@@ -132,11 +132,13 @@
"\n",
"num_trot_steps = 5\n",
"total_time = 10\n",
- "cr = ClassicalRegister(1, 'c')\n",
+ "cr = ClassicalRegister(1, \"c\")\n",
"\n",
- "spec_op = PauliTrotterEvolution(trotter_mode=Suzuki(order=2, reps=num_trot_steps)).convert(U_ham)\n",
+ "spec_op = PauliTrotterEvolution(\n",
+ " trotter_mode=Suzuki(order=2, reps=num_trot_steps)\n",
+ ").convert(U_ham)\n",
"spec_circ = spec_op.to_circuit()\n",
- "spec_circ_t = transpile(spec_circ, basis_gates=['sx', 'rz', 'cx'])\n",
+ "spec_circ_t = transpile(spec_circ, basis_gates=[\"sx\", \"rz\", \"cx\"])\n",
"spec_circ_t.add_register(cr)\n",
"spec_circ_t.measure(0, cr[0])"
]
@@ -162,7 +164,7 @@
}
],
"source": [
- "spec_circ_t.draw('mpl')"
+ "spec_circ_t.draw(\"mpl\")"
]
},
{
@@ -170,7 +172,7 @@
"id": "95ff35f5",
"metadata": {},
"source": [
- "Now let's fix our parameters and sweep over frequency with a number of points `num_pts`. The eigenvalues of our model Hamiltonian $H_{\\rm Pauli}$ are $\\pm \\mu$, so we need to choose a range that includes those numbers.\n",
+ "Now let's fix our parameters and sweep over the frequency with several points `num_pts`. The eigenvalues of our model Hamiltonian $H_{\\rm Pauli}$ are $\\pm \\mu$, so we need to choose a range that includes those numbers.\n",
"\n",
"Note that the `Parameter`s' keys and values must be separated and converted into a `List` of `List`s. The keys give us the `Parameter`s inside each circuit. In this case, we only have a single circuit, so the `List` of keys contains a single `List`. For the `Parameter` values, there is a `List` for each value of `ww`. "
]
@@ -183,11 +185,7 @@
"outputs": [],
"source": [
"# fixed Parameters\n",
- "fixed_params = {\n",
- " cc: 0.3,\n",
- " mu: 0.7,\n",
- " tt: total_time\n",
- "}\n",
+ "fixed_params = {cc: 0.3, mu: 0.7, tt: total_time}\n",
"# Parameter value for single circuit\n",
"param_keys = list(spec_circ_t.parameters)\n",
"\n",
@@ -220,11 +218,9 @@
"with Session(backend=backend):\n",
" sampler = Sampler()\n",
" job = sampler.run(\n",
- " circuits=[spec_circ_t]*num_pts,\n",
- " parameter_values=param_vals,\n",
- " shots=1e5\n",
+ " circuits=[spec_circ_t] * num_pts, parameter_values=param_vals, shots=1e5\n",
" )\n",
- " result = job.result()\n"
+ " result = job.result()"
]
},
{
@@ -245,7 +241,7 @@
"Zexps = []\n",
"for dist in result.quasi_dists:\n",
" if 1 in dist:\n",
- " Zexps.append(1 - 2*dist[1])\n",
+ " Zexps.append(1 - 2 * dist[1])\n",
" else:\n",
" Zexps.append(1)"
]
@@ -255,7 +251,7 @@
"id": "f66fcbbe",
"metadata": {},
"source": [
- "As a sanity check, we'll calculate the exact expectation values with Qiskit Opflow."
+ "As a quick check, we'll calculate the exact expectation values with Qiskit Opflow."
]
},
{
@@ -267,14 +263,10 @@
"source": [
"from qiskit.opflow import PauliExpectation, Zero\n",
"\n",
- "param_bind = {\n",
- " cc: 0.3,\n",
- " mu: 0.7,\n",
- " tt: total_time\n",
- "}\n",
+ "param_bind = {cc: 0.3, mu: 0.7, tt: total_time}\n",
"\n",
- "init_state = Zero^2\n",
- "obsv = I^Z\n",
+ "init_state = Zero ^ 2\n",
+ "obsv = I ^ Z\n",
"Zexp_exact = (U_ham @ init_state).adjoint() @ obsv @ (U_ham @ init_state)\n",
"\n",
"diag_meas_op = PauliExpectation().convert(Zexp_exact)\n",
@@ -321,15 +313,16 @@
],
"source": [
"import matplotlib.pyplot as plt\n",
- "plt.style.use('dark_background')\n",
+ "\n",
+ "plt.style.use(\"dark_background\")\n",
"\n",
"fig, ax = plt.subplots(dpi=100)\n",
- "ax.plot([-param_bind[mu], -param_bind[mu]], [0, 1], ls='--', color='purple')\n",
- "ax.plot([param_bind[mu], param_bind[mu]], [0, 1], ls='--', color='purple')\n",
- "ax.plot(wvals, Zexact_values, label='Exact')\n",
+ "ax.plot([-param_bind[mu], -param_bind[mu]], [0, 1], ls=\"--\", color=\"purple\")\n",
+ "ax.plot([param_bind[mu], param_bind[mu]], [0, 1], ls=\"--\", color=\"purple\")\n",
+ "ax.plot(wvals, Zexact_values, label=\"Exact\")\n",
"ax.plot(wvals, Zexps, label=f\"{backend}\")\n",
- "ax.set_xlabel(r'$\\omega$ (arb)')\n",
- "ax.set_ylabel(r'$\\langle Z \\rangle$ Expectation')\n",
+ "ax.set_xlabel(r\"$\\omega$ (arb)\")\n",
+ "ax.set_ylabel(r\"$\\langle Z \\rangle$ Expectation\")\n",
"ax.legend()"
]
},
@@ -352,6 +345,7 @@
],
"source": [
"import qiskit_ibm_runtime\n",
+ "\n",
"qiskit_ibm_runtime.version.get_version_info()"
]
},
@@ -378,6 +372,7 @@
],
"source": [
"from qiskit.tools.jupyter import *\n",
+ "\n",
"%qiskit_version_table"
]
}
diff --git a/docs/tutorials/user-transpiled-circuits.ipynb b/docs/tutorials/user-transpiled-circuits.ipynb
index cc333750a..cf34dccaf 100644
--- a/docs/tutorials/user-transpiled-circuits.ipynb
+++ b/docs/tutorials/user-transpiled-circuits.ipynb
@@ -12,7 +12,7 @@
"\n",
"## Transpiling circuits for IBM Quantum devices\n",
"\n",
- "In the code cell below, we create a small circuit that our transpiler will try to optimize. In this example, we create a circuit that carries out Grover's algorithm, with an oracle that marks the state `111`. We then simulate the ideal distribution (what we'd expect to measure if we ran this on a perfect quantum computer, an infinite number of times) for comparison later. "
+ "In the following code cell, we create a small circuit that our transpiler will try to optimize. In this example, we create a circuit that carries out Grover's algorithm, with an oracle that marks the state `111`. We then simulate the ideal distribution (what we'd expect to measure if we ran this on a perfect quantum computer, an infinite number of times) for comparison later. "
]
},
{
@@ -1040,16 +1040,19 @@
"# Create circuit to test transpiler on\n",
"from qiskit import QuantumCircuit\n",
"from qiskit.circuit.library import GroverOperator, Diagonal\n",
- "oracle = Diagonal([1]*7 + [-1])\n",
+ "\n",
+ "oracle = Diagonal([1] * 7 + [-1])\n",
"qc = QuantumCircuit(3)\n",
- "qc.h([0,1,2])\n",
+ "qc.h([0, 1, 2])\n",
"qc = qc.compose(GroverOperator(oracle))\n",
"\n",
"# Use Statevector object to calculate the ideal output\n",
"from qiskit.quantum_info import Statevector\n",
+ "\n",
"ideal_distribution = Statevector.from_instruction(qc).probabilities_dict()\n",
"\n",
"from qiskit.visualization import plot_histogram\n",
+ "\n",
"plot_histogram(ideal_distribution)"
]
},
@@ -1057,7 +1060,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "Next, we need to choose a backend to transpile for. In the cell below, we create a service instance, which we'll use to start a session, and get the backend object, which contains information for the transpiler. Since the transpilation process depends on the device, we'll ask the runtime service for a specific device by name. In this example, we'll use `ibm_algiers`, which is only available through IBM Cloud."
+ "Next, we need to choose a backend to transpile for. In the following cell, we create a service instance, which we'll use to start a session, and get the backend object, which contains information for the transpiler. Since the transpilation process depends on the device, we'll ask the runtime service for a specific device by name. In this example, we'll use `ibm_algiers`, which is only available through IBM Cloud."
]
},
{
@@ -1067,17 +1070,18 @@
"outputs": [],
"source": [
"from qiskit_ibm_runtime import QiskitRuntimeService\n",
+ "\n",
"service = QiskitRuntimeService()\n",
- "backend = service.backend('ibm_algiers')"
+ "backend = service.backend(\"ibm_algiers\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "Next, we transpile the circuits for our backend. We're going to compare the performance of the transpiler with `optimization_level` set to `0` (lowest) against `3` (highest). The lowest optimization level just does the bare minimum needed to get the circuit running on the device, i.e. map the circuit qubits to the device qubits, and add swaps gates to allow all 2-qubit operations. The highest optimization level is much smarter and uses lots of tricks to reduce the overall gate count. Since multi-qubit gates have high error rates, and qubits decohere over time, the shorter circuits should give better results.\n",
+ "Next, we transpile the circuits for our backend. We're going to compare the performance of the transpiler with `optimization_level` set to `0` (lowest) against `3` (highest). The lowest optimization level just does the bare minimum needed to get the circuit running on the device; it maps the circuit qubits to the device qubits, and adds swaps gates to allow all 2-qubit operations. The highest optimization level is much smarter and uses lots of tricks to reduce the overall gate count. Since multi-qubit gates have high error rates, and qubits decohere over time, the shorter circuits should give better results.\n",
"\n",
- "In the cell below, we transpile `qc` for both values of `optimization_level`, print the number of CNOT gates, and add the transpiled circuits to a list. Some of the transpiler's algorithms are randomized, so we set a seed for reproducibility."
+ "In the following cell, we transpile `qc` for both values of `optimization_level`, print the number of CNOT gates, and add the transpiled circuits to a list. Some of the transpiler's algorithms are randomized, so we set a seed for reproducibility."
]
},
{
@@ -1099,14 +1103,13 @@
"qc.measure_all()\n",
"\n",
"from qiskit import transpile\n",
+ "\n",
"circuits = []\n",
"for optimization_level in [0, 3]:\n",
- " t_qc = transpile(qc,\n",
- " backend,\n",
- " optimization_level=optimization_level,\n",
- " seed_transpiler=0)\n",
- " print(f'CNOTs (optimization_level={optimization_level}): ',\n",
- " t_qc.count_ops()['cx'])\n",
+ " t_qc = transpile(\n",
+ " qc, backend, optimization_level=optimization_level, seed_transpiler=0\n",
+ " )\n",
+ " print(f\"CNOTs (optimization_level={optimization_level}): \", t_qc.count_ops()[\"cx\"])\n",
" circuits.append(t_qc)"
]
},
@@ -1116,7 +1119,7 @@
"source": [
"Since CNOTs usually have a high error rate, the circuit transpiled with `optimization_level=3` should perform much better.\n",
"\n",
- "Another way we can improve performance is through [dynamic decoupling](https://qiskit.org/documentation/stubs/qiskit.transpiler.passes.DynamicalDecoupling.html), where we apply a sequence of gates to idling qubits. This cancels out some unwanted interactions with the environment. In the cell below, we add dynamic decoupling to the circuit transpiled with `optimization_level=3`, and add it to our list."
+ "Another way we can improve performance is through [dynamic decoupling](https://qiskit.org/documentation/stubs/qiskit.transpiler.passes.DynamicalDecoupling.html), where we apply a sequence of gates to idling qubits. This cancels out some unwanted interactions with the environment. In the following cell, we add dynamic decoupling to the circuit transpiled with `optimization_level=3`, and add it to our list."
]
},
{
@@ -1136,9 +1139,7 @@
"dd_sequence = [XGate(), XGate()]\n",
"\n",
"# Run scheduling and dynamic decoupling passes on circuit\n",
- "pm = PassManager([ASAPSchedule(durations),\n",
- " DynamicalDecoupling(durations, dd_sequence)]\n",
- " )\n",
+ "pm = PassManager([ASAPSchedule(durations), DynamicalDecoupling(durations, dd_sequence)])\n",
"circ_dd = pm.run(circuits[1])\n",
"\n",
"# Add this new circuit to our list\n",
@@ -1153,7 +1154,7 @@
"\n",
"## Run user-transpiled circuits using Qiskit Runtime\n",
"\n",
- "At this point, we have a list of circuits (named `circuits`) transpiled for `ibm_algiers`. In the cell below, we create an instance of the sampler primitive, and start a session using the context manager (`with ...:`), which automatically opens and closes the session for us. This is where we pass the `skip_transpilation=True` argument.\n",
+ "At this point, we have a list of circuits (named `circuits`) transpiled for `ibm_algiers`. In the following cell, we create an instance of the sampler primitive, and start a session using the context manager (`with ...:`), which automatically opens and closes the session for us. This is where we pass the `skip_transpilation=True` argument.\n",
"\n",
"Within the context manager, we sample the circuits and store the results to `result`."
]
@@ -1170,8 +1171,9 @@
" sampler = Sampler()\n",
" job = sampler.run(\n",
" circuits=circuits, # sample all three circuits\n",
- " skip_transpilation=True, \n",
- " shots=8000)\n",
+ " skip_transpilation=True,\n",
+ " shots=8000,\n",
+ " )\n",
" result = job.result()"
]
},
@@ -2672,13 +2674,18 @@
],
"source": [
"from qiskit.visualization import plot_histogram\n",
+ "\n",
"binary_prob = [quasi_dist.binary_probabilities() for quasi_dist in result.quasi_dists]\n",
- "plot_histogram(binary_prob+[ideal_distribution],\n",
- " bar_labels=False,\n",
- " legend=['optimization_level=0',\n",
- " 'optimization_level=3',\n",
- " 'optimization_level=3 + dd',\n",
- " 'ideal distribution'])"
+ "plot_histogram(\n",
+ " binary_prob + [ideal_distribution],\n",
+ " bar_labels=False,\n",
+ " legend=[\n",
+ " \"optimization_level=0\",\n",
+ " \"optimization_level=3\",\n",
+ " \"optimization_level=3 + dd\",\n",
+ " \"ideal distribution\",\n",
+ " ],\n",
+ ")"
]
},
{
@@ -2705,6 +2712,7 @@
],
"source": [
"from qiskit.quantum_info import hellinger_fidelity\n",
+ "\n",
"for counts in result.quasi_dists:\n",
" print(\n",
" f\"{hellinger_fidelity(counts.binary_probabilities(), ideal_distribution):.3f}\"\n",
@@ -2729,6 +2737,7 @@
],
"source": [
"import qiskit_ibm_runtime\n",
+ "\n",
"qiskit_ibm_runtime.version.get_version_info()"
]
},
@@ -2764,6 +2773,7 @@
],
"source": [
"from qiskit.tools.jupyter import *\n",
+ "\n",
"%qiskit_version_table\n",
"%qiskit_copyright"
]
diff --git a/docs/tutorials/vqe_with_estimator.ipynb b/docs/tutorials/vqe_with_estimator.ipynb
index b993bb776..b22c2732d 100644
--- a/docs/tutorials/vqe_with_estimator.ipynb
+++ b/docs/tutorials/vqe_with_estimator.ipynb
@@ -5,11 +5,11 @@
"id": "0658e7c7",
"metadata": {},
"source": [
- "# Variational Quantum Eigensolver with Estimator Primitive\n",
+ "# Variational Quantum Eigensolver with Estimator primitive\n",
"\n",
"## Overview\n",
"\n",
- "The Variational Quantum Eigensolver (VQE) is an optimization routine for finding the ground state energy (the lowest eigenvalue) of a [Hamiltonian](https://en.wikipedia.org/wiki/Hamiltonian_(quantum_mechanics)) and is a considered to be a viable candidate for near-term hardware. In this tutorial, you will learn how to use Qiskit Runtime to submit variational jobs using the estimator primitive. Specifically, you will calculate the ground state energy of the $H_2$ molecule."
+ "The Variational Quantum Eigensolver (VQE) is an optimization routine for finding the ground state energy (the lowest eigenvalue) of a [Hamiltonian](https://en.wikipedia.org/wiki/Hamiltonian_(quantum_mechanics)) and is a considered to be a viable candidate for near-term hardware. In this tutorial, you will learn how to use Qiskit Runtime to submit variational jobs using the `Estimator` primitive. Specifically, you will calculate the ground state energy of the $H_2$ molecule."
]
},
{
@@ -29,7 +29,7 @@
"source": [
"## Generate molecular Hamiltonians\n",
"\n",
- "This tutorial uses Qiskit Nature to generate and handle molecular Hamiltonians. If you haven't already, you can install Qiskit Nature (and the PySCF addon) using the commands shown below. For more information about Qiskit Nature, see the [_Getting started_ guide](https://qiskit.org/documentation/nature/getting_started.html).\n",
+ "This tutorial uses Qiskit Nature to generate and handle molecular Hamiltonians. If you haven't already, you can install Qiskit Nature (and the PySCF addon) using the following commands. For more information about Qiskit Nature, see the [_Getting started_ guide](https://qiskit.org/documentation/nature/getting_started.html).\n",
"\n",
"```\n",
"pip install qiskit-nature\n",
@@ -47,12 +47,14 @@
"outputs": [],
"source": [
"from qiskit_nature.second_q.drivers import PySCFDriver\n",
+ "\n",
"driver = PySCFDriver(\n",
" atom=\"H 0 0 0; H 0 0 0.72\" # Two Hydrogen atoms, 0.72 Angstrom apart\n",
")\n",
"molecule = driver.run()\n",
"\n",
"from qiskit_nature.second_q.mappers import QubitConverter, ParityMapper\n",
+ "\n",
"qubit_converter = QubitConverter(ParityMapper())\n",
"hamiltonian = qubit_converter.convert(molecule.second_q_ops()[0])"
]
@@ -64,7 +66,7 @@
"source": [
"## Solve classically\n",
"\n",
- "Since this problem is very small, we can solve it exactly using classical methods. The code below uses the minimum eigensolver from the `NumPy` package to find the electronic ground state energy (in Hartree units), which we will use to assess the performance of the VQE."
+ "Since this problem is very small, we can solve it exactly using classical methods. The following code uses the minimum eigensolver from the `NumPy` package to find the electronic ground state energy (in Hartree units), which we will use to assess the performance of the VQE."
]
},
{
@@ -86,6 +88,7 @@
],
"source": [
"from qiskit.algorithms.minimum_eigensolvers import NumPyMinimumEigensolver\n",
+ "\n",
"sol = NumPyMinimumEigensolver().compute_minimum_eigenvalue(hamiltonian)\n",
"real_solution = molecule.interpret(sol)\n",
"\n",
@@ -99,7 +102,7 @@
"source": [
"## Solve with VQE\n",
"\n",
- "Next, we will create our service instance and specify our backend. In this example we will use a simulator to avoid queue times, but you can use the code below to run on a real device by simply changing the backend."
+ "Next, we will create our service instance and specify our backend. In this example we will use a simulator to avoid queue times, but you can use the following code to run on a real device by simply changing the backend."
]
},
{
@@ -124,10 +127,10 @@
"The next code cell specifies how we want to run the VQE. This includes\n",
"\n",
"- the type of circuit (ansatz) used to create our trial state,\n",
- "- the classical algorithm that decides how to adjust our trial state to acheive better solutions, and\n",
+ "- the classical algorithm that decides how to adjust our trial state to achieve better solutions, and\n",
"- the starting parameters.\n",
"\n",
- "We will also create a simple object to log our intermediate resuts for plotting later."
+ "We will also create a simple object to log our intermediate results for plotting later."
]
},
{
@@ -141,29 +144,36 @@
"\n",
"# Use RealAmplitudes circuit to create trial states\n",
"from qiskit.circuit.library import RealAmplitudes\n",
+ "\n",
"ansatz = RealAmplitudes(num_qubits=2, reps=2)\n",
"\n",
"# Search for better states using SPSA algorithm\n",
"from qiskit.algorithms.optimizers import SPSA\n",
+ "\n",
"optimizer = SPSA(150)\n",
"\n",
"# Set a starting point for reproduceability\n",
"import numpy as np\n",
+ "\n",
"np.random.seed(6)\n",
"initial_point = np.random.uniform(-np.pi, np.pi, 12)\n",
"\n",
"# Create an object to store intermediate results\n",
"from dataclasses import dataclass\n",
+ "\n",
+ "\n",
"@dataclass\n",
"class VQELog:\n",
" values: list\n",
" parameters: list\n",
+ "\n",
" def update(self, count, parameters, mean, _metadata):\n",
" self.values.append(mean)\n",
" self.parameters.append(parameters)\n",
" print(f\"Running circuit {count} of ~350\", end=\"\\r\", flush=True)\n",
"\n",
- "log = VQELog([],[])"
+ "\n",
+ "log = VQELog([], [])"
]
},
{
@@ -195,17 +205,26 @@
" options = Options()\n",
" options.optimization_level = 3\n",
"\n",
- " vqe = VQE(Estimator(session=session, options=options),\n",
- " ansatz, optimizer, callback=log.update, initial_point=initial_point)\n",
+ " vqe = VQE(\n",
+ " Estimator(session=session, options=options),\n",
+ " ansatz,\n",
+ " optimizer,\n",
+ " callback=log.update,\n",
+ " initial_point=initial_point,\n",
+ " )\n",
" result = vqe.compute_minimum_eigenvalue(hamiltonian)\n",
" print(\"Experiment complete.\".ljust(30))\n",
" print(f\"Raw result: {result.optimal_value}\")\n",
- " \n",
- " if 'simulator' not in backend:\n",
+ "\n",
+ " if \"simulator\" not in backend:\n",
" # Run once with ZNE error mitigation\n",
" options.resilience_level = 2\n",
- " vqe = VQE(Estimator(session=session, options=options),\n",
- " ansatz, SPSA(1), initial_point=result.optimal_point)\n",
+ " vqe = VQE(\n",
+ " Estimator(session=session, options=options),\n",
+ " ansatz,\n",
+ " SPSA(1),\n",
+ " initial_point=result.optimal_point,\n",
+ " )\n",
" result = vqe.compute_minimum_eigenvalue(hamiltonian)\n",
" print(f\"Mitigated result: {result.optimal_value}\")"
]
@@ -215,7 +234,7 @@
"id": "8199c3e9",
"metadata": {},
"source": [
- "Finally, the code cell below plots the intermediate results from the optimization process. The optimization algorithm tweaks the parameters to gradually home in on values that produce lower energies. Provided the algorithm does not get caught in a local minima, this graph will plateau at the electronic ground state energy of the molecule."
+ "Finally, the following code cell plots the intermediate results from the optimization process. The optimization algorithm tweaks the parameters to gradually home in on values that produce lower energies. Provided the algorithm does not get caught in a local minima, this graph will plateau at the electronic ground state energy of the molecule."
]
},
{
@@ -1637,6 +1656,7 @@
],
"source": [
"import qiskit_ibm_runtime\n",
+ "\n",
"qiskit_ibm_runtime.version.get_version_info()"
]
},
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 63322ebcd..6113ed906 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -7,6 +7,7 @@ sphinx-rtd-theme>=0.4.0
sphinx-tabs>=1.1.11
sphinx-automodapi
sphinx-autodoc-typehints<=1.19.2
+nbqa==1.5.3
matplotlib>=2.1
jupyter
jupyter-sphinx
diff --git a/test/docs/IBMQuantum/Abbreviations.yml b/test/docs/IBMQuantum/Abbreviations.yml
new file mode 100644
index 000000000..e7b85f235
--- /dev/null
+++ b/test/docs/IBMQuantum/Abbreviations.yml
@@ -0,0 +1,7 @@
+extends: existence
+message: "Do not use periods in all-uppercase abbreviations such as '%s'."
+link: 'https://www.ibm.com/developerworks/library/styleguidelines/index.html#N100DC'
+level: error
+nonword: true
+tokens:
+ - '\b(?:[A-Z]\.){3,5}'
diff --git a/test/docs/IBMQuantum/DashSpacing.yml b/test/docs/IBMQuantum/DashSpacing.yml
new file mode 100644
index 000000000..ea9a103b7
--- /dev/null
+++ b/test/docs/IBMQuantum/DashSpacing.yml
@@ -0,0 +1,13 @@
+extends: existence
+message: "Add spaces around the dash in '%s'."
+link: 'https://www.ibm.com/developerworks/library/styleguidelines/index.html#N106BF'
+ignorecase: true
+nonword: true
+level: error
+action:
+ name: edit
+ params:
+ - remove
+ - ' '
+tokens:
+ - '[^\s][—–][^\s]'
diff --git a/test/docs/IBMQuantum/Definitions.yml b/test/docs/IBMQuantum/Definitions.yml
new file mode 100644
index 000000000..b60b88851
--- /dev/null
+++ b/test/docs/IBMQuantum/Definitions.yml
@@ -0,0 +1,69 @@
+extends: conditional
+message: "Define acronyms and abbreviations (such as '%s') on first occurrence if they're likely to be unfamiliar."
+link: 'https://www.ibm.com/developerworks/library/styleguidelines/index.html#N100DC'
+level: suggestion
+ignorecase: false
+# Ensures that the existence of 'first' implies the existence of 'second'.
+first: '\b([A-Z]{3,5}s?)\b'
+second: '\(([A-Z]{3,5}s?)\)'
+# ... with the exception of these:
+exceptions:
+ - API
+ - ASP
+ - CLI
+ - CPU
+ - CNOT
+ - CSS
+ - CSV
+ - DEBUG
+ - DOM
+ - DPI
+ - FAQ
+ - GCC
+ - GDB
+ - GET
+ - GPU
+ - GTK
+ - GUI
+ - HTML
+ - HTTP
+ - HTTPS
+ - IBM
+ - IDE
+ - JAR
+ - JSON
+ - JSX
+ - LESS
+ - LLDB
+ - NBQA
+ - NET
+ - NOTE
+ - NVDA
+ - OSS
+ - PATH
+ - PDF
+ - PHP
+ - POST
+ - QPU
+ - RAM
+ - REPL
+ - RSA
+ - SCM
+ - SCSS
+ - SDK
+ - SQL
+ - SSH
+ - SSL
+ - SVG
+ - SWAT
+ - TBD
+ - TCP
+ - TODO
+ - URI
+ - URL
+ - USB
+ - UTF
+ - XML
+ - XSS
+ - YAML
+ - ZIP
diff --git a/test/docs/IBMQuantum/Headings.yml b/test/docs/IBMQuantum/Headings.yml
new file mode 100644
index 000000000..cd0f4f770
--- /dev/null
+++ b/test/docs/IBMQuantum/Headings.yml
@@ -0,0 +1,28 @@
+extends: capitalization
+message: "'%s' should use sentence-style capitalization."
+link: 'https://www.ibm.com/developerworks/library/styleguidelines/index.html#N1030C'
+level: warning
+scope: heading
+match: $sentence
+indicators:
+ - ':'
+ - '.'
+ - ')'
+exceptions:
+ - API
+ - App ID
+ - IBM
+ - IBM Quantum
+ - Qiskit
+ - Runtime
+ - Sampler
+ - Estimator
+ - Terraform
+ - Trotter
+ - Grover
+ - Hamiltonian
+ - Hamiltonians
+ - Cloud
+ - Spectroscopic Eigensolver Algorithm
+ - Variational Quantum Eigensolver
+ - (\d+)\.
diff --git a/test/docs/IBMQuantum/However.yml b/test/docs/IBMQuantum/However.yml
new file mode 100644
index 000000000..e1322dc45
--- /dev/null
+++ b/test/docs/IBMQuantum/However.yml
@@ -0,0 +1,7 @@
+extends: existence
+message: Double-check your punctuation around 'however' (see github.com/IBM/ibm-quantum-style-guide/issues/10 for more information).
+level: suggestion
+code: false
+ignorecase: false
+raw:
+ - ([^;,] however|however[^,])
diff --git a/test/docs/IBMQuantum/Latin.yml b/test/docs/IBMQuantum/Latin.yml
new file mode 100644
index 000000000..b0d2b2b1c
--- /dev/null
+++ b/test/docs/IBMQuantum/Latin.yml
@@ -0,0 +1,13 @@
+extends: substitution
+message: "Use '%s' instead of '%s'."
+link: 'https://www.ibm.com/developerworks/library/styleguidelines/index.html#wordlist'
+ignorecase: true
+level: error
+nonword: true
+action:
+ name: replace
+swap:
+ '\b(?:eg|e\.g\.)[\s,]': for example
+ '\b(?:ie|i\.e\.)[\s,]': that is
+ '\betc\.': and so on
+ '\bvs\.': versus
diff --git a/test/docs/IBMQuantum/OxfordComma.yml b/test/docs/IBMQuantum/OxfordComma.yml
new file mode 100644
index 000000000..6e7f76c7a
--- /dev/null
+++ b/test/docs/IBMQuantum/OxfordComma.yml
@@ -0,0 +1,6 @@
+extends: existence
+message: "Use the Oxford comma in '%s'."
+link: 'https://www.ibm.com/developerworks/library/styleguidelines/index.html#N106BF'
+level: suggestion
+tokens:
+ - '(?:[^,]+,){1,}\s\w+\sand'
diff --git a/test/docs/IBMQuantum/Politeness.yml b/test/docs/IBMQuantum/Politeness.yml
new file mode 100644
index 000000000..43bf6975d
--- /dev/null
+++ b/test/docs/IBMQuantum/Politeness.yml
@@ -0,0 +1,9 @@
+extends: existence
+message: "Don't use '%s'"
+link: 'https://github.com/IBM/ibm-quantum-style-guide/issues/16'
+ignorecase: true
+level: error
+tokens:
+ - please
+ - thanks
+ - thank you
diff --git a/test/docs/IBMQuantum/Repetition.yml b/test/docs/IBMQuantum/Repetition.yml
new file mode 100644
index 000000000..102ebb3ce
--- /dev/null
+++ b/test/docs/IBMQuantum/Repetition.yml
@@ -0,0 +1,6 @@
+extends: repetition
+message: "'%s' is repeated!"
+level: error
+alpha: true
+tokens:
+ - '[^\s]+'
diff --git a/test/docs/IBMQuantum/Spelling.yml b/test/docs/IBMQuantum/Spelling.yml
new file mode 100644
index 000000000..1dc1ad07a
--- /dev/null
+++ b/test/docs/IBMQuantum/Spelling.yml
@@ -0,0 +1,5 @@
+extends: spelling
+message: "Unknown word '%s'; fix or add to dictionary."
+level: error
+ignore:
+ - dictionary.txt
diff --git a/test/docs/IBMQuantum/Terms.yml b/test/docs/IBMQuantum/Terms.yml
new file mode 100644
index 000000000..77527dfeb
--- /dev/null
+++ b/test/docs/IBMQuantum/Terms.yml
@@ -0,0 +1,184 @@
+extends: substitution
+message: Use '%s' rather than '%s'
+link: 'https://www.ibm.com/developerworks/library/styleguidelines/index.html#wordlist'
+level: warning
+ignorecase: true
+action:
+ name: replace
+# swap maps tokens in form of bad: good
+swap:
+ '(?:Ctrl|control)-click': press Ctrl and click
+ 'a lot(?: of)?': many|much
+ 'backward(?:-)?compatible': compatible with earlier versions
+ 'down(?:-)?level': earlier|previous|not at the latest level
+ 'mash(?: )?up': create
+ 'pop-up (?:blocker|killer)': software to block pop-up ad windows
+ 're(?:-)?occur': recur
+ 'sort(?:-|/)?merge': sort|merge
+ 'do(?: )(?!not|so)': complete|perform
+
+ bottom: end|last
+ below: following
+ above: previous
+ top: start|beginning|first
+ a number of: several
+ abort: cancel|stop
+ administrate: administer
+ all caps: uppercase
+ and/or: a or b|a, b, or both
+ as long as: if|provided that
+ as per: according to|as|as in
+ back-level: earlier|previous|not at the latest level
+ Big Blue: IBM
+ blink: flash
+ blue screen of death: stop error
+ breadcrumbing: breadcrumb trail
+ canned: preplanned|preconfigured|predefined
+ case insensitive: not case-sensitive
+ catastrophic error: unrecoverable error
+ CBE: Common Base Event
+ CBTS: CICS BTS|BTS
+ cold boot: hardware restart
+ cold start: hardware restart
+ comes with: includes
+ componentization: component-based development|component model|component architecture|shared components
+ componentize: develop components
+ comprised of: consist of
+ connect with: connect to
+ context menu: menu|pop-up menu
+ contextual help: help|context-sensitive help
+ crash: fail|lock up|stop|stop responding
+ CRUD: create retrieve update and delete
+ customer: client
+ datum: data
+ debuggable: debug
+ deconfigure: unconfigure
+ deinstall: uninstall
+ deinstallation: uninstallation
+ demilitarized zone: DMZ
+ demo: demonstration
+ depress: press|type
+ deregister: unregister
+ desire: want|required
+ destroy: delete from the database
+ dismount: demount|unmount|remove
+ downgrade: upgrade|fallback|fall back|rollback|roll back
+ downward compatible: compatible with earlier versions
+ drag and drop: drag
+ drill up: navigate
+ e-fix: fix|interim fix
+ eFix: fix|interim fix
+ end user: user
+ end-user interface: graphical interface|interface
+ EUI: graphical user interface|interface
+ expose: display|show|make available
+ fill in: complete|enter|specify
+ fixed disk drive: hard disk drive
+ flavor: version|method
+ floppy disk: diskette|diskette drive
+ floppy drive: diskette|diskette drive
+ floppy: diskette|diskette drive
+ forward compatible: compatible with later versions
+ gzip: compress
+ gzipped: archive|compressed file
+ hard drive: hard disk|hard disk drive
+ hard file: hard disk|hard disk drive
+ hence: therefore
+ i-fix: interim fix
+ i-Fix: interim fix
+ IBM's: IBM's|IBM's AIX
+ ifix: interim fix
+ iFix: interim fix
+ in order to: to
+ in other words: for example|that is
+ in spite of: regardless of|despite
+ in the event: in case|if|when
+ inactivate: deactivate
+ information on: information about
+ information technology: IT
+ instead of: rather than
+ insure: ensure
+ Internet address: IP address|URL|Internet email address|web address
+ irrecoverable: unrecoverable
+ jar: compress|archive
+ keep in mind: remember
+ launch: start|open
+ left-hand: left
+ leverage: use
+ line cord: power cable|power cord
+ main directory: root directory
+ memory stick: USB flash drive
+ microcomputer: PC
+ motherboard: system board
+ mouse over: point to|move the mouse pointer over|Mouse|mouse over
+ network-centric computing: network computing
+ non-English: in languages other than English|non-English-language
+ nonrecoverable: unrecoverable
+ notion: concept
+ off-premise: on-premises|off-premises|onsite|offsite
+ offline storage: auxiliary storage
+ okay: OK
+ on ramp: access method
+ on the fly: dynamically|as needed|in real time|immediately
+ on the other hand: however|alternatively|conversely
+ on-premise: on-premises|off-premises|onsite|offsite
+ on-ramp: access method
+ pain point: challenge|concern|difficulty|issue
+ parent task: parent process
+ patch: fix|test fix|interim fix|fix pack|program temporary fix
+ perimeter network: DMZ
+ power down: turn on|turn off
+ power off: turn on|turn off
+ power on: turn on|turn off
+ preload: preinstall|preinstalled
+ preloaded: preinstall|preinstalled
+ prepend: add a prefix to
+ prior to: before
+ recommend: suggest
+ retry: retry|try again
+ right double-click: double right-click
+ right-hand: right
+ rule of thumb: rule
+ sanity check: test|evaluate
+ secondary storage: auxiliary storage
+ selection button: left mouse button
+ serial database: nonpartitioned database environment
+ shift-click: press Shift and click
+ ship: include|included
+ Simple Object Access Protocol: SOAP
+ single quote mark: single quotation mark
+ single quote: single quotation mark
+ SME routine: session management exit routine
+ start up: start
+ sunset: withdraw from service|withdraw from marketing|discontinue|no longer support
+ switch off: power on|turn on|power off|turn off
+ switch on: power on|turn on|power off|turn off
+ tar: compress|archive
+ tarball: tar file
+ terminate: end|stop
+ thru: through
+ thumbstick: USB flash drive
+ thus: therefore
+ toggle off: toggle
+ tooling: tools
+ touchscreen: touch-sensitive screen
+ transition: make the transition|move|migrate|change
+ transparent: indiscernible|not visible
+ typo: typing error|typographical error
+ uncheck: clear
+ uncompress: decompress
+ undeploy: remove|withdraw
+ unjar: extract
+ unselect: clear|deselect
+ untar: extract
+ unzip: unzip
+ upward compatible: compatible with later versions
+ utilize: use
+ versus: compared to
+ via: through
+ warning notice: attention notice
+ web-enable: enable for the web
+ webinar: webinar|webcast|web seminar|web-based event
+ wish: want
+ zero out: zero
+ zip: zip|compress
diff --git a/test/docs/dictionary.txt b/test/docs/dictionary.txt
new file mode 100644
index 000000000..81c20c11b
--- /dev/null
+++ b/test/docs/dictionary.txt
@@ -0,0 +1,245 @@
+Abelian
+Abhinav
+Aer
+Akira
+Amyra
+Andersson
+Andriyash
+Aroosa
+Arunachalam
+Asfaw
+Auditability
+Babbush
+Barowski
+Bello
+Bengio
+Bergholm
+Bernagozzi
+Bertels
+Bertet
+Boeblingen
+Boixo
+Boulant
+Briegel
+Broughton
+Brukner
+Bucher
+CNOTs
+Carleo
+Carrera
+Cerezo
+Chuang
+Cincio
+Clauser
+Colbeck
+Corcoles
+Courville
+Derks
+Deutsch
+Deutschle
+Dewes
+Dunjko
+Elies
+Esteve
+Faehrmann
+Farhi
+Fock
+Francesco
+Fredkin
+Gacon
+Garey
+Glick
+Goemans
+Gogolin
+Goodfellow
+Greenberger
+Griffiths
+Gutmann
+Hadamard
+Haide
+Hamiltonian
+Hamiltonians
+Harkins
+Hartmut
+Hartree
+Havlicek
+Hellinger
+Hindy
+Hiptmair
+Hoyer
+Hubregtsen
+Ijaz
+Iten
+Izaac
+Jakob
+Jozsa
+Jurcevic
+Kandala
+Keras
+Killoran
+Kitaev
+Koen
+Kohli
+Kristan
+Kulchytskyy
+Kus
+Lauro
+Leib
+Litinski
+Liu
+Lorenza
+Lucchi
+Lukasz
+Maika
+Markus
+Masoud
+Melko
+Mezzacapo
+Minev
+Mohseni
+Mondada
+Mosca
+Mueggenburg
+Neven
+Ong
+Opflow
+Osodo
+Ozair
+Peruzzo
+Petar
+Petruccione
+Pichlmeier
+Plesch
+QPUs
+Qiskit's
+Ravi
+Revview
+Rivero
+Rolfe
+Runtime's
+Schmitt
+Schroeter
+Schuld
+Schwarz
+Shadbolt
+Shen
+Shende
+Shewchuk
+Shimony
+Shor's
+Simulatable
+Smelyanskiy
+Srinivasan
+Stamatopoulos
+Steenken
+Stephane
+Streif
+Sukin
+Takita
+Tanvi
+Tapp
+Technol
+Temme
+Toeplitz
+Toffoli
+Tommaso
+Trackerservice
+Trotterization
+Trotterize
+Trotterizing
+Vadim
+Vedran
+Ville
+Vion
+Vivek
+Vojtech
+Volkoff
+Weedbrook
+Wierichs
+Woerner
+Wootton
+Youngseok
+Yousef
+Yunchao
+Yung
+Zeilinger
+Zeng
+Zhou
+Zoufal
+addon
+anharmonic
+ansatz
+ansatzes
+arXiv
+autoencoder
+autoencoders
+backend's
+bilinearity
+bitstring
+bool
+colocated
+coprime
+decohere
+disproven
+doi
+ebit
+eigenbasis
+eigensolver
+eigensolvers
+eigenstate
+eigenstates
+endian
+exponentials
+expressibility
+fanout
+fermionic
+fidelities
+hyperparameter
+hyperparameters
+ket
+kets
+minimax
+misclassifying
+multilinear
+namespace
+nucleobase
+orthogonalization
+orthonormality
+parameterization
+polynomially
+preprint
+priori
+pseudocode
+qiskit
+quantizing
+quasiprobabilities
+quasiprobability
+qubit
+qubit's
+qubits
+qudit
+qutrits
+recalibrated
+reuploading
+satisfiability
+simulability
+subfield
+subfields
+subscripting
+substring
+substrings
+sudoku
+summand
+summands
+tooltip
+tooltips
+transmon
+transpilation
+transpile
+transpiled
+transpiler
+transpiler's
+transpiling
+tridiagonal
+trits
+unitaries
diff --git a/test/docs/vale.sh b/test/docs/vale.sh
new file mode 100755
index 000000000..f4bd36416
--- /dev/null
+++ b/test/docs/vale.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+cd ./docs
+
+vale .
+
+echo
+echo "Linting notebooks using nbQA:"
+
+notebooks=$(find . -name "*.ipynb" -not -name "*checkpoint*" -not -path "./_**")
+
+python -m nbqa vale ${notebooks} --nbqa-shell --nbqa-md