Skip to content

Commit

Permalink
Docs preview for PR #2053.
Browse files Browse the repository at this point in the history
  • Loading branch information
cuda-quantum-bot committed Aug 9, 2024
1 parent 3173e7c commit 33686ef
Show file tree
Hide file tree
Showing 16 changed files with 329 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
"source": [
"\n",
"\n",
"Given a data set $X = (x_1, x_2, \\cdots, x_N) $, a coreset is weighted data set of much smaller size ($X', w$) that represents $X$ enough such that analysis of ($X', w$) can allow us to draw reasonable approximate conclusions about $X$. There are various approaches to build coresets. They can be found in Practical Coreset Construction for Machine Learning (https://arxiv.org/pdf/1703.06476.pdf) and New Streaming Algorithms for Coresets in Machine Learning (https://arxiv.org/pdf/1703.06476.pdf).\n",
"Given a data set $X = (x_1, x_2, \\cdots, x_N)$, a coreset is weighted data set of much smaller size ($X', w$) that represents $X$ enough such that analysis of ($X', w$) can allow us to draw reasonable approximate conclusions about $X$. There are various approaches to build coresets. They can be found in Practical Coreset Construction for Machine Learning (https://arxiv.org/pdf/1703.06476.pdf) and New Streaming Algorithms for Coresets in Machine Learning (https://arxiv.org/pdf/1703.06476.pdf).\n",
"\n",
"\n",
"Essentially, coreset construction boils down to finding the optimal coreset size and weights given some error tolerance. Given the constraints of a quantum computer, in this work, a coreset size is selected $a$ $priori$, and the error is determined for each model.\n",
Expand Down Expand Up @@ -221,7 +221,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"The divisive clustering problem will be implemented on a quantum computer using a variational quantum algorithm (VQA) approach. A VQA takes a Hamiltonian (encoded with the optimization problem) and a parameterized ansatz and evaluates expectation values (quantum computer) that inform updates to the ansatz parameters (classical computer). The graph $G$ (Code in the \"src\" file)is used to construct the Hamiltonian, derived specifically for the divisive clustering problem, and motivated by a max-cut Hamiltonian. The `spin.z(i)` method in CUDA-Q adds a Pauli Z operation that acts on qubit $i$ to the Hamiltonian."
"The divisive clustering problem will be implemented on a quantum computer using a variational quantum algorithm (VQA) approach. A VQA takes a Hamiltonian (encoded with the optimization problem) and a parameterized ansatz and evaluates expectation values (quantum computer) that inform updates to the ansatz parameters (classical computer). The graph $G$ (Code in the \"src\" file) is used to construct the Hamiltonian, derived specifically for the divisive clustering problem, and motivated by a max-cut Hamiltonian. The `spin.z(i)` method in CUDA-Q adds a Pauli Z operation that acts on qubit $i$ to the Hamiltonian."
]
},
{
Expand Down Expand Up @@ -360,7 +360,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"The next step is to select a classical optimizer. There are multiple [optimizers](https://nvidia.github.io/cuda-quantum/latest/api/languages/python_api.html#optimizers) built-in to CUDA-Q that can be selected. The cde below returns the optimizer with the proper number of initial parameters. "
"The next step is to select a classical optimizer. There are multiple [optimizers](https://nvidia.github.io/cuda-quantum/latest/api/languages/python_api.html#optimizers) built-in to CUDA-Q that can be selected. The code below returns the optimizer with the proper number of initial parameters. "
]
},
{
Expand Down Expand Up @@ -401,14 +401,14 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"The `DivisiveClusteringVQA` class enables the procedure to iteratively bipartions the coreset points until each is its own cluster. If you wish to develop on top of this or see how the underlying code works, please see the `divisive_clustering.py` file in the src directory. \n",
"The `DivisiveClusteringVQA` class enables the procedure to iteratively bipartition the coreset points until each is its own cluster. If you wish to develop on top of this or see how the underlying code works, please see the `divisive_clustering.py` file in the src directory. \n",
"\n",
"`run_divisive_clustering`, takes the current iteration's coreset points that will be bipartitioned as inputs, extracts the appropriate weights and builds a graph $G$. The graph is then an input into the `get_counts_from_simulation` function. \n",
"`run_divisive_clustering`, takes the current iteration's coreset points that will be bipartitioned as inputs, extracts the appropriate weights, and builds a graph $G$. The graph is then an input into the `get_counts_from_simulation` function. \n",
"\n",
"\n",
"`get_counts_from_simulation` handles preparation and execution of the quantum simulation. First, it takes $G$ and from it builds a spin Hamiltonian. Second, it defines a cost function, which in this case is a lambda function that returns the expectation value of our parameterized quantum circuit and the Hamiltonian. This value is obtained using the CUDA-Q `observe` command, accelerated by GPUs. After the expectation value is minimized, the quantum circuit corresponding to the optimal parameters is sampled using the CUDA-Q `sample` function. The bitstrings and their associated counts are returned by `get_counts_from_simulation`.\n",
"\n",
"A subset of these counts is evaluated to compute their exact cost. The best bitstring is returned and later used to assign the coreste points to one of two clusters.\n"
"A subset of these counts is evaluated to compute their exact cost. The best bitstring is returned and later used to assign the coreset points to one of two clusters.\n"
]
},
{
Expand Down Expand Up @@ -522,12 +522,12 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"An instance of the `DivisiveClusteringVQA` class is mostly constructed from variables previously discussed like the functions for building the Hamiltonians and quantum circuits. Parameters related tot he quantum simulation can also be specified here such as `circuit_depth` and `max_shots`. The ` threshold_for_max_cut` parameter specifies what percent of the sample results from the quantum computer are checked for the best bitstring value.\n",
"An instance of the `DivisiveClusteringVQA` class is mostly constructed from variables previously discussed like the functions for building the Hamiltonians and quantum circuits. Parameters related to the quantum simulation can also be specified here such as `circuit_depth` and `max_shots`. The ` threshold_for_max_cut` parameter specifies what percent of the sample results from the quantum computer are checked for the best bitstring value.\n",
"\n",
"The other options specify advanced features like if the data is normalized and how the graph weights are computed.\n",
"\n",
"\n",
"Finally, the `get_divisive_sequence` method performs the iterations and produces the clustering data which we will analyze below. Note that this postprocessing code is not exposed int his tutorial but can be found in the source code. \n"
"Finally, the `get_divisive_sequence` method performs the iterations and produces the clustering data which we will analyze below. Note that this postprocessing code is not exposed in this tutorial but can be found in the source code. \n"
]
},
{
Expand Down Expand Up @@ -571,7 +571,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"The data can be nicely visualized with a Dendrogram which maps where the bipartitionings occurred. Early splits are generally mark divisions between the least like data."
"The data can be nicely visualized with a Dendrogram which maps where the bipartitionings occurred. Early splits generally mark divisions between the least similar data."
]
},
{
Expand Down Expand Up @@ -599,7 +599,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Each branch point in the dendrogram aboves corresponds to the one of the plots below. Notice the first iterations are the most complicated and the final iterations become trivial bipartitioning of two points. Occasionally, especially in the first iteration, the partitioning might be puzzling at first glance. The data might be seem to naturally cluster into two groups just by looking at it. However, there are cases where a stray point seems to belong in the wrong cluster. There are two explanations for this. 1) The quantum sampling is approximate and stochastic. It is possible that too few shots were taken to samples the ground state of the problem. 2) It is important to remember that we are clustering coresets and not data points. There can be cases where it is optimal to pay a penalty by excluding a point based on proximity if the weights are small enough that the penalty has less impact. Usually, if a point looks unusually clustered and you go look at the original coresets plotted above, that point will have a small weight."
"Each branch point in the dendrogram aboves corresponds to one of the plots below. Notice the first iterations are the most complicated, and the final iterations become trivial bipartitioning of two points. Occasionally, especially in the first iteration, the partitioning might be puzzling at first glance. The data might seem to naturally cluster into two groups. However, there are cases where a stray point seems to belong in the wrong cluster. There are two explanations for this. 1) The quantum sampling is approximate and stochastic. It is possible that too few shots were taken to sample the ground state of the problem. 2) It is important to remember that we are clustering coresets and not data points. There can be cases where it is optimal to pay a penalty by excluding a point based on proximity if the weights are small enough that the penalty has less impact. Usually, if a point looks unusually clustered and you go look at the original coresets plotted above, that point will have a small weight."
]
},
{
Expand All @@ -626,7 +626,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"The hierarchical clustering can be converted to flat clustering by drawing a line perpendicular to the branches. Any data point that intersects the line is considered to be in the same cluster. The function below performs this task at threshold height of 1.5. If you want to use the number of clusters instead of height, you can use `dendo.get_clusters_using_k()` method. You pass the number of desired clusters as an argument. Figure below shows the clusters that are formed at threshold height of 1.5."
"The hierarchical clustering can be converted to flat clustering by drawing a line perpendicular to the branches. Any data point that intersects the line is considered to be in the same cluster. The function below performs this task at threshold height of 1.5. If you want to use the number of clusters instead of height, you can use `dendo.get_clusters_using_k()` method. You pass the number of desired clusters as an argument. The figure below shows the clusters that are formed at threshold height of 1.5."
]
},
{
Expand Down Expand Up @@ -690,11 +690,11 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"The function below uses the `dendo.get_voronoi_tessalation()` method to convert the clusters into regions. `coreset_df`, `clusters` and `colors` need to be passed as the arguments to create the regions. This function creates a region for each coreset point separately and then colors them according to the clusters and colors passed as arguments. Another option is to create region using the centroids of the clusters. You need to pass `tesslation_by_cluster=True` to the function perform this task.\n",
"The function below uses the `dendo.get_voronoi_tessalation()` method to convert the clusters into regions. `coreset_df`, `clusters` and `colors` need to be passed as the arguments to create the regions. This function creates a region for each coreset point separately and then colors them according to the clusters with colors passed as arguments. Another option is to create regions using the centroids of the clusters. You need to pass `tesslation_by_cluster=True` to the function to perform this task.\n",
"\n",
"Once the region creation is complete, you can use `plot_voironi()` method to plot the regions. The function takes the clusters and colors as arguments. \n",
"\n",
"Remembering that these regions were based on coresets, they can then overly the original data set be used to cluster the data based on the coreset analysis."
"Remembering that these regions were based on coresets, they can overlay the original data set and be used to cluster the data based on the coreset analysis."
]
},
{
Expand Down Expand Up @@ -724,7 +724,7 @@
"source": [
"## QAOA Implementation\n",
"\n",
"CUDA-Q is designed to be a flexible tools for developers so they can test different implementations of the same code. For example, one can perform the same analysis, instead using a QAOA approach. Only the kernel needs to be changed as is done below."
"CUDA-Q is designed to be a flexible tool for developers so they can test different implementations of the same code. For example, one can perform the same analysis, instead using a QAOA approach. Only the kernel needs to be changed as is done below."
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"source": [
"# Readout Error Mitigation\n",
"\n",
"Readout errors are caused by imperfect qubit measurement and are a common source of error in quantum computing. Properly modelling these errors in simulation can give the user tools to understand better how these errors are and how to mitigate them when running on actual quantum devices.\n",
"Readout errors are caused by imperfect qubit measurement and are a common source of error in quantum computing. Properly modelling these errors in simulation can give the user tools to understand better what these errors are and how to mitigate them when running on actual quantum devices.\n",
"\n",
"Readout errors can be mitigated with a confusion matrix $A$. It is a square matrix of size $2^n \\times 2^n$ and tells about the probability of observing the state $|y\\rangle$ given the true state $|x\\rangle$. The confusion matrix characterizes the readout error of the device and is circuit-independent. Once $A$ is estimated, we can compute its pseudoinverse $A^+$ which can be applied to the noisy probability distribution $p_{\\text{noisy}}$ to obtain an adjusted quasi-probability distribution \n",
"\n",
Expand All @@ -18,7 +18,7 @@
"In this tutorial, we show how to build a confusion matrix with the following approaches.\n",
"\n",
"- Using a single qubit model\n",
"- using $k$ local confusion matrices\n",
"- Using $k$ local confusion matrices\n",
"- A full confusion matrix for each $2^n$ combination\n",
"\n",
"The last method works well for correcting correlated errors (which affect multiple qubits together). However, it becomes impractical for large numbers of qubits."
Expand Down Expand Up @@ -73,7 +73,7 @@
"To model the readout error, we apply a bitflip channel on every qubit at the end of the circuit using an Identity gate. The probability of bitflip `probs` can be the same or different for all the qubits.\n",
"\n",
"<div class=\"alert alert-block alert-success\"><b>Note: </b>\n",
"In principle, readout error is applied to the measurement gate but we use Identity gate as adding a quantum error on the measurement gate is not yet supported. Also, the Identity gate is not present in the <kbd>add_channel</kbd> method, so we model the Identity gate using a rotation gate with an angle of 0.0.\n",
"In principle, readout error is applied to the measurement gate but we use the Identity gate because adding a quantum error on the measurement gate is not yet supported. Also, the Identity gate is not present in the <kbd>add_channel</kbd> method, so we model the Identity gate using a rotation gate with an angle of 0.0.\n",
"</div>"
]
},
Expand Down Expand Up @@ -114,7 +114,7 @@
"id": "bb4c7a14-1c0c-4fab-a6aa-7174c23baa7f",
"metadata": {},
"source": [
"We define a cudaq kernel which will help create a set of quantum circuits to take measurements of the basis states for $n$ qubits. It takes the number of qubits and the basis state as arguments."
"We define a cudaq kernel which will help create a set of quantum circuits to take measurements of the basis states for $n$ qubits. The kernel takes the number of qubits and the basis state as arguments."
]
},
{
Expand All @@ -141,7 +141,7 @@
"id": "95411463-cd1e-499f-baef-d624acc0122c",
"metadata": {},
"source": [
"For the tutorial, we will use GHZ state on three qubits for testing readout error mitigation. The GHZ state on 3 qubits is described as:\n",
"For the tutorial, we will use the GHZ state on three qubits to test readout error mitigation. The GHZ state on 3 qubits is described as:\n",
"\n",
"$$\n",
"\\frac{|000\\rangle + |111\\rangle}{\\sqrt{2}}\n",
Expand All @@ -163,7 +163,7 @@
" for i in range(n_qubits - 1):\n",
" cx(qvector[i], qvector[i + 1])\n",
"\n",
" # Apply id gates for readout error mitigation\n",
" # Apply identity gates for readout error mitigation\n",
" for i in range(n_qubits):\n",
" rx(0.0, qvector[i])\n",
"\n",
Expand Down Expand Up @@ -199,7 +199,7 @@
"id": "032f6898-c953-4d30-a2bf-e8b46ee77c62",
"metadata": {},
"source": [
"It is possible that the adjusted quasi-probability distribution $p_{\\text{mitigated}}$ obtained by application of $A^+$ to $p_{\\text{noisy}}$ can be possibly non-positive. We need to find the closest positive probability distribution in such a case.\n",
"It is possible that the adjusted quasi-probability distribution $p_{\\text{mitigated}}$ obtained by application of $A^+$ to $p_{\\text{noisy}}$ may be non-positive. We need to find the closest positive probability distribution in such a case.\n",
"\n",
" $$ p'' = \\min_{p_{\\rm positive}} \\|p_{\\rm noisy} - p_{\\rm positive}\\|_1$$\n",
"\n",
Expand Down Expand Up @@ -393,7 +393,7 @@
"source": [
"## Inverse confusion matrix from single-qubit noise model\n",
"\n",
"Here we assume that the readout error of each qubit is independent and with the same confusion probabilities. Then, the confusion matrix $A_1$ for a single qubit can be defined as\n",
"Here we assume that the readout error of each qubit is independent with the same confusion probabilities. Then, the confusion matrix $A_1$ for a single qubit can be defined as\n",
"\n",
"$$\n",
"A_1 = \\begin{bmatrix}\n",
Expand All @@ -402,7 +402,7 @@
"\\end{bmatrix}\n",
"$$\n",
"\n",
"where $P(y|x)$ is the probability of observing state $|y\\rangle$ when measuring true state $|x\\rangle$. Using $A_1$ the full $2^n \\times 2^n$ confusion matrix $A$ can be written as \n",
"where $P(y|x)$ is the probability of observing state $|y\\rangle$ when measuring the true state $|x\\rangle$. Using $A_1$, the full $2^n \\times 2^n$ confusion matrix $A$ can be written as \n",
"\n",
"$$\n",
"A = A_1 \\otimes \\dots \\otimes A_1\n",
Expand Down Expand Up @@ -719,7 +719,7 @@
"source": [
"## Inverse of full confusion matrix\n",
"\n",
"Here we generate a quantum circuit for each of the basis states of $n$ qubits i.e. $2^n$ combinations. This gives more accurate readout error mitigation. Since it scales exponentially with the number of qubits, it is only practical for small devices."
"Here we generate a quantum circuit for each of the basis states of $n$ qubits (i.e., $2^n$ combinations). This gives more accurate readout error mitigation. Since it scales exponentially with the number of qubits, it is only practical for small devices."
]
},
{
Expand Down
Loading

0 comments on commit 33686ef

Please sign in to comment.