diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..73533bc7e --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + // Suggest that users have the MS Docs Authoring Pack, which provides + // a number of tools for working with DocFX-based documentation repos. + "docsmsft.docs-authoring-pack" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..cd15b0b93 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "markdownlint.config": { + "default": true, + // Use #-style section headings without the ending # marks, as that can + // cause problems working with the Samples Browser. + "MD003": {"style": "atx"}, + "MD013": false + } +} \ No newline at end of file diff --git a/api/docfx.json b/api/docfx.json index e40da05fc..bc42fee5d 100644 --- a/api/docfx.json +++ b/api/docfx.json @@ -39,15 +39,7 @@ "overwrite": [], "externalReference": [], "globalMetadata": { - "latex_macros": { - "ket": ["\\left| #1\\right\\rangle", 1], - "bra": ["\\left\\langle #1\\right|", 1], - "braket": ["\\left\\langle #1 \\right\\rangle", 1], - "boldone": "\\mathbf{1}", - "expect": "\\mathbb{E}", - "variance": "\\operatorname{Var}", - "defeq": "\\mathrel{:=}" - }, + "show_latex": true, "ms.prod": "quantum", "ms.topic": "managed-reference", "ms.devlang":"qsharp", @@ -57,7 +49,21 @@ "feedback_product_url": "https://github.com/microsoft/quantum/issues", "titleSuffix": "Q# reference - Microsoft Quantum" }, - "fileMetadata": {}, + "fileMetadata": { + "latex_macros": { + "**/**.yml": { + "ket": ["\\left| #1\\right\\rangle", 1], + "bra": ["\\left\\langle #1\\right|", 1], + "braket": [ "\\left\\langle #1 \\right\\rangle", 1 ], + "id": "\\mathbb{1}", + "boldone": "\\mathbf{1}", + "expect": "\\mathbb{E}", + "variance": "\\operatorname{Var}", + "defeq": "\\mathrel{:=}", + "dd": "\\mathrm{d}" + } + } + }, "template": [], "dest": "quantum-api" } diff --git a/articles/Glossary.md b/articles/Glossary.md index e9efc15a7..0846c66ab 100644 --- a/articles/Glossary.md +++ b/articles/Glossary.md @@ -36,7 +36,6 @@ uid: microsoft.quantum.glossary |Quantum State|A representation of the qubits in the system. This is usually denoted as a complex column vector. For more information, see . | |Qubit|Unit of quantum storage. See the section for more details.| |Repeat-until-success|A quantum algorithm that probabilistically succeeds. Upon failure, the routine will re-try until successful (or a limit has been reached). | -|Software Stack|The complete set of classical and quantum software as well as the compilers, simulators and runtimes necessary to operate a quantum computer. See the section for more details. | |Target machine|A compilation target that lowers an abstract quantum program towards hardware or simulation. This typically include re-writes for many purposes including gate replacement, encoding for error correction, geometric layout and others.| |Tuple|Comma separated types grouped together via parenthesis. | |User-defined type|Collection of built-in or previously defined types that may be referred to as a single unit.| diff --git a/articles/TOC.yml b/articles/TOC.yml index b03bcce33..be715ddf9 100644 --- a/articles/TOC.yml +++ b/articles/TOC.yml @@ -29,7 +29,15 @@ - name: How-to guides items: - name: Install the QDK - href: install-guide/index.md + items: + - name: Installation overview + href: install-guide/index.md + - name: Q# + C# + href: install-guide/csinstall.md + - name: Q# + Python + href: install-guide/pyinstall.md + - name: Q# Jupyter notebooks + href: install-guide/qjupyter.md - name: Update the QDK href: install-guide/update.md - name: Create a Q# project diff --git a/articles/concepts/circuits.md b/articles/concepts/circuits.md index 20fc46ac1..9f8f804be 100644 --- a/articles/concepts/circuits.md +++ b/articles/concepts/circuits.md @@ -34,7 +34,7 @@ For example, the symbol ![](~/media/concepts_2.png) -is the [Hadamard](xref:microsoft.quantum.primitive.h) gate acting on a single-qubit register. +is the [Hadamard](xref:microsoft.quantum.intrinsic.h) gate acting on a single-qubit register. Quantum gates are ordered in chronological order with the left-most gate as the gate first applied to the qubits. In other words, if you picture the wires as holding the quantum state, the wires bring the quantum state through each of the gates in the diagram from left to right. @@ -77,7 +77,7 @@ In general, we describe such controlled operations in circuit diagrams as ![](~/media/concepts_5.png) Here the black circle denotes the quantum bit on which the gate is controlled and a vertical wire denotes the unitary that is applied when the control qubit takes the value $1$. -For the special cases where $G=X$ and $G=Z$ we introduce the following notation to describe the controlled version of the gates (note that the controlled-X gate is the [$CNOT$ gate](xref:microsoft.quantum.primitive.cnot)): +For the special cases where $G=X$ and $G=Z$ we introduce the following notation to describe the controlled version of the gates (note that the controlled-X gate is the [$CNOT$ gate](xref:microsoft.quantum.intrinsic.cnot)): @@ -102,7 +102,7 @@ Specifically, such a subcircuit looks like: ![Measurement circuit](~/media/concepts_7.png) -Q# implements a [Measure operator](xref:microsoft.quantum.primitive.measure) for this purpose. +Q# implements a [Measure operator](xref:microsoft.quantum.intrinsic.measure) for this purpose. See the [section on measurements](xref:microsoft.quantum.libraries.standard.prelude#measurements) for more information. Similarly, the subcircuit diff --git a/articles/concepts/pauli-measurements.md b/articles/concepts/pauli-measurements.md index 83809915a..4d088a2d0 100644 --- a/articles/concepts/pauli-measurements.md +++ b/articles/concepts/pauli-measurements.md @@ -1,120 +1,230 @@ --- -title: Pauli Measurements | Microsoft Docs +title: Pauli Measurements description: Pauli Measurements author: QuantumWriter uid: microsoft.quantum.concepts.pauli -ms.author: nawiebe@microsoft.com +ms.author: nawiebe@microsoft.com ms.date: 12/11/2017 ms.topic: article --- # Pauli Measurements -In the previous discussions, we have focused on computational basis measurements. In fact there are other common measurements that occur in quantum computing that, from a notational perspective, are convenient to express in terms of computational basis measurements. The most common set of these measurements are *Pauli measurements*. In such cases, it is common to discuss measuring a Pauli operator, in general an operator such as $X,Y,Z$ or $Z\otimes Z, X\otimes X, X\otimes Y$ and so forth. Discussing measurement in terms of Pauli operators is especially common in the subfield of quantum error correction. In Q# we follow a similar convention; we now explain this alternative view of measurements. +In the previous discussions, we have focused on computational basis measurements. +In fact, there are other common measurements that occur in quantum computing that, from a notational perspective, are convenient to express in terms of computational basis measurements. +As you work with Q#, the most common kind of measurements that you'll run into will likely be *Pauli measurements*, which generalize computational basis measurements to include measurements in other bases, and of parity between different qubits. +In such cases, it is common to discuss measuring a Pauli operator, in general an operator such as $X,Y,Z$ or $Z\otimes Z, X\otimes X, X\otimes Y$, and so forth. -Before delving into the details of how to think of a Pauli measurement, it is useful to think about what measuring a single qubit inside a quantum computer does to the quantum state. Imagine that we have an $n$-qubit quantum state; then measuring one qubit immediately rules out half of the $2^n$ possibilities that state could be in. In other words, the measurement projects the quantum state onto one of two half-spaces. We can generalize the way we think about measurement to reflect this. +> [!TIP] +> In Q#, multi-qubit Pauli operators are generally represented by arrays of type `Pauli[]`. +> For example, to represent $X \otimes Z \otimes Y$, you can use the array `[PauliX, PauliZ, PauliY]`. -In order to concisely identify these subspaces, we need a language for describing them. One way to do this is to describe the two subspaces by specifying them through a matrix that just has two unique eigenvalues, taken by convention to be $\pm 1$. The simplest example of this is: +Discussing measurement in terms of Pauli operators is especially common in the subfield of quantum error correction. +In Q#, we follow a similar convention; we now explain this alternative view of measurements. + +Before delving into the details of how to think of a Pauli measurement, it is useful to think about what measuring a single qubit inside a quantum computer does to the quantum state. +Imagine that we have an $n$-qubit quantum state; then measuring one qubit immediately rules out half of the $2^n$ possibilities that state could be in. +In other words, the measurement projects the quantum state onto one of two half-spaces. +We can generalize the way we think about measurement to reflect this intuition. + +In order to concisely identify these subspaces, we need a language for describing them. +One way to describe the two subspaces is by specifying them through a matrix that just has two unique eigenvalues, taken by convention to be $\pm 1$. +For a simple example of describing subspaces in this way, consider $Z$: $$ - Z = \begin{bmatrix} 1 & 0 \\\\ 0 & -1 \end{bmatrix}. +\begin{align} + Z & = \begin{bmatrix} 1 & 0 \\\\ 0 & -1 \end{bmatrix}. +\end{align} $$ -The Pauli-$Z$ matrix clearly has two eigenvectors $\ket{0}$ and $\ket{1}$ with eigenvalues $\pm 1$. Thus if we measure the qubit and obtain $\ket{0}$ we are in the $+1$ eigenspace (the set of all vectors that are formed of sums of eigenvectors with only positive or only negative eigenvalues) of the operator and if we measure $\ket{1}$ we are in the $-1$ eigenspace of $Z$. This process is referred to in the language of Pauli measurements as "measuring Pauli $Z$" and is entirely equivalent to performing a computational basis measurement. +By reading the diagonal elements of the Pauli-$Z$ matrix, we can see that $Z$ has two eigenvectors, $\ket{0}$ and $\ket{1}$, with corresponding eigenvalues $\pm 1$. +Thus, if we measure the qubit and obtain `Zero` (corresponding to the state $\ket{0}$), we know that the state of our qubit is a $+1$ eigenstate of the $Z$ operator. +Similarly, if we obtain `One`, we know that the state of our qubit is a $-1$ eigenstate of $Z$. +This process is referred to in the language of Pauli measurements as "measuring Pauli $Z$," and is entirely equivalent to performing a computational basis measurement. -Of course any $2\times 2$ matrix that is a unitary transformation of $Z$ also satisfies this criteria. This is to say that we could also consider matrix $A=U^\dagger Z U$, for any unitary matrix $U$, to give a matrix that defines the two outcomes of a measurement in its $\pm 1$ eigenvectors. The notation of Pauli measurements references this by identifying $X,Y,Z$ measurements as equivalent measurements that one could do to gain information from a qubit. These measurements are given below for convenience. +Any $2\times 2$ matrix that is a unitary transformation of $Z$ also satisfies this criteria. +That is, we could also use a matrix $A=U^\dagger Z U$, where $U$ is any other unitary matrix, to give a matrix that defines the two outcomes of a measurement in its $\pm 1$ eigenvectors. +The notation of Pauli measurements references this unitary equivalence by identifying $X,Y,Z$ measurements as equivalent measurements that one could do to gain information from a qubit. +These measurements are given below for convenience. -$$ -\begin{array}{|c|c|} -\text{Pauli Measurement} & U\\\\ -Z & \boldone\\\\ -X & H\\\\ -Y & HS^\dagger\\\\ -\end{array} -$$ -That is, using this language, "measure $Y$" is equivalent to applying $HS^\dagger$ and then measuring in the computational basis, where $S$ is the so-called phase gate given by +|Pauli Measurement |Unitary transformation | +|-------------------|------------------------| +| $Z$ | $\boldone$ | +| $X$ | $H$ | +| $Y$ | $HS^{\dagger}$ | + +That is, using this language, "measure $Y$" is equivalent to applying $HS^\dagger$ and then measuring in the computational basis, where [`S`](xref:microsoft.quantum.intrinsic.s) is an intrinsic quantum operation sometimes called the "phase gate," and can be simulated by the unitary matrix $$ -\begin{bmatrix}1 &0\\\\ 0&i\end{bmatrix}. +\begin{align} + S = \begin{bmatrix} + 1 & 0 \\\\ 0 & i + \end{bmatrix}. +\end{align} $$ -It is also equivalent to applying $HS^\dagger$ to the quantum state vector and then measuring $Z$. The correct state would then be found by transforming back to the computational basis, which amounts to applying $SH$ to the quantum state vector. +It is also equivalent to applying $HS^\dagger$ to the quantum state vector and then measuring $Z$, such that the following operation is equivalent to `Measure([PauliY], [q]])`: -## Q# outcome classical information obtained from quantum state -In Q# we say the outcome, i.e., the classical information extracted from interacting with the state, is $j$ which is in the set $\{0,1\}$ if the result is in the $(-1)^j$ eigenspace of the Pauli operator measured. +```Q# +operation MeasureY(qubit : Qubit) : Result { + mutable result = Zero; + within { + H(q); + Adjoint S(q); + } apply { + set result = M(q); + } + return result; +} +``` -Measurements of multi-qubit Pauli operators are defined similarly, as seen from: +The correct state would then be found by transforming back to the computational basis, which amounts to applying $SH$ to the quantum state vector; in the above snippet, the transformation back to the computational basis is handled automatically by the use of the `within … apply` block. -$$ -Z\otimes Z = \begin{bmatrix}1 &0 &0&0\\\\ 0&-1&0&0\\\\ 0&0&-1&0\\\\ 0&0&0&1\end{bmatrix}. -$$ +In Q#, we say the outcome---that is, the classical information extracted from interacting with the state---is given by a `Result` value $j \in \\{\texttt{Zero}, \texttt{One}\\}$ indicating if the result is in the $(-1)^j$ eigenspace of the Pauli operator measured. -Thus the tensor products of two Pauli-$Z$ operators forms a matrix composed of two spaces consisting of $+1$ and $-1$ eigenvalues. As with the single-qubit case, both constitute a half-space meaning that half of the accessible vector space belongs to the $+1$ eigenspace and the remaining half to the $-1$ eigenspace. In general, it is easy to see from the definition of the tensor product that any tensor product of Pauli-$Z$ operators and the identity also obeys this. For example, -$$ -Z\otimes\boldone=\begin{bmatrix} 1&0&0&0\\\\ 0&1&0&0\\\\ 0&0&-1&0\\\\ 0&0&0&-1\end{bmatrix}. -$$ +## Multiple-qubit measurements -As before, any unitary transformation of such matrices also describes two half-spaces labeled by $\pm 1$ eigenvalues. For example, $X\otimes X = H\otimes H(Z\otimes Z)H\otimes H$ from the identity that $Z=HXH$. Similar to the one-qubit case, all two-qubit Pauli-measurements can be written as $U^\dagger (Z\otimes \id) U$ for $4\times 4$ unitary matrices $U$. We enumerate the transformations in the following table where we introduce for convenience the swap gate which swaps qubits $0$ and $1$: $\operatorname{SWAP}=\operatorname{CNOT}\_{01}\operatorname{CNOT}\_{10}\operatorname{CNOT}\_{01}$: +Measurements of multi-qubit Pauli operators are defined similarly, as seen from: $$ -\begin{array}{|c|c|} -\text{Pauli Measurement} & U\\\\ -\hline -Z\otimes \boldone & \boldone\otimes \boldone\\\\ -X\otimes \boldone & H\otimes \boldone\\\\ -Y\otimes \boldone & HS^\dagger\otimes \boldone\\\\ -\boldone \otimes Z & \operatorname{SWAP}\\\\ -\boldone \otimes X & (H\otimes \boldone)\operatorname{SWAP}\\\\ -\boldone \otimes Y & (HS^\dagger\otimes \boldone)\operatorname{SWAP}\\\\ -Z\otimes Z & \operatorname{CNOT}\_{10}\\\\ -X\otimes Z & \operatorname{CNOT}\_{10}(H\otimes \boldone)\\\\ -Y\otimes Z & \operatorname{CNOT}\_{10}(HS^\dagger\otimes \boldone)\\\\ -Z\otimes X & \operatorname{CNOT}\_{10}(\boldone\otimes H)\\\\ -X\otimes X & \operatorname{CNOT}\_{10}(H\otimes H)\\\\ -Y\otimes X & \operatorname{CNOT}\_{10}(HS^\dagger\otimes H)\\\\ -Z\otimes Y & \operatorname{CNOT}\_{10}(\boldone \otimes HS^\dagger)\\\\ -X\otimes Y & \operatorname{CNOT}\_{10}(H\otimes HS^\dagger)\\\\ -Y\otimes Y & \operatorname{CNOT}\_{10}(HS^\dagger\otimes HS^\dagger)\\\\ -\end{array} +Z\otimes Z = \begin{bmatrix}1 &0 &0&0\\\\ 0&-1&0&0\\\\ 0&0&-1&0\\\\ 0&0&0&1\end{bmatrix}. $$ -Here the gate $\operatorname{CNOT}\_{10}$ appears for the following reason. Each Pauli measurement that does not include the $\boldone$ matrix is equivalent up to a unitary to $Z\otimes Z$ by the above reasoning. The eigenvalues of $Z\otimes Z$ only depend on the parity of the qubits that comprise each computational basis vector and the controlled-not operations that appear in this list serve to compute this parity and store it in the first bit. Then once the first bit is measured, we can recover the identity of the resultant half-space which is equivalent to measuring the Pauli operator. +Thus the tensor products of two Pauli-$Z$ operators forms a matrix composed of two spaces consisting of $+1$ and $-1$ eigenvalues. +As with the single-qubit case, both constitute a half-space meaning that half of the accessible vector space belongs to the $+1$ eigenspace and the remaining half to the $-1$ eigenspace. +In general, it is easy to see from the definition of the tensor product that any tensor product of Pauli-$Z$ operators and the identity also obeys this. +For example, -One additional note, while it may be tempting to assume that measuring $Z\otimes Z$ is the same as measuring $Z\otimes \id$ and then $\id \otimes Z$, this assumption would be false. The reason is that measuring $Z\otimes Z$ projects the quantum state into either the $+1$ or $-1$ eigenstate of these operators. Measuring $Z\otimes \id$ and then $\id \otimes Z$ projects the quantum state vector first onto a half space of $Z\otimes \id$ and then onto a half space of $\id \otimes Z$. As there are four computational basis vectors, performing both measurements reduces the state to a quarter-space and hence reduces it to a single computational basis vector. +$$ +\begin{align} + Z \otimes \boldone = \begin{bmatrix} + 1 & 0 & 0 & 0 \\\\ + 0 & 1 & 0 & 0 \\\\ + 0 & 0 & -1 & 0 \\\\ + 0 & 0 & 0 & -1 + \end{bmatrix}. +\end{align} +$$ +As before, any unitary transformation of such matrices also describes two half-spaces labeled by $\pm 1$ eigenvalues. +For example, $X\otimes X = H\otimes H(Z\otimes Z)H\otimes H$ from the identity that $Z=HXH$. +Similar to the one-qubit case, all two-qubit Pauli-measurements can be written as $U^\dagger (Z\otimes \id) U$ for $4\times 4$ unitary matrices $U$. +We enumerate the transformations in the following table. + +> [!NOTE] +> In the table below, we use $\operatorname{SWAP}$ to indicate the matrix +> $$ +> \begin{align} +> \operatorname{SWAP} & = +> \left(\begin{matrix} +> 1 & 0 & 0 & 0 \\\\ +> 0 & 0 & 1 & 0 \\\\ +> 0 & 1 & 0 & 0 \\\\ +> 0 & 0 & 0 & 1 +> \end{matrix}\right) +> \end{align} +> $$ +> used to simulate the intrinsic operation [`SWAP`](xref:microsoft.quantum.intrinsic). + +|Pauli Measurement |Unitary transformation | +|----------------------|------------------------| +| $Z \otimes \boldone$ | $\boldone \otimes \boldone$ | +| $Z\otimes \boldone$ | $\boldone\otimes \boldone$ | +| $X\otimes \boldone$ | $H\otimes \boldone$ | +| $Y\otimes \boldone$ | $HS^\dagger\otimes \boldone$ | +| $\boldone \otimes Z$ | $\operatorname{SWAP}$ | +| $\boldone \otimes X$ | $(H\otimes \boldone)\operatorname{SWAP}$ | +| $\boldone \otimes Y$ | $(HS^\dagger\otimes \boldone)\operatorname{SWAP}$ | +| $Z\otimes Z$ | $\operatorname{CNOT}\_{10}$ | +| $X\otimes Z$ | $\operatorname{CNOT}\_{10}(H\otimes \boldone)$ | +| $Y\otimes Z$ | $\operatorname{CNOT}\_{10}(HS^\dagger\otimes \boldone)$ | +| $Z\otimes X$ | $\operatorname{CNOT}\_{10}(\boldone\otimes H)$ | +| $X\otimes X$ | $\operatorname{CNOT}\_{10}(H\otimes H)$ | +| $Y\otimes X$ | $\operatorname{CNOT}\_{10}(HS^\dagger\otimes H)$ | +| $Z\otimes Y$ | $\operatorname{CNOT}\_{10}(\boldone \otimes HS^\dagger)$ | +| $X\otimes Y$ | $\operatorname{CNOT}\_{10}(H\otimes HS^\dagger)$ | +| $Y\otimes Y$ | $\operatorname{CNOT}\_{10}(HS^\dagger\otimes HS^\dagger)$ | + +Here, the [`CNOT`](xref:microsoft.quantum.intrinsic.cnot) operation appears for the following reason. +Each Pauli measurement that does not include the $\boldone$ matrix is equivalent up to a unitary to $Z\otimes Z$ by the above reasoning. +The eigenvalues of $Z\otimes Z$ only depend on the parity of the qubits that comprise each computational basis vector, and the controlled-not operations serve to compute this parity and store it in the first bit. +Then once the first bit is measured, we can recover the identity of the resultant half-space, which is equivalent to measuring the Pauli operator. + +One additional note: while it may be tempting to assume that measuring $Z\otimes Z$ is the same as sequentially measuring $Z\otimes \mathbb{1}$ and then $\mathbb{1} \otimes Z$, this assumption would be false. +The reason is that measuring $Z\otimes Z$ projects the quantum state into either the $+1$ or $-1$ eigenstate of these operators. +Measuring $Z\otimes \mathbb{1}$ and then $\mathbb{1} \otimes Z$ projects the quantum state vector first onto a half space of $Z\otimes \mathbb{1}$ and then onto a half space of $\mathbb{1} \otimes Z$. +As there are four computational basis vectors, performing both measurements reduces the state to a quarter-space and hence reduces it to a single computational basis vector. ## Correlations between qubits -Another way of looking at measuring tensor products of Paulis such as $X\otimes X$ or $Z\otimes Z$ is that these measurements let you look at information stored in the correlations between the two qubits. Measuring $X\otimes \id$ lets you look at information that is locally stored in the first qubit. While both types of measurements are equally valuable in quantum computing, the former illuminates the power of quantum computing. It reveals that in quantum computing often the information you wish to learn is not stored in any single qubit but rather stored non-locally in all the qubits at once, and only by looking at it through a joint measurement with $Z\otimes Z$ does this information become manifest. +Another way of looking at measuring tensor products of Pauli matrices such as $X\otimes X$ or $Z\otimes Z$ is that these measurements let you look at information stored in the correlations between the two qubits. +Measuring $X\otimes \id$ lets you look at information that is locally stored in the first qubit. +While both types of measurements are equally valuable in quantum computing, the former illuminates the power of quantum computing. +It reveals that in quantum computing, often the information you wish to learn is not stored in any single qubit but rather stored non-locally in all the qubits at once, and therefore only by looking at it through a joint measurement (e.g. $Z\otimes Z$) does this information become manifest. -Arbitrary Pauli operators such as $X\otimes Y \otimes Z \otimes \boldone$ can also be measured. All such tensor products of Pauli operators have only two eigenvalues $\pm 1$ and both eigenspaces constitute half-spaces of the entire vector space. Thus they coincide with the requirements stated above. +For example, in error correction, we often wish to learn what error occured while learning nothing about the state that we're trying to protect. +The [bit-flip code sample](https://github.com/microsoft/Quantum/tree/master/samples/error-correction/bit-flip-code) shows an example of how you can do that using measurements like $Z \otimes Z \otimes \id$ and $\id \otimes Z \otimes Z$. + -In Q#, such measurements return $j$ if the measurement yields a result in the eigenspace of sign $(-1)^j$. Having this as a built-in feature in Q# is helpful because measuring such operators requires long chains of controlled-NOT gates and basis transformations to describe the diagonalizing $U$ gate needed to express the operation as a tensor product of $Z$ and $\id$. By simply being able to specify that you wish to do one of these pre-defined measurements, you don't need to worry about how to transform your basis such that a computational basis measurement provides the necessary information. Q# handles all the necessary basis transformations for you automatically. See [Q# library reference for Pauli measurements](/qsharp/api/canon/microsoft.quantum.canon.measurepaulis) +Arbitrary Pauli operators such as $X\otimes Y \otimes Z \otimes \boldone$ can also be measured. +All such tensor products of Pauli operators have only two eigenvalues $\pm 1$ and both eigenspaces constitute half-spaces of the entire vector space. +Thus they coincide with the requirements stated above. + +In Q#, such measurements return $j$ if the measurement yields a result in the eigenspace of sign $(-1)^j$. +Having Pauli measurements as a built-in feature in Q# is helpful because measuring such operators requires long chains of controlled-NOT gates and basis transformations to describe the diagonalizing $U$ gate needed to express the operation as a tensor product of $Z$ and $\id$. +By being able to specify that you wish to do one of these pre-defined measurements, you don't need to worry about how to transform your basis such that a computational basis measurement provides the necessary information. +Q# handles all the necessary basis transformations for you automatically. +For more information, see the [`Measure`](xref:microsoft.quantum.intrinsic.measure) and [`MeasurePaulis`](xref:microsoft.quantum.measurement.measurepaulis) operations. ## The No-Cloning Theorem -Quantum information is powerful. It enables us to do amazing things such as factor numbers exponentially faster than the best known classical algorithms, or efficiently simulate correlated electron systems that classically require exponential cost to simulate accurately. However, there are limitations to the power of quantum computing. One such limitation is given by the *No-Cloning Theorem*. + +Quantum information is powerful. +It enables us to do amazing things such as factor numbers exponentially faster than the best known classical algorithms, or efficiently simulate correlated electron systems that classically require exponential cost to simulate accurately. +However, there are limitations to the power of quantum computing. +One such limitation is given by the *No-Cloning Theorem*. The No-Cloning Theorem is aptly named. It disallows cloning of generic quantum states by a quantum computer. The proof of the theorem is remarkably straightforward. -While a full proof of the no-cloning theorem is a little too technical for our discussion here, the proof of the theorem in the case where the quantum computer in question has no additional ancilla qubits is within our scope (ancilla qubits are qubits used for scratch space during a computation and are easily used and managed in Q#, see ). -For such a quantum computer, the cloning operation must be a unitary matrix. We disallow measurement, since it would corrupt the quantum state we are trying to clone. The unitary matrix we want must have the property that +While a full proof of the no-cloning theorem is a little too technical for our discussion here, the proof in the case of no additional auxiliary qubits is within our scope (auxiliary qubits are qubits used for scratch space during a computation and are easily used and managed in Q#, see ). + +For such a quantum computer, the cloning operation must be described by a unitary matrix. +We disallow measurement, since it would corrupt the quantum state we are trying to clone. +To simulate the cloning operation, we want the unitary matrix used to have the property that $$ - U \ket{\psi} \ket{0} = \ket{\psi} \ket{\psi}, + U \ket{\psi} \ket{0} = \ket{\psi} \ket{\psi} $$ for any state $\ket{\psi}$. The linearity property of matrix multiplication then implies that for any second quantum state $\ket{\phi}$, +$$ \begin{align} -&U\left[\frac{1}{\sqrt{2}}\left(\ket{\phi}+\ket{\psi} \right)\right]\ket{0}=\frac{1}{\sqrt{2}}U\ket{\phi}\ket{0}+\frac{1}{\sqrt{2}}U\ket{\psi}\ket{0}\\\\ -&\qquad\qquad=\frac{1}{\sqrt{2}}\left(\ket{\phi}\ket{\phi}+\ket{\psi}\ket{\psi}\right)\\\\ -&\qquad\qquad\ne \left(\frac{1}{\sqrt{2}}\left(\ket{\phi}+\ket{\psi} \right)\right)\otimes\left(\frac{1}{\sqrt{2}}\left(\ket{\phi}+\ket{\psi} \right)\right). + U \left[ + \frac{1}{\sqrt{2}}\left(\ket{\phi}+\ket{\psi} \right) + \right] \ket{0} + & = \frac{1}{\sqrt{2}} U\ket{\phi}\ket{0} + + \frac{1}{\sqrt{2}} U\ket{\psi}\ket{0} \\\\ + & = \frac{1}{\sqrt{2}} \left( + \ket{\phi} \ket{\phi} + \ket{\psi} \ket{\psi} + \right) \\\\ + & \ne \left( + \frac{1}{\sqrt{2}}\left(\ket{\phi}+\ket{\psi} \right) + \right) \otimes \left( + \frac{1}{\sqrt{2}}\left(\ket{\phi}+\ket{\psi} \right) + \right). \end{align} +$$ -This provides the fundamental intuition behind the No-Cloning Theorem: any device that copies an unknown quantum state must induce errors on at least some of the states it copies. While the key assumption that the cloner acts linearly on the input state can be violated through the addition of ancilla and measurement of the ancilla qubits, such interactions also leak information about the system through the measurement statistics and prevent exact cloning in such cases as well. For a more complete proof of the No-Cloning Theorem see [For more information](xref:microsoft.quantum.more-information). - -The No-Cloning Theorem is important for qualitative understanding of quantum computing because if you could clone quantum states inexpensively then you would be granted a near-magical ability to learn from quantum states. Indeed, you could violate Heisenberg's vaunted uncertainty principle. Alternatively, you could use an optimal cloner to take a single sample from a complex quantum distribution and learn everything you could possibly learn about that distribution from just one sample. This would be like you flipping a coin and observing heads and then upon telling a friend about the result having them respond "Ah the distribution of that coin must be Bernoulli with $p=0.512643\ldots$!" Such a statement would be non-sensical because one bit of information (the heads outcome) simply cannot provide the many bits of information needed to encode the distribution without substantial prior information. Similarly, without prior information we cannot perfectly clone a quantum state just as we cannot prepare an ensemble of such coins without knowing $p$. +This provides the fundamental intuition behind the No-Cloning Theorem: any device that copies an unknown quantum state must induce errors on at least some of the states it copies. +While the key assumption that the cloner acts linearly on the input state can be violated through the addition and measurement of auxiliary qubits, such interactions also leak information about the system through the measurement statistics and prevent exact cloning in such cases as well. +For a more complete proof of the No-Cloning Theorem see [For more information](xref:microsoft.quantum.more-information). -Information is not free in quantum computing. Each qubit measured gives a single bit of information, and the No-Cloning Theorem shows that there is no backdoor that can be exploited to get around the fundamental tradeoff between information gained about the system and the disturbance invoked upon it. +The No-Cloning Theorem is important for qualitative understanding of quantum computing because if you could clone quantum states inexpensively then you would be granted a near-magical ability to learn from quantum states. +Indeed, you could violate Heisenberg's vaunted uncertainty principle. +Alternatively, you could use an optimal cloner to take a single sample from a complex quantum distribution and learn everything you could possibly learn about that distribution from just one sample. +This would be like you flipping a coin and observing heads and then upon telling a friend about the result having them respond "Ah the distribution of that coin must be Bernoulli with $p=0.512643\ldots$!" Such a statement would be non-sensical because one bit of information (the heads outcome) simply cannot provide the many bits of information needed to encode the distribution without substantial prior information. +Similarly, without prior information we cannot perfectly clone a quantum state just as we cannot prepare an ensemble of such coins without knowing $p$. +Information is not free in quantum computing. +Each qubit measured gives a single bit of information, and the No-Cloning Theorem shows that there is no backdoor that can be exploited to get around the fundamental tradeoff between information gained about the system and the disturbance invoked upon it. diff --git a/articles/concepts/software-stack.md b/articles/concepts/software-stack.md deleted file mode 100644 index 798f0acaf..000000000 --- a/articles/concepts/software-stack.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Software stack | Microsoft Docs -description: Software stack -author: QuantumWriter -uid: microsoft.quantum.concepts.software-stack -ms.author: nawiebe@microsoft.com -ms.date: 12/11/2017 -ms.topic: article ---- - -# Software stack for quantum computing -Normally when we think of a computer we envision a single device running an application, but modern computing environments are much more complex and advanced. The application we interact with typically rests on multiple layers of software that provide for the application's execution down to the hardware level. These software layers are necessary to abstract the development of an application solution from the underlying complexity of the complete computing system. If a developer had to think about bus, cache architectures, communication protocols, and more while writing a simple smartphone app, the task would become much more complex. The concept of a *software stack* was developed in classical computing to address these issues. Borrowing from the classical concept, a software stack is also a key part of the vision behind quantum computing with Q#. - -## Conventional stack -The key idea behind a software stack is recursion. It consists of several nested layers of interfaces that abstract the details of the lower levels of the device away from the developer. For example, a commonly used software stack involves running ASP.NET (a programming language), on top of SQL server (a relational database management system), which runs on top of Internet Information Services (a web server), which runs on top of Windows server (an operating system), which drives the computer hardware. By looking at software as a hierarchy, one can write software in ASP.NET without needing to understand the low-level details of all the software below it. - -## Quantum stack - -The software stack in quantum computing is no different in principle, and in practice operates at a lower level than traditional stacks. What does a quantum stack look like? A quantum computer is not a replacement for traditional (often called classical) computers. In fact, quantum computers will almost certainly work in tandem with classical computers to solve computational problems. In part, this arises because of the fragility of quantum data. Quantum data is so fragile that if you even look at it you almost certainly damage the information being observed. Quantum computers will thus need to be designed with quantum error correction in mind so that stray interactions from its physical environment do not inadvertently damage the information and computation. For this reason, a natural target for Q# is an error-corrected quantum computer (often called a *fault-tolerant* quantum computer) that accepts a list of quantum instructions (called gates or gate operations) and applies those instructions to the quantum data stored within it. Note that if the number of qubits and gate operations in a quantum algorithm or program is small enough, error correction may not be absolutely necessary. However as the number of qubits and gate operations grow, it will more certainly be a requirement, thus we architect our software stack and Q# to aptly and efficiently handle error correction and enable scalable, fault-tolerant quantum computing. - -### Error correction -Error correction requires a fast and reliable classical computer to be run in concert with the quantum computer to correct errors as they appear in the quantum computation. In practice, components such as field-programmable gate arrays (FPGAs) or fast cryogenic processors may be needed to identify and correct the errors faster than they naturally accumulate in the quantum computer. As a result, a quantum computer is a hybrid machine comprised of several different computational devices that operate over a wide range of temperatures. For this reason, it is much more helpful to think about programming a quantum computer through the lens of a software stack, as there are many layers of hardware and software (classical and quantum) required to ultimately achieve the implementation of a quantum algorithm on a quantum computer. - -### Quantum conceptual stack -A conceptual stack that illustrates the functional flow of factoring 8704143553785700723 in a quantum computing environment is shown below: - -![Software stack](~/media/concepts_stack.png) - -### Specification and algorithm -There are several broad stages of programming such a quantum computation. The first, and arguably most challenging phase, is specifying the problem that one wishes to solve. In this case, the problem is to factor the number 8704143553785700723 into a product of two prime numbers. The next step involves designing an algorithm for solving this computational problem. In this case, Shor's famous quantum factoring algorithm can be used to find the factors. This algorithm is expressed in Q# and then a sequence of quantum operations is output that could be run on an idealized error-free quantum computer. - -### Physical gates -In this example, assume nature is not so kind as to provide an error-free quantum computer so the subsequent step takes the operations emitted by Q# and translates them using templates specified by the quantum error correction method chosen into physical gates that the basic hardware can execute. This process involves replacing every logical qubit described in the previous model with a host of physical qubits that are used to store and protect the information within a single qubit in a redundant fashion that can resist local errors on the constituent physical qubits long enough for such errors to be detected and corrected. Just as the logical qubits described by the Q# code need to be replaced with many physical qubits, similarly each quantum gate described in the output needs to be translated into a sequence of physical gates that act upon the physical qubits. For this reason, the output of Q# is seldom the final target for quantum computing and further levels of abstraction are needed to execute the code on hardware in an oblivious fashion. - -### Control computer -The physical gate sequence is then loaded into an ordinary computer that sends these instructions down to a control computer that interfaces directly with the quantum computer. This layer within the software stack is often handled by experimental control software such as [QCoDeS](http://qcodes.github.io/Qcodes/). - -### Interface computer -The final step in this process involves the interface computer first streaming the gates as needed to a fast control computer. Then the fast control computer applies the voltages needed (commonly called pulses) to implement the required gates on qubits. This has to be done while correcting any errors that are observed through quantum error correction. Cryogenic FPGAs or other exotic hardware may be needed to perform these steps within the stringent time requirements imposed by the rate at which errors appear in the quantum computer. The target language on this level is often [VHDL](https://en.wikipedia.org/wiki/VHDL), which requires a distinct way of thinking from that which is used at the top end of the stack to parse a description of a quantum algorithm. - -### The Q# quantum programming language -The aim of Q# is to provide a simple language that allows developers to write code that targets a wealth of quantum computing platforms and interface with the intervening layers of software that stand between the user and the quantum device. The language facilitates this by embracing the notion of a software stack and abstracting many of the details of the underlying quantum computer while allowing other levels of the stack, exposed through a language such as C#, to perform the necessary translations from Q# code to fundamental operations. This allows the developer to focus on what they do best: designing algorithms and solving problems. diff --git a/articles/concepts/toc.yml b/articles/concepts/toc.yml index 4745119c8..8523b66cf 100644 --- a/articles/concepts/toc.yml +++ b/articles/concepts/toc.yml @@ -16,5 +16,3 @@ href: circuits.md - name: Quantum oracles href: oracles.md -- name: Software stack - href: software-stack.md diff --git a/articles/contributing/code.md b/articles/contributing/code.md index 55768d4ce..91d2b63e2 100644 --- a/articles/contributing/code.md +++ b/articles/contributing/code.md @@ -54,7 +54,7 @@ For instance, the following test checks that `H(q); X(q); H(q);` as called by [!NOTE] > We unfortunately cannot accept code and documentation contributions on the [**microsoft/Quantum-NC**](https://github.com/microsoft/Quantum-NC) repository at this time, but we still very much appreciate bug reports. -There are also a few other, more specialized repositories focusing on different events, or on auxillary functionality related to the Quantum Development Kit. +There are also a few other, more specialized repositories focusing on different events, or on auxiliary functionality related to the Quantum Development Kit. - [**msr-quarc/qsharp.sty**](https://github.com/msr-quarc/qsharp.sty): LaTeX formatting support for Q# syntax. - [**msr-quarc/intern-workshop-2019**](https://github.com/msr-quarc/intern-workshop-2019): IQ# Notebook for Deutsch–Jozsa tutorial given at the 2019 intern workshop. diff --git a/articles/how-to-guides/create-qsharp-project.md b/articles/how-to-guides/create-qsharp-project.md index d366ce7a1..917c7107b 100644 --- a/articles/how-to-guides/create-qsharp-project.md +++ b/articles/how-to-guides/create-qsharp-project.md @@ -18,7 +18,7 @@ A Q# project contains Q# files containing quantum code, as well as a host progra Choose your development environment and language from the sections below: * [Python](#create-a-python-project) -* [Jupyter notebooks](#create-a-jupyter-notebook-project) +* [Q# Jupyter notebooks](#create-a-q-jupyter-notebook-project) * [C# with Visual Studio](#create-a-c-project-on-windows-using-visual-studio) * [C# with VS Code](#create-a-c-project-using-vs-code) * [C# with the command line](#create-a-c-project-using-the-dotnet-command-line-tool) @@ -27,7 +27,7 @@ Choose your development environment and language from the sections below: 1. Pre-requisites - * The [Quantum Development Kit for Python](xref:microsoft.quantum.install#develop-with-python) + * Install the [Quantum Development Kit for Python](xref:microsoft.quantum.install.python) 1. Create a folder for your project, and navigate to that folder @@ -70,11 +70,11 @@ Choose your development environment and language from the sections below: You can now continue to develop your quantum program. -## Create a Jupyter Notebook project +## Create a Q# Jupyter Notebook project 1. Pre-requisites - * The [Quantum Development Kit for Jupyter notebooks](xref:microsoft.quantum.install#develop-with-jupyter-notebooks) + * Install the [Quantum Development Kit for Jupyter notebooks](xref:microsoft.quantum.install.jupyter) 1. Run the following command to start the notebook server: @@ -110,7 +110,7 @@ You can now add other Q# operations to continue your quantum development. 1. Pre-requisites - * The [Quantum Development Kit for Visual Studio](xref:microsoft.quantum.install#develop-with-c-on-windows-using-visual-studio) + * Install the [Quantum Development Kit extension for Visual Studio](xref:microsoft.quantum.install.cs) 1. Create a new Q# application @@ -139,7 +139,7 @@ You can now continue your quantum development using Visual Studio 1. Pre-requisites - * The [Quantum Development Kit for VS Code](xref:microsoft.quantum.install#develop-with-c-using-visual-studio-code) + * Install the [Quantum Development Kit extension for VS Code](xref:microsoft.quantum.install.cs) 1. Create a new project: @@ -164,7 +164,7 @@ You can now continue your quantum development using Visual Studio Code. 1. Pre-requisites - * The [Quantum Development Kit for the Command Line](xref:microsoft.quantum.install#develop-with-c-using-the-dotnet-command-line-tool) + * Install the [Quantum Development Kit for the Command Line](xref:microsoft.quantum.install.cs) 1. Create a new application diff --git a/articles/index.yml b/articles/index.yml index 11bbf9d5f..401ed7f4a 100644 --- a/articles/index.yml +++ b/articles/index.yml @@ -1,11 +1,11 @@ ### YamlMime:Landing -title: Microsoft Quantum Documentation -summary: Learn how to use the Microsoft Quantum Developer Kit and Q#, a language for quantum algorithms. Learn key concepts and write your first quantum program. +title: Microsoft Quantum Development Kit +summary: Learn how to use the Microsoft Quantum Development Kit and Q#, a language for programming quantum algorithms. metadata: - title: Microsoft Quantum Documentation - Q# API Reference - description: Learn how to use the Microsoft Quantum Developer Kit and Q#, a language for quantum programming. Learn key concepts and write your first quantum program. Explore the rich tools and libraries of the QDK. + title: Microsoft Quantum Development Kit - Q# API Reference + description: Learn how to use the Microsoft Quantum Development Kit and Q#, a language for programming quantum algorithms. Learn key concepts and write your first quantum program. Explore the rich tools and libraries of the QDK. ms.prod: quantum ms.topic: landing-page ms.collection: collection @@ -48,9 +48,9 @@ landingContent: - linkListType: how-to-guide links: - text: Python install - url: install-guide/index.md#develop-with-python + url: install-guide/pyinstall.md - text: Jupyter install - url: install-guide/index.md#develop-with-jupyter-notebooks + url: install-guide/qjupyter.md - linkListType: how-to-guide links: - text: Q# Samples with Python @@ -67,9 +67,9 @@ landingContent: - linkListType: how-to-guide links: - text: Visual Studio install - url: install-guide/index.md#develop-with-c-on-windows-using-visual-studio + url: install-guide/csinstall.md - text: Visual Studio Code install - url: install-guide/index.md#develop-with-c-using-visual-studio-code + url: install-guide/csinstall.md # Samples - title: Q# samples diff --git a/articles/install-guide/csinstall.md b/articles/install-guide/csinstall.md new file mode 100644 index 000000000..539818292 --- /dev/null +++ b/articles/install-guide/csinstall.md @@ -0,0 +1,141 @@ +--- +title: Develop with Q# + C# +author: natke +ms.author: nakersha +ms.date: 9/30/2019 +ms.topic: article +ms.custom: how-to +uid: microsoft.quantum.install.cs +--- +# Develop with Q# + C# + +Install the QDK to develop C# host programs to call Q# operations. + +Q# is built to play well with .NET languages--specifically C#. You can work with this pairing inside different development environments: + +- [Q# + C# using Visual Studio (Windows)](#VS) +- [Q# + C# using Visual Studio Code (Windows, Linux and Mac)](#VSC) +- [Q# + C# using the `dotnet` command-line tool](#command) + +## Develop with Q# + C# using Visual Studio + +Visual Studio offers a rich environment for developing Q# programs. The Q# Visual Studio extension contains templates for Q# files and projects as well as syntax highlighting, code completion and IntelliSense support. + + +1. Pre-requisites + + - [Visual Studio](https://visualstudio.microsoft.com/downloads/) 16.3, with the .NET Core cross-platform development workload enabled + +1. Install the Q# Visual Studio extension + + - Download and install the [Visual Studio extension](https://marketplace.visualstudio.com/items?itemName=quantum.DevKit) + +1. Verify the installation by creating a `Hello World` application + + - Create a new Q# application + + - Go to **File** -> **New** -> **Project** + - Type `Q#` in the search box + - Select **Q# Application** + - Select **Next** + - Choose a name and location for your application + - Select **Create** + + - Inspect the project + + You should see that two files have been created: `Driver.cs`, which is the C# host application; and `Operation.qs`, which is a Q# program that defines a simple operation to print a message to the console. + + - Run the application + + - Select **Debug** -> **Start Without Debugging** + - You should see the text `Hello quantum world!` printed to a console window. + +> [!NOTE] +> * If you have multiple projects within one Visual Studio solution, all projects contained in the solution need to be in the same folder as the solution, or in one of its subfolders. + +## Develop with Q# + C# using Visual Studio Code + +Visual Studio Code (VS Code) offers a rich environment for developing Q# programs on Windows, Linux and Mac. The Q# VS Code extension includes support for Q# syntax highlighting, code completion, and Q# code snippets. + +1. Pre-requisites + + - [VS Code](https://code.visualstudio.com/download) + - [.NET Core SDK 3.1 or later](https://www.microsoft.com/net/download) + +1. Install the Quantum VS Code extension + + - Install the [VS Code extension](https://marketplace.visualstudio.com/items?itemName=quantum.quantum-devkit-vscode) + +1. Install the Quantum project templates: + + - Go to **View** -> **Command Palette** + - Select **Q#: Install project templates** + + You now have the Quantum Development Kit installed and ready to use in your own applications and libraries. + +1. Verify the installation by creating a `Hello World` application + + - Create a new project: + + - Go to **View** -> **Command Palette** + - Select **Q#: Create New Project** + - Select **Standalone console application** + - Navigate to the location on the file system where you would like to create the application + - Click on the **Open new project...** button, once the project has been created + + - If you don't already have the C# extension for VS Code installed, a pop-up will appear. Install the extension. + + - Run the application: + + - Go to **Terminal** -> **New Terminal** + - Enter `dotnet run` + - You should see the following text in the output window `Hello quantum world!` + + +> [!NOTE] +> * Workspaces with multiple root folders are not currently supported by the Visual Studio Code extension. If you have multiple projects within one VS Code workspace, all projects need to be contained within the same root folder. + +## Develop with Q# + C# using the `dotnet` command-line tool + +Of course, you can also build and run Q# programs from the command line by simply installing the .NET Core SDK and the QDK project templates. + +1. Pre-requisites + + - [.NET Core SDK 3.1 or later](https://www.microsoft.com/net/download) + +1. Install the Quantum project templates for .NET + + ```bash + dotnet new -i Microsoft.Quantum.ProjectTemplates + ``` + + You now have the Quantum Development Kit installed and ready to use in your own applications and libraries. + +1. Verify the installation by creating a `Hello World` application + + - Create a new application + + ```bash + dotnet new console -lang Q# -o runSayHello + ``` + + - Navigate to the new application directory + + ```bash + cd runSayHello + ``` + + You should see that two files have been created, along with the project files of the application: a Q# file (`Operation.qs`) and a C# host file (`Driver.cs`). + + - Run the application + + ```bash + dotnet run + ``` + + You should see the following output: `Hello quantum world!` + + +## What's next? + +Now that you have installed the Quantum Development Kit in your preferred environment, you can write and run [your first quantum program](xref:microsoft.quantum.write-program). diff --git a/articles/install-guide/index.md b/articles/install-guide/index.md index 29ace0234..f7cefdf13 100644 --- a/articles/install-guide/index.md +++ b/articles/install-guide/index.md @@ -14,240 +14,14 @@ Learn how to install the Microsoft Quantum Development Kit (QDK), so that you ca - the Q# programming language - a set of libraries that abstract complex functionality in Q# -- a host application (written in Python or a .NET language) that runs quantum operations written in Q# +- APIs for Python and .NET languages (i.e.: C#, F#, and VB.NET) for running quantum programs written in Q# - tools to facilitate your development -Depending on your chosen development environment, there are different installation steps. Choose your environment from the sections below. +Q# programs are often paired with a host program written in a .NET language (typically C#) or Python. This allows us to call quantum operations from inside a classical program. +In addition, the QDK provides Q# support for Jupyter Notebooks with the IQ# Jupyter kernel. -## Develop with Python +The QDK is available for multiple development environments. Select your preferred setup from the sections below: -The qsharp package for Python makes it easy to simulate Q# operations and functions from within Python. IQ# (pronounced i-q-sharp) is an extension primarily used by Jupyter and Python that provides the core functionality for compiling and simulating Q# operations. - -1. Pre-requisites - - - [Python](https://www.python.org/downloads/) 3.6 or later - - The [PIP](https://pip.pypa.io/en/stable/installing) Python package manager - - [.NET Core SDK 3.0 or later](https://www.microsoft.com/net/download) - -1. Install the `qsharp` package - - ```bash - pip install qsharp - ``` - -1. Install the `iqsharp` package - - ```bash - dotnet tool install -g Microsoft.Quantum.IQSharp - dotnet iqsharp install - ``` - -1. Verify the installation by creating a `Hello World` application - - - Create a minimal Q# operation, by creating a file called `Operation.qs`, and adding the following code to it: - - ```qsharp - namespace HelloWorld - { - open Microsoft.Quantum.Intrinsic; - open Microsoft.Quantum.Canon; - - operation SayHello() : Result { - Message("Hello from quantum world!"); - return Zero; - } - } - ``` - - - Create a Python program called `hello_world.py` to call the Q# `SayHello()` operation: - - ```python - import qsharp - - from HelloWorld import SayHello - - SayHello.simulate() - ``` - - - Run the program: - - ```bash - python hello_world.py - ``` - - - Verify the output. Your program should output the following lines: - - ```bash - Hello from quantum world! - 0 - ``` - -## Develop with Jupyter notebooks - -A favorite of academic settings, scientific labs, and online-based collaborative programming, Jupyter Notebooks offer in-place code execution—now including Q# code—along with instructions, notes, and other content. Here's what you need to do to start creating your own Q# notebooks. - -IQ# (pronounced i-q-sharp) is an extension primarily used by Jupyter and Python to the .NET Core SDK that provides the core functionality for compiling and simulating Q# operations. - - -1. Pre-requisites - - - [Python](https://www.python.org/downloads/) 3.6 or later - - [Jupyter Notebook](https://jupyter.readthedocs.io/en/latest/install.html) - - [.NET Core SDK 3.0 or later](https://www.microsoft.com/net/download) - -1. Install the `iqsharp` package - - ```bash - dotnet tool install -g Microsoft.Quantum.IQSharp - dotnet iqsharp install - ``` - -1. Verify the installation by creating a `Hello World` application - - - Run the following command to start the notebook server: - - ```bash - jupyter notebook - ``` - - - Browse to the URL shown on the command line. For example: [http://localhost:8888/?token=c790a52ba54f0cf77465c3c8983d776348285b0280d91b85] - - - Create a Jupyter notebook with a Q# kernel, and add the following code to the first notebook cell: - - ```qsharp - operation SayHello () : Unit { - Message("Hello from quantum world!"); - } - ``` - - - Run this cell of the notebook: - - ![Jupyter notebook cell with Q# code](~/media/install-guide-jupyter.png) - - You should see `SayHello` in the output of the cell. When running in jupyter notebooks, the Q# code is compiled, and the notebook outputs the name of the operation(s) that it finds. - - - - In a new cell, simulate the execution in a quantum computer of the operation you just created by using the `%simulate` magic: - - ![Jupyter notebook cell with %simulate magic](~/media/install-guide-jupyter-simulate.png) - - You should see the message printed on the screen along with the result of the operation you invoked (in this case, empty). - - -## Develop with C# on Windows, using Visual Studio - -Visual Studio offers a rich environment for developing Q# programs, offering great features like code completion and syntax highlighting that guide the developer in building their applications. The Q# Visual Studio extension contains templates for Q# files and projects as well as syntax highlighting and IntelliSense support. - - -1. Pre-requisites - - - [Visual Studio](https://visualstudio.microsoft.com/downloads/) 16.3, with the .NET Core cross-platform development workload enabled - -1. Install the Q# Visual Studio extension - - - Download the [Visual Studio extension](https://marketplace.visualstudio.com/items?itemName=quantum.DevKit) - - Add the extension to Visual Studio - -1. Verify the installation by creating a `Hello World` application - - - Create a new Q# application - - - Go to **File** -> **New** -> **Project** - - Type `Q#` in the search box - - Select **Q# Application** - - Select **Next** - - Choose a name and location for your application - - Select **Create** - - - Inspect the project - - You should see that two files have been created: `Driver.cs`, which is the C# host application; and `Operation.qs`, which is a Q# program that defines a simple operation to print a message to the console. - - - Run the application - - - Select **Debug** -> **Start Without Debugging** - - You should see the text `Hello quantum world!` printed to a console window. - -> [!NOTE] -> * If you have multiple projects within one Visual Studio solution, all projects contained in the solution need to be in the same folder as the solution, or in one of its subfolders. - -## Develop with C#, using Visual Studio Code - -Visual Studio Code (VS Code) offers a rich environment for developing Q# programs across many multiple computer environments, including Windows, Linux and Mac, offering great features like code completion and syntax highlighting that guide the developer in building their applications. The Q# VS Code extension contains syntax highlighting, and Q# code snippets. - -1. Pre-requisites - - - [VS Code](https://code.visualstudio.com/download) - - [.NET Core SDK 3.0 or later](https://www.microsoft.com/net/download) - -1. Install the Quantum VS Code extension - - - Install the [VS Code extension](https://marketplace.visualstudio.com/items?itemName=quantum.quantum-devkit-vscode) - -1. Install the Quantum project templates: - - - Go to **View** -> **Command Palette** - - Select **Q#: Install project templates** - - You now have the Quantum Development Kit installed and ready to use in your own applications and libraries. - -1. Verify the installation by creating a `Hello World` application - - - Create a new project: - - - Go to **View** -> **Command Palette** - - Select **Q#: Create New Project** - - Navigate to the location on the file system where you would like to create the application - - Click on the **Open new project...** button, once the project has been created - - - Run the application: - - - Go to **Debug** -> **Start Without Debugging** - - You should see the following text in the output window `Hello quantum world!` - -> [!NOTE] -> * > * Workspaces with multiple root folders are not currently supported by the Visual Studio Code extension. If you have multiple projects within one VS Code workspace, all projects need to be contained within the same root folder. - -## Develop with C#, using the `dotnet` command-line tool - -Of course, you can also build and run Q# programs from the command line by simply installing the .NET Core SDK and the QDK project templates. - -1. Pre-requisites - - - [.NET Core SDK 3.0 or later](https://www.microsoft.com/net/download) - -1. Install the Quantum project templates for .NET - - ```bash - dotnet new -i Microsoft.Quantum.ProjectTemplates - ``` - - You now have the Quantum Development Kit installed and ready to use in your own applications and libraries. - -1. Verify the installation by creating a `Hello World` application - - - Create a new application - - ```bash - dotnet new console -lang Q# -o runSayHello - ``` - - - Navigate to the new application directory - - ```bash - cd runSayHello - ``` - - You should see that two files have been created, along with the project files of the application: a Q# file (`Operation.qs`) and a C# host file (`Driver.cs`). - - - Run the application - - ```bash - dotnet run - ``` - - You should see the following output: `Hello quantum world!` - -## What's next? - -Now that you have installed the Quantum Development Kit in your preferred environment, you can write and run [your first quantum program](xref:microsoft.quantum.write-program). +- [Install Q# for C#:](xref:microsoft.quantum.install.cs) choose this environment if you want to combine C# and Q# to create a C# host program that calls Q# operations. +- [Install Q# for Python:](xref:microsoft.quantum.install.python) choose this environment if you want to combine Python and Q# to create a Python host program that calls Q# operations. +- [Install Q# for Jupyter Notebooks:](xref:microsoft.quantum.install.jupyter) choose this environment to execute Q# code in cells with embedded text or create quantum computing interactive tutorials. Do not choose this environment if you want to combine Q# with an external classical host program. diff --git a/articles/install-guide/pyinstall.md b/articles/install-guide/pyinstall.md new file mode 100644 index 000000000..c044a64b0 --- /dev/null +++ b/articles/install-guide/pyinstall.md @@ -0,0 +1,83 @@ +--- +title: Develop with Q# + Python +author: natke +ms.author: nakersha +ms.date: 9/30/2019 +ms.topic: article +ms.custom: how-to +uid: microsoft.quantum.install.python +--- + +# Develop with Q# + Python + +Install the QDK to develop Python host programs to call Q# operations. + +1. Pre-requisites + + - [Python](https://www.python.org/downloads/) 3.6 or later + - The [PIP](https://pip.pypa.io/en/stable/installing) Python package manager + - [.NET Core SDK 3.1 or later](https://www.microsoft.com/net/download) + + +1. Install the `qsharp` package, a Python package that enables interop between Q# and Python. + + ```bash + pip install qsharp + ``` + +1. Install `iqsharp`, a kernel used by Jupyter and Python that provides the core functionality for compiling and executing Q# operations. + + ```bash + dotnet tool install -g Microsoft.Quantum.IQSharp + dotnet iqsharp install + ``` + +1. While you can use Q# with Python in any IDE, we highly recommend using Visual Studio Code (VS Code) IDE for your Q# + Python applications. By using Visual Studio Code and the QDK Visual Studio Code extension you gain access to richer functionality. + + - Install [VS Code](https://code.visualstudio.com/download) (Windows, Linux and Mac) + - Install the [QDK extension for VS Code](https://marketplace.visualstudio.com/items?itemName=quantum.quantum-devkit-vscode). + +1. Verify the installation by creating a `Hello World` application + + - Create a minimal Q# operation, by creating a file called `Operation.qs`, and adding the following code to it: + + ```qsharp + namespace HelloWorld { + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Canon; + + operation SayHello() : Unit { + Message("Hello from quantum world!"); + } + } + ``` + + - Create a Python program called `hello_world.py` to call the Q# `SayHello()` operation: + + ```python + import qsharp + + from HelloWorld import SayHello + + SayHello.simulate() + ``` + + - Run the program: + + ```bash + python hello_world.py + ``` + + - Verify the output. Your program should output the following lines: + + ```bash + Hello from quantum world! + ``` + + +> [!NOTE] +> * You can also use Python Jupyter notebooks to write the classical Python program and call Q# operations from the cells. The Python code is just a normal Python program. + +## What's next? + +Now that you have installed the Quantum Development Kit in your preferred environment, you can write and run [your first quantum program](xref:microsoft.quantum.write-program). diff --git a/articles/install-guide/qjupyter.md b/articles/install-guide/qjupyter.md new file mode 100644 index 000000000..83e593283 --- /dev/null +++ b/articles/install-guide/qjupyter.md @@ -0,0 +1,68 @@ +--- +title: Develop with Q# Jupyter notebooks +author: natke +ms.author: nakersha +ms.date: 9/30/2019 +ms.topic: article +ms.custom: how-to +uid: microsoft.quantum.install.jupyter +--- + +# Develop with Q# Jupyter notebooks + +Install the QDK for developing Q# operations on Q# Jupyter Notebooks. + +Jupyter Notebooks allow in-place code execution alongside instructions, notes, and other content. This environment is ideal for writing Q# code with embedded explanations or quantum computing interactive tutorials. Here's what you need to do to start creating your own Q# notebooks. + +IQ# (pronounced i-q-sharp) is an extension primarily used by Jupyter and Python to the .NET Core SDK that provides the core functionality for compiling and simulating Q# operations. + +> [!NOTE] +> * In Q# Jupyter Notebooks you can only run Q# code, and the operations cannot be called from external host programs (e.g. Python or C# files). This environment is not appropriate if your goal is to combine an external classical host program with the quantum program. + +1. Pre-requisites + + - [Python](https://www.python.org/downloads/) 3.6 or later + - [Jupyter Notebook](https://jupyter.readthedocs.io/en/latest/install.html) + - [.NET Core SDK 3.1 or later](https://www.microsoft.com/net/download) + +1. Install the `iqsharp` package + + ```bash + dotnet tool install -g Microsoft.Quantum.IQSharp + dotnet iqsharp install + ``` + +1. Verify the installation by creating a `Hello World` application + + - Run the following command to start the notebook server: + + ```bash + jupyter notebook + ``` + + - To open the Jupyter notebook copy and paste the URL provided by the command line into your browser. + + - Create a Jupyter notebook with a Q# kernel, and add the following code to the first notebook cell: + + ```qsharp + operation SayHello () : Unit { + Message("Hello from quantum world!"); + } + ``` + + - Run this cell of the notebook: + + ![Jupyter notebook cell with Q# code](~/media/install-guide-jupyter.png) + + You should see `SayHello` in the output of the cell. When running in jupyter notebooks, the Q# code is compiled, and the notebook outputs the name of the operation(s) that it finds. + + + - In a new cell, execute the operation you just created (in a simulator) by using the `%simulate` command: + + ![Jupyter notebook cell with %simulate magic](~/media/install-guide-jupyter-simulate.png) + + You should see the message printed on the screen along with the result of the operation you invoked (here, we see the empty tuple `()` because our operation simply returns a `Unit` type). + +## What's next? + +Now that you have installed the Quantum Development Kit in your preferred environment, you can write and run [your first quantum program](xref:microsoft.quantum.write-program). diff --git a/articles/install-guide/update.md b/articles/install-guide/update.md index e206910a1..e6afacb6a 100644 --- a/articles/install-guide/update.md +++ b/articles/install-guide/update.md @@ -14,67 +14,99 @@ Learn how to update the Microsoft Quantum Development Kit (QDK) to the latest ve This article assumes that you already have the QDK installed. If you are installing for the first time, then please refer to the [installation guide](xref:microsoft.quantum.install). +We recommend keeping up to date with the latest QDK release. Follow this update guide to upgrade to the most recent QDK version. +The process consists of two parts: +1. updating your existing Q# files and projects to align your code with any updated syntax +2. updating the QDK itself for your chosen development environment ## Updating Q# Projects -1. First, install the latest version of the [.NET Core SDK 3.0](https://dotnet.microsoft.com/download) and run the following command in the command prompt: -```bash -dotnet --version -``` - Verify the output is 3.0.100 or higher, then follow the instructions below depending on your setup. +Regardless of whether you are using C# or Python to host Q# operations, follow these instructions to update your Q# projects. -### In Visual Studio +1. First, check that you have the latest version of the [.NET Core SDK 3.1](https://dotnet.microsoft.com/download). Run the following command in the command prompt: + ```bash + dotnet --version + ``` +Verify the output is `3.1.100` or higher. If not, install the [latest version](https://dotnet.microsoft.com/download) and check again. Then follow the instructions below depending on your setup (Visual Studio, Visual Studio Code, or directly the command line). + +### Update Q# projects in Visual Studio - 1. Update to the latest version of Visual Studio 2019, see [here](https://docs.microsoft.com/visualstudio/install/update-visual-studio?view=vs-2019) for instructions - 2. Open your solution in Visual Studio - 3. From the menu, select Build > Clean Solution - 4. [Update the target framework](https://docs.microsoft.com/visualstudio/ide/visual-studio-multi-targeting-overview?view=vs-2019#change-the-target-framework) in each of your .csproj files to netcoreapp3.0 (or netstandard2.1 if it is a library project) - 5. Save and close all files in your solution - 6. Select Tools > Command Line > Developer Command Prompt - 7. For each project in the solution, run the following command: - ```bash - dotnet add [project_name].csproj package Microsoft.Quantum.Development.Kit - ``` -If your projects use any other Microsoft.Quantum packages, run the command for these too. - 8. Close the command prompt and select Build > Build Solution (do *not* select Rebuild Solution, as rebuilding will initially fail) - -### In Visual Studio Code +1. Update to the latest version of Visual Studio 2019, see [here](https://docs.microsoft.com/visualstudio/install/update-visual-studio?view=vs-2019) for instructions +2. Open your solution in Visual Studio +3. From the menu, select **Build** -> **Clean Solution** +4. In each of your .csproj files, update the target framework to `netcoreapp3.0` (or `netstandard2.1` if it is a library project). + That is, edit lines of the form: + ```xml + netcoreapp3.0 + ``` + You can find more details on specifying target frameworks [here](https://docs.microsoft.com/dotnet/standard/frameworks#how-to-specify-target-frameworks). +5. Save and close all files in your solution +6. Select **Tools** -> **Command Line** -> **Developer Command Prompt** +7. For each project in the solution, run the following command: + ```bash + dotnet add [project_name].csproj package Microsoft.Quantum.Development.Kit + ``` + If your projects use any other Microsoft.Quantum packages (e.g. Microsoft.Quantum.Numerics), run the command for these too. +8. Close the command prompt and select **Build** -> **Build Solution** (do *not* select Rebuild Solution, as rebuilding will initially fail) + +You can now skip ahead to [update your Visual Studio QDK extension](#update-visual-studio-qdk-extension). + + +### Update Q# projects in Visual Studio Code 1. In Visual Studio Code, open the folder containing the project to update -1. Select Terminal > New Terminal -1. Follow the instructions for updating using the command line +2. Select **Terminal** -> **New Terminal** +3. Follow the instructions for updating using the command line (directly below) -### Using the command line +### Update Q# projects using the command line 1. Navigate to the folder containing your project file 2. Run the following command: -```bash -dotnet clean [project_name].csproj -``` - -3. [Update the target framework](https://docs.microsoft.com/dotnet/standard/frameworks#how-to-specify-target-frameworks) in each of your .csproj files to netcoreapp3.0 (or netstandard2.1 if it is a library project) + ```bash + dotnet clean [project_name].csproj + ``` + +3. In each of your .csproj files, update the target framework to `netcoreapp3.0` (or `netstandard2.1` if it is a library project). + That is, edit lines of the form: + ```xml + netcoreapp3.0 + ``` + You can find more details on specifying target frameworks [here](https://docs.microsoft.com/dotnet/standard/frameworks#how-to-specify-target-frameworks). 4. Run the following command: -```bash -dotnet add package Microsoft.Quantum.Development.Kit -``` -if your project uses any other Microsoft.Quantum packages, run the command for these too. - -5. Save and close all files + ```bash + dotnet add package Microsoft.Quantum.Development.Kit + ``` + If your project uses any other Microsoft.Quantum packages (e.g. Microsoft.Quantum.Numerics), run the command for these too. +5. Save and close all files. 6. Repeat 1-4 for each project dependency, then navigate back to the folder containing your main project and run: -```bash -dotnet build [project_name].csproj -``` + ```bash + dotnet build [project_name].csproj + ``` -## Update IQ# for Python +With your Q# projects now updated, follow the instructions below to update the QDK itself. -1. Update the `iqsharp` kernel +## Updating the QDK + +The process to update the QDK varies depending on your development language and environment. +Select your development environment below. + +* [Python: update the IQ# extension](#update-iq-for-python) +* [Jupyter Notebooks: update the IQ# extension](#update-iq-for-jupyter-notebooks) +* [Visual Studio: update the QDK extension](#update-visual-studio-qdk-extension) +* [VS Code: update the QDK extension](#update-vs-code-qdk-extension) +* [Command-line and C#: update project templates](#c-using-the-dotnet-command-line-tool) + + +### Update IQ# for Python + +1. Update the `iqsharp` kernel ```bash dotnet tool update -g Microsoft.Quantum.IQSharp dotnet iqsharp install ``` -1. Verify the `iqsharp` version +2. Verify the `iqsharp` version ```bash dotnet iqsharp --version @@ -83,17 +115,18 @@ dotnet build [project_name].csproj You should see the following output: ```bash - iqsharp: 0.10.1911.307 + iqsharp: 0.10.1912.501 Jupyter Core: 1.2.20112.0 ``` + Don't worry if your `iqsharp` version is higher, it should match the [latest release](xref:microsoft.quantum.relnotes). -1. Update the `qsharp` package +3. Update the `qsharp` package ```bash pip install qsharp --upgrade ``` -1. Verify the `qsharp` version +4. Verify the `qsharp` version ```bash pip show qsharp @@ -103,18 +136,18 @@ dotnet build [project_name].csproj ```bash Name: qsharp - Version: 0.10.1911.307 + Version: 0.10.1912.501 Summary: Python client for Q#, a domain-specific quantum programming language ... ``` -1. Run the following command from the location of your `.qs` files +5. Run the following command from the location of your `.qs` files ```bash python -c "import qsharp; qsharp.reload()" ``` -1. You can now use the updated QDK version to run your existing quantum programs. +6. You can now use the updated QDK version to run your existing quantum programs. -## Update IQ# for Jupyter notebooks +### Update IQ# for Jupyter Notebooks 1. Update the `iqsharp` kernel @@ -123,26 +156,28 @@ dotnet build [project_name].csproj dotnet iqsharp install ``` -1. Verify the `iqsharp` version +2. Verify the `iqsharp` version ```bash dotnet iqsharp --version ``` - You should see the following output: + Your output should be similar to the following: ```bash - iqsharp: 0.10.1911.307 + iqsharp: 0.10.1912.501 Jupyter Core: 1.2.20112.0 ``` -1. Run the following command from a cell in your Jupyter Notebook: + Don't worry if your `iqsharp` version is higher, it should match the [latest release](xref:microsoft.quantum.relnotes). + +3. Run the following command from a cell in your Jupyter Notebook: ``` %workspace reload ``` -1. You can now open an existing Jupyter notebook and run it with the updated QDK. +4. You can now open an existing Jupyter notebook and run it with the updated QDK. -## Update Visual Studio QDK extension +### Update Visual Studio QDK extension 1. Update the Q# Visual Studio extension @@ -152,7 +187,7 @@ dotnet build [project_name].csproj > [!NOTE] > The project templates are updated with the extension. The updated templates apply to newly created projects only. The code for your existing projects is not updated when the extension is updated. -## Update VS Code QDK extension +### Update VS Code QDK extension 1. Update the Quantum VS Code extension @@ -161,12 +196,13 @@ dotnet build [project_name].csproj - Select the **Microsoft Quantum Development Kit for Visual Studio Code** extension - Reload the extension -1. Update the Quantum project templates: +2. Update the Quantum project templates: - Go to **View** -> **Command Palette** - Select **Q#: Install project templates** + - After a few seconds you should get a popup confirming "project templates installed successfully" -## C#, using the `dotnet` command-line tool +### C#, using the `dotnet` command-line tool 1. Update the Quantum project templates for .NET diff --git a/articles/intro-to-katas.md b/articles/intro-to-katas.md index 071d8c6fc..fd211551e 100644 --- a/articles/intro-to-katas.md +++ b/articles/intro-to-katas.md @@ -14,7 +14,7 @@ uid: microsoft.quantum.overview.katas ## Learning by Doing -The tutorials and katas collected in this project emphasize learning by doing: they offer programming tasks that cover certain topics which progress from very simple to quite challenging. Each task asks you to fill in some code; the first tasks might require just one line, and the later ones might require a sizable fragment of code. +The tutorials and exercises collected in this project emphasize learning by doing: they offer programming tasks that cover certain topics which progress from very simple to quite challenging. Each task asks you to fill in some code; the first tasks might require just one line, and the later ones might require a sizable fragment of code. Most importantly, the katas include testing frameworks that sets up, runs and validates the solutions to the tasks. This allows you to get immediate feedback on your solution and to reconsider your approach if it is incorrect. @@ -31,10 +31,12 @@ Here is a summary of the main topics covered in the Quantum Katas. We recommend ### Introduction to quantum computing concepts -* [Complex arithmetic](https://github.com/microsoft/QuantumKatas/blob/master/tutorials/ComplexArithmetic) -* [Linear algebra](https://github.com/microsoft/QuantumKatas/blob/master/tutorials/LinearAlgebra) -* [The concept of a qubit](https://github.com/microsoft/QuantumKatas/blob/master/tutorials/Qubit) -* [Single-qubit quantum gates](https://github.com/microsoft/QuantumKatas/blob/master/tutorials/SingleQubitGates) +* [Complex arithmetic](https://github.com/microsoft/QuantumKatas/tree/master/tutorials/ComplexArithmetic) +* [Linear algebra](https://github.com/microsoft/QuantumKatas/tree/master/tutorials/LinearAlgebra) +* [The concept of a qubit](https://github.com/microsoft/QuantumKatas/tree/master/tutorials/Qubit) +* [Single-qubit quantum gates](https://github.com/microsoft/QuantumKatas/tree/master/tutorials/SingleQubitGates) +* [Multi-qubit systems](https://github.com/microsoft/QuantumKatas/tree/master/tutorials/MultiQubitSystems) +* [Multi-qubit gates](https://github.com/microsoft/QuantumKatas/tree/master/tutorials/MultiQubitGates) ### Quantum computing fundamentals @@ -47,10 +49,10 @@ Here is a summary of the main topics covered in the Quantum Katas. We recommend * [Quantum teleportation](https://github.com/microsoft/QuantumKatas/tree/master/Teleportation) * [Superdense coding](https://github.com/microsoft/QuantumKatas/tree/master/SuperdenseCoding) -* [Deutsch–Jozsa algorithm](https://github.com/microsoft/QuantumKatas/blob/master/tutorials/DeutschJozsaAlgorithm) +* [Deutsch–Jozsa algorithm](https://github.com/microsoft/QuantumKatas/tree/master/tutorials/ExploringDeutschJozsaAlgorithm) * [Implementing Grover's search algorithm](https://github.com/microsoft/QuantumKatas/tree/master/GroversAlgorithm) -* [Exploring high-level properties of Grover's search algorithm](https://github.com/microsoft/QuantumKatas/blob/master/tutorials/ExploringGroversAlgorithm) -* Solving real problems using Grover's algorithm: [SAT problems](https://github.com/microsoft/QuantumKatas/blob/master/SolveSATWithGrover) and [graph coloring problems](https://github.com/microsoft/QuantumKatas/blob/master/GraphColoring) +* [Exploring high-level properties of Grover's search algorithm](https://github.com/microsoft/QuantumKatas/tree/master/tutorials/ExploringGroversAlgorithm) +* Solving real problems using Grover's algorithm: [SAT problems](https://github.com/microsoft/QuantumKatas/tree/master/SolveSATWithGrover) and [graph coloring problems](https://github.com/microsoft/QuantumKatas/tree/master/GraphColoring) ### Protocols and libraries @@ -61,8 +63,8 @@ Here is a summary of the main topics covered in the Quantum Katas. We recommend ### Entanglement games -* [CHSH game](https://github.com/microsoft/QuantumKatas/blob/master/CHSHGame) -* [GHZ game](https://github.com/microsoft/QuantumKatas/blob/master/GHZGame) +* [CHSH game](https://github.com/microsoft/QuantumKatas/tree/master/CHSHGame) +* [GHZ game](https://github.com/microsoft/QuantumKatas/tree/master/GHZGame) * [Mermin-Peres magic square game](https://github.com/microsoft/QuantumKatas/tree/master/MagicSquareGame) ## Resources diff --git a/articles/language/file-structure.md b/articles/language/file-structure.md index 8523c6466..ad73c6bf2 100644 --- a/articles/language/file-structure.md +++ b/articles/language/file-structure.md @@ -243,12 +243,12 @@ If one or more specializations besides the default body need to be explicitly de then the implementation for the default body needs to be wrapped into a suitable specialization declaration as well: ```qsharp -operation CountOnes(qs: Qubit[]) : Int { +operation CountOnes(qubits: Qubit[]) : Int { body (...) // default body specialization { mutable n = 0; - for (q in qs) { + for (qubit in qubits) { set n += M(q) == One ? 1 | 0; } return n; @@ -311,7 +311,7 @@ An operation declaration might be as simple as the following, which defines the primitive Pauli X operation: ```qsharp -operation X (q : Qubit) : Unit +operation X (qubit : Qubit) : Unit is Adj + Ctl { body intrinsic; adjoint self; diff --git a/articles/language/statements.md b/articles/language/statements.md index ad45162da..47bda4051 100644 --- a/articles/language/statements.md +++ b/articles/language/statements.md @@ -60,8 +60,7 @@ For example: /// /// # See Also /// - Microsoft.Quantum.Intrinsic.H -operation ApplyTwice<'T>(op : ('T => Unit), target : 'T) : Unit -{ +operation ApplyTwice<'T>(op : ('T => Unit), target : 'T) : Unit { op(target); op(target); } @@ -113,7 +112,6 @@ If a short name `Z` for `X.Y` has been defined in that namespace and file, then ```qsharp namespace NS { - open Microsoft.Quantum.Intrinsic; // opens the namespace open Microsoft.Quantum.Math as Math; // defines a short name for the namespace } @@ -222,7 +220,7 @@ Similar statements are available for all binary operators in which the type of t This provides for example a convenient way to accumulate values: ```qsharp mutable results = new Result[0]; -for (q in qubits) { +for (qubit in qubits) { set results += [M(q)]; // ... } @@ -235,7 +233,7 @@ Correspondingly, update-and-reassign statements exist for named items in user-de ```qsharp newtype Complex = (Re : Double, Im : Double); -function AddAll (reals : Double[], ims : Double[]) : Complex[] { +function ElementwisePlus(reals : Double[], ims : Double[]) : Complex[] { mutable res = Complex(0.,0.); for (r in reals) { @@ -254,19 +252,17 @@ and thus help avoid having to update array items in the first place. Update-and-reassign statements provide an alternative if needed: ```qsharp -operation RandomInts(maxInt : Int, nrSamples : Int) : Int[] { - +operation GenerateRandomInts(max : Int, nSamples : Int) : Int[] { mutable samples = new Double[0]; - for (i in 1 .. nrSamples) { - set samples += [RandomInt(maxInt)]; + for (i in 1 .. nSamples) { + set samples += [RandomInt(max)]; } return samples; } -operation SampleUniformDistr(nrSamples : Int, prec : Int) : Double[] { - - let normalization = 1. / IntAsDouble(prec); - mutable samples = RandomInts(prec, nrSamples); +operation SampleUniformDistrbution(nSamples : Int, nSteps : Int) : Double[] { + let normalization = 1. / IntAsDouble(nSteps); + mutable samples = GenerateRandomInts(nSteps, nSamples); for (i in IndexRange(samples) { let value = IntAsDouble(samples[i]); @@ -281,10 +277,9 @@ operation SampleUniformDistr(nrSamples : Int, prec : Int) : Double[] { The function ```qsharp -function EmbedPauli (pauli : Pauli, location : Int, n : Int) : Pauli[] -{ - mutable pauliArray = new Pauli[n]; - for (index in 0 .. n - 1) { +function PauliEmbedding(pauli : Pauli, length : Int, location : Int) : Pauli[] { + mutable pauliArray = new Pauli[length]; + for (index in 0 .. length - 1) { set pauliArray w/= index <- index == location ? pauli | PauliI; } @@ -295,8 +290,8 @@ for example can simply be simplified using the function `ConstantArray` in `Micr and returning a copy-and-update expression: ```qsharp -function EmbedPauli (pauli : Pauli, i : Int, n : Int) : Pauli[] { - return ConstantArray(n, PauliI) w/ i <- pauli; +function PauliEmbedding(pauli : Pauli, length : Int, location : Int) : Pauli[] { + return ConstantArray(length, PauliI) w/ location <- pauli; } ``` @@ -387,8 +382,8 @@ For example, ```qsharp // ... -for (qb in qubits) { // qubits contains a Qubit[] - H(qb); +for (qubit in qubits) { // qubits contains a Qubit[] + H(qubit); } mutable results = new (Int, Results)[Length(qubits)]; @@ -420,13 +415,13 @@ so symbols bound in the body are available in the condition and fixup. ```qsharp mutable iter = 1; repeat { - ProbabilisticCircuit(qs); - let success = ComputeSuccessIndicator(qs); + ProbabilisticCircuit(qubits); + let success = ComputeSuccessIndicator(qubits); } until (success || iter > maxIter) fixup { iter += 1; - ComputeCorrection(qs); + ComputeCorrection(qubits); } ``` @@ -441,26 +436,26 @@ available in subsequent repetitions. For example, the following code is a probabilistic circuit that implements an important rotation gate $V_3 = (\boldone + 2 i Z) / \sqrt{5}$ using the Hadamard and T gates. -The loop terminates in 8/5 repetitions on average. +The loop terminates in $\frac{8}{5}$ repetitions on average. See [*Repeat-Until-Success: Non-deterministic decomposition of single-qubit unitaries*](https://arxiv.org/abs/1311.1074) (Paetznick and Svore, 2014) for details. ```qsharp -using (anc = Qubit()) { +using (qubit = Qubit()) { repeat { - H(anc); - T(anc); - CNOT(target,anc); - H(anc); - Adjoint T(anc); - H(anc); - T(anc); - H(anc); - CNOT(target,anc); - T(anc); + H(qubit); + T(qubit); + CNOT(target, qubit); + H(qubit); + Adjoint T(qubit); + H(qubit); + T(qubit); + H(qubit); + CNOT(target, qubit); + T(qubit); Z(target); - H(anc); - let result = M(anc); + H(qubit); + let result = M(qubit); } until (result == Zero); } ``` @@ -615,15 +610,15 @@ an array of qubits, indicated by `Qubit[`, an `Int` expression, and `]`. For example, ```qsharp -using (q = Qubit()) { +using (qubit = Qubit()) { // ... } -using ((ancilla, qubits) = (Qubit(), Qubit[bits * 2 + 3])) { +using ((auxiliary, qubits) = (Qubit(), Qubit[bits * 2 + 3])) { // ... } ``` -### Dirty Qubits +### Borrowed Qubits The `borrowing` statement is used to obtain qubits for temporary use. The statement consists of the keyword `borrowing`, followed by an open @@ -634,10 +629,10 @@ The binding follows the same pattern and rules as the one in a `using` statement For example, ```qsharp -borrowing (q = Qubit()) { +borrowing (qubit = Qubit()) { // ... } -borrowing ((ancilla, qubits) = (Qubit(), Qubit[bits * 2 + 3])) { +borrowing ((auxiliary, qubits) = (Qubit(), Qubit[bits * 2 + 3])) { // ... } ``` @@ -648,9 +643,8 @@ i.e. their state at the beginning and at the end of the statement block is expec This state in particular is not necessarily a classical state, such that in most cases, borrowing scopes should not contain measurements. -Such qubits are often known as “dirty ancilla”. See [*Factoring using 2n+2 qubits with Toffoli based modular multiplication*](https://arxiv.org/abs/1611.07995) -(Haner, Roetteler, and Svore 2017) for an example of dirty ancilla use. +(Haner, Roetteler, and Svore 2017) for an example of borrowed qubit use. When borrowing qubits, the system will first try to fill the request from qubits that are in use but that are not accessed during the body of the `borrowing` statement. diff --git a/articles/language/type-model.md b/articles/language/type-model.md index c83b7ee31..e3a0cb0dc 100644 --- a/articles/language/type-model.md +++ b/articles/language/type-model.md @@ -161,7 +161,7 @@ newtype Nested = (Double, (ItemName : Int, String)); Named items have the advantage that they can be accessed directly via the access operator `::`. ```qsharp -function Addition (c1 : Complex, c2 : Complex) : Complex { +function ComplexAddition(c1 : Complex, c2 : Complex) : Complex { return Complex(c1::Re + c2::Re, c1::Im + c2::Im); } ``` @@ -172,7 +172,7 @@ The "unwrap" operator, `!`, allows to extract the value contained in a user defi The type of such an "unwrap" expression is the underlying type of the user defined type. ```qsharp -function PrintMsg (value : Nested) : Unit { +function PrintedMessage(value : Nested) : Unit { let (d, (_, str)) = value!; Message ($"{str}, value: {d}"); } @@ -338,30 +338,31 @@ with the same result type and an input type that is compatible with `'A`. That is, given the following definitions: ```qsharp -operation Invertible (qs : Qubit[]) : Unit +operation Invert(qubits : Qubit[]) : Unit is Adj {...} -operation Unitary (qs : Qubit[]) : Unit + +operation ApplyUnitary(qubits : Qubit[]) : Unit is Adj + Ctl {...} -function ConjugateInvertibleWith ( - inner: (Qubit[] => Unit is Adj), - outer : (Qubit[] => Unit is Adj)) +function ConjugateInvertWith( + inner : (Qubit[] => Unit is Adj), + outer : (Qubit[] => Unit is Adj)) : (Qubit[] => Unit is Adj) {...} -function ConjugateUnitaryWith ( - inner: (Qubit[] => Unit is Adj + Ctl), - outer : (Qubit[] => Unit is Adj)) +function ConjugateUnitaryWith( + inner : (Qubit[] => Unit is Adj + Ctl), + outer : (Qubit[] => Unit is Adj)) : (Qubit[] => Unit is Adj + Ctl) {...} ``` the following are true: -- The operation `ConjugateInvertibleWith` may be invoked with an `inner` - argument of either `Invertible` or `Unitary`. -- The operation `ConjugateUnitaryWith` may be invoked with an `inner` - argument of `Unitary`, but not `Invertible`. +- The function `ConjugateInvertWith` may be invoked with an `inner` + argument of either `Invert` or `ApplyUnitary`. +- The function `ConjugateUnitaryWith` may be invoked with an `inner` + argument of `ApplyUnitary`, but not `Invert`. - A value of type `(Qubit[] => Unit is Adj + Ctl)` may be returned - from `ConjugateInvertibleWith`. + from `ConjugateInvertWith`. > [!IMPORTANT] > Q# 0.3 introduces a significant difference in the behavior of @@ -480,14 +481,12 @@ This example of a Q# operation comes from the [Measurement](https://github.com/m ```qsharp /// # Summary /// Prepares a state and measures it in the Pauli-Z basis. -operation MeasureOneQubit () : Result { +operation MeasureOneQubit() : Result { mutable result = Zero; using (qubit = Qubit()) { // Allocate a qubit H(qubit); // Use a quantum operation on that qubit - set result = M(qubit); // Measure the qubit - if (result == One) { // Reset the qubit so that it can be released X(qubit); } @@ -499,12 +498,11 @@ operation MeasureOneQubit () : Result { This example of a function comes from the [PhaseEstimation](https://github.com/microsoft/Quantum/tree/master/samples/characterization/phase-estimation) sample. It contains purely classical code. You can see that, unlike the example above, no qubits are allocated, and no quantum operations are used. - ```qsharp /// # Summary /// Given two arrays, returns a new array that is the pointwise product /// of each of the given arrays. -function MultiplyPointwise (left : Double[], right : Double[]) : Double[] { +function PointwiseProduct(left : Double[], right : Double[]) : Double[] { mutable product = new Double[Length(left)]; for (idxElement in IndexRange(left)) { @@ -520,7 +518,10 @@ It is also possible for a function to be passed qubits for processing, as in thi /// # Summary /// Translate MCT masks into multiple-controlled Toffoli gates (with single /// targets). -function GateMasksToToffoliGates (qubits : Qubit[], masks : MCMTMask[]) : MCTGate[] { +function GateMasksToToffoliGates( + qubits : Qubit[], + masks : MCMTMask[]) +: MCTGate[] { mutable result = new MCTGate[0]; let n = Length(qubits); diff --git a/articles/libraries/chemistry/concepts/algorithms.md b/articles/libraries/chemistry/concepts/algorithms.md index b818a4d32..bc49f73a4 100644 --- a/articles/libraries/chemistry/concepts/algorithms.md +++ b/articles/libraries/chemistry/concepts/algorithms.md @@ -71,13 +71,13 @@ $$ $$ Here, $e^{-iHt} \ket{00} = e^{it} \ket{00}$ and $e^{-iHt} \ket{01} = e^{-it} \ket{01}$, which can be seen directly as a consequence of the fact that the parity of $00$ is $0$ while the parity of the bit string $01$ is $1$. -Exponentials of Pauli operators can be implemented directly in Q# using the operation: +Exponentials of Pauli operators can be implemented directly in Q# using the operation: ```qsharp using(qubits = Qubit[2]){ let pauliString = [PauliX, PauliX]; let evolutionTime = 1.0; - // This applies e^{- i X \otimes X t} to qubits 0 and 1. + // This applies 𝑒^{- 𝑖 𝑋⊗𝑋 𝑡} to qubits 0 and 1. Exp(pauliString, - evolutionTime, qubits); } ``` diff --git a/articles/libraries/chemistry/concepts/jordan-wigner.md b/articles/libraries/chemistry/concepts/jordan-wigner.md index 62433af9e..992f69664 100644 --- a/articles/libraries/chemistry/concepts/jordan-wigner.md +++ b/articles/libraries/chemistry/concepts/jordan-wigner.md @@ -23,10 +23,15 @@ This means that qubits can naturally store the occupation of a given spin orbita We then have that $a^\dagger_j \ket{0}_j = \ket{1}_j$ and $a^\dagger_j \ket{1}_j = 0$. It is easy to verify that \begin{align} -a^\dagger_j &= \begin{bmatrix}0 & 1 \\\ 0 &0 \end{bmatrix}=\frac{X_j + iY_j}{2}, \nonumber\\\\ -a_j &= \begin{bmatrix}0 & 0 \\\ 1 &0 \end{bmatrix}=\frac{X_j - iY_j}{2}, +a^\dagger_j &= \begin{bmatrix}0 & 0 \\\ 1 &0 \end{bmatrix}=\frac{X_j - iY_j}{2}, \nonumber\\\\ +a_j &= \begin{bmatrix}0 & 1 \\\ 0 &0 \end{bmatrix}=\frac{X_j + iY_j}{2}, \end{align} where $X_j$ and $Y_j$ are the Pauli-$X$ and -$Y$ operators acting on qubit $j$. + +>[!NOTE] +> In Q# the $\ket{0}$ state represents the +1 eigenstate of the $Z$ operator. In some areas of physics $\ket{0}$ represents the low-energy ground state and thus the -1 eigenstate of the $Z$ operator. Therefore some formulas might differ from popular literature. + +In the chemistry library we use $\ket{0}$ to represent an unoccupied spin-orbital. This shows that for a single spin orbital it is easy to represent creation and annihilation operators in terms of unitary matrices that quantum computers understand. Note that while $X$ and $Y$ are unitary $a^\dagger$ and $a$ are not. We will see later that this does not pose a challenge for simulation. diff --git a/articles/libraries/numerics/numerics.md b/articles/libraries/numerics/numerics.md index 0cce25b47..a39c789e3 100644 --- a/articles/libraries/numerics/numerics.md +++ b/articles/libraries/numerics/numerics.md @@ -65,7 +65,7 @@ For each of the three types above, a variety of operations is available: - Reciprocal (1/x) - Measurement (classical Double) -For more information and detailed documentation for each of these operations, see the Q# library reference docs at [docs.microsoft.com](https://docs.microsoft.com/en-us/quantum) +For more information and detailed documentation for each of these operations, see the Q# library reference docs at [docs.microsoft.com](https://docs.microsoft.com/quantum) ## Sample: Integer addition @@ -79,15 +79,14 @@ sum is computed modulo $2^n$ if $y$ is stored in an $n$-bit register. Using the Quantum Development Kit, this operation can be applied as follows: ```qsharp -operation MyAdditionTest (xInt : Int, yInt : Int, n : Int) : Unit -{ +operation TestMyAddition(xValue : Int, yValue : Int, n : Int) : Unit { using ((xQubits, yQubits) = (Qubit[n], Qubit[n])) { x = LittleEndian(xQubits); // define bit order y = LittleEndian(yQubits); - ApplyXorInPlace(xInt, x); // initialize values - ApplyXorInPlace(yInt, y); + ApplyXorInPlace(xValue, x); // initialize values + ApplyXorInPlace(yValue, y); AddI(x, y); // perform addition x+y into y @@ -108,7 +107,7 @@ $$ where $d$ denotes the *degree*. To do so, all that is needed are the polynomial coefficients `[a_0,..., a_d]` (of type `Double[]`), the input `x : FixedPoint` and the output `y : FixedPoint` (initially zero): ```qsharp -EvaluatePolynomialFxP([1.0, 2.0], xFxP, yFxP); +EvaluatePolynomialFxP([1.0, 2.0], x, y); ``` The result, $P(x)=1+2x$, will be stored in `yFxP`. @@ -120,11 +119,11 @@ $$ $f(x)$ is approximated well by $P_{even}(x)$ or $P_{odd}(x) := x\cdot P_{even}(x)$, respectively. In Q#, these two cases can be handled as follows: ```qsharp -EvaluateEvenPolynomialFxP([1.0, 2.0], xFxP, yFxP); +EvaluateEvenPolynomialFxP([1.0, 2.0], x, y); ``` which evaluates $P_{even}(x) = 1 + 2x^2$, and ```qsharp -EvaluateOddPolynomialFxP([1.0, 2.0], xFxP, yFxP); +EvaluateOddPolynomialFxP([1.0, 2.0], x, y); ``` which evaluates $P_{odd}(x) = x + 2x^3$. diff --git a/articles/libraries/standard/algorithms.md b/articles/libraries/standard/algorithms.md index fbb1374f2..a1d30105e 100644 --- a/articles/libraries/standard/algorithms.md +++ b/articles/libraries/standard/algorithms.md @@ -45,7 +45,7 @@ The Fourier transform is a fundamental tool of classical analysis and is just as In addition, the efficiency of the *quantum Fourier transform* (QFT) far surpasses what is possible on a classical machine making it one of the first tools of choice when designing a quantum algorithm. As an approximate generalization of the QFT, we provide the operation that allows for further optimizations by pruning rotations that aren't strictly necessary for the desired algorithmic accuracy. -The approximate QFT requires the dyadic $Z$-rotation operation as well as the operation. +The approximate QFT requires the dyadic $Z$-rotation operation as well as the operation. The input and output are assumed to be encoded in big endian encoding (lowest bit/qubit is on the left, same as [ket notation](xref:microsoft.quantum.concepts.dirac)). The approximation parameter $a$ determines the pruning level of the $Z$-rotations, i.e., $a \in [0..n]$. In this case all $Z$-rotations $2\pi/2^k$ where $k > a$ are removed from the QFT circuit. diff --git a/articles/libraries/standard/applications.md b/articles/libraries/standard/applications.md index a7e126831..3c4b7dfee 100644 --- a/articles/libraries/standard/applications.md +++ b/articles/libraries/standard/applications.md @@ -97,15 +97,16 @@ As an example, the Trotter-Suzuki decomposition may be called using the followin ```qsharp function TrotterSimulationAlgorithm( - trotterStepSize: Double, - trotterOrder: Int) - : SimulationAlgorithm { + trotterStepSize : Double, + trotterOrder : Int) +: SimulationAlgorithm { ... } + function TimeDependentTrotterSimulationAlgorithm( - trotterStepSize: Double, - trotterOrder: Int) - : TimeDependentSimulationAlgorithm { + trotterStepSize : Double, + trotterOrder : Int) +: TimeDependentSimulationAlgorithm { ... } ``` @@ -128,11 +129,11 @@ Thus we define the convenient function ```qsharp function InterpolatedEvolution( - interpolationTime: Double, - evolutionGeneratorStart: EvolutionGenerator, - evolutionGeneratorEnd: EvolutionGenerator, - timeDependentSimulationAlgorithm: TimeDependentSimulationAlgorithm) - : (Qubit[] => Unit is Adj + Ctl) { + interpolationTime : Double, + evolutionGeneratorStart : EvolutionGenerator, + evolutionGeneratorEnd : EvolutionGenerator, + timeDependentSimulationAlgorithm : TimeDependentSimulationAlgorithm) +: (Qubit[] => Unit is Adj + Ctl) { ... } @@ -143,13 +144,13 @@ This returns a unitary operation that implements all steps of adiabatic state pr We also define a helpful operation that automatically performs all steps of a typical quantum chemistry experiment. For instance we have the following, which returns an energy estimate of the state produced by adiabatic state preparation: ```qsharp -operation AdiabaticStateEnergyEstimate( - nQubits : Int, - statePrepUnitary: (Qubit[] => Unit), - adiabaticUnitary: (Qubit[] => Unit), +operation EstimateAdiabaticStateEnergy( + nQubits : Int, + statePrepUnitary : (Qubit[] => Unit), + adiabaticUnitary : (Qubit[] => Unit), qpeUnitary: (Qubit[] => Unit is Adj + Ctl), - phaseEstAlgorithm : ((DiscreteOracle, Qubit[]) => Double)) - : Double { + phaseEstAlgorithm : ((DiscreteOracle, Qubit[]) => Double)) +: Double { ... } ``` diff --git a/articles/libraries/standard/characterization.md b/articles/libraries/standard/characterization.md index 38169f0d8..6f6e004d5 100644 --- a/articles/libraries/standard/characterization.md +++ b/articles/libraries/standard/characterization.md @@ -35,11 +35,11 @@ In discussing iterative phase estimation, we will consider a unitary $U$ given a As described in the section on oracles in [data structures](xref:microsoft.quantum.libraries.data-structures), the Q# canon models such operations by the user-defined type, defined by the tuple type `((Int, Qubit[]) => Unit : Adjoint, Controlled)`. Concretely, if `U : DiscreteOracle`, then `U(m)` implements $U^m$ for `m : Int`. -With this definition in place, each step of iterative phase estimation proceeds by preparing an auxillary qubit in the $\ket{+}$ state along with the initial state $\ket{\phi}$ that we assume is an [eigenvector](xref:microsoft.quantum.concepts.matrix-advanced) of $U(m)$, i.e. $U(m)\ket{\phi}= e^{im\phi}\ket{\phi}$. +With this definition in place, each step of iterative phase estimation proceeds by preparing an auxiliary qubit in the $\ket{+}$ state along with the initial state $\ket{\phi}$ that we assume is an [eigenvector](xref:microsoft.quantum.concepts.matrix-advanced) of $U(m)$, i.e. $U(m)\ket{\phi}= e^{im\phi}\ket{\phi}$. A controlled application of `U(m)` is then used which prepares the state $\left(R\_1(m \phi) \ket{+}\right)\ket{\phi}$. As in the quantum case, the effect of a controlled application of the oracle `U(m)` is precisely the same as the effect of applying $R_1$ for the unknown phase on $\ket{+}$, such that we can describe the effects of $U$ in this simpler fashion. Optionally, the algorithm then rotates the control qubit by applying $R_1(-m\theta)$ to obtain a state $\ket{\psi}=\left(R\_1(m [\phi-\theta]) \ket{+}\right)\ket{\phi}$$. -The auxillary qubit used as a control for `U(m)` is then measured in the $X$ basis to obtain a single classical `Result`. +The auxiliary qubit used as a control for `U(m)` is then measured in the $X$ basis to obtain a single classical `Result`. At this point, reconstructing the phase from the `Result` values obtained through iterative phase estimation is a classical statistical inference problem. Finding the value of $m$ that maximizes the information gained, given a fixed inference method, is simply a problem in statistics. @@ -192,25 +192,27 @@ Thus, as seen in **H2Sample**, an operation can accept an iterative phase estima ```qsharp operation H2EstimateEnergy( - idxBondLength : Int, + idxBondLength : Int, trotterStepSize : Double, - phaseEstAlgorithm : ((DiscreteOracle, Qubit[]) => Double)) + phaseEstAlgorithm : ((DiscreteOracle, Qubit[]) => Double)) : Double ``` -These myriad phase estimation algorithms are optimized for different properties and input parameters, which must be understood to make the best choice for the target application. For instance, some phase estimation algorithms are adaptive, meaning that future steps are classically controlled by the measurement results of previous steps. Some require the ability to exponentiate its black-box unitary oracle by arbitrary real powers, and others only require integer powers but are only able to resolve a phase estimate modulo $2\pi$. Some require many auxillary qubits, and other require only one. +These myriad phase estimation algorithms are optimized for different properties and input parameters, which must be understood to make the best choice for the target application. For instance, some phase estimation algorithms are adaptive, meaning that future steps are classically controlled by the measurement results of previous steps. Some require the ability to exponentiate its black-box unitary oracle by arbitrary real powers, and others only require integer powers but are only able to resolve a phase estimate modulo $2\pi$. Some require many auxiliary qubits, and others require only one. Similarly, using random walk phase estimation proceeds in much the same way as for other algorithms provided with the canon: ```qsharp -operation ExampleOracle(eigenphase : Double, time : Double, register : Qubit[]) : Unit -is Adj + Ctl { +operation ApplyExampleOracle( + eigenphase : Double, + time : Double, + register : Qubit[]) +: Unit is Adj + Ctl { Rz(2.0 * eigenphase * time, register[0]); } -operation BayesianPhaseEstimationCanonSample(eigenphase : Double) : Double { - - let oracle = ContinuousOracle(ExampleOracle(eigenphase, _, _)); +operation EstimateBayesianPhase(eigenphase : Double) : Double { + let oracle = ContinuousOracle(ApplyExampleOracle(eigenphase, _, _)); using (eigenstate = Qubit()) { X(eigenstate); // The additional inputs here specify the mean and variance of the prior, the number of diff --git a/articles/libraries/standard/control-flow.md b/articles/libraries/standard/control-flow.md index 8fd354e64..d2e031c8d 100644 --- a/articles/libraries/standard/control-flow.md +++ b/articles/libraries/standard/control-flow.md @@ -53,9 +53,9 @@ In Q#, we might use to represent this ```qsharp /// # Summary /// Applies $H$ to all qubits in a register. -operation HAll(register : Qubit[]) : Unit -is Adj + Ctl { - +operation ApplyHadamardToAll( + register : Qubit[]) +: Unit is Adj + Ctl { for (qubit in register) { H(qubit); } @@ -135,26 +135,26 @@ Since controlling operations can be expensive in general, using controlled varia > ('T => Unit is Adj + Ctl), 'T) => Unit > ``` -Similarly, produces operations which apply a sequence of other operations in turn. +Similarly, produces operations which apply a sequence of other operations in turn. For instance, the following are equivalent: ```qsharp H(qubit); X(qubit); -Bind([H, X], qubit); +Bound([H, X], qubit); ``` Combining with iteration patterns can make this especially useful: ```qsharp // Bracket the quantum Fourier transform with $XH$ on each qubit. -ApplyWith(ApplyToEach(Bind([H, X]), _), QFT, _); +ApplyWith(ApplyToEach(Bound([H, X]), _), QFT, _); ``` ### Time-Ordered Composition ### We can go still further by thinking of flow control in terms of partial application and classical functions, and can model even fairly sophisticated quantum concepts in terms of classical flow control. This analogy is made precise by the recognition that unitary operators correspond exactly to the side effects of calling operations, such that any decomposition of unitary operators in terms of other unitary operators corresponds to constructing a particular calling sequence for classical subroutines which emit instructions to act as particular unitary operators. -Under this view, `Bind` is precisely the representation of the matrix product, since `Bind([A, B])(target)` is equivalent to `A(target); B(target);`, which in turn is the calling sequence corresponding to $BA$. +Under this view, `Bound` is precisely the representation of the matrix product, since `Bound([A, B])(target)` is equivalent to `A(target); B(target);`, which in turn is the calling sequence corresponding to $BA$. A more sophisticated example is the [Trotter–Suzuki expansion](https://arxiv.org/abs/math-ph/0506007v1). As discussed in the Dynamical Generator Representation section of [data structures](xref:microsoft.quantum.libraries.data-structures), the Trotter–Suzuki expansion provides a particularly useful way of expressing matrix exponentials. @@ -199,12 +199,11 @@ We won't call this operation directly, however, and so we add `_` to the beginni ```qsharp operation _ControlledOnBitString( - bits : Bool[], - oracle: (Qubit[] => Unit is Adj + Ctl), - controlRegister : Qubit[], - targetRegister: Qubit[]) -: Unit -is Adj + Ctl { + bits : Bool[], + oracle: (Qubit[] => Unit is Adj + Ctl), + controlRegister : Qubit[], + targetRegister: Qubit[]) +: Unit is Adj + Ctl ``` Note that we take a string of bits, represented as a `Bool` array, that we use to specify the conditioning that we want to apply to the operation `oracle` that we are given. @@ -217,6 +216,7 @@ Thus, we can apply $P = X^{s\_0} \otimes X^{s\_1} \otimes \cdots \otimes X^{s\_{ This construction is precisely `ApplyWith`, so we write the body of our new operation accordingly: ```qsharp +{ ApplyWithCA( ApplyPauliFromBitString(PauliX, false, bits, _), (Controlled oracle)(_, targetRegister), @@ -235,8 +235,8 @@ In this way, our new function looks and feels very much like `Controlled`, illus ```qsharp function ControlledOnBitString( - bits : Bool[], - oracle: (Qubit[] => Unit is Adj + Ctl)) + bits : Bool[], + oracle: (Qubit[] => Unit is Adj + Ctl)) : ((Qubit[], Qubit[]) => Unit is Adj + Ctl) { return _ControlledOnBitString(bits, oracle, _, _); } diff --git a/articles/machines/qc-trace-simulator/depth-counter.md b/articles/machines/qc-trace-simulator/depth-counter.md index 9a50d772d..82e746dd6 100644 --- a/articles/machines/qc-trace-simulator/depth-counter.md +++ b/articles/machines/qc-trace-simulator/depth-counter.md @@ -22,12 +22,12 @@ that by default, only the T depth of operations is computed (which is often desi are aggregated over all the edges of the operations call graph. Let us now compute the depth -of the operation. We will use the following Q# driver code: +of the operation. We will use the following Q# sample code: ```qsharp -open Microsoft.Quantum.Primitive; -operation CCNOTDriver() : Unit { +open Microsoft.Quantum.Intrinsic; +operation ApplySampleWithCCNOT() : Unit { using (qubits = Qubit[3]) { CCNOT(qubits[0], qubits[1], qubits[2]); T(qubits[0]); @@ -37,7 +37,7 @@ operation CCNOTDriver() : Unit { ## Using Depth Counter within a C# Program -To check that `CCNOT` has `T` depth 5 and `CCNOTDriver` has `T` depth 6 +To check that `CCNOT` has `T` depth 5 and `ApplySampleWithCCNOT` has `T` depth 6 we can use the following C# code: ```csharp @@ -46,18 +46,18 @@ using System.Diagnostics; var config = new QCTraceSimulatorConfiguration(); config.useDepthCounter = true; var sim = new QCTraceSimulator(config); -var res = CCNOTDriver.Run(sim).Result; +var res = ApplySampleWithCCNOT.Run(sim).Result; -double tDepth = sim.GetMetric(DepthCounter.Metrics.Depth); -double tDepthAll = sim.GetMetric(DepthCounter.Metrics.Depth); +double tDepth = sim.GetMetric(DepthCounter.Metrics.Depth); +double tDepthAll = sim.GetMetric(DepthCounter.Metrics.Depth); ``` -The first part of the program executes `CCNOTDriver`. In the second part, we use the method -`QCTraceSimulator.GetMetric` to get the `T` depth of `CCNOT` and `CCNOTDriver`: +The first part of the program executes `ApplySampleWithCCNOT`. In the second part, we use the method +`QCTraceSimulator.GetMetric` to get the `T` depth of `CCNOT` and `ApplySampleWithCCNOT`: ```csharp -double tDepth = sim.GetMetric(DepthCounter.Metrics.Depth); -double tDepthAll = sim.GetMetric(DepthCounter.Metrics.Depth); +double tDepth = sim.GetMetric(DepthCounter.Metrics.Depth); +double tDepthAll = sim.GetMetric(DepthCounter.Metrics.Depth); ``` Finally, to output all the statistics collected by `Depth Counter` in CSV format we can diff --git a/articles/machines/qc-trace-simulator/distinct-inputs-checker.md b/articles/machines/qc-trace-simulator/distinct-inputs-checker.md index 6f400bba5..bc3299260 100644 --- a/articles/machines/qc-trace-simulator/distinct-inputs-checker.md +++ b/articles/machines/qc-trace-simulator/distinct-inputs-checker.md @@ -17,8 +17,12 @@ potential bugs in the code. Consider the following piece of Q# code to illustrate the issues detected by this package: ```qsharp -operation DoBoth(q1 : Qubit, q2 : Qubit, op1 : (Qubit => Unit), op2 : (Qubit => Unit)) : Unit { - +operation ApplyBoth( + q1 : Qubit, + q2 : Qubit, + op1 : (Qubit => Unit), + op2 : (Qubit => Unit)) +: Unit { op1(q1); op2(q2); } @@ -30,19 +34,18 @@ and operations acting on different qubits commute. Let us now consider an example, where this operation is used: ```qsharp -operation CapturedQubits () : Unit { - - using (q = Qubit[3]) { - let op1 = CNOT(_, q[1]); - let op2 = CNOT(q[1], _); - DoBoth(q[0], q[2], op1, op2); +operation ApplyWithNonDistinctInputs() : Unit { + using (qubits = Qubit[3]) { + let op1 = CNOT(_, qubits[1]); + let op2 = CNOT(qubits[1], _); + ApplyBoth(qubits[0], qubits[2], op1, op2); } } ``` Now `op1` and `op2` are both obtained using partial application and share a -qubit. When the user calls `DoBoth` in the example above the result of the operation -will depend on the order of `op1` and `op2` inside `DoBoth`. This is definitely +qubit. When the user calls `ApplyBoth` in the example above the result of the operation +will depend on the order of `op1` and `op2` inside `ApplyBoth`. This is definitely not what the user would expect to happen. The `Distinct Inputs Checker` will detect such situations when enabled and will throw `DistinctInputsCheckerException`. See the API documentation on [DistinctInputsCheckerException](https://docs.microsoft.com/dotnet/api/Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.DistinctInputsCheckerException) for more details. diff --git a/articles/machines/qc-trace-simulator/index.md b/articles/machines/qc-trace-simulator/index.md index d5526c443..079ffc675 100644 --- a/articles/machines/qc-trace-simulator/index.md +++ b/articles/machines/qc-trace-simulator/index.md @@ -27,30 +27,27 @@ details on this. There are two kinds of measurements that appear in quantum algorithms. The first kind plays an auxiliary role where the user usually knows the probability of the outcomes. In this case the user can write - from the namespace to express this knowledge. The following example illustrates this: + from the namespace to express this knowledge. The following example illustrates this: ```qsharp -operation Teleportation (source : Qubit, target : Qubit) : Unit { - - using (ancilla = Qubit()) { - - H(ancilla); - CNOT(ancilla, target); - - CNOT(source, ancilla); +operation TeleportQubit(source : Qubit, target : Qubit) : Unit { + using (qubit = Qubit()) { + H(qubit); + CNOT(qubit, target); + CNOT(source, qubit); H(source); AssertProb([PauliZ], [source], Zero, 0.5, "Outcomes must be equally likely", 1e-5); - AssertProb([PauliZ], [ancilla], Zero, 0.5, "Outcomes must be equally likely", 1e-5); + AssertProb([PauliZ], [q], Zero, 0.5, "Outcomes must be equally likely", 1e-5); if (M(source) == One) { Z(target); X(source); } - if (M(ancilla) == One) { X(target); X(ancilla); } + if (M(q) == One) { X(target); X(q); } } } ``` When the trace simulator executes `AssertProb` it will record that measuring -`PauliZ` on `source` and `ancilla` should be given an outcome of `Zero` with probability +`PauliZ` on `source` and `q` should be given an outcome of `Zero` with probability 0.5. When the simulator executes `M` later, it will find the recorded values of the outcome probabilities and `M` will return `Zero` or `One` with probability 0.5. When the same code is executed on a simulator that keeps track of the diff --git a/articles/machines/qc-trace-simulator/invalidated-qubits-use-checker.md b/articles/machines/qc-trace-simulator/invalidated-qubits-use-checker.md index 6fd916283..e1ddc7b49 100644 --- a/articles/machines/qc-trace-simulator/invalidated-qubits-use-checker.md +++ b/articles/machines/qc-trace-simulator/invalidated-qubits-use-checker.md @@ -13,7 +13,7 @@ uid: microsoft.quantum.machines.qc-trace-simulator.invalidated-qubits The `Invalidated Qubits Use Checker` is a part of the quantum computer [TraceSimulator](xref:microsoft.quantum.machines.qc-trace-simulator.intro) designed for detecting potential bugs in the code. Consider the following piece of Q# code to illustrate the issues detected by the `Invalidated Qubits Use Checker`. ```qsharp -operation UseReleasedQubit () : Unit { +operation UseReleasedQubit() : Unit { mutable q = new Qubit[1]; using (ans = Qubit()) { set q w/= 0 <- ans; diff --git a/articles/machines/qc-trace-simulator/primitive-operations-counter.md b/articles/machines/qc-trace-simulator/primitive-operations-counter.md index eae4e7bd4..fc5823378 100644 --- a/articles/machines/qc-trace-simulator/primitive-operations-counter.md +++ b/articles/machines/qc-trace-simulator/primitive-operations-counter.md @@ -13,15 +13,15 @@ uid: microsoft.quantum.machines.qc-trace-simulator.primitive-counter The `Primitive Operations Counter` is a part of the quantum computer [Trace Simulator](xref:microsoft.quantum.machines.qc-trace-simulator.intro). It counts the number of primitive executions used by every operation invoked in a quantum program. All operations from -`Microsoft.Quantum.Primitive` are expressed in terms of single qubit rotations, +`Microsoft.Quantum.Intrinsic` are expressed in terms of single qubit rotations, T gates, single qubit Clifford gates, CNOT gates and measurements of multi-qubit Pauli observables. Collected statistics are aggregated over the edges of the operations call graph. Let us now count how many `T` gates are needed to implement the `CCNOT` operation. ```qsharp -open Microsoft.Quantum.Primitive; -operation CCNOTDriver() : Unit { +open Microsoft.Quantum.Intrinsic; +operation ApplySampleWithCCNOT() : Unit { using (qubits = Qubit[3]) { CCNOT(qubits[0], qubits[1], qubits[2]); @@ -32,7 +32,7 @@ operation CCNOTDriver() : Unit { ## Using the Primitive Operations Counter within a C# Program -To check that `CCNOT` indeed requires 7 `T` gates and that `CCNOTDriver` executes 8 `T` +To check that `CCNOT` indeed requires 7 `T` gates and that `ApplySampleWithCCNOT` executes 8 `T` gates we can use the following C# code: ```csharp @@ -41,28 +41,28 @@ gates we can use the following C# code: var config = new QCTraceSimulatorConfiguration(); config.usePrimitiveOperationsCounter = true; var sim = new QCTraceSimulator(config); -var res = CCNOTDriver.Run(sim).Result; +var res = ApplySampleWithCCNOT.Run(sim).Result; -double tCountAll = sim.GetMetric(PrimitiveOperationsGroupsNames.T); -double tCount = sim.GetMetric(PrimitiveOperationsGroupsNames.T); +double tCountAll = sim.GetMetric(PrimitiveOperationsGroupsNames.T); +double tCount = sim.GetMetric(PrimitiveOperationsGroupsNames.T); ``` -The first part of the program executes `CCNOTDriver`. In the second part, we use the method -`QCTraceSimulator.GetMetric` to get the number of T gates executed by `CCNOTDriver`: +The first part of the program executes `ApplySampleWithCCNOT`. In the second part, we use the method +`QCTraceSimulator.GetMetric` to get the number of T gates executed by `ApplySampleWithCCNOT`: ```csharp -double tCount = sim.GetMetric(PrimitiveOperationsGroupsNames.T); -double tCountAll = sim.GetMetric(PrimitiveOperationsGroupsNames.T); +double tCount = sim.GetMetric(PrimitiveOperationsGroupsNames.T); +double tCountAll = sim.GetMetric(PrimitiveOperationsGroupsNames.T); ``` When `GetMetric` is called with two type parameters it returns the value of the metric associated with a given call graph edge. In our example operation -`Primitive.CCNOT` is called within `CCNOTDriver` and therefore the call graph contains -the edge ``. +`Primitive.CCNOT` is called within `ApplySampleWithCCNOT` and therefore the call graph contains +the edge ``. To get the number of `CNOT` gates used, we can add the following line: ```csharp -double cxCount = sim.GetMetric(PrimitiveOperationsGroupsNames.CX); +double cxCount = sim.GetMetric(PrimitiveOperationsGroupsNames.CX); ``` Finally, to output all the statistics collected by the gate counter in CSV format we can diff --git a/articles/machines/qc-trace-simulator/width-counter.md b/articles/machines/qc-trace-simulator/width-counter.md index 549e38875..33cff5558 100644 --- a/articles/machines/qc-trace-simulator/width-counter.md +++ b/articles/machines/qc-trace-simulator/width-counter.md @@ -11,16 +11,15 @@ uid: microsoft.quantum.machines.qc-trace-simulator.width-counter # Width Counter The `Width Counter` counts the number of qubits allocated and borrowed by each operation. - All operations from the `Microsoft.Quantum.Primitive` namespace are expressed in terms of single qubit rotations, + All operations from the `Microsoft.Quantum.Intrinsic` namespace are expressed in terms of single qubit rotations, T gates, single qubit Clifford gates, CNOT gates and measurements of multi-qubit Pauli observables. Some of the primitive operations can allocate extra qubits. For example, multiply controlled `X` gates or controlled `T` gates. Let us compute the number of extra qubits allocated by the implementation of a multiply controlled `X` gate: ```qsharp -open Microsoft.Quantum.Primitive; +open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Arrays; -operation MultiControlledXDriver( numberOfQubits : Int ) : Unit { - +operation ApplyMultiControlledX( numberOfQubits : Int ) : Unit { using(qubits = Qubit[numberOfQubits]) { Controlled X (Rest(qubits), Head(qubits)); } @@ -38,20 +37,20 @@ var config = new QCTraceSimulatorConfiguration(); config.useWidthCounter = true; var sim = new QCTraceSimulator(config); int totalNumberOfQubits = 5; -var res = MultiControlledXDriver.Run(sim, totalNumberOfQubits).Result; +var res = ApplyMultiControlledX.Run(sim, totalNumberOfQubits).Result; double allocatedQubits = - sim.GetMetric( + sim.GetMetric( WidthCounter.Metrics.ExtraWidth, functor: OperationFunctor.Controlled); double inputWidth = - sim.GetMetric( + sim.GetMetric( WidthCounter.Metrics.InputWidth, functor: OperationFunctor.Controlled); ``` -The first part of the program executes `MultiControlledXDriver`. In the second part we use the method +The first part of the program executes `ApplyMultiControlledX`. In the second part we use the method `QCTraceSimulator.GetMetric` to get the number of allocated qubits as well as the number of qubits that Controlled `X` received as input. diff --git a/articles/machines/resources-estimator.md b/articles/machines/resources-estimator.md index 30bdb3632..99cad8c4f 100644 --- a/articles/machines/resources-estimator.md +++ b/articles/machines/resources-estimator.md @@ -112,32 +112,32 @@ The following is the list of metrics estimated by the `ResourcesEstimator`: ## Providing the Probability of Measurement Outcomes - from the namespace can + from the namespace can be used to provide information about the expected probability of a measurement to help drive the execution of the Q# program. The following example illustrates this: ```qsharp -operation Teleportation (source : Qubit, target : Qubit) : Unit { +operation Teleport(source : Qubit, target : Qubit) : Unit { - using (ancilla = Qubit()) { + using (qubit = Qubit()) { - H(ancilla); - CNOT(ancilla, target); + H(q); + CNOT(qubit, target); - CNOT(source, ancilla); + CNOT(source, qubit); H(source); AssertProb([PauliZ], [source], Zero, 0.5, "Outcomes must be equally likely", 1e-5); - AssertProb([PauliZ], [ancilla], Zero, 0.5, "Outcomes must be equally likely", 1e-5); + AssertProb([PauliZ], [qubit], Zero, 0.5, "Outcomes must be equally likely", 1e-5); if (M(source) == One) { Z(target); X(source); } - if (M(ancilla) == One) { X(target); X(ancilla); } + if (M(qubit) == One) { X(target); X(qubit); } } } ``` When the `ResourcesEstimator` encounters `AssertProb` it will record that measuring -`PauliZ` on `source` and `ancilla` should be given an outcome of `Zero` with probability +`PauliZ` on `source` and `q` should be given an outcome of `Zero` with probability 0.5. When it executes `M` later, it will find the recorded values of the outcome probabilities and `M` will return `Zero` or `One` with probability 0.5. diff --git a/articles/media/qrng-Bloch.PNG b/articles/media/qrng-Bloch.PNG new file mode 100644 index 000000000..ddfd632ac Binary files /dev/null and b/articles/media/qrng-Bloch.PNG differ diff --git a/articles/media/qrng-H.PNG b/articles/media/qrng-H.PNG new file mode 100644 index 000000000..3defc90aa Binary files /dev/null and b/articles/media/qrng-H.PNG differ diff --git a/articles/media/qrng-meas.PNG b/articles/media/qrng-meas.PNG new file mode 100644 index 000000000..0d34805ea Binary files /dev/null and b/articles/media/qrng-meas.PNG differ diff --git a/articles/quickstarts/Bloch.svg b/articles/media/src/qrng-Bloch.svg similarity index 100% rename from articles/quickstarts/Bloch.svg rename to articles/media/src/qrng-Bloch.svg diff --git a/articles/quickstarts/H.svg b/articles/media/src/qrng-H.svg similarity index 100% rename from articles/quickstarts/H.svg rename to articles/media/src/qrng-H.svg diff --git a/articles/quickstarts/Measurement2.svg b/articles/media/src/qrng-meas.svg similarity index 100% rename from articles/quickstarts/Measurement2.svg rename to articles/media/src/qrng-meas.svg diff --git a/articles/quickstarts/qrng.md b/articles/quickstarts/qrng.md index 0dae4840b..ffa4c6a18 100644 --- a/articles/quickstarts/qrng.md +++ b/articles/quickstarts/qrng.md @@ -29,10 +29,10 @@ A simple example of a quantum algorithm written in Q# is a quantum random number open Microsoft.Quantum.Intrinsic; operation QuantumRandomNumberGenerator() : Result { - using(q = Qubit()) { // Allocate a qubit. - H(q); // Put the qubit to superposition. It now has a 50% chance of being 0 or 1. - let r = M(q); // Measure the qubit value. - Reset(q); + using(qubit = Qubit()) { // Allocate a qubit. + H(qubit); // Put the qubit to superposition. It now has a 50% chance of being 0 or 1. + let r = M(v); // Measure the qubit value. + Reset(qubit); return r; } } @@ -41,7 +41,7 @@ A simple example of a quantum algorithm written in Q# is a quantum random number As mentioned in our [What is Quantum Computing?](xref:microsoft.quantum.overview.what) article, a qubit is a unit of quantum information that can be in superposition. When measured, a qubit can only be either 0 or 1. However, during execution the state of the qubit represents the probability of reading either a 0 or a 1 with a measurement. This probabilistic state is known as superposition. We can use this probability to generate random numbers. -In our Q# operation, we introduce the `Qubit` datatype, native to Q#. We can only allocate a `Qubit` with a `using` statement. When it gets allocated a qubit is always in the `Zero` state. +In our Q# operation, we introduce the `Qubit` datatype, native to Q#. We can only allocate a `Qubit` with a `using` statement. When it gets allocated, a qubit is always in the `Zero` state. Using the `H` operation, we are able to put our `Qubit` in superposition. To measure a qubit and read its value, you use the `M` intrinsic operation. @@ -51,18 +51,61 @@ When a `Qubit` is de-allocated it must be explicitly set back to the `Zero` stat ### Visualizing the code with the Bloch sphere -In the Bloch sphere the north pole represents the classical value **0** and the south pole represents the classical value **1**. Any superposition can be represented by a point on the sphere (represented by an arrow). When the closer the end of the arrow to a pole, the higher the probability the qubit collapses into the classical value assigned to that pole when measured. For example, the qubit state represented by the red arrow below has a higher probability of giving the value **0** if we measure it. +In the Bloch sphere, the north pole represents the classical value **0** and the south pole represents the classical value **1**. Any superposition can be represented by a point on the sphere (represented by an arrow). The closer the end of the arrow to a pole the higher the probability the qubit collapses into the classical value assigned to that pole when measured. For example, the qubit state represented by the red arrow below has a higher probability of giving the value **0** if we measure it. - + We can use this representation to visualize what the code is doing: * First we start with a qubit initalizated in the state **0** and apply `H` to create a superposition in which the probabilities for **0** and **1** are the same. - + * Then we measure the qubit and save the output: - + Since the outcome of the measurement is completely random, we have obtained a random bit. We can call this operation several times to create integers. For example, if we call the operation three times to obtain three random bits, we can build random 3-bit numbers (that is, a random number between 0 and 7). + +## Creating a complete random number generator using a host program + +Now that we have a Q# operation that generates random bits, we can use it to build a complete quantum random number generator with a host program. + + ### [Python with Visual Studio Code or the Command Line](#tab/tabid-python) + + To run your new Q# program from Python, save the following code as `host.py`: + +:::code language="python" source="~/quantum/samples/getting-started/qrng/host.py" range="11-30"::: + + You can then run your Python host program from the command line: + ```bash + $ python host.py + Preparing Q# environment... + ..The random number generated is 42 + ``` + ### [C# with Visual Studio Code or the Command Line](#tab/tabid-csharp) + + To run your new Q# program from C#, modify `Driver.cs` to include the following C# code: + + :::code language="csharp" source="~/quantum/samples/getting-started/qrng/Host.cs" range="4-39"::: + + You can then run your C# host program from the command line: + + ```bash + $ dotnet run + The random number generated is 42 + ``` + + ### [C# with Visual Studio 2019](#tab/tabid-vs2019) + + To run your new Q# program from C# in Visual Studio, modify `Driver.cs` to include the following C# code: + + :::code language="csharp" source="~/quantum/samples/getting-started/qrng/Host.cs" range="4-39"::: + + Then press F5, the program will start execution and a new window will pop up with the random number generated: + + ```bash + $ dotnet run + The random number generated is 42 + ``` + *** diff --git a/articles/quickstarts/search.md b/articles/quickstarts/search.md index 27b442868..037ce7da2 100644 --- a/articles/quickstarts/search.md +++ b/articles/quickstarts/search.md @@ -38,11 +38,11 @@ The number of incremental boosts is fewer than the number of items in the list. 1. Add the following code to the `Operations.qs` file in your new project: - [!code-qsharp[](~/quantum/samples/algorithms/simple-grover/SimpleGrover.qs?highlight=5,27)] + :::code language="qsharp" source="~/quantum/samples/algorithms/simple-grover/SimpleGrover.qs" range="4-23" highlight="5,27"::: 1. To define the list that we're searching, create a new file `Reflections.qs`, and paste in the following code: - [!code-qsharp[](~/quantum/samples/algorithms/simple-grover/Reflections.qs)] + :::code language="qsharp" source="~/quantum/samples/algorithms/simple-grover/Reflections.qs" range="4-70"::: The `ReflectAboutMarked` operation defines the marked input that you are searching for: the string of alternating zeros and ones. This sample hard-codes the marked input, and can be extended to search for different inputs or generalized for any input. @@ -52,7 +52,7 @@ The number of incremental boosts is fewer than the number of items in the list. To run your new Q# program from Python, save the following code as `host.py`: - [!code-python[](~/quantum/samples/algorithms/simple-grover/host.py)] + :::code language="python" source="~/quantum/samples/algorithms/simple-grover/host.py" range="9-14"::: You can then run your Python host program from the command line: @@ -70,7 +70,7 @@ The number of incremental boosts is fewer than the number of items in the list. To run your new Q# program from C#, modify `Driver.cs` to include the following C# code: - [!code-csharp[](~/quantum/samples/algorithms/simple-grover/Host.cs)] + :::code language="csharp" source="~/quantum/samples/algorithms/simple-grover/Host.cs" range="4-23"::: You can then run your C# host program from the command line: @@ -89,7 +89,7 @@ The number of incremental boosts is fewer than the number of items in the list. To run your new Q# program from C# in Visual Studio, modify `Driver.cs` to include the following C# code: - [!code-csharp[](~/quantum/samples/algorithms/simple-grover/Host.cs)] + :::code language="csharp" source="~/quantum/samples/algorithms/simple-grover/Host.cs" range="4-23"::: Then press F5, the program will start execution and a new windows will pop-up with the following results: diff --git a/articles/relnotes/0.3-migration.md b/articles/relnotes/0.3-migration.md index 45fc40144..d829f7380 100644 --- a/articles/relnotes/0.3-migration.md +++ b/articles/relnotes/0.3-migration.md @@ -80,12 +80,12 @@ As can be seen from the example above, iteration over arrays is now also support Allocations within `using` and `borrowing` are newly possible for single qubits, qubit arrays, and nested tuples thereof: ```qsharp - using (q = Qubit()) { - // q contains a single qubit + using (qubit = Qubit()) { + // qubit contains a single qubit } - borrowing ((cs, q) = (Qubit[3], Qubit())) { - // cs contains an array of three qubits, and q contains a single qubit + borrowing ((qubits, qubit) = (Qubit[3], Qubit())) { + // qubits contains an array of three qubits, and qubit contains a single qubit } ``` @@ -114,17 +114,17 @@ The following example illustrates how to use the new modifier: ```qsharp newtype Unitary = (Qubit => Unit: Adjoint, Controlled); - operation Foo (unitaries : Unitary[], q : Qubit) : Unit { + operation Foo (unitaries : Unitary[], qubit : Qubit) : Unit { for (unitary in unitaries[1 .. Length(unitaries)-1]) { // Each element of unitaries is an instance of the user-defined // type Unitary, so unitary! unwraps each element to an operation // type that we can call. - unitary! (q); + unitary! (qubit); // The unwrap operator can also be used as a part of functor // expressions and when indexing into arrays. - Adjoint unitary! (q); - Adjoint unitaries[0]! (q); + Adjoint unitary! (qubit); + Adjoint unitaries[0]! (qubit); } } ``` diff --git a/articles/relnotes/index.md b/articles/relnotes/index.md index 573ba8252..402600e8d 100644 --- a/articles/relnotes/index.md +++ b/articles/relnotes/index.md @@ -16,6 +16,19 @@ For installation instructions, please refer to the [install guide](xref:microsof For update instructions, please refer to the [update guide](xref:microsoft.quantum.update). +## Version 0.10.2001.2702 + +*Release date: January 28th, 2020* + +This release contains the following: + +- New Microsoft.Quantum.SDK NuGet package, see the [README](https://github.com/microsoft/qsharp-compiler/blob/master/src/QuantumSdk/README.md) for more details +- Added support for .NET Core 3.1, it is highly recommended to have version 3.1.100 installed since building with older .NET Core SDK versions may cause issues +- New compiler transformations available under Microsoft.Quantum.QsCompiler.Experimental +- New functionality to expose output state vectors as HTML in IQ# +- Added support for EstimateFrequencyA to Microsoft.Quantum.Characterization for Hadamard and SWAP tests +- AmplitudeAmplification namespace now uses Q# style guide + ## Version 0.10.1912.0501 *Release date: December 5th, 2019* diff --git a/articles/techniques/file-structure.md b/articles/techniques/file-structure.md index a77cdcead..c733ca839 100644 --- a/articles/techniques/file-structure.md +++ b/articles/techniques/file-structure.md @@ -1,11 +1,12 @@ --- # Mandatory fields. See more on aka.ms/skyeye/meta. -title: Quantum development techniques introduction | Microsoft Docs -description: Quantum development techniques introduction +title: Q# program overview - Q# techniques | Microsoft Docs +description: Q# program overview - Q# techniques author: QuantumWriter ms.author: Christopher.Granade@microsoft.com ms.date: 12/11/2017 ms.topic: article +uid: microsoft.quantum.techniques.file-structure # Use only one of the following. Use ms.service for services, ms.prod for on-prem. Remove the # before the relevant field. # For Quantum products none of these categories have been defined yet. # ms.service: service-name-from-white-list diff --git a/articles/techniques/going-further.md b/articles/techniques/going-further.md index 9c0be5183..88555246e 100644 --- a/articles/techniques/going-further.md +++ b/articles/techniques/going-further.md @@ -1,11 +1,12 @@ --- # Mandatory fields. See more on aka.ms/skyeye/meta. -title: Q# techniques - going further | Microsoft Docs -description: Q# techniques - going further +title: Going further - Q# techniques | Microsoft Docs +description: Going further - Q# techniques author: QuantumWriter ms.author: Christopher.Granade@microsoft.com ms.date: 12/11/2017 ms.topic: article +uid: microsoft.quantum.techniques.going-further # Use only one of the following. Use ms.service for services, ms.prod for on-prem. Remove the # before the relevant field. # For Quantum products none of these categories have been defined yet. # ms.service: service-name-from-white-list diff --git a/articles/techniques/index.md b/articles/techniques/index.md index 6c7a40de9..b2bda3a9b 100644 --- a/articles/techniques/index.md +++ b/articles/techniques/index.md @@ -12,26 +12,36 @@ uid: microsoft.quantum.techniques.intro # Quantum Development Techniques -![Quantum](~/media/mobius_strip_preview.png) - -This section details the core concepts used to create quantum programs in Q#, and to interact with those programs from classical .NET applications. -This section assumes some knowledge of quantum computing concepts like those described in [Quantum computing concepts](xref:microsoft.quantum.concepts.intro). - - - - - - - - - +This section of our documentation details the core concepts used to create quantum programs in Q#, and to interact with those programs from classical applications. +We assume *some* knowledge of quantum computing concepts, like those described in [Quantum computing concepts](xref:microsoft.quantum.concepts.intro), but you need not be an expert in quantum computing to get a lot from these sections. +Their contents are as follows. +- [Q# program overview](xref:microsoft.quantum.techniques.file-structure) provides an overview of the purpose and functionality of the Q# programming language. + In particular, it clarifies how Q# is *not* a language for merely simulating quantum mechanics---though that functionality is of course provided by our full state simulator. + Rather, Q# was designed with an eye on the future, and its programs describe how a classical control computer *interacts* with qubits. +- [Operations and functions](xref:microsoft.quantum.techniques.opsandfunctions) details the two callable types of the Q# language: *operations*, which include action on qubits and quantum systems; and *functions*, which strictly work with classical information. + Without both classical and quantum information working in tandem, quantum computing would remain out of reach. + This section describes how to define and use these callables within the control flow of a Q# program. +- [Local variables](xref:microsoft.quantum.techniques.local-variables) describes the role of variables within Q# programs and how to leverage them effectively. + In particular, you will learn the difference between immutable/mutable variables and how to assign/re-assign them. +- [Working with qubits](xref:microsoft.quantum.techniques.qubits) describes the features of Q# that you can use to address individual qubits and systems of qubits. + Specifically, that entails their allocation, performing operations on them, and ultimately their measurement. + Additionally, you will learn some useful control flow techniques. +- In [Putting it all together](xref:microsoft.quantum.techniques.puttingittogether), you will leverage the techniques from the sections above to create a program which performs **quantum teleportation**: using two classical bits to "teleport" the full state of one qubit onto another. +- [Going further](xref:microsoft.quantum.techniques.going-further) introduces advanced techniques that can prove helpful as you move toward more complex quantum programming. + In particular, we discuss the use of *type-parameterized* operations and functions in Q#, which enable higher-order control flow by remaining agnostic to the specific types of their input/output, as well as *borrowing* qubits. + The latter differs from basic qubit allocation in that a Q# operation may use "dirty" qubits---qubits not necessarily initialized to a known state---to assist computations. +- [Testing and debugging](xref:microsoft.quantum.techniques.testing-and-debugging) details some techniques for making sure your code is doing what it is supposed to do. + Due to the general opacity of quantum information, debugging a quantum program can require specialized techniques. + Fortunately, Q# supports many of the classical debugging techniques programmers are used to, as well as those that are quantum-specific. These include creating/running unit tests in Q#, embedding *assertions* on values and probabilities in your code, and the `Dump` functions which output the state of target machine. + The latter can be used alongside our full state simulator to debug certain parts of computations by skirting some quantum limitations (e.g. the no-cloning theorem). +![Quantum](~/media/mobius_strip_preview.png) diff --git a/articles/techniques/local-variables.md b/articles/techniques/local-variables.md index adcad6962..b0bbcab32 100644 --- a/articles/techniques/local-variables.md +++ b/articles/techniques/local-variables.md @@ -1,11 +1,12 @@ --- # Mandatory fields. See more on aka.ms/skyeye/meta. -title: Q# techniques - local variables | Microsoft Docs -description: Q# techniques - local variables +title: Local variables - Q# techniques | Microsoft Docs +description: Local variables - Q# techniques author: QuantumWriter ms.author: Christopher.Granade@microsoft.com ms.date: 12/11/2017 ms.topic: article +uid: microsoft.quantum.techniques.local-variables # Use only one of the following. Use ms.service for services, ms.prod for on-prem. Remove the # before the relevant field. # For Quantum products none of these categories have been defined yet. # ms.service: service-name-from-white-list diff --git a/articles/techniques/operations-and-functions.md b/articles/techniques/operations-and-functions.md index ed71d85ae..b3bafd330 100644 --- a/articles/techniques/operations-and-functions.md +++ b/articles/techniques/operations-and-functions.md @@ -1,6 +1,6 @@ --- -title: Q# techniques - operations and functions | Microsoft Docs -description: Q# techniques - operations and functions +title: Operations and functions - Q# techniques | Microsoft Docs +description: Operations and functions - Q# techniques uid: microsoft.quantum.techniques.opsandfunctions author: QuantumWriter ms.author: Christopher.Granade@microsoft.com @@ -61,7 +61,7 @@ If an operation implements a unitary transformation, then it is possible to defi The existence of these specializations can be declared as part of the operation signature: `is Adj + Ctl` in the following example. The corresponding implementation for each such implicitly declared specialization is then generated by the compiler. ```qsharp -operation PrepareEntangledPair(here : Qubit, there : Qubit) : Unit { +operation PrepareEntangledPair(here : Qubit, there : Qubit) : Unit is Adj + Ctl { // implies the existence of an adjoint, a controlled, and a controlled adjoint specialization H(here); CNOT(here, there); diff --git a/articles/techniques/putting-it-all-together.md b/articles/techniques/putting-it-all-together.md index f3d33c059..fa4ea67fa 100644 --- a/articles/techniques/putting-it-all-together.md +++ b/articles/techniques/putting-it-all-together.md @@ -1,7 +1,7 @@ --- # Mandatory fields. See more on aka.ms/skyeye/meta. -title: Q# techniques - putting it all together | Microsoft Docs -description: Q# techniques - putting it all together +title: Putting it all together - Q# techniques | Microsoft Docs +description: Putting it all together - Q# techniques uid: microsoft.quantum.techniques.puttingittogether author: QuantumWriter ms.author: Christopher.Granade@microsoft.com @@ -14,7 +14,7 @@ ms.topic: article # ms.technology: tech-name-from-white-list --- -# Putting it All Together: Teleportation # +# Putting It All Together: Teleportation # Let's return to the example of the teleportation circuit defined in [Quantum Circuits](xref:microsoft.quantum.concepts.circuits). We're going to use this to illustrate the concepts we've learned so far. An explanation of quantum teleportation is provided below for those who are unfamiliar with the theory, followed by a walkthrough of the code implementation in Q#. ## Quantum Teleportation: Theory @@ -146,7 +146,7 @@ We also need to allocate a qubit `here` which we achieve with a `using` block: ``` ### Step 1: Create an entangled state -We can then create the entangled pair between `here` and `there` by using the @"microsoft.quantum.primitive.h" and @"microsoft.quantum.primitive.cnot" operations: +We can then create the entangled pair between `here` and `there` by using the @"microsoft.quantum.intrinsic.h" and @"microsoft.quantum.intrinsic.cnot" operations: ```qsharp H(here); @@ -162,7 +162,7 @@ We then use the next $\operatorname{CNOT}$ and $H$ gates to move our message qub ``` ### Step 3 & 4: Measuring and interpreting the result -Finally, we use @"microsoft.quantum.primitive.m" to perform the measurements and perform the necessary gate operations to get the desired state, as denoted by `if` statements: +Finally, we use @"microsoft.quantum.intrinsic.m" to perform the measurements and perform the necessary gate operations to get the desired state, as denoted by `if` statements: ```qsharp // Measure out the entanglement diff --git a/articles/techniques/testing-and-debugging.md b/articles/techniques/testing-and-debugging.md index 060ed565d..3566fa20b 100644 --- a/articles/techniques/testing-and-debugging.md +++ b/articles/techniques/testing-and-debugging.md @@ -1,6 +1,6 @@ --- -title: Q# techniques - testing and debugging | Microsoft Docs -description: Q# techniques - testing and debugging +title: Testing and debugging - Q# techniques | Microsoft Docs +description: Testing and debugging - Q# techniques author: tcNickolas ms.author: mamykhai@microsoft.com uid: microsoft.quantum.techniques.testing-and-debugging @@ -45,8 +45,8 @@ Initially this file contains one sample unit test `AllocateQubit` which checks t @Test("QuantumSimulator") operation AllocateQubit () : Unit { - using (q = Qubit()) { - Assert([PauliZ], [q], Zero, "Newly allocated qubit must be in the |0⟩ state."); + using (qubit = Qubit()) { + Assert([PauliZ], [qubit], Zero, "Newly allocated qubit must be in the |0⟩ state."); } Message("Test passed"); diff --git a/articles/techniques/working-with-qubits.md b/articles/techniques/working-with-qubits.md index fcfc0c281..794cf782b 100644 --- a/articles/techniques/working-with-qubits.md +++ b/articles/techniques/working-with-qubits.md @@ -1,6 +1,6 @@ --- -title: Working with Qubits | Microsoft Docs -description: Working with Qubits +title: Working with Qubits +description: Working with Qubits - Q# techniques author: QuantumWriter ms.author: Christopher.Granade@microsoft.com ms.date: 12/11/2017 @@ -8,11 +8,11 @@ ms.topic: article uid: microsoft.quantum.techniques.qubits --- -# Working with Qubits # +# Working with Qubits Having now seen a variety of different parts of the Q# language, let us get into the thick of it and see how to use qubits themselves. -## Allocating Qubits ## +## Allocating Qubits First, to obtain a qubit that we can use in Q#, we *allocate* qubits within a `using` block: @@ -28,9 +28,9 @@ At the end of the `using` block, any qubits allocated by that block are immediat > [!WARNING] > Target machines expect that qubits are in the $\ket{0}$ state immediately before deallocation, so that they can be reused and offered to other `using` blocks for allocation. > Whenever possible, use unitary operations to return any allocated qubits to $\ket{0}$. -> If need be, the @"microsoft.quantum.intrinsic.reset" operation can be used to measure a qubit instead, and to use that measurement result to ensure that the measured qubit is returned to $\ket{0}$. Such a measurement will destroy any entanglement with the remaining qubits and can thus impact the computation. +> If need be, the @"microsoft.quantum.intrinsic.reset" operation can be used to measure a qubit instead, and to use that measurement result to ensure that the measured qubit is returned to $\ket{0}$. Such a measurement will destroy any entanglement with the remaining qubits and can thus impact the computation. -## Intrinsic Operations ## +## Intrinsic Operations Once allocated, a qubit can then be passed to functions and operations. In some sense, this is all that a Q# program can do with a qubit, as the actions that can be taken are all defined as operations. @@ -38,12 +38,11 @@ We will see these operations in more detail in [Intrinsic Operations and Functio First, the single-qubit Pauli operators $X$, $Y$, and $Z$ are represented in Q# by the intrinsic operations `X`, `Y`, and `Z`, each of which has type `(Qubit => Unit is Adj + Ctl)`. As described in [Intrinsic Operations and Functions](xref:microsoft.quantum.libraries.standard.prelude), we can think of $X$ and hence of `X` as a bit-flip operation or NOT gate. -This lets us prepare states of the form $\ket{s_0 s_1 \dots s_n}$ for some classical bit string $s$: +The `X` operation lets us prepare states of the form $\ket{s_0 s_1 \dots s_n}$ for some classical bit string $s$: ```qsharp -operation PrepareBitString(bitstring : Bool[], register : Qubit[]) : Unit +operation PrepareBitString(bitstring : Bool[], register : Qubit[]) : Unit is Adj + Ctl { - let nQubits = Length(register); for (idxQubit in 0..nQubits - 1) { if (bitstring[idxQubit]) { @@ -52,14 +51,15 @@ is Adj + Ctl { } } -operation Example() : Unit { - +operation RunExample() : Unit { using (register = Qubit[8]) { PrepareBitString( [true, true, false, false, true, false, false, true], register ); // At this point, register now has the state |11001001〉. + // Resetting the qubits will allow us to deallocate them properly. + ResetAll(register); } } ``` @@ -71,7 +71,6 @@ We can also prepare states such as $\ket{+} = \left(\ket{0} + \ket{1}\right) / \ ```qsharp operation PreparePlusMinusState(bitstring : Bool[], register : Qubit[]) : Unit { - // First, get a computational basis state of the form // |s_0 s_1 ... s_n〉 by using PrepareBitString, above. PrepareBitString(bitstring, register); @@ -83,41 +82,39 @@ operation PreparePlusMinusState(bitstring : Bool[], register : Qubit[]) : Unit { } ``` -## Measurements ## +## Measurements -Using the `Measure` operation, which is a built in intrinsic non-unitary operation, we can extract classical information from an object of type `Qubit` and assign a classical value as a result, which has a reserved type `Result`, indicating that the result is no longer a quantum state. -The input to `Measure` is a Pauli axis on the Bloch sphere, represented by an object of type `Pauli` (i.e., for instance `PauliX`) and an object of type `Qubit`. +Using the `Measure` operation, which is a built-in intrinsic non-unitary operation, we can extract classical information from an object of type `Qubit` and assign a classical value as a result, which has a reserved type `Result`, indicating that the result is no longer a quantum state. +The input to `Measure` is a Pauli axis on the Bloch sphere, represented by a value of type `Pauli` (for instance `PauliX`) and an value of type `Qubit`. -A simple example is the following operation which creates one qubit in the $\ket{0}$ state, then applies a Hadamard gate ``H`` to it and then measures the result in the `PauliZ` basis. +A simple example is the following operation, which allocates one qubit in the $\ket{0}$ state, then applies a Hadamard operation `H` to it and measures the result in the `PauliZ` basis. ```qsharp -operation MeasurementOneQubit () : Result { - - // The following using block creates a fresh qubit and initializes it +operation MeasureOneQubit() : Result { + // The following using block creates a fresh qubit and initializes it // in the |0〉 state. using (qubit = Qubit()) { - // We apply a Hadamard operation H to the state, thereby creating the - // state 1/sqrt(2)(|0〉+|1〉). - H(qubit); + // We apply a Hadamard operation H to the state, thereby preparing the + // state 1 / sqrt(2) (|0〉 + |1〉). + H(qubit); // Now we measure the qubit in Z-basis. let result = M(qubit); - // As the qubit is now in an eigenstate of the measurement operator, - // we reset the qubit before releasing it. - if (result == One) { X(qubit); } - // Finally, we return the result of the measurement. + // As the qubit is now in an eigenstate of the measurement operator, + // we reset the qubit before releasing it. + if (result == One) { X(qubit); } + // Finally, we return the result of the measurement. return result; } } ``` -A slightly more complicated example is given by the following operation which returns the Boolean value `true` if all qubits in a register of type `Qubit[]` are in the state zero, when measured in a specified Pauli basis and `false` otherwise. +A slightly more complicated example is given by the following operation, which returns the Boolean value `true` if all qubits in a register of type `Qubit[]` are in the state zero when measured in a specified Pauli basis, and which returns `false` otherwise. ```qsharp -operation AllMeasurementsZero (qs : Qubit[], pauli : Pauli) : Bool { - +operation MeasureIfAllQubitsAreZero(qubits : Qubit[], pauli : Pauli) : Bool { mutable value = true; - for (q in qs) { - if ( Measure([pauli], [q]) == One ) { + for (qubit in qubits) { + if (Measure([pauli], [qubit]) == One) { set value = false; } } @@ -125,36 +122,40 @@ operation AllMeasurementsZero (qs : Qubit[], pauli : Pauli) : Bool { } ``` -The Q# language allows dependencies of classical control flow on measurement results of qubits. This in turn enables to implement powerful probabilistic gadgets that can reduce the computational cost for implementing unitaries. As an example, it is easy to implement so-called *Repeat-Until-Success* in Q# which are probabilistic circuits that have an *expected* low cost in terms of elementary gates, but for which the true cost depends on an actual run and an actual interleaving of various possible branchings. +The Q# language allows classical control flow to depend on the results of measuring qubits. +This capability in turn enables implementing powerful probabilistic gadgets that can reduce the computational cost for implementing unitaries. +As an example, it is easy to implement so-called *Repeat-Until-Success* (RUS) patterns in Q#. +These RUS patterns are probabilistic programs that have an *expected* low cost in terms of elementary gates, but for which the true cost depends on an actual run and an actual interleaving of various possible branchings. To facilitate Repeat-Until-Success (RUS) patterns, Q# supports the construct + ```qsharp repeat { - statementBlock1 + statementBlock1 } until (expression) fixup { statementBlock2 } ``` -where `statementBlock1` and `statementBlock2` are zero or more Q# statements, and `expression` any valid expression that evaluates to a value of type `Bool`. -In a typical use case, the following circuit implements a rotation around an irrational axis of $(I + 2i Z)/\sqrt{5}$ on the Bloch sphere. This is accomplished by using a known RUS pattern: -```qsharp -operation RUScircuit (qubit : Qubit) : Unit { +where `statementBlock1` and `statementBlock2` are zero or more Q# statements, and `expression` any valid expression that evaluates to a value of type `Bool`. +In a typical use case, the following Q# operation implements a rotation around an irrational axis of $(I + 2i Z)/\sqrt{5}$ on the Bloch sphere. This is accomplished by using a known RUS pattern: - using(ancillas = Qubit[2]) { - ApplyToEachA(H, ancillas); +```qsharp +operation ApplyVRotationUsingRUS(qubit : Qubit) : Unit { + using (controls = Qubit[2]) { + ApplyToEachA(H, controls); mutable finished = false; repeat { - Controlled X(ancillas, qubit); + Controlled X(controls, qubit); S(qubit); - Controlled X(ancillas, qubit); + Controlled X(controls, qubit); Z(qubit); } - until(finished) + until (finished) fixup { - if AllMeasurementsZero(ancillas, Xpauli) { + if (MeasureIfAllQubitsAreZero(controls, PauliX)) { set finished = true; } } @@ -164,49 +165,53 @@ operation RUScircuit (qubit : Qubit) : Unit { This example shows the use of a mutable variable `finished` which is in scope of the entire repeat-until-fixup loop and which gets initialized before the loop and updated in the fixup step. -Finally, we show an example of a RUS pattern to prepare a quantum state $\frac{1}{\sqrt{3}}\left(\sqrt{2}\ket{0}+\ket{1}\right)$, starting from the $\ket{+}$ state. See also the [unit testing sample provided with the standard library](https://github.com/microsoft/Quantum/blob/master/samples/diagnostics/unit-testing/RepeatUntilSuccessCircuits.qs): +Finally, we show an example of a RUS pattern to prepare a quantum state $\frac{1}{\sqrt{3}}\left(\sqrt{2}\ket{0}+\ket{1}\right)$, starting from the $\ket{+}$ state. +See also the [unit testing sample provided with the standard library](https://github.com/microsoft/Quantum/blob/master/samples/diagnostics/unit-testing/RepeatUntilSuccessCircuits.qs): ```qsharp -operation RepeatUntilSuccessStatePreparation( target : Qubit ) : Unit { - - using( ancilla = Qubit() ) { - H(ancilla); +operation PrepareStateUsingRUS(target : Qubit) : Unit { + using (auxiliary = Qubit()) { + H(auxiliary); repeat { - // We expect target and ancilla qubit to be in |+⟩ state. - AssertProb( - [PauliX], [target], Zero, 1.0, + // We expect the target and auxiliary qubits to each be in + // the |+⟩ state. + AssertProb( + [PauliX], [target], Zero, 1.0, "target qubit should be in the |+⟩ state", 1e-10 ); - AssertProb( - [PauliX], [ancilla], Zero, 1.0, - "ancilla qubit should be in the |+⟩ state", 1e-10 ); - - Adjoint T(ancilla); - CNOT(target, ancilla); - T(ancilla); - - // The probability of measuring |+⟩ state on ancilla is 3/4. - AssertProb( - [PauliX], [ancilla], Zero, 3. / 4., - "Error: the probability to measure |+⟩ in the first - ancilla must be 3/4", + AssertProb( + [PauliX], [auxiliary], Zero, 1.0, + "auxiliary qubit should be in the |+⟩ state", 1e-10 ); + + Adjoint T(auxiliary); + CNOT(target, auxiliary); + T(auxiliary); + + // The probability of measuring |+⟩ state on the auxiliary qubit + // is 3/4. + AssertProb( + [PauliX], [auxiliary], Zero, 3. / 4., + "Error: the probability to measure |+⟩ in the first + auxiliary must be 3/4", 1e-10); - // If we get measurement outcome Zero, we prepare the required state - let outcome = Measure([PauliX], [ancilla]); + // If we get the measurement outcome Zero, we prepare the + // required state. + let outcome = Measure([PauliX], [auxiliary]); } - until( outcome == Zero ) + until (outcome == Zero) fixup { - // Bring ancilla and target back to |+⟩ state - if( outcome == One ) { - Z(ancilla); + // Bring the auxiliary and target qubits back to |+⟩ state. + if (outcome == One) { + Z(auxiliary); X(target); H(target); } } - // Return ancilla back to Zero state - H(ancilla); + // Return the auxiliary qubit back to the Zero state. + H(auxiliary); } } ``` - -Notable programmatic features shown in this operation are a more complex `fixup` part of the loop which involves quantum operations, and the use of `AssertProb` statements to ascertain the probability of measuring the quantum state at certain specified points in the program. See also [Testing and debugging](xref:microsoft.quantum.techniques.testing-and-debugging) for more information about `Assert` and `AssertProb` statements. + +Notable programmatic features shown in this operation are a more complex `fixup` part of the loop, which involves quantum operations, and the use of `AssertProb` statements to ascertain the probability of measuring the quantum state at certain specified points in the program. +See also [Testing and debugging](xref:microsoft.quantum.techniques.testing-and-debugging) for more information about the [`Assert`](xref:microsoft.quantum.intrinsic.assert) and [`AssertProb`](xref:microsoft.quantum.intrinsic.assertprob) operations. diff --git a/articles/welcome.md b/articles/welcome.md index 1e23cc995..eeccc90a2 100644 --- a/articles/welcome.md +++ b/articles/welcome.md @@ -10,7 +10,9 @@ ms.topic: overview # Get started with the Quantum Development Kit (QDK) -Welcome to the Microsoft Quantum Development Kit! Here, you will find all the tools you need to learn about quantum programming with Q#. To guide you in learning quantum computing with Q#, we provide this Getting Started Guide, a journey guide for both those of you who want to start coding quantum programs, and people who are not yet ready to start coding but want to learn more about Q# and quantum programming. +Welcome to the Microsoft Quantum Development Kit! Here, you will find all the tools you need to learn about quantum programming with Q#. To guide you in learning quantum computing with Q#, we provide this Getting Started Guide, a guide for those of you who want to start coding quantum programs, and people who are not yet ready to start coding but want to learn more about Q# and quantum programming. + +If you are ready to start coding, [install the QDK now](xref:microsoft.quantum.install). ## Questions about quantum computing @@ -49,9 +51,8 @@ The Getting Started guides and articles above are meant to guide both the coder * Explore our [Q# samples](https://docs.microsoft.com/samples/browse/?languages=qsharp) and discover the problems you can solve with quantum computing. * Develop on a local machine with the host programming language and development environment of your choice: - * Develop with [Python](xref:microsoft.quantum.install#develop-with-python) - * Develop with [Visual Studio](xref:microsoft.quantum.install#develop-with-c-on-windows-using-visual-studio) - * Develop with [Visual Studio Code](xref:microsoft.quantum.install#develop-with-c-using-visual-studio-code) - * Develop with [Jupyter Notebooks](xref:microsoft.quantum.install#develop-with-jupyter-notebooks) + * Develop with [Q# + Python](xref:microsoft.quantum.install.python) + * Develop with [Q# + C#](xref:microsoft.quantum.install.cs) + * Develop with [Q# Jupyter Notebooks](xref:microsoft.quantum.install.jupyter) * Become part of the Microsoft Quantum community by contributing to the [QDK](xref:microsoft.quantum.contributing) open source project.