diff --git a/docs/run/primitives.mdx b/docs/run/primitives.mdx
index 9a6fd952ede..70c9f1aa0da 100644
--- a/docs/run/primitives.mdx
+++ b/docs/run/primitives.mdx
@@ -45,12 +45,13 @@ An expectation value of an observable could be the target quantity in scenarios
The open-source primitives contain the base classes (to define interfaces) and a reference implementation. The Qiskit Runtime primitives provide a more sophisticated implementation (such as with error mitigation) as a cloud-based service.
+
## Where should I import the primitive from?
There are different primitive implementations in the ``qiskit``, ``qiskit_aer``, and ``qiskit_ibm_runtime`` libraries.
Each implementation serves a specific purpose:
-* The primitives in ``qiskit`` can perform local state vector simulations - useful for quickly prototyping algorithms.
+* The primitives in ``qiskit`` can perform local statevector simulations - useful for quickly prototyping algorithms.
* The `qiskit.primitives` module enables the development of primitive-style quantum programs and was specifically designed to simplify switching between different types of backends. The module provides three separate classes for each primitive type:
1. `Sampler` and `Estimator`
diff --git a/docs/verify/__use_estimator.mdx b/docs/verify/__use_estimator.mdx
deleted file mode 100644
index 3eabf7b0c13..00000000000
--- a/docs/verify/__use_estimator.mdx
+++ /dev/null
@@ -1,248 +0,0 @@
----
-title: Estimator primitive
-description: How to compute an expectation value with the `Estimator` primitive
----
-
-# Compute an expectation value with `Estimator` primitive
-
-This guide shows how to get the expected value of an observable for a given quantum circuit with the [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) primitive.
-
-
- While this guide uses Qiskit’s reference implementation, the `Estimator` primitive can be run with any provider using [`qiskit.primitives.BackendEstimator`](../api/qiskit/qiskit.primitives.BackendEstimator).
-
- ```python
- from qiskit.primitives import BackendEstimator
- from import QiskitProvider
-
- provider = QiskitProvider()
- backend = provider.get_backend('backend_name')
- estimator = BackendEstimator(backend)
- ```
-
- There are some providers that implement primitives natively (see [this page](https://qiskit.org/providers/#primitives) for more details).
-
-
-## Initialize observables
-
-The first step is to define the observables whose expected value you want to compute. Each observable can be any `BaseOperator`, like the operators from [`qiskit.quantum_info`](../api/qiskit/quantum_info).
-Among them it is preferable to use [`qiskit.quantum_info.SparsePauliOp`](../api/qiskit/qiskit.quantum_info.SparsePauliOp).
-
-```python
-from qiskit.quantum_info import SparsePauliOp
-
-observable = SparsePauliOp(["II", "XX", "YY", "ZZ"], coeffs=[1, 1, -1, 1])
-```
-
-## Initialize quantum circuit
-
-Then you need to create the [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit)s for which you want to obtain the expected value.
-
-```python
-from qiskit import QuantumCircuit
-
-qc = QuantumCircuit(2)
-qc.h(0)
-qc.cx(0,1)
-qc.draw("mpl")
-```
-
-
-
-
- The [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit) you pass to [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) must not include any measurements.
-
-
-## Initialize the `Estimator`
-
-Then, you need to instantiate an [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator).
-
-```python
-from qiskit.primitives import Estimator
-
-estimator = Estimator()
-```
-
-## Run and get results
-
-Now that you have defined your `estimator`, you can run your estimation by calling the [`qiskit.primitives.Estimator.run`](../api/qiskit/qiskit.primitives.Estimator#run) method,
-which returns an instance of [`qiskit.providers.JobV1`](../api/qiskit/qiskit.providers.JobV1). You can get the results from the job (as a [`qiskit.primitives.EstimatorResult`](../api/qiskit/qiskit.primitives.EstimatorResult) object)
-with the [`qiskit.providers.JobV1.result`](../api/qiskit/qiskit.providers.JobV1#result) method.
-
-```python
-job = estimator.run(qc, observable)
-result = job.result()
-print(result)
-```
-
-```python
-EstimatorResult(values=array([4.]), metadata=[{}])
-```
-
-While this example only uses one [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit) and one observable, if you want to get expectation values for multiple circuits and observables you can
-pass a `list` of [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit)s and a list of `BaseOperator`s to the [`qiskit.primitives.Estimator.run`](../api/qiskit/qiskit.primitives.Estimator#run) method. Both `list`s must have
-the same length.
-
-### Get the expected value
-
-From these results you can extract the expected values with the attribute [`qiskit.primitives.EstimatorResult.values`](../api/qiskit/qiskit.primitives.EstimatorResult#values).
-
-[`qiskit.primitives.EstimatorResult.values`](../api/qiskit/qiskit.primitives.EstimatorResult#values) returns a `numpy.ndarray`
-whose `i`-th element is the expectation value corresponding to the `i`-th circuit and `i`-th observable.
-
-```python
-exp_value = result.values[0]
-print(exp_value)
-```
-
-```python
-3.999999999999999
-```
-
-## Parameterized circuit with `Estimator`
-
-The [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) primitive can be run with unbound parameterized circuits like the one below.
-You can also manually bind values to the parameters of the circuit and follow the steps
-of the previous example.
-
-```python
-from qiskit.circuit import Parameter
-
-theta = Parameter('θ')
-param_qc = QuantumCircuit(2)
-param_qc.ry(theta, 0)
-param_qc.cx(0,1)
-print(param_qc.draw())
-```
-
-```
- ┌───────┐
-q_0: ┤ Ry(θ) ├──■──
- └───────┘┌─┴─┐
-q_1: ─────────┤ X ├
- └───┘
-```
-
-The main difference with the previous case is that now you need to specify the sets of parameter values
-for which you want to evaluate the expectation value as a `list` of `list`s of `float`s.
-The `i`-th element of the outer `list` is the set of parameter values
-that corresponds to the `i`-th circuit and observable.
-
-```python
-import numpy as np
-
-parameter_values = [[0], [np.pi/6], [np.pi/2]]
-
-job = estimator.run([param_qc]*3, [observable]*3, parameter_values=parameter_values)
-values = job.result().values
-
-for i in range(3):
- print(f"Parameter: {parameter_values[i][0]:.5f}\t Expectation value: {values[i]}")
-```
-
-```
-Parameter: 0.00000 Expectation value: 2.0
-Parameter: 0.52360 Expectation value: 3.0
-Parameter: 1.57080 Expectation value: 4.0
-```
-
-## Change run options
-
-Your workflow might require tuning primitive run options, such as the amount of shots.
-
-By default, the reference [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) class performs an exact statevector
-calculation based on the [`qiskit.quantum_info.Statevector`](../api/qiskit/qiskit.quantum_info.Statevector) class. However, this can be
-modified to include shot noise if the number of `shots` is set.
-For reproducibility purposes, a `seed` will also be set in the following examples.
-
-There are two main ways of setting options in the [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator):
-
-- Set keyword arguments in the [`qiskit.primitives.Estimator.run`](../api/qiskit/qiskit.primitives.Estimator#run) method.
-- Modify [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) options.
-
-### Set keyword arguments for [`qiskit.primitives.Estimator.run`](../api/qiskit/qiskit.primitives.Estimator#run)
-
-If you only want to change the settings for a specific run, it can be more convenient to
-set the options inside the [`qiskit.primitives.Estimator.run`](../api/qiskit/qiskit.primitives.Estimator#run) method. You can do this by
-passing them as keyword arguments.
-
-```python
-job = estimator.run(qc, observable, shots=2048, seed=123)
-result = job.result()
-print(result)
-```
-
-```python
-EstimatorResult(values=array([4.]), metadata=[{'variance': 3.552713678800501e-15, 'shots': 2048}])
-```
-
-```python
-print(result.values[0])
-```
-
-```python
-3.999999998697238
-```
-
-### Modify [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) options
-
-If you want to keep some configuration values for several runs, it can be better to
-change the [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) options. That way you can use the same
-[`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) object as many times as you wish without having to
-rewrite the configuration values every time you use [`qiskit.primitives.Estimator.run`](../api/qiskit/qiskit.primitives.Estimator#run).
-
-#### Modify existing [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator)
-
-If you prefer to change the options of an already-defined [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator), you can use
-the method [`qiskit.primitives.Estimator.set_options`](../api/qiskit/qiskit.primitives.Estimator#set_options) and introduce the new options as keyword arguments.
-
-```python
-estimator.set_options(shots=2048, seed=123)
-
-job = estimator.run(qc, observable)
-result = job.result()
-print(result)
-```
-
-```python
-EstimatorResult(values=array([4.]), metadata=[{'variance': 3.552713678800501e-15, 'shots': 2048}])
-```
-
-```python
-print(result.values[0])
-```
-
-```python
-3.999999998697238
-```
-
-#### Define a new [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) with the options
-
-If you prefer to define a new [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) with new options, you need to
-define a `dict` like this one:
-
-```python
-options = {"shots": 2048, "seed": 123}
-```
-
-And then you can introduce it into your new [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) with the
-`options` argument.
-
-```python
-estimator = Estimator(options=options)
-
-job = estimator.run(qc, observable)
-result = job.result()
-print(result)
-```
-
-```python
-EstimatorResult(values=array([4.]), metadata=[{'variance': 3.552713678800501e-15, 'shots': 2048}])
-```
-
-```python
-print(result.values[0])
-```
-
-```python
-3.999999998697238
-```
diff --git a/docs/verify/__use_sampler.mdx b/docs/verify/__use_sampler.mdx
deleted file mode 100644
index 0951d6655ef..00000000000
--- a/docs/verify/__use_sampler.mdx
+++ /dev/null
@@ -1,235 +0,0 @@
----
-title: Sampler primitive
-description: How to compute circuit output probabilities with the `Sampler` primitive
----
-
-# Compute circuit output probabilities with `Sampler` primitive
-
-This guide shows how to get the probability distribution of a quantum circuit with the [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) primitive.
-
-
- While this guide uses Qiskit’s reference implementation, the `Sampler` primitive can be run with any provider using [`qiskit.primitives.BackendSampler`](../api/qiskit/qiskit.primitives.BackendSampler).
-
- ```python
- from qiskit.primitives import BackendSampler
- from import QiskitProvider
-
- provider = QiskitProvider()
- backend = provider.get_backend('backend_name')
- sampler = BackendSampler(backend)
- ```
-
- There are some providers that implement primitives natively (see [this page](http://qiskit.org/providers/#primitives) for more details).
-
-
-## Initialize quantum circuits
-
-The first step is to create the [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit)s from which you want to obtain the probability distribution.
-
-```python
-from qiskit import QuantumCircuit
-
-qc = QuantumCircuit(2)
-qc.h(0)
-qc.cx(0,1)
-qc.measure_all()
-qc.draw("mpl")
-```
-
-
-
-
-The [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit) you pass to [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) has to include measurements.
-
-
-## Initialize the `Sampler`
-
-Then, you need to create a [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) instance.
-
-```python
-from qiskit.primitives import Sampler
-
-sampler = Sampler()
-```
-
-## Run and get results
-
-Now that you have defined your `sampler`, you can run it by calling the [`qiskit.primitives.Sampler.run`](../api/qiskit/qiskit.primitives.Sampler#run) method,
-which returns an instance of [`qiskit.providers.JobV1`](../api/qiskit/qiskit.providers.JobV1). You can get the results from the job (as a [`qiskit.primitives.SamplerResult`](../api/qiskit/qiskit.primitives.SamplerResult) object)
-with the [`qiskit.providers.JobV1.result`](../api/qiskit/qiskit.providers.JobV1#result) method.
-
-```python
-job = sampler.run(qc)
-result = job.result()
-print(result)
-```
-
-```python
-SamplerResult(quasi_dists=[{0: 0.4999999999999999, 3: 0.4999999999999999}], metadata=[{}])
-```
-
-While this example only uses one [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit), if you want to sample multiple circuits you can
-pass a `list` of [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit) instances to the [`qiskit.primitives.Sampler.run`](../api/qiskit/qiskit.primitives.Sampler#run) method.
-
-### Get the probability distribution
-
-From these results you can extract the quasi-probability distributions with the attribute [`qiskit.primitives.Sampler.quasi_dists`](../api/qiskit/qiskit.primitives.Sampler#quasi_dists).
-
-Even though there is only one circuit in this example, [`qiskit.primitives.Sampler.quasi_dists`](../api/qiskit/qiskit.primitives.Sampler#quasi_dists) returns a list of [`qiskit.result.QuasiDistribution`](../api/qiskit/qiskit.result.QuasiDistribution)s.
-`result.quasi_dists[i]` is the quasi-probability distribution of the `i`-th circuit.
-
-
-A quasi-probability distribution differs from a probability distribution in that negative values are also allowed.
-However the quasi-probabilities must sum up to 1 like probabilities.
-Negative quasi-probabilities may appear when using error mitigation techniques.
-
-
-```python
-quasi_dist = result.quasi_dists[0]
-print(quasi_dist)
-```
-
-```python
-{0: 0.4999999999999999, 3: 0.4999999999999999}
-```
-
-#### Probability distribution with binary outputs
-
-If you prefer to see the output keys as binary strings instead of decimal numbers, you can use the
-[`qiskit.result.QuasiDistribution.binary_probabilities`](../api/qiskit/qiskit.result.QuasiDistribution#binary_probabilities) method.
-
-```python
-print(quasi_dist.binary_probabilities())
-```
-
-```python
-{'00': 0.4999999999999999, '11': 0.4999999999999999}
-```
-
-## Parameterized circuit with `Sampler`
-
-The [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) primitive can be run with unbound parameterized circuits like the one below.
-You can also manually bind values to the parameters of the circuit and follow the steps
-of the previous example.
-
-```python
-from qiskit.circuit import Parameter
-
-theta = Parameter('θ')
-param_qc = QuantumCircuit(2)
-param_qc.ry(theta, 0)
-param_qc.cx(0,1)
-param_qc.measure_all()
-print(param_qc.draw())
-```
-
-```
- ┌───────┐ ░ ┌─┐
- q_0: ┤ Ry(θ) ├──■───░─┤M├───
- └───────┘┌─┴─┐ ░ └╥┘┌─┐
- q_1: ─────────┤ X ├─░──╫─┤M├
- └───┘ ░ ║ └╥┘
-meas: 2/══════════════════╩══╩═
- 0 1
-```
-
-The main difference from the previous case is that now you need to specify the sets of parameter values
-for which you want to evaluate the expectation value as a `list` of `list`s of `float`s.
-The `i`-th element of the outer `list` is the set of parameter values
-that corresponds to the `i`-th circuit.
-
-```python
-import numpy as np
-
-parameter_values = [[0], [np.pi/6], [np.pi/2]]
-
-job = sampler.run([param_qc]*3, parameter_values=parameter_values)
-dists = job.result().quasi_dists
-
-for i in range(3):
- print(f"Parameter: {parameter_values[i][0]:.5f}\t Probabilities: {dists[i]}")
-```
-
-```
-Parameter: 0.00000 Probabilities: {0: 1.0}
-Parameter: 0.52360 Probabilities: {0: 0.9330127018922194, 3: 0.0669872981077807}
-Parameter: 1.57080 Probabilities: {0: 0.5000000000000001, 3: 0.4999999999999999}
-```
-
-## Change run options
-
-Your workflow might require tuning primitive run options, such as the amount of shots.
-
-By default, the reference [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) class performs an exact statevector
-calculation based on the [`qiskit.quantum_info.Statevector`](../api/qiskit/qiskit.quantum_info.Statevector) class. However, this can be
-modified to include shot noise if the number of `shots` is set.
-For reproducibility purposes, a `seed` will also be set in the following examples.
-
-There are two main ways of setting options in the [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler):
-
-- Set keyword arguments in the [`qiskit.primitives.Sampler.run`](../api/qiskit/qiskit.primitives.Sampler#run) method.
-- Modify [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) options.
-
-### Set keyword arguments for [`qiskit.primitives.Sampler.run`](../api/qiskit/qiskit.primitives.Sampler#run)
-
-If you only want to change the settings for a specific run, it can be more convenient to
-set the options inside the [`qiskit.primitives.Sampler.run`](../api/qiskit/qiskit.primitives.Sampler#run) method. You can do this by
-passing them as keyword arguments.
-
-```python
-job = sampler.run(qc, shots=2048, seed=123)
-result = job.result()
-print(result)
-```
-
-```python
-SamplerResult(quasi_dists=[{0: 0.5205078125, 3: 0.4794921875}], metadata=[{'shots': 2048}])
-```
-
-### Modify [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) options
-
-If you want to keep some configuration values for several runs, it can be better to
-change the [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) options. That way you can use the same
-[`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) object as many times as you wish without having to
-rewrite the configuration values every time you use [`qiskit.primitives.Sampler.run`](../api/qiskit/qiskit.primitives.Sampler#run).
-
-#### Modify existing [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler)
-
-If you prefer to change the options of an already-defined [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler), you can use
-[`qiskit.primitives.Sampler.set_options`](../api/qiskit/qiskit.primitives.Sampler#set_options) and introduce the new options as keyword arguments.
-
-```python
-sampler.set_options(shots=2048, seed=123)
-
-job = sampler.run(qc)
-result = job.result()
-print(result)
-```
-
-```python
-SamplerResult(quasi_dists=[{0: 0.5205078125, 3: 0.4794921875}], metadata=[{'shots': 2048}])
-```
-
-#### Define a new [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) with the options
-
-If you prefer to define a new [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) with new options, you need to
-define a `dict` like this one:
-
-```python
-options = {"shots": 2048, "seed": 123}
-```
-
-And then you can introduce it into your new [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) with the
-`options` argument.
-
-```python
-sampler = Sampler(options=options)
-
-job = sampler.run(qc)
-result = job.result()
-print(result)
-```
-
-```python
-SamplerResult(quasi_dists=[{0: 0.5205078125, 3: 0.4794921875}], metadata=[{'shots': 2048}])
-```
diff --git a/docs/verify/_toc.json b/docs/verify/_toc.json
index 208ecf41cdc..5d7d1881035 100644
--- a/docs/verify/_toc.json
+++ b/docs/verify/_toc.json
@@ -6,8 +6,12 @@
"url": "/verify"
},
{
- "title": "Simulators overview",
- "url": "/verify/simulators"
+ "title": "IBM Quantum simulators",
+ "url": "/verify/cloud-based-simulators"
+ },
+ {
+ "title": "Simulate with Qiskit primitives",
+ "url": "/verify/simulate-with-qiskit-primitives"
},
{
"title": "Simulate with noise",
diff --git a/docs/verify/simulators.mdx b/docs/verify/cloud-based-simulators.mdx
similarity index 94%
rename from docs/verify/simulators.mdx
rename to docs/verify/cloud-based-simulators.mdx
index 4246835d8b7..32693a46137 100644
--- a/docs/verify/simulators.mdx
+++ b/docs/verify/cloud-based-simulators.mdx
@@ -1,11 +1,11 @@
---
-title: Simulators overview
-description: Overview of simulators
+title: IBM Quantum simulators
+description: Overview of IBM Quantum cloud-based simulators
---
-# Simulators overview
+# IBM Quantum simulators
-This page gives details about the IBM Quantum cloud-based simulators. For information about the Qiskit built-in simulator, see the [Python-based simulators page in the API reference.](https://docs.quantum-computing.ibm.com/api/qiskit/providers_basicaer)
+This page gives details about the IBM Quantum cloud-based simulators. For information about the Qiskit built-in simulator, see the [Python-based simulators page in the API reference.](../api/qiskit/providers_basicaer) You can also use the [Qiskit reference primitives](simulate-with-primitives) for local statevector simulation.
IBM Quantum features a collection of high-performance simulators for prototyping quantum circuits and algorithms.
diff --git a/docs/verify/index.mdx b/docs/verify/index.mdx
index 49decf10e9a..587e845683f 100644
--- a/docs/verify/index.mdx
+++ b/docs/verify/index.mdx
@@ -6,7 +6,7 @@ description: Introduction to the Verify phase
In the verify phase, you test your quantum programs by running them on simulated devices and exploring their performance under realistic device [noise models](https://qiskit.org/ecosystem/aer/apidocs/aer_noise.html). This allows you to validate them before sending them to a physical system. This phase consists of the following steps:
-1. Run your program on a [quantum simulator](simulators).
+1. Run your program on a quantum simulator, using [Qiskit reference primitives](simulate-with-primitives) or [IBM Quantum cloud-based simulators](simulators).
1. [Add noise to your simulation](noise).
2. Optionally [create your own noise model](building_noise_models).
diff --git a/docs/verify/simulate-with-qiskit-primitives.mdx b/docs/verify/simulate-with-qiskit-primitives.mdx
new file mode 100644
index 00000000000..f96f6e591b9
--- /dev/null
+++ b/docs/verify/simulate-with-qiskit-primitives.mdx
@@ -0,0 +1,455 @@
+---
+title: Simulate with Qiskit primitives
+description: Simulate with Qiskit reference primitives. How to compute an expectation value with the Estimator primitive, and how to compute circuit output probabilities with the Sampler primitive
+---
+
+# Simulate with Qiskit primitives
+
+The reference primitives in Qiskit can perform local statevector simulations, which is useful for quickly prototyping algorithms.
+
+The `Estimator` primitive can compute an expectation value, and the `Sampler` primitive can compute circuit output probabilities.
+
+For import instructions, see the topic [Where should I import the primitive from?](../run/primitives#import-primitives)
+
+## Compute an expectation value with the `Estimator` primitive
+
+Follow these instructions to get the expected value of an observable for a given quantum circuit with the [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) primitive.
+
+
+ While this guide uses Qiskit’s reference implementation, the `Estimator` primitive can be run with any provider using [`qiskit.primitives.BackendEstimator`](../api/qiskit/qiskit.primitives.BackendEstimator).
+
+ ```python
+ from qiskit.primitives import BackendEstimator
+ from import QiskitProvider
+
+ provider = QiskitProvider()
+ backend = provider.get_backend('backend_name')
+ estimator = BackendEstimator(backend)
+ ```
+
+ There are some providers that implement primitives natively (see [this page](https://qiskit.org/providers/#primitives) for more details).
+
+
+### Initialize observables
+
+The first step is to define the observables whose expected value you want to compute. Each observable can be any `BaseOperator`, like the operators from [`qiskit.quantum_info`](../api/qiskit/quantum_info).
+Among them it is preferable to use [`qiskit.quantum_info.SparsePauliOp`](../api/qiskit/qiskit.quantum_info.SparsePauliOp).
+
+```python
+from qiskit.quantum_info import SparsePauliOp
+
+observable = SparsePauliOp(["II", "XX", "YY", "ZZ"], coeffs=[1, 1, -1, 1])
+```
+
+### Initialize QuantumCircuit
+
+Next, create the [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit)s for which you want to obtain the expected value.
+
+```python
+from qiskit import QuantumCircuit
+
+qc = QuantumCircuit(2)
+qc.h(0)
+qc.cx(0,1)
+qc.draw("mpl")
+```
+
+
+
+
+ The [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit) you pass to [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) must not include any measurements.
+
+
+### Initialize `Estimator`
+
+Next, instantiate an [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator).
+
+```python
+from qiskit.primitives import Estimator
+
+estimator = Estimator()
+```
+
+### Run and get results
+
+Now that you have defined your `estimator`, you can run your estimation by calling the [`qiskit.primitives.Estimator.run`](../api/qiskit/qiskit.primitives.Estimator#run) method,
+which returns an instance of [`qiskit.providers.JobV1`](../api/qiskit/qiskit.providers.JobV1). You can get the results from the job (as a [`qiskit.primitives.EstimatorResult`](../api/qiskit/qiskit.primitives.EstimatorResult) object)
+with the [`qiskit.providers.JobV1.result`](../api/qiskit/qiskit.providers.JobV1#result) method.
+
+```python
+job = estimator.run(qc, observable)
+result = job.result()
+print(result)
+```
+
+```python
+EstimatorResult(values=array([4.]), metadata=[{}])
+```
+
+This example only uses one [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit) and one observable. If you want to get expectation values for multiple circuits and observables, you can pass a `list` of [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit)s and a list of `BaseOperator`s to the [`qiskit.primitives.Estimator.run`](../api/qiskit/qiskit.primitives.Estimator#run) method. Both `list`s must have the same length.
+
+#### Get the expected value
+
+From these results you can extract the expected values with the attribute [`qiskit.primitives.EstimatorResult.values`](../api/qiskit/qiskit.primitives.EstimatorResult#values).
+
+[`qiskit.primitives.EstimatorResult.values`](../api/qiskit/qiskit.primitives.EstimatorResult#values) returns a `numpy.ndarray`
+whose `i`th element is the expectation value corresponding to the `i`th circuit and `i`th observable.
+
+```python
+exp_value = result.values[0]
+print(exp_value)
+```
+
+```python
+3.999999999999999
+```
+
+### Parameterized circuit with `Estimator`
+
+The [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) primitive can be run with unbound parameterized circuits like the one below.
+You can also manually bind values to the parameters of the circuit and follow the steps of the previous example.
+
+```python
+from qiskit.circuit import Parameter
+
+theta = Parameter('θ')
+param_qc = QuantumCircuit(2)
+param_qc.ry(theta, 0)
+param_qc.cx(0,1)
+print(param_qc.draw())
+```
+
+```
+ ┌───────┐
+q_0: ┤ Ry(θ) ├──■──
+ └───────┘┌─┴─┐
+q_1: ─────────┤ X ├
+ └───┘
+```
+
+The main difference with the previous case is that now you need to specify the sets of parameter values for which you want to evaluate the expectation value as a `list` of `list`s of `float`s.
+The `i`th element of the outer `list` is the set of parameter values that corresponds to the `i`th circuit and observable.
+
+```python
+import numpy as np
+
+parameter_values = [[0], [np.pi/6], [np.pi/2]]
+
+job = estimator.run([param_qc]*3, [observable]*3, parameter_values=parameter_values)
+values = job.result().values
+
+for i in range(3):
+ print(f"Parameter: {parameter_values[i][0]:.5f}\t Expectation value: {values[i]}")
+```
+
+```
+Parameter: 0.00000 Expectation value: 2.0
+Parameter: 0.52360 Expectation value: 3.0
+Parameter: 1.57080 Expectation value: 4.0
+```
+
+### Change run options
+
+Your workflow might require tuning primitive run options, such as the number of shots.
+
+By default, the reference [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) class performs an exact statevector calculation based on the [`qiskit.quantum_info.Statevector`](../api/qiskit/qiskit.quantum_info.Statevector) class. However, this can be modified to include shot noise if the number of `shots` is set. For reproducibility purposes, a `seed` will also be set in the following examples.
+
+There are two main ways of setting options in the [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator):
+
+- Set keyword arguments in the [`qiskit.primitives.Estimator.run`](../api/qiskit/qiskit.primitives.Estimator#run) method.
+- Modify [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) options.
+
+#### Set keyword arguments for [`qiskit.primitives.Estimator.run`](../api/qiskit/qiskit.primitives.Estimator#run)
+
+If you only want to change the settings for a specific run, it can be more convenient to set the options inside the [`qiskit.primitives.Estimator.run`](../api/qiskit/qiskit.primitives.Estimator#run) method. You can do this by passing them as keyword arguments.
+
+```python
+job = estimator.run(qc, observable, shots=2048, seed=123)
+result = job.result()
+print(result)
+```
+
+```python
+EstimatorResult(values=array([4.]), metadata=[{'variance': 3.552713678800501e-15, 'shots': 2048}])
+```
+
+```python
+print(result.values[0])
+```
+
+```python
+3.999999998697238
+```
+
+#### Modify [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) options
+
+If you want to keep some configuration values for several runs, it can be better to change the [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) options. That way you can use the same [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) object as many times as you wish without having to
+rewrite the configuration values every time you use [`qiskit.primitives.Estimator.run`](../api/qiskit/qiskit.primitives.Estimator#run).
+
+#### Modify existing [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator)
+
+If you prefer to change the options of an already-defined [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator), you can use the method [`qiskit.primitives.Estimator.set_options`](../api/qiskit/qiskit.primitives.Estimator#set_options) and introduce the new options as keyword arguments.
+
+```python
+estimator.set_options(shots=2048, seed=123)
+
+job = estimator.run(qc, observable)
+result = job.result()
+print(result)
+```
+
+```python
+EstimatorResult(values=array([4.]), metadata=[{'variance': 3.552713678800501e-15, 'shots': 2048}])
+```
+
+```python
+print(result.values[0])
+```
+
+```python
+3.999999998697238
+```
+
+#### Define a new [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) with the options
+
+If you prefer to define a new [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) with new options, define a `dict` like this one:
+
+```python
+options = {"shots": 2048, "seed": 123}
+```
+
+You can then introduce it into your new [`qiskit.primitives.Estimator`](../api/qiskit/qiskit.primitives.Estimator) with the `options` argument.
+
+```python
+estimator = Estimator(options=options)
+
+job = estimator.run(qc, observable)
+result = job.result()
+print(result)
+```
+
+```python
+EstimatorResult(values=array([4.]), metadata=[{'variance': 3.552713678800501e-15, 'shots': 2048}])
+```
+
+```python
+print(result.values[0])
+```
+
+```python
+3.999999998697238
+```
+## Compute circuit output probabilities with `Sampler` primitive
+
+Follow these instructions to get the probability distribution of a quantum circuit with the [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) primitive.
+
+
+ While this guide uses Qiskit’s reference implementation, the `Sampler` primitive can be run with any provider using [`qiskit.primitives.BackendSampler`](../api/qiskit/qiskit.primitives.BackendSampler).
+
+ ```python
+ from qiskit.primitives import BackendSampler
+ from import QiskitProvider
+
+ provider = QiskitProvider()
+ backend = provider.get_backend('backend_name')
+ sampler = BackendSampler(backend)
+ ```
+
+ There are some providers that implement primitives natively (see [this page](http://qiskit.org/providers/#primitives) for more details).
+
+
+### Initialize QuantumCircuit
+
+The first step is to create the [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit)s from which you want to obtain the probability distribution.
+
+```python
+from qiskit import QuantumCircuit
+
+qc = QuantumCircuit(2)
+qc.h(0)
+qc.cx(0,1)
+qc.measure_all()
+qc.draw("mpl")
+```
+
+
+
+
+The [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit) you pass to [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) must include measurements.
+
+
+### Initialize `Sampler`
+
+Next, create a [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) instance.
+
+```python
+from qiskit.primitives import Sampler
+
+sampler = Sampler()
+```
+
+### Run and get results
+
+Now that you have defined your `sampler`, run it by calling the [`qiskit.primitives.Sampler.run`](../api/qiskit/qiskit.primitives.Sampler#run) method, which returns an instance of [`qiskit.providers.JobV1`](../api/qiskit/qiskit.providers.JobV1). You can get the results from the job (as a [`qiskit.primitives.SamplerResult`](../api/qiskit/qiskit.primitives.SamplerResult) object) with the [`qiskit.providers.JobV1.result`](../api/qiskit/qiskit.providers.JobV1#result) method.
+
+```python
+job = sampler.run(qc)
+result = job.result()
+print(result)
+```
+
+```python
+SamplerResult(quasi_dists=[{0: 0.4999999999999999, 3: 0.4999999999999999}], metadata=[{}])
+```
+
+While this example only uses one [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit), you can sample multiple circuits by passing a `list` of [`qiskit.circuit.QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit) instances to the [`qiskit.primitives.Sampler.run`](../api/qiskit/qiskit.primitives.Sampler#run) method.
+
+### Get the probability distribution
+
+From these results you can extract the quasi-probability distributions with the attribute [`qiskit.primitives.Sampler.quasi_dists`](../api/qiskit/qiskit.primitives.Sampler#quasi_dists).
+
+Even though there is only one circuit in this example, [`qiskit.primitives.Sampler.quasi_dists`](../api/qiskit/qiskit.primitives.Sampler#quasi_dists) returns a list of [`qiskit.result.QuasiDistribution`](../api/qiskit/qiskit.result.QuasiDistribution)s.
+`result.quasi_dists[i]` is the quasi-probability distribution of the `i`th circuit.
+
+
+A quasi-probability distribution differs from a probability distribution in that negative values are also allowed.
+However, the quasi-probabilities must sum up to 1 like probabilities.
+Negative quasi-probabilities may appear when using error mitigation techniques.
+
+
+```python
+quasi_dist = result.quasi_dists[0]
+print(quasi_dist)
+```
+
+```python
+{0: 0.4999999999999999, 3: 0.4999999999999999}
+```
+
+#### Probability distribution with binary outputs
+
+If you prefer to see the output keys as binary strings instead of decimal numbers, you can use the [`qiskit.result.QuasiDistribution.binary_probabilities`](../api/qiskit/qiskit.result.QuasiDistribution#binary_probabilities) method.
+
+```python
+print(quasi_dist.binary_probabilities())
+```
+
+```python
+{'00': 0.4999999999999999, '11': 0.4999999999999999}
+```
+
+### Parameterized circuit with `Sampler`
+
+The [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) primitive can be run with unbound parameterized circuits like the one below.
+You can also manually bind values to the parameters of the circuit and follow the steps of the previous example.
+
+```python
+from qiskit.circuit import Parameter
+
+theta = Parameter('θ')
+param_qc = QuantumCircuit(2)
+param_qc.ry(theta, 0)
+param_qc.cx(0,1)
+param_qc.measure_all()
+print(param_qc.draw())
+```
+
+```
+ ┌───────┐ ░ ┌─┐
+ q_0: ┤ Ry(θ) ├──■───░─┤M├───
+ └───────┘┌─┴─┐ ░ └╥┘┌─┐
+ q_1: ─────────┤ X ├─░──╫─┤M├
+ └───┘ ░ ║ └╥┘
+ meas: 2/══════════════════╩══╩═
+ 0 1
+```
+
+The main difference from the previous case is that now you need to specify the sets of parameter values for which you want to evaluate the expectation value as a `list` of `list`s of `float`s. The `i`th element of the outer `list` is the set of parameter values that corresponds to the `i`th circuit.
+
+```python
+import numpy as np
+
+parameter_values = [[0], [np.pi/6], [np.pi/2]]
+
+job = sampler.run([param_qc]*3, parameter_values=parameter_values)
+dists = job.result().quasi_dists
+
+for i in range(3):
+ print(f"Parameter: {parameter_values[i][0]:.5f}\t Probabilities: {dists[i]}")
+```
+
+```
+Parameter: 0.00000 Probabilities: {0: 1.0}
+Parameter: 0.52360 Probabilities: {0: 0.9330127018922194, 3: 0.0669872981077807}
+Parameter: 1.57080 Probabilities: {0: 0.5000000000000001, 3: 0.4999999999999999}
+```
+
+### Change run options
+
+Your workflow might require tuning primitive run options, such as the number of shots.
+
+By default, the reference [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) class performs an exact statevector
+calculation based on the [`qiskit.quantum_info.Statevector`](../api/qiskit/qiskit.quantum_info.Statevector) class. However, this can be
+modified to include shot noise if the number of `shots` is set.
+For reproducibility purposes, a `seed` will also be set in the following examples.
+
+There are two main ways of setting options in the [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler):
+
+- Set keyword arguments in the [`qiskit.primitives.Sampler.run`](../api/qiskit/qiskit.primitives.Sampler#run) method.
+- Modify [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) options.
+
+#### Set keyword arguments for [`qiskit.primitives.Sampler.run`](../api/qiskit/qiskit.primitives.Sampler#run)
+
+If you only want to change the settings for a specific run, it can be more convenient to set the options inside the [`qiskit.primitives.Sampler.run`](../api/qiskit/qiskit.primitives.Sampler#run) method. You can do this by passing them as keyword arguments.
+
+```python
+job = sampler.run(qc, shots=2048, seed=123)
+result = job.result()
+print(result)
+```
+
+```python
+SamplerResult(quasi_dists=[{0: 0.5205078125, 3: 0.4794921875}], metadata=[{'shots': 2048}])
+```
+
+#### Modify [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) options
+
+If you want to keep some configuration values for several runs, it can be better to change the [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) options. That way you can use the same [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) object as many times as you wish without having to rewrite the configuration values every time you use [`qiskit.primitives.Sampler.run`](../api/qiskit/qiskit.primitives.Sampler#run).
+
+#### Modify existing [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler)
+
+If you prefer to change the options of an already-defined [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler), you can use [`qiskit.primitives.Sampler.set_options`](../api/qiskit/qiskit.primitives.Sampler#set_options) and introduce the new options as keyword arguments.
+
+```python
+sampler.set_options(shots=2048, seed=123)
+
+job = sampler.run(qc)
+result = job.result()
+print(result)
+```
+
+```python
+SamplerResult(quasi_dists=[{0: 0.5205078125, 3: 0.4794921875}], metadata=[{'shots': 2048}])
+```
+
+#### Define a new [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) with the options
+
+If you prefer to define a new [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) with new options, define a `dict` like this one:
+
+```python
+options = {"shots": 2048, "seed": 123}
+```
+
+You can then introduce it into your new [`qiskit.primitives.Sampler`](../api/qiskit/qiskit.primitives.Sampler) with the `options` argument.
+
+```python
+sampler = Sampler(options=options)
+
+job = sampler.run(qc)
+result = job.result()
+print(result)
+```
+
+```python
+SamplerResult(quasi_dists=[{0: 0.5205078125, 3: 0.4794921875}], metadata=[{'shots': 2048}])
+```
diff --git a/public/images/verify/use_estimator/initialize.png b/public/images/verify/simulate-with-qiskit-primitives/estimator-initialize.png
similarity index 100%
rename from public/images/verify/use_estimator/initialize.png
rename to public/images/verify/simulate-with-qiskit-primitives/estimator-initialize.png
diff --git a/public/images/verify/use_sampler/initialize.png b/public/images/verify/simulate-with-qiskit-primitives/sampler-initialize.png
similarity index 100%
rename from public/images/verify/use_sampler/initialize.png
rename to public/images/verify/simulate-with-qiskit-primitives/sampler-initialize.png