qsharp-lang 0.1.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +21 -0
- package/README.md +74 -0
- package/dist/browser.d.ts +26 -0
- package/dist/browser.js +156 -0
- package/dist/cancellation.d.ts +10 -0
- package/dist/cancellation.js +31 -0
- package/dist/compiler/common.d.ts +31 -0
- package/dist/compiler/common.js +47 -0
- package/dist/compiler/compiler.d.ts +28 -0
- package/dist/compiler/compiler.js +62 -0
- package/dist/compiler/events.d.ts +54 -0
- package/dist/compiler/events.js +92 -0
- package/dist/compiler/worker-browser.d.ts +1 -0
- package/dist/compiler/worker-browser.js +43 -0
- package/dist/compiler/worker-node.d.ts +1 -0
- package/dist/compiler/worker-node.js +41 -0
- package/dist/compiler/worker-proxy.d.ts +7 -0
- package/dist/compiler/worker-proxy.js +16 -0
- package/dist/debug-service/debug-service.d.ts +35 -0
- package/dist/debug-service/debug-service.js +136 -0
- package/dist/debug-service/worker-browser.d.ts +1 -0
- package/dist/debug-service/worker-browser.js +32 -0
- package/dist/debug-service/worker-node.d.ts +1 -0
- package/dist/debug-service/worker-node.js +30 -0
- package/dist/debug-service/worker-proxy.d.ts +7 -0
- package/dist/debug-service/worker-proxy.js +22 -0
- package/dist/katas-content.generated.d.ts +61 -0
- package/dist/katas-content.generated.js +2499 -0
- package/dist/katas.d.ts +55 -0
- package/dist/katas.js +16 -0
- package/dist/language-service/language-service.d.ts +48 -0
- package/dist/language-service/language-service.js +85 -0
- package/dist/language-service/worker-browser.d.ts +1 -0
- package/dist/language-service/worker-browser.js +32 -0
- package/dist/language-service/worker-node.d.ts +1 -0
- package/dist/language-service/worker-node.js +30 -0
- package/dist/language-service/worker-proxy.d.ts +6 -0
- package/dist/language-service/worker-proxy.js +20 -0
- package/dist/log.d.ts +33 -0
- package/dist/log.js +92 -0
- package/dist/main.d.ts +11 -0
- package/dist/main.js +82 -0
- package/dist/samples.generated.d.ts +6 -0
- package/dist/samples.generated.js +62 -0
- package/dist/vsdiagnostic.d.ts +27 -0
- package/dist/vsdiagnostic.js +117 -0
- package/dist/worker-proxy.d.ts +95 -0
- package/dist/worker-proxy.js +226 -0
- package/lib/node/qsc_wasm.cjs +1010 -0
- package/lib/node/qsc_wasm.d.cts +266 -0
- package/lib/node/qsc_wasm_bg.wasm +0 -0
- package/lib/web/qsc_wasm.d.ts +328 -0
- package/lib/web/qsc_wasm.js +1026 -0
- package/lib/web/qsc_wasm_bg.wasm +0 -0
- package/package.json +35 -0
|
@@ -0,0 +1,2499 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
"katas": [
|
|
3
|
+
{
|
|
4
|
+
"id": "getting_started",
|
|
5
|
+
"title": "Getting Started",
|
|
6
|
+
"sections": [
|
|
7
|
+
{
|
|
8
|
+
"type": "lesson",
|
|
9
|
+
"id": "getting_started__welcome",
|
|
10
|
+
"title": "Welcome to Quantum Katas",
|
|
11
|
+
"items": [
|
|
12
|
+
{
|
|
13
|
+
"type": "text-content",
|
|
14
|
+
"asHtml": "<p>kaˑ ta | kah-tuh\n<em>The japanese word for "form", a pattern of learning and practicing new skills.</em></p>\n<style>\n.transparent {\n background: rgba(0, 0, 0, 0.0) !important;\n}\n</style>\n<table>\n <tbody>\n <tr class=\"transparent\" style=\"border:none;\">\n <td rowspan=\"2\" style=\"border:none;\">\n<svg width=\"60\" height=\"60\" viewBox=\"0 0 60 60\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M9.8217 47.3824L24.8211 56.6477C28.0044 58.614 31.9943 58.614 35.1776 56.6477L50.1776 47.3823C53.1025 45.5756 54.9447 42.2482 54.9988 38.8089L54.9998 38.7205L55 38.6532V21.4635C55 17.892 53.1703 14.5804 50.1756 12.7319L35.1756 3.47308C32.0922 1.56982 28.2527 1.51086 25.1224 3.29619C21.6795 5.40493 18.2269 7.53883 14.7882 9.66472C13.1339 10.6874 11.4796 11.7102 9.82439 12.7312C6.82974 14.5797 5 17.8913 5 21.4628V38.6525C5 42.2229 6.82857 45.5336 9.8217 47.3824ZM26.6114 39.2349L17.9869 44.7687C16.3555 45.8154 14.288 45.8453 12.6282 44.8461L11.6711 44.2646C9.74699 43.0761 8.57144 40.9477 8.57144 38.6525V21.4628C8.57144 19.1672 9.74734 17.0386 11.672 15.8502C13.3329 14.8257 14.9905 13.8008 16.6456 12.7776L16.6473 12.7766C17.8068 12.0597 18.9658 11.3432 20.1244 10.6277C20.0405 11.1621 19.9973 11.7071 19.9973 12.2581V25.4847H20.0007V29.4C20.0007 32.9703 21.8293 36.281 24.8225 38.1299L26.6114 39.2349ZM51.4286 21.4635V31.1833C51.0515 30.8728 50.6487 30.5893 50.2222 30.3364L38.5843 23.4349L35.1764 21.3313C31.9944 19.3672 28.0071 19.3672 24.8251 21.3313L23.5687 22.1068V12.2581C23.5687 9.98662 24.7051 7.8762 26.5751 6.65704L26.9077 6.45332C28.9117 5.33069 31.3592 5.37674 33.3272 6.59151L48.3272 15.8503C50.2523 17.0386 51.4286 19.1675 51.4286 21.4635ZM36.4287 29.3966C36.4287 31.6919 35.2532 33.8202 33.329 35.0087L29.9944 37.0644L26.6718 35.012C24.7477 33.8235 23.5722 31.6952 23.5722 29.4V26.3641L26.6736 24.4497C28.7191 23.1871 31.2824 23.1871 33.3279 24.4497L36.4287 26.3637V29.3966ZM48.3282 44.2645L33.3282 53.5299C31.2818 54.7939 28.7169 54.7939 26.6705 53.5299L18.591 48.5391C19.0369 48.35 19.4708 48.1216 19.888 47.854L31.6969 40.2771L35.1784 38.1265C38.1715 36.2777 40.0001 32.967 40.0001 29.3966V28.4897L48.4278 33.4875C50.2616 34.575 51.3991 36.5642 51.4282 38.7242C51.4028 40.9278 50.201 43.1077 48.3282 44.2645Z\" fill=\"url(#paint0_linear_21_1848)\"/>\n<defs>\n<linearGradient id=\"paint0_linear_21_1848\" x1=\"15.7843\" y1=\"7.90763\" x2=\"43.8968\" y2=\"52.1059\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"0.538864\" stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n</defs>\n</svg>\n\n</td>\n <td style=\"border:none;\">\n <b>Self-paced AI-assisted learning</b>\n </td>\n </tr>\n <tr class=\"transparent\" style=\"border:none;\">\n <td style=\"border:none;\">\n Quantum katas are self-paced learning tutorials assisted by Copilot in Azure Quantum.\n </td>\n </tr>\n <tr class=\"transparent\" style=\"border:none;\">\n <td rowspan=\"2\" style=\"border:none;\">\n<svg width=\"60\" height=\"60\" viewBox=\"0 0 60 60\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M39.2767 30.3697C39.2767 31.3851 38.5022 32.5816 36.635 33.597C34.8158 34.5863 32.2172 35.2368 29.2785 35.2368C26.3397 35.2368 23.7411 34.5863 21.922 33.597C20.0547 32.5816 19.2803 31.3851 19.2803 30.3697C19.2803 29.3543 20.0547 28.1579 21.922 27.1424C23.7411 26.1532 26.3397 25.5027 29.2785 25.5027C32.2172 25.5027 34.8158 26.1532 36.635 27.1424C38.5022 28.1579 39.2767 29.3543 39.2767 30.3697Z\" stroke=\"url(#paint0_linear_21_1849)\" stroke-width=\"2.5\"/>\n<path d=\"M29.4818 40.2027C28.4664 40.2027 27.27 39.4282 26.2545 37.561C25.2653 35.7418 24.6148 33.1432 24.6148 30.2045C24.6148 27.2657 25.2653 24.6671 26.2545 22.848C27.27 20.9808 28.4665 20.2063 29.4818 20.2063C30.4972 20.2063 31.6937 20.9808 32.7091 22.848C33.6984 24.6671 34.3489 27.2657 34.3489 30.2045C34.3489 33.1432 33.6984 35.7418 32.7091 37.561C31.6937 39.4282 30.4972 40.2027 29.4818 40.2027Z\" stroke=\"url(#paint1_linear_21_1849)\" stroke-width=\"2.5\"/>\n<circle cx=\"29.5133\" cy=\"30.514\" r=\"1.70516\" stroke=\"url(#paint2_linear_21_1849)\" stroke-width=\"2\"/>\n<rect x=\"14.4272\" y=\"15.4275\" width=\"29.9456\" height=\"29.9456\" rx=\"2.25\" stroke=\"url(#paint3_linear_21_1849)\" stroke-width=\"3.5\"/>\n<path d=\"M33.7385 56.9989C33.7385 57.9654 34.522 58.7489 35.4885 58.7489C36.455 58.7489 37.2385 57.9654 37.2385 56.9989L33.7385 56.9989ZM33.7385 49.6212L33.7385 56.9989L37.2385 56.9989L37.2385 49.6212L33.7385 49.6212Z\" fill=\"url(#paint4_linear_21_1849)\"/>\n<path d=\"M27.5173 56.9989C27.5173 57.9654 28.3008 58.7489 29.2673 58.7489C30.2338 58.7489 31.0173 57.9654 31.0173 56.9989L27.5173 56.9989ZM27.5173 49.6212L27.5173 56.9989L31.0173 56.9989L31.0173 49.6212L27.5173 49.6212Z\" fill=\"url(#paint5_linear_21_1849)\"/>\n<path d=\"M21.2961 56.9989C21.2961 57.9654 22.0796 58.7489 23.0461 58.7489C24.0126 58.7489 24.7961 57.9654 24.7961 56.9989L21.2961 56.9989ZM21.2961 49.6212L21.2961 56.9989L24.7961 56.9989L24.7961 49.6212L21.2961 49.6212Z\" fill=\"url(#paint6_linear_21_1849)\"/>\n<path d=\"M56 37.548C56.9665 37.548 57.75 36.7645 57.75 35.798C57.75 34.8315 56.9665 34.048 56 34.048V37.548ZM48.6223 37.548H56V34.048H48.6223V37.548Z\" fill=\"url(#paint7_linear_21_1849)\"/>\n<path d=\"M56 31.3267C56.9665 31.3267 57.75 30.5432 57.75 29.5767C57.75 28.6102 56.9665 27.8267 56 27.8267V31.3267ZM48.6223 31.3267H56V27.8267H48.6223V31.3267Z\" fill=\"url(#paint8_linear_21_1849)\"/>\n<path d=\"M56 25.1053C56.9665 25.1053 57.75 24.3218 57.75 23.3553C57.75 22.3888 56.9665 21.6053 56 21.6053V25.1053ZM48.6223 25.1053H56V21.6053H48.6223V25.1053Z\" fill=\"url(#paint9_linear_21_1849)\"/>\n<path d=\"M2.99998 21.6051C2.03348 21.6051 1.24998 22.3886 1.24998 23.3551C1.24998 24.3216 2.03348 25.1051 2.99998 25.1051V21.6051ZM10.3777 21.6051H2.99998V25.1051H10.3777V21.6051Z\" fill=\"url(#paint10_linear_21_1849)\"/>\n<path d=\"M2.99998 27.8263C2.03348 27.8263 1.24998 28.6098 1.24998 29.5763C1.24998 30.5428 2.03348 31.3263 2.99998 31.3263V27.8263ZM10.3777 27.8263H2.99998V31.3263H10.3777V27.8263Z\" fill=\"url(#paint11_linear_21_1849)\"/>\n<path d=\"M2.99998 34.0472C2.03348 34.0472 1.24998 34.8307 1.24998 35.7972C1.24998 36.7637 2.03348 37.5472 2.99998 37.5472V34.0472ZM10.3777 34.0472H2.99998V37.5472H10.3777V34.0472Z\" fill=\"url(#paint12_linear_21_1849)\"/>\n<path d=\"M37.2385 3.99998C37.2385 3.03348 36.455 2.24998 35.4885 2.24998C34.522 2.24998 33.7385 3.03348 33.7385 3.99998L37.2385 3.99998ZM37.2385 11.3777L37.2385 3.99998L33.7385 3.99998L33.7385 11.3777L37.2385 11.3777Z\" fill=\"url(#paint13_linear_21_1849)\"/>\n<path d=\"M31.0173 3.99998C31.0173 3.03348 30.2338 2.24998 29.2673 2.24998C28.3008 2.24998 27.5173 3.03348 27.5173 3.99998L31.0173 3.99998ZM31.0173 11.3777L31.0173 3.99998L27.5173 3.99998L27.5173 11.3777L31.0173 11.3777Z\" fill=\"url(#paint14_linear_21_1849)\"/>\n<path d=\"M24.7961 3.99998C24.7961 3.03348 24.0126 2.24998 23.0461 2.24998C22.0796 2.24998 21.2961 3.03348 21.2961 3.99998L24.7961 3.99998ZM24.7961 11.3777L24.7961 3.99998L21.2961 3.99998L21.2961 11.3777L24.7961 11.3777Z\" fill=\"url(#paint15_linear_21_1849)\"/>\n<defs>\n<linearGradient id=\"paint0_linear_21_1849\" x1=\"29.2785\" y1=\"24.2527\" x2=\"29.2785\" y2=\"36.4868\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint1_linear_21_1849\" x1=\"35.5989\" y1=\"30.2045\" x2=\"23.3648\" y2=\"30.2045\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint2_linear_21_1849\" x1=\"29.5133\" y1=\"27.8088\" x2=\"29.5133\" y2=\"33.2192\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint3_linear_21_1849\" x1=\"13.3685\" y1=\"14.7144\" x2=\"43.7833\" y2=\"46.8572\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint4_linear_21_1849\" x1=\"38.0652\" y1=\"55.2713\" x2=\"35.5501\" y2=\"52.385\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint5_linear_21_1849\" x1=\"31.844\" y1=\"55.2713\" x2=\"29.3289\" y2=\"52.385\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint6_linear_21_1849\" x1=\"25.6228\" y1=\"55.2713\" x2=\"23.1077\" y2=\"52.385\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint7_linear_21_1849\" x1=\"54.2724\" y1=\"33.2213\" x2=\"51.3861\" y2=\"35.7364\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint8_linear_21_1849\" x1=\"54.2724\" y1=\"27\" x2=\"51.3861\" y2=\"29.5151\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint9_linear_21_1849\" x1=\"54.2724\" y1=\"20.7787\" x2=\"51.3861\" y2=\"23.2937\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint10_linear_21_1849\" x1=\"4.72757\" y1=\"25.9318\" x2=\"7.61388\" y2=\"23.4167\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint11_linear_21_1849\" x1=\"4.72757\" y1=\"32.153\" x2=\"7.61388\" y2=\"29.6379\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint12_linear_21_1849\" x1=\"4.72757\" y1=\"38.3739\" x2=\"7.61388\" y2=\"35.8588\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint13_linear_21_1849\" x1=\"32.9119\" y1=\"5.72757\" x2=\"35.4269\" y2=\"8.61388\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint14_linear_21_1849\" x1=\"26.6907\" y1=\"5.72757\" x2=\"29.2057\" y2=\"8.61388\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint15_linear_21_1849\" x1=\"20.4695\" y1=\"5.72757\" x2=\"22.9845\" y2=\"8.61388\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n</defs>\n</svg>\n\n</td>\n <td style=\"border:none;\">\n <b>Focused on quantum computing and programming</b>\n </td>\n </tr>\n <tr class=\"transparent\" style=\"border:none;\">\n <td style=\"border:none;\">\n The Quantum katas focus on teaching quantum computing concepts and quantum programming using the Q# language.\n </td>\n </tr>\n <tr class=\"transparent\" style=\"border:none;\">\n <td rowspan=\"2\" style=\"border:none;\">\n<svg width=\"60\" height=\"60\" viewBox=\"0 0 60 60\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<rect x=\"6.5\" y=\"4.5\" width=\"46.4629\" height=\"51.0428\" rx=\"1.5\" stroke=\"url(#paint0_linear_21_1847)\" stroke-width=\"3\"/>\n<line x1=\"6.83203\" y1=\"11.5767\" x2=\"53.547\" y2=\"11.5767\" stroke=\"url(#paint1_linear_21_1847)\" stroke-width=\"3\"/>\n<circle cx=\"10.0383\" cy=\"8.03779\" r=\"1.37397\" fill=\"url(#paint2_linear_21_1847)\"/>\n<circle cx=\"14.6179\" cy=\"8.03779\" r=\"1.37397\" fill=\"url(#paint3_linear_21_1847)\"/>\n<circle cx=\"19.1977\" cy=\"8.03779\" r=\"1.37397\" fill=\"url(#paint4_linear_21_1847)\"/>\n<path d=\"M21 18L16 21.1818L21 25\" stroke=\"url(#paint5_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M32 25L36 21.8182L32 18\" stroke=\"url(#paint6_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M24.5718 16.5952L27.7067 26\" stroke=\"url(#paint7_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M15.0837 33.8157L20.2104 33.8552\" stroke=\"url(#paint8_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M15.0078 39L20.1344 39.0395\" stroke=\"url(#paint9_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M15.0078 44L20.1344 44.0395\" stroke=\"url(#paint10_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M23 33.8684L39.0133 34.0001\" stroke=\"url(#paint11_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M23.0833 39L39.0966 39.1317\" stroke=\"url(#paint12_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M23.0833 44L39.0966 44.1317\" stroke=\"url(#paint13_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<defs>\n<linearGradient id=\"paint0_linear_21_1847\" x1=\"29.7315\" y1=\"3\" x2=\"29.7315\" y2=\"57.0428\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint1_linear_21_1847\" x1=\"30.1895\" y1=\"13.0767\" x2=\"30.1895\" y2=\"14.0767\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint2_linear_21_1847\" x1=\"10.0383\" y1=\"6.66382\" x2=\"10.0383\" y2=\"9.41176\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#7F4CD7\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint3_linear_21_1847\" x1=\"14.6179\" y1=\"6.66382\" x2=\"14.6179\" y2=\"9.41176\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#7F4CD7\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint4_linear_21_1847\" x1=\"19.1977\" y1=\"6.66382\" x2=\"19.1977\" y2=\"9.41176\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#7F4CD7\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint5_linear_21_1847\" x1=\"18.5\" y1=\"18\" x2=\"18.5\" y2=\"25\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint6_linear_21_1847\" x1=\"34\" y1=\"25\" x2=\"34\" y2=\"18\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint7_linear_21_1847\" x1=\"26.1392\" y1=\"21.2976\" x2=\"25.1906\" y2=\"21.6138\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint8_linear_21_1847\" x1=\"17.6394\" y1=\"34.8354\" x2=\"17.6317\" y2=\"35.8354\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint9_linear_21_1847\" x1=\"17.5634\" y1=\"40.0197\" x2=\"17.5557\" y2=\"41.0197\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint10_linear_21_1847\" x1=\"17.5634\" y1=\"45.0197\" x2=\"17.5557\" y2=\"46.0197\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint11_linear_21_1847\" x1=\"30.9994\" y1=\"34.9342\" x2=\"30.9912\" y2=\"35.9342\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint12_linear_21_1847\" x1=\"31.0827\" y1=\"40.0658\" x2=\"31.0745\" y2=\"41.0658\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint13_linear_21_1847\" x1=\"31.0827\" y1=\"45.0658\" x2=\"31.0745\" y2=\"46.0658\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n</defs>\n</svg>\n\n</td>\n <td style=\"border:none;\">\n <b>Tutorials with theory and interactive hands on exercises</b>\n </td>\n </tr>\n <tr class=\"transparent\" style=\"border:none;\">\n <td style=\"border:none;\">\n Each tutorial includes relevant theory and supporting interactive exercises designed to test knowledge.\n </td>\n </tr>\n </tbody>\n</table>",
|
|
15
|
+
"asMarkdown": "\nkaˑ ta | kah-tuh\n_The japanese word for \"form\", a pattern of learning and practicing new skills._\n\n<style>\n.transparent {\n background: rgba(0, 0, 0, 0.0) !important;\n}\n</style>\n<table>\n <tbody>\n <tr class=\"transparent\" style=\"border:none;\">\n <td rowspan=\"2\" style=\"border:none;\">\n<svg width=\"60\" height=\"60\" viewBox=\"0 0 60 60\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M9.8217 47.3824L24.8211 56.6477C28.0044 58.614 31.9943 58.614 35.1776 56.6477L50.1776 47.3823C53.1025 45.5756 54.9447 42.2482 54.9988 38.8089L54.9998 38.7205L55 38.6532V21.4635C55 17.892 53.1703 14.5804 50.1756 12.7319L35.1756 3.47308C32.0922 1.56982 28.2527 1.51086 25.1224 3.29619C21.6795 5.40493 18.2269 7.53883 14.7882 9.66472C13.1339 10.6874 11.4796 11.7102 9.82439 12.7312C6.82974 14.5797 5 17.8913 5 21.4628V38.6525C5 42.2229 6.82857 45.5336 9.8217 47.3824ZM26.6114 39.2349L17.9869 44.7687C16.3555 45.8154 14.288 45.8453 12.6282 44.8461L11.6711 44.2646C9.74699 43.0761 8.57144 40.9477 8.57144 38.6525V21.4628C8.57144 19.1672 9.74734 17.0386 11.672 15.8502C13.3329 14.8257 14.9905 13.8008 16.6456 12.7776L16.6473 12.7766C17.8068 12.0597 18.9658 11.3432 20.1244 10.6277C20.0405 11.1621 19.9973 11.7071 19.9973 12.2581V25.4847H20.0007V29.4C20.0007 32.9703 21.8293 36.281 24.8225 38.1299L26.6114 39.2349ZM51.4286 21.4635V31.1833C51.0515 30.8728 50.6487 30.5893 50.2222 30.3364L38.5843 23.4349L35.1764 21.3313C31.9944 19.3672 28.0071 19.3672 24.8251 21.3313L23.5687 22.1068V12.2581C23.5687 9.98662 24.7051 7.8762 26.5751 6.65704L26.9077 6.45332C28.9117 5.33069 31.3592 5.37674 33.3272 6.59151L48.3272 15.8503C50.2523 17.0386 51.4286 19.1675 51.4286 21.4635ZM36.4287 29.3966C36.4287 31.6919 35.2532 33.8202 33.329 35.0087L29.9944 37.0644L26.6718 35.012C24.7477 33.8235 23.5722 31.6952 23.5722 29.4V26.3641L26.6736 24.4497C28.7191 23.1871 31.2824 23.1871 33.3279 24.4497L36.4287 26.3637V29.3966ZM48.3282 44.2645L33.3282 53.5299C31.2818 54.7939 28.7169 54.7939 26.6705 53.5299L18.591 48.5391C19.0369 48.35 19.4708 48.1216 19.888 47.854L31.6969 40.2771L35.1784 38.1265C38.1715 36.2777 40.0001 32.967 40.0001 29.3966V28.4897L48.4278 33.4875C50.2616 34.575 51.3991 36.5642 51.4282 38.7242C51.4028 40.9278 50.201 43.1077 48.3282 44.2645Z\" fill=\"url(#paint0_linear_21_1848)\"/>\n<defs>\n<linearGradient id=\"paint0_linear_21_1848\" x1=\"15.7843\" y1=\"7.90763\" x2=\"43.8968\" y2=\"52.1059\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"0.538864\" stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n</defs>\n</svg>\n\n</td>\n <td style=\"border:none;\">\n <b>Self-paced AI-assisted learning</b>\n </td>\n </tr>\n <tr class=\"transparent\" style=\"border:none;\">\n <td style=\"border:none;\">\n Quantum katas are self-paced learning tutorials assisted by Copilot in Azure Quantum.\n </td>\n </tr>\n <tr class=\"transparent\" style=\"border:none;\">\n <td rowspan=\"2\" style=\"border:none;\">\n<svg width=\"60\" height=\"60\" viewBox=\"0 0 60 60\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M39.2767 30.3697C39.2767 31.3851 38.5022 32.5816 36.635 33.597C34.8158 34.5863 32.2172 35.2368 29.2785 35.2368C26.3397 35.2368 23.7411 34.5863 21.922 33.597C20.0547 32.5816 19.2803 31.3851 19.2803 30.3697C19.2803 29.3543 20.0547 28.1579 21.922 27.1424C23.7411 26.1532 26.3397 25.5027 29.2785 25.5027C32.2172 25.5027 34.8158 26.1532 36.635 27.1424C38.5022 28.1579 39.2767 29.3543 39.2767 30.3697Z\" stroke=\"url(#paint0_linear_21_1849)\" stroke-width=\"2.5\"/>\n<path d=\"M29.4818 40.2027C28.4664 40.2027 27.27 39.4282 26.2545 37.561C25.2653 35.7418 24.6148 33.1432 24.6148 30.2045C24.6148 27.2657 25.2653 24.6671 26.2545 22.848C27.27 20.9808 28.4665 20.2063 29.4818 20.2063C30.4972 20.2063 31.6937 20.9808 32.7091 22.848C33.6984 24.6671 34.3489 27.2657 34.3489 30.2045C34.3489 33.1432 33.6984 35.7418 32.7091 37.561C31.6937 39.4282 30.4972 40.2027 29.4818 40.2027Z\" stroke=\"url(#paint1_linear_21_1849)\" stroke-width=\"2.5\"/>\n<circle cx=\"29.5133\" cy=\"30.514\" r=\"1.70516\" stroke=\"url(#paint2_linear_21_1849)\" stroke-width=\"2\"/>\n<rect x=\"14.4272\" y=\"15.4275\" width=\"29.9456\" height=\"29.9456\" rx=\"2.25\" stroke=\"url(#paint3_linear_21_1849)\" stroke-width=\"3.5\"/>\n<path d=\"M33.7385 56.9989C33.7385 57.9654 34.522 58.7489 35.4885 58.7489C36.455 58.7489 37.2385 57.9654 37.2385 56.9989L33.7385 56.9989ZM33.7385 49.6212L33.7385 56.9989L37.2385 56.9989L37.2385 49.6212L33.7385 49.6212Z\" fill=\"url(#paint4_linear_21_1849)\"/>\n<path d=\"M27.5173 56.9989C27.5173 57.9654 28.3008 58.7489 29.2673 58.7489C30.2338 58.7489 31.0173 57.9654 31.0173 56.9989L27.5173 56.9989ZM27.5173 49.6212L27.5173 56.9989L31.0173 56.9989L31.0173 49.6212L27.5173 49.6212Z\" fill=\"url(#paint5_linear_21_1849)\"/>\n<path d=\"M21.2961 56.9989C21.2961 57.9654 22.0796 58.7489 23.0461 58.7489C24.0126 58.7489 24.7961 57.9654 24.7961 56.9989L21.2961 56.9989ZM21.2961 49.6212L21.2961 56.9989L24.7961 56.9989L24.7961 49.6212L21.2961 49.6212Z\" fill=\"url(#paint6_linear_21_1849)\"/>\n<path d=\"M56 37.548C56.9665 37.548 57.75 36.7645 57.75 35.798C57.75 34.8315 56.9665 34.048 56 34.048V37.548ZM48.6223 37.548H56V34.048H48.6223V37.548Z\" fill=\"url(#paint7_linear_21_1849)\"/>\n<path d=\"M56 31.3267C56.9665 31.3267 57.75 30.5432 57.75 29.5767C57.75 28.6102 56.9665 27.8267 56 27.8267V31.3267ZM48.6223 31.3267H56V27.8267H48.6223V31.3267Z\" fill=\"url(#paint8_linear_21_1849)\"/>\n<path d=\"M56 25.1053C56.9665 25.1053 57.75 24.3218 57.75 23.3553C57.75 22.3888 56.9665 21.6053 56 21.6053V25.1053ZM48.6223 25.1053H56V21.6053H48.6223V25.1053Z\" fill=\"url(#paint9_linear_21_1849)\"/>\n<path d=\"M2.99998 21.6051C2.03348 21.6051 1.24998 22.3886 1.24998 23.3551C1.24998 24.3216 2.03348 25.1051 2.99998 25.1051V21.6051ZM10.3777 21.6051H2.99998V25.1051H10.3777V21.6051Z\" fill=\"url(#paint10_linear_21_1849)\"/>\n<path d=\"M2.99998 27.8263C2.03348 27.8263 1.24998 28.6098 1.24998 29.5763C1.24998 30.5428 2.03348 31.3263 2.99998 31.3263V27.8263ZM10.3777 27.8263H2.99998V31.3263H10.3777V27.8263Z\" fill=\"url(#paint11_linear_21_1849)\"/>\n<path d=\"M2.99998 34.0472C2.03348 34.0472 1.24998 34.8307 1.24998 35.7972C1.24998 36.7637 2.03348 37.5472 2.99998 37.5472V34.0472ZM10.3777 34.0472H2.99998V37.5472H10.3777V34.0472Z\" fill=\"url(#paint12_linear_21_1849)\"/>\n<path d=\"M37.2385 3.99998C37.2385 3.03348 36.455 2.24998 35.4885 2.24998C34.522 2.24998 33.7385 3.03348 33.7385 3.99998L37.2385 3.99998ZM37.2385 11.3777L37.2385 3.99998L33.7385 3.99998L33.7385 11.3777L37.2385 11.3777Z\" fill=\"url(#paint13_linear_21_1849)\"/>\n<path d=\"M31.0173 3.99998C31.0173 3.03348 30.2338 2.24998 29.2673 2.24998C28.3008 2.24998 27.5173 3.03348 27.5173 3.99998L31.0173 3.99998ZM31.0173 11.3777L31.0173 3.99998L27.5173 3.99998L27.5173 11.3777L31.0173 11.3777Z\" fill=\"url(#paint14_linear_21_1849)\"/>\n<path d=\"M24.7961 3.99998C24.7961 3.03348 24.0126 2.24998 23.0461 2.24998C22.0796 2.24998 21.2961 3.03348 21.2961 3.99998L24.7961 3.99998ZM24.7961 11.3777L24.7961 3.99998L21.2961 3.99998L21.2961 11.3777L24.7961 11.3777Z\" fill=\"url(#paint15_linear_21_1849)\"/>\n<defs>\n<linearGradient id=\"paint0_linear_21_1849\" x1=\"29.2785\" y1=\"24.2527\" x2=\"29.2785\" y2=\"36.4868\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint1_linear_21_1849\" x1=\"35.5989\" y1=\"30.2045\" x2=\"23.3648\" y2=\"30.2045\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint2_linear_21_1849\" x1=\"29.5133\" y1=\"27.8088\" x2=\"29.5133\" y2=\"33.2192\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint3_linear_21_1849\" x1=\"13.3685\" y1=\"14.7144\" x2=\"43.7833\" y2=\"46.8572\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint4_linear_21_1849\" x1=\"38.0652\" y1=\"55.2713\" x2=\"35.5501\" y2=\"52.385\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint5_linear_21_1849\" x1=\"31.844\" y1=\"55.2713\" x2=\"29.3289\" y2=\"52.385\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint6_linear_21_1849\" x1=\"25.6228\" y1=\"55.2713\" x2=\"23.1077\" y2=\"52.385\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint7_linear_21_1849\" x1=\"54.2724\" y1=\"33.2213\" x2=\"51.3861\" y2=\"35.7364\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint8_linear_21_1849\" x1=\"54.2724\" y1=\"27\" x2=\"51.3861\" y2=\"29.5151\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint9_linear_21_1849\" x1=\"54.2724\" y1=\"20.7787\" x2=\"51.3861\" y2=\"23.2937\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint10_linear_21_1849\" x1=\"4.72757\" y1=\"25.9318\" x2=\"7.61388\" y2=\"23.4167\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint11_linear_21_1849\" x1=\"4.72757\" y1=\"32.153\" x2=\"7.61388\" y2=\"29.6379\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint12_linear_21_1849\" x1=\"4.72757\" y1=\"38.3739\" x2=\"7.61388\" y2=\"35.8588\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint13_linear_21_1849\" x1=\"32.9119\" y1=\"5.72757\" x2=\"35.4269\" y2=\"8.61388\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint14_linear_21_1849\" x1=\"26.6907\" y1=\"5.72757\" x2=\"29.2057\" y2=\"8.61388\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n<linearGradient id=\"paint15_linear_21_1849\" x1=\"20.4695\" y1=\"5.72757\" x2=\"22.9845\" y2=\"8.61388\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#A06ADF\"/>\n<stop offset=\"1\" stop-color=\"#3E72F8\"/>\n</linearGradient>\n</defs>\n</svg>\n\n</td>\n <td style=\"border:none;\">\n <b>Focused on quantum computing and programming</b>\n </td>\n </tr>\n <tr class=\"transparent\" style=\"border:none;\">\n <td style=\"border:none;\">\n The Quantum katas focus on teaching quantum computing concepts and quantum programming using the Q# language.\n </td>\n </tr>\n <tr class=\"transparent\" style=\"border:none;\">\n <td rowspan=\"2\" style=\"border:none;\">\n<svg width=\"60\" height=\"60\" viewBox=\"0 0 60 60\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<rect x=\"6.5\" y=\"4.5\" width=\"46.4629\" height=\"51.0428\" rx=\"1.5\" stroke=\"url(#paint0_linear_21_1847)\" stroke-width=\"3\"/>\n<line x1=\"6.83203\" y1=\"11.5767\" x2=\"53.547\" y2=\"11.5767\" stroke=\"url(#paint1_linear_21_1847)\" stroke-width=\"3\"/>\n<circle cx=\"10.0383\" cy=\"8.03779\" r=\"1.37397\" fill=\"url(#paint2_linear_21_1847)\"/>\n<circle cx=\"14.6179\" cy=\"8.03779\" r=\"1.37397\" fill=\"url(#paint3_linear_21_1847)\"/>\n<circle cx=\"19.1977\" cy=\"8.03779\" r=\"1.37397\" fill=\"url(#paint4_linear_21_1847)\"/>\n<path d=\"M21 18L16 21.1818L21 25\" stroke=\"url(#paint5_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M32 25L36 21.8182L32 18\" stroke=\"url(#paint6_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M24.5718 16.5952L27.7067 26\" stroke=\"url(#paint7_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M15.0837 33.8157L20.2104 33.8552\" stroke=\"url(#paint8_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M15.0078 39L20.1344 39.0395\" stroke=\"url(#paint9_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M15.0078 44L20.1344 44.0395\" stroke=\"url(#paint10_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M23 33.8684L39.0133 34.0001\" stroke=\"url(#paint11_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M23.0833 39L39.0966 39.1317\" stroke=\"url(#paint12_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<path d=\"M23.0833 44L39.0966 44.1317\" stroke=\"url(#paint13_linear_21_1847)\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n<defs>\n<linearGradient id=\"paint0_linear_21_1847\" x1=\"29.7315\" y1=\"3\" x2=\"29.7315\" y2=\"57.0428\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint1_linear_21_1847\" x1=\"30.1895\" y1=\"13.0767\" x2=\"30.1895\" y2=\"14.0767\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint2_linear_21_1847\" x1=\"10.0383\" y1=\"6.66382\" x2=\"10.0383\" y2=\"9.41176\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#7F4CD7\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint3_linear_21_1847\" x1=\"14.6179\" y1=\"6.66382\" x2=\"14.6179\" y2=\"9.41176\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#7F4CD7\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint4_linear_21_1847\" x1=\"19.1977\" y1=\"6.66382\" x2=\"19.1977\" y2=\"9.41176\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#7F4CD7\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint5_linear_21_1847\" x1=\"18.5\" y1=\"18\" x2=\"18.5\" y2=\"25\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint6_linear_21_1847\" x1=\"34\" y1=\"25\" x2=\"34\" y2=\"18\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint7_linear_21_1847\" x1=\"26.1392\" y1=\"21.2976\" x2=\"25.1906\" y2=\"21.6138\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint8_linear_21_1847\" x1=\"17.6394\" y1=\"34.8354\" x2=\"17.6317\" y2=\"35.8354\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint9_linear_21_1847\" x1=\"17.5634\" y1=\"40.0197\" x2=\"17.5557\" y2=\"41.0197\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint10_linear_21_1847\" x1=\"17.5634\" y1=\"45.0197\" x2=\"17.5557\" y2=\"46.0197\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint11_linear_21_1847\" x1=\"30.9994\" y1=\"34.9342\" x2=\"30.9912\" y2=\"35.9342\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint12_linear_21_1847\" x1=\"31.0827\" y1=\"40.0658\" x2=\"31.0745\" y2=\"41.0658\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n<linearGradient id=\"paint13_linear_21_1847\" x1=\"31.0827\" y1=\"45.0658\" x2=\"31.0745\" y2=\"46.0658\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#8661C5\"/>\n<stop offset=\"1\" stop-color=\"#1864F0\"/>\n</linearGradient>\n</defs>\n</svg>\n\n</td>\n <td style=\"border:none;\">\n <b>Tutorials with theory and interactive hands on exercises</b>\n </td>\n </tr>\n <tr class=\"transparent\" style=\"border:none;\">\n <td style=\"border:none;\">\n Each tutorial includes relevant theory and supporting interactive exercises designed to test knowledge.\n </td>\n </tr>\n </tbody>\n</table>"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"type": "exercise",
|
|
21
|
+
"id": "getting_started__flip_qubit",
|
|
22
|
+
"title": "Flip a Qubit",
|
|
23
|
+
"description": {
|
|
24
|
+
"type": "text-content",
|
|
25
|
+
"asHtml": "<p>Exercises are problems that you have to solve by writing Q# code. On each exercise, you will be presented with placeholder code that you will have to fill in with the correct solution.</p>\n<p><strong>Input:</strong> A qubit in the $|0\\rangle$ state.</p>\n<p><strong>Goal:</strong> Apply the X gate to the qubit, i.e., perform a "bit flip" to set the qubit into the $|1\\rangle$ state.</p>\n<details>\n<summary><strong>Need a hint?</strong></summary>\nFor some problems a hint will be provided to help you if you are stuck. For this exercise, read line number 3 in the code below.\n</details>\n",
|
|
26
|
+
"asMarkdown": "Exercises are problems that you have to solve by writing Q# code. On each exercise, you will be presented with placeholder code that you will have to fill in with the correct solution.\n\n**Input:** A qubit in the $|0\\rangle$ state.\n\n**Goal:** Apply the X gate to the qubit, i.e., perform a \"bit flip\" to set the qubit into the $|1\\rangle$ state.\n\n<details>\n<summary><strong>Need a hint?</strong></summary>\nFor some problems a hint will be provided to help you if you are stuck. For this exercise, read line number 3 in the code below.\n</details>\n"
|
|
27
|
+
},
|
|
28
|
+
"sourceIds": [
|
|
29
|
+
"KatasLibrary.qs",
|
|
30
|
+
"getting_started__flip_qubit__Verification.qs"
|
|
31
|
+
],
|
|
32
|
+
"placeholderCode": "namespace Kata {\n operation FlipQubit(q : Qubit): Unit is Adj + Ctl {\n // Uncomment the following line to solve this exercise.\n //X(q);\n }\n}",
|
|
33
|
+
"explainedSolution": {
|
|
34
|
+
"type": "explained-solution",
|
|
35
|
+
"items": [
|
|
36
|
+
{
|
|
37
|
+
"type": "text-content",
|
|
38
|
+
"asHtml": "<p>Once you have successfully implemented a solution or if you are stuck on a problem, you can consult our reference solution, which contains additional details on how to solve the exercise.</p>\n<p>For this exercise, you can solve the problem by simply using Q#'s <code>X</code> operation on the input qubit, which will perform a "bit flip" and set the qubit into the $|1\\rangle$ state.</p>\n",
|
|
39
|
+
"asMarkdown": "\nOnce you have successfully implemented a solution or if you are stuck on a problem, you can consult our reference solution, which contains additional details on how to solve the exercise.\n\nFor this exercise, you can solve the problem by simply using Q#'s `X` operation on the input qubit, which will perform a \"bit flip\" and set the qubit into the $|1\\rangle$ state."
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"type": "solution",
|
|
43
|
+
"id": "getting_started__flip_qubit_solution",
|
|
44
|
+
"code": "namespace Kata {\n operation FlipQubit(q : Qubit): Unit is Adj + Ctl {\n // Perform a \"bit flip\" on the qubit by applying the X gate.\n X(q);\n }\n}"
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"id": "qubit",
|
|
53
|
+
"title": "The Qubit",
|
|
54
|
+
"sections": [
|
|
55
|
+
{
|
|
56
|
+
"type": "lesson",
|
|
57
|
+
"id": "qubit__overview",
|
|
58
|
+
"title": "Overview",
|
|
59
|
+
"items": [
|
|
60
|
+
{
|
|
61
|
+
"type": "text-content",
|
|
62
|
+
"asHtml": "<p>This kata introduces you to one of the core concepts in quantum computing - the qubit, and its representation in mathematical notation and in Q# code.</p>\n<p><strong>This kata covers the following topics:</strong></p>\n<ul>\n<li>The concept of a qubit</li>\n<li>Superposition</li>\n<li>Vector representation of qubit states</li>\n<li>Dirac notation</li>\n<li>Relative and global phase</li>\n<li><code>Qubit</code> data type in Q#</li>\n<li>Visualizing the quantum state using <code>DumpMachine</code></li>\n</ul>\n<p><strong>What you should know to start working on this kata:</strong></p>\n<ul>\n<li>Complex arithmetic</li>\n<li>Linear algebra</li>\n</ul>\n",
|
|
63
|
+
"asMarkdown": "\nThis kata introduces you to one of the core concepts in quantum computing - the qubit, and its representation in mathematical notation and in Q# code.\n\n**This kata covers the following topics:**\n\n- The concept of a qubit\n- Superposition\n- Vector representation of qubit states\n- Dirac notation\n- Relative and global phase\n- `Qubit` data type in Q#\n- Visualizing the quantum state using `DumpMachine`\n\n**What you should know to start working on this kata:**\n\n- Complex arithmetic\n- Linear algebra"
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"type": "lesson",
|
|
69
|
+
"id": "qubit__concept",
|
|
70
|
+
"title": "The Concept of Qubit",
|
|
71
|
+
"items": [
|
|
72
|
+
{
|
|
73
|
+
"type": "text-content",
|
|
74
|
+
"asHtml": "<p>The basic building block of a classical computer is the bit - a single memory cell that is either in state $0$ or in state $1$. Similarly, the basic building block of a quantum computer is the quantum bit, or <strong>qubit</strong>. Like the classical bit, a qubit can be in state $0$ or in state $1$. Unlike the classical bit, however, the qubit isn't limited to just those two states - it may also be in a combination, or <strong>superposition</strong> of those states.</p>\n<blockquote>\n<p>A common misconception about quantum computing is that a qubit is always in state $1$ or state $0$, we just don't know which one until we "measure" it. That is not the case. A qubit in a superposition is in a linear combination of the states 0 and 1. When a qubit is measured, it is forced to collapse into one state or the other - in other words, measuring a qubit is a drastic process that changes its initial state.</p>\n</blockquote>\n<h2 id=\"matrix-representation\">Matrix Representation</h2>\n<p>The state of a qubit is represented by a complex vector of size 2:</p>\n<p>$$\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix}$$</p>\n<p>Here $\\alpha$ and $\\beta$ are complex numbers. $\\alpha$ represents how "close" the qubit is to state $0$, and $\\beta$ represents how "close" the qubit is to state $1$. This vector is normalized: $|\\alpha|^2 + |\\beta|^2 = 1$.\nα and β are known as the probability amplitudes of states 0 and 1, respectively.</p>\n<p>$\\alpha$ and $\\beta$ are known as the probability amplitudes of states $0$ and $1$, respectively.</p>\n<h2 id=\"basis-states\">Basis States</h2>\n<p>A qubit in state $0$ would be represented by the following vector:</p>\n<p>$$\\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix}$$</p>\n<p>Likewise, a qubit in state $1$ would be represented by this vector:</p>\n<p>$$\\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix}$$</p>\n<p>Note that you can use scalar multiplication and vector addition to express any qubit state $\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix}$ as a sum of these two vectors with certain probability amplitudes $\\alpha$ and $\\beta$, known as linear combination.</p>\n<p>$$\n\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} =\n\\begin{bmatrix} \\alpha \\\\ 0 \\end{bmatrix} + \\begin{bmatrix} 0 \\\\ \\beta \\end{bmatrix} =\n\\alpha \\cdot \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} + \\beta \\cdot \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix}\n$$</p>\n<p>Because of this, qubit states $0$ and $1$ are known as basis states. These two vectors have two properties.</p>\n<ol>\n<li>They are normalized.</li>\n</ol>\n<p>$$\n\\langle \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} , \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} \\rangle =\n\\langle \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} , \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} \\rangle = 1\n$$</p>\n<ol start=\"2\">\n<li>They are orthogonal to each other.</li>\n</ol>\n<p>$$\n\\langle \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} , \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} \\rangle =\n\\langle \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} , \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} \\rangle = 0\n$$</p>\n<blockquote>\n<p>As a reminder, $\\langle V , W \\rangle$ is the inner product of $V$ and $W$.</p>\n</blockquote>\n<p>This means that these vectors form an <strong>orthonormal basis</strong>. The basis of $\\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix}$ and $\\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix}$ is called the <strong>computational basis</strong>, also known as the <strong>canonical basis</strong>.</p>\n<blockquote>\n<p>There exist other orthonormal bases, for example, the <strong>Hadamard basis</strong>, formed by the vectors</p>\n<p>$$\\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} \\text{ and } \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ -\\frac{1}{\\sqrt{2}} \\end{bmatrix}$$</p>\n<p>You can check that these vectors are normalized, and orthogonal to each other. Any qubit state can be expressed as a linear combination of these vectors:</p>\n<p>$$\n\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} =\n\\frac{\\alpha + \\beta}{\\sqrt{2}} \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} +\n\\frac{\\alpha - \\beta}{\\sqrt{2}} \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ -\\frac{1}{\\sqrt{2}} \\end{bmatrix}\n$$</p>\n<p>The Hadamard basis is widely used in quantum computing, for example, in the <a href=\"https://en.wikipedia.org/wiki/BB84\" target=\"_blank\">BB84 quantum key distribution protocol</a>.</p>\n</blockquote>\n",
|
|
75
|
+
"asMarkdown": "\nThe basic building block of a classical computer is the bit - a single memory cell that is either in state $0$ or in state $1$. Similarly, the basic building block of a quantum computer is the quantum bit, or **qubit**. Like the classical bit, a qubit can be in state $0$ or in state $1$. Unlike the classical bit, however, the qubit isn't limited to just those two states - it may also be in a combination, or **superposition** of those states.\n\n> A common misconception about quantum computing is that a qubit is always in state $1$ or state $0$, we just don't know which one until we \"measure\" it. That is not the case. A qubit in a superposition is in a linear combination of the states 0 and 1. When a qubit is measured, it is forced to collapse into one state or the other - in other words, measuring a qubit is a drastic process that changes its initial state.\n\n## Matrix Representation\n\nThe state of a qubit is represented by a complex vector of size 2:\n\n$$\\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix}$$\n\nHere $\\alpha$ and $\\beta$ are complex numbers. $\\alpha$ represents how \"close\" the qubit is to state $0$, and $\\beta$ represents how \"close\" the qubit is to state $1$. This vector is normalized: $|\\alpha|^2 + |\\beta|^2 = 1$.\nα and β are known as the probability amplitudes of states 0 and 1, respectively.\n\n$\\alpha$ and $\\beta$ are known as the probability amplitudes of states $0$ and $1$, respectively.\n\n## Basis States\n\nA qubit in state $0$ would be represented by the following vector:\n\n$$\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$$\n\nLikewise, a qubit in state $1$ would be represented by this vector:\n\n$$\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$$\n\nNote that you can use scalar multiplication and vector addition to express any qubit state $\\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix}$ as a sum of these two vectors with certain probability amplitudes $\\alpha$ and $\\beta$, known as linear combination.\n\n$$\n\\begin{bmatrix} \\alpha \\\\\\ \\beta \\\\end{bmatrix} =\n\\begin{bmatrix} \\alpha \\\\\\ 0 \\end{bmatrix} + \\begin{bmatrix} 0 \\\\\\ \\beta \\\\end{bmatrix} =\n\\alpha \\cdot \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} + \\beta \\cdot \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}\n$$\n\nBecause of this, qubit states $0$ and $1$ are known as basis states. These two vectors have two properties.\n\n1. They are normalized.\n\n$$\n\\langle \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} , \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\rangle =\n\\langle \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} , \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} \\rangle = 1\n$$\n\n2. They are orthogonal to each other.\n\n$$\n\\langle \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} , \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} \\rangle =\n\\langle \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} , \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\\\rangle = 0\n$$\n\n> As a reminder, $\\langle V , W \\rangle$ is the inner product of $V$ and $W$.\n\nThis means that these vectors form an **orthonormal basis**. The basis of $\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$ and $\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$ is called the **computational basis**, also known as the **canonical basis**.\n\n> There exist other orthonormal bases, for example, the **Hadamard basis**, formed by the vectors\n>\n> $$\\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} \\text{ and } \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ -\\frac{1}{\\sqrt{2}} \\end{bmatrix}$$\n>\n> You can check that these vectors are normalized, and orthogonal to each other. Any qubit state can be expressed as a linear combination of these vectors:\n>\n> $$\n> \\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix} =\n> \\frac{\\alpha + \\beta}{\\sqrt{2}} \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} +\n> \\frac{\\alpha - \\beta}{\\sqrt{2}} \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ -\\frac{1}{\\sqrt{2}} \\end{bmatrix}\n> $$\n>\n> The Hadamard basis is widely used in quantum computing, for example, in the <a href=\"https://en.wikipedia.org/wiki/BB84\" target=\"_blank\">BB84 quantum key distribution protocol</a>."
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"type": "lesson",
|
|
81
|
+
"id": "qubit__dirac_notation",
|
|
82
|
+
"title": "Dirac Notation",
|
|
83
|
+
"items": [
|
|
84
|
+
{
|
|
85
|
+
"type": "text-content",
|
|
86
|
+
"asHtml": "<p>Dirac notation is a shorthand notation that eases writing quantum states and computing linear algebra. In Dirac notation, a vector is denoted by a symbol called a <strong>ket</strong>. For example, a qubit in state $0$ is represented by the ket $|0\\rangle$, and a qubit in state $1$ is represented by the ket $|1\\rangle$:</p>\n<table>\n <tr>\n <td>$$|0\\rangle = \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$$</td>\n <td>$$|1\\rangle = \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$$</td>\n </tr>\n</table>\n\n<p>These two kets represent basis states, so they can be used to represent any other state:</p>\n<p>$$\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} = \\alpha|0\\rangle + \\beta|1\\rangle$$</p>\n<p>Dirac notation is not only restricted to vectors $0$ and $1$, but it can be used to represent any arbitrary vector. For example the vector $\\psi$ can be written as:</p>\n<p>$$|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$$</p>\n<p>Other examples of vector states represented in Dirac notation are:</p>\n<table>\n <tr>\n <td>$$|+\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle + |1\\rangle\\big)$$</td>\n <td>$$|-\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle - |1\\rangle\\big)$$</td>\n </tr>\n <tr>\n <td>$$|i\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle + i|1\\rangle\\big)$$</td>\n <td>$$|-i\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle - i|1\\rangle\\big)$$</td>\n </tr>\n</table>\n\n<p>We will learn more about Dirac notation in the next katas, as we introduce quantum gates and multi-qubit systems.</p>\n",
|
|
87
|
+
"asMarkdown": "\nDirac notation is a shorthand notation that eases writing quantum states and computing linear algebra. In Dirac notation, a vector is denoted by a symbol called a **ket**. For example, a qubit in state $0$ is represented by the ket $|0\\rangle$, and a qubit in state $1$ is represented by the ket $|1\\rangle$:\n\n<table>\n <tr>\n <td>$$|0\\rangle = \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$$</td>\n <td>$$|1\\rangle = \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$$</td>\n </tr>\n</table>\n\nThese two kets represent basis states, so they can be used to represent any other state:\n\n$$\\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix} = \\alpha|0\\rangle + \\beta|1\\rangle$$\n\nDirac notation is not only restricted to vectors $0$ and $1$, but it can be used to represent any arbitrary vector. For example the vector $\\psi$ can be written as:\n\n$$|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$$\n\nOther examples of vector states represented in Dirac notation are:\n\n<table>\n <tr>\n <td>$$|+\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle + |1\\rangle\\big)$$</td>\n <td>$$|-\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle - |1\\rangle\\big)$$</td>\n </tr>\n <tr>\n <td>$$|i\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle + i|1\\rangle\\big)$$</td>\n <td>$$|-i\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle - i|1\\rangle\\big)$$</td>\n </tr>\n</table>\n\nWe will learn more about Dirac notation in the next katas, as we introduce quantum gates and multi-qubit systems."
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"type": "lesson",
|
|
93
|
+
"id": "qubit__relative_and_global_phase",
|
|
94
|
+
"title": "Relative and Global Phase",
|
|
95
|
+
"items": [
|
|
96
|
+
{
|
|
97
|
+
"type": "text-content",
|
|
98
|
+
"asHtml": "<p>Complex numbers have a parameter called the phase. If a complex number $z = x + iy$ is written in polar form $z = re^{i\\theta}$, its phase is $\\theta$ where $\\theta = tan^{-1}(\\frac{y}{x})$.</p>\n<p>The probability amplitudes $\\alpha$ and $\\beta$ are complex numbers, therefore $\\alpha$ and $\\beta$ have a phase. For example, consider a qubit in state $\\frac{1 + i}{2}|0\\rangle + \\frac{1 - i}{2}|1\\rangle$. If you do the math, you see that $\\theta = tan^{-1}(1) = \\frac{\\pi}{4}$. Thus, the phase of $|0\\rangle$ is $\\frac{\\pi}{4}$, and the phase of $|1\\rangle$ is $-\\frac{\\pi}{4}$. The difference between these two phases is known as <strong>relative phase</strong>.</p>\n<p>Multiplying the state of the entire system by $e^{i\\theta}$ doesn't affect the relative phase: $\\alpha|0\\rangle + \\beta|1\\rangle$ has the same relative phase as $e^{i\\theta}\\big(\\alpha|0\\rangle + \\beta|1\\rangle\\big)$. In the second expression, $\\theta$ is known as the system's <strong>global phase</strong>.</p>\n<p>The state of a qubit (or, more generally, the state of a quantum system) is defined by its relative phase - global phase arises as a consequence of using linear algebra to represent qubits, and has no physical meaning. That is, applying a phase to the entire state of a system (multiplying the entire vector by $e^{i\\theta}$ for any real $\\theta$) doesn't actually affect the state of the system. Because of this, global phase is sometimes known as <strong>unobservable phase</strong> or <strong>hidden phase</strong>.</p>\n",
|
|
99
|
+
"asMarkdown": "\nComplex numbers have a parameter called the phase. If a complex number $z = x + iy$ is written in polar form $z = re^{i\\theta}$, its phase is $\\theta$ where $\\theta = tan^{-1}(\\frac{y}{x})$.\n\nThe probability amplitudes $\\alpha$ and $\\beta$ are complex numbers, therefore $\\alpha$ and $\\beta$ have a phase. For example, consider a qubit in state $\\frac{1 + i}{2}|0\\rangle + \\frac{1 - i}{2}|1\\rangle$. If you do the math, you see that $\\theta = tan^{-1}(1) = \\frac{\\pi}{4}$. Thus, the phase of $|0\\rangle$ is $\\frac{\\pi}{4}$, and the phase of $|1\\rangle$ is $-\\frac{\\pi}{4}$. The difference between these two phases is known as **relative phase**.\n\nMultiplying the state of the entire system by $e^{i\\theta}$ doesn't affect the relative phase: $\\alpha|0\\rangle + \\beta|1\\rangle$ has the same relative phase as $e^{i\\theta}\\big(\\alpha|0\\rangle + \\beta|1\\rangle\\big)$. In the second expression, $\\theta$ is known as the system's **global phase**.\n\nThe state of a qubit (or, more generally, the state of a quantum system) is defined by its relative phase - global phase arises as a consequence of using linear algebra to represent qubits, and has no physical meaning. That is, applying a phase to the entire state of a system (multiplying the entire vector by $e^{i\\theta}$ for any real $\\theta$) doesn't actually affect the state of the system. Because of this, global phase is sometimes known as **unobservable phase** or **hidden phase**."
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"type": "lesson",
|
|
105
|
+
"id": "qubit__qsharp_data_type",
|
|
106
|
+
"title": "Q# Qubit Data Type",
|
|
107
|
+
"items": [
|
|
108
|
+
{
|
|
109
|
+
"type": "text-content",
|
|
110
|
+
"asHtml": "<p>In Q#, qubits are represented by the <code>Qubit</code> data type. On a physical quantum computer, it's impossible to directly access the state of a qubit, whether to read its exact state, or to set it to a desired state, and this data type reflects that. Instead, you can change the state of a qubit using quantum gates, and extract information about the state of the system using measurements.</p>\n<p>That being said, when you run Q# code on a quantum simulator instead of a physical quantum computer, you can use diagnostic functions that allow you to peek at the state of the quantum system. This is very useful both for learning and for debugging small Q# programs.</p>\n<p>The qubits aren't an ordinary data type, so the variables of this type have to be declared and initialized ("allocated") a little differently.</p>\n<p>Freshly allocated qubits start out in state $|0\\rangle$, and have to be returned to that state by the time they are released. If you attempt to release a qubit in any state other than $|0\\rangle$, it will result in a runtime error. We will see why it is important later, when we look at multi-qubit systems.</p>\n<h2 id=\"visualizing-quantum-state\">Visualizing Quantum State</h2>\n<p>Before we continue, let's learn some techniques to visualize the quantum state of our qubits.</p>\n<h3 id=\"display-the-quantum-state-of-a-single-qubit-program\">Display the Quantum State of a Single-Qubit Program</h3>\n<p>Let's start with a simple scenario: a program that acts on a single qubit. \nThe state of the quantum system used by this program can be represented as a complex vector of length 2, or, using Dirac notation,</p>\n<p>$$\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} = \\alpha|0\\rangle + \\beta|1\\rangle$$</p>\n<p>If this program runs on a physical quantum system, there is no way to get the information about the values of $\\alpha$ and $\\beta$ at a certain point of the program execution from a single observation. \nYou would need to run the program repeatedly up to this point, perform a measurement on the system, and aggregate the results of multiple measurements to estimate $\\alpha$ and $\\beta$.</p>\n<p>However, at the early stages of quantum program development the program typically runs on a simulator - a classical program which simulates the behavior of a small quantum system while having complete information about its internal state. \nYou can take advantage of this to do some non-physical things, such as peeking at the internals of the quantum system to observe its exact state without disturbing it!</p>\n<p>The <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.diagnostics.dumpmachine\" target=\"_blank\"><code>DumpMachine</code></a> function from the <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.diagnostics\" target=\"_blank\"><code>Microsoft.Quantum.Diagnostics namespace</code></a> allows you to do exactly that. The output of <code>DumpMachine</code> is accurate up to a global phase, and remember that global phase does not have any physical meaning. When using <code>DumpMachine</code>, you may see that all probability amplitudes are multiplied by some complex number compared to the state you're expecting.</p>\n<h3 id=\"demo-dumpmachine-for-single-qubit-systems\">Demo: DumpMachine For Single-Qubit Systems</h3>\n<p>The following demo shows how to allocate a qubit and examine its state in Q#. You'll use <code>DumpMachine</code> to output the state of the system at any point in the program without affecting the state.</p>\n<blockquote>\n<p>Note that the Q# code doesn't have access to the output of <code>DumpMachine</code>, so you cannot write any non-physical code in Q#!</p>\n</blockquote>\n",
|
|
111
|
+
"asMarkdown": "\nIn Q#, qubits are represented by the `Qubit` data type. On a physical quantum computer, it's impossible to directly access the state of a qubit, whether to read its exact state, or to set it to a desired state, and this data type reflects that. Instead, you can change the state of a qubit using quantum gates, and extract information about the state of the system using measurements.\n\nThat being said, when you run Q# code on a quantum simulator instead of a physical quantum computer, you can use diagnostic functions that allow you to peek at the state of the quantum system. This is very useful both for learning and for debugging small Q# programs.\n\nThe qubits aren't an ordinary data type, so the variables of this type have to be declared and initialized (\"allocated\") a little differently.\n\nFreshly allocated qubits start out in state $|0\\rangle$, and have to be returned to that state by the time they are released. If you attempt to release a qubit in any state other than $|0\\rangle$, it will result in a runtime error. We will see why it is important later, when we look at multi-qubit systems.\n\n## Visualizing Quantum State\n\nBefore we continue, let's learn some techniques to visualize the quantum state of our qubits.\n\n### Display the Quantum State of a Single-Qubit Program\n\nLet's start with a simple scenario: a program that acts on a single qubit. \nThe state of the quantum system used by this program can be represented as a complex vector of length 2, or, using Dirac notation,\n\n$$\\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix} = \\alpha|0\\rangle + \\beta|1\\rangle$$\n\nIf this program runs on a physical quantum system, there is no way to get the information about the values of $\\alpha$ and $\\beta$ at a certain point of the program execution from a single observation. \nYou would need to run the program repeatedly up to this point, perform a measurement on the system, and aggregate the results of multiple measurements to estimate $\\alpha$ and $\\beta$.\n\nHowever, at the early stages of quantum program development the program typically runs on a simulator - a classical program which simulates the behavior of a small quantum system while having complete information about its internal state. \nYou can take advantage of this to do some non-physical things, such as peeking at the internals of the quantum system to observe its exact state without disturbing it!\n\nThe <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.diagnostics.dumpmachine\" target=\"_blank\">`DumpMachine`</a> function from the <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.diagnostics\" target=\"_blank\">`Microsoft.Quantum.Diagnostics namespace`</a> allows you to do exactly that. The output of `DumpMachine` is accurate up to a global phase, and remember that global phase does not have any physical meaning. When using `DumpMachine`, you may see that all probability amplitudes are multiplied by some complex number compared to the state you're expecting.\n\n### Demo: DumpMachine For Single-Qubit Systems\n\nThe following demo shows how to allocate a qubit and examine its state in Q#. You'll use `DumpMachine` to output the state of the system at any point in the program without affecting the state.\n\n> Note that the Q# code doesn't have access to the output of `DumpMachine`, so you cannot write any non-physical code in Q#!"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"type": "example",
|
|
115
|
+
"id": "qubit__single_qubit_dump_machine_demo",
|
|
116
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n\n @EntryPoint()\n operation RunExample(): Unit {\n // This line allocates a qubit in state |0⟩.\n use q = Qubit();\n Message(\"State |0⟩:\");\n\n // This line prints out the state of the quantum computer.\n // Since only one qubit is allocated, only its state is printed.\n DumpMachine();\n\n // This line changes the qubit from state |0⟩ to state |1⟩.\n X(q);\n\n Message(\"State |1⟩:\");\n DumpMachine();\n\n // This line changes the qubit to state |-⟩ = (1/sqrt(2))(|0⟩ - |1⟩).\n // That is, this puts the qubit into a superposition where the absolute\n // value of the probability amplitudes is 1/sqrt(2), which is \n // approximately 0.707107.\n H(q);\n\n Message(\"State |-⟩:\");\n DumpMachine();\n\n // This line changes the qubit to state |-i⟩ = (1/sqrt(2))(|0⟩ - i|1⟩).\n S(q);\n\n Message(\"State |-i⟩:\");\n DumpMachine();\n\n // This will put the qubit into an uneven superposition, where the\n // amplitudes of |0⟩ and |1⟩ have different absolute values.\n Rx(2.0, q);\n Ry(1.0, q);\n\n Message(\"Uneven superposition state:\");\n DumpMachine();\n\n // This line returns the qubit to state |0⟩, which must be done before\n // the qubit is released or otherwise a runtime error might occur.\n Reset(q);\n }\n}\n"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"type": "text-content",
|
|
120
|
+
"asHtml": "<p>The exact behavior of this operation called <code>RunExample</code> depends on the quantum simulator or processor you are using.</p>\n<p>On the simulator used in these demos, this function prints the information on each basis state that has a non-zero amplitude, one basis state per row.\nThis includes information about the amplitude of the state, the probability of measuring that state, and the phase of the state.</p>\n<p>Note that each row has the following format:</p>\n<table>\n <thead>\n <tr>\n <th>Basis State<br>(|𝜓ₙ…𝜓₁⟩)</th>\n <th>Amplitude</th>\n <th>Measurement Probability</th>\n <th>Phase</th>\n </tr>\n </thead>\n</table>\n\n<p>For example, the state $|0\\rangle$ would be represented as follows:</p>\n<table>\n <tbody>\n <tr>\n <td>|0⟩</td>\n <td>1.0000+0.0000𝑖</td>\n <td>100.0000%</td>\n <td>↑ 0.0000</td></tr>\n </tbody>\n</table>\n\n<blockquote>\n<p>It is important to note that although we reason about quantum systems in terms of their state, Q# does not have any representation of the quantum state in the language. Instead, state is an internal property of the quantum system, modified using gates. For more information, see <a href=\"https://docs.microsoft.com/azure/quantum/concepts-dirac-notation#q-gate-sequences-equivalent-to-quantum-states\" target=\"_blank\">Q# documentation on quantum states</a>.</p>\n</blockquote>\n",
|
|
121
|
+
"asMarkdown": "\nThe exact behavior of this operation called `RunExample` depends on the quantum simulator or processor you are using.\n\nOn the simulator used in these demos, this function prints the information on each basis state that has a non-zero amplitude, one basis state per row.\nThis includes information about the amplitude of the state, the probability of measuring that state, and the phase of the state.\n\nNote that each row has the following format:\n\n<table>\n <thead>\n <tr>\n <th>Basis State<br>(|𝜓ₙ…𝜓₁⟩)</th>\n <th>Amplitude</th>\n <th>Measurement Probability</th>\n <th>Phase</th>\n </tr>\n </thead>\n</table>\n\nFor example, the state $|0\\rangle$ would be represented as follows:\n\n<table>\n <tbody>\n <tr>\n <td>|0⟩</td>\n <td>1.0000+0.0000𝑖</td>\n <td>100.0000%</td>\n <td>↑ 0.0000</td></tr>\n </tbody>\n</table>\n\n> It is important to note that although we reason about quantum systems in terms of their state, Q# does not have any representation of the quantum state in the language. Instead, state is an internal property of the quantum system, modified using gates. For more information, see <a href=\"https://docs.microsoft.com/azure/quantum/concepts-dirac-notation#q-gate-sequences-equivalent-to-quantum-states\" target=\"_blank\">Q# documentation on quantum states</a>."
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"type": "exercise",
|
|
127
|
+
"id": "qubit__learn_single_qubit_state",
|
|
128
|
+
"title": "Learn the State of a Single Qubit",
|
|
129
|
+
"description": {
|
|
130
|
+
"type": "text-content",
|
|
131
|
+
"asHtml": "<p><strong>Input:</strong> A qubit in an unknown state $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$. The amplitudes $\\alpha$ and $\\beta$ will be real and non-negative.</p>\n<p><strong>Output:</strong> A tuple of two numbers $(\\alpha', \\beta')$ - your estimates of the amplitudes $\\alpha$ and $\\beta$.\nThe absolute errors $|\\alpha - \\alpha'|$ and $|\\beta - \\beta'|$ should be less than or equal to 0.001.</p>\n<p>Please note that the state parameter is guaranteed to be the same\nif you run the code several times. Your operation will be called\nonce for every run.</p>\n<details>\n <summary><b>Need a hint?</b></summary>\n On a physical quantum system, there would be no way to obtain the values of $\\alpha$ and $\\beta$ from a single observation. Since this program runs on a simulator, we can use <code>DumpMachine</code> to inspect the qubit and take a note of its state. Furthermore, the problem statement guarantees, that the state will be the same from invocation to invocation. So we can update the code to return the amplitudes that we've taken note of. Then run the code again.\n</details>\n",
|
|
132
|
+
"asMarkdown": "\n**Input:** A qubit in an unknown state $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$. The amplitudes $\\alpha$ and $\\beta$ will be real and non-negative.\n\n**Output:** A tuple of two numbers $(\\alpha', \\beta')$ - your estimates of the amplitudes $\\alpha$ and $\\beta$.\nThe absolute errors $|\\alpha - \\alpha'|$ and $|\\beta - \\beta'|$ should be less than or equal to 0.001.\n\nPlease note that the state parameter is guaranteed to be the same\nif you run the code several times. Your operation will be called\nonce for every run.\n\n<details>\n <summary><b>Need a hint?</b></summary>\n On a physical quantum system, there would be no way to obtain the values of $\\alpha$ and $\\beta$ from a single observation. Since this program runs on a simulator, we can use <code>DumpMachine</code> to inspect the qubit and take a note of its state. Furthermore, the problem statement guarantees, that the state will be the same from invocation to invocation. So we can update the code to return the amplitudes that we've taken note of. Then run the code again.\n</details>\n"
|
|
133
|
+
},
|
|
134
|
+
"sourceIds": [
|
|
135
|
+
"KatasLibrary.qs",
|
|
136
|
+
"qubit__learn_single_qubit_state__Verification.qs"
|
|
137
|
+
],
|
|
138
|
+
"placeholderCode": "namespace Kata {\n operation LearnSingleQubitState(q: Qubit): (Double, Double) {\n // Implement your solution here...\n\n return (0.0, 0.0);\n }\n}\n",
|
|
139
|
+
"explainedSolution": {
|
|
140
|
+
"type": "explained-solution",
|
|
141
|
+
"items": [
|
|
142
|
+
{
|
|
143
|
+
"type": "text-content",
|
|
144
|
+
"asHtml": "<p>Learn the amplitudes $\\alpha$ and $\\beta$ by calling <code>DumpMachine</code> and return the values shown in the output of this function.</p>\n",
|
|
145
|
+
"asMarkdown": "\nLearn the amplitudes $\\alpha$ and $\\beta$ by calling `DumpMachine` and return the values shown in the output of this function."
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"type": "solution",
|
|
149
|
+
"id": "qubit__learn_single_qubit_state_solution",
|
|
150
|
+
"code": "namespace Kata { \n open Microsoft.Quantum.Diagnostics;\n\n operation LearnSingleQubitState (q : Qubit) : (Double, Double) {\n DumpMachine(); // Only used to learn the amplitudes.\n return (0.9689, 0.2474);\n }\n}\n"
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"type": "lesson",
|
|
157
|
+
"id": "qubit__visualizing_multi_qubit",
|
|
158
|
+
"title": "Display the Quantum State of a Multi-Qubit Program",
|
|
159
|
+
"items": [
|
|
160
|
+
{
|
|
161
|
+
"type": "text-content",
|
|
162
|
+
"asHtml": "<p>Now let's take a look at the general case: a program that acts on $N$ qubits. \nThe state of the quantum system used by this program can be represented as a complex vector of length $2^N$, or, using Dirac notation,</p>\n<p>$$\\begin{bmatrix} x_0 \\\\ x_1 \\\\ \\vdots \\\\ x_{2^N-1}\\end{bmatrix} = \\sum_{k = 0}^{2^N-1} x_k |k\\rangle$$</p>\n<p>Same as in the single-qubit case, <code>DumpMachine</code> allows you to see the amplitudes $x_k$ for all basis states $|k\\rangle$ directly.</p>\n<blockquote>\n<p>Note the use of an integer in the ket notation instead of a bit string with one bit per qubit. \n<code>DumpMachine</code> uses big-endian to convert bit strings to integers in the ket notation.\nWe will learn more details on endianness in the "Multi-Qubit Systems" kata.</p>\n</blockquote>\n<h2 id=\"demo-dumpmachine-for-multi-qubit-systems\">Demo: DumpMachine for Multi-Qubit Systems</h2>\n",
|
|
163
|
+
"asMarkdown": "\nNow let's take a look at the general case: a program that acts on $N$ qubits. \nThe state of the quantum system used by this program can be represented as a complex vector of length $2^N$, or, using Dirac notation,\n\n$$\\begin{bmatrix} x_0 \\\\\\ x_1 \\\\\\ \\vdots \\\\\\ x_{2^N-1}\\end{bmatrix} = \\sum_{k = 0}^{2^N-1} x_k |k\\rangle$$\n\nSame as in the single-qubit case, `DumpMachine` allows you to see the amplitudes $x_k$ for all basis states $|k\\rangle$ directly.\n\n> Note the use of an integer in the ket notation instead of a bit string with one bit per qubit. \n`DumpMachine` uses big-endian to convert bit strings to integers in the ket notation.\nWe will learn more details on endianness in the \"Multi-Qubit Systems\" kata.\n\n## Demo: DumpMachine for Multi-Qubit Systems"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"type": "example",
|
|
167
|
+
"id": "qubit__multi_qubit_dump_machine_demo",
|
|
168
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n\n @EntryPoint()\n operation MultiQubitDumpMachineDemo(): Unit {\n // This line allocates two qubits in state |00⟩.\n use qs = Qubit[2];\n Message(\"State |00⟩:\");\n\n // This line prints out the state of the quantum system.\n DumpMachine();\n\n // X gate changes the second qubit into state |1⟩.\n // The entire system is now in state |01⟩, or, in little-endian notation, |2⟩.\n X(qs[1]);\n Message(\"State |01⟩:\");\n DumpMachine();\n\n CNOT(qs[1], qs[0]);\n Rx(1.0, qs[0]);\n Ry(2.0, qs[1]);\n Rz(3.0, qs[1]);\n\n Message(\"Uneven superposition state:\");\n DumpMachine();\n\n // This line returns the qubits to state |0⟩ before releasing them.\n ResetAll(qs);\n }\n}\n"
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"type": "exercise",
|
|
174
|
+
"id": "qubit__learn_basis_state_amplitudes",
|
|
175
|
+
"title": "Learn Basis State Amplitudes",
|
|
176
|
+
"description": {
|
|
177
|
+
"type": "text-content",
|
|
178
|
+
"asHtml": "<p><strong>Input:</strong> 2 qubits in an unknown state $|\\psi\\rangle = \\sum_{k = 0}^{3} x_k |k\\rangle$. The amplitudes $x_k$ will be real and non-negative.</p>\n<p><strong>Output:</strong> A tuple of two numbers $(x_1', x_2')$ - your estimates of the amplitudes of the state $|1\\rangle$ and $|2\\rangle$, respectively.\nThe absolute errors $|x_1 - x_1'|$ and $|x_2 - x_2'|$ should be less than or equal to 0.001.</p>\n<p>Please note that the state parameter is guaranteed to be the same\nif you run the code several times. Your operation will be called\nonce for every run.</p>\n<details>\n <summary><b>Need a hint?</b></summary>\n On a physical quantum system, there would be no way to obtain these values from a single observation. Since this program runs on a simulator, we can use <code>DumpMachine</code> to inspect the qubits and take a note of their state. Furthermore, the problem statement guarantees, that the state will be the same from invocation to invocation. So we can update the code to return the amplitudes that we've taken note of. Then run the code again.\n</details>\n",
|
|
179
|
+
"asMarkdown": "\n**Input:** 2 qubits in an unknown state $|\\psi\\rangle = \\sum_{k = 0}^{3} x_k |k\\rangle$. The amplitudes $x_k$ will be real and non-negative.\n\n**Output:** A tuple of two numbers $(x_1', x_2')$ - your estimates of the amplitudes of the state $|1\\rangle$ and $|2\\rangle$, respectively.\nThe absolute errors $|x_1 - x_1'|$ and $|x_2 - x_2'|$ should be less than or equal to 0.001.\n\nPlease note that the state parameter is guaranteed to be the same\nif you run the code several times. Your operation will be called\nonce for every run.\n\n<details>\n <summary><b>Need a hint?</b></summary>\n On a physical quantum system, there would be no way to obtain these values from a single observation. Since this program runs on a simulator, we can use <code>DumpMachine</code> to inspect the qubits and take a note of their state. Furthermore, the problem statement guarantees, that the state will be the same from invocation to invocation. So we can update the code to return the amplitudes that we've taken note of. Then run the code again.\n</details>\n"
|
|
180
|
+
},
|
|
181
|
+
"sourceIds": [
|
|
182
|
+
"KatasLibrary.qs",
|
|
183
|
+
"qubit__learn_basis_state_amplitudes__Verification.qs"
|
|
184
|
+
],
|
|
185
|
+
"placeholderCode": "namespace Kata {\n operation LearnBasisStateAmplitudes(qs: Qubit[]): (Double, Double) {\n // Implement your solution here...\n\n return (0.0, 0.0);\n }\n}\n",
|
|
186
|
+
"explainedSolution": {
|
|
187
|
+
"type": "explained-solution",
|
|
188
|
+
"items": [
|
|
189
|
+
{
|
|
190
|
+
"type": "text-content",
|
|
191
|
+
"asHtml": "<p>Learn the amplitudes $x_k$ by calling <code>DumpMachine</code> and return the values shown in the output of this function.</p>\n",
|
|
192
|
+
"asMarkdown": "\nLearn the amplitudes $x_k$ by calling `DumpMachine` and return the values shown in the output of this function."
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"type": "solution",
|
|
196
|
+
"id": "qubit__learn_basis_state_amplitudes_solution",
|
|
197
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n\n operation LearnBasisStateAmplitudes(qs: Qubit[]): (Double, Double) {\n DumpMachine(); // Only used to learn the amplitudes.\n return (0.3821, 0.339);\n }\n}\n"
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"type": "lesson",
|
|
204
|
+
"id": "qubit__conclusion",
|
|
205
|
+
"title": "Conclusion",
|
|
206
|
+
"items": [
|
|
207
|
+
{
|
|
208
|
+
"type": "text-content",
|
|
209
|
+
"asHtml": "<p>Congratulations! In this kata you learned the basics of qubits and qubit states. Here are a few key concepts to keep in mind:</p>\n<ul>\n<li>A qubit is a basic unit of quantum information, analogous to a bit in classical computing.</li>\n<li>Superposition is a quantum phenomenon where a qubit is in a combination of both 0 and 1 states. When measured, a qubit goes from being in superposition to one of the classical states.</li>\n<li>A qubit can be represented as $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$, where $\\alpha$ and $\\beta$ are complex numbers and state vectors $|0\\rangle$ and $|1\\rangle$ are $0$ and $1$ states respectively.</li>\n<li>In Q#, qubits are represented by the <code>Qubit</code> data type. When simulating a quantum program, you can use <code>DumpMachine</code> to inspect the state of a qubit without disturbing it.</li>\n</ul>\n",
|
|
210
|
+
"asMarkdown": "\nCongratulations! In this kata you learned the basics of qubits and qubit states. Here are a few key concepts to keep in mind:\n* A qubit is a basic unit of quantum information, analogous to a bit in classical computing.\n* Superposition is a quantum phenomenon where a qubit is in a combination of both 0 and 1 states. When measured, a qubit goes from being in superposition to one of the classical states.\n* A qubit can be represented as $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$, where $\\alpha$ and $\\beta$ are complex numbers and state vectors $|0\\rangle$ and $|1\\rangle$ are $0$ and $1$ states respectively.\n* In Q#, qubits are represented by the `Qubit` data type. When simulating a quantum program, you can use `DumpMachine` to inspect the state of a qubit without disturbing it."
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"id": "single_qubit_gates",
|
|
218
|
+
"title": "Single-Qubit Gates",
|
|
219
|
+
"sections": [
|
|
220
|
+
{
|
|
221
|
+
"type": "lesson",
|
|
222
|
+
"id": "single_qubit_gates__overview",
|
|
223
|
+
"title": "Overview",
|
|
224
|
+
"items": [
|
|
225
|
+
{
|
|
226
|
+
"type": "text-content",
|
|
227
|
+
"asHtml": "<p>This kata introduces you to single-qubit gates. Quantum gates are the quantum counterpart to classical logic gates, acting as the building blocks of quantum algorithms. Quantum gates transform qubit states in various ways, and can be applied sequentially to perform complex quantum calculations. Single-qubit gates, as their name implies, act on individual qubits. You can learn more at <a href=\"https://en.wikipedia.org/wiki/Quantum_logic_gate\" target=\"_blank\">Wikipedia</a>.</p>\n<p><strong>This kata covers the following topics:</strong></p>\n<ul>\n<li>Matrix representation</li>\n<li>Ket-bra representation</li>\n<li>The most important single-qubit gates</li>\n</ul>\n<p><strong>What you should know to start working on this kata:</strong></p>\n<ul>\n<li>Basic linear algebra</li>\n<li>The concept of qubit</li>\n</ul>\n",
|
|
228
|
+
"asMarkdown": "\nThis kata introduces you to single-qubit gates. Quantum gates are the quantum counterpart to classical logic gates, acting as the building blocks of quantum algorithms. Quantum gates transform qubit states in various ways, and can be applied sequentially to perform complex quantum calculations. Single-qubit gates, as their name implies, act on individual qubits. You can learn more at <a href=\"https://en.wikipedia.org/wiki/Quantum_logic_gate\" target=\"_blank\">Wikipedia</a>.\n\n**This kata covers the following topics:**\n\n- Matrix representation\n- Ket-bra representation\n- The most important single-qubit gates\n\n**What you should know to start working on this kata:**\n\n- Basic linear algebra\n- The concept of qubit"
|
|
229
|
+
}
|
|
230
|
+
]
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"type": "lesson",
|
|
234
|
+
"id": "single_qubit_gates__basics",
|
|
235
|
+
"title": "The Basics",
|
|
236
|
+
"items": [
|
|
237
|
+
{
|
|
238
|
+
"type": "text-content",
|
|
239
|
+
"asHtml": "<p>There are certain properties common to all quantum gates. This section will introduce those properties, using the $X$ gate as an example.</p>\n<h2 id=\"matrix-representation\">Matrix Representation</h2>\n<p>Quantum gates are represented as $2^N \\times 2^N$ unitary matrices, where $N$ is the number of qubits the gate operates on. \nAs a quick reminder, a unitary matrix is a square matrix whose inverse is its adjoint, thus $U^* U = UU^* = UU^{-1} = \\mathbb{I}$.\nSingle-qubit gates are represented by $2 \\times 2$ matrices.\nOur example for this section, the $X$ gate, is represented by the following matrix:</p>\n<p>$$\\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix}$$</p>\n<p>You may recall that the state of a qubit is represented by a vector of size $2$. You can apply a gate to a qubit by multiplying the gate's matrix by the qubit's state vector. The result will be another vector, representing the new state of the qubit. For example, applying the $X$ gate to the computational basis states looks like this:</p>\n<p>$$\nX|0\\rangle =\n\\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix}\n\\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} 0 \\cdot 1 + 1 \\cdot 0 \\\\ 1 \\cdot 1 + 0 \\cdot 0 \\end{bmatrix} =\n\\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix}\n$$</p>\n<p>$$\nX|1\\rangle =\n\\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix}\n\\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} =\n\\begin{bmatrix} 0 \\cdot 0 + 1 \\cdot 1 \\\\ 1 \\cdot 0 + 0 \\cdot 1 \\end{bmatrix} =\n\\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix}\n$$</p>\n<p>The general case:</p>\n<p>$$|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$$</p>\n<p>$$\nX|\\psi\\rangle =\n\\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix}\n\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} =\n\\begin{bmatrix} 0 \\cdot \\alpha + 1 \\cdot \\beta \\\\ 1 \\cdot \\alpha + 0 \\cdot \\beta \\end{bmatrix} =\n\\begin{bmatrix} \\beta \\\\ \\alpha \\end{bmatrix}\n$$</p>\n<blockquote>\n<p>If you need a reminder of what $|0\\rangle$, $|1\\rangle$, and $|\\psi\\rangle$ mean, you can review the section on Dirac notation in "The Qubit" kata.</p>\n</blockquote>\n<p>Quantum gates are represented by matrices, just like quantum states are represented by vectors. Because this is the most common way to represent quantum gates, the terms "gate" and "gate matrix" will be used interchangeably in this kata.</p>\n<p>Applying several quantum gates in sequence is equivalent to performing several of these multiplications. \nFor example, if you have gates $A$ and $B$ and a qubit in state $|\\psi\\rangle$, the result of applying $A$ followed by $B$ to that qubit would be $B\\big(A|\\psi\\rangle\\big)$ (the gate closest to the qubit state gets applied first). \nMatrix multiplication is associative, so this is equivalent to multiplying the $B$ matrix by the $A$ matrix, producing a compound gate of the two, and then applying that to the qubit: $\\big(BA\\big)|\\psi\\rangle$.</p>\n<blockquote>\n<p>Note that matrix multiplication isn’t commutative, thus $(BA) \\neq (AB)$.</p>\n</blockquote>\n<p>All quantum gates are reversible - there is another gate which will undo any given gate's transformation, returning the qubit to its original state. \nThis means that when dealing with quantum gates, information about qubit states is never lost, as opposed to classical logic gates, some of which destroy information. \nQuantum gates are represented by unitary matrices, so the inverse of a gate is its adjoint; these terms are also used interchangeably in quantum computing.</p>\n<h2 id=\"effects-on-basis-states\">Effects on Basis States</h2>\n<p>There is a simple way to find out what a gate does to the two computational basis states $|0\\rangle$ and $|1\\rangle$. Consider an arbitrary gate:</p>\n<p>$$A = \\begin{bmatrix} \\epsilon & \\zeta \\\\ \\eta & \\mu \\end{bmatrix}$$</p>\n<p>Watch what happens when we apply it to these states:</p>\n<p>$$\nA|0\\rangle =\n\\begin{bmatrix} \\epsilon & \\zeta \\\\ \\eta & \\mu \\end{bmatrix}\n\\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} \\epsilon \\cdot 1 + \\zeta \\cdot 0 \\\\ \\eta \\cdot 1 + \\mu \\cdot 0 \\end{bmatrix} =\n\\begin{bmatrix} \\epsilon \\\\ \\eta \\end{bmatrix} = \\epsilon|0\\rangle + \\eta|1\\rangle\n$$</p>\n<p>$$\nA|1\\rangle =\n\\begin{bmatrix} \\epsilon & \\zeta \\\\ \\eta & \\mu \\end{bmatrix}\n\\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} =\n\\begin{bmatrix} \\epsilon \\cdot 0 + \\zeta \\cdot 1 \\\\ \\eta \\cdot 0 + \\mu \\cdot 1 \\end{bmatrix} =\n\\begin{bmatrix} \\zeta \\\\ \\mu \\end{bmatrix} = \\zeta|0\\rangle + \\mu|1\\rangle\n$$</p>\n<p>Notice that applying the gate to the $|0\\rangle$ state transforms it into the state written as the first column of the gate's matrix. Likewise, applying the gate to the $|1\\rangle$ state transforms it into the state written as the second column. This holds true for any quantum gate, including, of course, the $X$ gate:</p>\n<p>$$X = \\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix}$$</p>\n<p>$$X|0\\rangle = \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} = |1\\rangle$$</p>\n<p>$$X|1\\rangle = \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} = |0\\rangle$$</p>\n<p>Once you understand how a gate affects the computational basis states, you can easily find how it affects any state.\nRecall that any qubit state vector can be written as a linear combination of the basis states:</p>\n<p>$$|\\psi\\rangle = \\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} = \\alpha|0\\rangle + \\beta|1\\rangle$$</p>\n<p>Because matrix multiplication distributes over addition, once you know how a gate affects those two basis states, you can calculate how it affects any state:</p>\n<p>$$X|\\psi\\rangle = X\\big(\\alpha|0\\rangle + \\beta|1\\rangle\\big) = X\\big(\\alpha|0\\rangle\\big) + X\\big(\\beta|1\\rangle\\big) = \\alpha X|0\\rangle + \\beta X|1\\rangle = \\alpha|1\\rangle + \\beta|0\\rangle$$</p>\n<p>That is, applying a gate to a qubit in superposition is equivalent to applying that gate to the basis states that make up that superposition and adding the results with appropriate weights.</p>\n",
|
|
240
|
+
"asMarkdown": "\nThere are certain properties common to all quantum gates. This section will introduce those properties, using the $X$ gate as an example.\n\n## Matrix Representation\n\nQuantum gates are represented as $2^N \\times 2^N$ unitary matrices, where $N$ is the number of qubits the gate operates on. \nAs a quick reminder, a unitary matrix is a square matrix whose inverse is its adjoint, thus $U^* U = UU^* = UU^{-1} = \\mathbb{I}$.\nSingle-qubit gates are represented by $2 \\times 2$ matrices.\nOur example for this section, the $X$ gate, is represented by the following matrix:\n\n$$\\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix}$$\n\nYou may recall that the state of a qubit is represented by a vector of size $2$. You can apply a gate to a qubit by multiplying the gate's matrix by the qubit's state vector. The result will be another vector, representing the new state of the qubit. For example, applying the $X$ gate to the computational basis states looks like this:\n\n$$\nX|0\\rangle =\n\\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix}\n\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} 0 \\cdot 1 + 1 \\cdot 0 \\\\\\ 1 \\cdot 1 + 0 \\cdot 0 \\end{bmatrix} =\n\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}\n$$\n\n$$\nX|1\\rangle =\n\\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix}\n\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} =\n\\begin{bmatrix} 0 \\cdot 0 + 1 \\cdot 1 \\\\\\ 1 \\cdot 0 + 0 \\cdot 1 \\end{bmatrix} =\n\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}\n$$\n\nThe general case:\n\n$$|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$$\n\n$$\nX|\\psi\\rangle =\n\\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix}\n\\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix} =\n\\begin{bmatrix} 0 \\cdot \\alpha + 1 \\cdot \\beta \\\\\\ 1 \\cdot \\alpha + 0 \\cdot \\beta \\end{bmatrix} =\n\\begin{bmatrix} \\beta \\\\\\ \\alpha \\end{bmatrix}\n$$\n\n> If you need a reminder of what $|0\\rangle$, $|1\\rangle$, and $|\\psi\\rangle$ mean, you can review the section on Dirac notation in \"The Qubit\" kata.\n\nQuantum gates are represented by matrices, just like quantum states are represented by vectors. Because this is the most common way to represent quantum gates, the terms \"gate\" and \"gate matrix\" will be used interchangeably in this kata.\n\nApplying several quantum gates in sequence is equivalent to performing several of these multiplications. \nFor example, if you have gates $A$ and $B$ and a qubit in state $|\\psi\\rangle$, the result of applying $A$ followed by $B$ to that qubit would be $B\\big(A|\\psi\\rangle\\big)$ (the gate closest to the qubit state gets applied first). \nMatrix multiplication is associative, so this is equivalent to multiplying the $B$ matrix by the $A$ matrix, producing a compound gate of the two, and then applying that to the qubit: $\\big(BA\\big)|\\psi\\rangle$.\n\n>Note that matrix multiplication isn’t commutative, thus $(BA) \\neq \\(AB)$.\n\nAll quantum gates are reversible - there is another gate which will undo any given gate's transformation, returning the qubit to its original state. \nThis means that when dealing with quantum gates, information about qubit states is never lost, as opposed to classical logic gates, some of which destroy information. \nQuantum gates are represented by unitary matrices, so the inverse of a gate is its adjoint; these terms are also used interchangeably in quantum computing.\n\n## Effects on Basis States\n\nThere is a simple way to find out what a gate does to the two computational basis states $|0\\rangle$ and $|1\\rangle$. Consider an arbitrary gate:\n\n$$A = \\begin{bmatrix} \\epsilon & \\zeta \\\\\\ \\eta & \\mu \\end{bmatrix}$$\n\nWatch what happens when we apply it to these states:\n\n$$\nA|0\\rangle =\n\\begin{bmatrix} \\epsilon & \\zeta \\\\\\ \\eta & \\mu \\end{bmatrix}\n\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} \\epsilon \\cdot 1 + \\zeta \\cdot 0 \\\\\\ \\eta \\cdot 1 + \\mu \\cdot 0 \\end{bmatrix} =\n\\begin{bmatrix} \\epsilon \\\\\\ \\eta \\end{bmatrix} = \\epsilon|0\\rangle + \\eta|1\\rangle\n$$\n\n$$\nA|1\\rangle =\n\\begin{bmatrix} \\epsilon & \\zeta \\\\\\ \\eta & \\mu \\end{bmatrix}\n\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} =\n\\begin{bmatrix} \\epsilon \\cdot 0 + \\zeta \\cdot 1 \\\\\\ \\eta \\cdot 0 + \\mu \\cdot 1 \\end{bmatrix} =\n\\begin{bmatrix} \\zeta \\\\\\ \\mu \\end{bmatrix} = \\zeta|0\\rangle + \\mu|1\\rangle\n$$\n\nNotice that applying the gate to the $|0\\rangle$ state transforms it into the state written as the first column of the gate's matrix. Likewise, applying the gate to the $|1\\rangle$ state transforms it into the state written as the second column. This holds true for any quantum gate, including, of course, the $X$ gate:\n\n$$X = \\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix}$$\n\n$$X|0\\rangle = \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} = |1\\rangle$$\n\n$$X|1\\rangle = \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} = |0\\rangle$$\n\nOnce you understand how a gate affects the computational basis states, you can easily find how it affects any state.\nRecall that any qubit state vector can be written as a linear combination of the basis states:\n\n$$|\\psi\\rangle = \\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix} = \\alpha|0\\rangle + \\beta|1\\rangle$$\n\nBecause matrix multiplication distributes over addition, once you know how a gate affects those two basis states, you can calculate how it affects any state:\n\n$$X|\\psi\\rangle = X\\big(\\alpha|0\\rangle + \\beta|1\\rangle\\big) = X\\big(\\alpha|0\\rangle\\big) + X\\big(\\beta|1\\rangle\\big) = \\alpha X|0\\rangle + \\beta X|1\\rangle = \\alpha|1\\rangle + \\beta|0\\rangle$$\n\nThat is, applying a gate to a qubit in superposition is equivalent to applying that gate to the basis states that make up that superposition and adding the results with appropriate weights."
|
|
241
|
+
}
|
|
242
|
+
]
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"type": "lesson",
|
|
246
|
+
"id": "single_qubit_gates__ket_bra_representation",
|
|
247
|
+
"title": "Ket-Bra Representation",
|
|
248
|
+
"items": [
|
|
249
|
+
{
|
|
250
|
+
"type": "text-content",
|
|
251
|
+
"asHtml": "<p>There is another way to represent quantum gates, this time using Dirac notation. However, the kets we've been using aren't enough to represent arbitrary matrices. We need to introduce another piece of notation: the <strong>bra</strong> (this is why Dirac notation is sometimes called <strong>bra-ket notation</strong>).</p>\n<p>Recall that kets represent column vectors; a bra is a ket's row vector counterpart. For any ket $|\\psi\\rangle$, the corresponding bra is its adjoint (conjugate transpose): $\\langle\\psi| = |\\psi\\rangle^\\dagger$.</p>\n<p>Some examples:</p>\n<table>\n <tr>\n <th>Ket</th>\n <th>Bra</th>\n </tr>\n <tr>\n <td>$|0\\rangle = \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$</td>\n <td>$\\langle0| = \\begin{bmatrix} 1 & 0 \\end{bmatrix}$</td>\n </tr>\n <tr>\n <td>$|1\\rangle = \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$</td>\n <td>$\\langle1| = \\begin{bmatrix} 0 & 1 \\end{bmatrix}$</td>\n </tr>\n <tr>\n <td>$|i\\rangle = \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ \\frac{i}{\\sqrt{2}} \\end{bmatrix}$</td>\n <td>$\\langle i| = \\begin{bmatrix} \\frac{1}{\\sqrt{2}} & -\\frac{i}{\\sqrt{2}} \\end{bmatrix}$</td>\n </tr>\n <tr>\n <td>$|\\psi\\rangle = \\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix}$</td>\n <td>$\\langle\\psi| = \\begin{bmatrix} \\overline{\\alpha} & \\overline{\\beta} \\end{bmatrix}$</td>\n </tr>\n <tr>\n <td>$|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$</td>\n <td>$\\langle\\psi| = \\overline{\\alpha}\\langle0| + \\overline{\\beta}\\langle1|$</td>\n </tr>\n</table>\n\n<p>Kets and bras give us a neat way to express inner and outer products. The inner product of $|\\phi\\rangle$ and $|\\psi\\rangle$ is the matrix product of $\\langle\\phi|$ and $|\\psi\\rangle$, denoted as $\\langle\\phi|\\psi\\rangle$, and their outer product is the matrix product of $|\\phi\\rangle$ and $\\langle\\psi|$, denoted as $|\\phi\\rangle\\langle\\psi|$. Notice that the norm of $|\\psi\\rangle$ is $\\sqrt{\\langle\\psi|\\psi\\rangle}$.</p>\n<p>This brings us to representing matrices. Recall that the outer product of two vectors of the same size produces a square matrix. We can use a linear combination of several outer products of simple vectors (such as basis vectors) to express any square matrix. For example, the $X$ gate can be expressed as follows:</p>\n<p>$$X = |0\\rangle\\langle1| + |1\\rangle\\langle0|$$</p>\n<p>$$\n|0\\rangle\\langle1| + |1\\rangle\\langle0| =\n\\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix}\\begin{bmatrix} 0 & 1 \\end{bmatrix} +\n\\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix}\\begin{bmatrix} 1 & 0 \\end{bmatrix} =\n\\begin{bmatrix} 0 & 1 \\\\ 0 & 0 \\end{bmatrix} + \\begin{bmatrix} 0 & 0 \\\\ 1 & 0 \\end{bmatrix} =\n\\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix}\n$$</p>\n<p>This representation can be used to carry out calculations in Dirac notation without ever switching back to matrix representation:</p>\n<p>$$X|0\\rangle = \\big(|0\\rangle\\langle1| + |1\\rangle\\langle0|\\big)|0\\rangle = |0\\rangle\\langle1|0\\rangle + |1\\rangle\\langle0|0\\rangle = |0\\rangle\\big(\\langle1|0\\rangle\\big) + |1\\rangle\\big(\\langle0|0\\rangle\\big) = |0\\rangle(0) + |1\\rangle(1) = |1\\rangle$$</p>\n<blockquote>\n<p>That last step may seem a bit confusing. Recall that $|0\\rangle$ and $|1\\rangle$ form an <strong>orthonormal basis</strong>. That is, they are both normalized, and they are orthogonal to each other.</p>\n<p>A vector is normalized if its norm is equal to $1$, which only happens if its inner product with itself is equal to $1$. This means that $\\langle0|0\\rangle = \\langle1|1\\rangle = 1$</p>\n<p>Two vectors are orthogonal to each other if their inner product equals $0$. This means that $\\langle0|1\\rangle = \\langle 1|0\\rangle = 0$.</p>\n</blockquote>\n<p>In general case, a matrix \n$$A = \\begin{bmatrix} a_{00} & a_{01} \\\\ a_{10} & a_{11} \\end{bmatrix}$$\nwill have the following ket-bra representation:\n$$A = a_{00} |0\\rangle\\langle0| + a_{01} |0\\rangle\\langle1| + a_{10} |1\\rangle\\langle0| + a_{11} |1\\rangle\\langle1|$$</p>\n",
|
|
252
|
+
"asMarkdown": "\nThere is another way to represent quantum gates, this time using Dirac notation. However, the kets we've been using aren't enough to represent arbitrary matrices. We need to introduce another piece of notation: the **bra** (this is why Dirac notation is sometimes called **bra-ket notation**).\n\nRecall that kets represent column vectors; a bra is a ket's row vector counterpart. For any ket $|\\psi\\rangle$, the corresponding bra is its adjoint (conjugate transpose): $\\langle\\psi| = |\\psi\\rangle^\\dagger$.\n\nSome examples:\n\n<table>\n <tr>\n <th>Ket</th>\n <th>Bra</th>\n </tr>\n <tr>\n <td>$|0\\rangle = \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$</td>\n <td>$\\langle0| = \\begin{bmatrix} 1 & 0 \\end{bmatrix}$</td>\n </tr>\n <tr>\n <td>$|1\\rangle = \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$</td>\n <td>$\\langle1| = \\begin{bmatrix} 0 & 1 \\end{bmatrix}$</td>\n </tr>\n <tr>\n <td>$|i\\rangle = \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ \\frac{i}{\\sqrt{2}} \\end{bmatrix}$</td>\n <td>$\\langle i| = \\begin{bmatrix} \\frac{1}{\\sqrt{2}} & -\\frac{i}{\\sqrt{2}} \\end{bmatrix}$</td>\n </tr>\n <tr>\n <td>$|\\psi\\rangle = \\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix}$</td>\n <td>$\\langle\\psi| = \\begin{bmatrix} \\overline{\\alpha} & \\overline{\\beta} \\end{bmatrix}$</td>\n </tr>\n <tr>\n <td>$|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$</td>\n <td>$\\langle\\psi| = \\overline{\\alpha}\\langle0| + \\overline{\\beta}\\langle1|$</td>\n </tr>\n</table>\n\nKets and bras give us a neat way to express inner and outer products. The inner product of $|\\phi\\rangle$ and $|\\psi\\rangle$ is the matrix product of $\\langle\\phi|$ and $|\\psi\\rangle$, denoted as $\\langle\\phi|\\psi\\rangle$, and their outer product is the matrix product of $|\\phi\\rangle$ and $\\langle\\psi|$, denoted as $|\\phi\\rangle\\langle\\psi|$. Notice that the norm of $|\\psi\\rangle$ is $\\sqrt{\\langle\\psi|\\psi\\rangle}$.\n\nThis brings us to representing matrices. Recall that the outer product of two vectors of the same size produces a square matrix. We can use a linear combination of several outer products of simple vectors (such as basis vectors) to express any square matrix. For example, the $X$ gate can be expressed as follows:\n\n$$X = |0\\rangle\\langle1| + |1\\rangle\\langle0|$$\n\n$$\n|0\\rangle\\langle1| + |1\\rangle\\langle0| =\n\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}\\begin{bmatrix} 0 & 1 \\end{bmatrix} +\n\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}\\begin{bmatrix} 1 & 0 \\end{bmatrix} =\n\\begin{bmatrix} 0 & 1 \\\\\\ 0 & 0 \\end{bmatrix} + \\begin{bmatrix} 0 & 0 \\\\\\ 1 & 0 \\end{bmatrix} =\n\\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix}\n$$\n\nThis representation can be used to carry out calculations in Dirac notation without ever switching back to matrix representation:\n\n$$X|0\\rangle = \\big(|0\\rangle\\langle1| + |1\\rangle\\langle0|\\big)|0\\rangle = |0\\rangle\\langle1|0\\rangle + |1\\rangle\\langle0|0\\rangle = |0\\rangle\\big(\\langle1|0\\rangle\\big) + |1\\rangle\\big(\\langle0|0\\rangle\\big) = |0\\rangle(0) + |1\\rangle(1) = |1\\rangle$$\n\n> That last step may seem a bit confusing. Recall that $|0\\rangle$ and $|1\\rangle$ form an **orthonormal basis**. That is, they are both normalized, and they are orthogonal to each other.\n>\n> A vector is normalized if its norm is equal to $1$, which only happens if its inner product with itself is equal to $1$. This means that $\\langle0|0\\rangle = \\langle1|1\\rangle = 1$\n>\n> Two vectors are orthogonal to each other if their inner product equals $0$. This means that $\\langle0|1\\rangle = \\langle 1|0\\rangle = 0$.\n\nIn general case, a matrix \n$$A = \\begin{bmatrix} a_{00} & a_{01} \\\\\\ a_{10} & a_{11} \\end{bmatrix}$$\nwill have the following ket-bra representation:\n$$A = a_{00} |0\\rangle\\langle0| + a_{01} |0\\rangle\\langle1| + a_{10} |1\\rangle\\langle0| + a_{11} |1\\rangle\\langle1|$$"
|
|
253
|
+
}
|
|
254
|
+
]
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"type": "lesson",
|
|
258
|
+
"id": "single_qubit_gates__ket_bra_decomposition",
|
|
259
|
+
"title": "Ket-Bra Decomposition",
|
|
260
|
+
"items": [
|
|
261
|
+
{
|
|
262
|
+
"type": "text-content",
|
|
263
|
+
"asHtml": "<p>This section describes a more formal process of finding the ket-bra decompositions of quantum gates. This section is not necessary to start working with quantum gates, so feel free to skip it for now, and come back to it later.</p>\n<p>You can use the properties of <em>eigenvalues</em> and <em>eigenvectors</em> to find the ket-bra decomposition of any gate. Given a gate $A$ and the orthogonal vectors $|\\phi\\rangle$ and $|\\psi\\rangle$, if:</p>\n<p>$$A|\\phi\\rangle = x_\\phi|\\phi\\rangle$$\n$$A|\\psi\\rangle = x_\\psi|\\psi\\rangle$$</p>\n<p>Real numbers $x_\\phi$ and $x_\\psi$ are called eigenvalues and $|\\phi\\rangle$ and $|\\psi\\rangle$ are eigenvectors of $A$. Then:</p>\n<p>$$A = x_\\phi|\\phi\\rangle\\langle\\phi| + x_\\psi|\\psi\\rangle\\langle\\psi|$$</p>\n<p>Let's use our $X$ gate as a simple example. The $X$ gate has two eigenvectors: $|+\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle + |1\\rangle\\big)$ and $|-\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle - |1\\rangle\\big)$. Their eigenvalues are $1$ and $-1$ respectively:</p>\n<p>$$X|+\\rangle = |+\\rangle$$\n$$X|-\\rangle = -|-\\rangle$$</p>\n<p>Here's what the decomposition looks like:\n$$X = |+\\rangle\\langle+| - |-\\rangle\\langle-| =$$\n$$\\frac{1}{2}\\big[\\big(|0\\rangle + |1\\rangle\\big)\\big(\\langle0| + \\langle1|\\big) - \\big(|0\\rangle - |1\\rangle\\big)\\big(\\langle0| - \\langle1|\\big)\\big] =$$\n$$\\frac{1}{2}\\big(|0\\rangle\\langle0| + |0\\rangle\\langle1| + |1\\rangle\\langle0| + |1\\rangle\\langle1| - |0\\rangle\\langle0| + |0\\rangle\\langle1| + |1\\rangle\\langle0| - |1\\rangle\\langle1|\\big) =$$\n$$\\frac{1}{2}\\big(2|0\\rangle\\langle1| + 2|1\\rangle\\langle0|\\big) =$$\n$$|0\\rangle\\langle1| + |1\\rangle\\langle0|$$</p>\n",
|
|
264
|
+
"asMarkdown": "\nThis section describes a more formal process of finding the ket-bra decompositions of quantum gates. This section is not necessary to start working with quantum gates, so feel free to skip it for now, and come back to it later.\n\nYou can use the properties of _eigenvalues_ and _eigenvectors_ to find the ket-bra decomposition of any gate. Given a gate $A$ and the orthogonal vectors $|\\phi\\rangle$ and $|\\psi\\rangle$, if:\n\n$$A|\\phi\\rangle = x_\\phi|\\phi\\rangle$$\n$$A|\\psi\\rangle = x_\\psi|\\psi\\rangle$$\n\nReal numbers $x_\\phi$ and $x_\\psi$ are called eigenvalues and $|\\phi\\rangle$ and $|\\psi\\rangle$ are eigenvectors of $A$. Then:\n\n$$A = x_\\phi|\\phi\\rangle\\langle\\phi| + x_\\psi|\\psi\\rangle\\langle\\psi|$$\n\nLet's use our $X$ gate as a simple example. The $X$ gate has two eigenvectors: $|+\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle + |1\\rangle\\big)$ and $|-\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle - |1\\rangle\\big)$. Their eigenvalues are $1$ and $-1$ respectively:\n\n$$X|+\\rangle = |+\\rangle$$\n$$X|-\\rangle = -|-\\rangle$$\n\nHere's what the decomposition looks like:\n$$X = |+\\rangle\\langle+| - |-\\rangle\\langle-| =$$\n$$\\frac{1}{2}\\big[\\big(|0\\rangle + |1\\rangle\\big)\\big(\\langle0| + \\langle1|\\big) - \\big(|0\\rangle - |1\\rangle\\big)\\big(\\langle0| - \\langle1|\\big)\\big] =$$\n$$\\frac{1}{2}\\big(|0\\rangle\\langle0| + |0\\rangle\\langle1| + |1\\rangle\\langle0| + |1\\rangle\\langle1| - |0\\rangle\\langle0| + |0\\rangle\\langle1| + |1\\rangle\\langle0| - |1\\rangle\\langle1|\\big) =$$\n$$\\frac{1}{2}\\big(2|0\\rangle\\langle1| + 2|1\\rangle\\langle0|\\big) =$$\n$$|0\\rangle\\langle1| + |1\\rangle\\langle0|$$"
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"type": "lesson",
|
|
270
|
+
"id": "single_qubit_gates__important_gates",
|
|
271
|
+
"title": "Pauli Gates",
|
|
272
|
+
"items": [
|
|
273
|
+
{
|
|
274
|
+
"type": "text-content",
|
|
275
|
+
"asHtml": "<p>This section introduces some of the common single-qubit gates, including their matrix form, their ket-bra decomposition, and a brief "cheatsheet" listing their effect on some common qubit states.</p>\n<p>You can use a tool called <a href=\"https://algassert.com/quirk\" target=\"_blank\">Quirk</a> to visualize how these gates interact with various qubit states.</p>\n<p>This section relies on the following notation:</p>\n<table>\n <tr>\n <td>$|+\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle + |1\\rangle\\big)$</td>\n <td>$|-\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle - |1\\rangle\\big)$</td>\n </tr>\n <tr>\n <td>$|i\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle + i|1\\rangle\\big)$</td>\n <td>$|-i\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle - i|1\\rangle\\big)$</td>\n </tr>\n</table>\n\n<p>The Pauli gates, named after <a href=\"https://en.wikipedia.org/wiki/Wolfgang_Pauli\" target=\"_blank\">Wolfgang Pauli</a>, are based on the so-called <strong>Pauli matrices</strong>, $X$, $Y$ and $Z$. All three Pauli gates are <strong>self-adjoint</strong>, meaning that each one is its own inverse, $XX = \\mathbb{I}$.</p>\n<table>\n <tr>\n <th>Gate</th>\n <th>Matrix</th>\n <th>Ket-Bra</th>\n <th>Applying to $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$</th>\n <th>Applying to basis states</th>\n <th>Q# Documentation</th>\n </tr>\n <tr>\n <td>$X$</td>\n <td>$\\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix}$</td>\n <td>$|0\\rangle\\langle1| + |1\\rangle\\langle0|$</td>\n <td>$X|\\psi\\rangle = \\alpha|1\\rangle + \\beta|0\\rangle$</td>\n <td>\n $X|0\\rangle = |1\\rangle$<br>\n $X|1\\rangle = |0\\rangle$<br>\n $X|+\\rangle = |+\\rangle$<br>\n $X|-\\rangle = -|-\\rangle$<br>\n $X|i\\rangle = i|-i\\rangle$<br>\n $X|-i\\rangle = -i|i\\rangle$\n </td>\n <td><a href=\"https://learn.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.x\" target=\"_blank\">X</a></td>\n </tr>\n <tr>\n <td>$Y$</td>\n <td>$\\begin{bmatrix} 0 & -i \\\\\\ i & 0 \\end{bmatrix}$</td>\n <td>$i(|1\\rangle\\langle0| - |0\\rangle\\langle1|)$</td>\n <td>$Y|\\psi\\rangle = i\\big(\\alpha|1\\rangle - \\beta|0\\rangle\\big)$</td>\n <td>\n $Y|0\\rangle = i|1\\rangle$<br>\n $Y|1\\rangle = -i|0\\rangle$<br>\n $Y|+\\rangle = -i|-\\rangle$<br>\n $Y|-\\rangle = i|+\\rangle$<br>\n $Y|i\\rangle = |i\\rangle$<br>\n $Y|-i\\rangle = -|-i\\rangle$<br>\n </td>\n <td><a href=\"https://learn.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.y\" target=\"_blank\">Y</a></td>\n </tr>\n <tr>\n <td>$Z$</td>\n <td>$\\begin{bmatrix} 1 & 0 \\\\\\ 0 & -1 \\end{bmatrix}$</td>\n <td>$|0\\rangle\\langle0| - |1\\rangle\\langle1|$</td>\n <td>$Z|\\psi\\rangle = \\alpha|0\\rangle - \\beta|1\\rangle$</td>\n <td>\n $Z|0\\rangle = |0\\rangle$<br>\n $Z|1\\rangle = -|1\\rangle$<br>\n $Z|+\\rangle = |-\\rangle$<br>\n $Z|-\\rangle = |+\\rangle$<br>\n $Z|i\\rangle = |-i\\rangle$<br>\n $Z|-i\\rangle = |i\\rangle$<br>\n </td>\n <td><a href=\"https://learn.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.z\" target=\"_blank\">Z</a></td>\n </tr>\n</table>\n\n<blockquote>\n<p>The $X$ gate is sometimes referred to as the <strong>bit flip</strong> gate, or the <strong>NOT</strong> gate, because it acts like the classical NOT gate on the computational basis.</p>\n<p>The $Z$ gate is sometimes referred to as the <strong>phase flip</strong> gate.</p>\n</blockquote>\n<p>Here are several properties of the Pauli gates that are easy to verify and convenient to remember:</p>\n<ul>\n<li>Different Pauli gates <em>anti-commute</em>:\n$$XZ = -ZX, XY = -YX, YZ = -ZY$$</li>\n<li>A product of any two Pauli gates equals the third gate, with an extra $i$ (or $-i$) phase:\n$$XY = iZ, YZ = iX, ZX = iY$$ </li>\n<li>A product of all three Pauli gates equals identity (with an extra $i$ phase):\n$$XYZ = iI$$</li>\n</ul>\n",
|
|
276
|
+
"asMarkdown": "\nThis section introduces some of the common single-qubit gates, including their matrix form, their ket-bra decomposition, and a brief \"cheatsheet\" listing their effect on some common qubit states.\n\nYou can use a tool called <a href=\"https://algassert.com/quirk\" target=\"_blank\">Quirk</a> to visualize how these gates interact with various qubit states.\n\nThis section relies on the following notation:\n\n<table>\n <tr>\n <td>$|+\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle + |1\\rangle\\big)$</td>\n <td>$|-\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle - |1\\rangle\\big)$</td>\n </tr>\n <tr>\n <td>$|i\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle + i|1\\rangle\\big)$</td>\n <td>$|-i\\rangle = \\frac{1}{\\sqrt{2}}\\big(|0\\rangle - i|1\\rangle\\big)$</td>\n </tr>\n</table>\n\nThe Pauli gates, named after <a href=\"https://en.wikipedia.org/wiki/Wolfgang_Pauli\" target=\"_blank\">Wolfgang Pauli</a>, are based on the so-called **Pauli matrices**, $X$, $Y$ and $Z$. All three Pauli gates are **self-adjoint**, meaning that each one is its own inverse, $XX = \\mathbb{I}$.\n\n<table>\n <tr>\n <th>Gate</th>\n <th>Matrix</th>\n <th>Ket-Bra</th>\n <th>Applying to $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$</th>\n <th>Applying to basis states</th>\n <th>Q# Documentation</th>\n </tr>\n <tr>\n <td>$X$</td>\n <td>$\\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix}$</td>\n <td>$|0\\rangle\\langle1| + |1\\rangle\\langle0|$</td>\n <td>$X|\\psi\\rangle = \\alpha|1\\rangle + \\beta|0\\rangle$</td>\n <td>\n $X|0\\rangle = |1\\rangle$<br>\n $X|1\\rangle = |0\\rangle$<br>\n $X|+\\rangle = |+\\rangle$<br>\n $X|-\\rangle = -|-\\rangle$<br>\n $X|i\\rangle = i|-i\\rangle$<br>\n $X|-i\\rangle = -i|i\\rangle$\n </td>\n <td><a href=\"https://learn.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.x\" target=\"_blank\">X</a></td>\n </tr>\n <tr>\n <td>$Y$</td>\n <td>$\\begin{bmatrix} 0 & -i \\\\\\ i & 0 \\end{bmatrix}$</td>\n <td>$i(|1\\rangle\\langle0| - |0\\rangle\\langle1|)$</td>\n <td>$Y|\\psi\\rangle = i\\big(\\alpha|1\\rangle - \\beta|0\\rangle\\big)$</td>\n <td>\n $Y|0\\rangle = i|1\\rangle$<br>\n $Y|1\\rangle = -i|0\\rangle$<br>\n $Y|+\\rangle = -i|-\\rangle$<br>\n $Y|-\\rangle = i|+\\rangle$<br>\n $Y|i\\rangle = |i\\rangle$<br>\n $Y|-i\\rangle = -|-i\\rangle$<br>\n </td>\n <td><a href=\"https://learn.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.y\" target=\"_blank\">Y</a></td>\n </tr>\n <tr>\n <td>$Z$</td>\n <td>$\\begin{bmatrix} 1 & 0 \\\\\\ 0 & -1 \\end{bmatrix}$</td>\n <td>$|0\\rangle\\langle0| - |1\\rangle\\langle1|$</td>\n <td>$Z|\\psi\\rangle = \\alpha|0\\rangle - \\beta|1\\rangle$</td>\n <td>\n $Z|0\\rangle = |0\\rangle$<br>\n $Z|1\\rangle = -|1\\rangle$<br>\n $Z|+\\rangle = |-\\rangle$<br>\n $Z|-\\rangle = |+\\rangle$<br>\n $Z|i\\rangle = |-i\\rangle$<br>\n $Z|-i\\rangle = |i\\rangle$<br>\n </td>\n <td><a href=\"https://learn.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.z\" target=\"_blank\">Z</a></td>\n </tr>\n</table>\n\n> The $X$ gate is sometimes referred to as the **bit flip** gate, or the **NOT** gate, because it acts like the classical NOT gate on the computational basis.\n>\n> The $Z$ gate is sometimes referred to as the **phase flip** gate.\n\nHere are several properties of the Pauli gates that are easy to verify and convenient to remember:\n\n- Different Pauli gates *anti-commute*:\n $$XZ = -ZX, XY = -YX, YZ = -ZY$$\n- A product of any two Pauli gates equals the third gate, with an extra $i$ (or $-i$) phase:\n $$XY = iZ, YZ = iX, ZX = iY$$ \n- A product of all three Pauli gates equals identity (with an extra $i$ phase):\n $$XYZ = iI$$"
|
|
277
|
+
}
|
|
278
|
+
]
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
"type": "lesson",
|
|
282
|
+
"id": "single_qubit_gates__pauli_gates_in_qsharp",
|
|
283
|
+
"title": "Pauli Gates in Q#",
|
|
284
|
+
"items": [
|
|
285
|
+
{
|
|
286
|
+
"type": "text-content",
|
|
287
|
+
"asHtml": "<p>The following example contains code demonstrating how to apply gates in Q#, using the Pauli $X$ gate as an example. It sets up a series of quantum states, and then shows the result of applying the $X$ gate to each one.</p>\n<p>In the previous kata we discussed that qubit state in Q# cannot be directly assigned or accessed. The same logic is extended to quantum gates: applying a gate to a qubit modifies the internal state of that qubit, but doesn't return the resulting state of the qubit. This is why we never assign the output of these gates to any variables in this demo - they don't produce any output.</p>\n<p>The same principle applies to successive qubit gates. In the mathematical notation, applying an $X$ gate followed by a $Z$ gate to a state $|\\psi\\rangle$ is denoted as $Z(X(|\\psi\\rangle))$ because the result of applying a gate to a state is another state. In Q#, applying a gate doesn't return anything, so you can't use its output as an input to another gate - something like <code>Z(X(q))</code> will not produce the expected result. Instead, to apply several gates to the same qubit, you need to call them separately in the order in which they are applied:</p>\n<pre><code class=\"language-qsharp\">X(q);\nZ(q);\n</code></pre>\n<p>All the basic gates we will be covering in this kata are part of the <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic\" target=\"_blank\">Intrinsic</a> namespace. We're also using the function <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.diagnostics.dumpmachine\" target=\"_blank\">DumpMachine</a> to print the state of the quantum simulator.</p>\n",
|
|
288
|
+
"asMarkdown": "\nThe following example contains code demonstrating how to apply gates in Q#, using the Pauli $X$ gate as an example. It sets up a series of quantum states, and then shows the result of applying the $X$ gate to each one.\n\nIn the previous kata we discussed that qubit state in Q# cannot be directly assigned or accessed. The same logic is extended to quantum gates: applying a gate to a qubit modifies the internal state of that qubit, but doesn't return the resulting state of the qubit. This is why we never assign the output of these gates to any variables in this demo - they don't produce any output.\n\nThe same principle applies to successive qubit gates. In the mathematical notation, applying an $X$ gate followed by a $Z$ gate to a state $|\\psi\\rangle$ is denoted as $Z(X(|\\psi\\rangle))$ because the result of applying a gate to a state is another state. In Q#, applying a gate doesn't return anything, so you can't use its output as an input to another gate - something like `Z(X(q))` will not produce the expected result. Instead, to apply several gates to the same qubit, you need to call them separately in the order in which they are applied:\n\n```qsharp\nX(q);\nZ(q);\n```\n\nAll the basic gates we will be covering in this kata are part of the <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic\" target=\"_blank\">Intrinsic</a> namespace. We're also using the function <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.diagnostics.dumpmachine\" target=\"_blank\">DumpMachine</a> to print the state of the quantum simulator."
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"type": "example",
|
|
292
|
+
"id": "single_qubit_gates__pauli_gates_in_qsharp_demo",
|
|
293
|
+
"code": "namespace Demo {\n // To use elements from a namespace, you need to use the `open` keyword to\n // access them.\n open Microsoft.Quantum.Diagnostics;\n\n @EntryPoint()\n operation PauliGatesUsage () : Unit {\n // This allocates a qubit for us to work with.\n use q = Qubit();\n\n // This will put the qubit into an uneven superposition |𝜓❭, where the\n // amplitudes of |0⟩ and |1⟩ have different absolute values.\n Ry(1.0, q);\n\n Message(\"Qubit in state |𝜓❭:\");\n DumpMachine();\n\n // Let's apply the X gate; notice how it swaps the amplitudes of the\n // |0❭ and |1❭ basis states.\n X(q);\n Message(\"Qubit in state X|𝜓❭:\");\n DumpMachine();\n\n // Applying the Z gate adds -1 relative phase to the |1❭ basis states.\n Z(q);\n Message(\"Qubit in state ZX|𝜓❭:\");\n DumpMachine();\n\n // Finally, applying the Y gate returns the qubit to its original state\n // |𝜓❭, with an extra global phase of i.\n Y(q);\n Message(\"Qubit in state YZX|𝜓❭:\");\n DumpMachine();\n\n // This returns the qubit to state |0❭.\n Reset(q);\n }\n}\n"
|
|
294
|
+
}
|
|
295
|
+
]
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
"type": "exercise",
|
|
299
|
+
"id": "single_qubit_gates__y_gate",
|
|
300
|
+
"title": "The Y Gate",
|
|
301
|
+
"description": {
|
|
302
|
+
"type": "text-content",
|
|
303
|
+
"asHtml": "<p><strong>Input:</strong> A qubit in an arbitrary state $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$.</p>\n<p><strong>Goal:</strong> Apply the Y gate to the qubit, i.e., transform the given state into $i\\alpha|1\\rangle - i\\beta|0\\rangle$.</p>\n",
|
|
304
|
+
"asMarkdown": "**Input:** A qubit in an arbitrary state $|\\\\psi\\\\rangle = \\\\alpha|0\\\\rangle + \\\\beta|1\\\\rangle$.\n\n**Goal:** Apply the Y gate to the qubit, i.e., transform the given state into $i\\\\alpha|1\\\\rangle - i\\\\beta|0\\\\rangle$."
|
|
305
|
+
},
|
|
306
|
+
"sourceIds": [
|
|
307
|
+
"KatasLibrary.qs",
|
|
308
|
+
"single_qubit_gates__y_gate__Verification.qs"
|
|
309
|
+
],
|
|
310
|
+
"placeholderCode": "namespace Kata {\n operation ApplyY(q : Qubit) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}",
|
|
311
|
+
"explainedSolution": {
|
|
312
|
+
"type": "explained-solution",
|
|
313
|
+
"items": [
|
|
314
|
+
{
|
|
315
|
+
"type": "text-content",
|
|
316
|
+
"asHtml": "<p>We have to do exactly what the task asks us to do: apply the Pauli gate $Y=\\begin{bmatrix} 0 & -i \\\\ i & 0 \\end{bmatrix}$.</p>\n<p>This has the effect of turning $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$ into $Y|\\psi\\rangle = i\\alpha|1\\rangle - i\\beta|0\\rangle$, which in matrix form looks as follows:\n$$\n\\begin{bmatrix} 0 & -i \\\\ i & 0 \\end{bmatrix} \\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} = \n\\begin{bmatrix} -i\\beta \\\\ i\\alpha \\end{bmatrix}\n$$</p>\n",
|
|
317
|
+
"asMarkdown": "\nWe have to do exactly what the task asks us to do: apply the Pauli gate $Y=\\\\begin{bmatrix} 0 & -i \\\\\\\\ i & 0 \\\\end{bmatrix}$.\n\nThis has the effect of turning $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$ into $Y|\\psi\\rangle = i\\alpha|1\\rangle - i\\beta|0\\rangle$, which in matrix form looks as follows:\n$$\n\\begin{bmatrix} 0 & -i \\\\\\ i & 0 \\end{bmatrix} \\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix} = \n\\begin{bmatrix} -i\\beta \\\\\\ i\\alpha \\end{bmatrix}\n$$"
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
"type": "solution",
|
|
321
|
+
"id": "single_qubit_gates__y_gate_solution",
|
|
322
|
+
"code": "namespace Kata {\n operation ApplyY(q : Qubit) : Unit is Adj + Ctl {\n Y(q); // As simple as this.\n }\n}"
|
|
323
|
+
}
|
|
324
|
+
]
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
"type": "exercise",
|
|
329
|
+
"id": "single_qubit_gates__global_phase_i",
|
|
330
|
+
"title": "Applying a Global Phase",
|
|
331
|
+
"description": {
|
|
332
|
+
"type": "text-content",
|
|
333
|
+
"asHtml": "<p><strong>Input:</strong> A qubit in an arbitrary state $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$.</p>\n<p><strong>Goal:</strong> Use several Pauli gates to change the qubit state to $i|\\psi\\rangle = i\\alpha|0\\rangle + i\\beta|1\\rangle$.</p>\n",
|
|
334
|
+
"asMarkdown": "**Input:** A qubit in an arbitrary state $|\\\\psi\\\\rangle = \\\\alpha|0\\\\rangle + \\\\beta|1\\\\rangle$.\n\n**Goal:** Use several Pauli gates to change the qubit state to $i|\\\\psi\\\\rangle = i\\\\alpha|0\\\\rangle + i\\\\beta|1\\\\rangle$."
|
|
335
|
+
},
|
|
336
|
+
"sourceIds": [
|
|
337
|
+
"KatasLibrary.qs",
|
|
338
|
+
"single_qubit_gates__global_phase_i__Verification.qs"
|
|
339
|
+
],
|
|
340
|
+
"placeholderCode": "namespace Kata {\n operation GlobalPhaseI(q : Qubit) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}",
|
|
341
|
+
"explainedSolution": {
|
|
342
|
+
"type": "explained-solution",
|
|
343
|
+
"items": [
|
|
344
|
+
{
|
|
345
|
+
"type": "text-content",
|
|
346
|
+
"asHtml": "<p>We need to apply a gate which applies a global phase of $i$, i.e. $|\\psi\\rangle \\rightarrow i|\\psi\\rangle$.\nThe matrix representation of such a gate is $\\begin{bmatrix} i & 0 \\\\ 0 & i \\end{bmatrix} = i\\begin{bmatrix} 1 & 0 \\\\ 0 & 1 \\end{bmatrix} = iI$.\nSince we are restricted to the Pauli gates, we use the property that a product of any two distinct Pauli gates equals the third gate with a $+i$ or a $-i$ global phase: $-iXYZ=I$. This can be restated as $XYZ = iI$.\n$$\n\\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix}\\begin{bmatrix} 0 & -i \\\\ i & 0 \\end{bmatrix}\\begin{bmatrix} 1 & 0 \\\\ 0 & -1 \\end{bmatrix} = \n\\begin{bmatrix} i & 0 \\\\ 0 & i \\end{bmatrix}\n$$</p>\n<blockquote>\n<p>Remember the rightmost gates in mathematical notation are applied first in Q# code. Hence we first apply the $Z$ gate, followed by the $Y$ gate, and finally the $X$ gate.</p>\n</blockquote>\n",
|
|
347
|
+
"asMarkdown": "\nWe need to apply a gate which applies a global phase of $i$, i.e. $|\\psi\\rangle \\rightarrow i|\\psi\\rangle$.\nThe matrix representation of such a gate is $\\begin{bmatrix} i & 0 \\\\\\ 0 & i \\end{bmatrix} = i\\begin{bmatrix} 1 & 0 \\\\\\ 0 & 1 \\end{bmatrix} = iI$.\nSince we are restricted to the Pauli gates, we use the property that a product of any two distinct Pauli gates equals the third gate with a $+i$ or a $-i$ global phase: $-iXYZ=I$. This can be restated as $XYZ = iI$.\n$$\n\\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix}\\begin{bmatrix} 0 & -i \\\\\\ i & 0 \\end{bmatrix}\\begin{bmatrix} 1 & 0 \\\\\\ 0 & -1 \\end{bmatrix} = \n\\begin{bmatrix} i & 0 \\\\\\ 0 & i \\end{bmatrix}\n$$\n\n> Remember the rightmost gates in mathematical notation are applied first in Q# code. Hence we first apply the $Z$ gate, followed by the $Y$ gate, and finally the $X$ gate."
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
"type": "solution",
|
|
351
|
+
"id": "single_qubit_gates__global_phase_i_solution",
|
|
352
|
+
"code": "namespace Kata {\n operation GlobalPhaseI(q : Qubit) : Unit is Adj + Ctl {\n X(q);\n Z(q);\n Y(q);\n }\n}"
|
|
353
|
+
}
|
|
354
|
+
]
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
"type": "exercise",
|
|
359
|
+
"id": "single_qubit_gates__sign_flip_on_zero",
|
|
360
|
+
"title": "Sign Flip on Zero",
|
|
361
|
+
"description": {
|
|
362
|
+
"type": "text-content",
|
|
363
|
+
"asHtml": "<p><strong>Input:</strong> A qubit in an arbitrary state $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$.</p>\n<p><strong>Goal:</strong> Use several Pauli gates to change the qubit state to $- \\alpha|0\\rangle + \\beta|1\\rangle$, i.e., apply the transformation represented by the following matrix::</p>\n<p>$$\\begin{bmatrix} -1 & 0 \\\\ 0 & 1 \\end{bmatrix}$$</p>\n",
|
|
364
|
+
"asMarkdown": "**Input:** A qubit in an arbitrary state $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$.\n\n**Goal:** Use several Pauli gates to change the qubit state to $- \\alpha|0\\rangle + \\beta|1\\rangle$, i.e., apply the transformation represented by the following matrix::\n\n$$\\begin{bmatrix} -1 & 0 \\\\\\ 0 & 1 \\end{bmatrix}$$"
|
|
365
|
+
},
|
|
366
|
+
"sourceIds": [
|
|
367
|
+
"KatasLibrary.qs",
|
|
368
|
+
"single_qubit_gates__sign_flip_on_zero__Verification.qs"
|
|
369
|
+
],
|
|
370
|
+
"placeholderCode": "namespace Kata {\n operation SignFlipOnZero (q : Qubit) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
371
|
+
"explainedSolution": {
|
|
372
|
+
"type": "explained-solution",
|
|
373
|
+
"items": [
|
|
374
|
+
{
|
|
375
|
+
"type": "text-content",
|
|
376
|
+
"asHtml": "<p>The first thing to notice is that the gate $\\begin{bmatrix} -1 & 0 \\\\ 0 & 1 \\end{bmatrix}$ is quite similar to the Pauli $Z$ gate $\\begin{bmatrix} 1 & 0 \\\\ 0 & -1 \\end{bmatrix}$.\nThe only difference being that the negative phase is applied on the $|0\\rangle$ instead of $|1\\rangle$. Hence we can simulate this gate by switching $|0\\rangle$ and $|1\\rangle$ states, applying the Pauli $Z$ gate and switching them back. The Pauli $X$ gate (also called the $NOT$ gate or the bit flip gate) is the perfect gate to flip the state of the qubit and to undo the action afterwards.</p>\n<p>Hence we can express the $Z_0 = \\begin{bmatrix} -1 & 0 \\\\ 0 & 1 \\end{bmatrix}$ matrix as</p>\n<p>$$\nZ_0 =\n\\begin{bmatrix} -1 & 0 \\\\ 0 & 1 \\end{bmatrix} = \n\\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix} \\begin{bmatrix} 1 & 0 \\\\ 0 & -1 \\end{bmatrix} \\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix} = \nXZX\n$$</p>\n",
|
|
377
|
+
"asMarkdown": "\nThe first thing to notice is that the gate $\\begin{bmatrix} -1 & 0 \\\\\\ 0 & 1 \\end{bmatrix}$ is quite similar to the Pauli $Z$ gate $\\begin{bmatrix} 1 & 0 \\\\\\ 0 & -1 \\end{bmatrix}$.\nThe only difference being that the negative phase is applied on the $|0\\rangle$ instead of $|1\\rangle$. Hence we can simulate this gate by switching $|0\\rangle$ and $|1\\rangle$ states, applying the Pauli $Z$ gate and switching them back. The Pauli $X$ gate (also called the $NOT$ gate or the bit flip gate) is the perfect gate to flip the state of the qubit and to undo the action afterwards.\n\nHence we can express the $Z_0 = \\begin{bmatrix} -1 & 0 \\\\\\ 0 & 1 \\end{bmatrix}$ matrix as\n\n$$\nZ_0 =\n\\begin{bmatrix} -1 & 0 \\\\\\ 0 & 1 \\end{bmatrix} = \n\\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix} \\begin{bmatrix} 1 & 0 \\\\\\ 0 & -1 \\end{bmatrix} \\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix} = \nXZX\n$$"
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"type": "solution",
|
|
381
|
+
"id": "single_qubit_gates__sign_flip_on_zero_solution",
|
|
382
|
+
"code": "namespace Kata {\n operation SignFlipOnZero (q : Qubit) : Unit is Adj+Ctl {\n X(q);\n Z(q);\n X(q);\n }\n}\n"
|
|
383
|
+
}
|
|
384
|
+
]
|
|
385
|
+
}
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
"type": "exercise",
|
|
389
|
+
"id": "single_qubit_gates__prepare_minus",
|
|
390
|
+
"title": "Prepare Minus",
|
|
391
|
+
"description": {
|
|
392
|
+
"type": "text-content",
|
|
393
|
+
"asHtml": "<p><strong>Input:</strong> A qubit in state $|0\\rangle$.</p>\n<p><strong>Goal:</strong> Transform the qubit into state $|-\\rangle$.</p>\n",
|
|
394
|
+
"asMarkdown": "**Input:** A qubit in state $|0\\rangle$.\n\n**Goal:** Transform the qubit into state $|-\\rangle$."
|
|
395
|
+
},
|
|
396
|
+
"sourceIds": [
|
|
397
|
+
"KatasLibrary.qs",
|
|
398
|
+
"single_qubit_gates__prepare_minus__Verification.qs"
|
|
399
|
+
],
|
|
400
|
+
"placeholderCode": "namespace Kata {\n operation PrepareMinus(q : Qubit) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
401
|
+
"explainedSolution": {
|
|
402
|
+
"type": "explained-solution",
|
|
403
|
+
"items": [
|
|
404
|
+
{
|
|
405
|
+
"type": "text-content",
|
|
406
|
+
"asHtml": "<p>We know that applying the Hadamard gate $H$ on the computational basis states $|0\\rangle$ and $|1\\rangle$ results in Hadamard basis states $|+\\rangle$ and $|-\\rangle$, respectively.\nWe are given a qubit in the state $|0\\rangle$. We first apply the Pauli $X$ gate to turn it into $X|0\\rangle=|1\\rangle$, and then apply the $H$ gate, turning the qubit into the required $H|1\\rangle=|-\\rangle$ state.</p>\n",
|
|
407
|
+
"asMarkdown": "\nWe know that applying the Hadamard gate $H$ on the computational basis states $|0\\rangle$ and $|1\\rangle$ results in Hadamard basis states $|+\\rangle$ and $|-\\rangle$, respectively.\nWe are given a qubit in the state $|0\\rangle$. We first apply the Pauli $X$ gate to turn it into $X|0\\rangle=|1\\rangle$, and then apply the $H$ gate, turning the qubit into the required $H|1\\rangle=|-\\rangle$ state."
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
"type": "solution",
|
|
411
|
+
"id": "single_qubit_gates__prepare_minus_solution",
|
|
412
|
+
"code": "namespace Kata {\n operation PrepareMinus (q : Qubit) : Unit is Adj+Ctl {\n X(q);\n H(q);\n }\n}\n"
|
|
413
|
+
}
|
|
414
|
+
]
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
"type": "lesson",
|
|
419
|
+
"id": "single_qubit_gates__phase_shift_gates",
|
|
420
|
+
"title": "Phase Shift Gates",
|
|
421
|
+
"items": [
|
|
422
|
+
{
|
|
423
|
+
"type": "text-content",
|
|
424
|
+
"asHtml": "<p>The next two gates are known as phase shift gates. They apply a phase to the $|1\\rangle$ state, and leave the $|0\\rangle$ state unchanged.</p>\n<table>\n <tr>\n <th>Gate</th>\n <th>Matrix</th>\n <th>Ket-Bra</th>\n <th>Applying to $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$</th>\n <th>Applying to basis states</th>\n <th>Q# Documentation</th>\n </tr>\n <tr>\n <td>$S$</td>\n <td>$\\begin{bmatrix} 1 & 0 \\\\\\ 0 & i \\end{bmatrix}$</td>\n <td>$|0\\rangle\\langle0| + i|1\\rangle\\langle1|$</td>\n <td>$S|\\psi\\rangle = \\alpha|0\\rangle + i\\beta|1\\rangle$</td>\n <td>\n $S|0\\rangle = |0\\rangle$<br>\n $S|1\\rangle = i|1\\rangle$<br>\n $S|+\\rangle = |i\\rangle$<br>\n $S|-\\rangle = |-i\\rangle$<br>\n $S|i\\rangle = |-\\rangle$<br>\n $S|-i\\rangle = |+\\rangle$<br>\n </td>\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.s\" target=\"_blank\">S</a></td>\n </tr>\n <tr>\n <td>$T$</td>\n <td>$\\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i\\pi/4} \\end{bmatrix}$</td>\n <td>$|0\\rangle\\langle0| + e^{i\\pi/4}|1\\rangle$$\\langle1|$</td>\n <td>$T|\\psi\\rangle = \\alpha|0\\rangle + e^{i\\pi/4} \\beta |1\\rangle$</td>\n <td>\n $T|0\\rangle = |0\\rangle$<br>\n $T|1\\rangle = e^{i\\pi/4}|1\\rangle$\n </td>\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.t\" target=\"_blank\">T</a></td>\n </tr>\n</table>\n\n<blockquote>\n<p>Notice that applying the $T$ gate twice is equivalent to applying the $S$ gate, and applying the $S$ gate twice is equivalent to applying the $Z$ gate: \n$$T^2 = S, S^2 = Z$$</p>\n</blockquote>\n",
|
|
425
|
+
"asMarkdown": "\nThe next two gates are known as phase shift gates. They apply a phase to the $|1\\rangle$ state, and leave the $|0\\rangle$ state unchanged.\n\n<table>\n <tr>\n <th>Gate</th>\n <th>Matrix</th>\n <th>Ket-Bra</th>\n <th>Applying to $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$</th>\n <th>Applying to basis states</th>\n <th>Q# Documentation</th>\n </tr>\n <tr>\n <td>$S$</td>\n <td>$\\begin{bmatrix} 1 & 0 \\\\\\ 0 & i \\end{bmatrix}$</td>\n <td>$|0\\rangle\\langle0| + i|1\\rangle\\langle1|$</td>\n <td>$S|\\psi\\rangle = \\alpha|0\\rangle + i\\beta|1\\rangle$</td>\n <td>\n $S|0\\rangle = |0\\rangle$<br>\n $S|1\\rangle = i|1\\rangle$<br>\n $S|+\\rangle = |i\\rangle$<br>\n $S|-\\rangle = |-i\\rangle$<br>\n $S|i\\rangle = |-\\rangle$<br>\n $S|-i\\rangle = |+\\rangle$<br>\n </td>\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.s\" target=\"_blank\">S</a></td>\n </tr>\n <tr>\n <td>$T$</td>\n <td>$\\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i\\pi/4} \\end{bmatrix}$</td>\n <td>$|0\\rangle\\langle0| + e^{i\\pi/4}|1\\rangle$$\\langle1|$</td>\n <td>$T|\\psi\\rangle = \\alpha|0\\rangle + e^{i\\pi/4} \\beta |1\\rangle$</td>\n <td>\n $T|0\\rangle = |0\\rangle$<br>\n $T|1\\rangle = e^{i\\pi/4}|1\\rangle$\n </td>\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.t\" target=\"_blank\">T</a></td>\n </tr>\n</table>\n\n> Notice that applying the $T$ gate twice is equivalent to applying the $S$ gate, and applying the $S$ gate twice is equivalent to applying the $Z$ gate: \n$$T^2 = S, S^2 = Z$$"
|
|
426
|
+
}
|
|
427
|
+
]
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
"type": "exercise",
|
|
431
|
+
"id": "single_qubit_gates__three_quarters_pi_phase",
|
|
432
|
+
"title": "Three-Fourths Phase",
|
|
433
|
+
"description": {
|
|
434
|
+
"type": "text-content",
|
|
435
|
+
"asHtml": "<p><strong>Input:</strong> A qubit in an arbitrary state $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$.</p>\n<p><strong>Goal:</strong> Use several phase shift gates to apply the transformation represented by the following matrix to the given qubit:</p>\n<p>$$\\begin{bmatrix} 1 & 0 \\\\ 0 & e^{3i\\pi/4} \\end{bmatrix}$$</p>\n",
|
|
436
|
+
"asMarkdown": "**Input:** A qubit in an arbitrary state $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$.\n\n**Goal:** Use several phase shift gates to apply the transformation represented by the following matrix to the given qubit:\n\n$$\\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{3i\\pi/4} \\end{bmatrix}$$"
|
|
437
|
+
},
|
|
438
|
+
"sourceIds": [
|
|
439
|
+
"KatasLibrary.qs",
|
|
440
|
+
"single_qubit_gates__three_quarters_pi_phase__Verification.qs"
|
|
441
|
+
],
|
|
442
|
+
"placeholderCode": "namespace Kata {\n operation ThreeQuartersPiPhase (q : Qubit) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
443
|
+
"explainedSolution": {
|
|
444
|
+
"type": "explained-solution",
|
|
445
|
+
"items": [
|
|
446
|
+
{
|
|
447
|
+
"type": "text-content",
|
|
448
|
+
"asHtml": "<p>The three-fourths phase gate above can be expressed as a product of 2 canonical gates - the $T$ gate is $\\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i\\pi/4} \\end{bmatrix}$ and the $S$ gate is $\\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i\\pi/2} \\end{bmatrix}$.</p>\n<p>$$\n\\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i3\\pi/4} \\end{bmatrix} = \n\\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i\\pi/4} \\end{bmatrix} \\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i\\pi/2} \\end{bmatrix} = \n\\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i\\pi/4} \\end{bmatrix} \\begin{bmatrix} 1 & 0 \\\\ 0 & i \\end{bmatrix} = \nTS\n$$</p>\n<p>Note that $TS = ST$, so it doesn't matter in what order those gates are applied.</p>\n",
|
|
449
|
+
"asMarkdown": "\nThe three-fourths phase gate above can be expressed as a product of 2 canonical gates - the $T$ gate is $\\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i\\pi/4} \\end{bmatrix}$ and the $S$ gate is $\\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i\\pi/2} \\end{bmatrix}$.\n\n$$\n\\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i3\\pi/4} \\end{bmatrix} = \n\\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i\\pi/4} \\end{bmatrix} \\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i\\pi/2} \\end{bmatrix} = \n\\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i\\pi/4} \\end{bmatrix} \\begin{bmatrix} 1 & 0 \\\\\\ 0 & i \\end{bmatrix} = \nTS\n$$\n\nNote that $TS = ST$, so it doesn't matter in what order those gates are applied."
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
"type": "solution",
|
|
453
|
+
"id": "single_qubit_gates__three_quarters_pi_solution",
|
|
454
|
+
"code": "namespace Kata {\n operation ThreeQuartersPiPhase (q : Qubit) : Unit is Adj+Ctl {\n S(q);\n T(q);\n }\n}\n"
|
|
455
|
+
}
|
|
456
|
+
]
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
"type": "lesson",
|
|
461
|
+
"id": "single_qubit_gates__rotation_gates",
|
|
462
|
+
"title": "Rotation Gates",
|
|
463
|
+
"items": [
|
|
464
|
+
{
|
|
465
|
+
"type": "text-content",
|
|
466
|
+
"asHtml": "<p>The next few gates are parametrized: their exact behavior depends on a numeric parameter - an angle $\\theta$, given in radians. \nThese gates are the $X$ rotation gate $R_x(\\theta)$, $Y$ rotation gate $R_y(\\theta)$, $Z$ rotation gate $R_z(\\theta)$, and the arbitrary phase gate $R_1(\\theta)$. \nNote that for the first three gates the parameter $\\theta$ is multiplied by $\\frac{1}{2}$ within the gate's matrix.</p>\n<blockquote>\n<p>These gates are known as rotation gates, because they represent rotations around various axes on the Bloch sphere. The Bloch sphere is a way of representing the qubit states visually, mapping them onto the surface of a sphere. \nUnfortunately, this visualization isn't very useful beyond single-qubit states, which is why we have opted not to go into details in this kata.\nIf you are curious about it, you can learn more in <a href=\"https://en.wikipedia.org/wiki/Bloch_sphere\" target=\"_blank\">this Wikipedia article</a>.</p>\n</blockquote>\n<table>\n <tr>\n <th>Gate</th>\n <th>Matrix</th>\n <th>Applying to $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$</th>\n <th>Applying to basis states</th>\n <th>Q# Documentation</th>\n </tr>\n <tr>\n <td>$R_x(\\theta)$</td>\n <td>$\\begin{bmatrix} \\cos\\frac{\\theta}{2} & -i\\sin\\frac{\\theta}{2} \\\\\\ -i\\sin\\frac{\\theta}{2} & \\cos\\frac{\\theta}{2} \\end{bmatrix}$</td>\n <td>$R_x(\\theta)|\\psi\\rangle = (\\alpha\\cos\\frac{\\theta}{2} - i\\beta\\sin\\frac{\\theta}{2})|0\\rangle + (\\beta\\cos\\frac{\\theta}{2} - i\\alpha\\sin\\frac{\\theta}{2})|1\\rangle$</td>\n <td>\n $R_x(\\theta)|0\\rangle = \\cos\\frac{\\theta}{2}|0\\rangle - i\\sin\\frac{\\theta}{2}|1\\rangle$<br>\n $R_x(\\theta)i\\sin\\frac{\\theta}{2}|0\\rangle$\n </td>\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.rx\" target=\"_blank\">Rx</a></td>\n </tr>\n <tr>\n <td>$R_y(\\theta)$</td>\n <td>$\\begin{bmatrix} \\cos\\frac{\\theta}{2} & -\\sin\\frac{\\theta}{2} \\\\\\ \\sin\\frac{\\theta}{2} & \\cos\\frac{\\theta}{2} \\end{bmatrix}$</td>\n <td>$R_y(\\theta)|\\psi\\rangle = (\\alpha\\cos\\frac{\\theta}{2} - \\beta\\sin\\frac{\\theta}{2})|0\\rangle + (\\beta\\cos\\frac{\\theta}{2} + \\alpha\\sin\\frac{\\theta}{2})|1\\rangle$</td>\n <td>\n $R_y(\\theta)|0\\rangle = \\cos\\frac{\\theta}{2}|0\\rangle + \\sin\\frac{\\theta}{2}|1\\rangle$<br>\n $R_y(\\theta)\\sin\\frac{\\theta}{2}|0\\rangle$\n </td>\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.ry\" target=\"_blank\">Ry</a></td>\n </tr>\n <tr>\n <td>$R_z(\\theta)$</td>\n <td>$\\begin{bmatrix} e^{-i\\theta/2} & 0 \\\\\\ 0 & e^{i\\theta/2} \\end{bmatrix}$</td>\n <td>$R_z(\\theta)|\\psi\\rangle = \\alpha e^{-i\\theta/2}|0\\rangle + \\beta e^{i\\theta/2}|1\\rangle$</td>\n <td>\n $R_z(\\theta)|0\\rangle = e^{-i\\theta/2}|0\\rangle$<br>\n $R_z(\\theta)$\n </td>\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.rz\" target=\"_blank\">Rz</a></td>\n </tr>\n <tr>\n <td>$R_1(\\theta)$</td>\n <td>$\\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i\\theta} \\end{bmatrix}$</td>\n <td>$R_1(\\theta)|\\psi\\rangle = \\alpha|0\\rangle + \\beta e^{i\\theta}|1\\rangle$</td>\n <td>\n $R_1(\\theta)|0\\rangle = |0\\rangle$<br>\n $R_1(\\theta)$\n </td> \n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.r1\" target=\"_blank\">R1</a></td>\n </tr>\n</table>\n\n<p>You have already encountered some special cases of the $R_1$ gate: </p>\n<p>$$T = R_1(\\frac{\\pi}{4}), S = R_1(\\frac{\\pi}{2}), Z = R_1(\\pi)$$</p>\n<p>In addition, this gate is closely related to the $R_z$ gate: applying $R_1$ gate is equivalent to applying the $R_z$ gate, and then applying a global phase: </p>\n<p>$$R_1(\\theta) = e^{i\\theta/2}R_z(\\theta)$$</p>\n<p>In addition, the rotation gates are very closely related to their respective Pauli gates: </p>\n<p>$$X = iR_x(\\pi), Y = iR_y(\\pi), Z = iR_z(\\pi)$$</p>\n",
|
|
467
|
+
"asMarkdown": "\nThe next few gates are parametrized: their exact behavior depends on a numeric parameter - an angle $\\theta$, given in radians. \nThese gates are the $X$ rotation gate $R_x(\\theta)$, $Y$ rotation gate $R_y(\\theta)$, $Z$ rotation gate $R_z(\\theta)$, and the arbitrary phase gate $R_1(\\theta)$. \nNote that for the first three gates the parameter $\\theta$ is multiplied by $\\frac{1}{2}$ within the gate's matrix.\n\n> These gates are known as rotation gates, because they represent rotations around various axes on the Bloch sphere. The Bloch sphere is a way of representing the qubit states visually, mapping them onto the surface of a sphere. \n> Unfortunately, this visualization isn't very useful beyond single-qubit states, which is why we have opted not to go into details in this kata.\n> If you are curious about it, you can learn more in <a href=\"https://en.wikipedia.org/wiki/Bloch_sphere\" target=\"_blank\">this Wikipedia article</a>.\n\n<table>\n <tr>\n <th>Gate</th>\n <th>Matrix</th>\n <th>Applying to $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$</th>\n <th>Applying to basis states</th>\n <th>Q# Documentation</th>\n </tr>\n <tr>\n <td>$R_x(\\theta)$</td>\n <td>$\\begin{bmatrix} \\cos\\frac{\\theta}{2} & -i\\sin\\frac{\\theta}{2} \\\\\\ -i\\sin\\frac{\\theta}{2} & \\cos\\frac{\\theta}{2} \\end{bmatrix}$</td>\n <td>$R_x(\\theta)|\\psi\\rangle = (\\alpha\\cos\\frac{\\theta}{2} - i\\beta\\sin\\frac{\\theta}{2})|0\\rangle + (\\beta\\cos\\frac{\\theta}{2} - i\\alpha\\sin\\frac{\\theta}{2})|1\\rangle$</td>\n <td>\n $R_x(\\theta)|0\\rangle = \\cos\\frac{\\theta}{2}|0\\rangle - i\\sin\\frac{\\theta}{2}|1\\rangle$<br>\n $R_x(\\theta)i\\sin\\frac{\\theta}{2}|0\\rangle$\n </td>\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.rx\" target=\"_blank\">Rx</a></td>\n </tr>\n <tr>\n <td>$R_y(\\theta)$</td>\n <td>$\\begin{bmatrix} \\cos\\frac{\\theta}{2} & -\\sin\\frac{\\theta}{2} \\\\\\ \\sin\\frac{\\theta}{2} & \\cos\\frac{\\theta}{2} \\end{bmatrix}$</td>\n <td>$R_y(\\theta)|\\psi\\rangle = (\\alpha\\cos\\frac{\\theta}{2} - \\beta\\sin\\frac{\\theta}{2})|0\\rangle + (\\beta\\cos\\frac{\\theta}{2} + \\alpha\\sin\\frac{\\theta}{2})|1\\rangle$</td>\n <td>\n $R_y(\\theta)|0\\rangle = \\cos\\frac{\\theta}{2}|0\\rangle + \\sin\\frac{\\theta}{2}|1\\rangle$<br>\n $R_y(\\theta)\\sin\\frac{\\theta}{2}|0\\rangle$\n </td>\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.ry\" target=\"_blank\">Ry</a></td>\n </tr>\n <tr>\n <td>$R_z(\\theta)$</td>\n <td>$\\begin{bmatrix} e^{-i\\theta/2} & 0 \\\\\\ 0 & e^{i\\theta/2} \\end{bmatrix}$</td>\n <td>$R_z(\\theta)|\\psi\\rangle = \\alpha e^{-i\\theta/2}|0\\rangle + \\beta e^{i\\theta/2}|1\\rangle$</td>\n <td>\n $R_z(\\theta)|0\\rangle = e^{-i\\theta/2}|0\\rangle$<br>\n $R_z(\\theta)$\n </td>\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.rz\" target=\"_blank\">Rz</a></td>\n </tr>\n <tr>\n <td>$R_1(\\theta)$</td>\n <td>$\\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i\\theta} \\end{bmatrix}$</td>\n <td>$R_1(\\theta)|\\psi\\rangle = \\alpha|0\\rangle + \\beta e^{i\\theta}|1\\rangle$</td>\n <td>\n $R_1(\\theta)|0\\rangle = |0\\rangle$<br>\n $R_1(\\theta)$\n </td> \n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.r1\" target=\"_blank\">R1</a></td>\n </tr>\n</table>\n\nYou have already encountered some special cases of the $R_1$ gate: \n\n$$T = R_1(\\frac{\\pi}{4}), S = R_1(\\frac{\\pi}{2}), Z = R_1(\\pi)$$\n\nIn addition, this gate is closely related to the $R_z$ gate: applying $R_1$ gate is equivalent to applying the $R_z$ gate, and then applying a global phase: \n\n$$R_1(\\theta) = e^{i\\theta/2}R_z(\\theta)$$\n\nIn addition, the rotation gates are very closely related to their respective Pauli gates: \n\n$$X = iR_x(\\pi), Y = iR_y(\\pi), Z = iR_z(\\pi)$$"
|
|
468
|
+
}
|
|
469
|
+
]
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
"type": "exercise",
|
|
473
|
+
"id": "single_qubit_gates__prepare_rotated_state",
|
|
474
|
+
"title": "Prepare Rotated State",
|
|
475
|
+
"description": {
|
|
476
|
+
"type": "text-content",
|
|
477
|
+
"asHtml": "<p><strong>Inputs:</strong></p>\n<ol>\n<li>Real numbers $\\alpha$ and $\\beta$ such that $\\alpha^2 + \\beta^2 = 1$.</li>\n<li>A qubit in state $|0\\rangle$.</li>\n</ol>\n<p><strong>Goal:</strong> Use a rotation gate to transform the qubit into state $\\alpha|0\\rangle -i\\beta|1\\rangle$.</p>\n<blockquote>\n<p>You will probably need functions from the <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math\" target=\"_blank\">Math</a> namespace, specifically <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arctan2\" target=\"_blank\">ArcTan2</a>.</p>\n<p>You can assign variables in Q# by using the <code>let</code> keyword: <code>let num = 3;</code> or <code>let result = Function(input);</code></p>\n</blockquote>\n",
|
|
478
|
+
"asMarkdown": "**Inputs:**\n\n1. Real numbers $\\alpha$ and $\\beta$ such that $\\alpha^2 + \\beta^2 = 1$.\n2. A qubit in state $|0\\rangle$.\n\n**Goal:** Use a rotation gate to transform the qubit into state $\\alpha|0\\rangle -i\\beta|1\\rangle$.\n\n> You will probably need functions from the <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math\" target=\"_blank\">Math</a> namespace, specifically <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arctan2\" target=\"_blank\">ArcTan2</a>.\n>\n> You can assign variables in Q# by using the `let` keyword: `let num = 3;` or `let result = Function(input);`"
|
|
479
|
+
},
|
|
480
|
+
"sourceIds": [
|
|
481
|
+
"KatasLibrary.qs",
|
|
482
|
+
"single_qubit_gates__prepare_rotated_state__Verification.qs"
|
|
483
|
+
],
|
|
484
|
+
"placeholderCode": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation PrepareRotatedState(alpha : Double, beta : Double, q : Qubit)\n : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
485
|
+
"explainedSolution": {
|
|
486
|
+
"type": "explained-solution",
|
|
487
|
+
"items": [
|
|
488
|
+
{
|
|
489
|
+
"type": "text-content",
|
|
490
|
+
"asHtml": "<p>We use the rotation gate $R_x(\\theta)$. This gate turns the state $|0\\rangle$ into $R_x(\\theta)|0\\rangle = \\cos\\frac{\\theta}{2}|0\\rangle - i\\sin\\frac{\\theta}{2}|1\\rangle$.\nThis is similar to the state we need. We just need to find an angle $\\theta$ such that $\\cos\\frac{\\theta}{2}=\\alpha$ and $\\sin\\frac{\\theta}{2}=\\beta$. We can use these two equations to solve for $\\theta$: $\\theta = 2\\arctan\\frac{\\beta}{\\alpha}$. (<em>Note: It is given that $\\alpha^2 + \\beta^2=1$</em>).\nHence the required gate is $R_x(2\\arctan\\frac{\\beta}{\\alpha})$, which in matrix form is $\\begin{bmatrix} \\alpha & -i\\beta \\\\ -i\\beta & \\alpha \\end{bmatrix}$.\nThis gate turns $|0\\rangle = \\begin{bmatrix} 1 \\\\ 0\\end{bmatrix}$ into $\\begin{bmatrix} \\alpha & -i\\beta \\\\ -i\\beta & \\alpha \\end{bmatrix} \\begin{bmatrix} 1 \\\\ 0\\end{bmatrix} = \\begin{bmatrix} \\alpha \\\\ -i\\beta \\end{bmatrix} = \\alpha|0\\rangle -i\\beta|1\\rangle$.</p>\n<blockquote>\n<p>Trigonometric functions are available in Q# via the <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math\" target=\"_blank\">Math</a> namespace. In this case we will need <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arctan2\" target=\"_blank\">ArcTan2</a>.</p>\n</blockquote>\n",
|
|
491
|
+
"asMarkdown": "\nWe use the rotation gate $R_x(\\theta)$. This gate turns the state $|0\\rangle$ into $R_x(\\theta)|0\\rangle = \\cos\\frac{\\\\theta}{2}|0\\rangle - i\\sin\\frac{\\theta}{2}|1\\rangle$.\nThis is similar to the state we need. We just need to find an angle $\\theta$ such that $\\cos\\frac{\\theta}{2}=\\alpha$ and $\\sin\\frac{\\theta}{2}=\\beta$. We can use these two equations to solve for $\\theta$: $\\theta = 2\\arctan\\frac{\\beta}{\\alpha}$. (*Note: It is given that $\\alpha^2 + \\beta^2=1$*).\nHence the required gate is $R_x(2\\arctan\\frac{\\beta}{\\alpha})$, which in matrix form is $\\begin{bmatrix} \\alpha & -i\\beta \\\\\\ -i\\beta & \\alpha \\end{bmatrix}$.\nThis gate turns $|0\\rangle = \\begin{bmatrix} 1 \\\\\\ 0\\end{bmatrix}$ into $\\begin{bmatrix} \\alpha & -i\\beta \\\\\\ -i\\beta & \\alpha \\end{bmatrix} \\begin{bmatrix} 1 \\\\\\ 0\\end{bmatrix} = \\begin{bmatrix} \\alpha \\\\\\ -i\\beta \\end{bmatrix} = \\alpha|0\\rangle -i\\beta|1\\rangle$.\n\n> Trigonometric functions are available in Q# via the <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math\" target=\"_blank\">Math</a> namespace. In this case we will need <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arctan2\" target=\"_blank\">ArcTan2</a>."
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
"type": "solution",
|
|
495
|
+
"id": "single_qubit_gates__prepare_rotated_state_solution",
|
|
496
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation PrepareRotatedState (alpha : Double, beta : Double, q : Qubit) : Unit is Adj+Ctl {\n let phi = ArcTan2(beta, alpha);\n Rx(2.0 * phi, q);\n }\n}\n"
|
|
497
|
+
}
|
|
498
|
+
]
|
|
499
|
+
}
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
"type": "exercise",
|
|
503
|
+
"id": "single_qubit_gates__prepare_arbitrary_state",
|
|
504
|
+
"title": "Prepare Arbitrary State",
|
|
505
|
+
"description": {
|
|
506
|
+
"type": "text-content",
|
|
507
|
+
"asHtml": "<p><strong>Inputs:</strong></p>\n<ol>\n<li>A non-negative real number $\\alpha$.</li>\n<li>A non-negative real number $\\beta = \\sqrt{1 - \\alpha^2}$.</li>\n<li>A real number $\\theta$.</li>\n<li>A qubit in state $|0\\rangle$.</li>\n</ol>\n<p><strong>Goal:</strong> Transform the qubit into state $\\alpha|0\\rangle + e^{i\\theta}\\beta|1\\rangle$.</p>\n<blockquote>\n<p>Since only the relative amplitudes and relative phase have any physical meaning, this allows us to prepare any single-qubit quantum state we want to.</p>\n</blockquote>\n",
|
|
508
|
+
"asMarkdown": "**Inputs:**\n\n1. A non-negative real number $\\alpha$.\n2. A non-negative real number $\\beta = \\sqrt{1 - \\alpha^2}$.\n3. A real number $\\theta$.\n4. A qubit in state $|0\\rangle$.\n\n**Goal:** Transform the qubit into state $\\alpha|0\\rangle + e^{i\\theta}\\beta|1\\rangle$.\n\n> Since only the relative amplitudes and relative phase have any physical meaning, this allows us to prepare any single-qubit quantum state we want to."
|
|
509
|
+
},
|
|
510
|
+
"sourceIds": [
|
|
511
|
+
"KatasLibrary.qs",
|
|
512
|
+
"single_qubit_gates__prepare_arbitrary_state__Verification.qs"
|
|
513
|
+
],
|
|
514
|
+
"placeholderCode": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation PrepareArbitraryState(\n alpha : Double,beta : Double, theta : Double, q : Qubit)\n : Unit is Adj+Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
515
|
+
"explainedSolution": {
|
|
516
|
+
"type": "explained-solution",
|
|
517
|
+
"items": [
|
|
518
|
+
{
|
|
519
|
+
"type": "text-content",
|
|
520
|
+
"asHtml": "<p>This exercise can be done in two steps.</p>\n<ol>\n<li>Convert the state from $|0\\rangle$ to $\\alpha|0\\rangle + \\beta|1\\rangle$.\nIn a similar manner to the "Preparing a Rotated State" exercise, we first prepare an $\\alpha|0\\rangle -i\\beta|1\\rangle$ state using the $R_x$ gate, and then removing the relative phase of $-i$ by applying the $S$ gate, which would turn $\\alpha|0\\rangle -i\\beta|1\\rangle$ to $\\alpha|0\\rangle + \\beta|1\\rangle$.\nAn alternative, simpler approach is to use the $R_y$ gate, which allows us to get the necessary state right away without introducing a relative phase:\n$$\nR_y(2\\arctan\\frac{\\beta}{\\alpha}) = \\begin{bmatrix} \\alpha & -\\beta \\\\ \\beta & \\alpha \\end{bmatrix}\n$$</li>\n<li>Add a phase of $e^{i\\theta}$ to the $|1\\rangle$ basis state using the $R_1(\\theta)$ gate. This would turn $\\alpha|0\\rangle +\\beta|1\\rangle$ to $\\alpha|0\\rangle + e^{i\\theta}\\beta|1\\rangle$.</li>\n</ol>\n<p>The solution can be represented as $R_1(\\theta)R_y(2\\arctan\\frac{\\beta}{\\alpha})$ or in matrix form as:\n$$\n\\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i\\theta} \\end{bmatrix}\\begin{bmatrix} \\alpha & -\\beta \\\\ \\beta & \\alpha \\end{bmatrix} = \n\\begin{bmatrix} \\alpha & -\\beta \\\\ e^{i\\theta}\\beta & e^{i\\theta}\\alpha \\end{bmatrix}\n$$</p>\n<p>This turns $|0\\rangle = \\begin{bmatrix} 1 \\\\ 0\\end{bmatrix}$ into $\\begin{bmatrix} \\alpha & -\\beta \\\\ e^{i\\theta}\\beta & e^{i\\theta}\\alpha \\end{bmatrix} \\begin{bmatrix} 1 \\\\ 0\\end{bmatrix} = \\begin{bmatrix} \\alpha \\\\ e^{i\\theta}\\beta \\end{bmatrix} = \\alpha|0\\rangle +e^{i\\theta}\\beta|1\\rangle$.</p>\n",
|
|
521
|
+
"asMarkdown": "\nThis exercise can be done in two steps.\n\n1. Convert the state from $|0\\rangle$ to $\\alpha|0\\rangle + \\beta|1\\rangle$.\n In a similar manner to the \"Preparing a Rotated State\" exercise, we first prepare an $\\alpha|0\\rangle -i\\beta|1\\rangle$ state using the $R_x$ gate, and then removing the relative phase of $-i$ by applying the $S$ gate, which would turn $\\alpha|0\\rangle -i\\beta|1\\rangle$ to $\\alpha|0\\rangle + \\beta|1\\rangle$.\n An alternative, simpler approach is to use the $R_y$ gate, which allows us to get the necessary state right away without introducing a relative phase:\n$$\nR_y(2\\arctan\\frac{\\beta}{\\alpha}) = \\begin{bmatrix} \\alpha & -\\beta \\\\\\ \\beta & \\alpha \\end{bmatrix}\n$$\n2. Add a phase of $e^{i\\theta}$ to the $|1\\rangle$ basis state using the $R_1(\\theta)$ gate. This would turn $\\alpha|0\\rangle +\\beta|1\\rangle$ to $\\alpha|0\\rangle + e^{i\\theta}\\beta|1\\rangle$.\n\nThe solution can be represented as $R_1(\\theta)R_y(2\\arctan\\frac{\\beta}{\\alpha})$ or in matrix form as:\n$$\n\\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i\\theta} \\end{bmatrix}\\begin{bmatrix} \\alpha & -\\beta \\\\\\ \\beta & \\alpha \\end{bmatrix} = \n\\begin{bmatrix} \\alpha & -\\beta \\\\\\ e^{i\\theta}\\beta & e^{i\\theta}\\alpha \\end{bmatrix}\n$$\n\nThis turns $|0\\rangle = \\begin{bmatrix} 1 \\\\\\ 0\\end{bmatrix}$ into $\\begin{bmatrix} \\alpha & -\\beta \\\\\\ e^{i\\theta}\\beta & e^{i\\theta}\\alpha \\end{bmatrix} \\begin{bmatrix} 1 \\\\\\ 0\\end{bmatrix} = \\begin{bmatrix} \\alpha \\\\\\ e^{i\\theta}\\beta \\end{bmatrix} = \\alpha|0\\rangle +e^{i\\theta}\\beta|1\\rangle$."
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
"type": "solution",
|
|
525
|
+
"id": "single_qubit_gates__prepare_arbitrary_state_solution",
|
|
526
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation PrepareArbitraryState (alpha : Double, beta : Double, theta : Double, q : Qubit) : Unit is Adj+Ctl {\n let phi = ArcTan2(beta, alpha);\n Ry(2.0 * phi, q);\n R1(theta, q);\n }\n}\n"
|
|
527
|
+
}
|
|
528
|
+
]
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
"type": "lesson",
|
|
533
|
+
"id": "single_qubit_gates__conclusion",
|
|
534
|
+
"title": "Conclusion",
|
|
535
|
+
"items": [
|
|
536
|
+
{
|
|
537
|
+
"type": "text-content",
|
|
538
|
+
"asHtml": "<p>Congratulations! In this Kata you learned the matrix and the Ket-Bra representation of quantum gates. Here are a few key concepts to keep in mind:</p>\n<ul>\n<li>Single-qubit gates act on individual qubits and are represented by $2 \\times 2$ unitary matrices.</li>\n<li>The effect of a gate applied to a qubit can be calculated by multiplying the corresponding matrix by the state vector of the qubit.</li>\n<li>Applying several quantum gates in sequence is equivalent to performing several matrix multiplications.</li>\n<li>A square matrix can be represented as the outer product of two vectors. The outer product is the matrix product of $|\\phi\\rangle$ and $\\langle\\psi|$, denoted as $|\\phi\\rangle\\langle\\psi|$.</li>\n<li>Pauli gates, phase shift gates, and rotation gates are examples of single-qubit gates. All of them are available in Q#.</li>\n</ul>\n<p>Next, you will learn about multi-qubit systems and the multi-qubit gates in the “Multi-Qubit Systems” Kata.</p>\n",
|
|
539
|
+
"asMarkdown": "\nCongratulations! In this Kata you learned the matrix and the Ket-Bra representation of quantum gates. Here are a few key concepts to keep in mind:\n* Single-qubit gates act on individual qubits and are represented by $2 \\times 2$ unitary matrices.\n* The effect of a gate applied to a qubit can be calculated by multiplying the corresponding matrix by the state vector of the qubit.\n* Applying several quantum gates in sequence is equivalent to performing several matrix multiplications.\n* A square matrix can be represented as the outer product of two vectors. The outer product is the matrix product of $|\\phi\\rangle$ and $\\langle\\psi|$, denoted as $|\\phi\\rangle\\langle\\psi|$.\n* Pauli gates, phase shift gates, and rotation gates are examples of single-qubit gates. All of them are available in Q#.\n\nNext, you will learn about multi-qubit systems and the multi-qubit gates in the “Multi-Qubit Systems” Kata."
|
|
540
|
+
}
|
|
541
|
+
]
|
|
542
|
+
}
|
|
543
|
+
]
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
"id": "multi_qubit_systems",
|
|
547
|
+
"title": "Multi-Qubit Systems",
|
|
548
|
+
"sections": [
|
|
549
|
+
{
|
|
550
|
+
"type": "lesson",
|
|
551
|
+
"id": "multi_qubit_systems__overview",
|
|
552
|
+
"title": "Overview",
|
|
553
|
+
"items": [
|
|
554
|
+
{
|
|
555
|
+
"type": "text-content",
|
|
556
|
+
"asHtml": "<p>This kata introduces you to multi-qubit systems - their representation in mathematical notation and in Q# code, and the concept of entanglement.</p>\n<p>If you are not familiar with single-qubit systems, we recommend that you complete "The Qubit" kata first.</p>\n<p><strong>This kata covers the following topics:</strong></p>\n<ul>\n<li>Vector representation of multi-qubit systems</li>\n<li>Entangled and separable states</li>\n<li>Dirac notation</li>\n</ul>\n<p><strong>What you should know to start working on this kata:</strong></p>\n<ul>\n<li>Basic single-qubit gates</li>\n<li>The concept of tensor product</li>\n</ul>\n",
|
|
557
|
+
"asMarkdown": "\nThis kata introduces you to multi-qubit systems - their representation in mathematical notation and in Q# code, and the concept of entanglement.\n\nIf you are not familiar with single-qubit systems, we recommend that you complete \"The Qubit\" kata first.\n\n**This kata covers the following topics:**\n\n- Vector representation of multi-qubit systems\n- Entangled and separable states\n- Dirac notation\n\n**What you should know to start working on this kata:**\n\n- Basic single-qubit gates\n- The concept of tensor product"
|
|
558
|
+
}
|
|
559
|
+
]
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
"type": "lesson",
|
|
563
|
+
"id": "multi_qubit_systems__introduction",
|
|
564
|
+
"title": "Multi-Qubit Systems",
|
|
565
|
+
"items": [
|
|
566
|
+
{
|
|
567
|
+
"type": "text-content",
|
|
568
|
+
"asHtml": "<p>In a previous kata we discussed the concept of a qubit - the basic building block of a quantum computer.\nA multi-qubit system is a collection of multiple qubits, treated as a single system.</p>\n<p>Let's start by examining a system of two classical bits. Each bit can be in two states: $0$ and $1$. Therefore, a system of two bits can be in four different states: $00$, $01$, $10$, and $11$. Generally, a system of $N$ classical bits can be in any of the $2^N$ states.</p>\n<p>A system of $N$ qubits can also be in any of the $2^N$ classical states, but, unlike the classical bits, it can also be in a <strong>superposition</strong> of all these states.</p>\n<p>Similarly to single-qubit systems, a state of an $N$-qubit system can be represented as a complex vector of size $2^N$:\n$$\\begin{bmatrix} x_0 \\\\ x_1 \\\\ \\vdots \\\\ x_{2^N-1}\\end{bmatrix}$$</p>\n<h2 id=\"basis-states\">Basis States</h2>\n<p>Similarly to single-qubit systems, multi-qubit systems have their own sets of basis states.\nThe computational basis for an $N$-qubit system is a set of $2^N$ vectors, in each of which with one element equals $1$, and the other elements equal $0$.</p>\n<p>For example, this is the <strong>computational basis</strong> for a two-qubit system:</p>\n<table>\n <tr>\n <td>$$\\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix}$$</td>\n <td>$$\\begin{bmatrix} 0 \\\\\\ 1 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix}$$</td>\n <td>$$\\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 1 \\\\\\ 0 \\end{bmatrix}$$</td>\n <td>$$\\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 0 \\\\\\ 1 \\end{bmatrix}$$</td>\n </tr>\n</table>\n\n<p>It is easy to see that these vectors form an orthonormal basis. Note that each of these basis states can be represented as a tensor product of some combination of single-qubit basis states:</p>\n<table>\n <tr>\n <td>$\\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$</td>\n <td>$\\begin{bmatrix} 0 \\\\\\ 1 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$</td>\n <td>$\\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 1 \\\\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$</td>\n <td>$\\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 0 \\\\\\ 1 \\end{bmatrix} =\n\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} \\otimes \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$</td>\n </tr>\n</table>\n\n<p>Any two-qubit system can be expressed as some linear combination of those tensor products of single-qubit basis states.</p>\n<p>Similar logic applies to systems of more than two qubits. In general case,</p>\n<p>$$\n\\begin{bmatrix} x_0 \\\\ x_1 \\\\ \\vdots \\\\ x_{2^N-1} \\end{bmatrix} =\nx_0 \\begin{bmatrix} 1 \\\\ 0 \\\\ \\vdots \\\\ 0 \\end{bmatrix} +\nx_1 \\begin{bmatrix} 0 \\\\ 1 \\\\ \\vdots \\\\ 0 \\end{bmatrix} + \\dotsb +\nx_{2^N-1} \\begin{bmatrix} 0 \\\\ 0 \\\\ \\vdots \\\\ 1 \\end{bmatrix}\n$$</p>\n<p>The coefficients of the basis vectors define how "close" is the system state to the corresponding basis vector.</p>\n<blockquote>\n<p>Just like with single-qubit systems, there exist other orthonormal bases states for multi-qubit systems. An example for a two-qubit system is the <strong>Bell basis</strong>:</p>\n<p>$$\\frac{1}{\\sqrt{2}}\\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 1 \\end{bmatrix}$$\n$$\\frac{1}{\\sqrt{2}}\\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ -1 \\end{bmatrix}$$\n$$\\frac{1}{\\sqrt{2}}\\begin{bmatrix} 0 \\\\ 1 \\\\ 1 \\\\ 0 \\end{bmatrix}$$\n$$\\frac{1}{\\sqrt{2}}\\begin{bmatrix} 0 \\\\ 1 \\\\ -1 \\\\ 0 \\end{bmatrix}$$</p>\n<p>You can check that these vectors are normalized, and orthogonal to each other, and that any two-qubit state can be expressed as a linear combination of these vectors. The vectors of Bell basis, however, can not be represented as tensor products of single-qubit basis states.</p>\n</blockquote>\n",
|
|
569
|
+
"asMarkdown": "\nIn a previous kata we discussed the concept of a qubit - the basic building block of a quantum computer.\nA multi-qubit system is a collection of multiple qubits, treated as a single system.\n\nLet's start by examining a system of two classical bits. Each bit can be in two states: $0$ and $1$. Therefore, a system of two bits can be in four different states: $00$, $01$, $10$, and $11$. Generally, a system of $N$ classical bits can be in any of the $2^N$ states.\n\nA system of $N$ qubits can also be in any of the $2^N$ classical states, but, unlike the classical bits, it can also be in a **superposition** of all these states.\n\nSimilarly to single-qubit systems, a state of an $N$-qubit system can be represented as a complex vector of size $2^N$:\n$$\\begin{bmatrix} x_0 \\\\\\ x_1 \\\\\\ \\vdots \\\\\\ x_{2^N-1}\\end{bmatrix}$$\n\n## Basis States\n\nSimilarly to single-qubit systems, multi-qubit systems have their own sets of basis states.\nThe computational basis for an $N$-qubit system is a set of $2^N$ vectors, in each of which with one element equals $1$, and the other elements equal $0$.\n\nFor example, this is the **computational basis** for a two-qubit system:\n\n<table>\n <tr>\n <td>$$\\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix}$$</td>\n <td>$$\\begin{bmatrix} 0 \\\\\\ 1 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix}$$</td>\n <td>$$\\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 1 \\\\\\ 0 \\end{bmatrix}$$</td>\n <td>$$\\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 0 \\\\\\ 1 \\end{bmatrix}$$</td>\n </tr>\n</table>\n\nIt is easy to see that these vectors form an orthonormal basis. Note that each of these basis states can be represented as a tensor product of some combination of single-qubit basis states:\n\n<table>\n <tr>\n <td>$\\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$</td>\n <td>$\\begin{bmatrix} 0 \\\\\\ 1 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$</td>\n <td>$\\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 1 \\\\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$</td>\n <td>$\\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 0 \\\\\\ 1 \\end{bmatrix} =\n\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} \\otimes \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$</td>\n </tr>\n</table>\n\nAny two-qubit system can be expressed as some linear combination of those tensor products of single-qubit basis states.\n\nSimilar logic applies to systems of more than two qubits. In general case,\n\n$$\n\\begin{bmatrix} x_0 \\\\\\ x_1 \\\\\\ \\vdots \\\\\\ x_{2^N-1} \\end{bmatrix} =\nx_0 \\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ \\vdots \\\\\\ 0 \\end{bmatrix} +\nx_1 \\begin{bmatrix} 0 \\\\\\ 1 \\\\\\ \\vdots \\\\\\ 0 \\end{bmatrix} + \\dotsb +\nx_{2^N-1} \\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ \\vdots \\\\\\ 1 \\end{bmatrix}\n$$\n\nThe coefficients of the basis vectors define how \"close\" is the system state to the corresponding basis vector.\n\n> Just like with single-qubit systems, there exist other orthonormal bases states for multi-qubit systems. An example for a two-qubit system is the **Bell basis**:\n>\n> $$\\frac{1}{\\sqrt{2}}\\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 1 \\end{bmatrix}$$\n> $$\\frac{1}{\\sqrt{2}}\\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ -1 \\end{bmatrix}$$\n> $$\\frac{1}{\\sqrt{2}}\\begin{bmatrix} 0 \\\\\\ 1 \\\\\\ 1 \\\\\\ 0 \\end{bmatrix}$$\n> $$\\frac{1}{\\sqrt{2}}\\begin{bmatrix} 0 \\\\\\ 1 \\\\\\ -1 \\\\\\ 0 \\end{bmatrix}$$\n>\n> You can check that these vectors are normalized, and orthogonal to each other, and that any two-qubit state can be expressed as a linear combination of these vectors. The vectors of Bell basis, however, can not be represented as tensor products of single-qubit basis states."
|
|
570
|
+
}
|
|
571
|
+
]
|
|
572
|
+
},
|
|
573
|
+
{
|
|
574
|
+
"type": "lesson",
|
|
575
|
+
"id": "multi_qubit_systems__separable_states",
|
|
576
|
+
"title": "Separable States",
|
|
577
|
+
"items": [
|
|
578
|
+
{
|
|
579
|
+
"type": "text-content",
|
|
580
|
+
"asHtml": "<p>Sometimes the global state of a multi-qubit system can be separated into the states of individual qubits or subsystems. To do this, you would express the vector state of the global system as a tensor product of the vectors representing each individual qubit/subsystem. Here is an example of a two-qubit state:</p>\n<p>$$\n\\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ 0 \\\\ \\frac{1}{\\sqrt{2}} \\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix}\n$$</p>\n<p>You can see that qubit 1 is in state $\\frac{1}{\\sqrt{2}}\\big(|0\\rangle + |1\\rangle\\big)$ and qubit 2 is in state $|0\\rangle$. The states that allow such representation are known as separable states, or product states, because you can separate the global state into the product of individual subsystems.</p>\n<p>The states that allow such representation are known as <strong>separable states</strong>.</p>\n<h2 id=\"🔎-analyze\">🔎 Analyze</h2>\n<p>Show that the state is separable:\n$$\n\\frac{1}{2} \\begin{bmatrix} 1 \\\\ i \\\\ -i \\\\ 1 \\end{bmatrix} =\n\\begin{bmatrix} ? \\\\ ? \\end{bmatrix} \\otimes \\begin{bmatrix} ? \\\\ ? \\end{bmatrix}\n$$</p>\n<details>\n<summary><b>Solution</b></summary>\nTo separate the state into a tensor product of two single-qubit states, we need to represent it in the following way:\n\n<p>$$\n\\begin{bmatrix} \\alpha \\gamma \\\\ \\alpha \\delta \\\\ \\beta \\gamma \\\\ \\beta \\delta \\end{bmatrix} = \n\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} \\otimes \\begin{bmatrix} \\gamma \\\\ \\delta \\end{bmatrix}\n$$</p>\n<p>This brings us to a system of equations:</p>\n<p>$$\n\\begin{cases}\n\\alpha\\gamma = \\frac{1}{2} \\\\ \\alpha\\delta = \\frac{i}{2} \\\\ \\beta \\gamma = \\frac{-i}{2} \\\\ \\beta \\delta = \\frac{1}{2}\n\\end{cases}\n$$</p>\n<p>Solving this system of equations gives us the answer:</p>\n<p>$$\\alpha = \\frac{1}{\\sqrt2}, \\beta = \\frac{-i}{\\sqrt2}, \\gamma = \\frac{1}{\\sqrt2}, \\delta = \\frac{i}{\\sqrt2}$$</p>\n<p>$$\n\\frac{1}{2} \\begin{bmatrix} 1 \\\\ i \\\\ -i \\\\ 1 \\end{bmatrix} =\n\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ -i \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ i \\end{bmatrix}\n$$</p>\n<p>Note that finding such representation is not always possible, as you will see in the next exercise.</p>\n</details>\n\n<h2 id=\"🔎-analyze-1\">🔎 Analyze</h2>\n<p>Is this state separable?</p>\n<p>$$\\frac{1}{\\sqrt{2}}\\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 1 \\end{bmatrix}$$</p>\n<details>\n<summary><b>Solution</b></summary>\nLet's assume that this state is separable and write down the system of equations to determine the coefficients of individual qubit states in the tensor product, similar to what we did in the previous exercise:\n\n<p>$$\n\\begin{cases}\n\\alpha\\gamma = \\frac{1}{\\sqrt2} \\\\ \\alpha\\delta = 0 \\\\ \\beta \\gamma = 0 \\\\ \\beta \\delta = \\frac{1}{\\sqrt2}\n\\end{cases}\n$$</p>\n<p>Now let's multiply the first and the last equations, and the second and the third equations:</p>\n<p>$$\n\\begin{cases}\n\\alpha\\beta\\gamma\\delta = \\frac{1}{2} \\\\ \\alpha\\beta\\gamma\\delta = 0\n\\end{cases}\n$$</p>\n<p>We can see that this system of equations doesn't have a solution, which means that this state is <b>not separable</b>.</p>\n</details>",
|
|
581
|
+
"asMarkdown": "\nSometimes the global state of a multi-qubit system can be separated into the states of individual qubits or subsystems. To do this, you would express the vector state of the global system as a tensor product of the vectors representing each individual qubit/subsystem. Here is an example of a two-qubit state:\n\n$$\n\\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ 0 \\\\\\ \\frac{1}{\\sqrt{2}} \\\\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}\n$$\n\nYou can see that qubit 1 is in state $\\frac{1}{\\sqrt{2}}\\big(|0\\rangle + |1\\rangle\\big)$ and qubit 2 is in state $|0\\rangle$. The states that allow such representation are known as separable states, or product states, because you can separate the global state into the product of individual subsystems.\n\nThe states that allow such representation are known as **separable states**.\n\n## 🔎 Analyze\n\nShow that the state is separable:\n$$\n\\frac{1}{2} \\begin{bmatrix} 1 \\\\\\ i \\\\\\ -i \\\\\\ 1 \\end{bmatrix} =\n\\begin{bmatrix} ? \\\\\\ ? \\end{bmatrix} \\otimes \\begin{bmatrix} ? \\\\\\ ? \\end{bmatrix}\n$$\n\n<details>\n<summary><b>Solution</b></summary>\nTo separate the state into a tensor product of two single-qubit states, we need to represent it in the following way:\n\n$$\n\\begin{bmatrix} \\alpha \\gamma \\\\\\ \\alpha \\delta \\\\\\ \\beta \\gamma \\\\\\ \\beta \\delta \\end{bmatrix} = \n\\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix} \\otimes \\begin{bmatrix} \\gamma \\\\\\ \\delta \\end{bmatrix}\n$$\n\nThis brings us to a system of equations:\n\n$$\n\\begin{cases}\n\\alpha\\gamma = \\frac{1}{2} \\\\\\ \\alpha\\delta = \\frac{i}{2} \\\\\\ \\beta \\gamma = \\frac{-i}{2} \\\\\\ \\beta \\delta = \\frac{1}{2}\n\\end{cases}\n$$\n\nSolving this system of equations gives us the answer:\n\n$$\\alpha = \\frac{1}{\\sqrt2}, \\beta = \\frac{-i}{\\sqrt2}, \\gamma = \\frac{1}{\\sqrt2}, \\delta = \\frac{i}{\\sqrt2}$$\n\n$$\n\\frac{1}{2} \\begin{bmatrix} 1 \\\\\\ i \\\\\\ -i \\\\\\ 1 \\end{bmatrix} =\n\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ -i \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ i \\end{bmatrix}\n$$\n\nNote that finding such representation is not always possible, as you will see in the next exercise.\n</details>\n\n## 🔎 Analyze\n\nIs this state separable?\n\n$$\\frac{1}{\\sqrt{2}}\\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 1 \\end{bmatrix}$$\n\n<details>\n<summary><b>Solution</b></summary>\nLet's assume that this state is separable and write down the system of equations to determine the coefficients of individual qubit states in the tensor product, similar to what we did in the previous exercise:\n\n$$\n\\begin{cases}\n\\alpha\\gamma = \\frac{1}{\\sqrt2} \\\\\\ \\alpha\\delta = 0 \\\\\\ \\beta \\gamma = 0 \\\\\\ \\beta \\delta = \\frac{1}{\\sqrt2}\n\\end{cases}\n$$\n\nNow let's multiply the first and the last equations, and the second and the third equations:\n\n$$\n\\begin{cases}\n\\alpha\\beta\\gamma\\delta = \\frac{1}{2} \\\\\\ \\alpha\\beta\\gamma\\delta = 0\n\\end{cases}\n$$\n\nWe can see that this system of equations doesn't have a solution, which means that this state is <b>not separable</b>.\n</details>"
|
|
582
|
+
}
|
|
583
|
+
]
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
"type": "lesson",
|
|
587
|
+
"id": "multi_qubit_systems__entanglement",
|
|
588
|
+
"title": "Entanglement",
|
|
589
|
+
"items": [
|
|
590
|
+
{
|
|
591
|
+
"type": "text-content",
|
|
592
|
+
"asHtml": "<p>Sometimes, quantum states cannot be written as individual qubit states. Quantum systems that are not separable are called entangled systems. If a state can be written as the product state of the individual subsystems, that state is not entangled.</p>\n<p>Entanglement is a quantum correlation, which is very different from classical correlations. In entanglement, the state of the subsystems isn't determined, and you can talk only about the probabilities associated with the outcomes. The global system must be considered as one.</p>\n<blockquote>\n<p>For example, every state in the Bell basis is an entangled state.</p>\n</blockquote>\n<p>Entanglement is a huge part of what makes quantum computing so powerful. It allows us to link the qubits so that they stop behaving like individuals and start behaving like a large, more complex system. In entangled systems, measuring one of the qubits modifies the state of the other qubits, and tells us something about their state.</p>\n<p>For example, consider two qubits $A$ and $B$ in superpositions such that the state of the global system is</p>\n<p>$$|\\psi\\rangle_{AB} = \\frac{1}{\\sqrt2}|00\\rangle + \\frac{1}{\\sqrt2}|11\\rangle$$</p>\n<p>In such a state, only two outcomes are possible when you measure the state of both qubits in the standard basis: $|00\\rangle$ and $|11\\rangle$. Notice that each outcome has the same probability of $\\frac{1}{2}$. There's zero probability of obtaining $|01\\rangle$ and $|10\\rangle$. If you measure the first qubit and you get that it is in $|0\\rangle$ state, then you can be positive that the second qubit is also in $|0\\rangle$ state, even without measuring it. The measurement outcomes are correlated, and the qubits are <em>entangled</em>.</p>\n<p>This property is used extensively in many quantum algorithms.</p>\n",
|
|
593
|
+
"asMarkdown": "\nSometimes, quantum states cannot be written as individual qubit states. Quantum systems that are not separable are called entangled systems. If a state can be written as the product state of the individual subsystems, that state is not entangled.\n\nEntanglement is a quantum correlation, which is very different from classical correlations. In entanglement, the state of the subsystems isn't determined, and you can talk only about the probabilities associated with the outcomes. The global system must be considered as one.\n\n> For example, every state in the Bell basis is an entangled state.\n\nEntanglement is a huge part of what makes quantum computing so powerful. It allows us to link the qubits so that they stop behaving like individuals and start behaving like a large, more complex system. In entangled systems, measuring one of the qubits modifies the state of the other qubits, and tells us something about their state.\n\nFor example, consider two qubits $A$ and $B$ in superpositions such that the state of the global system is\n\n$$|\\psi\\rangle_{AB} = \\frac{1}{\\sqrt2}|00\\rangle + \\frac{1}{\\sqrt2}|11\\rangle$$\n\nIn such a state, only two outcomes are possible when you measure the state of both qubits in the standard basis: $|00\\rangle$ and $|11\\rangle$. Notice that each outcome has the same probability of $\\frac{1}{2}$. There's zero probability of obtaining $|01\\rangle$ and $|10\\rangle$. If you measure the first qubit and you get that it is in $|0\\rangle$ state, then you can be positive that the second qubit is also in $|0\\rangle$ state, even without measuring it. The measurement outcomes are correlated, and the qubits are _entangled_.\n\nThis property is used extensively in many quantum algorithms."
|
|
594
|
+
}
|
|
595
|
+
]
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
"type": "lesson",
|
|
599
|
+
"id": "multi_qubit_systems__dirac_notation",
|
|
600
|
+
"title": "Dirac Notation",
|
|
601
|
+
"items": [
|
|
602
|
+
{
|
|
603
|
+
"type": "text-content",
|
|
604
|
+
"asHtml": "<p>Just like with single qubits, Dirac notation provides a useful shorthand for writing down states of multi-qubit systems.</p>\n<p>As we've seen earlier, multi-qubit systems have their own canonical bases, and the basis states can be represented as tensor products of single-qubit basis states. Any multi-qubit system can be represented as a linear combination of these basis states:</p>\n<p>$$\n\\begin{bmatrix} x_0 \\\\ x_1 \\\\ x_2 \\\\ x_3 \\end{bmatrix} =\nx_0\\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix} +\nx_1\\begin{bmatrix} 0 \\\\ 1 \\\\ 0 \\\\ 0 \\end{bmatrix} +\nx_2\\begin{bmatrix} 0 \\\\ 0 \\\\ 1 \\\\ 0 \\end{bmatrix} +\nx_3\\begin{bmatrix} 0 \\\\ 0 \\\\ 0 \\\\ 1 \\end{bmatrix} =\nx_0|0\\rangle \\otimes |0\\rangle +\nx_1|0\\rangle \\otimes |1\\rangle +\nx_2|1\\rangle \\otimes |0\\rangle +\nx_3|1\\rangle \\otimes |1\\rangle\n$$</p>\n<p>To simplify this, tensor products of basis states have their own notation:</p>\n<p>$$|0\\rangle \\otimes |0\\rangle = |00\\rangle$$\n$$|0\\rangle \\otimes |1\\rangle = |01\\rangle$$\n$$|1\\rangle \\otimes |0\\rangle = |10\\rangle$$\n$$|1\\rangle \\otimes |1\\rangle = |11\\rangle$$</p>\n<p>$$|0\\rangle \\otimes |0\\rangle \\otimes |0\\rangle = |000\\rangle$$</p>\n<p>And so on.</p>\n<p>Or, more generally:</p>\n<p>$$|i_0\\rangle \\otimes |i_1\\rangle \\otimes \\dotsb \\otimes |i_n\\rangle = |i_0i_1...i_n\\rangle$$</p>\n<p>Using this notation simplifies our example:</p>\n<p>$$\n\\begin{bmatrix} x_0 \\\\ x_1 \\\\ x_2 \\\\ x_3 \\end{bmatrix} =\nx_0|00\\rangle + x_1|01\\rangle + x_2|10\\rangle + x_3|11\\rangle\n$$</p>\n<p>Just like with single qubits, we can put arbitrary symbols within the kets the same way variables are used in algebra.\nWhether a ket represents a single qubit or an entire system depends on the context.\nSome ket symbols have a commonly accepted usage, such as the symbols for the Bell basis:</p>\n<table>\n <tr>\n <td>$|\\phi^+\\rangle = \\frac{1}{\\sqrt{2}}\\big(|00\\rangle + |11\\rangle\\big) \\\\\\ |\\phi^-\\rangle = \\frac{1}{\\sqrt{2}}\\big(|00\\rangle - |11\\rangle\\big)$</td>\n <td>$|\\psi^+\\rangle = \\frac{1}{\\sqrt{2}}\\big(|01\\rangle + |10\\rangle\\big) \\\\\\ |\\psi^-\\rangle = \\frac{1}{\\sqrt{2}}\\big(|01\\rangle - |10\\rangle\\big)$</td>\n </tr>\n</table>\n\n<blockquote>\n<h2 id=\"endianness\">Endianness</h2>\n<p>In classical computing, endianness refers to the order of bits (or bytes) when representing numbers in binary. You're probably familiar with the typical way of writing numbers in binary: $0 = 0_2$, $1 = 1_2$, $2 = 10_2$, $3 = 11_2$, $4 = 100_2$, $5 = 101_2$, $6 = 110_2$, etc. This is known as <strong>big-endian format</strong>. In big-endian format, the <em>most significant</em> bits come first. For example: $110_2 = 1 \\cdot 4 + 1 \\cdot 2 + 0 \\cdot 1 = 4 + 2 = 6$.</p>\n<p>There is an alternate way of writing binary numbers - <strong>little-endian format</strong>. In little-endian format, the <em>least significant</em> bits come first. For example, $2$ would be written as $01$, $4$ as $001$, and $6$ as $011$. To put it another way, in little endian format, the number is written backwards compared to the big-endian format.</p>\n<p>In Dirac notation for multi-qubit systems, it's common to see integer numbers within the kets instead of bit sequences. What those numbers mean depends on the context - whether the notation used is big-endian or little-endian.</p>\n<p>Examples with a 3 qubit system:</p>\n<table>\n <tr>\n <th>Integer Ket</th>\n <td>$|0\\rangle$</td>\n <td>$|1\\rangle$</td>\n <td>$|2\\rangle$</td>\n <td>$|3\\rangle$</td>\n <td>$|4\\rangle$</td>\n <td>$|5\\rangle$</td>\n <td>$|6\\rangle$</td>\n <td>$|7\\rangle$</td>\n </tr>\n <tr>\n <th>Big-endian</th>\n <td>$|000\\rangle$</td>\n <td>$|001\\rangle$</td>\n <td>$|010\\rangle$</td>\n <td>$|011\\rangle$</td>\n <td>$|100\\rangle$</td>\n <td>$|101\\rangle$</td>\n <td>$|110\\rangle$</td>\n <td>$|111\\rangle$</td>\n </tr>\n <tr>\n <th>Little-endian</th>\n <td>$|000\\rangle$</td>\n <td>$|100\\rangle$</td>\n <td>$|010\\rangle$</td>\n <td>$|110\\rangle$</td>\n <td>$|001\\rangle$</td>\n <td>$|101\\rangle$</td>\n <td>$|011\\rangle$</td>\n <td>$|111\\rangle$</td>\n </tr>\n</table>\n\n<p>Multi-qubit quantum systems that store superpositions of numbers are often referred to as <strong>quantum registers</strong>.</p>\n</blockquote>\n",
|
|
605
|
+
"asMarkdown": "\nJust like with single qubits, Dirac notation provides a useful shorthand for writing down states of multi-qubit systems.\n\nAs we've seen earlier, multi-qubit systems have their own canonical bases, and the basis states can be represented as tensor products of single-qubit basis states. Any multi-qubit system can be represented as a linear combination of these basis states:\n\n$$\n\\begin{bmatrix} x_0 \\\\\\ x_1 \\\\\\ x_2 \\\\\\ x_3 \\end{bmatrix} =\nx_0\\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix} +\nx_1\\begin{bmatrix} 0 \\\\\\ 1 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix} +\nx_2\\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 1 \\\\\\ 0 \\end{bmatrix} +\nx_3\\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 0 \\\\\\ 1 \\end{bmatrix} =\nx_0|0\\rangle \\otimes |0\\rangle +\nx_1|0\\rangle \\otimes |1\\rangle +\nx_2|1\\rangle \\otimes |0\\rangle +\nx_3|1\\rangle \\otimes |1\\rangle\n$$\n\nTo simplify this, tensor products of basis states have their own notation:\n\n$$|0\\rangle \\otimes |0\\rangle = |00\\rangle$$\n$$|0\\rangle \\otimes |1\\rangle = |01\\rangle$$\n$$|1\\rangle \\otimes |0\\rangle = |10\\rangle$$\n$$|1\\rangle \\otimes |1\\rangle = |11\\rangle$$\n\n$$|0\\rangle \\otimes |0\\rangle \\otimes |0\\rangle = |000\\rangle$$\n\nAnd so on.\n\nOr, more generally:\n\n$$|i_0\\rangle \\otimes |i_1\\rangle \\otimes \\dotsb \\otimes |i_n\\rangle = |i_0i_1...i_n\\rangle$$\n\nUsing this notation simplifies our example:\n\n$$\n\\begin{bmatrix} x_0 \\\\\\ x_1 \\\\\\ x_2 \\\\\\ x_3 \\end{bmatrix} =\nx_0|00\\rangle + x_1|01\\rangle + x_2|10\\rangle + x_3|11\\rangle\n$$\n\nJust like with single qubits, we can put arbitrary symbols within the kets the same way variables are used in algebra.\nWhether a ket represents a single qubit or an entire system depends on the context.\nSome ket symbols have a commonly accepted usage, such as the symbols for the Bell basis:\n\n<table>\n <tr>\n <td>$|\\phi^+\\rangle = \\frac{1}{\\sqrt{2}}\\big(|00\\rangle + |11\\rangle\\big) \\\\\\ |\\phi^-\\rangle = \\frac{1}{\\sqrt{2}}\\big(|00\\rangle - |11\\rangle\\big)$</td>\n <td>$|\\psi^+\\rangle = \\frac{1}{\\sqrt{2}}\\big(|01\\rangle + |10\\rangle\\big) \\\\\\ |\\psi^-\\rangle = \\frac{1}{\\sqrt{2}}\\big(|01\\rangle - |10\\rangle\\big)$</td>\n </tr>\n</table>\n\n>## Endianness\n>\n> In classical computing, endianness refers to the order of bits (or bytes) when representing numbers in binary. You're probably familiar with the typical way of writing numbers in binary: $0 = 0_2$, $1 = 1_2$, $2 = 10_2$, $3 = 11_2$, $4 = 100_2$, $5 = 101_2$, $6 = 110_2$, etc. This is known as **big-endian format**. In big-endian format, the *most significant* bits come first. For example: $110_2 = 1 \\cdot 4 + 1 \\cdot 2 + 0 \\cdot 1 = 4 + 2 = 6$.\n>\n> There is an alternate way of writing binary numbers - **little-endian format**. In little-endian format, the *least significant* bits come first. For example, $2$ would be written as $01$, $4$ as $001$, and $6$ as $011$. To put it another way, in little endian format, the number is written backwards compared to the big-endian format.\n>\n> In Dirac notation for multi-qubit systems, it's common to see integer numbers within the kets instead of bit sequences. What those numbers mean depends on the context - whether the notation used is big-endian or little-endian.\n>\n> Examples with a 3 qubit system:\n>\n> <table>\n> <tr>\n> <th>Integer Ket</th>\n> <td>$|0\\rangle$</td>\n> <td>$|1\\rangle$</td>\n> <td>$|2\\rangle$</td>\n> <td>$|3\\rangle$</td>\n> <td>$|4\\rangle$</td>\n> <td>$|5\\rangle$</td>\n> <td>$|6\\rangle$</td>\n> <td>$|7\\rangle$</td>\n> </tr>\n> <tr>\n> <th>Big-endian</th>\n> <td>$|000\\rangle$</td>\n> <td>$|001\\rangle$</td>\n> <td>$|010\\rangle$</td>\n> <td>$|011\\rangle$</td>\n> <td>$|100\\rangle$</td>\n> <td>$|101\\rangle$</td>\n> <td>$|110\\rangle$</td>\n> <td>$|111\\rangle$</td>\n> </tr>\n> <tr>\n> <th>Little-endian</th>\n> <td>$|000\\rangle$</td>\n> <td>$|100\\rangle$</td>\n> <td>$|010\\rangle$</td>\n> <td>$|110\\rangle$</td>\n> <td>$|001\\rangle$</td>\n> <td>$|101\\rangle$</td>\n> <td>$|011\\rangle$</td>\n> <td>$|111\\rangle$</td>\n> </tr>\n></table>\n>\n> Multi-qubit quantum systems that store superpositions of numbers are often referred to as **quantum registers**."
|
|
606
|
+
}
|
|
607
|
+
]
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
"type": "lesson",
|
|
611
|
+
"id": "multi_qubit_systems__in_qsharp",
|
|
612
|
+
"title": "Multi-Qubit Systems in Q#",
|
|
613
|
+
"items": [
|
|
614
|
+
{
|
|
615
|
+
"type": "text-content",
|
|
616
|
+
"asHtml": "<p>This demo shows you how to allocate multiple qubits in Q# and examine their joint state. It uses single-qubit gates for manipulating the individual qubit states - if you need a refresher on them, please review the single-qubit gates kata.</p>\n<p>These demos use the function <code>DumpMachine</code> to print the state of the quantum simulator.\nIf you aren't familiar with the output of this function for single qubits, you should revisit the qubit kata.\nWhen printing the state of multi-qubit systems, this function outputs the same information for each multi-qubit basis state.\nThe qubit kata explains how <code>DumpMachine</code> works for multiple qubits in more detail.</p>\n",
|
|
617
|
+
"asMarkdown": "\nThis demo shows you how to allocate multiple qubits in Q# and examine their joint state. It uses single-qubit gates for manipulating the individual qubit states - if you need a refresher on them, please review the single-qubit gates kata.\n\nThese demos use the function `DumpMachine` to print the state of the quantum simulator.\nIf you aren't familiar with the output of this function for single qubits, you should revisit the qubit kata.\nWhen printing the state of multi-qubit systems, this function outputs the same information for each multi-qubit basis state.\nThe qubit kata explains how `DumpMachine` works for multiple qubits in more detail."
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
"type": "example",
|
|
621
|
+
"id": "multi_qubit_systems__multi_qubit_systems_demo",
|
|
622
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n\n @EntryPoint()\n operation MultiQubitSystemsDemo () : Unit {\n // This allocates an array of 2 qubits, each of them in state |0⟩.\n // The overall state of the system is |00⟩\n use qs = Qubit[2];\n // X gate changes the first qubit into state |1⟩\n // The entire system is now in state |10⟩\n X(qs[0]);\n\n Message(\"System in state |10⟩:\");\n DumpMachine();\n\n // This changes the second qubit into state |+⟩ = (1/sqrt(2))(|0⟩ + |1⟩).\n // The entire system is now in state (1/sqrt(2))(|10⟩ + |11⟩)\n H(qs[1]);\n\n Message(\"System in state (1/sqrt(2))(|10⟩ + |11⟩):\");\n DumpMachine();\n\n // This changes the first qubit into state |-⟩ = (1/sqrt(2))(|0⟩ - |1⟩)\n // The entire system is now in state 0.5(|00⟩ + |01⟩ - |10⟩ - |11⟩)\n H(qs[0]);\n\n Message(\"System in state 0.5(|00⟩ + |01⟩ - |10⟩ - |11⟩):\");\n DumpMachine();\n\n // The next lines entangle the qubits.\n // Don't worry about what exactly they do for now\n H(qs[1]);\n CNOT(qs[0], qs[1]);\n\n Message(\"Entangled state 0.5(|00⟩ - |11⟩):\");\n DumpMachine();\n\n // Since the states of entangled qubits are inseparable,\n // it makes no sense to examine only one of them\n\n // This returns the system into state |00⟩\n ResetAll(qs);\n }\n}"
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
"type": "text-content",
|
|
626
|
+
"asHtml": "<blockquote>\n<p>You might have noticed that we've been "resetting" the qubits at the end of our demos, that is, returning them to $|0\\rangle$ state. Q# requires you to return your qubits into the $|0\\rangle$ state before releasing them at the end of the <code>using</code> block.\nThe reason for this is entanglement.</p>\n<p>Consider running a program on a quantum computer: the number of qubits is very limited, and you want to reuse the released qubits in other parts of the program.\nIf they are not in zero state by that time, they can potentially be still entangled with the qubits which are not yet released, thus operations you perform on them can affect the state of other parts of the program, causing erroneous and hard to debug behavior.</p>\n<p>Resetting the qubits to zero state automatically when they go outside the scope of their using block is dangerous as well: if they were entangled with others, measuring them to reset them can affect the state of the unreleased qubits, and thus change the results of the program - without the developer noticing this.</p>\n<p>The requirement that the qubits should be in zero state before they can be released aims to remind the developer to double-check that all necessary information has been properly extracted from the qubits, and that they are not entangled with unreleased qubits any more.</p>\n<p>(An alternative way to break entanglement is to measure qubits; in this case Q# allows to release them regardless of the measurement result. You can learn more about measurements in the qubit kata.)</p>\n</blockquote>\n<p>In the following exercises you will learn to prepare separable quantum states by manipulating individual qubits.\nYou will only need knowledge from the single-qubit gates kata for that.</p>\n<blockquote>\n<p>In each exercise, you'll be given an array of qubits to manipulate; you can access $i$-th element of the array <code>qs</code> as <code>qs[i]</code>.\nArray elements are indexed starting with 0, the first array element corresponds to the leftmost qubit in Dirac notation.</p>\n</blockquote>\n",
|
|
627
|
+
"asMarkdown": "\n> You might have noticed that we've been \"resetting\" the qubits at the end of our demos, that is, returning them to $|0\\rangle$ state. Q# requires you to return your qubits into the $|0\\rangle$ state before releasing them at the end of the `using` block.\n> The reason for this is entanglement.\n>\n> Consider running a program on a quantum computer: the number of qubits is very limited, and you want to reuse the released qubits in other parts of the program.\nIf they are not in zero state by that time, they can potentially be still entangled with the qubits which are not yet released, thus operations you perform on them can affect the state of other parts of the program, causing erroneous and hard to debug behavior.\n>\n> Resetting the qubits to zero state automatically when they go outside the scope of their using block is dangerous as well: if they were entangled with others, measuring them to reset them can affect the state of the unreleased qubits, and thus change the results of the program - without the developer noticing this.\n>\n> The requirement that the qubits should be in zero state before they can be released aims to remind the developer to double-check that all necessary information has been properly extracted from the qubits, and that they are not entangled with unreleased qubits any more.\n>\n> (An alternative way to break entanglement is to measure qubits; in this case Q# allows to release them regardless of the measurement result. You can learn more about measurements in the qubit kata.)\n\nIn the following exercises you will learn to prepare separable quantum states by manipulating individual qubits.\nYou will only need knowledge from the single-qubit gates kata for that.\n\n> In each exercise, you'll be given an array of qubits to manipulate; you can access $i$-th element of the array `qs` as `qs[i]`.\nArray elements are indexed starting with 0, the first array element corresponds to the leftmost qubit in Dirac notation."
|
|
628
|
+
}
|
|
629
|
+
]
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
"type": "exercise",
|
|
633
|
+
"id": "multi_qubit_systems__prepare_basis_state",
|
|
634
|
+
"title": "Prepare a Basis State",
|
|
635
|
+
"description": {
|
|
636
|
+
"type": "text-content",
|
|
637
|
+
"asHtml": "<p><strong>Input:</strong> A two-qubit system in the basis state $|00\\rangle = \\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix}$.</p>\n<p><strong>Goal:</strong> Transform the system into the basis state $|11\\rangle = \\begin{bmatrix} 0 \\\\ 0 \\\\ 0 \\\\ 1 \\end{bmatrix}$.</p>\n",
|
|
638
|
+
"asMarkdown": "**Input:** A two-qubit system in the basis state $|00\\rangle = \\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix}$.\n\n**Goal:** Transform the system into the basis state $|11\\rangle = \\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 0 \\\\\\ 1 \\end{bmatrix}$.\n"
|
|
639
|
+
},
|
|
640
|
+
"sourceIds": [
|
|
641
|
+
"KatasLibrary.qs",
|
|
642
|
+
"multi_qubit_systems__common.qs",
|
|
643
|
+
"multi_qubit_systems__prepare_basis_state__verification.qs"
|
|
644
|
+
],
|
|
645
|
+
"placeholderCode": "namespace Kata {\n operation PrepareBasisState(qs : Qubit[]) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}",
|
|
646
|
+
"explainedSolution": {
|
|
647
|
+
"type": "explained-solution",
|
|
648
|
+
"items": [
|
|
649
|
+
{
|
|
650
|
+
"type": "text-content",
|
|
651
|
+
"asHtml": "<p>The starting state can be represented as follows:\n$$ \\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix} = |0\\rangle \\otimes |0\\rangle $$</p>\n<p>The goal state can be represented as follows:\n$$ \\begin{bmatrix} 0 \\\\ 0 \\\\ 0 \\\\ 1 \\end{bmatrix} = |1\\rangle \\otimes |1\\rangle $$</p>\n<p>Applying an <strong>X</strong> gate to a qubit in the $|0\\rangle$ state transforms the qubit state into the $|1\\rangle$ state. So, if we apply the <strong>X</strong> gate on the first qubit and the second qubit, we get the desired state.</p>\n",
|
|
652
|
+
"asMarkdown": "\nThe starting state can be represented as follows:\n$$ \\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix} = |0\\rangle \\otimes |0\\rangle $$\n\nThe goal state can be represented as follows:\n$$ \\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 0 \\\\\\ 1 \\end{bmatrix} = |1\\rangle \\otimes |1\\rangle $$\n\nApplying an **X** gate to a qubit in the $|0\\rangle$ state transforms the qubit state into the $|1\\rangle$ state. So, if we apply the **X** gate on the first qubit and the second qubit, we get the desired state."
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
"type": "solution",
|
|
656
|
+
"id": "multi_qubit_systems__prepare_basis_state_solution",
|
|
657
|
+
"code": "namespace Kata {\n operation PrepareBasisState(qs : Qubit[]) : Unit is Adj + Ctl {\n X(qs[0]);\n X(qs[1]);\n }\n}"
|
|
658
|
+
}
|
|
659
|
+
]
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
"type": "exercise",
|
|
664
|
+
"id": "multi_qubit_systems__prepare_superposition",
|
|
665
|
+
"title": "Prepare a Superposition of Two Basis States",
|
|
666
|
+
"description": {
|
|
667
|
+
"type": "text-content",
|
|
668
|
+
"asHtml": "<p><strong>Input:</strong> A two-qubit system in the basis state $|00\\rangle = \\begin{bmatrix} 1 \\ 0 \\ 0 \\ 0 \\end{bmatrix}$.</p>\n<p><strong>Goal:</strong> Transform the system into the state $\\frac{1}{\\sqrt2}\\big(|00\\rangle - |01\\rangle\\big) = \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\ -1 \\\\ 0 \\\\ 0 \\end{bmatrix}$.</p>\n<details>\n <summary><b>Need a hint?</b></summary>\n Represent the target state as a tensor product $|0\\rangle \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle - |1\\rangle\\big) = \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\\\ -1 \\end{bmatrix}$.\n</details>\n",
|
|
669
|
+
"asMarkdown": "**Input:** A two-qubit system in the basis state $|00\\rangle = \\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix}$.\n\n**Goal:** Transform the system into the state $\\frac{1}{\\sqrt2}\\big(|00\\rangle - |01\\rangle\\big) = \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\\\ -1 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix}$.\n\n<details>\n <summary><b>Need a hint?</b></summary>\n Represent the target state as a tensor product $|0\\rangle \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle - |1\\rangle\\big) = \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\\\ -1 \\end{bmatrix}$.\n</details>\n"
|
|
670
|
+
},
|
|
671
|
+
"sourceIds": [
|
|
672
|
+
"KatasLibrary.qs",
|
|
673
|
+
"multi_qubit_systems__common.qs",
|
|
674
|
+
"multi_qubit_systems__prepare_superposition__verification.qs"
|
|
675
|
+
],
|
|
676
|
+
"placeholderCode": "namespace Kata {\n operation PrepareSuperposition(qs : Qubit[]) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}",
|
|
677
|
+
"explainedSolution": {
|
|
678
|
+
"type": "explained-solution",
|
|
679
|
+
"items": [
|
|
680
|
+
{
|
|
681
|
+
"type": "text-content",
|
|
682
|
+
"asHtml": "<p>We begin in the same state as the previous excercise:\n$$ \\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix} = \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} = |0\\rangle \\otimes |0\\rangle$$</p>\n<p>The goal state can be separated as follows:\n$$ \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ -1 \\\\ 0 \\\\ 0 \\end{bmatrix} = \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\ -1 \\end{bmatrix} = |0\\rangle \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle - |1\\rangle\\big)$$</p>\n<p>This means that the first qubit is already in the state we want it to be, but the second qubit needs to be transformed from the $ \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} $ into $ \\frac{1}{\\sqrt{2}}\\begin{bmatrix} 1 \\\\ -1\\end{bmatrix}$ state.</p>\n<p>First, we apply the <strong>X</strong> gate to the second qubit; this performs the following transformation:\n$$ X |0\\rangle = \\begin{bmatrix}0 & 1 \\\\ 1 & 0 \\end{bmatrix} \\cdot \\begin{bmatrix}1 \\\\ 0 \\end{bmatrix} = \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} = |1\\rangle $$</p>\n<p>Second, we apply the <strong>H</strong> gate to the second qubit; this transforms its state into the desired one:\n$$ H|1\\rangle = \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 & 1 \\\\ 1 & -1 \\end{bmatrix} \\cdot \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\ -1 \\end{bmatrix}$$</p>\n",
|
|
683
|
+
"asMarkdown": "\nWe begin in the same state as the previous excercise:\n$$ \\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix} = \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} = |0\\rangle \\otimes |0\\rangle$$\n\nThe goal state can be separated as follows:\n$$ \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ -1 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix} = \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\\\ -1 \\end{bmatrix} = |0\\rangle \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle - |1\\rangle\\big)$$\n\nThis means that the first qubit is already in the state we want it to be, but the second qubit needs to be transformed from the $ \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} $ into $ \\frac{1}{\\sqrt{2}}\\begin{bmatrix} 1 \\\\\\ -1\\end{bmatrix}$ state.\n\nFirst, we apply the **X** gate to the second qubit; this performs the following transformation:\n$$ X |0\\rangle = \\begin{bmatrix}0 & 1 \\\\\\ 1 & 0 \\end{bmatrix} \\cdot \\begin{bmatrix}1 \\\\\\ 0 \\end{bmatrix} = \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} = |1\\rangle $$\n\nSecond, we apply the **H** gate to the second qubit; this transforms its state into the desired one:\n$$ H|1\\rangle = \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 & 1 \\\\\\ 1 & -1 \\end{bmatrix} \\cdot \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\\\ -1 \\end{bmatrix}$$"
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
"type": "solution",
|
|
687
|
+
"id": "multi_qubit_systems__prepare_superposition_solution",
|
|
688
|
+
"code": "namespace Kata {\n operation PrepareSuperposition(qs : Qubit[]) : Unit is Adj + Ctl {\n X(qs[1]);\n H(qs[1]);\n }\n}"
|
|
689
|
+
}
|
|
690
|
+
]
|
|
691
|
+
}
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
"type": "exercise",
|
|
695
|
+
"id": "multi_qubit_systems__prepare_with_real",
|
|
696
|
+
"title": " Prepare a Superposition with Real Amplitudes",
|
|
697
|
+
"description": {
|
|
698
|
+
"type": "text-content",
|
|
699
|
+
"asHtml": "<p><strong>Input:</strong> A two-qubit system in the basis state $|00\\rangle = \\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix}$.</p>\n<p><strong>Goal:</strong> Transform the system into the state $\\frac{1}{2}\\big(|00\\rangle - |01\\rangle + |10\\rangle - |11\\rangle\\big) = \\frac{1}{2}\\begin{bmatrix} 1 \\\\ -1 \\\\ 1 \\\\ -1 \\end{bmatrix}$.</p>\n<details>\n <summary><b>Need a hint?</b></summary>\n Represent the target state as a tensor product $\\frac{1}{\\sqrt2}\\big(|0\\rangle + |1\\rangle\\big) \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle - |1\\rangle\\big) = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\\\ -1 \\end{bmatrix}$.\n</details>\n",
|
|
700
|
+
"asMarkdown": "\n**Input:** A two-qubit system in the basis state $|00\\rangle = \\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix}$.\n\n**Goal:** Transform the system into the state $\\frac{1}{2}\\big(|00\\rangle - |01\\rangle + |10\\rangle - |11\\rangle\\big) = \\frac{1}{2}\\begin{bmatrix} 1 \\\\\\ -1 \\\\\\ 1 \\\\\\ -1 \\end{bmatrix}$.\n\n<details>\n <summary><b>Need a hint?</b></summary>\n Represent the target state as a tensor product $\\frac{1}{\\sqrt2}\\big(|0\\rangle + |1\\rangle\\big) \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle - |1\\rangle\\big) = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\\\ -1 \\end{bmatrix}$.\n</details>\n"
|
|
701
|
+
},
|
|
702
|
+
"sourceIds": [
|
|
703
|
+
"KatasLibrary.qs",
|
|
704
|
+
"multi_qubit_systems__common.qs",
|
|
705
|
+
"multi_qubit_systems__prepare_with_real__verification.qs"
|
|
706
|
+
],
|
|
707
|
+
"placeholderCode": "namespace Kata {\n operation PrepareWithReal(qs : Qubit[]) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}",
|
|
708
|
+
"explainedSolution": {
|
|
709
|
+
"type": "explained-solution",
|
|
710
|
+
"items": [
|
|
711
|
+
{
|
|
712
|
+
"type": "text-content",
|
|
713
|
+
"asHtml": "<p>Again, to start we will represent the goal state as a tensor product of single-qubit states; this gives us the following representation:</p>\n<p>$$ \\frac{1}{2}\\big(|00\\rangle - |01\\rangle + |10\\rangle - |11\\rangle\\big) = \\frac{1}{2}\\begin{bmatrix} 1 \\\\ -1 \\\\ 1 \\\\ -1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ 1 \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\ -1 \\end{bmatrix} = \\frac{1}{\\sqrt2}\\big(|0\\rangle + |1\\rangle\\big) \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle - |1\\rangle\\big) $$</p>\n<p>This time we need to transform both the first and the second qubits. Let's start with the first qubit. Applying the <strong>H</strong> gate transforms its state as follows:</p>\n<p>$$ H|0\\rangle = \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 & 1 \\\\ 1 & -1 \\end{bmatrix} \\cdot \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2}\\big(|0\\rangle + |1\\rangle\\big)$$</p>\n<p>For the second qubit we can use the same transformation we've seen in the "Prepare a Superposition of Two Basis States" exercise; this will give the desired end state.</p>\n",
|
|
714
|
+
"asMarkdown": "\nAgain, to start we will represent the goal state as a tensor product of single-qubit states; this gives us the following representation:\n\n$$ \\frac{1}{2}\\big(|00\\rangle - |01\\rangle + |10\\rangle - |11\\rangle\\big) = \\frac{1}{2}\\begin{bmatrix} 1 \\\\\\ -1 \\\\\\ 1 \\\\\\ -1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\\\ -1 \\end{bmatrix} = \\frac{1}{\\sqrt2}\\big(|0\\rangle + |1\\rangle\\big) \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle - |1\\rangle\\big) $$\n\nThis time we need to transform both the first and the second qubits. Let's start with the first qubit. Applying the **H** gate transforms its state as follows:\n\n$$ H|0\\rangle = \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 & 1 \\\\\\ 1 & -1 \\end{bmatrix} \\cdot \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2}\\big(|0\\rangle + |1\\rangle\\big)$$\n\nFor the second qubit we can use the same transformation we've seen in the \"Prepare a Superposition of Two Basis States\" exercise; this will give the desired end state."
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
"type": "solution",
|
|
718
|
+
"id": "multi_qubit_systems__prepare_with_real_solution",
|
|
719
|
+
"code": "namespace Kata {\n operation PrepareWithReal(qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n X(qs[1]);\n H(qs[1]);\n }\n}"
|
|
720
|
+
}
|
|
721
|
+
]
|
|
722
|
+
}
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
"type": "exercise",
|
|
726
|
+
"id": "multi_qubit_systems__prepare_with_complex",
|
|
727
|
+
"title": "Prepare a Superposition with Complex Amplitudes",
|
|
728
|
+
"description": {
|
|
729
|
+
"type": "text-content",
|
|
730
|
+
"asHtml": "<p><strong>Input:</strong> A two-qubit system in the basis state $|00\\rangle = \\begin{bmatrix} 1 \\ 0 \\ 0 \\ 0 \\end{bmatrix}$.</p>\n<p><strong>Goal:</strong> Transform the system into the state $\\frac{1}{2}\\big(|00\\rangle + e^{i\\pi/4}|01\\rangle + e^{i\\pi/2}|10\\rangle + e^{3i\\pi/4}|11\\rangle\\big) = \\frac{1}{2}\\begin{bmatrix} 1 \\ e^{i\\pi/4} \\ e^{i\\pi/2} \\ e^{3i\\pi/4} \\end{bmatrix}$.</p>\n<details>\n <summary><b>Need a hint?</b></summary>\n Represent the target state as a tensor product $\\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/2}|1\\rangle\\big) \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/4}|1\\rangle\\big) = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ e^{i\\pi/2} \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\\\ e^{i\\pi/4} \\end{bmatrix}$.\n</details>\n",
|
|
731
|
+
"asMarkdown": "\n**Input:** A two-qubit system in the basis state $|00\\rangle = \\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix}$.\n\n**Goal:** Transform the system into the state $\\frac{1}{2}\\big(|00\\rangle + e^{i\\pi/4}|01\\rangle + e^{i\\pi/2}|10\\rangle + e^{3i\\pi/4}|11\\rangle\\big) = \\frac{1}{2}\\begin{bmatrix} 1 \\\\ e^{i\\pi/4} \\\\ e^{i\\pi/2} \\\\ e^{3i\\pi/4} \\end{bmatrix}$.\n\n<details>\n <summary><b>Need a hint?</b></summary>\n Represent the target state as a tensor product $\\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/2}|1\\rangle\\big) \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/4}|1\\rangle\\big) = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ e^{i\\pi/2} \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\\\ e^{i\\pi/4} \\end{bmatrix}$.\n</details>\n"
|
|
732
|
+
},
|
|
733
|
+
"sourceIds": [
|
|
734
|
+
"KatasLibrary.qs",
|
|
735
|
+
"multi_qubit_systems__common.qs",
|
|
736
|
+
"multi_qubit_systems__prepare_with_complex__verification.qs"
|
|
737
|
+
],
|
|
738
|
+
"placeholderCode": "namespace Kata {\n operation PrepareWithComplex(qs : Qubit[]) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}",
|
|
739
|
+
"explainedSolution": {
|
|
740
|
+
"type": "explained-solution",
|
|
741
|
+
"items": [
|
|
742
|
+
{
|
|
743
|
+
"type": "text-content",
|
|
744
|
+
"asHtml": "<p>The start state is the same as the previous exercises:\n$$ \\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix} = \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} = |0\\rangle \\otimes |0\\rangle $$</p>\n<p>The goal state, factored as a tensor product, looks like this (remember that $e^{3i\\pi/4} = e^{i\\pi/4} e^{i\\pi/2}$):</p>\n<p>$$\n\\frac{1}{2}\\begin{bmatrix} 1 \\\\ e^{i\\pi/4} \\\\ e^{i\\pi/2} \\\\ e^{3i\\pi/4} \\end{bmatrix} =\n\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ e^{i\\pi/2} \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\ e^{i\\pi/4} \\end{bmatrix} =\n\\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/2}|1\\rangle\\big) \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/4}|1\\rangle\\big) $$</p>\n<p>We will again need to adjust the states of both qubits independently.</p>\n<p>For the first qubit, we'll start by applying the <strong>H</strong> gate, getting the state $\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ 1 \\end{bmatrix}$, as we've seen in the previous task. Afterwards we'll apply the <strong>S</strong> gate with the following result:</p>\n<p>$$ \\begin{bmatrix} 1 & 0 \\\\ 0 & i \\end{bmatrix} \\cdot \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ i \\end{bmatrix}$$</p>\n<p>If we recall that $i = e^{i\\pi/2}$, we can write the final state of the second qubit as:\n$$ \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ e^{i\\pi/2} \\end{bmatrix} $$</p>\n<p>For the second qubit. we'll apply the <strong>H</strong> gate, followed by the <strong>T</strong> gate, with the following result:\n$$ \\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i\\pi/4} \\end{bmatrix} \\cdot \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ e^{i\\pi/4} \\end{bmatrix} $$</p>\n",
|
|
745
|
+
"asMarkdown": "\nThe start state is the same as the previous exercises:\n$$ \\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix} = \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} = |0\\rangle \\otimes |0\\rangle $$\n\nThe goal state, factored as a tensor product, looks like this (remember that $e^{3i\\pi/4} = e^{i\\pi/4} e^{i\\pi/2}$):\n\n$$\n\\frac{1}{2}\\begin{bmatrix} 1 \\\\\\ e^{i\\pi/4} \\\\\\ e^{i\\pi/2} \\\\\\ e^{3i\\pi/4} \\end{bmatrix} =\n\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ e^{i\\pi/2} \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\\\ e^{i\\pi/4} \\end{bmatrix} =\n\\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/2}|1\\rangle\\big) \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/4}|1\\rangle\\big) $$\n\nWe will again need to adjust the states of both qubits independently.\n\nFor the first qubit, we'll start by applying the **H** gate, getting the state $\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix}$, as we've seen in the previous task. Afterwards we'll apply the **S** gate with the following result:\n\n$$ \\begin{bmatrix} 1 & 0 \\\\\\ 0 & i \\end{bmatrix} \\cdot \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ i \\end{bmatrix}$$\n\nIf we recall that $i = e^{i\\pi/2}$, we can write the final state of the second qubit as:\n$$ \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ e^{i\\pi/2} \\end{bmatrix} $$\n\nFor the second qubit. we'll apply the **H** gate, followed by the **T** gate, with the following result:\n$$ \\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i\\pi/4} \\end{bmatrix} \\cdot \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ e^{i\\pi/4} \\end{bmatrix} $$"
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
"type": "solution",
|
|
749
|
+
"id": "multi_qubit_systems__prepare_with_complex_solution",
|
|
750
|
+
"code": "namespace Kata {\n operation PrepareWithComplex(qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n H(qs[1]);\n S(qs[0]);\n T(qs[1]);\n }\n}"
|
|
751
|
+
}
|
|
752
|
+
]
|
|
753
|
+
}
|
|
754
|
+
},
|
|
755
|
+
{
|
|
756
|
+
"type": "lesson",
|
|
757
|
+
"id": "multi_qubit_systems__conclusion",
|
|
758
|
+
"title": "Conclusion",
|
|
759
|
+
"items": [
|
|
760
|
+
{
|
|
761
|
+
"type": "text-content",
|
|
762
|
+
"asHtml": "<p>Congratulations! In this kata you learned to prepare separable multi-qubit states using only single-qubit gates. You also learned the difference between separable states an entangled states. Here are a few key concepts to keep in mind:</p>\n<ul>\n<li>A system of $N$ qubits can also be in a superposition of $2^N$ quantum states. The computational basis for an $N$-qubit system is a set of $2^N$ vectors.</li>\n<li>Any two-qubit system can be expressed as some linear combination of the tensor product of single-qubit basis states.</li>\n<li>Two qubits are entangled if their states are correlated and if they can't be described as two independent qubits.</li>\n</ul>\n<p>Next, you will learn about multi-qubit gates and how they can give you access to all states of multi-qubit systems in the "Multi-Qubit Gates" kata.</p>\n",
|
|
763
|
+
"asMarkdown": "\nCongratulations! In this kata you learned to prepare separable multi-qubit states using only single-qubit gates. You also learned the difference between separable states an entangled states. Here are a few key concepts to keep in mind:\n\n- A system of $N$ qubits can also be in a superposition of $2^N$ quantum states. The computational basis for an $N$-qubit system is a set of $2^N$ vectors.\n- Any two-qubit system can be expressed as some linear combination of the tensor product of single-qubit basis states.\n- Two qubits are entangled if their states are correlated and if they can't be described as two independent qubits.\n\nNext, you will learn about multi-qubit gates and how they can give you access to all states of multi-qubit systems in the \"Multi-Qubit Gates\" kata."
|
|
764
|
+
}
|
|
765
|
+
]
|
|
766
|
+
}
|
|
767
|
+
]
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
"id": "multi_qubit_gates",
|
|
771
|
+
"title": "Multi-Qubit Gates",
|
|
772
|
+
"sections": [
|
|
773
|
+
{
|
|
774
|
+
"type": "lesson",
|
|
775
|
+
"id": "multi_qubit_gates__overview",
|
|
776
|
+
"title": "Overview",
|
|
777
|
+
"items": [
|
|
778
|
+
{
|
|
779
|
+
"type": "text-content",
|
|
780
|
+
"asHtml": "<p>This kata continues the introduction to quantum gates, focusing on applying quantum gates to multi-qubit systems.</p>\n<p><strong>This kata covers the following topics:</strong></p>\n<ul>\n<li>Applying quantum gates to a part of the system</li>\n<li><code>CNOT</code> and <code>SWAP</code> gates</li>\n<li>Controlled gates</li>\n</ul>\n<p><strong>What you should know to start working on this kata:</strong></p>\n<ul>\n<li>Basic linear algebra</li>\n<li>The concept of qubit and multi-qubit systems</li>\n<li>Single-qubit and multi-qubit quantum gates</li>\n</ul>\n",
|
|
781
|
+
"asMarkdown": "\nThis kata continues the introduction to quantum gates, focusing on applying quantum gates to multi-qubit systems.\n\n**This kata covers the following topics:**\n- Applying quantum gates to a part of the system\n- `CNOT` and `SWAP` gates\n- Controlled gates\n\n**What you should know to start working on this kata:**\n- Basic linear algebra\n- The concept of qubit and multi-qubit systems\n- Single-qubit and multi-qubit quantum gates"
|
|
782
|
+
}
|
|
783
|
+
]
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
"type": "lesson",
|
|
787
|
+
"id": "multi_qubit_gates__the_basics",
|
|
788
|
+
"title": "The Basics",
|
|
789
|
+
"items": [
|
|
790
|
+
{
|
|
791
|
+
"type": "text-content",
|
|
792
|
+
"asHtml": "<p>As a reminder, single-qubit gates are represented by $2\\times2$ unitary matrices.</p>\n<p>The effect of a gate applied to a qubit can be calculated by multiplying the corresponding matrix by the state vector of the qubit to get the resulting state vector.</p>\n<p>Multi-qubit gates are represented by $2^N\\times2^N$ matrices, where $N$ is the number of qubits the gate operates on. To apply this gate, you multiply the matrix by the state vector of the $N$-qubit quantum system.</p>\n<h2 id=\"applying-gates-to-a-part-of-the-system\">Applying Gates to a Part of the System</h2>\n<p>The simplest thing we can do with multi-qubit systems is to apply gates to only a subset of qubits in the system.\nSimilar to how it is sometimes possible to represent the state of a multi-qubit systems as a tensor product of single-qubit states, you can construct gates that modify the state of a multi-qubit system as tensor products of gates that affect parts of the system.</p>\n<p>Let's consider an example of applying single-qubit gates to one of the qubits of a two-qubit system.\nIf you want to apply an $X$ gate to the first qubit of the system and do nothing to the second qubit, the resulting gate will be represented as a tensor product of an $X$ gate and the identity gate $I$ which corresponds to doing nothing:</p>\n<p>$$\nX \\otimes I =\n\\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 & 0 \\\\ 0 & 1 \\end{bmatrix} =\n\\begin{bmatrix}\n 0 & 0 & 1 & 0 \\\\ \n 0 & 0 & 0 & 1 \\\\ \n 1 & 0 & 0 & 0 \\\\ \n 0 & 1 & 0 & 0\n\\end{bmatrix}\n$$</p>\n<p>You can use the same approach when applying several gates to independent parts of the system at the same time.\nFor example, applying the $X$ gate to the first qubit and the $H$ gate to the second qubit would be represented as follows:</p>\n<p>$$\nX \\otimes H =\n\\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix} \\otimes \\frac{1}{\\sqrt{2}}\\begin{bmatrix} 1 & 1 \\\\ 1 & -1 \\end{bmatrix} =\n\\frac{1}{\\sqrt{2}}\\begin{bmatrix}\n 0 & 0 & 1 & 1 \\\\ \n 0 & 0 & 1 & -1 \\\\ \n 1 & 1 & 0 & 0 \\\\ \n 1 & -1 & 0 & 0\n\\end{bmatrix}\n$$</p>\n<blockquote>\n<p>Note that we can use mixed-multiplication property of tensor product to see that this is equivalent to applying $X$ gate to the first qubit and applying $H$ gate to the second qubit, in either order:</p>\n<p>$$X \\otimes H = (I X) \\otimes (H I) = (I \\otimes H) (X \\otimes I)$$\n$$X \\otimes H = (X I) \\otimes (I H) = (X \\otimes I) (I \\otimes H)$$</p>\n</blockquote>\n<p>This approach can be generalized to larger systems and gates that act on multiple qubits as well.\nIt is more complex when a multi-qubit gate is applied to a subset of qubits that are not "adjacent" to each other in the tensor product; we'll see an example later in this kata.</p>\n",
|
|
793
|
+
"asMarkdown": "\nAs a reminder, single-qubit gates are represented by $2\\times2$ unitary matrices.\n\nThe effect of a gate applied to a qubit can be calculated by multiplying the corresponding matrix by the state vector of the qubit to get the resulting state vector.\n\nMulti-qubit gates are represented by $2^N\\\\times2^N$ matrices, where $N$ is the number of qubits the gate operates on. To apply this gate, you multiply the matrix by the state vector of the $N$-qubit quantum system.\n\n## Applying Gates to a Part of the System\n\nThe simplest thing we can do with multi-qubit systems is to apply gates to only a subset of qubits in the system.\nSimilar to how it is sometimes possible to represent the state of a multi-qubit systems as a tensor product of single-qubit states, you can construct gates that modify the state of a multi-qubit system as tensor products of gates that affect parts of the system.\n\nLet's consider an example of applying single-qubit gates to one of the qubits of a two-qubit system.\nIf you want to apply an $X$ gate to the first qubit of the system and do nothing to the second qubit, the resulting gate will be represented as a tensor product of an $X$ gate and the identity gate $I$ which corresponds to doing nothing:\n\n$$\nX \\otimes I =\n\\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 & 0 \\\\\\ 0 & 1 \\end{bmatrix} =\n\\begin{bmatrix}\n 0 & 0 & 1 & 0 \\\\\\ \n 0 & 0 & 0 & 1 \\\\\\ \n 1 & 0 & 0 & 0 \\\\\\ \n 0 & 1 & 0 & 0\n\\end{bmatrix}\n$$\n\nYou can use the same approach when applying several gates to independent parts of the system at the same time.\nFor example, applying the $X$ gate to the first qubit and the $H$ gate to the second qubit would be represented as follows:\n\n$$\nX \\otimes H =\n\\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix} \\otimes \\frac{1}{\\sqrt{2}}\\begin{bmatrix} 1 & 1 \\\\\\ 1 & -1 \\end{bmatrix} =\n\\frac{1}{\\sqrt{2}}\\begin{bmatrix}\n 0 & 0 & 1 & 1 \\\\\\ \n 0 & 0 & 1 & -1 \\\\\\ \n 1 & 1 & 0 & 0 \\\\\\ \n 1 & -1 & 0 & 0\n\\end{bmatrix}\n$$\n\n> Note that we can use mixed-multiplication property of tensor product to see that this is equivalent to applying $X$ gate to the first qubit and applying $H$ gate to the second qubit, in either order:\n>\n> $$X \\otimes H = (I X) \\otimes (H I) = (I \\otimes H) (X \\otimes I)$$\n> $$X \\otimes H = (X I) \\otimes (I H) = (X \\otimes I) (I \\otimes H)$$\n\nThis approach can be generalized to larger systems and gates that act on multiple qubits as well.\nIt is more complex when a multi-qubit gate is applied to a subset of qubits that are not \"adjacent\" to each other in the tensor product; we'll see an example later in this kata."
|
|
794
|
+
}
|
|
795
|
+
]
|
|
796
|
+
},
|
|
797
|
+
{
|
|
798
|
+
"type": "exercise",
|
|
799
|
+
"id": "multi_qubit_gates__compound_gate",
|
|
800
|
+
"title": "Compound Gate",
|
|
801
|
+
"description": {
|
|
802
|
+
"type": "text-content",
|
|
803
|
+
"asHtml": "<p><strong>Inputs:</strong> $3$ qubits in an arbitrary superposition state $|\\psi\\rangle$, stored in an array of length 3.</p>\n<p><strong>Goal:</strong> Apply the following matrix to the system. This matrix can be represented as applying $3$ single-qubit gates.</p>\n<p>$$\nQ =\n\\begin{bmatrix}\n0 & -i & 0 & 0 & 0 & 0 & 0 & 0 \\\\ \ni & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\ \n0 & 0 & 0 & -i & 0 & 0 & 0 & 0 \\\\ \n0 & 0 & i & 0 & 0 & 0 & 0 & 0 \\\\ \n0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\\\ \n0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 \\\\ \n0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\\\ \n0 & 0 & 0 & 0 & 0 & 0 & -1 & 0\n\\end{bmatrix}\n$$</p>\n<blockquote>\n<p>We recommend to keep a list of common quantum gates on hand.</p>\n</blockquote>\n<details>\n <summary><b>Need a hint?</b></summary>\n <p>Start by noticing that the top right and bottom left quadrants of the matrix are filled with $0$s, and the bottom right quadrant equals to the top left one, multiplied by $i$. Does this look like a tensor product of a 1-qubit and 2-qubit matrices? Which ones?</p>\n</details>",
|
|
804
|
+
"asMarkdown": "**Inputs:** $3$ qubits in an arbitrary superposition state $|\\\\psi\\\\rangle$, stored in an array of length 3.\n\n**Goal:** Apply the following matrix to the system. This matrix can be represented as applying $3$ single-qubit gates.\n\n$$\nQ =\n\\begin{bmatrix}\n0 & -i & 0 & 0 & 0 & 0 & 0 & 0 \\\\\\ \ni & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n0 & 0 & 0 & -i & 0 & 0 & 0 & 0 \\\\\\ \n0 & 0 & i & 0 & 0 & 0 & 0 & 0 \\\\\\ \n0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\\\\\ \n0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 \\\\\\ \n0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\\\\\ \n0 & 0 & 0 & 0 & 0 & 0 & -1 & 0\n\\end{bmatrix}\n$$\n\n> We recommend to keep a list of common quantum gates on hand.\n\n<details>\n <summary><b>Need a hint?</b></summary>\n <p>Start by noticing that the top right and bottom left quadrants of the matrix are filled with $0$s, and the bottom right quadrant equals to the top left one, multiplied by $i$. Does this look like a tensor product of a 1-qubit and 2-qubit matrices? Which ones?</p>\n</details>"
|
|
805
|
+
},
|
|
806
|
+
"sourceIds": [
|
|
807
|
+
"KatasLibrary.qs",
|
|
808
|
+
"multi_qubit_gates__compound_gate__Verification.qs"
|
|
809
|
+
],
|
|
810
|
+
"placeholderCode": "namespace Kata {\n operation CompoundGate(qs : Qubit[]) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}",
|
|
811
|
+
"explainedSolution": {
|
|
812
|
+
"type": "explained-solution",
|
|
813
|
+
"items": [
|
|
814
|
+
{
|
|
815
|
+
"type": "text-content",
|
|
816
|
+
"asHtml": "<p>One way to represent a multi-qubit transformation is to use the tensor product of gates acting on subsets of qubits. For example, if you have 2 qubits, applying the <strong>Z</strong> gate on the first qubit and the <strong>X</strong> gate on the second qubit will create this matrix:\\n",</p>\n<p>$$\nZ \\otimes X =\n\\begin{bmatrix} 1 & 0 \\\\ 0 & -1 \\end{bmatrix} \\otimes \\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix} =\n\\begin{bmatrix} 0 & 1 & 0 & 0 \\\\ 1 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & -1 \\\\ 0 & 0 & -1 & 0 \\end{bmatrix}\n$$</p>\n<p>With this in mind, let's see how to reverse engineer the target matrix above to find the 3 gates which, acting on individual qubits, together form the target transformation.</p>\n<p>Start by noticing that the top right and bottom left quadrants of the target matrix are filled with $0$'s, and the bottom right quadrant equals to the top left one, multiplied by $i$. This hints at applying the <code>S</code> gate to the first qubit:</p>\n<p>$$\nQ =\n\\begin{bmatrix} 1 & 0 \\\\ 0 & i \\end{bmatrix} \\otimes\n\\begin{bmatrix}\n 0 & -i & 0 & 0 \\\\ \n i & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & -i \\\\ \n 0 & 0 & i & 0 \n\\end{bmatrix} =\n\\begin{bmatrix}\n 0 & -i & 0 & 0 & 0 & 0 & 0 & 0 \\\\ \n i & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & -i & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & i & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0\n\\end{bmatrix}\n$$</p>\n<p>Now the $4 \\times 4$ matrix has all $0$s in the top right and bottom left quadrants, and the bottom right quadrant equals to the top left one. This means the second qubit has the $I$ gate applied to it, and the third qubit - the $Y$ gate:</p>\n<p>$$\nQ =\n\\begin{bmatrix} 1 & 0 \\\\ 0 & i \\end{bmatrix} \\otimes \\begin{bmatrix} 1 & 0 \\\\ 0 & 1 \\end{bmatrix} \\otimes\n\\begin{bmatrix} 0 & -i \\\\ i & 0 \\end{bmatrix} = S \\otimes I \\otimes Y\n$$</p>\n",
|
|
817
|
+
"asMarkdown": "\nOne way to represent a multi-qubit transformation is to use the tensor product of gates acting on subsets of qubits. For example, if you have 2 qubits, applying the **Z** gate on the first qubit and the **X** gate on the second qubit will create this matrix:\\n\",\n\n$$\nZ \\otimes X =\n\\begin{bmatrix} 1 & 0 \\\\\\ 0 & -1 \\end{bmatrix} \\otimes \\begin{bmatrix} 0 & 1 \\\\\\ 1 & 0 \\end{bmatrix} =\n\\begin{bmatrix} 0 & 1 & 0 & 0 \\\\\\ 1 & 0 & 0 & 0 \\\\\\ 0 & 0 & 0 & -1 \\\\\\ 0 & 0 & -1 & 0 \\end{bmatrix}\n$$\n\nWith this in mind, let's see how to reverse engineer the target matrix above to find the 3 gates which, acting on individual qubits, together form the target transformation.\n\nStart by noticing that the top right and bottom left quadrants of the target matrix are filled with $0$'s, and the bottom right quadrant equals to the top left one, multiplied by $i$. This hints at applying the `S` gate to the first qubit:\n\n$$\nQ =\n\\begin{bmatrix} 1 & 0 \\\\\\ 0 & i \\end{bmatrix} \\otimes\n\\begin{bmatrix}\n 0 & -i & 0 & 0 \\\\\\ \n i & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & -i \\\\\\ \n 0 & 0 & i & 0 \n\\end{bmatrix} =\n\\begin{bmatrix}\n 0 & -i & 0 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n i & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & -i & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & i & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0\n\\end{bmatrix}\n$$\n\nNow the $4 \\times 4$ matrix has all $0$s in the top right and bottom left quadrants, and the bottom right quadrant equals to the top left one. This means the second qubit has the $I$ gate applied to it, and the third qubit - the $Y$ gate:\n\n$$\nQ =\n\\begin{bmatrix} 1 & 0 \\\\\\ 0 & i \\end{bmatrix} \\otimes \\begin{bmatrix} 1 & 0 \\\\\\ 0 & 1 \\end{bmatrix} \\otimes\n\\begin{bmatrix} 0 & -i \\\\\\ i & 0 \\end{bmatrix} = S \\otimes I \\otimes Y\n$$"
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
"type": "solution",
|
|
821
|
+
"id": "multi_qubit_gates__compound_gate_solution",
|
|
822
|
+
"code": "namespace Kata {\n operation CompoundGate (qs : Qubit[]) : Unit is Adj + Ctl {\n S(qs[0]);\n I(qs[1]); // this line can be omitted, since it doesn't change the qubit state\n Y(qs[2]);\n }\n}"
|
|
823
|
+
}
|
|
824
|
+
]
|
|
825
|
+
}
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
"type": "lesson",
|
|
829
|
+
"id": "multi_qubit_gates__cnot_gate",
|
|
830
|
+
"title": "CNOT Gate",
|
|
831
|
+
"items": [
|
|
832
|
+
{
|
|
833
|
+
"type": "text-content",
|
|
834
|
+
"asHtml": "<p>Our first proper multi-qubit gate is the <code>CNOT</code> ("controlled NOT") gate. The <code>CNOT</code> gate is a two-qubit gate, one is referred to as the <strong>control</strong> qubit, and the other one is the <strong>target</strong> qubit (usually the first qubit is the control, and the second qubit is the target).</p>\n<p><code>CNOT</code> acts as a conditional gate of sorts: if the control qubit is in state $|1\\rangle$, it applies the <code>X</code> gate to the target qubit, otherwise it does nothing.</p>\n<blockquote>\n<p>If the system is in a superposition of several basis states, the effects of the gate will be a linear combination of the effects of it acting separately on each of the basis states.\nThis will be the case for all quantum gates you'll encounter later that are specified in terms of basis states: since all unitary gates are linear, it is sufficient to define their effect on the basis states, and use linearity to figure out their effect on any state.</p>\n</blockquote>\n<table>\n <tr>\n <th>Gate</th>\n <th>Matrix</th>\n <th>Applying to $|\\psi\\rangle = \\alpha|00\\rangle + \\beta|01\\rangle + \\gamma|10\\rangle + \\delta|11\\rangle$</th>\n <th>Applying to basis states</th>\n <th>Q# Documentation</th>\n </tr>\n <tr>\n <td>$\\text{CNOT}$</td>\n <td>$\\begin{bmatrix} 1 & 0 & 0 & 0 \\\\\\ 0 & 1 & 0 & 0 \\\\\\ 0 & 0 & 0 & 1 \\\\\\ 0 & 0 & 1 & 0 \\end{bmatrix}$</td>\n <td>$\\text{CNOT}|\\psi\\rangle = \\alpha|00\\rangle + \\beta|01\\rangle + \\delta|10\\rangle + \\gamma|11\\rangle$</td>\n <td>\n $$\\text{CNOT}|00\\rangle = |00\\rangle$$\n $$\\text{CNOT}|01\\rangle = |01\\rangle$$\n $$\\text{CNOT}|10\\rangle = |11\\rangle$$\n $$\\text{CNOT}|11\\rangle = |10\\rangle$$\n </td>\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.cnot\" target=\"_blank\">CNOT</a></td>\n </tr>\n</table>\n\n<p>The <code>CNOT</code> gate is particularly useful for preparing entangled states. Consider the following separable state:</p>\n<p>$$\\big(\\alpha|0\\rangle + \\beta|1\\rangle\\big) \\otimes |0\\rangle = \\alpha|00\\rangle + \\beta|10\\rangle$$</p>\n<p>If we apply the $\\text{CNOT}$ gate to it, with the first qubit as the control, and the second as the target, we get the following state, which is not separable any longer:</p>\n<p>$$\\alpha|00\\rangle + \\beta|11\\rangle$$</p>\n<p>The <code>CNOT</code> gate is self-adjoint: applying it for the second time reverses its effect.</p>\n",
|
|
835
|
+
"asMarkdown": "\nOur first proper multi-qubit gate is the `CNOT` (\"controlled NOT\") gate. The `CNOT` gate is a two-qubit gate, one is referred to as the **control** qubit, and the other one is the **target** qubit (usually the first qubit is the control, and the second qubit is the target).\n\n`CNOT` acts as a conditional gate of sorts: if the control qubit is in state $|1\\\\rangle$, it applies the `X` gate to the target qubit, otherwise it does nothing.\n\n> If the system is in a superposition of several basis states, the effects of the gate will be a linear combination of the effects of it acting separately on each of the basis states.\n> This will be the case for all quantum gates you'll encounter later that are specified in terms of basis states: since all unitary gates are linear, it is sufficient to define their effect on the basis states, and use linearity to figure out their effect on any state.\n\n<table>\n <tr>\n <th>Gate</th>\n <th>Matrix</th>\n <th>Applying to $|\\psi\\rangle = \\alpha|00\\rangle + \\beta|01\\rangle + \\gamma|10\\rangle + \\delta|11\\rangle$</th>\n <th>Applying to basis states</th>\n <th>Q# Documentation</th>\n </tr>\n <tr>\n <td>$\\text{CNOT}$</td>\n <td>$\\begin{bmatrix} 1 & 0 & 0 & 0 \\\\\\ 0 & 1 & 0 & 0 \\\\\\ 0 & 0 & 0 & 1 \\\\\\ 0 & 0 & 1 & 0 \\end{bmatrix}$</td>\n <td>$\\text{CNOT}|\\psi\\rangle = \\alpha|00\\rangle + \\beta|01\\rangle + \\delta|10\\rangle + \\gamma|11\\rangle$</td>\n <td>\n $$\\text{CNOT}|00\\rangle = |00\\rangle$$\n $$\\text{CNOT}|01\\rangle = |01\\rangle$$\n $$\\text{CNOT}|10\\rangle = |11\\rangle$$\n $$\\text{CNOT}|11\\rangle = |10\\rangle$$\n </td>\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.cnot\" target=\"_blank\">CNOT</a></td>\n </tr>\n</table>\n\nThe `CNOT` gate is particularly useful for preparing entangled states. Consider the following separable state:\n\n$$\\big(\\alpha|0\\rangle + \\beta|1\\rangle\\big) \\otimes |0\\rangle = \\alpha|00\\rangle + \\beta|10\\rangle$$\n\nIf we apply the $\\\\text{CNOT}$ gate to it, with the first qubit as the control, and the second as the target, we get the following state, which is not separable any longer:\n\n$$\\alpha|00\\rangle + \\beta|11\\rangle$$\n\nThe `CNOT` gate is self-adjoint: applying it for the second time reverses its effect."
|
|
836
|
+
}
|
|
837
|
+
]
|
|
838
|
+
},
|
|
839
|
+
{
|
|
840
|
+
"type": "exercise",
|
|
841
|
+
"id": "multi_qubit_gates__preparing_bell_state",
|
|
842
|
+
"title": "Preparing a Bell State",
|
|
843
|
+
"description": {
|
|
844
|
+
"type": "text-content",
|
|
845
|
+
"asHtml": "<p><strong>Input:</strong> Two qubits in state $|00\\rangle$, stored in an array of length 2.</p>\n<p><strong>Goal:</strong> Transform the system into the Bell state $\\Phi^+ = \\frac{1}{\\sqrt{2}}\\big(|00\\rangle + |11\\rangle\\big)$.</p>\n",
|
|
846
|
+
"asMarkdown": "**Input:** Two qubits in state $|00\\\\rangle$, stored in an array of length 2.\n\n**Goal:** Transform the system into the Bell state $\\\\Phi^+ = \\\\frac{1}{\\\\sqrt{2}}\\\\big(|00\\\\rangle + |11\\\\rangle\\\\big)$."
|
|
847
|
+
},
|
|
848
|
+
"sourceIds": [
|
|
849
|
+
"KatasLibrary.qs",
|
|
850
|
+
"multi_qubit_gates__preparing_bell_state__Verification.qs"
|
|
851
|
+
],
|
|
852
|
+
"placeholderCode": "namespace Kata {\n operation BellState (qs : Qubit[]) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}",
|
|
853
|
+
"explainedSolution": {
|
|
854
|
+
"type": "explained-solution",
|
|
855
|
+
"items": [
|
|
856
|
+
{
|
|
857
|
+
"type": "text-content",
|
|
858
|
+
"asHtml": "<p>We've seen this state before in the[Multi-Qubit Systems kata, where we established that this state is not separable, i.e., it can not be prepared using just the single-qubit gates. To prepare it, we need to use <code>CNOT</code> gate.</p>\n<p>Let's look at the effect of the <code>CNOT</code> gate on a separable state described in the tutorial:\n$$CNOT_{1,2}\\big(\\alpha|0\\rangle + \\beta|1\\rangle\\big) \\otimes |0\\rangle = CNOT_{1,2}(\\alpha|00\\rangle + \\beta|10\\rangle) = \\alpha|00\\rangle + \\beta|11\\rangle$$</p>\n<p>This resulting state is exactly the state we need to prepare, with $\\alpha = \\beta = \\frac{1}{\\sqrt{2}}$!</p>\n<p>The solution takes two steps:</p>\n<ol>\n<li>Prepare a state $\\big(\\frac{1}{\\sqrt{2}}|0\\rangle + \\frac{1}{\\sqrt{2}}|1\\rangle\\big) \\otimes |0\\rangle$.\nWe can use the Hadamard gate to do this.</li>\n<li>Apply a CNOT take with the first qubit as the control and the second qubit as the target.</li>\n</ol>\n",
|
|
859
|
+
"asMarkdown": "\nWe've seen this state before in the[Multi-Qubit Systems kata, where we established that this state is not separable, i.e., it can not be prepared using just the single-qubit gates. To prepare it, we need to use `CNOT` gate.\n\nLet's look at the effect of the `CNOT` gate on a separable state described in the tutorial:\n$$CNOT_{1,2}\\big(\\alpha|0\\rangle + \\beta|1\\rangle\\big) \\otimes |0\\rangle = CNOT_{1,2}(\\alpha|00\\rangle + \\beta|10\\rangle) = \\alpha|00\\rangle + \\beta|11\\rangle$$\n\nThis resulting state is exactly the state we need to prepare, with $\\alpha = \\beta = \\frac{1}{\\sqrt{2}}$!\n\nThe solution takes two steps:\n1. Prepare a state $\\big(\\frac{1}{\\sqrt{2}}|0\\rangle + \\frac{1}{\\sqrt{2}}|1\\rangle\\big) \\otimes |0\\rangle$.\nWe can use the Hadamard gate to do this.\n2. Apply a CNOT take with the first qubit as the control and the second qubit as the target."
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
"type": "solution",
|
|
863
|
+
"id": "multi_qubit_gates__preparing_bell_state_solution",
|
|
864
|
+
"code": "namespace Kata {\n operation BellState (qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n CNOT(qs[0], qs[1]);\n }\n}"
|
|
865
|
+
}
|
|
866
|
+
]
|
|
867
|
+
}
|
|
868
|
+
},
|
|
869
|
+
{
|
|
870
|
+
"type": "lesson",
|
|
871
|
+
"id": "multi_qubit_gates__ket_bra_representation",
|
|
872
|
+
"title": "Ket-Bra Representation",
|
|
873
|
+
"items": [
|
|
874
|
+
{
|
|
875
|
+
"type": "text-content",
|
|
876
|
+
"asHtml": "<p>Same as in the case of single-qubit gates, we can represent multi-qubit gates using Dirac notation.</p>\n<blockquote>\n<p>Recall that kets represent column vectors and bras represent row vectors. For any ket $|\\psi\\rangle$, the corresponding bra is its adjoint (conjugate transpose): $\\langle\\psi| = |\\psi\\rangle^\\dagger$.</p>\n<p>Kets and bras are used to express inner and outer products. The inner product of $|\\phi\\rangle$ and $|\\psi\\rangle$ is the matrix product of $\\langle\\phi|$ and $|\\psi\\rangle$, denoted as $\\langle\\phi|\\psi\\rangle$, and their outer product is the matrix product of $|\\phi\\rangle$ and $\\langle\\psi|$, denoted as $|\\phi\\rangle\\langle\\psi|$.</p>\n<p>As we've seen in the "Single-Qubit Gates" kata, kets and bras can be used to represent matrices. The outer product of two vectors of the same size produces a square matrix. We can use a linear combination of several outer products of simple vectors (such as basis vectors) to express any square matrix.</p>\n</blockquote>\n<p>Let's consider ket-bra representation of the $\\text{CNOT}$ gate:</p>\n<p>$$\\text{CNOT} =$$\n$$|00\\rangle\\langle00| + |01\\rangle\\langle01| + |10\\rangle\\langle11| + |11\\rangle\\langle10| =$$\n$$\n\\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix}\\begin{bmatrix} 1 & 0 & 0 & 0 \\end{bmatrix} +\n\\begin{bmatrix} 0 \\\\ 1 \\\\ 0 \\\\ 0 \\end{bmatrix}\\begin{bmatrix} 0 & 1 & 0 & 0 \\end{bmatrix} +\n\\begin{bmatrix} 0 \\\\ 0 \\\\ 1 \\\\ 0 \\end{bmatrix}\\begin{bmatrix} 0 & 0 & 0 & 1 \\end{bmatrix} +\n\\begin{bmatrix} 0 \\\\ 0 \\\\ 0 \\\\ 1 \\end{bmatrix}\\begin{bmatrix} 0 & 0 & 1 & 0 \\end{bmatrix} =\n$$ \n$$\n\\begin{bmatrix} 1 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 0 \\\\ \\end{bmatrix} + \n\\begin{bmatrix} 0 & 0 & 0 & 0 \\\\ 0 & 1 & 0 & 0 \\\\ 0 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 0 \\\\ \\end{bmatrix} + \n\\begin{bmatrix} 0 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 1 \\\\ 0 & 0 & 0 & 0 \\\\ \\end{bmatrix} + \n\\begin{bmatrix} 0 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 0 \\\\ 0 & 0 & 1 & 0 \\\\ \\end{bmatrix} =\n$$\n$$\\begin{bmatrix} 1 & 0 & 0 & 0 \\\\ 0 & 1 & 0 & 0 \\\\ 0 & 0 & 0 & 1 \\\\ 0 & 0 & 1 & 0 \\\\ \\end{bmatrix}$$</p>\n<p>This representation can be used to carry out calculations in Dirac notation without ever switching back to matrix representation:</p>\n<p>$$\n\\text{CNOT}|10\\rangle = \n\\big(|00\\rangle\\langle00| + |01\\rangle\\langle01| + |10\\rangle\\langle11| + |11\\rangle\\langle10|\\big)|10\\rangle =$$\n$$|00\\rangle\\langle00|10\\rangle + |01\\rangle\\langle01|10\\rangle + |10\\rangle\\langle11|10\\rangle + |11\\rangle\\langle10|10\\rangle =$$\n$$|00\\rangle\\big(\\langle00|10\\rangle\\big) + |01\\rangle\\big(\\langle01|10\\rangle\\big) + |10\\rangle\\big(\\langle11|10\\rangle\\big) + |11\\rangle\\big(\\langle10|10\\rangle\\big) =$$\n$$|00\\rangle(0) + |01\\rangle(0) + |10\\rangle(0) + |11\\rangle(1) = |11\\rangle$$</p>\n<blockquote>\n<p>Notice how a lot of the inner product terms turn out to equal 0, and our expression is easily simplified. We have expressed the CNOT gate in terms of outer product of computational basis states, which are orthonormal, and apply it to another computational basis state, so the individual inner products are going to always be 0 or 1.</p>\n</blockquote>\n<p>In general case, a $4\\times4$ matrix that describes a 2-qubit gate\n$$A =\n\\begin{bmatrix}\n a_{00} & a_{01} & a_{02} & a_{03} \\\\ \n a_{10} & a_{11} & a_{12} & a_{13} \\\\ \n a_{20} & a_{21} & a_{22} & a_{23} \\\\ \n a_{30} & a_{31} & a_{32} & a_{33} \\\\ \n\\end{bmatrix}\n$$</p>\n<p>will have the following ket-bra representation:\n$$A =$$\n$$a_{00} |00\\rangle\\langle00| + a_{01} |00\\rangle\\langle01| + a_{02} |00\\rangle\\langle10| + a_{03} |00\\rangle\\langle11| +$$\n$$a_{10} |01\\rangle\\langle00| + a_{11} |01\\rangle\\langle01| + a_{12} |01\\rangle\\langle10| + a_{13} |01\\rangle\\langle11| +$$\n$$a_{20} |10\\rangle\\langle00| + a_{21} |10\\rangle\\langle01| + a_{22} |10\\rangle\\langle10| + a_{23} |10\\rangle\\langle11| +$$\n$$a_{30} |11\\rangle\\langle00| + a_{31} |11\\rangle\\langle01| + a_{32} |11\\rangle\\langle10| + a_{33} |11\\rangle\\langle11|$$</p>\n<p>A similar expression can be extended for matrices that describe $N$-qubit gates, where $N > 2$:</p>\n<p>$$A = \\sum_{i=0}^{2^N-1} \\sum_{j=0}^{2^N-1} a_{ij} |i\\rangle\\langle j|$$</p>\n<p>Dirac notation is particularly useful for expressing sparse matrices - matrices that have few non-zero elements. Indeed, consider the <code>CNOT</code> gate again: it is a $4 \\times 4$ matrix described with 16 elements, but its Dirac notation has only 4 terms, one for each non-zero element of the matrix.</p>\n<p>With enough practice you'll be able to perform computations in Dirac notation without spelling out all the bra-ket terms explicitly!</p>\n",
|
|
877
|
+
"asMarkdown": "\nSame as in the case of single-qubit gates, we can represent multi-qubit gates using Dirac notation.\n\n> Recall that kets represent column vectors and bras represent row vectors. For any ket $|\\psi\\rangle$, the corresponding bra is its adjoint (conjugate transpose): $\\langle\\psi| = |\\psi\\rangle^\\dagger$.\n>\n> Kets and bras are used to express inner and outer products. The inner product of $|\\phi\\rangle$ and $|\\psi\\rangle$ is the matrix product of $\\langle\\phi|$ and $|\\psi\\rangle$, denoted as $\\langle\\phi|\\psi\\rangle$, and their outer product is the matrix product of $|\\phi\\rangle$ and $\\langle\\psi|$, denoted as $|\\phi\\rangle\\langle\\psi|$.\n>\n> As we've seen in the \"Single-Qubit Gates\" kata, kets and bras can be used to represent matrices. The outer product of two vectors of the same size produces a square matrix. We can use a linear combination of several outer products of simple vectors (such as basis vectors) to express any square matrix.\n\nLet's consider ket-bra representation of the $\\\\text{CNOT}$ gate:\n\n$$\\text{CNOT} =$$\n$$|00\\rangle\\langle00| + |01\\rangle\\langle01| + |10\\rangle\\langle11| + |11\\rangle\\langle10| =$$\n$$\n\\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix}\\begin{bmatrix} 1 & 0 & 0 & 0 \\end{bmatrix} +\n\\begin{bmatrix} 0 \\\\\\ 1 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix}\\begin{bmatrix} 0 & 1 & 0 & 0 \\end{bmatrix} +\n\\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 1 \\\\\\ 0 \\end{bmatrix}\\begin{bmatrix} 0 & 0 & 0 & 1 \\end{bmatrix} +\n\\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 0 \\\\\\ 1 \\end{bmatrix}\\begin{bmatrix} 0 & 0 & 1 & 0 \\end{bmatrix} =\n$$ \n$$\n\\begin{bmatrix} 1 & 0 & 0 & 0 \\\\\\ 0 & 0 & 0 & 0 \\\\\\ 0 & 0 & 0 & 0 \\\\\\ 0 & 0 & 0 & 0 \\\\\\ \\end{bmatrix} + \n\\begin{bmatrix} 0 & 0 & 0 & 0 \\\\\\ 0 & 1 & 0 & 0 \\\\\\ 0 & 0 & 0 & 0 \\\\\\ 0 & 0 & 0 & 0 \\\\\\ \\end{bmatrix} + \n\\begin{bmatrix} 0 & 0 & 0 & 0 \\\\\\ 0 & 0 & 0 & 0 \\\\\\ 0 & 0 & 0 & 1 \\\\\\ 0 & 0 & 0 & 0 \\\\\\ \\end{bmatrix} + \n\\begin{bmatrix} 0 & 0 & 0 & 0 \\\\\\ 0 & 0 & 0 & 0 \\\\\\ 0 & 0 & 0 & 0 \\\\\\ 0 & 0 & 1 & 0 \\\\\\ \\end{bmatrix} =\n$$\n$$\\begin{bmatrix} 1 & 0 & 0 & 0 \\\\\\ 0 & 1 & 0 & 0 \\\\\\ 0 & 0 & 0 & 1 \\\\\\ 0 & 0 & 1 & 0 \\\\\\ \\end{bmatrix}$$\n\nThis representation can be used to carry out calculations in Dirac notation without ever switching back to matrix representation:\n\n$$\n\\text{CNOT}|10\\rangle = \n\\big(|00\\rangle\\langle00| + |01\\rangle\\langle01| + |10\\rangle\\langle11| + |11\\rangle\\langle10|\\big)|10\\rangle =$$\n$$|00\\rangle\\langle00|10\\rangle + |01\\rangle\\langle01|10\\rangle + |10\\rangle\\langle11|10\\rangle + |11\\rangle\\langle10|10\\rangle =$$\n$$|00\\rangle\\big(\\langle00|10\\rangle\\big) + |01\\rangle\\big(\\langle01|10\\rangle\\big) + |10\\rangle\\big(\\langle11|10\\rangle\\big) + |11\\rangle\\big(\\langle10|10\\rangle\\big) =$$\n$$|00\\rangle(0) + |01\\rangle(0) + |10\\rangle(0) + |11\\rangle(1) = |11\\rangle$$\n\n> Notice how a lot of the inner product terms turn out to equal 0, and our expression is easily simplified. We have expressed the CNOT gate in terms of outer product of computational basis states, which are orthonormal, and apply it to another computational basis state, so the individual inner products are going to always be 0 or 1.\n\nIn general case, a $4\\\\times4$ matrix that describes a 2-qubit gate\n$$A =\n\\begin{bmatrix}\n a_{00} & a_{01} & a_{02} & a_{03} \\\\\\ \n a_{10} & a_{11} & a_{12} & a_{13} \\\\\\ \n a_{20} & a_{21} & a_{22} & a_{23} \\\\\\ \n a_{30} & a_{31} & a_{32} & a_{33} \\\\\\ \n\\end{bmatrix}\n$$\n\nwill have the following ket-bra representation:\n$$A =$$\n$$a_{00} |00\\rangle\\langle00| + a_{01} |00\\rangle\\langle01| + a_{02} |00\\rangle\\langle10| + a_{03} |00\\rangle\\langle11| +$$\n$$a_{10} |01\\rangle\\langle00| + a_{11} |01\\rangle\\langle01| + a_{12} |01\\rangle\\langle10| + a_{13} |01\\rangle\\langle11| +$$\n$$a_{20} |10\\rangle\\langle00| + a_{21} |10\\rangle\\langle01| + a_{22} |10\\rangle\\langle10| + a_{23} |10\\rangle\\langle11| +$$\n$$a_{30} |11\\rangle\\langle00| + a_{31} |11\\rangle\\langle01| + a_{32} |11\\rangle\\langle10| + a_{33} |11\\rangle\\langle11|$$\n\nA similar expression can be extended for matrices that describe $N$-qubit gates, where $N > 2$:\n\n$$A = \\sum_{i=0}^{2^N-1} \\sum_{j=0}^{2^N-1} a_{ij} |i\\rangle\\langle j|$$\n\nDirac notation is particularly useful for expressing sparse matrices - matrices that have few non-zero elements. Indeed, consider the `CNOT` gate again: it is a $4 \\times 4$ matrix described with 16 elements, but its Dirac notation has only 4 terms, one for each non-zero element of the matrix.\n\nWith enough practice you'll be able to perform computations in Dirac notation without spelling out all the bra-ket terms explicitly!"
|
|
878
|
+
}
|
|
879
|
+
]
|
|
880
|
+
},
|
|
881
|
+
{
|
|
882
|
+
"type": "lesson",
|
|
883
|
+
"id": "multi_qubit_gates__ket_bra_decomposition",
|
|
884
|
+
"title": "Ket-Bra Decomposition",
|
|
885
|
+
"items": [
|
|
886
|
+
{
|
|
887
|
+
"type": "text-content",
|
|
888
|
+
"asHtml": "<p>This section describes a more formal process of finding the ket-bra decompositions of multi-qubit quantum gates.\nThis section is not necessary to start working with quantum gates, so feel free to skip it for now, and come back to it later.</p>\n<p>You can use the properties of eigenvalues and eigenvectors to find the ket-bra decomposition of any gate. Consider an $N$-qubit gate $A$; the matrix representation of the gate is a square matrix of size $2^N$. Therefore it also has $2^N$ orthogonal eigenvectors $|\\psi_i\\rangle$</p>\n<p>$$A|\\psi_i\\rangle = x_i|\\psi_i\\rangle, 0 \\leq i \\leq 2^N -1$$</p>\n<p>Then its ket-bra decomposition is:</p>\n<p>$$A = \\sum_{i=0}^{2^N-1} x_i|\\psi_i\\rangle\\langle\\psi_i|$$</p>\n<p>Let's use our <code>CNOT</code> gate as a simple example.\nThe $\\text{CNOT}$ gate has four eigenvectors.</p>\n<ul>\n<li>Two, as we can clearly see, are computational basis states $|00\\rangle$ and $|01\\rangle$ with eigen values $1$ and $1$, respectively (the basis states that are not affected by the gate).</li>\n<li>The other two are $|1\\rangle \\otimes |+\\rangle = \\frac{1}{\\sqrt{2}}\\big(|10\\rangle + |11\\rangle\\big)$ and $|1\\rangle \\otimes |-\\rangle = \\frac{1}{\\sqrt{2}}\\big(|10\\rangle - |11\\rangle\\big)$ with eigenvalues $1$ and $-1$, respectively:</li>\n</ul>\n<p>$$\\text{CNOT}|00\\rangle = |00\\rangle$$\n$$\\text{CNOT}|01\\rangle = |01\\rangle$$\n$$\\text{CNOT}|1+\\rangle = |1+\\rangle$$\n$$\\text{CNOT}|1-\\rangle = -|1-\\rangle$$</p>\n<p>Here's what the decomposition looks like:</p>\n<p>$$\\text{CNOT} =$$\n$$|00\\rangle\\langle00| + |01\\rangle\\langle01| + |1+\\rangle\\langle1+| - |1-\\rangle\\langle1-| =$$\n$$|00\\rangle\\langle00| + |01\\rangle\\langle01| + \\frac{1}{2}\\big[\\big(|10\\rangle + |11\\rangle\\big)\\big(\\langle10| + \\langle11|\\big) - \\big(|10\\rangle - |11\\rangle\\big)\\big(\\langle10| - \\langle11|\\big)\\big] =$$\n$$|00\\rangle\\langle00| + |01\\rangle\\langle01| + \\frac{1}{2}\\big(|10\\rangle\\langle10| + |10\\rangle\\langle11| + |11\\rangle\\langle10| + |11\\rangle\\langle11| - |10\\rangle\\langle10| + |10\\rangle\\langle11| + |11\\rangle\\langle10| - |11\\rangle\\langle11|\\big) =$$\n$$|00\\rangle\\langle00| + |01\\rangle\\langle01| + \\frac{1}{2}\\big(2|10\\rangle\\langle11| + 2|11\\rangle\\langle10|\\big) =$$\n$$|00\\rangle\\langle00| + |01\\rangle\\langle01| + |10\\rangle\\langle11| + |11\\rangle\\langle10|$$</p>\n",
|
|
889
|
+
"asMarkdown": "\nThis section describes a more formal process of finding the ket-bra decompositions of multi-qubit quantum gates.\nThis section is not necessary to start working with quantum gates, so feel free to skip it for now, and come back to it later.\n\nYou can use the properties of eigenvalues and eigenvectors to find the ket-bra decomposition of any gate. Consider an $N$-qubit gate $A$; the matrix representation of the gate is a square matrix of size $2^N$. Therefore it also has $2^N$ orthogonal eigenvectors $|\\psi_i\\rangle$\n\n$$A|\\psi_i\\rangle = x_i|\\psi_i\\rangle, 0 \\leq i \\leq 2^N -1$$\n\nThen its ket-bra decomposition is:\n\n$$A = \\sum_{i=0}^{2^N-1} x_i|\\psi_i\\rangle\\langle\\psi_i|$$\n\nLet's use our `CNOT` gate as a simple example.\nThe $\\\\text{CNOT}$ gate has four eigenvectors.\n * Two, as we can clearly see, are computational basis states $|00\\rangle$ and $|01\\rangle$ with eigen values $1$ and $1$, respectively (the basis states that are not affected by the gate).\n * The other two are $|1\\rangle \\otimes |+\\rangle = \\frac{1}{\\sqrt{2}}\\big(|10\\rangle + |11\\rangle\\big)$ and $|1\\rangle \\otimes |-\\rangle = \\frac{1}{\\sqrt{2}}\\big(|10\\rangle - |11\\rangle\\big)$ with eigenvalues $1$ and $-1$, respectively:\n\n$$\\text{CNOT}|00\\rangle = |00\\rangle$$\n$$\\text{CNOT}|01\\rangle = |01\\rangle$$\n$$\\text{CNOT}|1+\\rangle = |1+\\rangle$$\n$$\\text{CNOT}|1-\\rangle = -|1-\\rangle$$\n\nHere's what the decomposition looks like:\n\n$$\\text{CNOT} =$$\n$$|00\\rangle\\langle00| + |01\\rangle\\langle01| + |1+\\rangle\\langle1+| - |1-\\rangle\\langle1-| =$$\n$$|00\\rangle\\langle00| + |01\\rangle\\langle01| + \\frac{1}{2}\\big[\\big(|10\\rangle + |11\\rangle\\big)\\big(\\langle10| + \\langle11|\\big) - \\big(|10\\rangle - |11\\rangle\\big)\\big(\\langle10| - \\langle11|\\big)\\big] =$$\n$$|00\\rangle\\langle00| + |01\\rangle\\langle01| + \\frac{1}{2}\\big(|10\\rangle\\langle10| + |10\\rangle\\langle11| + |11\\rangle\\langle10| + |11\\rangle\\langle11| - |10\\rangle\\langle10| + |10\\rangle\\langle11| + |11\\rangle\\langle10| - |11\\rangle\\langle11|\\big) =$$\n$$|00\\rangle\\langle00| + |01\\rangle\\langle01| + \\frac{1}{2}\\big(2|10\\rangle\\langle11| + 2|11\\rangle\\langle10|\\big) =$$\n$$|00\\rangle\\langle00| + |01\\rangle\\langle01| + |10\\rangle\\langle11| + |11\\rangle\\langle10|$$"
|
|
890
|
+
}
|
|
891
|
+
]
|
|
892
|
+
},
|
|
893
|
+
{
|
|
894
|
+
"type": "lesson",
|
|
895
|
+
"id": "multi_qubit_gates__swap_gate",
|
|
896
|
+
"title": "SWAP Gate",
|
|
897
|
+
"items": [
|
|
898
|
+
{
|
|
899
|
+
"type": "text-content",
|
|
900
|
+
"asHtml": "<p>The <code>SWAP</code> gate acts on two qubits, and, as the name implies, swaps their quantum states.</p>\n<table>\n <tr>\n <th>Gate</th>\n <th>Matrix</th>\n <th>Applying to $|\\psi\\rangle = \\alpha|00\\rangle + \\beta|01\\rangle + \\gamma|10\\rangle + \\delta|11\\rangle$</th>\n <th>Applying to basis states</th>\n <th>Q# Documentation</th>\n </tr>\n <tr>\n <td>$\\text{SWAP}$</td>\n <td>$\\begin{bmatrix} 1 & 0 & 0 & 0 \\\\\\ 0 & 0 & 1 & 0 \\\\\\ 0 & 1 & 0 & 0 \\\\\\ 0 & 0 & 0 & 1 \\end{bmatrix}$</td>\n <td>$\\text{SWAP}|\\psi\\rangle = \\alpha|00\\rangle + \\gamma|01\\rangle + \\beta|10\\rangle + \\delta|11\\rangle$</td>\n <td>\n $$\\text{SWAP}|00\\rangle = |00\\rangle$$\n $$\\text{SWAP}|01\\rangle = |10\\rangle$$\n $$\\text{SWAP}|10\\rangle = |01\\rangle$$\n $$\\text{SWAP}|11\\rangle = |11\\rangle$$\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.swap\" target=\"_blank\">SWAP</a></td>\n </tr>\n</table>",
|
|
901
|
+
"asMarkdown": "\nThe `SWAP` gate acts on two qubits, and, as the name implies, swaps their quantum states.\n\n<table>\n <tr>\n <th>Gate</th>\n <th>Matrix</th>\n <th>Applying to $|\\psi\\rangle = \\alpha|00\\rangle + \\beta|01\\rangle + \\gamma|10\\rangle + \\delta|11\\rangle$</th>\n <th>Applying to basis states</th>\n <th>Q# Documentation</th>\n </tr>\n <tr>\n <td>$\\text{SWAP}$</td>\n <td>$\\begin{bmatrix} 1 & 0 & 0 & 0 \\\\\\ 0 & 0 & 1 & 0 \\\\\\ 0 & 1 & 0 & 0 \\\\\\ 0 & 0 & 0 & 1 \\end{bmatrix}$</td>\n <td>$\\text{SWAP}|\\psi\\rangle = \\alpha|00\\rangle + \\gamma|01\\rangle + \\beta|10\\rangle + \\delta|11\\rangle$</td>\n <td>\n $$\\text{SWAP}|00\\rangle = |00\\rangle$$\n $$\\text{SWAP}|01\\rangle = |10\\rangle$$\n $$\\text{SWAP}|10\\rangle = |01\\rangle$$\n $$\\text{SWAP}|11\\rangle = |11\\rangle$$\n <td><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.swap\" target=\"_blank\">SWAP</a></td>\n </tr>\n</table>"
|
|
902
|
+
}
|
|
903
|
+
]
|
|
904
|
+
},
|
|
905
|
+
{
|
|
906
|
+
"type": "exercise",
|
|
907
|
+
"id": "multi_qubit_gates__qubit_swap",
|
|
908
|
+
"title": "Qubit SWAP",
|
|
909
|
+
"description": {
|
|
910
|
+
"type": "text-content",
|
|
911
|
+
"asHtml": "<p><strong>Inputs:</strong></p>\n<ol>\n<li>$N$ qubits in an arbitrary state $|\\psi\\rangle$, stored in an array of length $N$.</li>\n<li>Integers <code>index1</code> and <code>index2</code> such that $0 \\le \\text{index1} < \\text{index2} \\le N - 1$.</li>\n</ol>\n<p><strong>Goal:</strong> Swap the states of the qubits at the given indices.</p>\n",
|
|
912
|
+
"asMarkdown": "**Inputs:**\n\n1. $N$ qubits in an arbitrary state $|\\\\psi\\\\rangle$, stored in an array of length $N$.\n2. Integers `index1` and `index2` such that $0 \\le \\text{index1} < \\text{index2} \\le N - 1$.\n\n**Goal:** Swap the states of the qubits at the given indices."
|
|
913
|
+
},
|
|
914
|
+
"sourceIds": [
|
|
915
|
+
"KatasLibrary.qs",
|
|
916
|
+
"multi_qubit_gates__qubit_swap__Verification.qs"
|
|
917
|
+
],
|
|
918
|
+
"placeholderCode": "namespace Kata {\n operation QubitSwap (qs : Qubit[], index1 : Int, index2 : Int)\n : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}",
|
|
919
|
+
"explainedSolution": {
|
|
920
|
+
"type": "explained-solution",
|
|
921
|
+
"items": [
|
|
922
|
+
{
|
|
923
|
+
"type": "text-content",
|
|
924
|
+
"asHtml": "<p>The SWAP gate allows us to swap the state of any two qubits. In this exercise you need to apply it to two qubits given by their indices in an array of qubits; you can access individual qubits of the array as <code>qs[index of a qubit]</code>.</p>\n",
|
|
925
|
+
"asMarkdown": "\nThe SWAP gate allows us to swap the state of any two qubits. In this exercise you need to apply it to two qubits given by their indices in an array of qubits; you can access individual qubits of the array as `qs[index of a qubit]`."
|
|
926
|
+
},
|
|
927
|
+
{
|
|
928
|
+
"type": "solution",
|
|
929
|
+
"id": "multi_qubit_gates__qubit_swap_solution",
|
|
930
|
+
"code": "namespace Kata {\n operation QubitSwap (qs : Qubit[], index1 : Int, index2 : Int) : Unit is Adj + Ctl {\n SWAP(qs[index1], qs[index2]);\n }\n}"
|
|
931
|
+
}
|
|
932
|
+
]
|
|
933
|
+
}
|
|
934
|
+
},
|
|
935
|
+
{
|
|
936
|
+
"type": "lesson",
|
|
937
|
+
"id": "multi_qubit_gates__acting_on_non_adjacent_qubits",
|
|
938
|
+
"title": "Multi-Qubit Gates Acting on Non-Adjacent Qubits",
|
|
939
|
+
"items": [
|
|
940
|
+
{
|
|
941
|
+
"type": "text-content",
|
|
942
|
+
"asHtml": "<p>In the above examples the <code>CNOT</code> gate acted on two adjacent qubits. However, multi-qubit gates can act on non-adjacent qubits as well. Let's see how to work out the math of the system state change in this case.</p>\n<p>Take 3 qubits in an arbitrary state $|\\psi\\rangle = x_{000} |000\\rangle + x_{001}|001\\rangle + x_{010}|010\\rangle + x_{011}|011\\rangle + x_{100}|100\\rangle + x_{101}|101\\rangle + x_{110}|110\\rangle + x_{111}|111\\rangle $.</p>\n<p>We can apply the <code>CNOT</code> gate on 1st and 3rd qubits, with the 1st qubit as control and the 3rd qubit as target. Let's label the 3-qubit gate that describes the effect of this on the whole system as <code>CINOT</code>. The <code>CINOT</code> ignores the 2nd qubit (leaves it unchanged) and applies the <code>CNOT</code> gate as specified above.</p>\n<h2 id=\"q\">Q#</h2>\n<p>In Q# we describe the operation as the sequence of gates that are applied to the qubits, regardless of whether the qubits are adjacent or not.</p>\n<pre><code class=\"language-qsharp\">operation CINOT (qs: Qubit[]) : Unit {\n CNOT(qs[0], qs[2]); // Length of qs is assumed to be 3\n}\n</code></pre>\n<h2 id=\"dirac-notation\">Dirac Notation</h2>\n<p>In Dirac notation we can consider the effect of the gate on each basis vector separately: each basis vector $|a_1a_2a_3\\rangle$ remains unchanged if $a_1 = 0$, and becomes $|a_1a_2(\\neg a_3)\\rangle$ if $a_1 = 1$. The full effect on the state becomes:</p>\n<p>$$\\text{CINOT}|\\psi\\rangle = x_{000} \\text{CINOT}|000\\rangle + x_{001} \\text{CINOT}|001\\rangle + x_{010} \\text{CINOT}|010\\rangle + x_{011} \\text{CINOT}|011\\rangle+$$\n$$x_{100} \\text{CINOT}|100\\rangle + x_{101} \\text{CINOT}|101\\rangle + x_{110} \\text{CINOT}|110\\rangle + x_{111} \\text{CINOT}|111\\rangle =$$\n$$x_{000}|000\\rangle + x_{001}|001\\rangle + x_{010}|010\\rangle + x_{011}|011\\rangle + x_{101}|100\\rangle + x_{100}|101\\rangle + x_{111}|110\\rangle + x_{110}|111\\rangle $$</p>\n<h2 id=\"matrix-form\">Matrix Form</h2>\n<p>$\\text{CINOT}$ can also be represented in matrix form as a $2^3 \\times 2^3$ matrix:\n$$\n\\begin{bmatrix}\n 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0\n\\end{bmatrix}\n$$</p>\n<p>Applying $\\text{CINOT}$ to $|\\psi\\rangle$ gives us\n$$\n\\text{CINOT} \\begin{bmatrix}\n 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0\n\\end{bmatrix}\n\\begin{bmatrix}\n x_{000} \\\\ x_{001} \\\\ x_{010} \\\\ x_{011} \\\\ x_{100} \\\\ x_{101} \\\\ x_{110} \\\\ x_{111}\n\\end{bmatrix} =\n\\begin{bmatrix}\n x_{000} \\\\ x_{001} \\\\ x_{010} \\\\ x_{011} \\\\ x_{101} \\\\ x_{100} \\\\ x_{111} \\\\ x_{110}\n\\end{bmatrix}\n$$</p>\n<p>However, as $N$ gets larger, creating a full size matrix can be extremely unwieldy. To express the matrix without spelling out its elements, we can use the following trick:</p>\n<ol>\n<li>Apply the <code>SWAP</code> gate on the 1st and 2nd qubits.\nThis will bring the qubits on which the <code>CNOT</code> gate acts next to each other, without any extra qubits between them.</li>\n<li>Apply the <code>CNOT</code> on 2nd and 3rd qubits.\nSince now the gate acts on adjacent qubits, this can be represented as a tensor product of the gate we're applying and <code>I</code> gates.</li>\n<li>Apply the <code>SWAP</code> gate on the 1st and 2nd qubits again.</li>\n</ol>\n<p>These can be represented as applying the following gates on the 3 qubits.</p>\n<ol>\n<li><p>$\\text{SWAP} \\otimes I$\n$$\nx_{000}|000\\rangle + x_{001}|001\\rangle + x_{100}|010\\rangle + x_{101}|011\\rangle +\nx_{010}|100\\rangle + x_{011}|101\\rangle + x_{110}|110\\rangle + x_{111}|111\\rangle\n$$</p>\n</li>\n<li><p>$I \\otimes \\text{CNOT}$\n$$\nx_{000}|000\\rangle + x_{001}|001\\rangle + x_{101}|010\\rangle + x_{100}|011\\rangle +\nx_{010}|100\\rangle + x_{011}|101\\rangle + x_{111}|110\\rangle + x_{110}|111\\rangle\n$$</p>\n</li>\n<li><p>$\\text{SWAP} \\otimes I$\n$$\nx_{000}|000\\rangle + x_{001}|001\\rangle + x_{010}|010\\rangle + x_{011}|011\\rangle +\nx_{101}|100\\rangle + x_{100}|101\\rangle + x_{111}|110\\rangle + x_{110}|111\\rangle\n$$</p>\n</li>\n</ol>\n<p>The result is the the $\\text{CINOT}$ gate as we intended; so we can write</p>\n<p>$$\\text{CINOT} = (\\text{SWAP} \\otimes I)(I \\otimes \\text{CNOT})(\\text{SWAP} \\otimes I)$$</p>\n<blockquote>\n<p>Note that in matrix notation we always apply a gate to the complete system, so we must apply $\\text{SWAP} \\otimes I$, spelling the identity gate explicitly.\nHowever, when implementing the unitary $\\text{SWAP} \\otimes I$ in Q#, we need only to call <code>SWAP(qs[0], qs[1])</code> - the remaining qubit <code>qs[2]</code> will not change, which is equivalent to applying an implicit identity gate.</p>\n<p>We can also spell out all gates applied explicitly (this makes for a much longer code, though):</p>\n<pre><code class=\"language-qsharp\">operation CINOT (qs: Qubit[]) : Unit {\n // First step\n SWAP(qs[0], qs[1]);\n I(qs[2]);\n // Second step\n I(qs[0]);\n CNOT(qs[1], qs[2]);\n // Third step\n SWAP(qs[0], qs[1]);\n I(qs[2]);\n}\n</code></pre>\n</blockquote>\n",
|
|
943
|
+
"asMarkdown": "\nIn the above examples the `CNOT` gate acted on two adjacent qubits. However, multi-qubit gates can act on non-adjacent qubits as well. Let's see how to work out the math of the system state change in this case.\n\nTake 3 qubits in an arbitrary state $|\\psi\\rangle = x_{000} |000\\rangle + x_{001}|001\\rangle + x_{010}|010\\rangle + x_{011}|011\\rangle + x_{100}|100\\rangle + x_{101}|101\\rangle + x_{110}|110\\rangle + x_{111}|111\\rangle $.\n\nWe can apply the `CNOT` gate on 1st and 3rd qubits, with the 1st qubit as control and the 3rd qubit as target. Let's label the 3-qubit gate that describes the effect of this on the whole system as `CINOT`. The `CINOT` ignores the 2nd qubit (leaves it unchanged) and applies the `CNOT` gate as specified above.\n\n## Q#\n\nIn Q# we describe the operation as the sequence of gates that are applied to the qubits, regardless of whether the qubits are adjacent or not.\n\n```qsharp\noperation CINOT (qs: Qubit[]) : Unit {\n CNOT(qs[0], qs[2]); // Length of qs is assumed to be 3\n}\n```\n\n## Dirac Notation\n\nIn Dirac notation we can consider the effect of the gate on each basis vector separately: each basis vector $|a_1a_2a_3\\rangle$ remains unchanged if $a_1 = 0$, and becomes $|a_1a_2(\\neg a_3)\\rangle$ if $a_1 = 1$. The full effect on the state becomes:\n\n$$\\text{CINOT}|\\psi\\rangle = x_{000} \\text{CINOT}|000\\rangle + x_{001} \\text{CINOT}|001\\rangle + x_{010} \\text{CINOT}|010\\rangle + x_{011} \\text{CINOT}|011\\rangle+$$\n$$x_{100} \\text{CINOT}|100\\rangle + x_{101} \\text{CINOT}|101\\rangle + x_{110} \\text{CINOT}|110\\rangle + x_{111} \\text{CINOT}|111\\rangle =$$\n$$x_{000}|000\\rangle + x_{001}|001\\rangle + x_{010}|010\\rangle + x_{011}|011\\rangle + x_{101}|100\\rangle + x_{100}|101\\rangle + x_{111}|110\\rangle + x_{110}|111\\rangle $$\n\n## Matrix Form\n\n$\\text{CINOT}$ can also be represented in matrix form as a $2^3 \\times 2^3$ matrix:\n$$\n\\begin{bmatrix}\n 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0\n\\end{bmatrix}\n$$\n\nApplying $\\text{CINOT}$ to $|\\psi\\rangle$ gives us\n$$\n\\text{CINOT} \\begin{bmatrix}\n 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0\n\\end{bmatrix}\n\\begin{bmatrix}\n x_{000} \\\\\\ x_{001} \\\\\\ x_{010} \\\\\\ x_{011} \\\\\\ x_{100} \\\\\\ x_{101} \\\\\\ x_{110} \\\\\\ x_{111}\n\\end{bmatrix} =\n\\begin{bmatrix}\n x_{000} \\\\\\ x_{001} \\\\\\ x_{010} \\\\\\ x_{011} \\\\\\ x_{101} \\\\\\ x_{100} \\\\\\ x_{111} \\\\\\ x_{110}\n\\end{bmatrix}\n$$\n\nHowever, as $N$ gets larger, creating a full size matrix can be extremely unwieldy. To express the matrix without spelling out its elements, we can use the following trick:\n\n1. Apply the `SWAP` gate on the 1st and 2nd qubits.\n This will bring the qubits on which the `CNOT` gate acts next to each other, without any extra qubits between them.\n2. Apply the `CNOT` on 2nd and 3rd qubits.\n Since now the gate acts on adjacent qubits, this can be represented as a tensor product of the gate we're applying and `I` gates.\n3. Apply the `SWAP` gate on the 1st and 2nd qubits again.\n\nThese can be represented as applying the following gates on the 3 qubits.\n\n1. $\\text{SWAP} \\otimes I$\n$$\nx_{000}|000\\rangle + x_{001}|001\\rangle + x_{100}|010\\rangle + x_{101}|011\\rangle +\nx_{010}|100\\rangle + x_{011}|101\\rangle + x_{110}|110\\rangle + x_{111}|111\\rangle\n$$\n\n2. $I \\otimes \\text{CNOT}$\n$$\nx_{000}|000\\rangle + x_{001}|001\\rangle + x_{101}|010\\rangle + x_{100}|011\\rangle +\nx_{010}|100\\\\rangle + x_{011}|101\\rangle + x_{111}|110\\rangle + x_{110}|111\\rangle\n$$\n\n3. $\\text{SWAP} \\otimes I$\n$$\nx_{000}|000\\rangle + x_{001}|001\\rangle + x_{010}|010\\rangle + x_{011}|011\\rangle +\nx_{101}|100\\rangle + x_{100}|101\\rangle + x_{111}|110\\rangle + x_{110}|111\\rangle\n$$\n\nThe result is the the $\\text{CINOT}$ gate as we intended; so we can write\n\n$$\\text{CINOT} = (\\text{SWAP} \\otimes I)(I \\otimes \\text{CNOT})(\\text{SWAP} \\otimes I)$$\n\n> Note that in matrix notation we always apply a gate to the complete system, so we must apply $\\text{SWAP} \\otimes I$, spelling the identity gate explicitly.\n> However, when implementing the unitary $\\text{SWAP} \\otimes I$ in Q#, we need only to call `SWAP(qs[0], qs[1])` - the remaining qubit `qs[2]` will not change, which is equivalent to applying an implicit identity gate.\n>\n> We can also spell out all gates applied explicitly (this makes for a much longer code, though):\n> ```qsharp\noperation CINOT (qs: Qubit[]) : Unit {\n // First step\n SWAP(qs[0], qs[1]);\n I(qs[2]);\n // Second step\n I(qs[0]);\n CNOT(qs[1], qs[2]);\n // Third step\n SWAP(qs[0], qs[1]);\n I(qs[2]);\n}\n```"
|
|
944
|
+
}
|
|
945
|
+
]
|
|
946
|
+
},
|
|
947
|
+
{
|
|
948
|
+
"type": "lesson",
|
|
949
|
+
"id": "multi_qubit_gates__controlled_gates",
|
|
950
|
+
"title": "Controlled Gates",
|
|
951
|
+
"items": [
|
|
952
|
+
{
|
|
953
|
+
"type": "text-content",
|
|
954
|
+
"asHtml": "<p><strong>Controlled gates</strong> are a class of gates derived from other gates as follows: they act on a control qubit and a target qubit, just like the <code>CNOT</code> gate.\nA controlled-<code>U</code> gate applies the <code>U</code> gate to the target qubit if the control qubit is in state $|1\\rangle$, and does nothing otherwise.</p>\n<p>Given a gate $U = \\begin{bmatrix} \\alpha & \\beta \\\\ \\gamma & \\delta \\end{bmatrix}$, its controlled version looks like this:</p>\n<table>\n <tr>\n <th>Gate</th>\n <th>Matrix</th>\n <th>Q# Documentation</th>\n </tr>\n <tr>\n <td>$\\text{Controlled U}$</td>\n <td>\n $$\n \\begin{bmatrix}\n 1 & 0 & 0 & 0 \\\\\\ \n 0 & 1 & 0 & 0 \\\\\\ \n 0 & 0 & \\alpha & \\beta \\\\\\ \n 0 & 0 & \\gamma & \\delta\n \\end{bmatrix}\n $$\n </td>\n <td><a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/expressions/functorapplication#controlled-functor\" target=\"_blank\">Controlled functor</a></td>\n </tr>\n</table>\n\n<blockquote>\n<p>The CNOT gate is en example of a controlled gate, which is why it is also known as the controlled NOT or controlled <code>X</code> gate.</p>\n</blockquote>\n<p>The concept of controlled gates can be generalized beyond controlling single-qubit gates.\nFor any multi-qubit gate, its controlled version will have an identity matrix in the top left quadrant, the gate itself in the bottom right, and $0$ everywhere else.\nHere, for example, is the <code>Controlled SWAP</code>, or <strong>Fredkin gate</strong>:</p>\n<p>$$\n\\begin{bmatrix}\n 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\\\ \n 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\n\\end{bmatrix}\n$$</p>\n<p>In Q#, controlled gates are applied using the <a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/expressions/functorapplication#controlled-functor\" target=\"_blank\"><code>Controlled</code></a> functor.\nThe controlled version of a gate accepts an array of control qubits (in this case an array of a single qubit), followed by the arguments to the original gate.\nFor example, these two lines are equivalent:</p>\n<pre><code class=\"language-qsharp\">Controlled X([control], target);\nCNOT(control, target);\n</code></pre>\n<p>If the original gate was implemented as an operation with multiple parameters, the controlled version of this gate will take those parameters as a tuple. For example, to apply Fredkin gate, you'd have to call:</p>\n<pre><code class=\"language-qsharp\">Controlled SWAP([control], (q1, q2));\n</code></pre>\n<p>You can use the controlled version of a Q# operation only if that operation has a controlled version defined.\nThe Q# compiler will often be able to generate a controlled version of the operation automatically if you put <code>is Ctl</code> after the operation's return type.\nIn other cases, you'll need to define the controlled version of an operation manually.</p>\n",
|
|
955
|
+
"asMarkdown": "\n**Controlled gates** are a class of gates derived from other gates as follows: they act on a control qubit and a target qubit, just like the `CNOT` gate.\nA controlled-`U` gate applies the `U` gate to the target qubit if the control qubit is in state $|1\\rangle$, and does nothing otherwise.\n\nGiven a gate $U = \\begin{bmatrix} \\alpha & \\beta \\\\\\ \\gamma & \\delta \\end{bmatrix}$, its controlled version looks like this:\n\n<table>\n <tr>\n <th>Gate</th>\n <th>Matrix</th>\n <th>Q# Documentation</th>\n </tr>\n <tr>\n <td>$\\text{Controlled U}$</td>\n <td>\n $$\n \\begin{bmatrix}\n 1 & 0 & 0 & 0 \\\\\\ \n 0 & 1 & 0 & 0 \\\\\\ \n 0 & 0 & \\alpha & \\beta \\\\\\ \n 0 & 0 & \\gamma & \\delta\n \\end{bmatrix}\n $$\n </td>\n <td><a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/expressions/functorapplication#controlled-functor\" target=\"_blank\">Controlled functor</a></td>\n </tr>\n</table>\n\n> The CNOT gate is en example of a controlled gate, which is why it is also known as the controlled NOT or controlled `X` gate.\n\nThe concept of controlled gates can be generalized beyond controlling single-qubit gates.\nFor any multi-qubit gate, its controlled version will have an identity matrix in the top left quadrant, the gate itself in the bottom right, and $0$ everywhere else.\nHere, for example, is the `Controlled SWAP`, or **Fredkin gate**:\n\n$$\n\\begin{bmatrix}\n 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\n\\end{bmatrix}\n$$\n\nIn Q#, controlled gates are applied using the <a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/expressions/functorapplication#controlled-functor\" target=\"_blank\">`Controlled`</a> functor.\nThe controlled version of a gate accepts an array of control qubits (in this case an array of a single qubit), followed by the arguments to the original gate.\nFor example, these two lines are equivalent:\n\n```qsharp\nControlled X([control], target);\nCNOT(control, target);\n```\n\nIf the original gate was implemented as an operation with multiple parameters, the controlled version of this gate will take those parameters as a tuple. For example, to apply Fredkin gate, you'd have to call:\n\n```qsharp\nControlled SWAP([control], (q1, q2));\n```\n\nYou can use the controlled version of a Q# operation only if that operation has a controlled version defined.\nThe Q# compiler will often be able to generate a controlled version of the operation automatically if you put `is Ctl` after the operation's return type.\nIn other cases, you'll need to define the controlled version of an operation manually."
|
|
956
|
+
}
|
|
957
|
+
]
|
|
958
|
+
},
|
|
959
|
+
{
|
|
960
|
+
"type": "exercise",
|
|
961
|
+
"id": "multi_qubit_gates__controlled_rotation",
|
|
962
|
+
"title": "Controlled Rotation",
|
|
963
|
+
"description": {
|
|
964
|
+
"type": "text-content",
|
|
965
|
+
"asHtml": "<p><strong>Inputs:</strong></p>\n<ol>\n<li>Two qubits in an arbitrary state $|\\phi\\rangle$, stored as an array of length 2.</li>\n<li>An angle $\\theta$: $-\\pi < \\theta \\leq \\pi$.</li>\n</ol>\n<p><strong>Goal:</strong> Apply a controlled $R_x$ gate, using the first qubit as control and the second qubit as target, with $\\theta$ as the angle argument for the gate.</p>\n<details>\n <summary><b>Need a hint?</b></summary>\n <p>If you were to apply a regular version of $R_x$ gate, it would take two parameters - angle $theta$ as the first parameter and the target qubit as the second parameter.</p>\n</details>",
|
|
966
|
+
"asMarkdown": "**Inputs:**\n\n1. Two qubits in an arbitrary state $|\\phi\\rangle$, stored as an array of length 2.\n2. An angle $\\theta$: $-\\pi < \\theta \\leq \\pi$.\n\n**Goal:** Apply a controlled $R_x$ gate, using the first qubit as control and the second qubit as target, with $\\theta$ as the angle argument for the gate.\n\n<details>\n <summary><b>Need a hint?</b></summary>\n <p>If you were to apply a regular version of $R_x$ gate, it would take two parameters - angle $theta$ as the first parameter and the target qubit as the second parameter.</p>\n</details>"
|
|
967
|
+
},
|
|
968
|
+
"sourceIds": [
|
|
969
|
+
"KatasLibrary.qs",
|
|
970
|
+
"multi_qubit_gates__controlled_rotation__Verification.qs"
|
|
971
|
+
],
|
|
972
|
+
"placeholderCode": "namespace Kata {\n operation ControlledRotation(qs : Qubit[], theta : Double)\n : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}",
|
|
973
|
+
"explainedSolution": {
|
|
974
|
+
"type": "explained-solution",
|
|
975
|
+
"items": [
|
|
976
|
+
{
|
|
977
|
+
"type": "text-content",
|
|
978
|
+
"asHtml": "<p>In Q# the <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.rx\" target=\"_blank\">Rx</a> gate takes the angle $\\theta$ and the target qubit as inputs. To create a controlled version of this gate, we can use the <code>Controlled</code> functor.</p>\n<p>A matrix representation of this operation would be:</p>\n<p>$$\n\\begin{bmatrix} 1 & 0 & 0 & 0 \\\\ 0 & 1 & 0 & 0 \\\\ 0 & 0 & \\cos\\frac{\\theta}{2} & -i\\sin\\frac{\\theta}{2} \\\\ 0 & 0 & -i\\sin\\frac{\\theta}{2} & \\cos\\frac{\\theta}{2} \\end{bmatrix}\n$$</p>\n<p>The parameters of the new gate are changed a bit:</p>\n<ul>\n<li>the first parameter has to be the array of control qubits; the <strong>Rx</strong> gate will be applied to the target only if these are all in the $|1\\rangle$ state. Note that this parameter has to be an array, even if there is just one control qubit!</li>\n<li>The second parameter is a tuple with the parameters that you would've passed to the original <strong>Rx</strong> gate. You can create a tuple of values by putting round brackets around them.</li>\n</ul>\n<blockquote>\n<p>The <code>Controlled</code> functor can be used before any single qubit gate to make it a controlled gate. The first argument will be an <code>array</code> of qubits even if you are using a single control qubit, like in the <strong>CNOT</strong> gate. The second argument is a tuple <code>()</code> with the parameters of the gate. For example, these two gates are equivalent: <code>CNOT(qs[0],qs[1])</code> and <code>Controlled X([qs[0]],(qs[1]));</code></p>\n</blockquote>\n",
|
|
979
|
+
"asMarkdown": "\nIn Q# the <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.rx\" target=\"_blank\">Rx</a> gate takes the angle $\\theta$ and the target qubit as inputs. To create a controlled version of this gate, we can use the `Controlled` functor.\n\nA matrix representation of this operation would be:\n\n$$\n\\begin{bmatrix} 1 & 0 & 0 & 0 \\\\\\ 0 & 1 & 0 & 0 \\\\\\ 0 & 0 & \\cos\\frac{\\theta}{2} & -i\\sin\\frac{\\theta}{2} \\\\\\ 0 & 0 & -i\\sin\\frac{\\theta}{2} & \\cos\\frac{\\theta}{2} \\end{bmatrix}\n$$\n\nThe parameters of the new gate are changed a bit:\n\n* the first parameter has to be the array of control qubits; the **Rx** gate will be applied to the target only if these are all in the $|1\\rangle$ state. Note that this parameter has to be an array, even if there is just one control qubit!\n* The second parameter is a tuple with the parameters that you would've passed to the original **Rx** gate. You can create a tuple of values by putting round brackets around them.\n\n> The `Controlled` functor can be used before any single qubit gate to make it a controlled gate. The first argument will be an `array` of qubits even if you are using a single control qubit, like in the **CNOT** gate. The second argument is a tuple `()` with the parameters of the gate. For example, these two gates are equivalent: `CNOT(qs[0],qs[1])` and `Controlled X([qs[0]],(qs[1]));`"
|
|
980
|
+
},
|
|
981
|
+
{
|
|
982
|
+
"type": "solution",
|
|
983
|
+
"id": "multi_qubit_gates__controlled_rotation_solution",
|
|
984
|
+
"code": "namespace Kata {\n operation ControlledRotation (qs : Qubit[], theta : Double) : Unit is Adj + Ctl {\n let controll = qs[0];\n let target = qs[1];\n Controlled Rx([controll], (theta, target));\n }\n}"
|
|
985
|
+
}
|
|
986
|
+
]
|
|
987
|
+
}
|
|
988
|
+
},
|
|
989
|
+
{
|
|
990
|
+
"type": "lesson",
|
|
991
|
+
"id": "multi_qubit_gates__multi_controlled_gates",
|
|
992
|
+
"title": "Multi-Controlled Gates",
|
|
993
|
+
"items": [
|
|
994
|
+
{
|
|
995
|
+
"type": "text-content",
|
|
996
|
+
"asHtml": "<p>Controlled gates can have multiple control qubits; in this case the gate $U$ is applied only if all control qubits are in the $|1\\rangle$ states.\nYou can think of it as constructing a controlled version of a gate that is already controlled.</p>\n<p>The simplest example of this is the <strong>Toffoli gate</strong>, or <code>CCNOT</code> (controlled controlled <code>NOT</code>) gate, which applies the <code>X</code> gate to the last qubit only if the first two qubits are in $|11\\rangle$ state:</p>\n<p>$$\n\\begin{bmatrix}\n 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0\n\\end{bmatrix}\n$$</p>\n<p>To construct a multi-controlled version of an operation in Q#, you can use the Controlled functor as well, passing all control qubits as an array that is the first parameter.</p>\n",
|
|
997
|
+
"asMarkdown": "\nControlled gates can have multiple control qubits; in this case the gate $U$ is applied only if all control qubits are in the $|1\\rangle$ states.\nYou can think of it as constructing a controlled version of a gate that is already controlled.\n\nThe simplest example of this is the **Toffoli gate**, or `CCNOT` (controlled controlled `NOT`) gate, which applies the `X` gate to the last qubit only if the first two qubits are in $|11\\rangle$ state:\n\n$$\n\\begin{bmatrix}\n 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\\\\\ \n 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0\n\\end{bmatrix}\n$$\n\nTo construct a multi-controlled version of an operation in Q#, you can use the Controlled functor as well, passing all control qubits as an array that is the first parameter."
|
|
998
|
+
}
|
|
999
|
+
]
|
|
1000
|
+
},
|
|
1001
|
+
{
|
|
1002
|
+
"type": "lesson",
|
|
1003
|
+
"id": "multi_qubit_gates__other_controlled_gates",
|
|
1004
|
+
"title": "Other Types of Controlled Gates",
|
|
1005
|
+
"items": [
|
|
1006
|
+
{
|
|
1007
|
+
"type": "text-content",
|
|
1008
|
+
"asHtml": "<p>Typically, the term "controlled <code>U</code> gate" refers to the type of gate we've described previously, which applies the gate <code>U</code> only if the control qubit(s) are in the $|1\\rangle$ state.</p>\n<p>It is possible, however, to define variants of controlled gates that use different states as control states.\nFor example, an <strong>anti-controlled</strong> <code>U</code> gate (sometimes called <strong>zero-controlled</strong>) applies a gate only if the control qubit is in the $|0\\rangle$ state.\nIt is also possible to define control conditions in other bases, for example, applying the gate if the control qubit is in the $|+\\rangle$ state.</p>\n<p>All the variants of controlled gates can be expressed in terms of the controls described in previous sections, using the following sequence of steps:</p>\n<ul>\n<li>First, apply a transformation on control qubits that will transform the state you want to use as control into the $|1...1\\rangle$ state.</li>\n<li>Apply the regular controlled version of the gate.</li>\n<li>Finally, undo the transformation on control qubits from the first step using the adjoint version of it.</li>\n</ul>\n<blockquote>\n<p>Why do we need this last step? Remember that controlled gates are defined in terms of their effect on the basis states:\nwe apply the gate on the target qubit if and only if the control qubit is in the state we want to control on, and we don't change the state of the control qubit at all.\nIf we don't undo the transformation we did on the first step, applying our gate to a basis state will modify not only the state of the target qubit but also the state of the control qubit, which is not what we're looking for.</p>\n<p>For example, consider an anti-controlled <code>X</code> gate - a gate that should apply an $X$ gate to the second qubit if the first qubit is in the $|0\\rangle$ state.\nHere is the effect we expect this gate to have on each of the 2-qubit basis states:</p>\n<table>\n <tr>\n <th>Input state</th>\n <th>Output state</th>\n </tr>\n <tr>\n <td>$|00\\rangle$</td>\n <td>$|01\\rangle$</td>\n </tr>\n <tr>\n <td>$|01\\rangle$</td>\n <td>$|00\\rangle$</td>\n </tr>\n <tr>\n <td>$|10\\rangle$</td>\n <td>$|10\\rangle$</td>\n </tr>\n <tr>\n <td>$|11\\rangle$</td>\n <td>$|11\\rangle$</td>\n </tr>\n</blockquote>\n</table>\n\n<blockquote>\n<p>Let's apply the anti-controlled <code>X</code> gate to the $|00\\rangle$ state step by step:</p>\n<ol>\n<li>Transform the state of the control qubit to $|1\\rangle$: we can do that by applying the $X$ gate to the first qubit:\n$$|00\\rangle \\rightarrow |10\\rangle$$</li>\n<li>Apply the regular <code>CNOT</code> gate:\n$$|10\\rangle \\rightarrow |11\\rangle$$</li>\n<li>Now, if we don't undo the change we did on the first step, we'll end up with a gate that transforms $|00\\rangle$ into $|11\\rangle$, which is not the transformation we're trying to implement.\nHowever, if we undo it by applying the <code>X</code> gate to the first qubit again, we'll get the correct state:\n$$|11\\rangle \\rightarrow |01\\rangle$$</li>\n</ol>\n<p>You can check that getting the right behavior of the operation on the rest of the basis states also requires that last step.</p>\n</blockquote>\n<p>Finally, let's take a look at a very useful operation <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.canon.controlledonbitstring\" target=\"_blank\">ControlledOnBitString</a> provided by the Q# Standard library.\nIt defines a variant of a gate controlled on a state specified by a bit mask; for example, bit mask <code>[true, false]</code> means that the gate should be applied only if the two control qubits are in the $|10\\rangle$ state.</p>\n<p>The sequence of steps that implement this variant are:</p>\n<ol>\n<li>Apply the <code>X</code> gate to each control qubit that corresponds to a <code>false</code> element of the bit mask (in the example, that's just the second qubit). After this, if the control qubits started in the $|10\\rangle$ state, they'll end up in the $|11\\rangle$ state, and if they started in any other state, they'll end up in any state but $|11\\rangle$.</li>\n<li>Apply the regular controlled version of the gate.</li>\n<li>Apply the $X$ gate to the same qubits to return them to their original state.</li>\n</ol>\n",
|
|
1009
|
+
"asMarkdown": "\nTypically, the term \"controlled `U` gate\" refers to the type of gate we've described previously, which applies the gate `U` only if the control qubit(s) are in the $|1\\rangle$ state.\n\nIt is possible, however, to define variants of controlled gates that use different states as control states.\nFor example, an **anti-controlled** `U` gate (sometimes called **zero-controlled**) applies a gate only if the control qubit is in the $|0\\rangle$ state.\nIt is also possible to define control conditions in other bases, for example, applying the gate if the control qubit is in the $|+\\rangle$ state.\n\nAll the variants of controlled gates can be expressed in terms of the controls described in previous sections, using the following sequence of steps:\n* First, apply a transformation on control qubits that will transform the state you want to use as control into the $|1...1\\rangle$ state.\n* Apply the regular controlled version of the gate.\n* Finally, undo the transformation on control qubits from the first step using the adjoint version of it.\n\n> Why do we need this last step? Remember that controlled gates are defined in terms of their effect on the basis states:\n> we apply the gate on the target qubit if and only if the control qubit is in the state we want to control on, and we don't change the state of the control qubit at all.\n> If we don't undo the transformation we did on the first step, applying our gate to a basis state will modify not only the state of the target qubit but also the state of the control qubit, which is not what we're looking for.\n>\n> For example, consider an anti-controlled `X` gate - a gate that should apply an $X$ gate to the second qubit if the first qubit is in the $|0\\rangle$ state.\n> Here is the effect we expect this gate to have on each of the 2-qubit basis states:\n>\n> <table>\n <tr>\n <th>Input state</th>\n <th>Output state</th>\n </tr>\n <tr>\n <td>$|00\\rangle$</td>\n <td>$|01\\rangle$</td>\n </tr>\n <tr>\n <td>$|01\\rangle$</td>\n <td>$|00\\rangle$</td>\n </tr>\n <tr>\n <td>$|10\\rangle$</td>\n <td>$|10\\rangle$</td>\n </tr>\n <tr>\n <td>$|11\\rangle$</td>\n <td>$|11\\rangle$</td>\n </tr>\n</table>\n\n> Let's apply the anti-controlled `X` gate to the $|00\\rangle$ state step by step:\n> 1. Transform the state of the control qubit to $|1\\rangle$: we can do that by applying the $X$ gate to the first qubit:\n> $$|00\\rangle \\rightarrow |10\\rangle$$\n> 2. Apply the regular `CNOT` gate:\n> $$|10\\rangle \\rightarrow |11\\rangle$$\n> 3. Now, if we don't undo the change we did on the first step, we'll end up with a gate that transforms $|00\\rangle$ into $|11\\rangle$, which is not the transformation we're trying to implement.\n> However, if we undo it by applying the `X` gate to the first qubit again, we'll get the correct state:\n> $$|11\\rangle \\rightarrow |01\\rangle$$\n>\n> You can check that getting the right behavior of the operation on the rest of the basis states also requires that last step.\n\nFinally, let's take a look at a very useful operation <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.canon.controlledonbitstring\" target=\"_blank\">ControlledOnBitString</a> provided by the Q# Standard library.\nIt defines a variant of a gate controlled on a state specified by a bit mask; for example, bit mask `[true, false]` means that the gate should be applied only if the two control qubits are in the $|10\\rangle$ state.\n\nThe sequence of steps that implement this variant are:\n1. Apply the `X` gate to each control qubit that corresponds to a `false` element of the bit mask (in the example, that's just the second qubit). After this, if the control qubits started in the $|10\\rangle$ state, they'll end up in the $|11\\rangle$ state, and if they started in any other state, they'll end up in any state but $|11\\rangle$.\n2. Apply the regular controlled version of the gate.\n3. Apply the $X$ gate to the same qubits to return them to their original state."
|
|
1010
|
+
}
|
|
1011
|
+
]
|
|
1012
|
+
},
|
|
1013
|
+
{
|
|
1014
|
+
"type": "exercise",
|
|
1015
|
+
"id": "multi_qubit_gates__arbitrary_controls",
|
|
1016
|
+
"title": "Arbitrary Controls",
|
|
1017
|
+
"description": {
|
|
1018
|
+
"type": "text-content",
|
|
1019
|
+
"asHtml": "<p><strong>Input:</strong></p>\n<ol>\n<li><code>controls</code> - a register of $N$ qubits in an arbitrary state $|\\phi\\rangle$.</li>\n<li><code>target</code> - a qubit in an arbitrary state $|\\psi\\rangle$.</li>\n<li><code>controlBits</code> - an array of $N$ booleans, specifying what state each control qubit should be in order to apply the gate.</li>\n</ol>\n<p><strong>Goal:</strong> Apply the controlled <code>X</code> gate with the <code>controls</code> as control qubits and <code>target</code> as target, with the state specified by <code>controlBits</code> as controls. If the element of the array is <code>true</code>, the corresponding qubit is a regular control (should be in state $|1\\rangle$), and if it is <code>false</code>, the corresponding qubit is an anti-control (should be in state $|0\\rangle$).</p>\n<blockquote>\n<p>For example, if <code>controlBits = [true, false, true]</code>, the controlled <code>X</code> gate should only be applied if the control qubits are in state $|101\\rangle$.</p>\n</blockquote>\n<details>\n <summary><strong>Need a hint?</strong></summary>\n <p>Consider using a library operation for this task. If you want to do it without a library operations, don't forget to reset the qubits back to the state they were originally in.</p>\n</details>\n",
|
|
1020
|
+
"asMarkdown": "**Input:**\n\n1. `controls` - a register of $N$ qubits in an arbitrary state $|\\phi\\rangle$.\n2. `target` - a qubit in an arbitrary state $|\\psi\\rangle$.\n3. `controlBits` - an array of $N$ booleans, specifying what state each control qubit should be in order to apply the gate.\n\n**Goal:** Apply the controlled `X` gate with the `controls` as control qubits and `target` as target, with the state specified by `controlBits` as controls. If the element of the array is `true`, the corresponding qubit is a regular control (should be in state $|1\\rangle$), and if it is `false`, the corresponding qubit is an anti-control (should be in state $|0\\rangle$).\n\n> For example, if `controlBits = [true, false, true]`, the controlled `X` gate should only be applied if the control qubits are in state $|101\\rangle$.\n\n<details>\n <summary><strong>Need a hint?</strong></summary>\n <p>Consider using a library operation for this task. If you want to do it without a library operations, don't forget to reset the qubits back to the state they were originally in.</p>\n</details>\n"
|
|
1021
|
+
},
|
|
1022
|
+
"sourceIds": [
|
|
1023
|
+
"KatasLibrary.qs",
|
|
1024
|
+
"multi_qubit_gates__arbitrary_controls__Verification.qs"
|
|
1025
|
+
],
|
|
1026
|
+
"placeholderCode": "namespace Kata {\n operation MultiControls(\n controls : Qubit[], target : Qubit, controlBits : Bool[])\n : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}",
|
|
1027
|
+
"explainedSolution": {
|
|
1028
|
+
"type": "explained-solution",
|
|
1029
|
+
"items": [
|
|
1030
|
+
{
|
|
1031
|
+
"type": "text-content",
|
|
1032
|
+
"asHtml": "<p>We are asked to perform a <code>X</code> gate on the <code>target</code> qubit controlled by the state of <code>controls</code> qubits; this state should correspond to the mask given by <code>controlBits</code>.</p>\n<p>If the <code>controlBits</code> mask consists of all <code>true</code> values, we can use a familiar <code>Controlled X</code> gate. What can we do if the mask has some <code>false</code> values in it?</p>\n<p>Turns out we can transform the state of the control qubits depending on the corresponding elements of <code>controlBits</code>: if the element is <code>false</code>, we apply an <code>X</code> gate to the corresponding qubit in the <code>controls</code> array. After this, <code>Controlled X</code> gate will apply an <code>X</code> gate in the exact case that we want.\nFinally, we'll need to remember to undo ("uncompute") the first step, otherwise our controlled gate will affect the state of the control qubits as well as the state of the target.</p>\n<p>As you can see in the first cell below, this can take quite some coding.</p>\n",
|
|
1033
|
+
"asMarkdown": "\nWe are asked to perform a `X` gate on the `target` qubit controlled by the state of `controls` qubits; this state should correspond to the mask given by `controlBits`.\n\nIf the `controlBits` mask consists of all `true` values, we can use a familiar `Controlled X` gate. What can we do if the mask has some `false` values in it?\n\nTurns out we can transform the state of the control qubits depending on the corresponding elements of `controlBits`: if the element is `false`, we apply an `X` gate to the corresponding qubit in the `controls` array. After this, `Controlled X` gate will apply an `X` gate in the exact case that we want.\nFinally, we'll need to remember to undo (\\\"uncompute\\\") the first step, otherwise our controlled gate will affect the state of the control qubits as well as the state of the target.\n\nAs you can see in the first cell below, this can take quite some coding."
|
|
1034
|
+
},
|
|
1035
|
+
{
|
|
1036
|
+
"type": "solution",
|
|
1037
|
+
"id": "multi_qubit_gates__arbitrary_controlled_solution_a",
|
|
1038
|
+
"code": "namespace Kata {\n operation MultiControls (controls : Qubit[], target : Qubit, controlBits : Bool[]) : Unit is Adj + Ctl {\n for index in 0 .. Length(controls) - 1 {\n if controlBits[index] == false {\n X(controls[index]); \n }\n }\n \n Controlled X(controls,target);\n \n for index in 0 .. Length(controls) - 1 {\n if controlBits[index] == false {\n X(controls[index]); \n }\n }\n }\n}"
|
|
1039
|
+
},
|
|
1040
|
+
{
|
|
1041
|
+
"type": "text-content",
|
|
1042
|
+
"asHtml": "<p>We can shorten the code a bit using the <code>within ... apply</code> construct which takes care of uncomputing the steps done in the first code block automatically:</p>\n",
|
|
1043
|
+
"asMarkdown": "\nWe can shorten the code a bit using the `within ... apply` construct which takes care of uncomputing the steps done in the first code block automatically:"
|
|
1044
|
+
},
|
|
1045
|
+
{
|
|
1046
|
+
"type": "solution",
|
|
1047
|
+
"id": "multi_qubit_gates__arbitrary_controlled_solution_b",
|
|
1048
|
+
"code": "namespace Kata {\n operation MultiControls (controls : Qubit[], target : Qubit, controlBits : Bool[]) : Unit is Adj + Ctl {\n within {\n for index in 0 .. Length(controls) - 1 {\n if controlBits[index] == false {\n X(controls[index]); \n }\n }\n } apply {\n Controlled X(controls,target);\n }\n }\n}"
|
|
1049
|
+
},
|
|
1050
|
+
{
|
|
1051
|
+
"type": "text-content",
|
|
1052
|
+
"asHtml": "<p>Finally, here is how the exact same task could be realized using the library function <a href=\"https://learn.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.canon.applycontrolledonbitstring\" target=\"_blank\">ApplyControlledOnBitString</a>.</p>\n",
|
|
1053
|
+
"asMarkdown": "\nFinally, here is how the exact same task could be realized using the library function <a href=\"https://learn.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.canon.applycontrolledonbitstring\" target=\"_blank\">ApplyControlledOnBitString</a>."
|
|
1054
|
+
},
|
|
1055
|
+
{
|
|
1056
|
+
"type": "solution",
|
|
1057
|
+
"id": "multi_qubit_gates__arbitrary_controlled_solution_c",
|
|
1058
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Canon;\n\n operation MultiControls (controls : Qubit[], target : Qubit, controlBits : Bool[]) : Unit is Adj + Ctl {\n ApplyControlledOnBitString(controlBits, X, controls, target);\n }\n}"
|
|
1059
|
+
}
|
|
1060
|
+
]
|
|
1061
|
+
}
|
|
1062
|
+
},
|
|
1063
|
+
{
|
|
1064
|
+
"type": "lesson",
|
|
1065
|
+
"id": "multi_qubit_gates__conclusion",
|
|
1066
|
+
"title": "Conclusion",
|
|
1067
|
+
"items": [
|
|
1068
|
+
{
|
|
1069
|
+
"type": "text-content",
|
|
1070
|
+
"asHtml": "<p>Congratulations! You have completed the series of introductory katas. In this kata you learned how to apply quantum gates to multi-qubit systems. Here are a few key concepts to keep in mind: </p>\n<ul>\n<li>Multi-qubit gates are constructed as the tensor products of gates that affect individual qubits of the system.</li>\n<li>CNOT gate is a type of controlled gate that acts on two qubits. If the control qubit is in state $\\ket{1}$, it applies the $X$ gate to the target qubit, otherwise it does nothing.</li>\n<li>In Q#, controlled gates are applied using the <code>Controlled</code> functor.</li>\n<li>In Q# you can apply a sequence of multi-qubit gates, regardless of whether the qubits are adjacent or not.</li>\n</ul>\n<p>Next, you will learn about quantum measurements in the "Measurements in Single-Qubit Systems" kata.</p>\n",
|
|
1071
|
+
"asMarkdown": "\nCongratulations! You have completed the series of introductory katas. In this kata you learned how to apply quantum gates to multi-qubit systems. Here are a few key concepts to keep in mind: \n* Multi-qubit gates are constructed as the tensor products of gates that affect individual qubits of the system.\n* CNOT gate is a type of controlled gate that acts on two qubits. If the control qubit is in state $\\ket{1}$, it applies the $X$ gate to the target qubit, otherwise it does nothing.\n* In Q#, controlled gates are applied using the `Controlled` functor.\n* In Q# you can apply a sequence of multi-qubit gates, regardless of whether the qubits are adjacent or not.\n\nNext, you will learn about quantum measurements in the \"Measurements in Single-Qubit Systems\" kata."
|
|
1072
|
+
}
|
|
1073
|
+
]
|
|
1074
|
+
}
|
|
1075
|
+
]
|
|
1076
|
+
},
|
|
1077
|
+
{
|
|
1078
|
+
"id": "single_qubit_measurements",
|
|
1079
|
+
"title": "Measurements in Single-Qubit Systems",
|
|
1080
|
+
"sections": [
|
|
1081
|
+
{
|
|
1082
|
+
"type": "lesson",
|
|
1083
|
+
"id": "single_qubit_measurements__overview",
|
|
1084
|
+
"title": "Overview",
|
|
1085
|
+
"items": [
|
|
1086
|
+
{
|
|
1087
|
+
"type": "text-content",
|
|
1088
|
+
"asHtml": "<p>This kata introduces you to measurements done on single-qubit systems.</p>\n<p>The concept of a measurement is a central part of quantum mechanics, as well as quantum algorithms. Single-qubit measurements, as their name implies, are measurements on single qubits. The outcomes of a measurement in quantum mechanics are probabilistic, and in general, change the state of the qubit according to the outcome of the measurement.</p>\n<p>We recommend you complete the "Single-Qubit Gates" kata before starting this one.</p>\n<p><strong>This kata covers the following topics:</strong></p>\n<ul>\n<li>Computational basis measurements</li>\n<li>Pauli basis measurements</li>\n<li>Measurements in arbitrary orthogonal bases</li>\n<li>Representing measurements as projector operators</li>\n</ul>\n<p><strong>What you should know to start working on this kata:</strong></p>\n<ul>\n<li>Basic linear algebra</li>\n<li>The concept of a qubit</li>\n<li>Single-qubit gates</li>\n</ul>\n<p>$\\renewcommand{\\ket}[1]{\\left\\lvert#1\\right\\rangle}$\n$\\renewcommand{\\bra}[1]{\\left\\langle#1\\right\\rvert}$</p>\n",
|
|
1089
|
+
"asMarkdown": "\nThis kata introduces you to measurements done on single-qubit systems.\n\nThe concept of a measurement is a central part of quantum mechanics, as well as quantum algorithms. Single-qubit measurements, as their name implies, are measurements on single qubits. The outcomes of a measurement in quantum mechanics are probabilistic, and in general, change the state of the qubit according to the outcome of the measurement.\n\nWe recommend you complete the \"Single-Qubit Gates\" kata before starting this one.\n\n**This kata covers the following topics:**\n\n- Computational basis measurements\n- Pauli basis measurements\n- Measurements in arbitrary orthogonal bases\n- Representing measurements as projector operators\n\n**What you should know to start working on this kata:**\n\n- Basic linear algebra\n- The concept of a qubit\n- Single-qubit gates\n\n$\\renewcommand{\\ket}[1]{\\left\\lvert#1\\right\\rangle}$\n$\\renewcommand{\\bra}[1]{\\left\\langle#1\\right\\rvert}$"
|
|
1090
|
+
}
|
|
1091
|
+
]
|
|
1092
|
+
},
|
|
1093
|
+
{
|
|
1094
|
+
"type": "lesson",
|
|
1095
|
+
"id": "single_qubit_measurements__computational_basis_measurements",
|
|
1096
|
+
"title": "Computational Basis Measurements",
|
|
1097
|
+
"items": [
|
|
1098
|
+
{
|
|
1099
|
+
"type": "text-content",
|
|
1100
|
+
"asHtml": "<p>In this section, we will discuss the simplest type of qubit measurements - measurements in the computational basis. This is the "default" type of measurements. Unless otherwise specified, "measurement" refers to this type.</p>\n<p>The state $\\ket{\\psi}$ of a single qubit can always be expressed in Dirac notation as:\n$$\\ket{\\psi} = \\alpha \\ket{0} + \\beta \\ket{1}$$\nwhere $\\alpha$ and $\\beta$ are complex numbers, and the state is normalized, $|\\alpha|^2 + |\\beta|^2 = 1$.</p>\n<p>To get some information about the qubit state, we can measure the qubit. Similar to the classical case of measuring a bit, the outcome of a measurement can be $0$ or $1$. However, unlike the classical case, quantum measurement is a probabilistic process.</p>\n<p>The probabilities of the measurement outcomes being $0$ and $1$ are $|\\alpha|^2$ and $|\\beta|^2$, respectively. Additionally, the state of the qubit is modified by the measurement - if the outcome of the measurement is $0$, then the post-measurement state of the qubit is $\\ket{0}$, and if the outcome is $1$, the state is $\\ket{1}$. In quantum mechanics, this is referred to as the <a href=\"https://en.wikipedia.org/wiki/Wave_function_collapse\" target=\"_blank\">collapse of the wave function</a>.</p>\n<p>The outcomes of computational basis measurements and their probabilities are summarized in the table below:</p>\n<table>\n <tr>\n <th>Measurement outcome</th>\n <th>Probability of outcome</th>\n <th>State after measurement</th>\n </tr>\n <tr>\n <td>$0$</td>\n <td>$|\\alpha|^2$</td>\n <td>$\\ket 0$</td>\n </tr>\n <tr>\n <td>$1$</td>\n <td>$|\\beta|^2$</td>\n <td>$\\ket 1$</td>\n </tr>\n</table>\n\n<blockquote>\n<p>Unlike quantum gates which are unitary and reversible operations, measurements are neither unitary nor reversible. Since the outcomes of a measurement are probabilistic, any two isolated qubits which are initially prepared in identical superposition states are in general not guaranteed to have the same measurement outcomes after each qubit has been measured separately. As we will see below, measurements are modeled by projection operators instead of unitary operators.</p>\n<p>Additionally, the assumption of the wave function being <strong>normalized</strong> is important, since the probability outcomes must sum up to $1$. If the wave function is not normalized, it is important to normalize it first in order to obtain the correct measurement probabilities.</p>\n</blockquote>\n<h2 id=\"🔎-analyze\">🔎 Analyze</h2>\n<p>The qubit is in the following state:\n$$\\ket \\psi = 0.6 \\ket 0 + 0.8 \\ket 1 \\equiv \\begin{bmatrix} 0.6 \\\\ 0.8\\end{bmatrix}.$$</p>\n<p>If this qubit is measured in the computational basis, what are the outcome probabilities?</p>\n<details>\n<summary><b>Solution</b></summary>\nThe given state $\\ket \\psi$ is normalized, since $0.6^2 + 0.8^2 = 1$. Hence, the probability of measuring $0$ is $|0.6|^2 = 0.36$, and the probability of measuring $1$ is $|0.8|^2 = 0.64$.\n</details>",
|
|
1101
|
+
"asMarkdown": "\nIn this section, we will discuss the simplest type of qubit measurements - measurements in the computational basis. This is the \"default\" type of measurements. Unless otherwise specified, \"measurement\" refers to this type.\n\nThe state $\\ket{\\psi}$ of a single qubit can always be expressed in Dirac notation as:\n$$\\ket{\\psi} = \\alpha \\ket{0} + \\beta \\ket{1}$$\nwhere $\\alpha$ and $\\beta$ are complex numbers, and the state is normalized, $|\\alpha|^2 + |\\beta|^2 = 1$.\n\nTo get some information about the qubit state, we can measure the qubit. Similar to the classical case of measuring a bit, the outcome of a measurement can be $0$ or $1$. However, unlike the classical case, quantum measurement is a probabilistic process.\n\nThe probabilities of the measurement outcomes being $0$ and $1$ are $|\\alpha|^2$ and $|\\beta|^2$, respectively. Additionally, the state of the qubit is modified by the measurement - if the outcome of the measurement is $0$, then the post-measurement state of the qubit is $\\ket{0}$, and if the outcome is $1$, the state is $\\ket{1}$. In quantum mechanics, this is referred to as the <a href=\"https://en.wikipedia.org/wiki/Wave_function_collapse\" target=\"_blank\">collapse of the wave function</a>.\n\nThe outcomes of computational basis measurements and their probabilities are summarized in the table below:\n<table>\n <tr>\n <th>Measurement outcome</th>\n <th>Probability of outcome</th>\n <th>State after measurement</th>\n </tr>\n <tr>\n <td>$0$</td>\n <td>$|\\alpha|^2$</td>\n <td>$\\ket 0$</td>\n </tr>\n <tr>\n <td>$1$</td>\n <td>$|\\beta|^2$</td>\n <td>$\\ket 1$</td>\n </tr>\n</table>\n\n>Unlike quantum gates which are unitary and reversible operations, measurements are neither unitary nor reversible. Since the outcomes of a measurement are probabilistic, any two isolated qubits which are initially prepared in identical superposition states are in general not guaranteed to have the same measurement outcomes after each qubit has been measured separately. As we will see below, measurements are modeled by projection operators instead of unitary operators.\n>\n>Additionally, the assumption of the wave function being **normalized** is important, since the probability outcomes must sum up to $1$. If the wave function is not normalized, it is important to normalize it first in order to obtain the correct measurement probabilities.\n\n## 🔎 Analyze\n\nThe qubit is in the following state:\n$$\\ket \\psi = 0.6 \\ket 0 + 0.8 \\ket 1 \\equiv \\begin{bmatrix} 0.6 \\\\\\ 0.8\\end{bmatrix}.$$\n\nIf this qubit is measured in the computational basis, what are the outcome probabilities?\n\n<details>\n<summary><b>Solution</b></summary>\nThe given state $\\ket \\psi$ is normalized, since $0.6^2 + 0.8^2 = 1$. Hence, the probability of measuring $0$ is $|0.6|^2 = 0.36$, and the probability of measuring $1$ is $|0.8|^2 = 0.64$.\n</details>"
|
|
1102
|
+
}
|
|
1103
|
+
]
|
|
1104
|
+
},
|
|
1105
|
+
{
|
|
1106
|
+
"type": "lesson",
|
|
1107
|
+
"id": "single_qubit_measurements__implementing_measurement",
|
|
1108
|
+
"title": "Implementing Measurement In Q# Using The M Operation",
|
|
1109
|
+
"items": [
|
|
1110
|
+
{
|
|
1111
|
+
"type": "text-content",
|
|
1112
|
+
"asHtml": "<p>In this demo, we prepare a qubit in the state $0.6|0\\rangle + 0.8|1\\rangle$, and then measure it in the computational basis. In Q#, single-qubit measurements in the computational basis can be implemented using the <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.m\" target=\"_blank\">M operation</a>. It will return the constant <code>Zero</code> if measurement result was $0$ or the constant <code>One</code> if the measurement result was $1$. <code>Zero</code> and <code>One</code> are constants of type <code>Result</code>.</p>\n<blockquote>\n<p>If you run this code multiple times, you will notice that whenever the measurement outcome is $1$, the post-measurement state of the qubit is $\\ket 1$, and similarly for $0$. This is in line with our expectation that after the measurement the wave function 'collapses' to the corresponding state.</p>\n</blockquote>\n",
|
|
1113
|
+
"asMarkdown": "\nIn this demo, we prepare a qubit in the state $0.6|0\\rangle + 0.8|1\\rangle$, and then measure it in the computational basis. In Q#, single-qubit measurements in the computational basis can be implemented using the <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.m\" target=\"_blank\">M operation</a>. It will return the constant `Zero` if measurement result was $0$ or the constant `One` if the measurement result was $1$. `Zero` and `One` are constants of type `Result`.\n\n> If you run this code multiple times, you will notice that whenever the measurement outcome is $1$, the post-measurement state of the qubit is $\\ket 1$, and similarly for $0$. This is in line with our expectation that after the measurement the wave function 'collapses' to the corresponding state."
|
|
1114
|
+
},
|
|
1115
|
+
{
|
|
1116
|
+
"type": "example",
|
|
1117
|
+
"id": "single_qubit_measurements__implementing_measurement_demo",
|
|
1118
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation SimpleMeasurementDemo() : Unit {\n use q = Qubit();\n // Prepare the qubit in the superposition state\n // |𝜓❭ = 0.6 |0❭ + 0.8 |1❭\n Ry(2.0 * ArcTan2(0.8, 0.6), q);\n\n Message(\"Qubit in state |𝜓❭:\");\n DumpMachine();\n\n Message(\"Measuring the qubit...\");\n let outcome = (M(q) == One ? 1 | 0);\n\n Message($\"The measurement outcome is {outcome}.\");\n Message(\"Post-measurement state of the qubit:\");\n DumpMachine();\n Reset(q);\n }\n}\n"
|
|
1119
|
+
}
|
|
1120
|
+
]
|
|
1121
|
+
},
|
|
1122
|
+
{
|
|
1123
|
+
"type": "lesson",
|
|
1124
|
+
"id": "single_qubit_measurements__measurement_statistics",
|
|
1125
|
+
"title": "Measurement Statistics",
|
|
1126
|
+
"items": [
|
|
1127
|
+
{
|
|
1128
|
+
"type": "text-content",
|
|
1129
|
+
"asHtml": "<p>The following code demonstrates that the theoretical and experimental values of the probability outcomes indeed match with each other. We repeatedly prepare the same state $\\ket \\psi = 0.6 \\ket 0 + 0.8 \\ket 1$ and measure it in the computational basis $100$ times. At the end, we expect 0 to be measured approximately $|0.6 |^2 \\cdot 100= 36$ times, and 1 to be measured approximately $|0.8|^2 \\cdot 100= 64$ times. Note that since measurements are probabilistic, we do not expect the results to match these values exactly. As we repeat the measurements, the resulting distribution will align with the theoretical probabilities.</p>\n",
|
|
1130
|
+
"asMarkdown": "\nThe following code demonstrates that the theoretical and experimental values of the probability outcomes indeed match with each other. We repeatedly prepare the same state $\\ket \\psi = 0.6 \\ket 0 + 0.8 \\ket 1$ and measure it in the computational basis $100$ times. At the end, we expect 0 to be measured approximately $|0.6 |^2 \\cdot 100= 36$ times, and 1 to be measured approximately $|0.8|^2 \\cdot 100= 64$ times. Note that since measurements are probabilistic, we do not expect the results to match these values exactly. As we repeat the measurements, the resulting distribution will align with the theoretical probabilities."
|
|
1131
|
+
},
|
|
1132
|
+
{
|
|
1133
|
+
"type": "example",
|
|
1134
|
+
"id": "single_qubit_measurements__measurement_statistics_demo",
|
|
1135
|
+
"code": "namespace Kata {\n\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation MeasumentStatisticsDemo() : Unit {\n mutable countZero = 0;\n let numRuns = 100;\n use q = Qubit();\n for i in 1 .. numRuns {\n // Prepare the qubit in the superposition state\n // |𝜓❭ = 0.6 |0❭ + 0.8 |1❭\n Ry(2.0 * ArcTan2(0.8, 0.6), q);\n\n // Measure in the computational basis, and update the counts according to the outcomes\n if M(q) == Zero {\n set countZero += 1;\n }\n // Reset the qubit for use in the next iteration\n Reset(q);\n }\n let countOne = numRuns - countZero;\n\n Message($\"Simulated probability of measuring 0 is 0.{countZero}.\");\n Message($\"Theoretical probability of measuring 0 is 0.36.\");\n\n Message($\"Simulated probability of measuring 1 is 0.{countOne}.\");\n Message($\"Theoretical probability of measuring 1 is 0.64.\");\n }\n\n}\n"
|
|
1136
|
+
},
|
|
1137
|
+
{
|
|
1138
|
+
"type": "text-content",
|
|
1139
|
+
"asHtml": "<p>Measurements can be used to distinguish orthogonal states. We start with an exercise for distinguishing between the computational basis states and discuss the general case of arbitrary basis measurements later in the kata.</p>\n",
|
|
1140
|
+
"asMarkdown": "\nMeasurements can be used to distinguish orthogonal states. We start with an exercise for distinguishing between the computational basis states and discuss the general case of arbitrary basis measurements later in the kata."
|
|
1141
|
+
}
|
|
1142
|
+
]
|
|
1143
|
+
},
|
|
1144
|
+
{
|
|
1145
|
+
"type": "exercise",
|
|
1146
|
+
"id": "single_qubit_measurements__distinguish_0_and_1",
|
|
1147
|
+
"title": "Distinguish |0〉 and |1〉",
|
|
1148
|
+
"description": {
|
|
1149
|
+
"type": "text-content",
|
|
1150
|
+
"asHtml": "<p><strong>Input:</strong> A qubit which is guaranteed to be in either the $|0\\rangle$ or the $|1\\rangle$ state.</p>\n<p><strong>Output:</strong> <code>true</code> if the qubit was in the $|0\\rangle$ state, or <code>false</code> if it was in the $|1\\rangle$ state. The state of the qubit at the end of the operation does not matter.</p>\n",
|
|
1151
|
+
"asMarkdown": "**Input:** A qubit which is guaranteed to be in either the $|0\\rangle$ or the $|1\\rangle$ state.\n\n**Output:** `true` if the qubit was in the $|0\\rangle$ state, or `false` if it was in the $|1\\rangle$ state. The state of the qubit at the end of the operation does not matter.\n"
|
|
1152
|
+
},
|
|
1153
|
+
"sourceIds": [
|
|
1154
|
+
"KatasLibrary.qs",
|
|
1155
|
+
"single_qubit_measurements__common.qs",
|
|
1156
|
+
"single_qubit_measurements__distinguish_0_and_1__verification.qs"
|
|
1157
|
+
],
|
|
1158
|
+
"placeholderCode": "namespace Kata {\n\n operation IsQubitZero(q : Qubit) : Bool {\n // The operation M will measure a qubit in the computational basis\n // (|0⟩ and |1⟩ basis) and return Zero if the observed state was |0⟩\n // or One if the state was |1⟩. Measuring a basis state will yield the\n // result matching that state deterministically. To answer the\n // question, you need to perform the measurement and check whether the\n // result equals Zero.\n\n // Implement your solution here...\n\n return false;\n }\n\n}\n",
|
|
1159
|
+
"explainedSolution": {
|
|
1160
|
+
"type": "explained-solution",
|
|
1161
|
+
"items": [
|
|
1162
|
+
{
|
|
1163
|
+
"type": "text-content",
|
|
1164
|
+
"asHtml": "<p>The input qubit is guaranteed to be either in basis state $|0\\rangle$ or $|1\\rangle$. This means that when measuring the qubit in the computational basis, the measurement will report the input state without any doubt.</p>\n<p>In Q# the operation <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.m\" target=\"_blank\"><code>M</code></a> can be used to measure a single qubit in the computational basis. The measurement result is a value of type <code>Result</code> - the operation <code>M</code> will return <code>One</code> if the input qubit was in the $|1\\rangle$ state and <code>Zero</code> if the input qubit was in the $|0\\rangle$ state. Since we need to encode the first case as <code>false</code> and the second one as <code>true</code>, we can return the result of equality comparison between measurement result and <code>Zero</code>.</p>\n",
|
|
1165
|
+
"asMarkdown": "\nThe input qubit is guaranteed to be either in basis state $|0\\rangle$ or $|1\\rangle$. This means that when measuring the qubit in the computational basis, the measurement will report the input state without any doubt.\n\nIn Q# the operation <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.m\" target=\"_blank\">`M`</a> can be used to measure a single qubit in the computational basis. The measurement result is a value of type `Result` - the operation `M` will return `One` if the input qubit was in the $|1\\rangle$ state and `Zero` if the input qubit was in the $|0\\rangle$ state. Since we need to encode the first case as `false` and the second one as `true`, we can return the result of equality comparison between measurement result and `Zero`."
|
|
1166
|
+
},
|
|
1167
|
+
{
|
|
1168
|
+
"type": "solution",
|
|
1169
|
+
"id": "single_qubit_measurements__distinguish_0_and_1_solution",
|
|
1170
|
+
"code": "namespace Kata {\n operation IsQubitZero(q : Qubit) : Bool {\n return M(q) == Zero;\n }\n \n}\n"
|
|
1171
|
+
}
|
|
1172
|
+
]
|
|
1173
|
+
}
|
|
1174
|
+
},
|
|
1175
|
+
{
|
|
1176
|
+
"type": "lesson",
|
|
1177
|
+
"id": "single_qubit_measurements__pauli_bases",
|
|
1178
|
+
"title": "Measurements in the Pauli Bases",
|
|
1179
|
+
"items": [
|
|
1180
|
+
{
|
|
1181
|
+
"type": "text-content",
|
|
1182
|
+
"asHtml": "<p>So far, we have discussed measurements done in the computational basis, that is, the ${ \\ket 0, \\ket 1}$ basis.</p>\n<p>It is also possible to implement measurements in other orthogonal bases, such as the Pauli X basis, which consists of the two vectors $\\ket + = \\frac1{\\sqrt2} \\big(\\ket 0 +\\ket 1\\big)$, and $\\ket - = \\frac1{\\sqrt2} \\big(\\ket 0 -\\ket 1\\big)$. Q# has a built-in operation <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.measure\" target=\"_blank\"><code>Measure</code></a> for measurements in the Pauli bases.</p>\n<blockquote>\n<p>The <code>Measure</code> operation can be used for measuring multiple qubits in a multi-qubit system; however, in this kata we only consider measurements for single-qubit systems.</p>\n</blockquote>\n<p>The eigenvalues of a Pauli matrix are $\\pm 1$, with one eigenvector corresponding to each eigenvalue. For any chosen Pauli basis, the <code>Measure</code> operation returns <code>Zero</code> if the measurement outcome corresponds to the eigenvalue $+1$, and returns <code>One</code> if the measurement outcome corresponds to the eigenvalue $-1$. As in the case of the computational basis measurements, the wave function of the qubit collapses to the corresponding state after the measurement is executed.</p>\n<p>The probabilities of the outcomes are defined using a similar rule: to measure a state $\\ket \\psi$ in a Pauli basis ${ \\ket {b_0}, \\ket {b_1}}$, we represent it as a linear combination of the basis vectors\n$$\\ket \\psi = c_0 \\ket {b_0} + c_1 \\ket {b_1}.$$</p>\n<p>The probabilities of outcomes $\\ket{b_0}$ and $\\ket{b_1}$ will be defined as $|c_0|^2$, and $|c_1|^2$, respectively.</p>\n<blockquote>\n<p>Computational basis measurement is often referred to as measurement in Pauli Z basis. Indeed, the eigenvectors of the Z gate are $\\ket 0$ and $\\ket 1$, with eigenvalues $+1$ and $-1$, respectively.</p>\n</blockquote>\n",
|
|
1183
|
+
"asMarkdown": "\nSo far, we have discussed measurements done in the computational basis, that is, the $\\{ \\ket 0, \\ket 1\\}$ basis.\n\nIt is also possible to implement measurements in other orthogonal bases, such as the Pauli X basis, which consists of the two vectors $\\ket + = \\frac1{\\sqrt2} \\big(\\ket 0 +\\ket 1\\big)$, and $\\ket - = \\frac1{\\sqrt2} \\big(\\ket 0 -\\ket 1\\big)$. Q# has a built-in operation <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.measure\" target=\"_blank\">`Measure`</a> for measurements in the Pauli bases.\n\n> The `Measure` operation can be used for measuring multiple qubits in a multi-qubit system; however, in this kata we only consider measurements for single-qubit systems.\n\nThe eigenvalues of a Pauli matrix are $\\pm 1$, with one eigenvector corresponding to each eigenvalue. For any chosen Pauli basis, the `Measure` operation returns `Zero` if the measurement outcome corresponds to the eigenvalue $+1$, and returns `One` if the measurement outcome corresponds to the eigenvalue $-1$. As in the case of the computational basis measurements, the wave function of the qubit collapses to the corresponding state after the measurement is executed.\n\nThe probabilities of the outcomes are defined using a similar rule: to measure a state $\\ket \\psi$ in a Pauli basis $\\{ \\ket {b_0}, \\ket {b_1}\\}$, we represent it as a linear combination of the basis vectors\n$$\\ket \\psi = c_0 \\ket {b_0} + c_1 \\ket {b_1}.$$\n\nThe probabilities of outcomes $\\ket{b_0}$ and $\\ket{b_1}$ will be defined as $|c_0|^2$, and $|c_1|^2$, respectively.\n\n> Computational basis measurement is often referred to as measurement in Pauli Z basis. Indeed, the eigenvectors of the Z gate are $\\ket 0$ and $\\ket 1$, with eigenvalues $+1$ and $-1$, respectively."
|
|
1184
|
+
}
|
|
1185
|
+
]
|
|
1186
|
+
},
|
|
1187
|
+
{
|
|
1188
|
+
"type": "exercise",
|
|
1189
|
+
"id": "single_qubit_measurements__distinguish_plus_and_minus",
|
|
1190
|
+
"title": "Distinguish |+〉 and |-〉",
|
|
1191
|
+
"description": {
|
|
1192
|
+
"type": "text-content",
|
|
1193
|
+
"asHtml": "<p><strong>Input</strong>: A qubit which is guaranteed to be in either the $\\ket +$ state, or the $\\ket -$ state.</p>\n<p><strong>Output</strong>: <code>true</code> if the qubit is in the $\\ket -$ state, or <code>false</code> if it was in the $\\ket +$ state.</p>\n<blockquote>\n<p>To perform a single-qubit measurement in a certain Pauli basis using the <code>Measure</code> operation,\nyou need to pass it two parameters: first, an array of one <code>Pauli</code> constant (<code>PauliX</code>, <code>PauliY</code> or <code>PauliZ</code>), and second, an array of one qubit you want to measure.</p>\n</blockquote>\n",
|
|
1194
|
+
"asMarkdown": "**Input**: A qubit which is guaranteed to be in either the $\\ket +$ state, or the $\\ket -$ state.\n\n**Output**: `true` if the qubit is in the $\\ket -$ state, or `false` if it was in the $\\ket +$ state.\n\n> To perform a single-qubit measurement in a certain Pauli basis using the `Measure` operation,\n> you need to pass it two parameters: first, an array of one `Pauli` constant (`PauliX`, `PauliY` or `PauliZ`), and second, an array of one qubit you want to measure.\n"
|
|
1195
|
+
},
|
|
1196
|
+
"sourceIds": [
|
|
1197
|
+
"KatasLibrary.qs",
|
|
1198
|
+
"single_qubit_measurements__common.qs",
|
|
1199
|
+
"single_qubit_measurements__distinguish_plus_and_minus__verification.qs"
|
|
1200
|
+
],
|
|
1201
|
+
"placeholderCode": "namespace Kata {\n\n operation IsQubitMinus(q : Qubit) : Bool {\n // Implement your solution here...\n\n return false;\n }\n\n}\n",
|
|
1202
|
+
"explainedSolution": {
|
|
1203
|
+
"type": "explained-solution",
|
|
1204
|
+
"items": [
|
|
1205
|
+
{
|
|
1206
|
+
"type": "text-content",
|
|
1207
|
+
"asHtml": "<p>The input qubit is guaranteed to be either in basis state $|+\\rangle$ or $|-\\rangle$. This means that when measuring the qubit in the Pauli X basis, the measurement will report the input state without any doubt. (Recall that these states are eigenstates for the Pauli X matrix).</p>\n<p>In Q# the operation <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.measure\" target=\"_blank\"><code>Measure</code></a> can be used to measure a qubit in Pauli basis of the user's choice. The operation returns a value of type <code>Result</code> and is <code>Zero</code> if the measured state corresponds to the eigenvalue $+1$, and <code>One</code> if it corresponds to the eigenvalue $-1$ of the Pauli operator.</p>\n<p>Since the states $\\ket +$ and $\\ket -$ correspond to the eigenvalues $+1$ and $-1$ of the Pauli X operator, we can return the result of equality comparison between the measurement result and <code>One</code>.\nNote that since <code>Measure</code> operation generally works with multiple qubits to perform multi-qubit measurements, it takes array parameters. To do a single-qubit measurement, you need to pass two arrays of one element, <code>[PauliX]</code> and <code>[q]</code>, rather than individual values.</p>\n",
|
|
1208
|
+
"asMarkdown": "\nThe input qubit is guaranteed to be either in basis state $|+\\rangle$ or $|-\\rangle$. This means that when measuring the qubit in the Pauli X basis, the measurement will report the input state without any doubt. (Recall that these states are eigenstates for the Pauli X matrix).\n\nIn Q# the operation <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.measure\" target=\"_blank\">`Measure`</a> can be used to measure a qubit in Pauli basis of the user's choice. The operation returns a value of type `Result` and is `Zero` if the measured state corresponds to the eigenvalue $+1$, and `One` if it corresponds to the eigenvalue $-1$ of the Pauli operator.\n\nSince the states $\\ket +$ and $\\ket -$ correspond to the eigenvalues $+1$ and $-1$ of the Pauli X operator, we can return the result of equality comparison between the measurement result and `One`.\nNote that since `Measure` operation generally works with multiple qubits to perform multi-qubit measurements, it takes array parameters. To do a single-qubit measurement, you need to pass two arrays of one element, `[PauliX]` and `[q]`, rather than individual values."
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
"type": "solution",
|
|
1212
|
+
"id": "single_qubit_measurements__distinguish_plus_and_minus_solution",
|
|
1213
|
+
"code": "namespace Kata {\n operation IsQubitMinus(q : Qubit): Bool {\n return Measure([PauliX], [q]) == One;\n }\n\n}\n"
|
|
1214
|
+
}
|
|
1215
|
+
]
|
|
1216
|
+
}
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
"type": "lesson",
|
|
1220
|
+
"id": "single_qubit_measurements__arbitrary_bases",
|
|
1221
|
+
"title": "Measurements in Arbitrary Orthogonal Bases",
|
|
1222
|
+
"items": [
|
|
1223
|
+
{
|
|
1224
|
+
"type": "text-content",
|
|
1225
|
+
"asHtml": "<p>It is possible to measure a qubit in orthogonal bases other than the Pauli bases. Suppose one wants to measure a qubit in an orthonormal basis $\\ket {b_0}$ and $\\ket {b_1}$. Let the state of the qubit be represented by the normalized vector $\\ket \\psi$. Then, one can always express the state in terms of the basis vectors $\\ket{b_0}$ and $\\ket{b_1}$, i.e., there exist complex numbers $c_0, c_1$, such that\n$$\n\\ket \\psi = c_0 \\ket {b_0} + c_1 \\ket {b_1}.\n$$\nThe rule for obtaining the probabilities of measurement outcomes is exactly the same as that for the computation basis measurement. For a measurement in a ${ b_0, b_1}$ basis we get</p>\n<ul>\n<li>Outcome $b_0$ with probability $|c_0|^2$ and the post-measurement qubit state of $\\ket {b_0}$</li>\n<li>Outcome $b_1$ with probability $|c_1|^2$ and the post-measurement qubit state of $\\ket {b_1}$</li>\n</ul>\n<p>This can be summarized in the following table:</p>\n<table>\n <tr>\n <th>Measurement outcome</th>\n <th>Probability of outcome</th>\n <th>State after measurement</th>\n </tr>\n <tr>\n <td>$b_0$</td>\n <td>$|c_0|^2$</td>\n <td>$\\ket{b_0}$</td>\n </tr>\n <tr>\n <td>$b_1$</td>\n <td>$|c_1|^2$</td>\n <td>$\\ket{b_1}$</td>\n </tr>\n</table>\n\n<p>As before, the assumption of $\\ket \\psi$ being normalized is important, since it guarantees that the two probabilities add to $1$.</p>\n<blockquote>\n<p>As you may recall, a global phase is said to be hidden or unobservable.\nThis is explained by the fact that global phases have no impact on quantum measurements. For example, consider two isolated qubits which are in (normalized) states $\\ket \\psi$ and $e^{i\\theta}\\ket \\psi$.\nIf both are measured in an orthogonal basis ${ \\ket{b_0},\\ket{b_1}}$, the probabilities of measuring $b_0$ or $b_1$ are identical in both cases, since $|\\bra{b_i}\\ket{\\psi}|^2 = |\\bra{b_i}e^{i\\theta}\\ket{\\psi}|^2 $.\nSimilarly, for either qubit, if $b_i$ is the measurement outcome, the post-measurement state of the qubit is $\\ket{b_i}$ for both qubits. Hence, the measurements are independent of the global phase $\\theta$.</p>\n</blockquote>\n<h2 id=\"measurements-as-projection-operations\">Measurements as Projection Operations</h2>\n<p>Just as qubits are represented by vectors and quantum gates are represented by matrices, quantum measurements are represented by orthogonal projection operators. An orthogonal projection operator is a matrix $P$ which satisfies the following property:\n$$\nP^2 = P^\\dagger = P.\n$$\n(As usual, the $\\dagger$ symbol denotes conjugate transposition.)</p>\n<p>As the name implies, orthogonal projection operators project the state of the qubit onto an orthogonal subspace. Using the ket-bra representation, one can represent a projection matrix in the Dirac notation.\nFor example, one may construct a projector onto the $\\ket{0}$ subspace as:\n$$\nP = \\ket 0 \\bra 0 \\equiv \\begin{bmatrix} 1 & 0 \\\\ 0 & 0\\end{bmatrix}.\n$$</p>\n<p>A measurement in an orthogonal basis ${ \\ket{b_0}, \\ket{b_1}}$ is described by a pair of projectors $P_0 = \\ket{b_0}\\bra{b_0}$ and $P_1 = \\ket{b_1}\\bra{b_1}$. Since $\\ket{b_0}$ and $\\ket{b_1}$ are orthogonal, their projectors are also orthogonal, i.e., $P_0 P_1 = P_1 P_0 = 0$. The rules for measurements in this basis can then be summarized as follows:</p>\n<ul>\n<li>Measuring a qubit in a state $\\ket \\psi$ is done by picking one of these projection operators at random.</li>\n<li>Projection $P_0$ is chosen with probability $|P_0 \\ket{\\psi}|^2$, and the projector $P_1$ is chosen with probability $|P_1\\ket{\\psi}|^2.$</li>\n<li>If projector $P_0$ is chosen, the post-measurement state of the qubit is given by\n$$\n\\frac1{|P_0 \\ket{\\psi}|}P_0 \\ket\\psi,\n$$\nand similarly for $P_1$.</li>\n</ul>\n<p>Although this formalism looks different from the previous sections, it is in fact equivalent. If $\\ket \\psi = c_0 \\ket{b_0} + c_1 \\ket{b_1}$, we have\n$$\nP_0 \\ket \\psi = c_0 \\ket{b_0}, \\text{so that } | P_0\\ket \\psi| = c_0,\n$$\nand similarly,\n$$\nP_1 \\ket \\psi = c_1 \\ket{b_1}, \\text{so that } |P_1\\ket \\psi| = c_1.\n$$</p>\n<p>Thus, as before, the probability of measuring $b_0$ is $|P_0\\ket\\psi|^2 = |c_0|^2$, and the probability of measuring $b_1$ is $|P_1\\ket\\psi|^2 = |c_1|^2$. Similarly, one can verify that the post-measurement outcomes are also $\\ket{b_0}$ and $\\ket{b_1}$ respectively (up to unobservable global phases).</p>\n<p>Although the projector formalism for single-qubit systems may seem superfluous, its importance will become clear later while considering measurements for multi-qubit systems.</p>\n<h2 id=\"arbitrary-basis-measurements-implementation\">Arbitrary Basis Measurements Implementation</h2>\n<p>In the previous section, we discussed measurements in Pauli bases using the built-in <code>Measure</code> operation. We will now show that it is always possible to measure a qubit in any orthogonal basis using just unitary rotation matrices and computation basis measurements.</p>\n<p>Consider a state $ \\ket \\psi = c_0 \\ket {b_0} + c_1 \\ket {b_1} $ which we would like to measure in an orthonormal basis ${ \\ket{b_0}, \\ket{b_1}}$. First, we construct the following unitary matrix:\n$$\nU = \\ket{0} \\bra{b_0} + \\ket{1} \\bra{b_1}\n$$</p>\n<p>The conjugate transpose of this unitary is the operator\n$$\nU^\\dagger = \\ket{b_0} \\bra{0} + \\ket{b_1} \\bra{1}\n$$</p>\n<p>(One may verify that $U$ is indeed a unitary matrix, by checking that $U^\\dagger U = U U^\\dagger = I$)</p>\n<p>Note that the effect of these matrices on the two bases is the following:\n$$U\\ket{b_0} = \\ket{0},$$\n$$U\\ket{b_1} = \\ket{1},$$\n$$U^\\dagger \\ket{0} = \\ket{b_0},$$\n$$U^\\dagger \\ket 1 = \\ket{b_1}.$$</p>\n<p>In order to implement a measurement in the ${ \\ket{b_0}, \\ket{b_1} }$ basis, we do the following:</p>\n<ol>\n<li>Apply $U$ to $\\ket \\psi$.<br>The resulting state is $U\\ket \\psi = c_0 \\ket 0 + c_1 \\ket 1 $.</li>\n<li>Measure the state $U\\ket{\\psi}$ in the computational basis.<br>The outcomes $0$ and $1$ occur with probabilities $|c_0|^2$ and $|c_1|^2$.</li>\n<li>Apply $U^\\dagger$ to the post-measurement state.<br>This transforms the states $\\ket 0$ and $\\ket 1$ to the states $\\ket{b_0}$ and $\\ket{b_1}$, respectively.</li>\n</ol>\n<p>Thus, $b_0$ and $b_1$ are measured with probabilities $|c_0|^2$ and $|c_1|^2$, respectively, with the end state being $\\ket{b_0}$ and $\\ket{b_1}$ - which is exactly the measurement we want to implement.</p>\n<p>This procedure can be used to distinguish arbitrary orthogonal states as well, as will become clear from the following exercises.</p>\n<h2 id=\"🔎-analyze\">🔎 Analyze</h2>\n<p><strong>The outcome probabilities for a measurement in a specified basis</strong></p>\n<ol>\n<li><p>What are the outcome probabilities of measuring a qubit in the $\\ket{0}$ state in the Pauli X basis, i.e., the ${ \\ket +, \\ket -}$ basis?</p>\n</li>\n<li><p>What are the outcome probabilities of measuring a qubit in the $0.6\\ket{0} + 0.8 \\ket{1}$ state in the Pauli Y basis, i.e., the ${ \\ket i, \\ket{-i}}$ basis?</p>\n</li>\n</ol>\n<details>\n<summary><b>Solution</b></summary>\n\n<ol>\n<li><p>To find the probabilities of measuring $+$ and $-$, we first need to express the state $\\ket 0$ in terms of $\\ket +$ and $\\ket -$. Using the fact that $\\ket{\\pm} = \\frac{1}{\\sqrt{2}} (\\ket{0} \\pm \\ket{1})$, we can show that\n $$\n \\ket 0 = \\frac{1}{\\sqrt{2}} \\ket{+} + \\frac{1}{\\sqrt{2}} \\ket{-}.\n $$\n Thus, the probability of measuring $+$ is $|\\frac1{\\sqrt2}|^2 = 0.5$, and similarly, the probability of measuring $-$ is $0.5$.</p>\n</li>\n<li><p>Similar to the first part, we need to express the state $\\ket \\psi = 0.6 \\ket 0 + 0.8 \\ket 1$ in the $\\ket{\\pm i}$ basis. For this calculation, we use the projection matrix approach.</p>\n<p> First, we recall that the states $\\ket{\\pm i}$ are given by\n $$\n \\ket{\\pm i} = \\frac1{\\sqrt2} (\\ket 0 \\pm i \\ket 1).\n $$</p>\n<p> We can now construct the two projectors $P_{\\pm i}$ onto states $\\ket {\\pm i}$ as follows:\n $$P_{i} = \\ket{i}\\bra{i} = \\frac{1}{2} \\begin{bmatrix} 1 \\\\ i \\end{bmatrix} \\begin{bmatrix} 1 & -i \\end{bmatrix} = \\frac{1}{2} \\begin{bmatrix}1 & -i \\\\ i & 1\\end{bmatrix},$$\n $$P_{-i} = \\ket{-i}\\bra{-i} = \\frac{1}{2} \\begin{bmatrix} 1 \\\\ -i \\end{bmatrix} \\begin{bmatrix} 1 & i \\end{bmatrix} = \\frac{1}{2} \\begin{bmatrix}1 & i \\\\ -i & 1\\end{bmatrix}.$$</p>\n<p> Recalling that the probabilities of measuring $\\pm i$ are equal to the norm of the vectors $P_{\\pm i}\\ket \\psi$, we now apply $P_{\\pm i}$ to $\\ket \\psi$:\n $$P_{+i} \\ket \\psi = \\frac{1}{2} \\begin{bmatrix}1 & -i \\\\ i & 1\\end{bmatrix} \\begin{bmatrix} 0.6 \\\\ 0.8 \\end{bmatrix} = \\frac{1}{2} \\begin{bmatrix} 0.6 - 0.8i \\\\ 0.8 + 0.6i \\end{bmatrix},$$\n $$P_{-i} \\ket \\psi = \\frac{1}{2} \\begin{bmatrix}1 & i \\\\ -i & 1\\end{bmatrix} \\begin{bmatrix} 0.6 \\\\ 0.8 \\end{bmatrix} = \\frac{1}{2} \\begin{bmatrix} 0.6 + 0.8i \\\\ 0.8 - 0.6i \\end{bmatrix}.$$</p>\n<p> Hence, the probabilities of measuring $\\pm i$, which we denote by $p(\\pm i)$, are:\n $$p(+i) = |P_{+i} \\ket \\psi|^2 = \\frac{1}{4}(|0.6 - 0.8i|^2 + |0.8 + 0.6i|^2) = \\frac{1}{2},$$\n $$p(-i) = |P_{-i} \\ket \\psi|^2 = \\frac{1}{4}(|0.6 + 0.8i|^2 + |0.8 - 0.6i|^2) = \\frac{1}{2}.$$</p>\n</li>\n</ol>\n</details>",
|
|
1226
|
+
"asMarkdown": "\nIt is possible to measure a qubit in orthogonal bases other than the Pauli bases. Suppose one wants to measure a qubit in an orthonormal basis $\\ket {b_0}$ and $\\ket {b_1}$. Let the state of the qubit be represented by the normalized vector $\\ket \\psi$. Then, one can always express the state in terms of the basis vectors $\\ket{b_0}$ and $\\ket{b_1}$, i.e., there exist complex numbers $c_0, c_1$, such that\n$$\n\\ket \\psi = c_0 \\ket {b_0} + c_1 \\ket {b_1}.\n$$\nThe rule for obtaining the probabilities of measurement outcomes is exactly the same as that for the computation basis measurement. For a measurement in a $\\{ b_0, b_1\\}$ basis we get\n\n- Outcome $b_0$ with probability $|c_0|^2$ and the post-measurement qubit state of $\\ket {b_0}$\n- Outcome $b_1$ with probability $|c_1|^2$ and the post-measurement qubit state of $\\ket {b_1}$\n\nThis can be summarized in the following table:\n<table>\n <tr>\n <th>Measurement outcome</th>\n <th>Probability of outcome</th>\n <th>State after measurement</th>\n </tr>\n <tr>\n <td>$b_0$</td>\n <td>$|c_0|^2$</td>\n <td>$\\ket{b_0}$</td>\n </tr>\n <tr>\n <td>$b_1$</td>\n <td>$|c_1|^2$</td>\n <td>$\\ket{b_1}$</td>\n </tr>\n</table>\n\nAs before, the assumption of $\\ket \\psi$ being normalized is important, since it guarantees that the two probabilities add to $1$.\n\n> As you may recall, a global phase is said to be hidden or unobservable.\nThis is explained by the fact that global phases have no impact on quantum measurements. For example, consider two isolated qubits which are in (normalized) states $\\ket \\psi$ and $e^{i\\theta}\\ket \\psi$.\nIf both are measured in an orthogonal basis $\\{ \\ket{b_0},\\ket{b_1}\\}$, the probabilities of measuring $b_0$ or $b_1$ are identical in both cases, since $|\\bra{b_i}\\ket{\\psi}|^2 = |\\bra{b_i}e^{i\\theta}\\ket{\\psi}|^2 $.\nSimilarly, for either qubit, if $b_i$ is the measurement outcome, the post-measurement state of the qubit is $\\ket{b_i}$ for both qubits. Hence, the measurements are independent of the global phase $\\theta$.\n\n## Measurements as Projection Operations\n\nJust as qubits are represented by vectors and quantum gates are represented by matrices, quantum measurements are represented by orthogonal projection operators. An orthogonal projection operator is a matrix $P$ which satisfies the following property:\n$$\nP^2 = P^\\dagger = P.\n$$\n(As usual, the $\\dagger$ symbol denotes conjugate transposition.)\n\nAs the name implies, orthogonal projection operators project the state of the qubit onto an orthogonal subspace. Using the ket-bra representation, one can represent a projection matrix in the Dirac notation.\nFor example, one may construct a projector onto the $\\ket{0}$ subspace as:\n$$\nP = \\ket 0 \\bra 0 \\equiv \\begin{bmatrix} 1 & 0 \\\\\\ 0 & 0\\end{bmatrix}.\n$$\n\nA measurement in an orthogonal basis $\\{ \\ket{b_0}, \\ket{b_1}\\}$ is described by a pair of projectors $P_0 = \\ket{b_0}\\bra{b_0}$ and $P_1 = \\ket{b_1}\\bra{b_1}$. Since $\\ket{b_0}$ and $\\ket{b_1}$ are orthogonal, their projectors are also orthogonal, i.e., $P_0 P_1 = P_1 P_0 = 0$. The rules for measurements in this basis can then be summarized as follows:\n\n- Measuring a qubit in a state $\\ket \\psi$ is done by picking one of these projection operators at random.\n- Projection $P_0$ is chosen with probability $|P_0 \\ket{\\psi}|^2$, and the projector $P_1$ is chosen with probability $|P_1\\ket{\\psi}|^2.$\n- If projector $P_0$ is chosen, the post-measurement state of the qubit is given by\n$$\n\\frac1{|P_0 \\ket{\\psi}|}P_0 \\ket\\psi,\n$$\nand similarly for $P_1$.\n\nAlthough this formalism looks different from the previous sections, it is in fact equivalent. If $\\ket \\psi = c_0 \\ket{b_0} + c_1 \\ket{b_1}$, we have\n$$\nP_0 \\ket \\psi = c_0 \\ket{b_0}, \\text{so that } | P_0\\ket \\psi| = c_0,\n$$\nand similarly,\n$$\nP_1 \\ket \\psi = c_1 \\ket{b_1}, \\text{so that } |P_1\\ket \\psi| = c_1.\n$$\n\nThus, as before, the probability of measuring $b_0$ is $|P_0\\ket\\psi|^2 = |c_0|^2$, and the probability of measuring $b_1$ is $|P_1\\ket\\psi|^2 = |c_1|^2$. Similarly, one can verify that the post-measurement outcomes are also $\\ket{b_0}$ and $\\ket{b_1}$ respectively (up to unobservable global phases).\n\nAlthough the projector formalism for single-qubit systems may seem superfluous, its importance will become clear later while considering measurements for multi-qubit systems.\n\n## Arbitrary Basis Measurements Implementation\n\nIn the previous section, we discussed measurements in Pauli bases using the built-in `Measure` operation. We will now show that it is always possible to measure a qubit in any orthogonal basis using just unitary rotation matrices and computation basis measurements.\n\nConsider a state $ \\ket \\psi = c_0 \\ket {b_0} + c_1 \\ket {b_1} $ which we would like to measure in an orthonormal basis $\\{ \\ket{b_0}, \\ket{b_1}\\}$. First, we construct the following unitary matrix:\n$$\nU = \\ket{0} \\bra{b_0} + \\ket{1} \\bra{b_1}\n$$\n\nThe conjugate transpose of this unitary is the operator\n$$\nU^\\dagger = \\ket{b_0} \\bra{0} + \\ket{b_1} \\bra{1}\n$$\n\n(One may verify that $U$ is indeed a unitary matrix, by checking that $U^\\dagger U = U U^\\dagger = I$)\n\nNote that the effect of these matrices on the two bases is the following:\n$$U\\ket{b_0} = \\ket{0},$$\n$$U\\ket{b_1} = \\ket{1},$$\n$$U^\\dagger \\ket{0} = \\ket{b_0},$$\n$$U^\\dagger \\ket 1 = \\ket{b_1}.$$\n\nIn order to implement a measurement in the ${ \\ket{b_0}, \\ket{b_1} }$ basis, we do the following:\n\n1. Apply $U$ to $\\ket \\psi$. \n The resulting state is $U\\ket \\psi = c_0 \\ket 0 + c_1 \\ket 1 $.\n2. Measure the state $U\\ket{\\psi}$ in the computational basis. \n The outcomes $0$ and $1$ occur with probabilities $|c_0|^2$ and $|c_1|^2$.\n3. Apply $U^\\dagger$ to the post-measurement state. \n This transforms the states $\\ket 0$ and $\\ket 1$ to the states $\\ket{b_0}$ and $\\ket{b_1}$, respectively.\n\nThus, $b_0$ and $b_1$ are measured with probabilities $|c_0|^2$ and $|c_1|^2$, respectively, with the end state being $\\ket{b_0}$ and $\\ket{b_1}$ - which is exactly the measurement we want to implement.\n\nThis procedure can be used to distinguish arbitrary orthogonal states as well, as will become clear from the following exercises.\n\n## 🔎 Analyze\n\n**The outcome probabilities for a measurement in a specified basis**\n\n1. What are the outcome probabilities of measuring a qubit in the $\\ket{0}$ state in the Pauli X basis, i.e., the $\\{ \\ket +, \\ket -\\}$ basis?\n\n2. What are the outcome probabilities of measuring a qubit in the $0.6\\ket{0} + 0.8 \\ket{1}$ state in the Pauli Y basis, i.e., the $\\{ \\ket i, \\ket{-i}\\}$ basis?\n\n<details>\n<summary><b>Solution</b></summary>\n\n1. To find the probabilities of measuring $+$ and $-$, we first need to express the state $\\ket 0$ in terms of $\\ket +$ and $\\ket -$. Using the fact that $\\ket{\\pm} = \\frac{1}{\\sqrt{2}} (\\ket{0} \\pm \\ket{1})$, we can show that\n $$\n \\ket 0 = \\frac{1}{\\sqrt{2}} \\ket{+} + \\frac{1}{\\sqrt{2}} \\ket{-}.\n $$\n Thus, the probability of measuring $+$ is $|\\frac1{\\sqrt2}|^2 = 0.5$, and similarly, the probability of measuring $-$ is $0.5$.\n\n2. Similar to the first part, we need to express the state $\\ket \\psi = 0.6 \\ket 0 + 0.8 \\ket 1$ in the $\\ket{\\pm i}$ basis. For this calculation, we use the projection matrix approach.\n\n First, we recall that the states $\\ket{\\pm i}$ are given by\n $$\n \\ket{\\pm i} = \\frac1{\\sqrt2} (\\ket 0 \\pm i \\ket 1).\n $$\n\n We can now construct the two projectors $P_{\\pm i}$ onto states $\\ket {\\pm i}$ as follows:\n $$P_{i} = \\ket{i}\\bra{i} = \\frac{1}{2} \\begin{bmatrix} 1 \\\\\\\\ i \\end{bmatrix} \\begin{bmatrix} 1 & -i \\end{bmatrix} = \\frac{1}{2} \\begin{bmatrix}1 & -i \\\\\\\\ i & 1\\end{bmatrix},$$\n $$P_{-i} = \\ket{-i}\\bra{-i} = \\frac{1}{2} \\begin{bmatrix} 1 \\\\\\\\ -i \\end{bmatrix} \\begin{bmatrix} 1 & i \\end{bmatrix} = \\frac{1}{2} \\begin{bmatrix}1 & i \\\\\\\\ -i & 1\\end{bmatrix}.$$\n\n Recalling that the probabilities of measuring $\\pm i$ are equal to the norm of the vectors $P_{\\pm i}\\ket \\psi$, we now apply $P_{\\pm i}$ to $\\ket \\psi$:\n $$P_{+i} \\ket \\psi = \\frac{1}{2} \\begin{bmatrix}1 & -i \\\\\\\\ i & 1\\end{bmatrix} \\begin{bmatrix} 0.6 \\\\\\\\ 0.8 \\end{bmatrix} = \\frac{1}{2} \\begin{bmatrix} 0.6 - 0.8i \\\\\\\\ 0.8 + 0.6i \\end{bmatrix},$$\n $$P_{-i} \\ket \\psi = \\frac{1}{2} \\begin{bmatrix}1 & i \\\\\\\\ -i & 1\\end{bmatrix} \\begin{bmatrix} 0.6 \\\\\\\\ 0.8 \\end{bmatrix} = \\frac{1}{2} \\begin{bmatrix} 0.6 + 0.8i \\\\\\\\ 0.8 - 0.6i \\end{bmatrix}.$$\n\n Hence, the probabilities of measuring $\\pm i$, which we denote by $p(\\pm i)$, are:\n $$p(+i) = |P_{+i} \\ket \\psi|^2 = \\frac{1}{4}(|0.6 - 0.8i|^2 + |0.8 + 0.6i|^2) = \\frac{1}{2},$$\n $$p(-i) = |P_{-i} \\ket \\psi|^2 = \\frac{1}{4}(|0.6 + 0.8i|^2 + |0.8 - 0.6i|^2) = \\frac{1}{2}.$$\n\n</details>"
|
|
1227
|
+
}
|
|
1228
|
+
]
|
|
1229
|
+
},
|
|
1230
|
+
{
|
|
1231
|
+
"type": "exercise",
|
|
1232
|
+
"id": "single_qubit_measurements__distinguish_orthogonal_states_1",
|
|
1233
|
+
"title": "Distinguishing Orthogonal States: 1",
|
|
1234
|
+
"description": {
|
|
1235
|
+
"type": "text-content",
|
|
1236
|
+
"asHtml": "<p><strong>Input:</strong> A qubit which is guaranteed to be in either the $\\ket {\\psi_+}$ or the $\\ket{\\psi_-} $ state, where $\\ket {\\psi_+} = 0.6\\ket 0 + 0.8 \\ket 1 $ and $\\ket {\\psi_-} = -0.8\\ket 0 + 0.6 \\ket 1$.</p>\n<p><strong>Output:</strong> <code>true</code> if the qubit was in the $\\ket {\\psi_+}$ state, or <code>false</code> if it was in the $\\ket{\\psi_-} $ state. The state of the qubit at the end of the operation does not matter.</p>\n<details>\n<summary><strong>Need a hint?</strong></summary>\nA suitable $R_y$ rotation can be used to go from the computational basis ${ \\ket 0, \\ket 1 }$ to the ${ \\ket{\\psi_+}, \\ket{\\psi_-} }$ basis and vice versa.\n</details>\n",
|
|
1237
|
+
"asMarkdown": "**Input:** A qubit which is guaranteed to be in either the $\\ket {\\psi_+}$ or the $\\ket{\\psi_-} $ state, where $\\ket {\\psi_+} = 0.6\\ket 0 + 0.8 \\ket 1 $ and $\\ket {\\psi_-} = -0.8\\ket 0 + 0.6 \\ket 1$.\n\n**Output:** `true` if the qubit was in the $\\ket {\\psi_+}$ state, or `false` if it was in the $\\ket{\\psi_-} $ state. The state of the qubit at the end of the operation does not matter.\n\n<details>\n<summary><strong>Need a hint?</strong></summary>\nA suitable $R_y$ rotation can be used to go from the computational basis ${ \\ket 0, \\ket 1 }$ to the ${ \\ket{\\psi_+}, \\ket{\\psi_-} }$ basis and vice versa.\n</details>\n"
|
|
1238
|
+
},
|
|
1239
|
+
"sourceIds": [
|
|
1240
|
+
"KatasLibrary.qs",
|
|
1241
|
+
"single_qubit_measurements__common.qs",
|
|
1242
|
+
"single_qubit_measurements__distinguish_orthogonal_states_1__verification.qs"
|
|
1243
|
+
],
|
|
1244
|
+
"placeholderCode": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation IsQubitPsiPlus(q : Qubit) : Bool {\n // Implement your solution here...\n\n return false;\n }\n\n}\n",
|
|
1245
|
+
"explainedSolution": {
|
|
1246
|
+
"type": "explained-solution",
|
|
1247
|
+
"items": [
|
|
1248
|
+
{
|
|
1249
|
+
"type": "text-content",
|
|
1250
|
+
"asHtml": "<p>We can distinguish between the states $\\ket{\\psi_\\pm}$ if we implement a measurement in the ${ \\ket{\\psi_+}, \\ket{\\psi_-}}$ basis. This can be done if we construct a unitary transformation which maps the $\\ket{\\psi_+}$ state to the $\\ket{0}$ state, and the $\\ket{\\psi_{-}}$ state to the $\\ket{1}$ state.</p>\n<p>We can notice that the $R_y$ rotation gate with $\\theta = 2 \\arctan \\frac{0.8}{0.6}$ is an appropriate transformation:</p>\n<p>$$R_y(\\theta) \\ket 0 = 0.6 \\ket 0 + 0.8 \\ket 1 = \\ket {\\psi_+},$$\n$$R_y(\\theta) \\ket 1 = -0.8 \\ket 0 + 0.6 \\ket 1 = \\ket{\\psi_-}.$$</p>\n<p>Thus, the inverse (adjoint) transformation $R_y(-\\theta)$ maps the $\\ket{\\psi_\\pm}$ basis to the computational basis, i.e.,\n$$R_y(-\\theta) \\ket {\\psi_+} = \\ket 0,$$\n$$R_y(-\\theta) \\ket {\\psi_-} = \\ket 1.$$</p>\n<p>Hence, if we apply $R_y(-\\theta)$ to the qubit, its state will be transformed to one of the computational basis states, at which point we can measure it using <code>M</code>. If <code>M</code> returns <code>Zero</code>, the rotated state is $\\ket{0}$, which means that the original state of the qubit was $\\ket{\\psi_+}$. Similarly, an output of <code>One</code> indicates that the qubit was originally in the state $\\ket{\\psi_-}$.</p>\n",
|
|
1251
|
+
"asMarkdown": "\nWe can distinguish between the states $\\ket{\\psi_\\pm}$ if we implement a measurement in the $\\{ \\ket{\\psi_+}, \\ket{\\psi_-}\\}$ basis. This can be done if we construct a unitary transformation which maps the $\\ket{\\psi_+}$ state to the $\\ket{0}$ state, and the $\\ket{\\psi_{-}}$ state to the $\\ket{1}$ state.\n\nWe can notice that the $R_y$ rotation gate with $\\theta = 2 \\arctan \\frac{0.8}{0.6}$ is an appropriate transformation:\n\n$$R_y(\\theta) \\ket 0 = 0.6 \\ket 0 + 0.8 \\ket 1 = \\ket {\\psi_+},$$\n$$R_y(\\theta) \\ket 1 = -0.8 \\ket 0 + 0.6 \\ket 1 = \\ket{\\psi_-}.$$\n\nThus, the inverse (adjoint) transformation $R_y(-\\theta)$ maps the $\\ket{\\psi_\\pm}$ basis to the computational basis, i.e.,\n$$R_y(-\\theta) \\ket {\\psi_+} = \\ket 0,$$\n$$R_y(-\\theta) \\ket {\\psi_-} = \\ket 1.$$\n\nHence, if we apply $R_y(-\\theta)$ to the qubit, its state will be transformed to one of the computational basis states, at which point we can measure it using `M`. If `M` returns `Zero`, the rotated state is $\\ket{0}$, which means that the original state of the qubit was $\\ket{\\psi_+}$. Similarly, an output of `One` indicates that the qubit was originally in the state $\\ket{\\psi_-}$."
|
|
1252
|
+
},
|
|
1253
|
+
{
|
|
1254
|
+
"type": "solution",
|
|
1255
|
+
"id": "single_qubit_measurements__distinguish_orthogonal_states_1_solution",
|
|
1256
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation IsQubitPsiPlus(q: Qubit): Bool { \n Ry(-2.0 * ArcTan2(0.8, 0.6), q);\n return M(q) == Zero;\n }\n\n}\n"
|
|
1257
|
+
}
|
|
1258
|
+
]
|
|
1259
|
+
}
|
|
1260
|
+
},
|
|
1261
|
+
{
|
|
1262
|
+
"type": "exercise",
|
|
1263
|
+
"id": "single_qubit_measurements__distinguish_orthogonal_states_2",
|
|
1264
|
+
"title": "Distinguishing Orthogonal States: 2",
|
|
1265
|
+
"description": {
|
|
1266
|
+
"type": "text-content",
|
|
1267
|
+
"asHtml": "<p><strong>Inputs:</strong></p>\n<ol>\n<li>Angle $\\alpha$, in radians, represented as a <code>Double</code>.</li>\n<li>A qubit which is guaranteed to be in either the $|A\\rangle$ or the $|B\\rangle$ state, where $|A\\rangle = \\cos \\alpha |0\\rangle - i \\sin \\alpha |1\\rangle$ and $|B\\rangle = - i \\sin \\alpha |0\\rangle + \\cos \\alpha |1\\rangle$.</li>\n</ol>\n<p><strong>Output:</strong> <code>true</code> if the qubit was in the $|A\\rangle$ state, or <code>false</code> if it was in the $|B\\rangle$ state. The state of the qubit at the end of the operation does not matter.</p>\n<details>\n <summary><strong>Need a hint?</strong></summary>\n <p>An $R_x$ rotation can be used to go from the computational basis $\\{ \\ket 0, \\ket 1 \\}$ to the $\\{ \\ket{A}, \\ket{B} \\}$ basis and vice versa.</p>\n</details>\n",
|
|
1268
|
+
"asMarkdown": "**Inputs:**\n\n1. Angle $\\alpha$, in radians, represented as a `Double`.\n2. A qubit which is guaranteed to be in either the $|A\\rangle$ or the $|B\\rangle$ state, where $|A\\rangle = \\cos \\alpha |0\\rangle - i \\sin \\alpha |1\\rangle$ and $|B\\rangle = - i \\sin \\alpha |0\\rangle + \\cos \\alpha |1\\rangle$.\n\n**Output:** `true` if the qubit was in the $|A\\rangle$ state, or `false` if it was in the $|B\\rangle$ state. The state of the qubit at the end of the operation does not matter.\n\n<details>\n <summary><strong>Need a hint?</strong></summary>\n <p>An $R_x$ rotation can be used to go from the computational basis $\\{ \\ket 0, \\ket 1 \\}$ to the $\\{ \\ket{A}, \\ket{B} \\}$ basis and vice versa.</p>\n</details>\n"
|
|
1269
|
+
},
|
|
1270
|
+
"sourceIds": [
|
|
1271
|
+
"KatasLibrary.qs",
|
|
1272
|
+
"single_qubit_measurements__common.qs",
|
|
1273
|
+
"single_qubit_measurements__distinguish_orthogonal_states_2__verification.qs"
|
|
1274
|
+
],
|
|
1275
|
+
"placeholderCode": "namespace Kata {\n\n operation IsQubitA(alpha : Double, q : Qubit) : Bool {\n // Implement your solution here...\n\n return false;\n }\n\n}\n",
|
|
1276
|
+
"explainedSolution": {
|
|
1277
|
+
"type": "explained-solution",
|
|
1278
|
+
"items": [
|
|
1279
|
+
{
|
|
1280
|
+
"type": "text-content",
|
|
1281
|
+
"asHtml": "<p>We can distinguish between the states $\\ket{A}$ and $\\ket B$ if we implement a measurement in the ${ \\ket{A}, \\ket{B}}$ basis.</p>\n<p>We can notice that the $R_x$ rotation gate with $\\theta = 2 \\alpha$ is an appropriate transformation which maps the $\\ket 0 $ state to the $\\ket A$ state, and the $\\ket 1$ state to the $\\ket B$ state:</p>\n<p>$$R_x(\\theta) \\ket 0 = \\cos \\alpha \\ket 0 -i \\sin \\alpha \\ket 1 = \\ket {A},$$\n$$R_x(\\theta) \\ket 1 = -i \\sin \\alpha \\ket 0 + \\cos \\alpha \\ket 1 = \\ket{B}.$$</p>\n<p>Thus, the inverse transformation $R_x(-\\theta)$ maps the $A/B$ basis to the $0/1$ basis.</p>\n<p>Therefore, if we apply $R_x(-\\theta)$ to the qubit and measure it using <code>M</code>, a measurement result of <code>Zero</code> will correspond to the qubit's original state being $\\ket{A}$, while a result of <code>One</code> will correspond to the qubit's original state being $\\ket B$.</p>\n",
|
|
1282
|
+
"asMarkdown": "\nWe can distinguish between the states $\\ket{A}$ and $\\ket B$ if we implement a measurement in the $\\{ \\ket{A}, \\ket{B}\\}$ basis.\n\nWe can notice that the $R_x$ rotation gate with $\\theta = 2 \\alpha$ is an appropriate transformation which maps the $\\ket 0 $ state to the $\\ket A$ state, and the $\\ket 1$ state to the $\\ket B$ state:\n\n$$R_x(\\theta) \\ket 0 = \\cos \\alpha \\ket 0 -i \\sin \\alpha \\ket 1 = \\ket {A},$$\n$$R_x(\\theta) \\ket 1 = -i \\sin \\alpha \\ket 0 + \\cos \\alpha \\ket 1 = \\ket{B}.$$\n\nThus, the inverse transformation $R_x(-\\theta)$ maps the $A/B$ basis to the $0/1$ basis.\n\nTherefore, if we apply $R_x(-\\theta)$ to the qubit and measure it using `M`, a measurement result of `Zero` will correspond to the qubit's original state being $\\ket{A}$, while a result of `One` will correspond to the qubit's original state being $\\ket B$."
|
|
1283
|
+
},
|
|
1284
|
+
{
|
|
1285
|
+
"type": "solution",
|
|
1286
|
+
"id": "single_qubit_measurements__distinguish_orthogonal_states_2_solution",
|
|
1287
|
+
"code": "namespace Kata {\n\n operation IsQubitA(alpha: Double, q: Qubit): Bool { \n Rx(-2.0 * alpha, q);\n return M(q) == Zero;\n }\n\n}\n"
|
|
1288
|
+
}
|
|
1289
|
+
]
|
|
1290
|
+
}
|
|
1291
|
+
},
|
|
1292
|
+
{
|
|
1293
|
+
"type": "exercise",
|
|
1294
|
+
"id": "single_qubit_measurements__a_b_basis_measurements",
|
|
1295
|
+
"title": "Measurement In The |A〉, |B〉 Basis",
|
|
1296
|
+
"description": {
|
|
1297
|
+
"type": "text-content",
|
|
1298
|
+
"asHtml": "<p><strong>Inputs:</strong></p>\n<ol>\n<li>Angle $\\alpha$, in radians, represented as a <code>Double</code>.</li>\n<li>A qubit in some unknown state.</li>\n</ol>\n<p><strong>Output:</strong> Implement a measurement in the ${\\ket A, \\ket B}$ basis. Same as in the previous exercise, $|A\\rangle = \\cos \\alpha |0\\rangle - i \\sin \\alpha |1\\rangle$ and $|B\\rangle = - i \\sin \\alpha |0\\rangle + \\cos \\alpha |1\\rangle$. Return <code>Zero</code> if the measurement outcome is $A$, and <code>One</code> if the outcome is $B$.\nThe state of the qubit after the measurement should correspond to the measurement result.</p>\n<details>\n <summary><strong>Need a hint?</strong></summary>\n <p>An $R_x$ rotation can be used to go from the computational basis $\\{ \\ket 0, \\ket 1 \\}$ to the $\\{ \\ket{A}, \\ket{B} \\}$ basis and vice versa.</p>\n</details>\n",
|
|
1299
|
+
"asMarkdown": "**Inputs:**\n\n1. Angle $\\alpha$, in radians, represented as a `Double`.\n1. A qubit in some unknown state.\n\n**Output:** Implement a measurement in the $\\{\\ket A, \\ket B\\}$ basis. Same as in the previous exercise, $|A\\rangle = \\cos \\alpha |0\\rangle - i \\sin \\alpha |1\\rangle$ and $|B\\rangle = - i \\sin \\alpha |0\\rangle + \\cos \\alpha |1\\rangle$. Return `Zero` if the measurement outcome is $A$, and `One` if the outcome is $B$.\nThe state of the qubit after the measurement should correspond to the measurement result.\n\n<details>\n <summary><strong>Need a hint?</strong></summary>\n <p>An $R_x$ rotation can be used to go from the computational basis $\\{ \\ket 0, \\ket 1 \\}$ to the $\\{ \\ket{A}, \\ket{B} \\}$ basis and vice versa.</p>\n</details>\n"
|
|
1300
|
+
},
|
|
1301
|
+
"sourceIds": [
|
|
1302
|
+
"KatasLibrary.qs",
|
|
1303
|
+
"single_qubit_measurements__common.qs",
|
|
1304
|
+
"single_qubit_measurements__a_b_basis_measurements__verification.qs"
|
|
1305
|
+
],
|
|
1306
|
+
"placeholderCode": "namespace Kata {\n\n operation MeasureInABBasis(alpha : Double, q : Qubit) : Result {\n // Implement your solution here...\n\n return Zero;\n }\n\n}\n",
|
|
1307
|
+
"explainedSolution": {
|
|
1308
|
+
"type": "explained-solution",
|
|
1309
|
+
"items": [
|
|
1310
|
+
{
|
|
1311
|
+
"type": "text-content",
|
|
1312
|
+
"asHtml": "<p>For this problem, we follow the procedure given in the "Measurements in Arbitrary Orthogonal Bases" section of the Kata.\nAs noted in the solution of the "Distinguishing Orthogonal States: 2" exercise, the gate $R_x(-\\theta)$, with $\\theta = 2\\alpha$ transforms the $\\ket A/\\ket B$ states to the $\\ket 0/\\ket 1$ states:\n$$R_x(-\\theta) \\ket A = \\ket 0,$$\n$$R_x(-\\theta) \\ket B = \\ket 1.$$\nHence, we first apply $R_x(-\\theta)$ to the qubit. Next, we measure in the computational basis using the <code>M</code> operation.\nIf the <code>M</code> operation returned <code>Zero</code>, we get measurement outcome $A$, and if it returned <code>One</code>, we get measurement outcome $B$.</p>\n<p>After the measurement, we apply the inverse of the $R_x(-\\theta)$ gate, which is the $R_x(\\theta)$ gate.\nThe final rotation ensures that the state of the qubit is in the state corresponding to the measurement outcome.</p>\n",
|
|
1313
|
+
"asMarkdown": "\nFor this problem, we follow the procedure given in the \"Measurements in Arbitrary Orthogonal Bases\" section of the Kata.\nAs noted in the solution of the \"Distinguishing Orthogonal States: 2\" exercise, the gate $R_x(-\\theta)$, with $\\theta = 2\\alpha$ transforms the $\\ket A/\\ket B$ states to the $\\ket 0/\\ket 1$ states:\n$$R_x(-\\theta) \\ket A = \\ket 0,$$\n$$R_x(-\\theta) \\ket B = \\ket 1.$$\nHence, we first apply $R_x(-\\theta)$ to the qubit. Next, we measure in the computational basis using the `M` operation.\nIf the `M` operation returned `Zero`, we get measurement outcome $A$, and if it returned `One`, we get measurement outcome $B$.\n\nAfter the measurement, we apply the inverse of the $R_x(-\\theta)$ gate, which is the $R_x(\\theta)$ gate.\nThe final rotation ensures that the state of the qubit is in the state corresponding to the measurement outcome."
|
|
1314
|
+
},
|
|
1315
|
+
{
|
|
1316
|
+
"type": "solution",
|
|
1317
|
+
"id": "single_qubit_measurements__a_b_basis_measurements_solution",
|
|
1318
|
+
"code": "namespace Kata {\n\n operation MeasureInABBasis(alpha: Double, q: Qubit): Result {\n Rx(-2.0 * alpha, q);\n let measurementResult = M(q);\n Rx(2.0 * alpha, q);\n return measurementResult;\n }\n\n}\n"
|
|
1319
|
+
}
|
|
1320
|
+
]
|
|
1321
|
+
}
|
|
1322
|
+
},
|
|
1323
|
+
{
|
|
1324
|
+
"type": "lesson",
|
|
1325
|
+
"id": "single_qubit_measurements__conclusion",
|
|
1326
|
+
"title": "Conclusion",
|
|
1327
|
+
"items": [
|
|
1328
|
+
{
|
|
1329
|
+
"type": "text-content",
|
|
1330
|
+
"asHtml": "<p>Congratulations! In this kata you learned how to apply measurements on single-qubit systems. Here are a few key concepts to keep in mind:</p>\n<ul>\n<li>Measurements are always done in an orthogonal basis. By default, we choose the computational basis $\\lbrace \\ket{0}, \\ket{1} \\rbrace$.</li>\n<li>Measurements are represented as projector operators, which are matrices.</li>\n<li>Unlike quantum gates, measurements are neither unitary nor reversible. When we measure a qubit, the state of the qubit collapses to one of the basis states, and the initial state is lost. </li>\n<li>In Q#, you can implement measurements in the computational basis using the <code>M</code> operation, and in the Pauli basis using the <code>Measure</code> operation.</li>\n</ul>\n<p>Next, you will learn about measurements in multi-qubit systems in the "Measurements in Multi-Qubit Systems" kata.</p>\n",
|
|
1331
|
+
"asMarkdown": "\nCongratulations! In this kata you learned how to apply measurements on single-qubit systems. Here are a few key concepts to keep in mind:\n* Measurements are always done in an orthogonal basis. By default, we choose the computational basis $\\lbrace \\ket{0}, \\ket{1} \\rbrace$.\n* Measurements are represented as projector operators, which are matrices.\n* Unlike quantum gates, measurements are neither unitary nor reversible. When we measure a qubit, the state of the qubit collapses to one of the basis states, and the initial state is lost. \n* In Q#, you can implement measurements in the computational basis using the `M` operation, and in the Pauli basis using the `Measure` operation. \n\nNext, you will learn about measurements in multi-qubit systems in the \"Measurements in Multi-Qubit Systems\" kata."
|
|
1332
|
+
}
|
|
1333
|
+
]
|
|
1334
|
+
}
|
|
1335
|
+
]
|
|
1336
|
+
},
|
|
1337
|
+
{
|
|
1338
|
+
"id": "multi_qubit_measurements",
|
|
1339
|
+
"title": "Measurements in Multi-Qubit Systems",
|
|
1340
|
+
"sections": [
|
|
1341
|
+
{
|
|
1342
|
+
"type": "lesson",
|
|
1343
|
+
"id": "multi_qubit_measurements__overview",
|
|
1344
|
+
"title": "Overview",
|
|
1345
|
+
"items": [
|
|
1346
|
+
{
|
|
1347
|
+
"type": "text-content",
|
|
1348
|
+
"asHtml": "<p>In the previous kata, we discussed the concept of measurements done on single-qubit systems.\nBuilding upon those ideas, this kata will introduce you to measurements done on multi-qubit systems, and how to implement such measurements in Q#.\nThis will include measuring a single qubit in a multi-qubit system, as well as measuring multiple qubits simultaneously.</p>\n<p><strong>This kata covers the following topics:</strong></p>\n<ul>\n<li>Measuring a single qubit in a multi-qubit system</li>\n<li>Measuring multiple qubits simultaneously</li>\n<li>How to implement such measurements in Q#</li>\n</ul>\n<p><strong>What you should know to start working on this kata:</strong></p>\n<ul>\n<li>Basic linear algebra</li>\n<li>Single and multi-qubit systems</li>\n<li>Single and multi-qubit gates</li>\n<li>Single-qubit system measurements</li>\n</ul>\n<p>$\\renewcommand{\\ket}[1]{\\left\\lvert#1\\right\\rangle}$\n$\\renewcommand{\\bra}[1]{\\left\\langle#1\\right\\rvert}$</p>\n",
|
|
1349
|
+
"asMarkdown": "\nIn the previous kata, we discussed the concept of measurements done on single-qubit systems.\nBuilding upon those ideas, this kata will introduce you to measurements done on multi-qubit systems, and how to implement such measurements in Q#.\nThis will include measuring a single qubit in a multi-qubit system, as well as measuring multiple qubits simultaneously.\n\n**This kata covers the following topics:**\n\n- Measuring a single qubit in a multi-qubit system\n- Measuring multiple qubits simultaneously\n- How to implement such measurements in Q#\n\n**What you should know to start working on this kata:**\n\n- Basic linear algebra\n- Single and multi-qubit systems\n- Single and multi-qubit gates\n- Single-qubit system measurements\n\n$\\renewcommand{\\ket}[1]{\\left\\lvert#1\\right\\rangle}$\n$\\renewcommand{\\bra}[1]{\\left\\langle#1\\right\\rvert}$"
|
|
1350
|
+
}
|
|
1351
|
+
]
|
|
1352
|
+
},
|
|
1353
|
+
{
|
|
1354
|
+
"type": "lesson",
|
|
1355
|
+
"id": "multi_qubit_measurements__types_of_measurements",
|
|
1356
|
+
"title": "Types of Measurements",
|
|
1357
|
+
"items": [
|
|
1358
|
+
{
|
|
1359
|
+
"type": "text-content",
|
|
1360
|
+
"asHtml": "<p>There are several types of measurements you can perform on an $n$-qubit system ($n>1$):</p>\n<ul>\n<li>Measuring all the qubits simultaneously in an orthogonal basis ($2^n$ possible outcomes). As we shall see below, this is a direct generalization of orthogonal basis measurements done in single-qubit systems introduced in the previous kata.</li>\n<li>Partial measurement: measuring $m$ qubits out of $n$, for $m<n$ ($2^m$ possible outcomes). Partial measurements involve a partial collapse of the system's wave function, since only some of the qubits are measured.</li>\n<li>Joint measurement: measuring a joint property of all $n$ qubits ($2$ possible outcomes).</li>\n</ul>\n<p>We will discuss these concepts in the same order as in the list above.</p>\n<h2 id=\"full-measurements-measurements-in-multi-qubit-bases\">Full Measurements: Measurements in Multi-Qubit Bases</h2>\n<p>Consider a system consisting of $n\\geq1$ qubits. The wave function of such a system belongs to a vector space of dimension $2^n$. Thus, the vector space is spanned by an orthogonal basis, such as the computational basis which consists of the vectors $|0\\dotsc0\\rangle, \\dotsc, |1\\dotsc 1\\rangle$. For generality, we consider an arbitrary orthonormal basis, which we denote by ${ |b_0\\rangle, |b_1\\rangle, \\dotsc, |b_{2^n-1}\\rangle }$.</p>\n<p>Then, the state $|\\psi\\rangle$ of the multi-qubit system can be expressed as a linear combination of the $2^n$ basis vectors $|b_i\\rangle$. That is, there exist complex numbers $c_0,c_1,\\dotsc, c_{2^n-1}$ such that</p>\n<p>$$\n|\\psi\\rangle = \\sum_{i=0}^{2^n-1} c_i|b_i\\rangle \\equiv \\begin{pmatrix} c_0 \\\\ c_1 \\\\ \\vdots \\\\ c_{2^n-1} \\end{pmatrix}\n$$</p>\n<p>In line with the usual convention, we choose the wave function to be normalized, so that $|c_0|^2 + \\dotsc + |c_{2^n-1}|^2 =1$. Then, a quantum measurement in the ${ |b_0\\rangle, |b_1\\rangle, \\dotsc, |b_{2^n-1}\\rangle }$ basis satisfies the following rules:</p>\n<ul>\n<li>The measurement outcome $b_i$ occurs with probability $|c_i|^2$.</li>\n<li>Whenever the measurement outcome is $b_i$, the wave function collapses to the state $|b_i\\rangle$. That is, the post-measurement state of the system is equal to $|b_i\\rangle$.</li>\n</ul>\n<p>This can be summarized in the following table:</p>\n<table>\n <tr>\n <th>Measurement outcome</th>\n <th>Probability of outcome</th>\n <th>State after measurement</th>\n </tr>\n <tr>\n <td>$b_i$</td>\n <td>$|c_i|^2$</td>\n <td>$\\ket{b_i}$</td>\n </tr>\n</table>\n\n<blockquote>\n<p>Similar to measurements in single-qubit systems, the assumption of normalization of the original wave function is required in order to ensure that the sum of all the outcome probabilities is 1.</p>\n</blockquote>\n<h2 id=\"multi-qubit-measurement-outcome-probabilities-i\">Multi-Qubit Measurement Outcome Probabilities I</h2>\n<p>Suppose that a two-qubit system is known to be in the following state:\n$$\\ket \\psi = \\frac{1}{3}\\ket {00} + \\frac{2}{3} \\ket {01} + \\frac{2}{3}\\ket {11}$$</p>\n<p>If all the qubits are measured simultaneously in the computational basis, what are the outcome probabilities?</p>\n<p>The wave function $|\\psi\\rangle$ is normalized, since $\\left(\\frac{1}{3}\\right)^2 + \\left(\\frac{2}{3}\\right)^2 + \\left(\\frac{2}{3}\\right)^2 = 1$. Hence, the probabilities of measuring each of the computational basis states is simply the square of the absolute value of the corresponding coefficients. That is, the probabilities of measuring $00$, $01$ and $11$ are $\\frac{1}{9}$, $\\frac{4}{9}$ and $\\frac{4}{9}$, respectively, and the probability of measuring the basis state $10$ that is not part of the superposition is $0$:</p>\n<table>\n <tr>\n <th>Measurement outcome</th>\n <th>Probability of outcome</th>\n </tr>\n <tr>\n <td>$00$</td>\n <td>$\\left( \\frac{1}{3}\\right)^2 = \\frac{1}{9}$</td>\n </tr> \n <tr>\n <td>$01$</td>\n <td>$\\left( \\frac{2}{3}\\right)^2 = \\frac{4}{9}$</td>\n </tr> \n <tr>\n <td>$10$</td>\n <td>$\\left( 0\\right)^2 = 0$</td>\n </tr> \n <tr>\n <td>$11$</td>\n <td>$\\left( \\frac{2}{3}\\right)^2 = \\frac{4}{9}$</td>\n </tr> \n</table>\n</details>\n\n<h2 id=\"multi-qubit-measurement-outcome-probabilities-ii\">Multi-Qubit Measurement Outcome Probabilities II</h2>\n<p>Suppose that a two-qubit system is known to be in the following state:\n$$\\ket \\psi = \\frac{2}{3}\\ket {00} + \\frac{1}{3} \\ket {01} + \\frac{2}{3}\\ket {11}$$</p>\n<p>If all the qubits are measured simultaneously in the Pauli X basis, that is, in the ${ \\ket{++}, \\ket{+-}, \\ket{-+}, \\ket{--}}$ basis, what are the outcome probabilities?</p>\n<h3 id=\"analytical-solution\">Analytical Solution</h3>\n<p>Using the expressions $|0\\rangle = \\frac{1}{\\sqrt{2}} \\big( |+\\rangle + |-\\rangle \\big)$ and $|1\\rangle = \\frac{1}{\\sqrt{2}} \\big( |+\\rangle - |-\\rangle \\big)$, we first express $|\\psi\\rangle$ in the Pauli X basis. This gives us\n$$\\ket \\psi = \\frac{2}{3}\\ket {00} + \\frac{1}{3} \\ket {01} + \\frac{2}{3}\\ket {11}$$</p>\n<p>$$= \\frac{2}{3} \\big[ \\frac{1}{\\sqrt{2}}\\big(\\ket{+} + \\ket{-}\\big) \\otimes \\frac{1}{\\sqrt{2}} \\big(\\ket{+} + \\ket{-}\\big) \\big] + \\frac{1}{3} \\big[ \\frac{1}{\\sqrt{2}}\\big(\\ket{+} + \\ket{-}\\big) \\otimes \\frac{1}{\\sqrt{2}} \\big(\\ket{+} - \\ket{-}\\big) \\big] + \\frac{2}{3} \\big[ \\frac{1}{\\sqrt{2}}\\big(\\ket{+} - \\ket{-}\\big) \\otimes \\frac{1}{\\sqrt{2}} \\big(\\ket{+} - \\ket{-}\\big) \\big]$$</p>\n<p>$$= \\frac{1}{3} \\big[ \\big(\\ket{+} + \\ket{-}\\big) \\otimes \\big(\\ket{+} + \\ket{-}\\big) \\big] + \\frac{1}{6} \\big[ \\big(\\ket{+} + \\ket{-}\\big) \\otimes \\big(\\ket{+} - \\ket{-}\\big) \\big] + \\frac{1}{3} \\big[ \\big(\\ket{+} - \\ket{-}\\big) \\otimes \\big(\\ket{+} - \\ket{-}\\big) \\big]$$</p>\n<p>$$= \\frac{1}{3} \\big[ \\ket{++} + \\ket{+-} + \\ket{-+} + \\ket{--} \\big] + \\frac{1}{6} \\big[ \\ket{++} - \\ket{+-} + \\ket{-+} - \\ket{--} \\big] + \\frac{1}{3} \\big[ \\ket{++} - \\ket{+-} - \\ket{-+} + \\ket{--} \\big]$$</p>\n<p>$$= (\\frac{1}{3} + \\frac{1}{6} + \\frac{1}{3})\\ket{++} + (\\frac{1}{3} - \\frac{1}{6} - \\frac{1}{3})\\ket{+-} + (\\frac{1}{3} + \\frac{1}{6} - \\frac{1}{3})\\ket{-+} + (\\frac{1}{3} - \\frac{1}{6} + \\frac{1}{3})\\ket{--}$$</p>\n<p>$$= \\frac{5}{6}\\ket{++} - \\frac{1}{6}\\ket{+-} + \\frac{1}{6}\\ket{-+} + \\frac{1}{2}\\ket{--}$$</p>\n<p>After this, the probabilities of measuring each of the four basis vectors is given by the square of the absolute value of its amplitude in the superposition:</p>\n<table>\n <tr>\n <th>Measurement outcome</th>\n <th>Probability of outcome</th>\n </tr>\n <tr>\n <td>$++$</td>\n <td>$\\left( \\frac{5}{6}\\right)^2 = \\frac{25}{36}$</td>\n </tr> \n <tr>\n <td>$+-$</td>\n <td>$\\left( -\\frac{1}{6}\\right)^2 = \\frac{1}{36}$</td>\n </tr> \n <tr>\n <td>$-+$</td>\n <td>$\\left( \\frac{1}{6}\\right)^2 = \\frac{1}{36}$</td>\n </tr>\n <tr>\n <td>$--$</td>\n <td>$\\left( \\frac{1}{2}\\right)^2 = \\frac{1}{4}$</td>\n </tr> \n</table>\n\n<h3 id=\"code-based-solution\">Code-Based Solution</h3>\n<p>We can also use Q# to solve this problem. It can be achieved in three steps:</p>\n<ol>\n<li>Prepare the state $\\ket \\psi$.</li>\n<li>Apply a transformation that maps the 2-qubit Pauli X basis into the 2-qubit computational basis. This transformation just applies a Hadamard gate to each of the qubits.</li>\n<li>View probabilities of each basis state with the <code>DumpMachine</code> function. Thanks to the previous step, the following state equivalence holds:</li>\n</ol>\n<table>\n <tr>\n <th>Before basis transformation</th>\n <th>After basis transformation</th>\n </tr>\n <tr>\n <td>$\\ket {++}$</td>\n <td>$\\ket {00}$</td>\n </tr> \n <tr>\n <td>$\\ket {+-}$</td>\n <td>$\\ket {01}$</td>\n </tr> \n <tr>\n <td>$\\ket {-+}$</td>\n <td>$\\ket {10}$</td>\n </tr>\n <tr>\n <td>$\\ket {--}$</td>\n <td>$\\ket {11}$</td>\n </tr> \n</table>\n\n<p>The amplitudes of the computational basis states after the transformation are the same as the amplitudes of the basis states of the Pauli X basis before the transformation!</p>\n<blockquote>\n<p>To implement the first step, we can represent $\\ket \\psi$ as<br>$$\\frac 2 3 \\ket {00} + {\\big (} \\frac 1 {\\sqrt 5} \\ket {0} + \\frac 2 {\\sqrt 5} \\ket {1} {\\big )} \\frac {\\sqrt 5} 3 \\ket {1}$$\nThis representation tells us how we should rotate individual qubits.</p>\n<p>Notice that we start by rotating the second qubit, as this gives a simpler implementation. If we started by rotating the first qubit, we would need to use a CNOT gate and a controlled $R_y$ gate to achieve the same result.</p>\n</blockquote>\n",
|
|
1361
|
+
"asMarkdown": "\nThere are several types of measurements you can perform on an $n$-qubit system ($n>1$):\n\n- Measuring all the qubits simultaneously in an orthogonal basis ($2^n$ possible outcomes). As we shall see below, this is a direct generalization of orthogonal basis measurements done in single-qubit systems introduced in the previous kata.\n- Partial measurement: measuring $m$ qubits out of $n$, for $m<n$ ($2^m$ possible outcomes). Partial measurements involve a partial collapse of the system's wave function, since only some of the qubits are measured.\n- Joint measurement: measuring a joint property of all $n$ qubits ($2$ possible outcomes).\n\nWe will discuss these concepts in the same order as in the list above.\n\n## Full Measurements: Measurements in Multi-Qubit Bases\n\nConsider a system consisting of $n\\geq1$ qubits. The wave function of such a system belongs to a vector space of dimension $2^n$. Thus, the vector space is spanned by an orthogonal basis, such as the computational basis which consists of the vectors $|0\\dotsc0\\rangle, \\dotsc, |1\\dotsc 1\\rangle$. For generality, we consider an arbitrary orthonormal basis, which we denote by $\\{ |b_0\\rangle, |b_1\\rangle, \\dotsc, |b_{2^n-1}\\rangle \\}$.\n\nThen, the state $|\\psi\\rangle$ of the multi-qubit system can be expressed as a linear combination of the $2^n$ basis vectors $|b_i\\rangle$. That is, there exist complex numbers $c_0,c_1,\\dotsc, c_{2^n-1}$ such that\n\n$$\n|\\psi\\rangle = \\sum_{i=0}^{2^n-1} c_i|b_i\\rangle \\equiv \\begin{pmatrix} c_0 \\\\\\ c_1 \\\\\\ \\vdots \\\\\\ c_{2^n-1} \\end{pmatrix}\n$$\n\nIn line with the usual convention, we choose the wave function to be normalized, so that $|c_0|^2 + \\dotsc + |c_{2^n-1}|^2 =1$. Then, a quantum measurement in the $\\{ |b_0\\rangle, |b_1\\rangle, \\dotsc, |b_{2^n-1}\\rangle \\}$ basis satisfies the following rules:\n\n- The measurement outcome $b_i$ occurs with probability $|c_i|^2$.\n- Whenever the measurement outcome is $b_i$, the wave function collapses to the state $|b_i\\rangle$. That is, the post-measurement state of the system is equal to $|b_i\\rangle$.\n\nThis can be summarized in the following table:\n\n<table>\n <tr>\n <th>Measurement outcome</th>\n <th>Probability of outcome</th>\n <th>State after measurement</th>\n </tr>\n <tr>\n <td>$b_i$</td>\n <td>$|c_i|^2$</td>\n <td>$\\ket{b_i}$</td>\n </tr>\n</table>\n\n> Similar to measurements in single-qubit systems, the assumption of normalization of the original wave function is required in order to ensure that the sum of all the outcome probabilities is 1.\n\n## Multi-Qubit Measurement Outcome Probabilities I\n\nSuppose that a two-qubit system is known to be in the following state:\n$$\\ket \\psi = \\frac{1}{3}\\ket {00} + \\frac{2}{3} \\ket {01} + \\frac{2}{3}\\ket {11}$$\n\nIf all the qubits are measured simultaneously in the computational basis, what are the outcome probabilities?\n\nThe wave function $|\\psi\\rangle$ is normalized, since $\\left(\\frac{1}{3}\\right)^2 + \\left(\\frac{2}{3}\\right)^2 + \\left(\\frac{2}{3}\\right)^2 = 1$. Hence, the probabilities of measuring each of the computational basis states is simply the square of the absolute value of the corresponding coefficients. That is, the probabilities of measuring $00$, $01$ and $11$ are $\\frac{1}{9}$, $\\frac{4}{9}$ and $\\frac{4}{9}$, respectively, and the probability of measuring the basis state $10$ that is not part of the superposition is $0$:\n\n<table>\n <tr>\n <th>Measurement outcome</th>\n <th>Probability of outcome</th>\n </tr>\n <tr>\n <td>$00$</td>\n <td>$\\left( \\frac{1}{3}\\right)^2 = \\frac{1}{9}$</td>\n </tr> \n <tr>\n <td>$01$</td>\n <td>$\\left( \\frac{2}{3}\\right)^2 = \\frac{4}{9}$</td>\n </tr> \n <tr>\n <td>$10$</td>\n <td>$\\left( 0\\right)^2 = 0$</td>\n </tr> \n <tr>\n <td>$11$</td>\n <td>$\\left( \\frac{2}{3}\\right)^2 = \\frac{4}{9}$</td>\n </tr> \n</table>\n</details>\n\n## Multi-Qubit Measurement Outcome Probabilities II\n\nSuppose that a two-qubit system is known to be in the following state:\n$$\\ket \\psi = \\frac{2}{3}\\ket {00} + \\frac{1}{3} \\ket {01} + \\frac{2}{3}\\ket {11}$$\n\nIf all the qubits are measured simultaneously in the Pauli X basis, that is, in the $\\{ \\ket{++}, \\ket{+-}, \\ket{-+}, \\ket{--}\\}$ basis, what are the outcome probabilities?\n\n### Analytical Solution\n\nUsing the expressions $|0\\rangle = \\frac{1}{\\sqrt{2}} \\big( |+\\rangle + |-\\rangle \\big)$ and $|1\\rangle = \\frac{1}{\\sqrt{2}} \\big( |+\\rangle - |-\\rangle \\big)$, we first express $|\\psi\\rangle$ in the Pauli X basis. This gives us\n$$\\ket \\psi = \\frac{2}{3}\\ket {00} + \\frac{1}{3} \\ket {01} + \\frac{2}{3}\\ket {11}$$\n\n$$= \\frac{2}{3} \\big[ \\frac{1}{\\sqrt{2}}\\big(\\ket{+} + \\ket{-}\\big) \\otimes \\frac{1}{\\sqrt{2}} \\big(\\ket{+} + \\ket{-}\\big) \\big] + \\frac{1}{3} \\big[ \\frac{1}{\\sqrt{2}}\\big(\\ket{+} + \\ket{-}\\big) \\otimes \\frac{1}{\\sqrt{2}} \\big(\\ket{+} - \\ket{-}\\big) \\big] + \\frac{2}{3} \\big[ \\frac{1}{\\sqrt{2}}\\big(\\ket{+} - \\ket{-}\\big) \\otimes \\frac{1}{\\sqrt{2}} \\big(\\ket{+} - \\ket{-}\\big) \\big]$$\n\n$$= \\frac{1}{3} \\big[ \\big(\\ket{+} + \\ket{-}\\big) \\otimes \\big(\\ket{+} + \\ket{-}\\big) \\big] + \\frac{1}{6} \\big[ \\big(\\ket{+} + \\ket{-}\\big) \\otimes \\big(\\ket{+} - \\ket{-}\\big) \\big] + \\frac{1}{3} \\big[ \\big(\\ket{+} - \\ket{-}\\big) \\otimes \\big(\\ket{+} - \\ket{-}\\big) \\big]$$\n\n$$= \\frac{1}{3} \\big[ \\ket{++} + \\ket{+-} + \\ket{-+} + \\ket{--} \\big] + \\frac{1}{6} \\big[ \\ket{++} - \\ket{+-} + \\ket{-+} - \\ket{--} \\big] + \\frac{1}{3} \\big[ \\ket{++} - \\ket{+-} - \\ket{-+} + \\ket{--} \\big]$$\n\n$$= (\\frac{1}{3} + \\frac{1}{6} + \\frac{1}{3})\\ket{++} + (\\frac{1}{3} - \\frac{1}{6} - \\frac{1}{3})\\ket{+-} + (\\frac{1}{3} + \\frac{1}{6} - \\frac{1}{3})\\ket{-+} + (\\frac{1}{3} - \\frac{1}{6} + \\frac{1}{3})\\ket{--}$$\n\n$$= \\frac{5}{6}\\ket{++} - \\frac{1}{6}\\ket{+-} + \\frac{1}{6}\\ket{-+} + \\frac{1}{2}\\ket{--}$$\n\nAfter this, the probabilities of measuring each of the four basis vectors is given by the square of the absolute value of its amplitude in the superposition:\n<table>\n <tr>\n <th>Measurement outcome</th>\n <th>Probability of outcome</th>\n </tr>\n <tr>\n <td>$++$</td>\n <td>$\\left( \\frac{5}{6}\\right)^2 = \\frac{25}{36}$</td>\n </tr> \n <tr>\n <td>$+-$</td>\n <td>$\\left( -\\frac{1}{6}\\right)^2 = \\frac{1}{36}$</td>\n </tr> \n <tr>\n <td>$-+$</td>\n <td>$\\left( \\frac{1}{6}\\right)^2 = \\frac{1}{36}$</td>\n </tr>\n <tr>\n <td>$--$</td>\n <td>$\\left( \\frac{1}{2}\\right)^2 = \\frac{1}{4}$</td>\n </tr> \n</table>\n\n### Code-Based Solution\n\nWe can also use Q# to solve this problem. It can be achieved in three steps:\n1. Prepare the state $\\ket \\psi$.\n2. Apply a transformation that maps the 2-qubit Pauli X basis into the 2-qubit computational basis. This transformation just applies a Hadamard gate to each of the qubits.\n3. View probabilities of each basis state with the `DumpMachine` function. Thanks to the previous step, the following state equivalence holds:\n\n<table>\n <tr>\n <th>Before basis transformation</th>\n <th>After basis transformation</th>\n </tr>\n <tr>\n <td>$\\ket {++}$</td>\n <td>$\\ket {00}$</td>\n </tr> \n <tr>\n <td>$\\ket {+-}$</td>\n <td>$\\ket {01}$</td>\n </tr> \n <tr>\n <td>$\\ket {-+}$</td>\n <td>$\\ket {10}$</td>\n </tr>\n <tr>\n <td>$\\ket {--}$</td>\n <td>$\\ket {11}$</td>\n </tr> \n</table>\n\nThe amplitudes of the computational basis states after the transformation are the same as the amplitudes of the basis states of the Pauli X basis before the transformation!\n\n>To implement the first step, we can represent $\\ket \\psi$ as \n>$$\\frac 2 3 \\ket {00} + {\\big (} \\frac 1 {\\sqrt 5} \\ket {0} + \\frac 2 {\\sqrt 5} \\ket {1} {\\big )} \\frac {\\sqrt 5} 3 \\ket {1}$$\n>This representation tells us how we should rotate individual qubits.\n>\n>Notice that we start by rotating the second qubit, as this gives a simpler implementation. If we started by rotating the first qubit, we would need to use a CNOT gate and a controlled $R_y$ gate to achieve the same result."
|
|
1362
|
+
},
|
|
1363
|
+
{
|
|
1364
|
+
"type": "example",
|
|
1365
|
+
"id": "multi_qubit_measurements__multi_qubit_probabilities_2_example",
|
|
1366
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n\n operation SetInitialState(qs: Qubit[]): Unit is Adj + Ctl {\n // Next two lines set the second qubit into the desired state\n let second_bit_angle = 2.0 * ArcCos(2.0 / 3.0);\n Ry(second_bit_angle, qs[1]);\n\n // Next two lines set the first qubit into the desired state\n let first_bit_angle = 2.0 * ArcCos(1.0 / Sqrt(5.0));\n Controlled Ry([qs[1]], (first_bit_angle, qs[0]));\n }\n\n operation ChangeBasis(qs: Qubit[]): Unit is Adj + Ctl {\n H(qs[0]);\n H(qs[1]);\n }\n\n @EntryPoint()\n operation CalculateProbabilities(): Unit {\n // This allocates qubits for us to work with\n use qs = Qubit[2];\n\n SetInitialState(qs);\n\n // Check that we've prepared the state |𝜓⟩\n Message(\"The state of the system before the transformation:\");\n DumpMachine();\n\n ChangeBasis(qs);\n\n Message(\"Final state of the two-qubit system:\");\n DumpMachine();\n\n // This returns the qubit array into state |00❭\n ResetAll(qs);\n }\n\n}\n"
|
|
1367
|
+
},
|
|
1368
|
+
{
|
|
1369
|
+
"type": "text-content",
|
|
1370
|
+
"asHtml": "<h2 id=\"measuring-each-qubit-in-a-system-sequentially\">Measuring Each Qubit in a System Sequentially</h2>\n<p>As described in the previous sections, in theory it is possible to measure all the qubits in an $n$-qubit system simultaneously in an orthogonal basis. The post-measurement state of the qubits is then exactly one of the $2^n$ possible basis states.</p>\n<p>In practice, this is implemented by measuring all the qubits one after another. For example, if one wants to measure a two-qubit system in the computational basis, one can implement this by first measuring the first qubit in the computational basis to obtain $0$ or $1$, and then measuring the second qubit in the computational basis. This can result in one of the four possible outcomes: $00, 01, 10, 11$.</p>\n<p>This can be generalized to measurements in other bases, such as the 2-qubit Pauli X basis $\\ket{++}, \\ket{+-}, \\ket{-+}, \\ket{--}$, and the bases for larger numbers of qubits.</p>\n<blockquote>\n<p>Note that measurement of all qubits sequentially can only be done in orthogonal bases ${ \\ket{b_i}}$, such that each $\\ket{b_i}$ is a tensor product state. That is, each $\\ket{b_i}$ must be of the form $\\ket{v_0} \\otimes \\ket{v_1} \\dotsc \\otimes \\ket{v_{n-1}}$, with each $\\ket{v_j}$ being a single-qubit basis state.\nFor example, for the 2-qubit Pauli X basis $\\ket{++}, \\ket{+-}, \\ket{-+}, \\ket{--}$ each basis state is a tensor product of states $\\ket{+}$ and $\\ket{-}$, which form a single-qubit basis state.</p>\n<p>Measuring in orthogonal bases which contain states which are not tensor product states, such as the Bell basis, are trickier to implement, and require appropriate unitary rotations in addition to measuring all qubits one after another.\nWe will not discuss such measurements in this kata.</p>\n<p>If we restrict ourselves to measurements in tensor product states, the distinction between measuring all the qubits simultaneously versus one after another is not important for an ideal quantum computer: in terms of the outcomes and measurement probabilities, both are identical. Furthermore, as long as all the qubits are measured, the sequence in which they are measured is also inconsequential. These factors can be important in the case of real quantum computers with imperfect qubits, but we restrict the discussion to ideal systems in this kata.</p>\n</blockquote>\n",
|
|
1371
|
+
"asMarkdown": "\n## Measuring Each Qubit in a System Sequentially\n\nAs described in the previous sections, in theory it is possible to measure all the qubits in an $n$-qubit system simultaneously in an orthogonal basis. The post-measurement state of the qubits is then exactly one of the $2^n$ possible basis states.\n\nIn practice, this is implemented by measuring all the qubits one after another. For example, if one wants to measure a two-qubit system in the computational basis, one can implement this by first measuring the first qubit in the computational basis to obtain $0$ or $1$, and then measuring the second qubit in the computational basis. This can result in one of the four possible outcomes: $00, 01, 10, 11$.\n\nThis can be generalized to measurements in other bases, such as the 2-qubit Pauli X basis $\\ket{++}, \\ket{+-}, \\ket{-+}, \\ket{--}$, and the bases for larger numbers of qubits.\n\n> Note that measurement of all qubits sequentially can only be done in orthogonal bases $\\{ \\ket{b_i}\\}$, such that each $\\ket{b_i}$ is a tensor product state. That is, each $\\ket{b_i}$ must be of the form $\\ket{v_0} \\otimes \\ket{v_1} \\dotsc \\otimes \\ket{v_{n-1}}$, with each $\\ket{v_j}$ being a single-qubit basis state.\nFor example, for the 2-qubit Pauli X basis $\\ket{++}, \\ket{+-}, \\ket{-+}, \\ket{--}$ each basis state is a tensor product of states $\\ket{+}$ and $\\ket{-}$, which form a single-qubit basis state.\n>\n> Measuring in orthogonal bases which contain states which are not tensor product states, such as the Bell basis, are trickier to implement, and require appropriate unitary rotations in addition to measuring all qubits one after another.\n> We will not discuss such measurements in this kata.\n>\n> If we restrict ourselves to measurements in tensor product states, the distinction between measuring all the qubits simultaneously versus one after another is not important for an ideal quantum computer: in terms of the outcomes and measurement probabilities, both are identical. Furthermore, as long as all the qubits are measured, the sequence in which they are measured is also inconsequential. These factors can be important in the case of real quantum computers with imperfect qubits, but we restrict the discussion to ideal systems in this kata."
|
|
1372
|
+
}
|
|
1373
|
+
]
|
|
1374
|
+
},
|
|
1375
|
+
{
|
|
1376
|
+
"type": "lesson",
|
|
1377
|
+
"id": "multi_qubit_measurements__measurement_statistics",
|
|
1378
|
+
"title": "Measurement Statistics for Qubit-By-Qubit Full Measurement",
|
|
1379
|
+
"items": [
|
|
1380
|
+
{
|
|
1381
|
+
"type": "text-content",
|
|
1382
|
+
"asHtml": "<p>This demo illustrates the equivalence of the measurement probabilities for simultaneous measurement on all qubits, and measurements on each of the qubits executed one after another. Using the wave function from exercise 1 above as an example, we show that the measurement probabilities obtained using the <code>M</code> operation in Q# are the same as those expected theoretically for exercise 1.</p>\n<p>The simulated probabilities will be different for each run of <code>DemoBasisMeasurement</code>. The simulated and theoretical probabilities are not expected to be identical, since measurements are probabilistic. However, we expect the values to be similar, and the simulated probabilities to approach the theoretical probabilities as the parameter <code>numRuns</code> is increased.</p>\n",
|
|
1383
|
+
"asMarkdown": "\nThis demo illustrates the equivalence of the measurement probabilities for simultaneous measurement on all qubits, and measurements on each of the qubits executed one after another. Using the wave function from exercise 1 above as an example, we show that the measurement probabilities obtained using the `M` operation in Q# are the same as those expected theoretically for exercise 1.\n\nThe simulated probabilities will be different for each run of `DemoBasisMeasurement`. The simulated and theoretical probabilities are not expected to be identical, since measurements are probabilistic. However, we expect the values to be similar, and the simulated probabilities to approach the theoretical probabilities as the parameter `numRuns` is increased."
|
|
1384
|
+
},
|
|
1385
|
+
{
|
|
1386
|
+
"type": "example",
|
|
1387
|
+
"id": "multi_qubit_measurements__measuring_one_at_a_time",
|
|
1388
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation DemoBasisMeasurement() : Unit {\n let numRuns = 1000;\n\n // Define coefficients and obtain measurement probabilities for the\n // state |psi❭ = 0.33 |00❭ + 0.67 |01❭ + 0.67 |11❭\n // Use little endian format to encode basis states as integer indices.\n let coefficients = [0.333, 0.0, 0.667, 0.667];\n let expected_probabilities = [0.111, 0.0, 0.445, 0.445];\n\n // Set up counter array for measurements.\n mutable countArray = [0, 0, 0, 0];\n\n use qs = Qubit[2];\n for i in 1 .. numRuns {\n // Prepare the state from Exercise 1:\n PrepareEx1State(qs);\n if i == 1 {\n Message(\"The state |psi❭ of the system before measurement is:\");\n DumpMachine();\n }\n\n // Measure the first qubit, followed by the second qubit, and\n // convert the result to little endian integer\n let result = MeasureInteger(qs);\n\n // Update countArray\n set countArray w/= result <- countArray[result] + 1;\n }\n\n // Obtain simulated probability of measurement for each outcome\n mutable simulated_probabilities = [];\n for i in 0 .. 3 {\n set simulated_probabilities +=\n [IntAsDouble(countArray[i]) / IntAsDouble(numRuns)];\n }\n\n Message($\"Theoretical measurement probabilities are {expected_probabilities}\");\n Message($\"Simulated measurement probabilities are {simulated_probabilities}\");\n }\n\n operation PrepareEx1State(q: Qubit[]): Unit {\n Ry(-ArcCos(1.0/9.0), q[0]);\n within {\n S(q[1]);\n H(q[1]);\n } apply {\n Rz(ArcTan(0.5), q[1]);\n CNOT(q[0], q[1]);\n Rz(ArcTan(0.5)-PI(), q[1]);\n CNOT(q[0], q[1]);\n }\n }\n}"
|
|
1389
|
+
},
|
|
1390
|
+
{
|
|
1391
|
+
"type": "text-content",
|
|
1392
|
+
"asHtml": "<h2 id=\"using-full-measurements-to-identify-the-state-of-the-system\">Using Full Measurements to Identify the State of the System</h2>\n<p>Full measurements can also be used to identify the state of the system, if it is guaranteed to be in one of several possible orthogonal states.</p>\n",
|
|
1393
|
+
"asMarkdown": "\n## Using Full Measurements to Identify the State of the System\n\nFull measurements can also be used to identify the state of the system, if it is guaranteed to be in one of several possible orthogonal states."
|
|
1394
|
+
}
|
|
1395
|
+
]
|
|
1396
|
+
},
|
|
1397
|
+
{
|
|
1398
|
+
"type": "exercise",
|
|
1399
|
+
"id": "multi_qubit_measurements__full_measurements",
|
|
1400
|
+
"title": "Distinguish Four Basis States",
|
|
1401
|
+
"description": {
|
|
1402
|
+
"type": "text-content",
|
|
1403
|
+
"asHtml": "<p><strong>Input:</strong> Two qubits (stored in an array of length 2) which are guaranteed to be in one of the four basis states ($|00\\rangle$, $|01\\rangle$, $|10\\rangle$, or $|11\\rangle$).</p>\n<p><strong>Output:</strong></p>\n<ul>\n<li>0 if the qubits were in the $|00\\rangle$ state,</li>\n<li>1 if they were in the $|01\\rangle$ state, </li>\n<li>2 if they were in the $|10\\rangle$ state, </li>\n<li>3 if they were in the $|11\\rangle$ state.</li>\n</ul>\n<p>In this task and the subsequent ones the order of qubit states in task description matches the order of qubits in the array (i.e., $|10\\rangle$ state corresponds to <code>qs[0]</code> in state $|1\\rangle$ and <code>qs[1]</code> in state $|0\\rangle$).</p>\n<p>The state of the qubits at the end of the operation does not matter.</p>\n",
|
|
1404
|
+
"asMarkdown": "**Input:** Two qubits (stored in an array of length 2) which are guaranteed to be in one of the four basis states ($|00\\rangle$, $|01\\rangle$, $|10\\rangle$, or $|11\\rangle$).\n\n**Output:**\n\n* 0 if the qubits were in the $|00\\rangle$ state,\n* 1 if they were in the $|01\\rangle$ state, \n* 2 if they were in the $|10\\rangle$ state, \n* 3 if they were in the $|11\\rangle$ state.\n\nIn this task and the subsequent ones the order of qubit states in task description matches the order of qubits in the array (i.e., $|10\\rangle$ state corresponds to `qs[0]` in state $|1\\rangle$ and `qs[1]` in state $|0\\rangle$).\n\nThe state of the qubits at the end of the operation does not matter.\n"
|
|
1405
|
+
},
|
|
1406
|
+
"sourceIds": [
|
|
1407
|
+
"multi_qubit_measurements__full_measurements__verify.qs",
|
|
1408
|
+
"multi_qubit_measurements__common.qs",
|
|
1409
|
+
"KatasLibrary.qs"
|
|
1410
|
+
],
|
|
1411
|
+
"placeholderCode": "namespace Kata {\n operation BasisStateMeasurement(qs : Qubit[]) : Int {\n // Implement your solution here...\n\n return -1;\n }\n\n}\n",
|
|
1412
|
+
"explainedSolution": {
|
|
1413
|
+
"type": "explained-solution",
|
|
1414
|
+
"items": [
|
|
1415
|
+
{
|
|
1416
|
+
"type": "text-content",
|
|
1417
|
+
"asHtml": "<p>First, we measure both qubits in the input array and store the result in <code>m1</code> and <code>m2</code>. We can decode these results like this: </p>\n<ul>\n<li><code>m1</code> is $|0\\rangle$ and <code>m2</code> is $|0\\rangle$: we return $0\\cdot2+0 = 0$</li>\n<li><code>m1</code> is $|0\\rangle$ and <code>m2</code> is $|1\\rangle$: we return $0\\cdot2+1 = 1$</li>\n<li><code>m1</code> is $|1\\rangle$ and <code>m2</code> is $|0\\rangle$: we return $1\\cdot2+0 = 2$</li>\n<li><code>m1</code> is $|1\\rangle$ and <code>m2</code> is $|1\\rangle$: we return $1\\cdot2+1 = 3$</li>\n</ul>\n<p>In other words, we treat the measurement results as the binary notation of the return value in big endian notation.</p>\n",
|
|
1418
|
+
"asMarkdown": "\nFirst, we measure both qubits in the input array and store the result in `m1` and `m2`. We can decode these results like this: \n- `m1` is $|0\\rangle$ and `m2` is $|0\\rangle$: we return $0\\cdot2+0 = 0$\n- `m1` is $|0\\rangle$ and `m2` is $|1\\rangle$: we return $0\\cdot2+1 = 1$\n- `m1` is $|1\\rangle$ and `m2` is $|0\\rangle$: we return $1\\cdot2+0 = 2$\n- `m1` is $|1\\rangle$ and `m2` is $|1\\rangle$: we return $1\\cdot2+1 = 3$\n\nIn other words, we treat the measurement results as the binary notation of the return value in big endian notation."
|
|
1419
|
+
},
|
|
1420
|
+
{
|
|
1421
|
+
"type": "solution",
|
|
1422
|
+
"id": "multi_qubit_measurements__full_measurements_solution",
|
|
1423
|
+
"code": "namespace Kata {\n \n operation BasisStateMeasurement(qs: Qubit[]): Int {\n // Measurement on the first qubit gives the higher bit of the answer, on the second - the lower\n let m1 = M(qs[0]) == Zero ? 0 | 1;\n let m2 = M(qs[1]) == Zero ? 0 | 1;\n return m1 * 2 + m2;\n }\n \n}\n"
|
|
1424
|
+
},
|
|
1425
|
+
{
|
|
1426
|
+
"type": "text-content",
|
|
1427
|
+
"asHtml": "<p>We can generalize this code to read out an integer in big endian notation from a qubit array of arbitrary length using several library operations and functions:</p>\n<ul>\n<li><code>MeasureEachZ</code> measures each of the qubits in the array in the computational basis and returns an array of <code>Result</code> data type.</li>\n<li><code>Reversed</code> reverses the given array.</li>\n<li><code>ResultArrayAsInt</code> converts an array of bits given as <code>Result</code> to an integer, assuming little-endian notation (that's why we have to reverse the array before converting it).</li>\n</ul>\n",
|
|
1428
|
+
"asMarkdown": "\nWe can generalize this code to read out an integer in big endian notation from a qubit array of arbitrary length using several library operations and functions:\n\n* `MeasureEachZ` measures each of the qubits in the array in the computational basis and returns an array of `Result` data type.\n* `Reversed` reverses the given array.\n* `ResultArrayAsInt` converts an array of bits given as `Result` to an integer, assuming little-endian notation (that's why we have to reverse the array before converting it)."
|
|
1429
|
+
},
|
|
1430
|
+
{
|
|
1431
|
+
"type": "solution",
|
|
1432
|
+
"id": "multi_qubit_measurements__full_measurements_solution_alt",
|
|
1433
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Measurement;\n\n operation BasisStateMeasurement(qs : Qubit[]) : Int {\n return ResultArrayAsInt(Reversed(MeasureEachZ(qs)));\n }\n \n}\n"
|
|
1434
|
+
}
|
|
1435
|
+
]
|
|
1436
|
+
}
|
|
1437
|
+
},
|
|
1438
|
+
{
|
|
1439
|
+
"type": "lesson",
|
|
1440
|
+
"id": "multi_qubit_measurements__partial_measurements",
|
|
1441
|
+
"title": "Partial Measurements",
|
|
1442
|
+
"items": [
|
|
1443
|
+
{
|
|
1444
|
+
"type": "text-content",
|
|
1445
|
+
"asHtml": "<p>For a system with $n>1$ qubits, it is possible to measure $m<n$ qubits one after another. The number of measurement outcomes is then $2^m$ instead of $2^n$. The probabilities of each of the outcomes and the post-measurement states of the qubits can be found using the projection formalism for measurements.</p>\n<p>First, we recall the concept of projection operators introduced in the single-qubit systems measurements kata. Measurements are modeled by orthogonal projection operators - matrices that satisfy\n$$P^2 = P^\\dagger = P$$\nConsider an $n$-qubit system in a state $|\\psi\\rangle$, for which the first $m<n$ qubits are measured in an orthogonal basis ${ |b_0\\rangle , |b_1\\rangle, \\dotsc, |b_{2^m-1}\\rangle}$ corresponding to the $m$ qubits being measured. Then we define $2^m$ projectors corresponding to each of the $|b_i\\rangle$ states as</p>\n<p>$$P_i = |b_i\\rangle \\langle b_i| \\otimes \\mathbb{1}_{n-m} $$</p>\n<p>where $\\mathbb{1}_{n-m}$ is the identity operator over the remaining $(n-m)$ qubits.</p>\n<p>The symbol $\\otimes$ represents the tensor product or the Kronecker product of two matrices. It is different from the usual matrix multiplication.\nIn the current context, $|b_i\\rangle \\langle b_i| \\otimes \\mathbb{1}_{n-m}$ simply means that </p>\n<ul>\n<li>The operator $|b_i\\rangle \\langle b_i|$ acts only on the $m$ qubits being measured.</li>\n<li>The effect of $P_i$ on the remaining qubits is $\\mathbb{1}_{n-m} $, i.e., the identity operator.</li>\n</ul>\n<p>Analogous to the case for measurements for single-qubit systems, the rules for partial measurement probabilities and outcomes can be summarized as follows:</p>\n<ul>\n<li>When a measurement is done, one of these projectors is chosen randomly. The probability of choosing projector $P_i$ is $\\big|P_i|\\psi\\rangle\\big|^2$.</li>\n<li>If the projector $P_i$ is chosen, the measurement outcome is $b_i$, and the state of the system after the measurement is given by\n$$\n\\frac{P_i |\\psi\\rangle}{\\big|P_i |\\psi\\rangle\\big|}.\n$$</li>\n</ul>\n<p>For example, consider a two-qubit system in the state $\\ket \\psi = \\frac{1}{\\sqrt{2}}\\ket{01} - \\frac{1}{\\sqrt 2}\\ket{10}$. Consider a measurement of the first qubit in the computational basis, i.e., in the ${\\ket 0 , \\ket 1 }$ basis. Then, we have two projectors that represent this measurement:\n$$P_0 = \\ket 0\\bra 0 \\otimes \\mathbb{1}$$\n$$P_1 = \\ket 1 \\bra 1 \\otimes \\mathbb{1}$$</p>\n<p>The action of $P_0$ on $\\ket \\psi$ is</p>\n<p>$$P_0 \\ket \\psi$$</p>\n<p>$$= \\left(\\ket 0\\bra 0 \\otimes \\mathbb{1}\\right) \\frac{1}{\\sqrt 2}\\big(\\ket{01} - \\ket{10}\\big)$$</p>\n<p>$$= \\frac{1}{\\sqrt 2} \\big( \\ket 0\\bra 0 0\\rangle \\otimes \\mathbb{1} \\ket{1} - \\ket 0 \\bra 0 1\\rangle \\otimes \\mathbb{1} \\ket 0 \\big)$$</p>\n<p>$$= \\frac{1}{\\sqrt 2} \\ket{01}$$</p>\n<p>Similarly, we obtain\n$$P_1 \\ket\\psi = -\\frac{1}{\\sqrt 2} \\ket{10}$$</p>\n<p>Clearly, we have $\\big|P_0 \\ket \\psi\\big| = \\big|P_1 \\ket \\psi\\big| = \\frac{1}{2}$ in this case. Thus, the probabilities of measuring $0$ and $1$ are both $0.5$, with the post-measurement states of system being $\\ket{01}$ and $\\ket{10}$, respectively.</p>\n<blockquote>\n<p>Similar to the case of single-qubit system measurements, the applicability of the formalism above requires the state of the multi-qubit system, $\\ket \\psi$, to be normalized. This is required to ensure that all the probabilities of individual outcomes add up to 1.</p>\n</blockquote>\n<h2 id=\"🔎-analyze\">🔎 Analyze</h2>\n<p><strong>Partial measurement probabilities for the Hardy state</strong></p>\n<p>Consider a 2-qubit system in the state $\\ket \\psi = \\frac{1}{\\sqrt{12}} \\big(3|00\\rangle + |01\\rangle + |10\\rangle + |11\\rangle\\big)$.</p>\n<p>If only the first qubit is measured in the computational basis, what are the probabilities of the outcomes, and the post-measurement states of the system?</p>\n<details>\n<summary><b>Solution</b></summary>\nA measurement outcome of $0$ on the first qubit corresponds to the projection operator $P_0 = |0\\rangle\\langle 0| \\otimes \\mathbb{1}$. Applying it to the state $\\ket \\psi$ gives us \n$$\\big|P_0 \\ket{\\psi}\\big|^2 = \\big|\\frac{1}{\\sqrt{12}} \\left(3\\ket {00} + \\ket{01}\\right) \\big|^2 = \\frac{5}{6}$$\nand \n$$\\frac{P_0 \\ket{\\psi}}{\\big|P_0 \\ket{\\psi}\\big|} = \\frac{1}{\\sqrt{10}} \\left( 3\\ket{00} + \\ket{01}\\right)$$\n\n<p>Similarly, $P_1 = |1\\rangle \\langle 1 | \\otimes \\mathbb{1}$ is the projector corresponding to a measurement outcome of $1$ on the first qubit. Applying $P_1$ on $\\ket{\\psi}$ gives us $\\big|P_1 \\ket{\\psi}\\big|^2 = \\frac{1}{6}$ and </p>\n<p>$$\\frac{P_1 \\ket{\\psi}}{\\big|P_1 \\ket{\\psi}\\big|} = \\frac{1}{\\sqrt{2}} \\left(\\ket{10} + \\ket{11}\\right)$$</p>\n<table>\n <tr>\n <th>Measurement outcome</th>\n <th>Probability of outcome</th>\n <th>Post-measurement state</th>\n </tr>\n <tr>\n <td>$0$</td>\n <td>$\\frac{5}{6}$</td>\n <td>$\\frac{1}{\\sqrt{10}} \\left( 3\\ket{00} + \\ket{01}\\right)$</td>\n </tr> \n <tr>\n <td>$1$</td>\n <td>$\\frac{1}{6}$</td>\n <td>$\\frac{1}{\\sqrt{2}} \\left(\\ket{10} + \\ket{11}\\right)$</td>\n </tr> \n</table>\n</details>",
|
|
1446
|
+
"asMarkdown": "\nFor a system with $n>1$ qubits, it is possible to measure $m<n$ qubits one after another. The number of measurement outcomes is then $2^m$ instead of $2^n$. The probabilities of each of the outcomes and the post-measurement states of the qubits can be found using the projection formalism for measurements.\n\nFirst, we recall the concept of projection operators introduced in the single-qubit systems measurements kata. Measurements are modeled by orthogonal projection operators - matrices that satisfy\n$$P^2 = P^\\dagger = P$$\nConsider an $n$-qubit system in a state $|\\psi\\rangle$, for which the first $m<n$ qubits are measured in an orthogonal basis $\\{ |b_0\\rangle , |b_1\\rangle, \\dotsc, |b_{2^m-1}\\rangle\\}$ corresponding to the $m$ qubits being measured. Then we define $2^m$ projectors corresponding to each of the $|b_i\\rangle$ states as\n\n$$P_i = |b_i\\rangle \\langle b_i| \\otimes \\mathbb{1}_{n-m} $$\n\nwhere $\\mathbb{1}_{n-m}$ is the identity operator over the remaining $(n-m)$ qubits.\n\nThe symbol $\\otimes$ represents the tensor product or the Kronecker product of two matrices. It is different from the usual matrix multiplication.\nIn the current context, $|b_i\\rangle \\langle b_i| \\otimes \\mathbb{1}_{n-m}$ simply means that \n- The operator $|b_i\\rangle \\langle b_i|$ acts only on the $m$ qubits being measured.\n- The effect of $P_i$ on the remaining qubits is $\\mathbb{1}_{n-m} $, i.e., the identity operator.\n\nAnalogous to the case for measurements for single-qubit systems, the rules for partial measurement probabilities and outcomes can be summarized as follows:\n- When a measurement is done, one of these projectors is chosen randomly. The probability of choosing projector $P_i$ is $\\big|P_i|\\psi\\rangle\\big|^2$.\n- If the projector $P_i$ is chosen, the measurement outcome is $b_i$, and the state of the system after the measurement is given by\n$$\n\\frac{P_i |\\psi\\rangle}{\\big|P_i |\\psi\\rangle\\big|}.\n$$\n\nFor example, consider a two-qubit system in the state $\\ket \\psi = \\frac{1}{\\sqrt{2}}\\ket{01} - \\frac{1}{\\sqrt 2}\\ket{10}$. Consider a measurement of the first qubit in the computational basis, i.e., in the $\\{\\ket 0 , \\ket 1 \\}$ basis. Then, we have two projectors that represent this measurement:\n$$P_0 = \\ket 0\\bra 0 \\otimes \\mathbb{1}$$\n$$P_1 = \\ket 1 \\bra 1 \\otimes \\mathbb{1}$$\n\nThe action of $P_0$ on $\\ket \\psi$ is\n\n$$P_0 \\ket \\psi$$\n\n$$= \\left(\\ket 0\\bra 0 \\otimes \\mathbb{1}\\right) \\frac{1}{\\sqrt 2}\\big(\\ket{01} - \\ket{10}\\big)$$\n\n$$= \\frac{1}{\\sqrt 2} \\big( \\ket 0\\bra 0 0\\rangle \\otimes \\mathbb{1} \\ket{1} - \\ket 0 \\bra 0 1\\rangle \\otimes \\mathbb{1} \\ket 0 \\big)$$\n\n$$= \\frac{1}{\\sqrt 2} \\ket{01}$$\n\nSimilarly, we obtain\n$$P_1 \\ket\\psi = -\\frac{1}{\\sqrt 2} \\ket{10}$$\n\nClearly, we have $\\big|P_0 \\ket \\psi\\big| = \\big|P_1 \\ket \\psi\\big| = \\frac{1}{2}$ in this case. Thus, the probabilities of measuring $0$ and $1$ are both $0.5$, with the post-measurement states of system being $\\ket{01}$ and $\\ket{10}$, respectively.\n\n> Similar to the case of single-qubit system measurements, the applicability of the formalism above requires the state of the multi-qubit system, $\\ket \\psi$, to be normalized. This is required to ensure that all the probabilities of individual outcomes add up to 1.\n\n## 🔎 Analyze\n\n**Partial measurement probabilities for the Hardy state**\n\nConsider a 2-qubit system in the state $\\ket \\psi = \\frac{1}{\\sqrt{12}} \\big(3|00\\rangle + |01\\rangle + |10\\rangle + |11\\rangle\\big)$.\n\nIf only the first qubit is measured in the computational basis, what are the probabilities of the outcomes, and the post-measurement states of the system?\n\n<details>\n<summary><b>Solution</b></summary>\nA measurement outcome of $0$ on the first qubit corresponds to the projection operator $P_0 = |0\\rangle\\langle 0| \\otimes \\mathbb{1}$. Applying it to the state $\\ket \\psi$ gives us \n$$\\big|P_0 \\ket{\\psi}\\big|^2 = \\big|\\frac{1}{\\sqrt{12}} \\left(3\\ket {00} + \\ket{01}\\right) \\big|^2 = \\frac{5}{6}$$\nand \n$$\\frac{P_0 \\ket{\\psi}}{\\big|P_0 \\ket{\\psi}\\big|} = \\frac{1}{\\sqrt{10}} \\left( 3\\ket{00} + \\ket{01}\\right)$$\n\nSimilarly, $P_1 = |1\\rangle \\langle 1 | \\otimes \\mathbb{1}$ is the projector corresponding to a measurement outcome of $1$ on the first qubit. Applying $P_1$ on $\\ket{\\psi}$ gives us $\\big|P_1 \\ket{\\psi}\\big|^2 = \\frac{1}{6}$ and \n\n$$\\frac{P_1 \\ket{\\psi}}{\\big|P_1 \\ket{\\psi}\\big|} = \\frac{1}{\\sqrt{2}} \\left(\\ket{10} + \\ket{11}\\right)$$\n\n<table>\n <tr>\n <th>Measurement outcome</th>\n <th>Probability of outcome</th>\n <th>Post-measurement state</th>\n </tr>\n <tr>\n <td>$0$</td>\n <td>$\\frac{5}{6}$</td>\n <td>$\\frac{1}{\\sqrt{10}} \\left( 3\\ket{00} + \\ket{01}\\right)$</td>\n </tr> \n <tr>\n <td>$1$</td>\n <td>$\\frac{1}{6}$</td>\n <td>$\\frac{1}{\\sqrt{2}} \\left(\\ket{10} + \\ket{11}\\right)$</td>\n </tr> \n</table>\n</details>"
|
|
1447
|
+
}
|
|
1448
|
+
]
|
|
1449
|
+
},
|
|
1450
|
+
{
|
|
1451
|
+
"type": "lesson",
|
|
1452
|
+
"id": "multi_qubit_measurements__measurement_statistics_for_partial_measurements",
|
|
1453
|
+
"title": "Measurement Statistics for Partial Measurement",
|
|
1454
|
+
"items": [
|
|
1455
|
+
{
|
|
1456
|
+
"type": "text-content",
|
|
1457
|
+
"asHtml": "<p>Using the <code>M</code> operation in Q#, we demonstrate that the simulated outcome probabilities and post-measurement outcomes match the theoretical values obtained using the projection operators as described above. We use the Hardy state from Exercise 4 with a computational basis measurement on the first qubit for this purpose.</p>\n<p>The simulated and theoretical measurement probabilities are not expected to match exactly, but should be close to each other, since measurement is probabilistic. However, the post-measurement states from the simulation should match the expected states for Exercise 4 precisely, since partial state collapse is not a probabilistic process.</p>\n",
|
|
1458
|
+
"asMarkdown": "\nUsing the `M` operation in Q#, we demonstrate that the simulated outcome probabilities and post-measurement outcomes match the theoretical values obtained using the projection operators as described above. We use the Hardy state from Exercise 4 with a computational basis measurement on the first qubit for this purpose.\n\nThe simulated and theoretical measurement probabilities are not expected to match exactly, but should be close to each other, since measurement is probabilistic. However, the post-measurement states from the simulation should match the expected states for Exercise 4 precisely, since partial state collapse is not a probabilistic process."
|
|
1459
|
+
},
|
|
1460
|
+
{
|
|
1461
|
+
"type": "example",
|
|
1462
|
+
"id": "multi_qubit_measurements__partial_measurements_demo",
|
|
1463
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation DemoPartialMeasurement() : Unit {\n let numRuns = 1000;\n let divider = \"--------------------------------------------------------------------------------------------------\";\n // \n // We can use coefficients without normalization in PrepareArbitraryStateD, \n // the operation will normalize them automatically.\n let coefficients = [3., 1., 1., 1.]; \n let expected_probabilities = [0.833, 0.167];\n \n // Set up the counter array for measurements.\n mutable countArray = [0, 0];\n \n use qs = Qubit[2];\n for i in 1 .. numRuns {\n // Prepare the state from Exercise 4:\n // |𝜓❭ = (1/√12)(3|00⟩+|01⟩+|10⟩+|11⟩) \n PrepareHardyState(qs);\n \n // Display the state of the qubits.\n if i == 1 {\n Message(\"The state |𝜓❭ of the system before measurement is:\");\n DumpMachine();\n Message(divider);\n }\n\n // Measure the first qubit.\n let outcome = M(qs[0]) == Zero ? 0 | 1;\n set countArray w/= outcome <- countArray[outcome] + 1;\n \n if countArray[outcome] == 1 { \n // The first time the outcome is 0/1, print the system state afterwards.\n Message(\"For outcome {outcome}, the post-measurement state of the system is:\");\n DumpMachine();\n }\n ResetAll(qs);\n }\n \n // Obtain simulated probability of measurement for each outcome\n mutable simulated_probabilities = [];\n for i in 0 .. 1 {\n set simulated_probabilities += [IntAsDouble(countArray[i]) / IntAsDouble(numRuns)];\n }\n \n Message($\"Theoretical measurement probabilities are {expected_probabilities}\");\n Message($\"Simulated measurement probabilities are {simulated_probabilities}\");\n }\n \n operation PrepareHardyState(q: Qubit[]): Unit {\n Ry(ArcCos(2.0/3.0), q[1]);\n within {\n S(q[0]);\n H(q[0]);\n } apply {\n CNOT(q[1], q[0]);\n Rz(ArcTan(1.0/2.0), q[0]);\n CNOT(q[1], q[0]);\n Rz(-ArcTan(2.0), q[0]);\n } \n }\n\n}\n"
|
|
1464
|
+
},
|
|
1465
|
+
{
|
|
1466
|
+
"type": "text-content",
|
|
1467
|
+
"asHtml": "<h2 id=\"using-partial-measurements-to-identify-the-state-of-the-system\">Using Partial Measurements to Identify the State of the System</h2>\n<p>In certain situations, it is possible to distinguish between orthogonal states of multi-qubit systems using partial measurements, as illustrated in the next exercise.</p>\n",
|
|
1468
|
+
"asMarkdown": "\n## Using Partial Measurements to Identify the State of the System\n\nIn certain situations, it is possible to distinguish between orthogonal states of multi-qubit systems using partial measurements, as illustrated in the next exercise."
|
|
1469
|
+
}
|
|
1470
|
+
]
|
|
1471
|
+
},
|
|
1472
|
+
{
|
|
1473
|
+
"type": "exercise",
|
|
1474
|
+
"id": "multi_qubit_measurements__partial_measurements_for_system",
|
|
1475
|
+
"title": "Distinguish Orthogonal States Using Partial Measurements",
|
|
1476
|
+
"description": {
|
|
1477
|
+
"type": "text-content",
|
|
1478
|
+
"asHtml": "<p><strong>Input</strong>: A 3-qubit system which is guaranteed to be in either the $\\ket{++-}$ state, or the $\\ket{---}$ state.</p>\n<p><strong>Output</strong>: </p>\n<ul>\n<li>0 if the qubit is in the $\\ket{++-}$ state,</li>\n<li>1 if the qubit is in the $\\ket{---}$ state.</li>\n</ul>\n<p>The state of the qubits at the end of the operation should be the same as the initial state.</p>\n",
|
|
1479
|
+
"asMarkdown": "**Input**: A 3-qubit system which is guaranteed to be in either the $\\ket{++-}$ state, or the $\\ket{---}$ state.\n\n**Output**: \n- 0 if the qubit is in the $\\ket{++-}$ state,\n- 1 if the qubit is in the $\\ket{---}$ state.\n\nThe state of the qubits at the end of the operation should be the same as the initial state.\n"
|
|
1480
|
+
},
|
|
1481
|
+
"sourceIds": [
|
|
1482
|
+
"multi_qubit_measurements__partial_measurements_for_system__verify.qs",
|
|
1483
|
+
"multi_qubit_measurements__common.qs",
|
|
1484
|
+
"KatasLibrary.qs"
|
|
1485
|
+
],
|
|
1486
|
+
"placeholderCode": "namespace Kata {\n operation IsPlusPlusMinus(qs : Qubit[]) : Int {\n // Implement your solution here...\n\n return -1;\n }\n\n}\n",
|
|
1487
|
+
"explainedSolution": {
|
|
1488
|
+
"type": "explained-solution",
|
|
1489
|
+
"items": [
|
|
1490
|
+
{
|
|
1491
|
+
"type": "text-content",
|
|
1492
|
+
"asHtml": "<p>Since the state of the first qubit is different in these states ($\\ket +$ and $\\ket -$, respectively), it is sufficient to measure only the first qubit in the Pauli X basis in order to distinguish the two states. Furthermore, this measurement will not change the state of the system, since the post-projection state is identical to the original state regardless of the input state.</p>\n",
|
|
1493
|
+
"asMarkdown": "\nSince the state of the first qubit is different in these states ($\\ket +$ and $\\ket -$, respectively), it is sufficient to measure only the first qubit in the Pauli X basis in order to distinguish the two states. Furthermore, this measurement will not change the state of the system, since the post-projection state is identical to the original state regardless of the input state."
|
|
1494
|
+
},
|
|
1495
|
+
{
|
|
1496
|
+
"type": "solution",
|
|
1497
|
+
"id": "multi_qubit_measurements__partial_measurements_for_system_solution",
|
|
1498
|
+
"code": "namespace Kata {\n\n operation IsPlusPlusMinus(qs: Qubit[]): Int {\n return Measure([PauliX], [qs[0]]) == Zero ? 0 | 1;\n }\n\n}\n"
|
|
1499
|
+
}
|
|
1500
|
+
]
|
|
1501
|
+
}
|
|
1502
|
+
},
|
|
1503
|
+
{
|
|
1504
|
+
"type": "lesson",
|
|
1505
|
+
"id": "multi_qubit_measurements__measurements_and_entanglement",
|
|
1506
|
+
"title": "Measurements and Entanglement",
|
|
1507
|
+
"items": [
|
|
1508
|
+
{
|
|
1509
|
+
"type": "text-content",
|
|
1510
|
+
"asHtml": "<p>Entanglement has an effect on the measurement statistics of the system. If two qubits are entangled, then their measurement outcomes will be correlated, while separable states (which are by definition not entangled) have uncorrelated measurement outcomes.</p>\n<blockquote>\n<p>It is useful to revisit the concepts of entanglement and separable states, which were introduced in the kata on multi-qubit systems. Consider a system of $n>1$ number of qubits, which we divide into two parts: A, consisting of $m$ qubits, and B, consisting of the remaining $n-m$ qubits. We say that the state $\\ket \\psi$ of the entire system is separable if it can be expressed as a tensor product of the states of parts A and B:\n$$\n\\ket \\psi = \\ket {\\phi_A} \\otimes \\ket{\\phi_B}\n$$\nwhere $\\ket{\\phi_A}$ and $\\ket{\\phi_B}$ are wave functions that describe parts $A$ and $B$, respectively. If it is not possible to express $\\ket \\psi$ in such a form, then we say that system A is entangled with system B.</p>\n</blockquote>\n<p>Consider a measurement on the subsystem $A$ of a separable state. Let the measurement be done in a basis ${ \\ket{b_0},\\dotsc,\\ket{b_{2^m-1}}}$. According to the projection formalism, a projection operator $P_i = \\ket{b_i}\\bra{b_i} \\otimes \\mathbb{1}$ is chosen randomly. The corresponding post-measurement state of the system is then given by</p>\n<p>$$\\ket{\\psi}_{i} \\equiv \\frac{P_i \\ket{\\psi}}{\\big|P_i \\ket{\\psi}\\big|}$$</p>\n<p>$$= \\frac{\\ket{b_i}\\bra{b_i}\\phi_A\\rangle \\otimes \\ket {\\phi_B}}{\\big|\\ket{b_i}\\bra{b_i}\\phi_A\\rangle \\otimes \\ket {\\phi_B}\\big|}$$</p>\n<p>$$= \\frac{\\bra{b_i}\\phi_A\\rangle \\cdot \\ket{b_i} \\otimes \\ket {\\phi_B}}{\\big|\\ket{b_i}\\big| \\cdot \\bra{b_i}\\phi_A\\rangle \\cdot \\big| \\ket {\\phi_B}\\big|}$$</p>\n<p>$$= \\ket{b_i} \\otimes \\ket{\\phi_B}$$</p>\n<p>Thus, the state of subsystem $B$ after the measurement is $\\ket{\\phi_B}$ independently of the outcome $i$ of the measurement on the first qubit. The results of a subsequent measurement on subsystem $B$, including outcome probabilities, will be independent of the result of the first measurement. In other words, the outcomes of the two measurements will be uncorrelated.</p>\n<p>On the other hand, if the system is entangled, then the measurement outcomes will be correlated, in a manner dictated by the bases chosen for the measurements on the two subsystems. The following exercise illustrates this phenomenon.</p>\n<h2 id=\"🔎-analyze\">🔎 Analyze</h2>\n<p><strong>Sequential measurements on an entangled state and a separable state</strong></p>\n<p>Consider two two-qubit states:</p>\n<ul>\n<li>The Bell state $|\\Phi^{+}\\rangle = \\frac{1}{\\sqrt{2}} \\big (|00\\rangle + |11\\rangle\\big)$.</li>\n<li>A state $\\ket \\Theta = \\frac{1}{2} \\big( \\ket{00} + \\ket{01} + \\ket{10} + \\ket{11} \\big)$.</li>\n</ul>\n<p>For both states, consider a measurement on the first qubit, followed by a measurement on the second qubit, both done in the computational basis. For which state can we expect the measurement outcomes to be correlated? Verify by calculating the sequential measurement probabilities explicitly for both states. </p>\n<details>\n<summary><b>Solution</b></summary>\n<p><b>The Bell state</b>: If the measurement outcome on the first qubit is $0$, a subsequent measurement on the second qubit *always* results in an outcome of $0$, with probability $1$. Similarly, if the measurement outcome on the first qubit is $1$, then the second qubit measurement always results in $1$. Thus, sequential measurements are perfectly *correlated*.</p>\n\n<p><b>Separable state $\\ket \\theta$</b>: Irrespective of whether the first qubit measurement outcome is $0$ of $1$ (each of which occurs with a probability of $0.5$), a subsequent measurement on the second qubit results in an outcome of $0$ or $1$ (both with a probability of $0.5$). Thus, sequential measurements are perfectly <b>uncorrelated</b>.</p>\n\n<p>This aligns with the fact that the Bell state is entangled, while the $\\ket{\\theta}$ is separable and can be expressed as $\\ket \\theta = \\ket + \\otimes \\ket +$.</p>\n</details>\n\n<h2 id=\"state-modification-using-partial-measurements\">State Modification Using Partial Measurements</h2>\n<p>For certain multi-qubit systems prepared in a superposition state, it is possible to use partial measurements to collapse a part of the system to some desired state.</p>\n",
|
|
1511
|
+
"asMarkdown": "\nEntanglement has an effect on the measurement statistics of the system. If two qubits are entangled, then their measurement outcomes will be correlated, while separable states (which are by definition not entangled) have uncorrelated measurement outcomes.\n\n> It is useful to revisit the concepts of entanglement and separable states, which were introduced in the kata on multi-qubit systems. Consider a system of $n>1$ number of qubits, which we divide into two parts: A, consisting of $m$ qubits, and B, consisting of the remaining $n-m$ qubits. We say that the state $\\ket \\psi$ of the entire system is separable if it can be expressed as a tensor product of the states of parts A and B:\n$$\n\\ket \\psi = \\ket {\\phi_A} \\otimes \\ket{\\phi_B}\n$$\nwhere $\\ket{\\phi_A}$ and $\\ket{\\phi_B}$ are wave functions that describe parts $A$ and $B$, respectively. If it is not possible to express $\\ket \\psi$ in such a form, then we say that system A is entangled with system B.\n\nConsider a measurement on the subsystem $A$ of a separable state. Let the measurement be done in a basis $\\{ \\ket{b_0},\\dotsc,\\ket{b_{2^m-1}}\\}$. According to the projection formalism, a projection operator $P_i = \\ket{b_i}\\bra{b_i} \\otimes \\mathbb{1}$ is chosen randomly. The corresponding post-measurement state of the system is then given by\n\n$$\\ket{\\psi}_{i} \\equiv \\frac{P_i \\ket{\\psi}}{\\big|P_i \\ket{\\psi}\\big|}$$\n\n$$= \\frac{\\ket{b_i}\\bra{b_i}\\phi_A\\rangle \\otimes \\ket {\\phi_B}}{\\big|\\ket{b_i}\\bra{b_i}\\phi_A\\rangle \\otimes \\ket {\\phi_B}\\big|}$$\n\n$$= \\frac{\\bra{b_i}\\phi_A\\rangle \\cdot \\ket{b_i} \\otimes \\ket {\\phi_B}}{\\big|\\ket{b_i}\\big| \\cdot \\bra{b_i}\\phi_A\\rangle \\cdot \\big| \\ket {\\phi_B}\\big|}$$\n\n$$= \\ket{b_i} \\otimes \\ket{\\phi_B}$$\n\nThus, the state of subsystem $B$ after the measurement is $\\ket{\\phi_B}$ independently of the outcome $i$ of the measurement on the first qubit. The results of a subsequent measurement on subsystem $B$, including outcome probabilities, will be independent of the result of the first measurement. In other words, the outcomes of the two measurements will be uncorrelated.\n\nOn the other hand, if the system is entangled, then the measurement outcomes will be correlated, in a manner dictated by the bases chosen for the measurements on the two subsystems. The following exercise illustrates this phenomenon.\n\n## 🔎 Analyze\n\n**Sequential measurements on an entangled state and a separable state**\n\nConsider two two-qubit states:\n- The Bell state $|\\Phi^{+}\\rangle = \\frac{1}{\\sqrt{2}} \\big (|00\\rangle + |11\\rangle\\big)$.\n- A state $\\ket \\Theta = \\frac{1}{2} \\big( \\ket{00} + \\ket{01} + \\ket{10} + \\ket{11} \\big)$.\n\nFor both states, consider a measurement on the first qubit, followed by a measurement on the second qubit, both done in the computational basis. For which state can we expect the measurement outcomes to be correlated? Verify by calculating the sequential measurement probabilities explicitly for both states. \n\n<details>\n<summary><b>Solution</b></summary>\n<p><b>The Bell state</b>: If the measurement outcome on the first qubit is $0$, a subsequent measurement on the second qubit *always* results in an outcome of $0$, with probability $1$. Similarly, if the measurement outcome on the first qubit is $1$, then the second qubit measurement always results in $1$. Thus, sequential measurements are perfectly *correlated*.</p>\n\n<p><b>Separable state $\\ket \\theta$</b>: Irrespective of whether the first qubit measurement outcome is $0$ of $1$ (each of which occurs with a probability of $0.5$), a subsequent measurement on the second qubit results in an outcome of $0$ or $1$ (both with a probability of $0.5$). Thus, sequential measurements are perfectly <b>uncorrelated</b>.</p>\n\n<p>This aligns with the fact that the Bell state is entangled, while the $\\ket{\\theta}$ is separable and can be expressed as $\\ket \\theta = \\ket + \\otimes \\ket +$.</p>\n</details>\n\n## State Modification Using Partial Measurements\n\nFor certain multi-qubit systems prepared in a superposition state, it is possible to use partial measurements to collapse a part of the system to some desired state."
|
|
1512
|
+
}
|
|
1513
|
+
]
|
|
1514
|
+
},
|
|
1515
|
+
{
|
|
1516
|
+
"type": "exercise",
|
|
1517
|
+
"id": "multi_qubit_measurements__state_modification",
|
|
1518
|
+
"title": "State Selection Using Partial Measurements",
|
|
1519
|
+
"description": {
|
|
1520
|
+
"type": "text-content",
|
|
1521
|
+
"asHtml": "<p><strong>Input</strong>: </p>\n<ol>\n<li>A 2-qubit system in the state\n$$\n|\\psi\\rangle = \\frac{1}{\\sqrt{2}} |0\\rangle \\otimes ( a |0\\rangle + b|1\\rangle) + \\frac{1}{\\sqrt{2}} |1\\rangle \\otimes (b|0\\rangle + a |1\\rangle),\n$$\nwhere the constants $a$ and $b$ satisfying $|a|^2 + |b|^2 = 1$ are unknown.</li>\n<li>An integer $ind$ which is either $0$ or $1$.</li>\n</ol>\n<p><strong>Goal</strong>: </p>\n<ul>\n<li>If $ind$ equals 0, the state of the second qubit should be $a|0\\rangle + b|1\\rangle$</li>\n<li>If $ind$ equals 1, the state of the second qubit should be $b|0\\rangle + a |1\\rangle$.</li>\n</ul>\n<p>The state of the first qubit at the end does not matter.</p>\n",
|
|
1522
|
+
"asMarkdown": "**Input**: \n1. A 2-qubit system in the state\n$$\n|\\psi\\rangle = \\frac{1}{\\sqrt{2}} |0\\rangle \\otimes ( a |0\\rangle + b|1\\rangle) + \\frac{1}{\\sqrt{2}} |1\\rangle \\otimes (b|0\\rangle + a |1\\rangle),\n$$\nwhere the constants $a$ and $b$ satisfying $|a|^2 + |b|^2 = 1$ are unknown.\n2. An integer $ind$ which is either $0$ or $1$.\n\n**Goal**: \n- If $ind$ equals 0, the state of the second qubit should be $a|0\\rangle + b|1\\rangle$\n- If $ind$ equals 1, the state of the second qubit should be $b|0\\rangle + a |1\\rangle$. \n\nThe state of the first qubit at the end does not matter.\n"
|
|
1523
|
+
},
|
|
1524
|
+
"sourceIds": [
|
|
1525
|
+
"multi_qubit_measurements__state_modification__verify.qs",
|
|
1526
|
+
"multi_qubit_measurements__common.qs",
|
|
1527
|
+
"KatasLibrary.qs"
|
|
1528
|
+
],
|
|
1529
|
+
"placeholderCode": "namespace Kata {\n operation StateSelction(qs : Qubit[], ind : Int) : Unit {\n // Implement your solution here...\n\n }\n}\n",
|
|
1530
|
+
"explainedSolution": {
|
|
1531
|
+
"type": "explained-solution",
|
|
1532
|
+
"items": [
|
|
1533
|
+
{
|
|
1534
|
+
"type": "text-content",
|
|
1535
|
+
"asHtml": "<p>We note that if we measure the first qubit in the computational basis, then an outcome of $0$ collapses the second qubit to the state $a\\ket 0 + b \\ket 1$, while an outcome of $1$ collapses the second qubit to the state $b\\ket 0 + a \\ket 1$.</p>\n<p>Thus, if $ind=0$ and we measure $0$ or if $ind=1$ and we measure $1$, then after the measurement the second qubit will be in the desired state. On the other hand, if $ind=1$ and we measure $0$, or if $ind=0$ and we measure $1$, then the state of the second qubit after the measurement is not what we're looking for, but we can adjust it using the Pauli X gate.</p>\n",
|
|
1536
|
+
"asMarkdown": "\nWe note that if we measure the first qubit in the computational basis, then an outcome of $0$ collapses the second qubit to the state $a\\ket 0 + b \\ket 1$, while an outcome of $1$ collapses the second qubit to the state $b\\ket 0 + a \\ket 1$.\n\nThus, if $ind=0$ and we measure $0$ or if $ind=1$ and we measure $1$, then after the measurement the second qubit will be in the desired state. On the other hand, if $ind=1$ and we measure $0$, or if $ind=0$ and we measure $1$, then the state of the second qubit after the measurement is not what we're looking for, but we can adjust it using the Pauli X gate."
|
|
1537
|
+
},
|
|
1538
|
+
{
|
|
1539
|
+
"type": "solution",
|
|
1540
|
+
"id": "multi_qubit_measurements__state_modification_solution",
|
|
1541
|
+
"code": "namespace Kata {\n\n operation StateSelction(qs : Qubit[], ind : Int) : Unit {\n // It is convenient to convert measurement outcome to an integer\n let outcome = M(qs[0]) == Zero ? 0 | 1;\n if outcome != ind {\n X(qs[1]);\n }\n }\n\n}\n"
|
|
1542
|
+
}
|
|
1543
|
+
]
|
|
1544
|
+
}
|
|
1545
|
+
},
|
|
1546
|
+
{
|
|
1547
|
+
"type": "lesson",
|
|
1548
|
+
"id": "multi_qubit_measurements__state_preparation",
|
|
1549
|
+
"title": "State Preparation",
|
|
1550
|
+
"items": [
|
|
1551
|
+
{
|
|
1552
|
+
"type": "text-content",
|
|
1553
|
+
"asHtml": "<p>Any multi-qubit state can be prepared from the $|0...0\\rangle$ state using an appropriate combination of quantum gates.\nHowever, sometimes it is easier and more efficient to prepare a state using partial measurements.\nYou could prepare a simpler state involving additional qubits, which, when measured, result in a collapse of the remaining qubits to the desired state with a high probability. This is called <strong>post-selection</strong>, and is particularly useful if it is easier to prepare the pre-measurement state with the extra qubits than to prepare the desired state directly using unitary gates alone. This is demonstrated by the following exercise.</p>\n",
|
|
1554
|
+
"asMarkdown": "\nAny multi-qubit state can be prepared from the $|0...0\\rangle$ state using an appropriate combination of quantum gates.\nHowever, sometimes it is easier and more efficient to prepare a state using partial measurements.\nYou could prepare a simpler state involving additional qubits, which, when measured, result in a collapse of the remaining qubits to the desired state with a high probability. This is called **post-selection**, and is particularly useful if it is easier to prepare the pre-measurement state with the extra qubits than to prepare the desired state directly using unitary gates alone. This is demonstrated by the following exercise."
|
|
1555
|
+
}
|
|
1556
|
+
]
|
|
1557
|
+
},
|
|
1558
|
+
{
|
|
1559
|
+
"type": "exercise",
|
|
1560
|
+
"id": "multi_qubit_measurements__state_preparation_using_partial_measurements",
|
|
1561
|
+
"title": "State Preparation Using Partial Measurements",
|
|
1562
|
+
"description": {
|
|
1563
|
+
"type": "text-content",
|
|
1564
|
+
"asHtml": "<p><strong>Input:</strong> Two qubits (in an array) which are in the state $\\ket{00}$.</p>\n<p><strong>Goal:</strong> Modify the qubits to the state $\\frac{1}{\\sqrt{3}} \\big(|00\\rangle + |01\\rangle + |10\\rangle\\big)$ using post-selection.</p>\n<br/>\n<details>\n <summary><b>Need a hint?</b></summary>\n Consider a 3-qubit state $\\frac{1}{2}(|00\\rangle + |01\\rangle + |11\\rangle) \\otimes |0\\rangle + \\frac{1}{2} |11\\rangle \\otimes |1\\rangle$.\n What happens when one measures the third qubit?\n</details>\n",
|
|
1565
|
+
"asMarkdown": "**Input:** Two qubits (in an array) which are in the state $\\ket{00}$.\n\n**Goal:** Modify the qubits to the state $\\frac{1}{\\sqrt{3}} \\big(|00\\rangle + |01\\rangle + |10\\rangle\\big)$ using post-selection.\n\n<br/>\n<details>\n <summary><b>Need a hint?</b></summary>\n Consider a 3-qubit state $\\frac{1}{2}(|00\\rangle + |01\\rangle + |11\\rangle) \\otimes |0\\rangle + \\frac{1}{2} |11\\rangle \\otimes |1\\rangle$.\n What happens when one measures the third qubit?\n</details>\n"
|
|
1566
|
+
},
|
|
1567
|
+
"sourceIds": [
|
|
1568
|
+
"multi_qubit_measurements__state_preparation__verify.qs",
|
|
1569
|
+
"multi_qubit_measurements__common.qs",
|
|
1570
|
+
"KatasLibrary.qs"
|
|
1571
|
+
],
|
|
1572
|
+
"placeholderCode": "namespace Kata {\n operation PostSelection(qs : Qubit[]) : Unit {\n // Implement your solution here...\n\n }\n}\n",
|
|
1573
|
+
"explainedSolution": {
|
|
1574
|
+
"type": "explained-solution",
|
|
1575
|
+
"items": [
|
|
1576
|
+
{
|
|
1577
|
+
"type": "text-content",
|
|
1578
|
+
"asHtml": "<p>While it is possible to prepare the state $\\ket \\psi$ directly using unitary rotations, it is simpler to use post-selection for preparing it. Here, we describe the procedure in more detail below.</p>\n<p>Initially we will prepare an equal superposition of all basis states corresponding to the first two qubits by applying the <strong>H</strong> gate to each of them: \n$$\\frac{1}{2} \\big(|00\\rangle + |01\\rangle + |10\\rangle + |11\\rangle\\big) \\otimes \\ket 0$$</p>\n<p>This state is a superposition of the state we want to prepare, and the $|11\\rangle$ state that we would like to discard.</p>\n<p>Now, we want to separate the first three basis states from the last one and to store this separation in the extra qubit. \nFor example, we can keep the state of the extra qubit $|0\\rangle$ for the basis states that we want to keep, and switch it to $|1\\rangle$ for the basis states that we would like to discard. \nA <strong>CCNOT</strong> gate can be used to accomplish this, with the first two qubits used as control qubits and the extra qubit as target. \nWhen the gate is applied, the state of the extra qubit will only change to $|1\\rangle$ if both control qubits are in the $|11\\rangle$ state, which marks exactly the state that we want to discard:</p>\n<p>$$\\text{CCNOT}\\frac{1}{2} \\big(|00\\textbf{0}\\rangle + |01\\textbf{0}\\rangle + |10\\textbf{0}\\rangle + |11\\textbf{0}\\rangle\\big) = \n\\frac{1}{2}\\big(|00\\rangle + |01\\rangle + |10\\rangle \\big) \\otimes |\\textbf{0}\\rangle + \\frac{1}{2}|11\\rangle \\otimes |\\textbf{1}\\rangle $$</p>\n<p>Finally we measure just the extra qubit; this causes a partial collapse of the system to the state defined by the measurement result:</p>\n<ul>\n<li>If the result is $|0\\rangle$, the system collapses to a state that is a linear combination of basis states which had the extra qubit in state $|0\\rangle$, i.e., the two qubits end up in the target state $\\frac{1}{\\sqrt3}\\big(|00\\rangle + |01\\rangle + |10\\rangle\\big)$. </li>\n<li>If the result is $|1\\rangle$, the system collapses to a state $|11\\rangle$, so our goal is not achieved. The good thing is, this only happens in 25% of the cases, and we can just reset our qubits to the $|00\\rangle$ state and try again.</li>\n</ul>\n<blockquote>\n<p>Q# has a built-in <a href=\"https://docs.microsoft.com/en-us/quantum/user-guide/using-qsharp/control-flow#repeat-until-success-loop\" target=\"_blank\">repeat-until-success (RUS) loop</a>, which comes in handy in this case. </p>\n<ul>\n<li>We will describe the main operations (applying <strong>H</strong> and <strong>CCNOT</strong> gates and the measurement) in the <code>repeat</code> part of the loop, which specifies its body. </li>\n<li><code>until</code> section specifies the condition which will break the loop. In this case the result of the measurement needs to be <code>Zero</code> to indicate our success. </li>\n<li>Finally, the <code>fixup</code> section allows us to clean up the results of the loop body execution before trying again if the success criteria is not met. In this case we reset the first two qubits back to the $|00\\rangle$ state.</li>\n</ul>\n</blockquote>\n<p>This technique is sometimes called post-selection.</p>\n",
|
|
1579
|
+
"asMarkdown": "\nWhile it is possible to prepare the state $\\ket \\psi$ directly using unitary rotations, it is simpler to use post-selection for preparing it. Here, we describe the procedure in more detail below.\n\nInitially we will prepare an equal superposition of all basis states corresponding to the first two qubits by applying the **H** gate to each of them: \n$$\\frac{1}{2} \\big(|00\\rangle + |01\\rangle + |10\\rangle + |11\\rangle\\big) \\otimes \\ket 0$$\n\nThis state is a superposition of the state we want to prepare, and the $|11\\rangle$ state that we would like to discard.\n\nNow, we want to separate the first three basis states from the last one and to store this separation in the extra qubit. \nFor example, we can keep the state of the extra qubit $|0\\rangle$ for the basis states that we want to keep, and switch it to $|1\\rangle$ for the basis states that we would like to discard. \nA **CCNOT** gate can be used to accomplish this, with the first two qubits used as control qubits and the extra qubit as target. \nWhen the gate is applied, the state of the extra qubit will only change to $|1\\rangle$ if both control qubits are in the $|11\\rangle$ state, which marks exactly the state that we want to discard:\n\n$$\\text{CCNOT}\\frac{1}{2} \\big(|00\\textbf{0}\\rangle + |01\\textbf{0}\\rangle + |10\\textbf{0}\\rangle + |11\\textbf{0}\\rangle\\big) = \n\\frac{1}{2}\\big(|00\\rangle + |01\\rangle + |10\\rangle \\big) \\otimes |\\textbf{0}\\rangle + \\frac{1}{2}|11\\rangle \\otimes |\\textbf{1}\\rangle $$\n\nFinally we measure just the extra qubit; this causes a partial collapse of the system to the state defined by the measurement result:\n* If the result is $|0\\rangle$, the system collapses to a state that is a linear combination of basis states which had the extra qubit in state $|0\\rangle$, i.e., the two qubits end up in the target state $\\frac{1}{\\sqrt3}\\big(|00\\rangle + |01\\rangle + |10\\rangle\\big)$. \n* If the result is $|1\\rangle$, the system collapses to a state $|11\\rangle$, so our goal is not achieved. The good thing is, this only happens in 25% of the cases, and we can just reset our qubits to the $|00\\rangle$ state and try again.\n\n\n> Q# has a built-in <a href=\"https://docs.microsoft.com/en-us/quantum/user-guide/using-qsharp/control-flow#repeat-until-success-loop\" target=\"_blank\">repeat-until-success (RUS) loop</a>, which comes in handy in this case. \n> * We will describe the main operations (applying **H** and **CCNOT** gates and the measurement) in the `repeat` part of the loop, which specifies its body. \n> * `until` section specifies the condition which will break the loop. In this case the result of the measurement needs to be `Zero` to indicate our success. \n> * Finally, the `fixup` section allows us to clean up the results of the loop body execution before trying again if the success criteria is not met. In this case we reset the first two qubits back to the $|00\\rangle$ state.\n\nThis technique is sometimes called post-selection."
|
|
1580
|
+
},
|
|
1581
|
+
{
|
|
1582
|
+
"type": "solution",
|
|
1583
|
+
"id": "multi_qubit_measurements__state_preparation_solution",
|
|
1584
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Measurement;\n\n operation PostSelection(qs: Qubit[]): Unit {\n // Initialize the extra qubit\n use anc = Qubit();\n // Using the repeat-until-success pattern to prepare the right state\n mutable res = Zero;\n repeat {\n ApplyToEach(H, qs);\n Controlled X(qs, anc);\n set res = MResetZ(anc);\n } \n until (res == Zero)\n fixup {\n ResetAll(qs);\n }\n }\n\n}\n"
|
|
1585
|
+
}
|
|
1586
|
+
]
|
|
1587
|
+
}
|
|
1588
|
+
},
|
|
1589
|
+
{
|
|
1590
|
+
"type": "lesson",
|
|
1591
|
+
"id": "multi_qubit_measurements__joint_measurements",
|
|
1592
|
+
"title": "Joint Measurements",
|
|
1593
|
+
"items": [
|
|
1594
|
+
{
|
|
1595
|
+
"type": "text-content",
|
|
1596
|
+
"asHtml": "<p>Joint measurements, also known as Pauli measurements, are a generalization of 2-outcome measurements to multiple qubits and other bases. In Q#, joint measurements in Pauli bases are implemented using the <a href=\"https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.measure\" target=\"_blank\"><code>Measure</code></a> operation. Let's review single-qubit measurements in a different light before discussing joint measurements.</p>\n<h2 id=\"single-qubit-pauli-measurement\">Single-Qubit Pauli Measurement</h2>\n<p>For single-qubit systems, any measurement corresponding to an orthogonal basis can be associated with a Hermitian matrix with eigenvalues $\\pm 1$. The possible measurement outcomes (represented as <code>Result</code> in Q#) are the eigenvalues of the Hermitian matrix, and the corresponding projection matrices for the measurement are the projection operators onto the <em>eigenspaces</em> corresponding to the eigenvalues.</p>\n<p>For example, consider the computational basis measurement, which can result in outcomes <code>Zero</code> or <code>One</code> corresponding to states $\\ket 0$ and $\\ket 1$. This measurement is associated with the Pauli Z operator, which is given by</p>\n<p>$$Z = \\begin{pmatrix} 1 & 0 \\\\ 0 & -1\\end{pmatrix} = \\ket{0}\\bra{0} - \\ket{1}\\bra{1}$$</p>\n<p>The $Z$ operator has two eigenvalues, $1$ and $-1$, with corresponding eigenvectors $\\ket{0}$ and $\\ket{1}$. A $Z$-measurement is then a measurement in the $\\{\\ket{0},\\ket{1}\\}$ basis, with the measurement outcomes being $1$ and $-1$ respectively. In Q#, by convention, an eigenvalue of $1$ corresponds to a <code>Result</code> of <code>Zero</code>, while an eigenvalue of $-1$ corresponds to a <code>Result</code> of <code>One</code>.</p>\n<p>Similarly, one can implement measurements corresponding to the Pauli X and Y operators. We summarize the various properties below:</p>\n<table>\n <tr>\n <th>Pauli Operator</th>\n <th>Matrix</th>\n <th>Eigenvalue</th>\n <th>Eigenvector/post-measurement state</th>\n <th>Measurement Result in Q#</th>\n </tr>\n <tr>\n <td rowspan=\"2\">$X$</td>\n <td rowspan=\"2\">$\\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix}$</td>\n <td>+1</td>\n <td>$\\ket{+}$</td>\n <td>Zero</td>\n </tr><tr>\n <td>-1</td>\n <td>$\\ket{-}$</td>\n <td>One</td>\n </tr>\n <tr>\n <td rowspan=\"2\">$Y$</td>\n <td rowspan=\"2\">$\\begin{bmatrix} 0 & -i \\\\ i & 0 \\end{bmatrix}$</td>\n <td>+1</td>\n <td>$\\ket{i}$</td>\n <td>Zero</td>\n </tr><tr>\n <td>-1</td>\n <td>$\\ket{-i}$</td>\n <td>One</td>\n </tr>\n <tr>\n <td rowspan=\"2\">$Z$</td>\n <td rowspan=\"2\">$\\begin{bmatrix} 1 & 0 \\\\ 0 & -1 \\end{bmatrix}$</td>\n <td>+1</td>\n <td>$\\ket{0}$</td>\n <td>Zero</td>\n </tr><tr>\n <td>-1</td>\n <td>$\\ket{1}$</td>\n <td>One</td>\n </tr>\n</table>\n\n<p>In general, any measurement on a single qubit which results in two outcomes corresponds to the Hermitian operator $U Z U^\\dagger$, for some $2\\times 2$ unitary matrix $U$.</p>\n<p>Joint measurements are a generalization of this principle for multi-qubit matrices.</p>\n<h2 id=\"parity-measurements\">Parity Measurements</h2>\n<p>The simplest joint measurement is a parity measurement. A parity measurement treats computational basis vectors differently depending on whether the number of 1's in the basis vector is even or odd.</p>\n<p>For example, the operator $Z\\otimes Z$, or $ZZ$ in short, is the parity measurement operator for a two-qubit system. The eigenvalues $1$ and $-1$ correspond to the subspaces spanned by basis vectors ${ |00\\rangle, |11\\rangle }$ and ${ |01\\rangle, |10\\rangle }$, respectively. That is, when a $ZZ$ measurement results in a <code>Zero</code> (i.e. the eigenvalue $+1$), the post-measurement state is a superposition of only those computational basis vectors which have an even number of $1$'s. On the other hand, a result of <code>One</code> corresponds to a post-measurement state with only odd parity computational basis vectors.</p>\n<p>Let's see what happens to various two-qubit states after the parity measurement. The $Z \\otimes Z$ matrix for two qubits is:</p>\n<p>$$\nZ \\otimes Z =\n\\begin{bmatrix}\n 1 & 0 & 0 & 0 \\\\ \n 0 & -1 & 0 & 0 \\\\ \n 0 & 0 & -1 & 0 \\\\ \n 0 & 0 & 0 & 1 \\\\ \n\\end{bmatrix}\n$$</p>\n<p>When this transformation is applied to a basis state $|00\\rangle$, we get</p>\n<p>$$\n\\begin{bmatrix}\n 1 & 0 & 0 & 0 \\\\ \n 0 & -1 & 0 & 0 \\\\ \n 0 & 0 & -1 & 0 \\\\ \n 0 & 0 & 0 & 1 \\\\ \n\\end{bmatrix}\n\\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix}\n$$</p>\n<p>Comparing this to the characteristic equation for eigenvectors of $Z \\otimes Z$ given by\n$ Z \\otimes Z |\\psi\\rangle = \\lambda |\\psi\\rangle$,\nit is easy to see that $|00\\rangle$ belongs to the $+1$ eigenspace, hence the $Z \\otimes Z$ measurement will return <code>Zero</code> and leave the state unchanged.</p>\n<p>Similarly, it can easily be verified that $|11\\rangle$ also belongs to $+1$ eigenspace, while $|01\\rangle$ and $|10\\rangle$ belong to the $-1$ eigenspace.</p>\n<p>Now, what happens if we apply a $Z \\otimes Z$ measurement to a superposition state $\\alpha |00\\rangle + \\beta |11\\rangle$? We can see that</p>\n<p>$$\n\\begin{bmatrix}\n 1 & 0 & 0 & 0 \\\\ \n 0 & -1 & 0 & 0 \\\\ \n 0 & 0 & -1 & 0 \\\\ \n 0 & 0 & 0 & 1 \\\\ \n\\end{bmatrix}\n\\begin{bmatrix} \\alpha \\\\ 0 \\\\ 0 \\\\ \\beta \\end{bmatrix} =\n\\begin{bmatrix} \\alpha \\\\ 0 \\\\ 0 \\\\ \\beta \\end{bmatrix}\n$$</p>\n<p>So this state also belongs to the $+1$ eigenspace, and measuring it will return <code>Zero</code> and leave the state unchanged. Similarly, we can verify that an $\\alpha |01\\rangle + \\beta |10\\rangle$ state belongs to the $-1$ eigenspace, and measuring it will return <code>One</code> without changing the state.</p>\n<p>Similarly, a parity measurement on a higher number of qubits can be implemented using a $Z \\otimes \\dotsc \\otimes Z$ measurement.</p>\n",
|
|
1597
|
+
"asMarkdown": "\nJoint measurements, also known as Pauli measurements, are a generalization of 2-outcome measurements to multiple qubits and other bases. In Q#, joint measurements in Pauli bases are implemented using the <a href=\"https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.measure\" target=\"_blank\">`Measure`</a> operation. Let's review single-qubit measurements in a different light before discussing joint measurements.\n\n## Single-Qubit Pauli Measurement\nFor single-qubit systems, any measurement corresponding to an orthogonal basis can be associated with a Hermitian matrix with eigenvalues $\\pm 1$. The possible measurement outcomes (represented as `Result` in Q#) are the eigenvalues of the Hermitian matrix, and the corresponding projection matrices for the measurement are the projection operators onto the *eigenspaces* corresponding to the eigenvalues.\n\nFor example, consider the computational basis measurement, which can result in outcomes `Zero` or `One` corresponding to states $\\ket 0$ and $\\ket 1$. This measurement is associated with the Pauli Z operator, which is given by\n\n$$Z = \\begin{pmatrix} 1 & 0 \\\\\\ 0 & -1\\end{pmatrix} = \\ket{0}\\bra{0} - \\ket{1}\\bra{1}$$\n\nThe $Z$ operator has two eigenvalues, $1$ and $-1$, with corresponding eigenvectors $\\ket{0}$ and $\\ket{1}$. A $Z$-measurement is then a measurement in the $\\\\{\\ket{0},\\ket{1}\\\\}$ basis, with the measurement outcomes being $1$ and $-1$ respectively. In Q#, by convention, an eigenvalue of $1$ corresponds to a `Result` of `Zero`, while an eigenvalue of $-1$ corresponds to a `Result` of `One`.\n\nSimilarly, one can implement measurements corresponding to the Pauli X and Y operators. We summarize the various properties below:\n<table>\n <tr>\n <th>Pauli Operator</th>\n <th>Matrix</th>\n <th>Eigenvalue</th>\n <th>Eigenvector/post-measurement state</th>\n <th>Measurement Result in Q#</th>\n </tr>\n <tr>\n <td rowspan=\"2\">$X$</td>\n <td rowspan=\"2\">$\\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix}$</td>\n <td>+1</td>\n <td>$\\ket{+}$</td>\n <td>Zero</td>\n </tr><tr>\n <td>-1</td>\n <td>$\\ket{-}$</td>\n <td>One</td>\n </tr>\n <tr>\n <td rowspan=\"2\">$Y$</td>\n <td rowspan=\"2\">$\\begin{bmatrix} 0 & -i \\\\ i & 0 \\end{bmatrix}$</td>\n <td>+1</td>\n <td>$\\ket{i}$</td>\n <td>Zero</td>\n </tr><tr>\n <td>-1</td>\n <td>$\\ket{-i}$</td>\n <td>One</td>\n </tr>\n <tr>\n <td rowspan=\"2\">$Z$</td>\n <td rowspan=\"2\">$\\begin{bmatrix} 1 & 0 \\\\ 0 & -1 \\end{bmatrix}$</td>\n <td>+1</td>\n <td>$\\ket{0}$</td>\n <td>Zero</td>\n </tr><tr>\n <td>-1</td>\n <td>$\\ket{1}$</td>\n <td>One</td>\n </tr>\n</table>\n\nIn general, any measurement on a single qubit which results in two outcomes corresponds to the Hermitian operator $U Z U^\\dagger$, for some $2\\times 2$ unitary matrix $U$.\n\nJoint measurements are a generalization of this principle for multi-qubit matrices.\n\n## Parity Measurements\nThe simplest joint measurement is a parity measurement. A parity measurement treats computational basis vectors differently depending on whether the number of 1's in the basis vector is even or odd.\n\nFor example, the operator $Z\\otimes Z$, or $ZZ$ in short, is the parity measurement operator for a two-qubit system. The eigenvalues $1$ and $-1$ correspond to the subspaces spanned by basis vectors $\\{ |00\\rangle, |11\\rangle \\}$ and $\\{ |01\\rangle, |10\\rangle \\}$, respectively. That is, when a $ZZ$ measurement results in a `Zero` (i.e. the eigenvalue $+1$), the post-measurement state is a superposition of only those computational basis vectors which have an even number of $1$'s. On the other hand, a result of `One` corresponds to a post-measurement state with only odd parity computational basis vectors.\n\nLet's see what happens to various two-qubit states after the parity measurement. The $Z \\otimes Z$ matrix for two qubits is:\n\n$$\nZ \\otimes Z =\n\\begin{bmatrix}\n 1 & 0 & 0 & 0 \\\\\\ \n 0 & -1 & 0 & 0 \\\\\\ \n 0 & 0 & -1 & 0 \\\\\\ \n 0 & 0 & 0 & 1 \\\\\\ \n\\end{bmatrix}\n$$\n\nWhen this transformation is applied to a basis state $|00\\rangle$, we get\n\n$$\n\\begin{bmatrix}\n 1 & 0 & 0 & 0 \\\\\\ \n 0 & -1 & 0 & 0 \\\\\\ \n 0 & 0 & -1 & 0 \\\\\\ \n 0 & 0 & 0 & 1 \\\\\\ \n\\end{bmatrix}\n\\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix} =\n\\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix}\n$$\n\nComparing this to the characteristic equation for eigenvectors of $Z \\otimes Z$ given by\n$ Z \\otimes Z |\\psi\\rangle = \\lambda |\\psi\\rangle$,\nit is easy to see that $|00\\rangle$ belongs to the $+1$ eigenspace, hence the $Z \\otimes Z$ measurement will return `Zero` and leave the state unchanged.\n\nSimilarly, it can easily be verified that $|11\\rangle$ also belongs to $+1$ eigenspace, while $|01\\rangle$ and $|10\\rangle$ belong to the $-1$ eigenspace.\n\nNow, what happens if we apply a $Z \\otimes Z$ measurement to a superposition state $\\alpha |00\\rangle + \\beta |11\\rangle$? We can see that\n\n$$\n\\begin{bmatrix}\n 1 & 0 & 0 & 0 \\\\\\ \n 0 & -1 & 0 & 0 \\\\\\ \n 0 & 0 & -1 & 0 \\\\\\ \n 0 & 0 & 0 & 1 \\\\\\ \n\\end{bmatrix}\n\\begin{bmatrix} \\alpha \\\\\\ 0 \\\\\\ 0 \\\\\\ \\beta \\end{bmatrix} =\n\\begin{bmatrix} \\alpha \\\\\\ 0 \\\\\\ 0 \\\\\\ \\beta \\end{bmatrix}\n$$\n\nSo this state also belongs to the $+1$ eigenspace, and measuring it will return `Zero` and leave the state unchanged. Similarly, we can verify that an $\\alpha |01\\rangle + \\beta |10\\rangle$ state belongs to the $-1$ eigenspace, and measuring it will return `One` without changing the state.\n\nSimilarly, a parity measurement on a higher number of qubits can be implemented using a $Z \\otimes \\dotsc \\otimes Z$ measurement."
|
|
1598
|
+
}
|
|
1599
|
+
]
|
|
1600
|
+
},
|
|
1601
|
+
{
|
|
1602
|
+
"type": "exercise",
|
|
1603
|
+
"id": "multi_qubit_measurements__two_qubit_parity_measurement",
|
|
1604
|
+
"title": "Two-Qubit Parity Measurement",
|
|
1605
|
+
"description": {
|
|
1606
|
+
"type": "text-content",
|
|
1607
|
+
"asHtml": "<p><strong>Inputs</strong>: Two qubits stored in an array which are guaranteed to be either in a superposition of the states $|00\\rangle$ and $|11\\rangle$ or in a superposition of states $|01\\rangle$ and $|10\\rangle$.</p>\n<p><strong>Output</strong>: 0 if qubits were in the first superposition, 1 if they were in the second superposition.<br><em>The state of the qubits at the end of the operation should be the same as the starting state.</em></p>\n",
|
|
1608
|
+
"asMarkdown": "**Inputs**: Two qubits stored in an array which are guaranteed to be either in a superposition of the states $|00\\rangle$ and $|11\\rangle$ or in a superposition of states $|01\\rangle$ and $|10\\rangle$.\n\n**Output**: 0 if qubits were in the first superposition, 1 if they were in the second superposition. \n*The state of the qubits at the end of the operation should be the same as the starting state.*\n"
|
|
1609
|
+
},
|
|
1610
|
+
"sourceIds": [
|
|
1611
|
+
"multi_qubit_measurements__joint_measurements__verify.qs",
|
|
1612
|
+
"multi_qubit_measurements__common.qs",
|
|
1613
|
+
"KatasLibrary.qs"
|
|
1614
|
+
],
|
|
1615
|
+
"placeholderCode": "namespace Kata {\n operation ParityMeasurement(qs : Qubit[]) : Int {\n // Implement your solution here...\n\n return -1;\n }\n\n}\n",
|
|
1616
|
+
"explainedSolution": {
|
|
1617
|
+
"type": "explained-solution",
|
|
1618
|
+
"items": [
|
|
1619
|
+
{
|
|
1620
|
+
"type": "text-content",
|
|
1621
|
+
"asHtml": "<p>If we were not asked to maintain the state of the qubits, one approach would be to measure both the qubits separately in the computational basis, and check if the result is the same for both the measurements. If the measurement results are equal, the input state must have been a superposition of $\\ket{00}$ and $\\ket{11}$, while different measurement outcomes will imply that the input state must have been a superposition of $\\ket{01}$ and $\\ket{10}$. However, in these measurements we will lose the information about the original superposition states: a state $\\alpha |00\\rangle + \\beta |11\\rangle$ will collapse to either $|00\\rangle$ or $|11\\rangle$, and we won't be able to recover the information about the coefficients $\\alpha$ and $\\beta$.</p>\n<p>We need to measure the <em>parity</em> of the state without collapsing it all the way to the basis states. <a href=\"https://docs.microsoft.com/en-us/quantum/concepts/pauli-measurements\" target=\"_blank\">Pauli measurements</a> can be used for joint measurements involving multiple qubits. For this task we apply the $Z \\otimes Z$ measurement on both qubits.</p>\n<p>A joint measurement using $Z \\otimes Z$ operator can be thought as projecting the measured state to one of the two eigenspaces of $Z \\otimes Z$ with $+1$ and $-1$ as the corresponding eigenvalues. The measurement returns <code>Zero</code> if the measured state is projected to the space with an eigenvalue of $+1$, and a result of <code>One</code> if projected to the space with an eigenvalue of $-1$.</p>\n<p>As we've seen in the tutorial, the state $\\alpha |00\\rangle + \\beta |11\\rangle$ is an eigenstate of the $Z \\otimes Z$ operator with the eigenvalue $+1$, and the state $\\alpha |01\\rangle + \\beta |10\\rangle$ is an eigenstate with the eigenvalue $-1$.\nHence, we can use this joint measurement to recognize which of the superposition states we were given while preserving the initial superposition state.</p>\n<p>In Q#, the operation <a href=\"https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.measure\" target=\"_blank\"><code>Measure</code></a> can be used to measure multiple qubits using an array of <a href=\"https://docs.microsoft.com/en-us/quantum/user-guide/language/types?#primitive-types\" target=\"_blank\"><code>Pauli</code></a> constants that define the basis for measurement.</p>\n",
|
|
1622
|
+
"asMarkdown": "\nIf we were not asked to maintain the state of the qubits, one approach would be to measure both the qubits separately in the computational basis, and check if the result is the same for both the measurements. If the measurement results are equal, the input state must have been a superposition of $\\ket{00}$ and $\\ket{11}$, while different measurement outcomes will imply that the input state must have been a superposition of $\\ket{01}$ and $\\ket{10}$. However, in these measurements we will lose the information about the original superposition states: a state $\\alpha |00\\rangle + \\beta |11\\rangle$ will collapse to either $|00\\rangle$ or $|11\\rangle$, and we won't be able to recover the information about the coefficients $\\alpha$ and $\\beta$.\n\nWe need to measure the *parity* of the state without collapsing it all the way to the basis states. <a href=\"https://docs.microsoft.com/en-us/quantum/concepts/pauli-measurements\" target=\"_blank\">Pauli measurements</a> can be used for joint measurements involving multiple qubits. For this task we apply the $Z \\otimes Z$ measurement on both qubits.\n\nA joint measurement using $Z \\otimes Z$ operator can be thought as projecting the measured state to one of the two eigenspaces of $Z \\otimes Z$ with $+1$ and $-1$ as the corresponding eigenvalues. The measurement returns `Zero` if the measured state is projected to the space with an eigenvalue of $+1$, and a result of `One` if projected to the space with an eigenvalue of $-1$.\n\nAs we've seen in the tutorial, the state $\\alpha |00\\rangle + \\beta |11\\rangle$ is an eigenstate of the $Z \\otimes Z$ operator with the eigenvalue $+1$, and the state $\\alpha |01\\rangle + \\beta |10\\rangle$ is an eigenstate with the eigenvalue $-1$.\nHence, we can use this joint measurement to recognize which of the superposition states we were given while preserving the initial superposition state.\n\nIn Q#, the operation <a href=\"https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.measure\" target=\"_blank\">`Measure`</a> can be used to measure multiple qubits using an array of <a href=\"https://docs.microsoft.com/en-us/quantum/user-guide/language/types?#primitive-types\" target=\"_blank\">`Pauli`</a> constants that define the basis for measurement."
|
|
1623
|
+
},
|
|
1624
|
+
{
|
|
1625
|
+
"type": "solution",
|
|
1626
|
+
"id": "multi_qubit_measurements__joint_measurements_solution",
|
|
1627
|
+
"code": "namespace Kata {\n\n operation ParityMeasurement(qs: Qubit[]): Int {\n return Measure([PauliZ, PauliZ], qs) == Zero ? 0 | 1;\n }\n \n}\n"
|
|
1628
|
+
}
|
|
1629
|
+
]
|
|
1630
|
+
}
|
|
1631
|
+
},
|
|
1632
|
+
{
|
|
1633
|
+
"type": "lesson",
|
|
1634
|
+
"id": "multi_qubit_measurements__pauli_measurements",
|
|
1635
|
+
"title": "Multi-Qubit Pauli Measurements",
|
|
1636
|
+
"items": [
|
|
1637
|
+
{
|
|
1638
|
+
"type": "text-content",
|
|
1639
|
+
"asHtml": "<p>Joint measurement is a generalization of the measurement in the computational basis.\nPauli measurements can also be generalized to a larger number of qubits. A multi-qubit Pauli measurement corresponds to an operator $M_1 \\otimes \\dotsc \\otimes M_n$, with each $M_i$ being from the set of gates ${X,Y,Z,I}$. If at least one of the operators is not the identity matrix, then the measurement can result in two outcomes: a <code>Result</code> of <code>Zero</code> corresponding to eigenvalue $+1$ and a <code>Result</code> of <code>One</code> corresponding to the eigenvalue $-1$. The corresponding projection operators are the projections onto the corresponding eigenspaces.</p>\n<p>For example, a Pauli/joint measurement corresponding to the $X\\otimes Z$ operator can be characterized as follows:</p>\n<table>\n <tr>\n <th>Eigenvalue</th>\n <th>Measurement Result in Q#</th>\n <th>Eigenbasis</th>\n <th>Measurement Projector</th>\n </tr>\n <tr>\n <td>$+1$</td>\n <td>Zero</td>\n <td>$\\{ \\ket{0,+}, \\ket{1,-} \\}$</td>\n <td>$P_{+1} = \\ket{0,+}\\bra{0,+} + \\ket{1,-} \\bra{1,-}$</td>\n </tr>\n <tr>\n <td>$-1$</td>\n <td>One</td>\n <td>$\\{ \\ket{0,-}, \\ket{1,+} \\}$</td>\n <td>$P_{-1} = \\ket{0,-}\\bra{0,-} + \\ket{1,+} \\bra{1,+}$</td>\n </tr>\n </table>\n\n<p> The rules for measurements are then the same as those outlined in the partial measurements section, with the projection operators in the table.</p>\n<h2 id=\"🔎-analyze\">🔎 Analyze</h2>\n<p><strong>Parity measurement in different basis</strong></p>\n<p>Consider a system which is in a state $\\alpha |00\\rangle + \\beta |01\\rangle + \\beta |10\\rangle + \\alpha |11\\rangle$.</p>\n<p>What are the possible outcomes and their associated probabilities, if a measurement in an $XX$ Pauli measurement is done?</p>\n<details>\n<summary><b>Solution</b></summary>\nThe first step towards identifying the outcomes and their probabilities for joint measurements is to identify the eigenvectors corresponding to eigenvalues $\\pm1$ of the Pauli operator. We note that since $X\\ket{\\pm}= \\pm\\ket{\\pm}$, we have\n\n<p>$$XX \\ket{++} = \\ket{++}$$\n$$XX \\ket{--} = \\ket{--}$$\n$$XX \\ket{+-} = -\\ket{+-}$$\n$$XX \\ket{-+} = -\\ket{-+}$$</p>\n<p>Thus, the $XX$ operator measures the parity in the Hadamard, or the $\\ket{\\pm}$ basis. That is, it distinguishes basis states with an even number of $+$'s from basis states which have an odd number of $+$'s.</p>\n<p>The projector corresponding to a result of <code>Zero</code> is given by $P_{+1} = \\ket{++}\\bra{++} + \\ket{--}\\bra{--}$, while the projector corresponding to a result of <code>One</code> is given by $P_{-1} = \\ket{+-}\\bra{+-} + \\ket{-+}\\bra{-+}$. Then, we note that $P_{+1}$ annihilates states with odd parity, while leaving states with even parity unaffected. That is, for any values of the constants \n$$P_{+1} ( \\gamma \\ket{++} + \\delta \\ket{--} ) =$$\n$$( \\gamma \\ket{++} + \\delta \\ket{--} )P_{+1} ( \\mu \\ket{-+} + \\nu \\ket{+-} ) = 0$$</p>\n<p>Similarly, $P_{-1}$ annihilates states with even parity, while leaving states with odd parity unaffected.</p>\n<p>Now we express the given state in the Hadamard basis. We note that it is possible to go from the computational basis to the Hadamard basis using the following relations:\n$$\\ket{0} = \\frac{1}{\\sqrt{2}} \\left( \\ket{+} + \\ket{-} \\right)$$\n$$\\ket{1} = \\frac{1}{\\sqrt{2}} \\left( \\ket{+} - \\ket{-} \\right)$$</p>\n<p>Using these, we obtain\n$$ \\alpha |00\\rangle + \\beta |01\\rangle + \\beta |10\\rangle + \\alpha |11\\rangle = (\\alpha + \\beta) |++\\rangle + (\\alpha - \\beta) |--\\rangle$$\nThus, this state has an even parity in the Hadamard basis. It follows that an $XX$ Pauli measurement will result in the outcome <code>Zero</code> with probability 1, leaving the state unchanged after the measurement.</p>\n</details>",
|
|
1640
|
+
"asMarkdown": "\nJoint measurement is a generalization of the measurement in the computational basis.\nPauli measurements can also be generalized to a larger number of qubits. A multi-qubit Pauli measurement corresponds to an operator $M_1 \\otimes \\dotsc \\otimes M_n$, with each $M_i$ being from the set of gates $\\{X,Y,Z,I\\}$. If at least one of the operators is not the identity matrix, then the measurement can result in two outcomes: a `Result` of `Zero` corresponding to eigenvalue $+1$ and a `Result` of `One` corresponding to the eigenvalue $-1$. The corresponding projection operators are the projections onto the corresponding eigenspaces.\n\nFor example, a Pauli/joint measurement corresponding to the $X\\otimes Z$ operator can be characterized as follows:\n<table>\n <tr>\n <th>Eigenvalue</th>\n <th>Measurement Result in Q#</th>\n <th>Eigenbasis</th>\n <th>Measurement Projector</th>\n </tr>\n <tr>\n <td>$+1$</td>\n <td>Zero</td>\n <td>$\\{ \\ket{0,+}, \\ket{1,-} \\}$</td>\n <td>$P_{+1} = \\ket{0,+}\\bra{0,+} + \\ket{1,-} \\bra{1,-}$</td>\n </tr>\n <tr>\n <td>$-1$</td>\n <td>One</td>\n <td>$\\{ \\ket{0,-}, \\ket{1,+} \\}$</td>\n <td>$P_{-1} = \\ket{0,-}\\bra{0,-} + \\ket{1,+} \\bra{1,+}$</td>\n </tr>\n </table>\n\n The rules for measurements are then the same as those outlined in the partial measurements section, with the projection operators in the table.\n\n## 🔎 Analyze\n\n**Parity measurement in different basis**\n\nConsider a system which is in a state $\\alpha |00\\rangle + \\beta |01\\rangle + \\beta |10\\rangle + \\alpha |11\\rangle$.\n\nWhat are the possible outcomes and their associated probabilities, if a measurement in an $XX$ Pauli measurement is done?\n\n<details>\n<summary><b>Solution</b></summary>\nThe first step towards identifying the outcomes and their probabilities for joint measurements is to identify the eigenvectors corresponding to eigenvalues $\\pm1$ of the Pauli operator. We note that since $X\\ket{\\pm}= \\pm\\ket{\\pm}$, we have\n\n$$XX \\ket{++} = \\ket{++}$$\n$$XX \\ket{--} = \\ket{--}$$\n$$XX \\ket{+-} = -\\ket{+-}$$\n$$XX \\ket{-+} = -\\ket{-+}$$\n\nThus, the $XX$ operator measures the parity in the Hadamard, or the $\\ket{\\pm}$ basis. That is, it distinguishes basis states with an even number of $+$'s from basis states which have an odd number of $+$'s.\n\nThe projector corresponding to a result of `Zero` is given by $P_{+1} = \\ket{++}\\bra{++} + \\ket{--}\\bra{--}$, while the projector corresponding to a result of `One` is given by $P_{-1} = \\ket{+-}\\bra{+-} + \\ket{-+}\\bra{-+}$. Then, we note that $P_{+1}$ annihilates states with odd parity, while leaving states with even parity unaffected. That is, for any values of the constants \n$$P_{+1} ( \\gamma \\ket{++} + \\delta \\ket{--} ) =$$\n$$( \\gamma \\ket{++} + \\delta \\ket{--} )P_{+1} ( \\mu \\ket{-+} + \\nu \\ket{+-} ) = 0$$\n\nSimilarly, $P_{-1}$ annihilates states with even parity, while leaving states with odd parity unaffected.\n\nNow we express the given state in the Hadamard basis. We note that it is possible to go from the computational basis to the Hadamard basis using the following relations:\n$$\\ket{0} = \\frac{1}{\\sqrt{2}} \\left( \\ket{+} + \\ket{-} \\right)$$\n$$\\ket{1} = \\frac{1}{\\sqrt{2}} \\left( \\ket{+} - \\ket{-} \\right)$$\n\nUsing these, we obtain\n$$ \\alpha |00\\rangle + \\beta |01\\rangle + \\beta |10\\rangle + \\alpha |11\\rangle = (\\alpha + \\beta) |++\\rangle + (\\alpha - \\beta) |--\\rangle$$\nThus, this state has an even parity in the Hadamard basis. It follows that an $XX$ Pauli measurement will result in the outcome `Zero` with probability 1, leaving the state unchanged after the measurement.\n</details>"
|
|
1641
|
+
}
|
|
1642
|
+
]
|
|
1643
|
+
},
|
|
1644
|
+
{
|
|
1645
|
+
"type": "lesson",
|
|
1646
|
+
"id": "multi_qubit_measurements__conclusion",
|
|
1647
|
+
"title": "Conclusion",
|
|
1648
|
+
"items": [
|
|
1649
|
+
{
|
|
1650
|
+
"type": "text-content",
|
|
1651
|
+
"asHtml": "<p>Congratulations! In this kata you learned how to apply measurements on multi-qubit systems. Here are a few key concepts to keep in mind:</p>\n<ul>\n<li>Full measurements: you measure all the qubits simultaneously in an orthogonal basis ($2^n$ possible outcomes).</li>\n<li>Partial measurements: you measure qubits $m$ out of $n$, for $m< n$ ($2^m$ possible outcomes).</li>\n<li>Joint measurement: Pauli measurement of all $n$ qubits (2 possible outcomes).</li>\n</ul>\n<p>Next, you will implement a quantum algorithm to generate random numbers in "Quantum Random Number Generation" kata.</p>\n",
|
|
1652
|
+
"asMarkdown": "\nCongratulations! In this kata you learned how to apply measurements on multi-qubit systems. Here are a few key concepts to keep in mind:\n* Full measurements: you measure all the qubits simultaneously in an orthogonal basis ($2^n$ possible outcomes).\n* Partial measurements: you measure qubits $m$ out of $n$, for $m< n$ ($2^m$ possible outcomes).\n* Joint measurement: Pauli measurement of all $n$ qubits (2 possible outcomes).\n\nNext, you will implement a quantum algorithm to generate random numbers in \"Quantum Random Number Generation\" kata."
|
|
1653
|
+
}
|
|
1654
|
+
]
|
|
1655
|
+
}
|
|
1656
|
+
]
|
|
1657
|
+
},
|
|
1658
|
+
{
|
|
1659
|
+
"id": "random_numbers",
|
|
1660
|
+
"title": "Quantum Random Number Generation",
|
|
1661
|
+
"sections": [
|
|
1662
|
+
{
|
|
1663
|
+
"type": "lesson",
|
|
1664
|
+
"id": "random_numbers__overview",
|
|
1665
|
+
"title": "Overview",
|
|
1666
|
+
"items": [
|
|
1667
|
+
{
|
|
1668
|
+
"type": "text-content",
|
|
1669
|
+
"asHtml": "<p>True random number generation is a notoriously difficult problem. Many "random" generators today are actually pseudo-random, using a starting seed to spawn seemingly-random numbers that are actually a repeatable function of that seed. Most true random number generators are based on measurements of some natural phenomenon, such as atmospheric noise or atomic decay. You can read more about it <a href=\"https://en.wikipedia.org/wiki/Random_number_generation\" target=\"_blank\">here</a>. </p>\n<p>Quantum random number generators (QRNGs) are truly random. The quantum algorithm for random number generation is one of the simplest applications of quantum computing principles, requiring very few qubits to run.</p>\n<p><strong>This kata covers the following topics:</strong></p>\n<ul>\n<li>Quantum random number generation and the principles behind it</li>\n<li>Implementation of a variety of QRNGs with equal probability of any given number</li>\n<li>Implementation a single-bit QRNG with weighted probabilities of generated bits</li>\n</ul>\n<p><strong>What you should know to start working on this kata:</strong></p>\n<ul>\n<li>The concept of qubit and measurement</li>\n<li>Single-qubit gates</li>\n</ul>\n",
|
|
1670
|
+
"asMarkdown": "\nTrue random number generation is a notoriously difficult problem. Many \"random\" generators today are actually pseudo-random, using a starting seed to spawn seemingly-random numbers that are actually a repeatable function of that seed. Most true random number generators are based on measurements of some natural phenomenon, such as atmospheric noise or atomic decay. You can read more about it <a href=\"https://en.wikipedia.org/wiki/Random_number_generation\" target=\"_blank\">here</a>. \n\nQuantum random number generators (QRNGs) are truly random. The quantum algorithm for random number generation is one of the simplest applications of quantum computing principles, requiring very few qubits to run.\n\n**This kata covers the following topics:**\n\n- Quantum random number generation and the principles behind it\n- Implementation of a variety of QRNGs with equal probability of any given number\n- Implementation a single-bit QRNG with weighted probabilities of generated bits\n\n**What you should know to start working on this kata:**\n\n- The concept of qubit and measurement\n- Single-qubit gates"
|
|
1671
|
+
}
|
|
1672
|
+
]
|
|
1673
|
+
},
|
|
1674
|
+
{
|
|
1675
|
+
"type": "lesson",
|
|
1676
|
+
"id": "random_numbers__introduction",
|
|
1677
|
+
"title": "Introduction",
|
|
1678
|
+
"items": [
|
|
1679
|
+
{
|
|
1680
|
+
"type": "text-content",
|
|
1681
|
+
"asHtml": "<p>Recall from the Qubit kata that a qubit state $|\\psi\\rangle$ is defined via the basis states $|0\\rangle$ and $|1\\rangle$ as $|\\psi\\rangle = \\begin{bmatrix} \\alpha \\ \\beta \\end{bmatrix} = \\alpha|0\\rangle + \\beta|1\\rangle$, where $|\\alpha|^2 + |\\beta|^2 = 1$</p>\n<p>We call $\\alpha$ and $\\beta$ the probability amplitudes of states $|0\\rangle$ and $|1\\rangle$, respectively. When $|\\psi\\rangle$ is measured in the $\\{|0\\rangle, |1\\rangle\\}$ basis (the computational basis), the probabilities of the outcomes are defined based on the state amplitudes: there is a $|\\alpha|^2$ probability that the measurement result will be $0$, and a $|\\beta|^2$ probability that the measurement result will be $1$.</p>\n<blockquote>\n<p>For example, a qubit in state $\\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix}$ will yield measurement results $0$ or $1$ with equal probability, while a qubit in state $\\begin{bmatrix} \\frac{1}{2} \\\\ \\frac{\\sqrt3}{2} \\end{bmatrix}$ will yield measurement result $0$ only 25% of the time, and $1$ 75% of the time.</p>\n</blockquote>\n<p>This knowledge is sufficient to implement a simple random number generator!</p>\n<blockquote>\n<p>Remember that you can refer to the Single-Qubit Gates kata if you need a refresher on the various quantum gates and their usage in Q#.</p>\n</blockquote>\n",
|
|
1682
|
+
"asMarkdown": "\nRecall from the Qubit kata that a qubit state $|\\psi\\rangle$ is defined via the basis states $|0\\rangle$ and $|1\\rangle$ as $|\\psi\\rangle = \\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} = \\alpha|0\\rangle + \\beta|1\\rangle$, where $|\\alpha|^2 + |\\beta|^2 = 1$\n\nWe call $\\alpha$ and $\\beta$ the probability amplitudes of states $|0\\rangle$ and $|1\\rangle$, respectively. When $|\\psi\\rangle$ is measured in the $\\\\{|0\\rangle, |1\\rangle\\\\}$ basis (the computational basis), the probabilities of the outcomes are defined based on the state amplitudes: there is a $|\\alpha|^2$ probability that the measurement result will be $0$, and a $|\\beta|^2$ probability that the measurement result will be $1$.\n\n> For example, a qubit in state $\\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix}$ will yield measurement results $0$ or $1$ with equal probability, while a qubit in state $\\begin{bmatrix} \\frac{1}{2} \\\\\\ \\frac{\\sqrt3}{2} \\end{bmatrix}$ will yield measurement result $0$ only 25% of the time, and $1$ 75% of the time.\n\nThis knowledge is sufficient to implement a simple random number generator!\n\n> Remember that you can refer to the Single-Qubit Gates kata if you need a refresher on the various quantum gates and their usage in Q#."
|
|
1683
|
+
}
|
|
1684
|
+
]
|
|
1685
|
+
},
|
|
1686
|
+
{
|
|
1687
|
+
"type": "exercise",
|
|
1688
|
+
"id": "random_numbers__random_bit",
|
|
1689
|
+
"title": "Generate a Single Random Bit",
|
|
1690
|
+
"description": {
|
|
1691
|
+
"type": "text-content",
|
|
1692
|
+
"asHtml": "<p><strong>Input:</strong> None.</p>\n<p><strong>Goal:</strong> Generate a $0$ or $1$ with equal probability.</p>\n<details>\n <summary><b>Need a hint?</b></summary>\n Use the allocated qubit, apply a quantum gate to it, measure it and use the result to return a $0$ or $1$.\n</details>\n\n<p><strong>Stretch goal:</strong> Can you find a different way to implement this operation?</p>\n<details>\n <summary><b>Need a hint?</b></summary>\n What are the different quantum states that produce $0$ and $1$ measurement results with the same probability? How would measuring the qubit in a different basis change the result?\n</details>\n",
|
|
1693
|
+
"asMarkdown": "**Input:** None.\n\n**Goal:** Generate a $0$ or $1$ with equal probability.\n<details>\n <summary><b>Need a hint?</b></summary>\n Use the allocated qubit, apply a quantum gate to it, measure it and use the result to return a $0$ or $1$.\n</details>\n\n**Stretch goal:** Can you find a different way to implement this operation?\n<details>\n <summary><b>Need a hint?</b></summary>\n What are the different quantum states that produce $0$ and $1$ measurement results with the same probability? How would measuring the qubit in a different basis change the result?\n</details>\n"
|
|
1694
|
+
},
|
|
1695
|
+
"sourceIds": [
|
|
1696
|
+
"random_numbers__random_bit__verification.qs",
|
|
1697
|
+
"KatasLibrary.qs",
|
|
1698
|
+
"random_numbers__common.qs"
|
|
1699
|
+
],
|
|
1700
|
+
"placeholderCode": "namespace Kata {\n operation RandomBit() : Int {\n use q = Qubit();\n // Implement your solution here...\n\n return -1;\n }\n\n}\n",
|
|
1701
|
+
"explainedSolution": {
|
|
1702
|
+
"type": "explained-solution",
|
|
1703
|
+
"items": [
|
|
1704
|
+
{
|
|
1705
|
+
"type": "text-content",
|
|
1706
|
+
"asHtml": "<p>The state of single qubit can be represented as a two-dimensional column vector $\\begin{bmatrix} \\alpha\\ \\beta \\end{bmatrix}$, where $\\alpha$ and $\\beta$ are complex numbers that satisfy $|\\alpha|^2 + |\\beta|^2 = 1$. When we measure the qubit, we get either 0 with probability $|\\alpha|^2$ or 1 with probability $|\\beta|^2$. Essentially we can control probablity of measurement outcome by setting the right amplitudes of basis states. </p>\n<p>When we allocate the qubit in Q#, amplitudes $\\alpha$ and $\\beta$ are 1 and 0, respectively. Now our goal is set equal amplitudes for $\\alpha$ and $\\beta$ for absolute randomness. We can achieve that by simply applying Hadamard gate to the initial state $|0\\rangle$:</p>\n<p>$$\nH|0\\rangle =\n\\frac{1}{\\sqrt{2}}\n\\begin{bmatrix} 1 & 1 \\\\ 1 & -1 \\end{bmatrix}\n\\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} =\n\\frac{1}{\\sqrt{2}}\n\\begin{bmatrix} 1 \\cdot 1 + 1 \\cdot 0 \\\\ 1 \\cdot 1 + (-1) \\cdot 0 \\end{bmatrix} =\n\\frac{1}{\\sqrt{2}}\n\\begin{bmatrix} 1 \\\\ 1 \\end{bmatrix}\n$$</p>\n<p>Now, both 0 and 1 measurement outcomes occur with equal probablity of $|\\frac{1}{\\sqrt{2}}|^2 = \\frac{1}{2}$.</p>\n<blockquote>\n<p>Note: Since probability is the square of the absolute value of amplitude, we will get the same randomness by applying a Hadamard gate on base state $|1\\rangle$. Try it out as an exercise!</p>\n</blockquote>\n",
|
|
1707
|
+
"asMarkdown": "\nThe state of single qubit can be represented as a two-dimensional column vector $\\begin{bmatrix} \\alpha\\\\ \\beta \\end{bmatrix}$, where $\\alpha$ and $\\beta$ are complex numbers that satisfy $|\\alpha|^2 + |\\beta|^2 = 1$. When we measure the qubit, we get either 0 with probability $|\\alpha|^2$ or 1 with probability $|\\beta|^2$. Essentially we can control probablity of measurement outcome by setting the right amplitudes of basis states. \n\nWhen we allocate the qubit in Q#, amplitudes $\\alpha$ and $\\beta$ are 1 and 0, respectively. Now our goal is set equal amplitudes for $\\alpha$ and $\\beta$ for absolute randomness. We can achieve that by simply applying Hadamard gate to the initial state $|0\\rangle$:\n\n$$\nH|0\\rangle =\n\\frac{1}{\\sqrt{2}}\n\\begin{bmatrix} 1 & 1 \\\\\\ 1 & -1 \\end{bmatrix}\n\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} =\n\\frac{1}{\\sqrt{2}}\n\\begin{bmatrix} 1 \\cdot 1 + 1 \\cdot 0 \\\\\\ 1 \\cdot 1 + (-1) \\cdot 0 \\end{bmatrix} =\n\\frac{1}{\\sqrt{2}}\n\\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix}\n$$\n\nNow, both 0 and 1 measurement outcomes occur with equal probablity of $|\\frac{1}{\\sqrt{2}}|^2 = \\frac{1}{2}$.\n\n> Note: Since probability is the square of the absolute value of amplitude, we will get the same randomness by applying a Hadamard gate on base state $|1\\rangle$. Try it out as an exercise!"
|
|
1708
|
+
},
|
|
1709
|
+
{
|
|
1710
|
+
"type": "solution",
|
|
1711
|
+
"id": "random_numbers__random_bit_solution",
|
|
1712
|
+
"code": "namespace Kata {\n operation RandomBit() : Int {\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state.\n H(q);\n\n // Measuring the qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n}\n"
|
|
1713
|
+
}
|
|
1714
|
+
]
|
|
1715
|
+
}
|
|
1716
|
+
},
|
|
1717
|
+
{
|
|
1718
|
+
"type": "exercise",
|
|
1719
|
+
"id": "random_numbers__random_two_bits",
|
|
1720
|
+
"title": "Generate a Random Two-Bit Number",
|
|
1721
|
+
"description": {
|
|
1722
|
+
"type": "text-content",
|
|
1723
|
+
"asHtml": "<p>Now that you can generate a single random bit, you can use that logic to create random multi-bit numbers. Let's try first to make a two-bit number by combining two randomly generated bits.</p>\n<p><strong>Input:</strong> None.</p>\n<p><strong>Goal:</strong> Generate a random number in the range $[0, 3]$ with an equal probability of getting each of the four numbers.</p>\n<p><strong>Stretch goal:</strong> Can you do this without allocating qubits in this operation?</p>\n<details>\n <summary><b>Need a hint?</b></summary>\n Remember that you can use previously defined operations to implement your solution. For convenience, the <b>RandomBit</b> operation is already available for you to use in this exercise.\n</details>\n",
|
|
1724
|
+
"asMarkdown": "\nNow that you can generate a single random bit, you can use that logic to create random multi-bit numbers. Let's try first to make a two-bit number by combining two randomly generated bits.\n\n**Input:** None.\n\n**Goal:** Generate a random number in the range $[0, 3]$ with an equal probability of getting each of the four numbers.\n\n**Stretch goal:** Can you do this without allocating qubits in this operation?\n<details>\n <summary><b>Need a hint?</b></summary>\n Remember that you can use previously defined operations to implement your solution. For convenience, the <b>RandomBit</b> operation is already available for you to use in this exercise.\n</details>\n"
|
|
1725
|
+
},
|
|
1726
|
+
"sourceIds": [
|
|
1727
|
+
"random_numbers__random_two_bits__verification.qs",
|
|
1728
|
+
"KatasLibrary.qs",
|
|
1729
|
+
"random_numbers__common.qs"
|
|
1730
|
+
],
|
|
1731
|
+
"placeholderCode": "namespace Kata {\n operation RandomTwoBits() : Int {\n // Implement your solution here...\n\n return -1;\n }\n\n // You can use this operation to implement your solution.\n operation RandomBit() : Int {\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state.\n H(q);\n\n // Measuring the qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n}\n",
|
|
1732
|
+
"explainedSolution": {
|
|
1733
|
+
"type": "explained-solution",
|
|
1734
|
+
"items": [
|
|
1735
|
+
{
|
|
1736
|
+
"type": "text-content",
|
|
1737
|
+
"asHtml": "<p>Let's reuse the <code>RandomBit</code> operation from the "Generate A Single Random Bit" exercise.\nWe can generate two random bits by calling the <code>RandomBit</code> operation twice, multiply the most significant bit by 2 and add the second random bit to generate a random two-bit number.</p>\n",
|
|
1738
|
+
"asMarkdown": "\nLet's reuse the `RandomBit` operation from the \"Generate A Single Random Bit\" exercise.\nWe can generate two random bits by calling the `RandomBit` operation twice, multiply the most significant bit by 2 and add the second random bit to generate a random two-bit number."
|
|
1739
|
+
},
|
|
1740
|
+
{
|
|
1741
|
+
"type": "solution",
|
|
1742
|
+
"id": "random_numbers__random_two_bits_solution",
|
|
1743
|
+
"code": "namespace Kata {\n operation RandomTwoBits(): Int {\n return 2 * RandomBit() + RandomBit();\n }\n\n operation RandomBit() : Int {\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state.\n H(q);\n\n // Measuring the qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n}\n"
|
|
1744
|
+
}
|
|
1745
|
+
]
|
|
1746
|
+
}
|
|
1747
|
+
},
|
|
1748
|
+
{
|
|
1749
|
+
"type": "exercise",
|
|
1750
|
+
"id": "random_numbers__random_n_bits",
|
|
1751
|
+
"title": "Generate a Number of Arbitrary Size",
|
|
1752
|
+
"description": {
|
|
1753
|
+
"type": "text-content",
|
|
1754
|
+
"asHtml": "<p>Let's take it a step further and generate an $N$-bit number. </p>\n<p><strong>Input:</strong> An integer $N$ ($1 \\le N \\le 10$).</p>\n<p><strong>Goal:</strong> Generate a random number in the range $[0, 2^N - 1]$ with an equal probability of getting each of the numbers in this range.</p>\n<blockquote>\n<p>Useful Q# documentation: </p>\n<ul>\n<li><a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/statements/iterations\" target=\"_blank\">for` loops</a></li>\n<li><a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/typesystem/immutability\" target=\"_blank\">mutable variables</a></li>\n<li><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.powi\" target=\"_blank\">exponents</a></li>\n</ul>\n</blockquote>\n<details>\n <summary><b>Need a hint?</b></summary>\n Remember that you can use previously defined operations to implement your solution. For convenience, the <b>RandomBit</b> operation is already available for you to use in this exercise.\n</details>\n",
|
|
1755
|
+
"asMarkdown": "Let's take it a step further and generate an $N$-bit number. \n\n**Input:** An integer $N$ ($1 \\le N \\le 10$).\n\n**Goal:** Generate a random number in the range $[0, 2^N - 1]$ with an equal probability of getting each of the numbers in this range.\n\n> Useful Q# documentation: \n> * <a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/statements/iterations\" target=\"_blank\">for` loops</a>\n> * <a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/typesystem/immutability\" target=\"_blank\">mutable variables</a>\n> * <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.powi\" target=\"_blank\">exponents</a>\n\n<details>\n <summary><b>Need a hint?</b></summary>\n Remember that you can use previously defined operations to implement your solution. For convenience, the <b>RandomBit</b> operation is already available for you to use in this exercise.\n</details>\n"
|
|
1756
|
+
},
|
|
1757
|
+
"sourceIds": [
|
|
1758
|
+
"random_numbers__random_n_bits__verification.qs",
|
|
1759
|
+
"KatasLibrary.qs",
|
|
1760
|
+
"random_numbers__common.qs"
|
|
1761
|
+
],
|
|
1762
|
+
"placeholderCode": "namespace Kata {\n operation RandomNBits(N : Int) : Int {\n // Implement your solution here...\n\n return -1;\n }\n\n // You can use this operation to implement your solution.\n operation RandomBit() : Int {\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state.\n H(q);\n\n // Measuring the qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n}\n",
|
|
1763
|
+
"explainedSolution": {
|
|
1764
|
+
"type": "explained-solution",
|
|
1765
|
+
"items": [
|
|
1766
|
+
{
|
|
1767
|
+
"type": "text-content",
|
|
1768
|
+
"asHtml": "<p>Let's reuse the <code>RandomBit</code> operation from the "Generate A Single Random Bit" exercise again.\nWe'll generate N random bits by calling <code>RandomBit</code> operation N times, and treat the result as a binary notation to convert it into an integer.\nSince the maximum value of the number written with N bits is $2^N - 1$, we don't need to do any extra checks to ensure that the result is within the given range.</p>\n",
|
|
1769
|
+
"asMarkdown": "\nLet's reuse the `RandomBit` operation from the \"Generate A Single Random Bit\" exercise again.\nWe'll generate N random bits by calling `RandomBit` operation N times, and treat the result as a binary notation to convert it into an integer.\nSince the maximum value of the number written with N bits is $2^N - 1$, we don't need to do any extra checks to ensure that the result is within the given range."
|
|
1770
|
+
},
|
|
1771
|
+
{
|
|
1772
|
+
"type": "solution",
|
|
1773
|
+
"id": "random_numbers__random_n_bits_solution",
|
|
1774
|
+
"code": "namespace Kata {\n operation RandomNBits(N: Int): Int {\n mutable result = 0;\n for i in 0..(N - 1) {\n set result = result * 2 + RandomBit();\n }\n return result;\n }\n\n operation RandomBit() : Int {\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state.\n H(q);\n\n // Measuring the qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n}\n"
|
|
1775
|
+
}
|
|
1776
|
+
]
|
|
1777
|
+
}
|
|
1778
|
+
},
|
|
1779
|
+
{
|
|
1780
|
+
"type": "exercise",
|
|
1781
|
+
"id": "random_numbers__weighted_random_bit",
|
|
1782
|
+
"title": "Generate a Weighted Bit",
|
|
1783
|
+
"description": {
|
|
1784
|
+
"type": "text-content",
|
|
1785
|
+
"asHtml": "<p>In each of the above exercises, all generated numbers were equally likely. Now let's create an operation that will return a random bit with different probabilities of outcomes. </p>\n<blockquote>\n<p>Remember that by setting the amplitudes of basis states $\\alpha$ and $\\beta$, we can control the probability of getting measurement outcomes $0$ and $1$ when the qubit is measured.</p>\n</blockquote>\n<p><strong>Input:</strong> \nA floating-point number $x$, $0 \\le x \\le 1$. </p>\n<p><strong>Goal:</strong> Generate $0$ or $1$ with probability of $0$ equal to $x$ and probability of $1$ equal to $1 - x$.</p>\n<blockquote>\n<p>Useful Q# documentation: </p>\n<ul>\n<li><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math\" target=\"_blank\"><code>Math</code> namespace</a></li>\n<li><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arccos\" target=\"_blank\"><code>ArcCos</code> function</a></li>\n<li><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.sqrt\" target=\"_blank\"><code>Sqrt</code> function</a></li>\n</ul>\n</blockquote>\n",
|
|
1786
|
+
"asMarkdown": "In each of the above exercises, all generated numbers were equally likely. Now let's create an operation that will return a random bit with different probabilities of outcomes. \n\n> Remember that by setting the amplitudes of basis states $\\alpha$ and $\\beta$, we can control the probability of getting measurement outcomes $0$ and $1$ when the qubit is measured.\n\n**Input:** \nA floating-point number $x$, $0 \\le x \\le 1$. \n\n**Goal:** Generate $0$ or $1$ with probability of $0$ equal to $x$ and probability of $1$ equal to $1 - x$.\n\n> Useful Q# documentation: \n> * <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math\" target=\"_blank\">`Math` namespace</a>\n> * <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arccos\" target=\"_blank\">`ArcCos` function</a>\n> * <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.sqrt\" target=\"_blank\">`Sqrt` function</a>\n"
|
|
1787
|
+
},
|
|
1788
|
+
"sourceIds": [
|
|
1789
|
+
"random_numbers__weighted_random_bit__verification.qs",
|
|
1790
|
+
"KatasLibrary.qs",
|
|
1791
|
+
"random_numbers__common.qs"
|
|
1792
|
+
],
|
|
1793
|
+
"placeholderCode": "namespace Kata {\n operation WeightedRandomBit(x : Double) : Int {\n // Implement your solution here...\n\n return -1;\n }\n\n}\n",
|
|
1794
|
+
"explainedSolution": {
|
|
1795
|
+
"type": "explained-solution",
|
|
1796
|
+
"items": [
|
|
1797
|
+
{
|
|
1798
|
+
"type": "text-content",
|
|
1799
|
+
"asHtml": "<p>An arbitrary single-qubit state can be written as:</p>\n<p>$$\n|\\psi\\rangle =\n \\cos \\frac{\\theta}{2} |0 \\rangle , + , e^{i\\phi} \\sin \\frac{\\theta}{2} |1\\rangle\n$$</p>\n<p>Here, $\\theta$ is the angle between the state vector and the $Z$-axis, and $\\phi$ is the longitude angle with respect to the $X$-axis on the Bloch sphere.</p>\n<p>Our goal is to generate $0$ or $1$ with the probability of generating a $0$ equal to $x$ and the probability of generating a $1$ equal to $1 - x$. This means that the qubit state should look like</p>\n<p>$$\n|\\psi\\rangle =\n \\sqrt x |0 \\rangle + \\sqrt{1 - x} |1\\rangle\n$$</p>\n<p>Comparing the amplitudes of the state $|0 \\rangle$ in the two equations, we get</p>\n<p>$$\n\\sqrt x = \\cos \\frac{\\theta}{2} \\Rightarrow \\theta = 2 \\arccos\\sqrt x\n$$</p>\n<p>Since $\\theta$ is the angle between the state vector and the $Z$-axis, we need to apply the <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.ry\"><code>Ry</code></a> gate with the calculated $\\theta$ to the starting state $|0 \\rangle$ to get the desired qubit state.</p>\n<p>The <code>Ry</code> operation applies a given rotation about the $Y$-axis (i.e., in the $ZX$-plane). Hence, $\\phi$ (longitude angle with respect to $X$-axis) is always equal to $0^{\\circ}$, which means that the relative phase $e^{i\\phi}$ doesn't have any impact on the resulting qubit state.</p>\n<blockquote>\n<p>We can also calculate ${\\theta}$ by comparing the amplitudes of the state $|1 \\rangle$ in the two equations, which is $2 \\arcsin\\sqrt{1.0 - x}$</p>\n</blockquote>\n",
|
|
1800
|
+
"asMarkdown": "\nAn arbitrary single-qubit state can be written as:\n\n$$\n|\\psi\\rangle =\n \\cos \\frac{\\theta}{2} |0 \\rangle \\, + \\, e^{i\\phi} \\sin \\frac{\\theta}{2} |1\\rangle\n$$\n\nHere, $\\theta$ is the angle between the state vector and the $Z$-axis, and $\\phi$ is the longitude angle with respect to the $X$-axis on the Bloch sphere.\n\nOur goal is to generate $0$ or $1$ with the probability of generating a $0$ equal to $x$ and the probability of generating a $1$ equal to $1 - x$. This means that the qubit state should look like\n\n$$\n|\\psi\\rangle =\n \\sqrt x |0 \\rangle + \\sqrt{1 - x} |1\\rangle\n$$\n\nComparing the amplitudes of the state $|0 \\rangle$ in the two equations, we get\n\n$$\n\\sqrt x = \\cos \\frac{\\theta}{2} \\Rightarrow \\theta = 2 \\arccos\\sqrt x\n$$\n\nSince $\\theta$ is the angle between the state vector and the $Z$-axis, we need to apply the [`Ry`](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.ry) gate with the calculated $\\theta$ to the starting state $|0 \\rangle$ to get the desired qubit state.\n\nThe `Ry` operation applies a given rotation about the $Y$-axis (i.e., in the $ZX$-plane). Hence, $\\phi$ (longitude angle with respect to $X$-axis) is always equal to $0^{\\circ}$, which means that the relative phase $e^{i\\phi}$ doesn't have any impact on the resulting qubit state.\n\n> We can also calculate ${\\theta}$ by comparing the amplitudes of the state $|1 \\rangle$ in the two equations, which is $2 \\arcsin\\sqrt{1.0 - x}$"
|
|
1801
|
+
},
|
|
1802
|
+
{
|
|
1803
|
+
"type": "solution",
|
|
1804
|
+
"id": "random_numbers__weighted_random_bit_solution",
|
|
1805
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation WeightedRandomBit(x : Double): Int {\n // Calculate theta value.\n let theta = 2.0 * ArcCos(Sqrt(x)); // (or) 2.0 * ArcSin(Sqrt(1.0 - x));\n\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state which aligns with given probabilities.\n Ry(theta, q);\n\n\n // Measuring state of qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Reset qubit and return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n\n}\n"
|
|
1806
|
+
}
|
|
1807
|
+
]
|
|
1808
|
+
}
|
|
1809
|
+
},
|
|
1810
|
+
{
|
|
1811
|
+
"type": "exercise",
|
|
1812
|
+
"id": "random_numbers__random_number",
|
|
1813
|
+
"title": "Generate a Random Number Between Min and Max",
|
|
1814
|
+
"description": {
|
|
1815
|
+
"type": "text-content",
|
|
1816
|
+
"asHtml": "<p>In the "Generate A Number Of Arbitrary Size" exercise, we generated numbers in the range $[0, 2^N-1]$ $(1 \\leq N \\leq 10)$. Now let's create an operation that will return a random number in the range $[min, max]$. </p>\n<p><strong>Input:</strong> \nTwo integers $min$ and $max$ ($0 \\leq min \\leq max \\leq 2^{10}-1$).</p>\n<p><strong>Goal:</strong> Generate a random number in the range $[min, max]$ with an equal probability of getting each of the numbers in this range.</p>\n<blockquote>\n<p>Useful Q# documentation: </p>\n<ul>\n<li><a href=\"https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.math.bitsizei\" target=\"_blank\"><code>BitSizeI</code> function</a></li>\n</ul>\n</blockquote>\n",
|
|
1817
|
+
"asMarkdown": "In the \"Generate A Number Of Arbitrary Size\" exercise, we generated numbers in the range $[0, 2^N-1]$ $(1 \\leq N \\leq 10)$. Now let's create an operation that will return a random number in the range $[min, max]$. \n\n**Input:** \nTwo integers $min$ and $max$ ($0 \\leq min \\leq max \\leq 2^{10}-1$).\n\n**Goal:** Generate a random number in the range $[min, max]$ with an equal probability of getting each of the numbers in this range.\n\n> Useful Q# documentation: \n> * <a href=\"https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.math.bitsizei\" target=\"_blank\">`BitSizeI` function</a>\n\n"
|
|
1818
|
+
},
|
|
1819
|
+
"sourceIds": [
|
|
1820
|
+
"random_numbers__random_number__verification.qs",
|
|
1821
|
+
"KatasLibrary.qs",
|
|
1822
|
+
"random_numbers__common.qs"
|
|
1823
|
+
],
|
|
1824
|
+
"placeholderCode": "namespace Kata {\n operation RandomNumberInRange(min : Int, max : Int) : Int {\n // Implement your solution here...\n\n return -1;\n }\n\n // You can use this operation to implement your solution.\n operation RandomBit() : Int {\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state.\n H(q);\n\n // Measuring the qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n}\n",
|
|
1825
|
+
"explainedSolution": {
|
|
1826
|
+
"type": "explained-solution",
|
|
1827
|
+
"items": [
|
|
1828
|
+
{
|
|
1829
|
+
"type": "text-content",
|
|
1830
|
+
"asHtml": "<p>We can reuse the <code>RandomBit</code> operation from the "Generate A Single Random Bit" exercise.</p>\n<p>We'll generate an $N$-bit random number by calling the <code>RandomNBits</code> operation, where N is the bitsize of $max - min$. We can repeat this process until the result is less than or equal than $max - min$, and return that number plus $min$.</p>\n",
|
|
1831
|
+
"asMarkdown": "\nWe can reuse the `RandomBit` operation from the \"Generate A Single Random Bit\" exercise.\n\nWe'll generate an $N$-bit random number by calling the `RandomNBits` operation, where N is the bitsize of $max - min$. We can repeat this process until the result is less than or equal than $max - min$, and return that number plus $min$."
|
|
1832
|
+
},
|
|
1833
|
+
{
|
|
1834
|
+
"type": "solution",
|
|
1835
|
+
"id": "random_numbers__random_number_solution",
|
|
1836
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation RandomNumberInRange(min: Int, max: Int): Int {\n let nBits = BitSizeI(max - min);\n mutable output = 0; \n repeat {\n set output = RandomNBits(nBits); \n } until output <= max - min;\n return output + min;\n }\n\n operation RandomNBits(N: Int): Int {\n mutable result = 0;\n for i in 0..(N - 1) {\n set result = result * 2 + RandomBit();\n }\n return result;\n }\n\n operation RandomBit() : Int {\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state.\n H(q);\n\n // Measuring the qubit and reset.\n let result = M(q);\n Reset(q);\n \n // Return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n}\n"
|
|
1837
|
+
}
|
|
1838
|
+
]
|
|
1839
|
+
}
|
|
1840
|
+
},
|
|
1841
|
+
{
|
|
1842
|
+
"type": "lesson",
|
|
1843
|
+
"id": "random_numbers__whats_next",
|
|
1844
|
+
"title": "What's Next?",
|
|
1845
|
+
"items": [
|
|
1846
|
+
{
|
|
1847
|
+
"type": "text-content",
|
|
1848
|
+
"asHtml": "<p>Congratulations! In this Kata you have created a truly random number generator using quantum computing. Here are a few key concepts to keep in mind:</p>\n<ul>\n<li>You can generate a random bit by applying a Hadamard gate to a state $\\ket{0}$, and then measuring the resulting qubit in the computational basis.</li>\n<li>The Q# <a href=\"https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.math.bitsizei\" target=\"_blank\">BitSizeI function</a> returns the numbers of bits needed to write an integer in binary.</li>\n</ul>\n<p><strong>Next Steps</strong></p>\n<p>We hope you enjoyed this Kata on quantum random number generation! If you're looking to learn more about quantum computing and Q#, here are some suggestions:</p>\n<ul>\n<li>To learn about superposition, interference and entanglement by using Q#, you can check <a href=\"https://learn.microsoft.com/en-us/training/modules/qsharp-explore-key-concepts-quantum-computing/\" target=\"_blank\">Microsoft Learn module "Explore the key concepts of quantum computing by using Q#"</a>.</li>\n<li>For another look at quantum random number generation, you can check out the <a href=\"https://docs.microsoft.com/learn/modules/qsharp-create-first-quantum-development-kit/1-introduction\" target=\"_blank\">Microsoft Learn module "Create your first Q# program by using the Quantum Development Kit"</a>.</li>\n</ul>\n",
|
|
1849
|
+
"asMarkdown": "\nCongratulations! In this Kata you have created a truly random number generator using quantum computing. Here are a few key concepts to keep in mind:\n* You can generate a random bit by applying a Hadamard gate to a state $\\ket{0}$, and then measuring the resulting qubit in the computational basis.\n* The Q# <a href=\"https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.math.bitsizei\" target=\"_blank\">BitSizeI function</a> returns the numbers of bits needed to write an integer in binary.\n\n**Next Steps**\n\nWe hope you enjoyed this Kata on quantum random number generation! If you're looking to learn more about quantum computing and Q#, here are some suggestions:\n* To learn about superposition, interference and entanglement by using Q#, you can check <a href=\"https://learn.microsoft.com/en-us/training/modules/qsharp-explore-key-concepts-quantum-computing/\" target=\"_blank\">Microsoft Learn module \"Explore the key concepts of quantum computing by using Q#\"</a>.\n* For another look at quantum random number generation, you can check out the <a href=\"https://docs.microsoft.com/learn/modules/qsharp-create-first-quantum-development-kit/1-introduction\" target=\"_blank\">Microsoft Learn module \"Create your first Q# program by using the Quantum Development Kit\"</a>."
|
|
1850
|
+
}
|
|
1851
|
+
]
|
|
1852
|
+
}
|
|
1853
|
+
]
|
|
1854
|
+
},
|
|
1855
|
+
{
|
|
1856
|
+
"id": "oracles",
|
|
1857
|
+
"title": "Oracles",
|
|
1858
|
+
"sections": [
|
|
1859
|
+
{
|
|
1860
|
+
"type": "lesson",
|
|
1861
|
+
"id": "oracles__overview",
|
|
1862
|
+
"title": "Overview",
|
|
1863
|
+
"items": [
|
|
1864
|
+
{
|
|
1865
|
+
"type": "text-content",
|
|
1866
|
+
"asHtml": "<p>Quantum oracles are a key part of many quantum algorithms that rely on quantum implementation of a classical function. The algorithms' discussions often assume that the quantum oracle that implements the function of interest is provided. This kata dives deeper into the definition of different types of quantum oracles, their properties, and the basic ways to implement the oracles.</p>\n<p><strong>This kata covers the following topics:</strong></p>\n<ul>\n<li>Quantum oracles and how they relate to classical oracles</li>\n<li>Two types of quantum oracles - phase oracles and marking oracles</li>\n<li>Phase kickback and its uses for oracles implementation</li>\n<li>Implementation and testing of quantum oracles in Q#</li>\n</ul>\n<p><strong>What you should know to start working on this kata:</strong></p>\n<ul>\n<li>Fundamental quantum concepts</li>\n<li>Multi-qubit gates (especially controlled gates)</li>\n</ul>\n",
|
|
1867
|
+
"asMarkdown": "\nQuantum oracles are a key part of many quantum algorithms that rely on quantum implementation of a classical function. The algorithms' discussions often assume that the quantum oracle that implements the function of interest is provided. This kata dives deeper into the definition of different types of quantum oracles, their properties, and the basic ways to implement the oracles.\n\n**This kata covers the following topics:**\n\n- Quantum oracles and how they relate to classical oracles\n- Two types of quantum oracles - phase oracles and marking oracles\n- Phase kickback and its uses for oracles implementation\n- Implementation and testing of quantum oracles in Q#\n\n**What you should know to start working on this kata:**\n\n- Fundamental quantum concepts\n- Multi-qubit gates (especially controlled gates)"
|
|
1868
|
+
}
|
|
1869
|
+
]
|
|
1870
|
+
},
|
|
1871
|
+
{
|
|
1872
|
+
"type": "lesson",
|
|
1873
|
+
"id": "oracles__classical_oracles",
|
|
1874
|
+
"title": "Classical Oracles",
|
|
1875
|
+
"items": [
|
|
1876
|
+
{
|
|
1877
|
+
"type": "text-content",
|
|
1878
|
+
"asHtml": "<p>In classical computing, we often discuss "black box" versus "white box" testing. In "white box" testing, the implementation of a function is visible to the tester, thus they can verify specific runtime or memory complexity expectations for the algorithm.<br>However, in "black box" testing, the tester doesn't have access to the details of the function implementation. They only have access to the "black box" that takes an input and produces the corresponding output. This means the tester can only test the functionality and expected behavior of the function, but not the implementation, which is hidden behind abstraction.</p>\n<p>Formally, a <strong>classical oracle</strong> is a function that, provided some input, produces a <em>deterministic</em> output\n(the same input <em>always</em> results in the same output).</p>\n<p>Some classical problems (typically <a href=\"https://en.wikipedia.org/wiki/Decision_problem\" target=\"_blank\">decision problems</a>) are also expressed in terms of oracles; in this case we do not care about how the function is implemented, but only about the functionality that it provides. </p>\n<blockquote>\n<p>Suppose I provided you a function which takes two list parameters as input, where these lists represent the availability of two employees at a company during the week. The function returns true if there is a day (Monday, Tuesday, Wednesday, Thursday, or Friday) for which they are both free and could schedule a meeting, and false if no such date exists.</p>\n<p>This function is an example of a classical oracle.</p>\n</blockquote>\n",
|
|
1879
|
+
"asMarkdown": "\nIn classical computing, we often discuss \"black box\" versus \"white box\" testing. In \"white box\" testing, the implementation of a function is visible to the tester, thus they can verify specific runtime or memory complexity expectations for the algorithm. \nHowever, in \"black box\" testing, the tester doesn't have access to the details of the function implementation. They only have access to the \"black box\" that takes an input and produces the corresponding output. This means the tester can only test the functionality and expected behavior of the function, but not the implementation, which is hidden behind abstraction.\n\nFormally, a **classical oracle** is a function that, provided some input, produces a *deterministic* output\n(the same input *always* results in the same output).\n\nSome classical problems (typically <a href=\"https://en.wikipedia.org/wiki/Decision_problem\" target=\"_blank\">decision problems</a>) are also expressed in terms of oracles; in this case we do not care about how the function is implemented, but only about the functionality that it provides. \n\n> Suppose I provided you a function which takes two list parameters as input, where these lists represent the availability of two employees at a company during the week. The function returns true if there is a day (Monday, Tuesday, Wednesday, Thursday, or Friday) for which they are both free and could schedule a meeting, and false if no such date exists.\n>\n> This function is an example of a classical oracle."
|
|
1880
|
+
}
|
|
1881
|
+
]
|
|
1882
|
+
},
|
|
1883
|
+
{
|
|
1884
|
+
"type": "exercise",
|
|
1885
|
+
"id": "oracles__implement_classical_oracles",
|
|
1886
|
+
"title": "Implement a Classical Oracle",
|
|
1887
|
+
"description": {
|
|
1888
|
+
"type": "text-content",
|
|
1889
|
+
"asHtml": "<p><strong>Input:</strong> \n A bit vector of length 3 represented as a <code>Bool[]</code> - a binary representation of a number.</p>\n<p><strong>Output:</strong>\n Return <code>true</code> if the input array represents the number $7$, and <code>false</code> otherwise.</p>\n<p><strong>Examples:</strong></p>\n<ul>\n<li>If the input array is <code>[true, true, true]</code>, return <code>true</code>.</li>\n<li>If the input array is <code>[true, true, false]</code>, return <code>false</code>.</li>\n</ul>\n",
|
|
1890
|
+
"asMarkdown": "**Input:** \n A bit vector of length 3 represented as a `Bool[]` - a binary representation of a number.\n\n**Output:**\n Return `true` if the input array represents the number $7$, and `false` otherwise.\n\n**Examples:**\n\n* If the input array is `[true, true, true]`, return `true`.\n* If the input array is `[true, true, false]`, return `false`.\n"
|
|
1891
|
+
},
|
|
1892
|
+
"sourceIds": [
|
|
1893
|
+
"KatasLibrary.qs",
|
|
1894
|
+
"oracles__common.qs",
|
|
1895
|
+
"oracles__classical_oracles__verification.qs"
|
|
1896
|
+
],
|
|
1897
|
+
"placeholderCode": "namespace Kata {\n function IsSeven(x : Bool[]) : Bool {\n // Implement your solution here...\n\n return false;\n }\n}\n",
|
|
1898
|
+
"explainedSolution": {
|
|
1899
|
+
"type": "explained-solution",
|
|
1900
|
+
"items": [
|
|
1901
|
+
{
|
|
1902
|
+
"type": "solution",
|
|
1903
|
+
"id": "oracles__classical_oracles_solution",
|
|
1904
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Convert;\n\n function IsSeven(x: Bool[]): Bool {\n return BoolArrayAsInt(x) == 7;\n }\n}\n"
|
|
1905
|
+
}
|
|
1906
|
+
]
|
|
1907
|
+
}
|
|
1908
|
+
},
|
|
1909
|
+
{
|
|
1910
|
+
"type": "lesson",
|
|
1911
|
+
"id": "oracles__quantum_oracles",
|
|
1912
|
+
"title": "Quantum Oracles",
|
|
1913
|
+
"items": [
|
|
1914
|
+
{
|
|
1915
|
+
"type": "text-content",
|
|
1916
|
+
"asHtml": "<p>An oracle in the quantum world is a "black box" operation that is used as input to an algorithm (such as Deutsch-Jozsa algorithm or Grover's search algorithm). \nMany quantum algorithms assume an oracle implementation of some classical function as input, but this is a very strong assumption - sometimes implementing the oracle for a function is a lot more complex than the algorithm that will use this oracle!<br>In this kata, you will learn the properties of quantum oracles and how to implement them.</p>\n<p>A quantum oracle implements a function $f: \\{0,1\\}^n \\rightarrow \\{0,1\\}^m$, where the input is $n$-bits of the form $x = (x_{0}, x_{1}, \\dots, x_{n-1})$. In most commonly used cases $m=1$, that is, the function can return values $0$ or $1$. In this kata, we will focus on this class of functions.</p>\n<p>Quantum oracles operate on qubit arrays (and can take classical parameters as well). The classical input is encoded into the state of an $n$-qubit register:<br>$$|x\\rangle = |x_0\\rangle \\otimes |x_1\\rangle \\otimes ... \\otimes |x_{n-1}\\rangle,$$ \nwhere $|x_i\\rangle$ represents the state of the $i$-th qubit. </p>\n<p>Oracles must be unitary transformations, and follow the same rules of linear algebra as other quantum operations.\nThis allows us to define quantum oracles based on their effect on the basis states - tensor products of single-qubit basis states $|0\\rangle$ and $|1\\rangle$. </p>\n<blockquote>\n<p>For example, an oracle that implements a function that takes 2 bits of input will be defined using its effect on basis states $|00\\rangle$, $|01\\rangle$, $|10\\rangle$, and $|11\\rangle$. </p>\n</blockquote>\n<p>There are two types of quantum oracles: phase oracles and marking oracles. Let's take a closer look at them.</p>\n<h2 id=\"phase-oracles\">Phase Oracles</h2>\n<p>For a function $f: \\{0,1\\}^n \\rightarrow \\{0,1\\}$, the phase oracle $U_{\\text{phase}}$ encodes the the values $f(0)$ and $f(1)$ in the relative phases of basis states $\\ket{0}$ and $\\ket{1}$, respectively.</p>\n<p>$$U_{phase} |\\vec{x}\\rangle = (-1)^{f(x)}|\\vec{x}\\rangle$$</p>\n<p>Thus, the phase oracle $U_{\\text{phase}}$ doesn't change the phase of the basis states for which $f(x)=0$, but multiplies the phase of the basis states for which $f(x)=1$ by $-1$.</p>\n<p>The effect of such an oracle on any single basis state is not particularly interesting: it just adds a global phase which is not something you can observe. However, if you apply this oracle to a <em>superposition</em> of basis states, its effect becomes noticeable. \nRemember that quantum operations are linear: if you define the effect of an operation on the basis states, you'll be able to deduce its effect on superposition states (which are just linear combinations of the basis states) using its linearity. </p>\n<p>A phase oracle doesn't have an "output", unlike the function it implements; the effect of the oracle application is the change in the state of the system.</p>\n",
|
|
1917
|
+
"asMarkdown": "\nAn oracle in the quantum world is a \"black box\" operation that is used as input to an algorithm (such as Deutsch-Jozsa algorithm or Grover's search algorithm). \nMany quantum algorithms assume an oracle implementation of some classical function as input, but this is a very strong assumption - sometimes implementing the oracle for a function is a lot more complex than the algorithm that will use this oracle! \nIn this kata, you will learn the properties of quantum oracles and how to implement them.\n\nA quantum oracle implements a function $f: \\\\{0,1\\\\}^n \\rightarrow \\\\{0,1\\\\}^m$, where the input is $n$-bits of the form $x = (x_{0}, x_{1}, \\dots, x_{n-1})$. In most commonly used cases $m=1$, that is, the function can return values $0$ or $1$. In this kata, we will focus on this class of functions.\n\nQuantum oracles operate on qubit arrays (and can take classical parameters as well). The classical input is encoded into the state of an $n$-qubit register: \n$$|x\\rangle = |x_0\\rangle \\otimes |x_1\\rangle \\otimes ... \\otimes |x_{n-1}\\rangle,$$ \nwhere $|x_i\\rangle$ represents the state of the $i$-th qubit. \n\nOracles must be unitary transformations, and follow the same rules of linear algebra as other quantum operations.\nThis allows us to define quantum oracles based on their effect on the basis states - tensor products of single-qubit basis states $|0\\rangle$ and $|1\\rangle$. \n\n> For example, an oracle that implements a function that takes 2 bits of input will be defined using its effect on basis states $|00\\rangle$, $|01\\rangle$, $|10\\rangle$, and $|11\\rangle$. \n\nThere are two types of quantum oracles: phase oracles and marking oracles. Let's take a closer look at them.\n\n## Phase Oracles\n\nFor a function $f: \\\\{0,1\\\\}^n \\rightarrow \\\\{0,1\\\\}$, the phase oracle $U_{\\text{phase}}$ encodes the the values $f(0)$ and $f(1)$ in the relative phases of basis states $\\ket{0}$ and $\\ket{1}$, respectively.\n\n$$U_{phase} |\\vec{x}\\rangle = (-1)^{f(x)}|\\vec{x}\\rangle$$\n\nThus, the phase oracle $U_{\\text{phase}}$ doesn't change the phase of the basis states for which $f(x)=0$, but multiplies the phase of the basis states for which $f(x)=1$ by $-1$.\n\nThe effect of such an oracle on any single basis state is not particularly interesting: it just adds a global phase which is not something you can observe. However, if you apply this oracle to a *superposition* of basis states, its effect becomes noticeable. \nRemember that quantum operations are linear: if you define the effect of an operation on the basis states, you'll be able to deduce its effect on superposition states (which are just linear combinations of the basis states) using its linearity. \n\nA phase oracle doesn't have an \"output\", unlike the function it implements; the effect of the oracle application is the change in the state of the system."
|
|
1918
|
+
}
|
|
1919
|
+
]
|
|
1920
|
+
},
|
|
1921
|
+
{
|
|
1922
|
+
"type": "lesson",
|
|
1923
|
+
"id": "oracles__phase_oracle",
|
|
1924
|
+
"title": "Phase Oracle for Alternating Bit Pattern Function",
|
|
1925
|
+
"items": [
|
|
1926
|
+
{
|
|
1927
|
+
"type": "text-content",
|
|
1928
|
+
"asHtml": "<p>Consider the function $f(x)$ that takes $3$ bits of input and returns $1$ if $x=101$ or $x=010$, and $0$ otherwise.</p>\n<p>The phase oracle that implements this function will take an array of 3 qubits as an input, flip the sign of basis states $|101\\rangle$ and $|010\\rangle$, and leave the rest of the basis states unchanged. Let's see the effect of this oracle on a superposition state.</p>\n",
|
|
1929
|
+
"asMarkdown": "\nConsider the function $f(x)$ that takes $3$ bits of input and returns $1$ if $x=101$ or $x=010$, and $0$ otherwise.\n\nThe phase oracle that implements this function will take an array of 3 qubits as an input, flip the sign of basis states $|101\\rangle$ and $|010\\rangle$, and leave the rest of the basis states unchanged. Let's see the effect of this oracle on a superposition state."
|
|
1930
|
+
},
|
|
1931
|
+
{
|
|
1932
|
+
"type": "example",
|
|
1933
|
+
"id": "oracles__phase_oracle_alt_bit",
|
|
1934
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n\n // This operation implements the oracle; we will learn how to implement oracles later in the kata\n operation AlternatingBitPattern_PhaseOracle(x: Qubit[]): Unit is Adj + Ctl {\n use q = Qubit();\n X(q);\n ApplyControlledOnBitString([false, true, false], Z, x, q);\n ApplyControlledOnBitString([true, false, true], Z, x, q);\n X(q);\n }\n\n @EntryPoint()\n operation PhaseOracle_Demo(): Unit {\n // Allocate 3 qubits in the |000⟩ state\n use q = Qubit[3];\n // Prepare an equal superposition of all basis states\n ApplyToEachA(H, q);\n\n // Print the current state of the system; notice the phases of each basis state\n Message(\"Starting state (equal superposition of all basis states):\");\n DumpMachine();\n\n // Apply the oracle\n AlternatingBitPattern_PhaseOracle(q);\n\n // Print the resulting state; notice which phases changed\n Message(\"State after applying the phase oracle:\");\n DumpMachine();\n\n // Reset our state back to all zeros for deallocation\n ResetAll(q);\n }\n \n}\n"
|
|
1935
|
+
},
|
|
1936
|
+
{
|
|
1937
|
+
"type": "text-content",
|
|
1938
|
+
"asHtml": "<p>We introduced the function <a href=\"https://learn.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.canon.applycontrolledonbitstring\" target=\"_blank\"><code>ApplyControlledOnBitString</code></a> provided by the Q# Standard library.\nIt defines a variant of a gate controlled on a state specified by a bit mask; for example, bit mask <code>[true, false]</code> means that the gate should be applied only if the two control qubits are in the $|10\\rangle$ state.</p>\n<p>The sequence of steps that implement this variant are:</p>\n<ol>\n<li>Apply the $X$ gate to each control qubit that corresponds to a <code>false</code> element of the bit mask. After this, if the control qubits started in the $|10\\rangle$ state, they'll end up in the $|11\\rangle$ state, and if they started in any other state, they'll end up in any state but $|11\\rangle$.</li>\n<li>Apply the regular controlled version of the gate.</li>\n<li>Apply the $X$ gate to the same qubits to return them to their original state.</li>\n</ol>\n<p>Due to this <a href=\"https://learn.microsoft.com/en-us/azure/quantum/user-guide/language/statements/conjugations\" target=\"_blank\">conjugation pattern</a>, the time complexity of this function is $2N$, where N is the number of control qubits.</p>\n<blockquote>\n<p>Notice that the input state in the demo above is an equal superposition of all basis states. \nAfter applying the oracle the absolute values of all amplitudes are the same, but the states $|010\\rangle$ and $|101\\rangle$ had their phase flipped to negative!<br>Recall that these two states are exactly the inputs for which $f(x) = 1$, thus they are exactly the two states we expect to experience a phase flip!</p>\n</blockquote>\n<p>In the next exercise you will implement the classical oracle that you've implemented in the first exercise, this time as a quantum phase oracle $U_{7,\\text{phase}}$ that encodes the number 7.</p>\n",
|
|
1939
|
+
"asMarkdown": "\nWe introduced the function <a href=\"https://learn.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.canon.applycontrolledonbitstring\" target=\"_blank\">`ApplyControlledOnBitString`</a> provided by the Q# Standard library.\nIt defines a variant of a gate controlled on a state specified by a bit mask; for example, bit mask `[true, false]` means that the gate should be applied only if the two control qubits are in the $|10\\rangle$ state.\n \nThe sequence of steps that implement this variant are:\n1. Apply the $X$ gate to each control qubit that corresponds to a `false` element of the bit mask. After this, if the control qubits started in the $|10\\rangle$ state, they'll end up in the $|11\\rangle$ state, and if they started in any other state, they'll end up in any state but $|11\\rangle$.\n2. Apply the regular controlled version of the gate.\n3. Apply the $X$ gate to the same qubits to return them to their original state.\n\nDue to this <a href=\"https://learn.microsoft.com/en-us/azure/quantum/user-guide/language/statements/conjugations\" target=\"_blank\">conjugation pattern</a>, the time complexity of this function is $2N$, where N is the number of control qubits.\n\n> Notice that the input state in the demo above is an equal superposition of all basis states. \nAfter applying the oracle the absolute values of all amplitudes are the same, but the states $|010\\rangle$ and $|101\\rangle$ had their phase flipped to negative! \n> Recall that these two states are exactly the inputs for which $f(x) = 1$, thus they are exactly the two states we expect to experience a phase flip!\n\nIn the next exercise you will implement the classical oracle that you've implemented in the first exercise, this time as a quantum phase oracle $U_{7,\\text{phase}}$ that encodes the number 7."
|
|
1940
|
+
}
|
|
1941
|
+
]
|
|
1942
|
+
},
|
|
1943
|
+
{
|
|
1944
|
+
"type": "exercise",
|
|
1945
|
+
"id": "oracles__phase_oracle_seven",
|
|
1946
|
+
"title": "Implement a Phase Oracle",
|
|
1947
|
+
"description": {
|
|
1948
|
+
"type": "text-content",
|
|
1949
|
+
"asHtml": "<p><strong>Input:</strong>\n 3 qubits in an arbitrary state $|x\\rangle$ (input/query register).</p>\n<p><strong>Goal:</strong></p>\n<p>Flip the sign of the input state $|x\\rangle$ if the input register is in\nthe state $|111\\rangle$ (encoding the integer $7$), and leave the input register unchanged otherwise.<br>Don't allocate extra qubits to perform this operation.</p>\n<p><strong>Examples:</strong></p>\n<ul>\n<li>If the query register is in the state $|111\\rangle$, flip its sign.</li>\n<li>If the query register is in the state $|010\\rangle$ or $|101\\rangle$, do nothing.</li>\n</ul>\n<details>\n <summary><b>Need a hint?</b></summary>\n To solve this problem, you need to find a gate that will only flip the sign of the $|111\\rangle$ basis state. Which single-qubit gate flips the sign of the basis state $|1\\rangle$ but not $|0\\rangle$? How can you modify this gate to solve this problem?\n</details>\n",
|
|
1950
|
+
"asMarkdown": "**Input:**\n 3 qubits in an arbitrary state $|x\\rangle$ (input/query register).\n\n**Goal:**\n\nFlip the sign of the input state $|x\\rangle$ if the input register is in\nthe state $|111\\rangle$ (encoding the integer $7$), and leave the input register unchanged otherwise. \nDon't allocate extra qubits to perform this operation.\n\n**Examples:**\n\n* If the query register is in the state $|111\\rangle$, flip its sign.\n* If the query register is in the state $|010\\rangle$ or $|101\\rangle$, do nothing.\n\n<details>\n <summary><b>Need a hint?</b></summary>\n To solve this problem, you need to find a gate that will only flip the sign of the $|111\\rangle$ basis state. Which single-qubit gate flips the sign of the basis state $|1\\rangle$ but not $|0\\rangle$? How can you modify this gate to solve this problem?\n</details>\n"
|
|
1951
|
+
},
|
|
1952
|
+
"sourceIds": [
|
|
1953
|
+
"KatasLibrary.qs",
|
|
1954
|
+
"oracles__common.qs",
|
|
1955
|
+
"oracles__phase_oracle_seven__verification.qs"
|
|
1956
|
+
],
|
|
1957
|
+
"placeholderCode": "namespace Kata {\n operation IsSeven_PhaseOracle(x : Qubit[]) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
1958
|
+
"explainedSolution": {
|
|
1959
|
+
"type": "explained-solution",
|
|
1960
|
+
"items": [
|
|
1961
|
+
{
|
|
1962
|
+
"type": "solution",
|
|
1963
|
+
"id": "oracles__phase_oracle_seven_solution",
|
|
1964
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Arrays;\n\n operation IsSeven_PhaseOracle(x: Qubit[]): Unit is Adj + Ctl {\n Controlled Z(Most(x), Tail(x));\n }\n}\n"
|
|
1965
|
+
},
|
|
1966
|
+
{
|
|
1967
|
+
"type": "text-content",
|
|
1968
|
+
"asHtml": "<p>Consider how the oracle acts on two basis states:\n$$U_{7,phase} |111\\rangle = -|111\\rangle$$\n$$U_{7,phase} |110\\rangle = |110\\rangle$$</p>\n<p>You can see that $U_{7,phase}$ does not change the input if it's a basis state (other than adding a global phase), and $U_{7,phase}$ does not change the norm of the state ($U_{7,phase}$ is a unitary operator). </p>\n<p>However, if we applied this oracle to a superposition state instead, what will that look like?</p>\n<p>Suppose that $|\\beta\\rangle$ is an equal superposition of the $|6\\rangle$ and $|7\\rangle$ states (encoded in big endian, with most significant bit first): \n$$|\\beta\\rangle = \\frac{1}{\\sqrt{2}} \\big(|110\\rangle + |111\\rangle\\big) = |11\\rangle \\otimes \\frac{1}{\\sqrt{2}} \\big(|0\\rangle + |1\\rangle\\big) = |11\\rangle \\otimes |+\\rangle = |11+\\rangle$$</p>\n<p>Let's consider how our operator $U_{7,phase}$ acts on this state:</p>\n<p>$$U_{7,phase} |\\beta\\rangle = U_{7,phase} \\Big[\\frac{1}{\\sqrt{2}} \\big(|110\\rangle + |111\\rangle\\big)\\Big]$$</p>\n<p>$$= \\frac{1}{\\sqrt{2}} \\big(U_{7,phase} |110\\rangle + U_{7,phase} |111\\rangle\\big)$$</p>\n<p>$$= \\frac{1}{\\sqrt{2}} \\big(|110\\rangle - |111\\rangle\\big) := |\\gamma\\rangle$$</p>\n<p>Was our input state modified during this operation? Let's simplify $|\\gamma\\rangle$:</p>\n<p>$$|\\gamma\\rangle = \\frac{1}{\\sqrt{2}} \\big(|110\\rangle - |111\\rangle\\big)$$</p>\n<p>$$= |11\\rangle \\otimes \\frac{1}{\\sqrt{2}} \\big(|0\\rangle - |1\\rangle\\big)$$</p>\n<p>$$= |11\\rangle \\otimes |-\\rangle = |11-\\rangle \\neq |\\beta\\rangle$$</p>\n<p>Here we see that the oracle modifies the input, if the input state was a <em>superposition</em> of the basis states, as a phase oracle will only modify the sign of the basis states. Thus when a superposition state is provided as input to an oracle, the input state can be modified via the application of the quantum oracle.</p>\n<blockquote>\n<p>It is also worth noting that while the oracle modified the input when provided a superposition state, it did <em>not</em> modify the norm of that state. As an exercise, you can verify this yourself by taking the norm of $|\\beta\\rangle$ and $|\\gamma\\rangle$, which both will result in a value of $1$.</p>\n<p>As another exercise, consider how you could distinguish between the input and output state programmatically? Is there an operation that you could apply to the initial state $|\\beta\\rangle$ and the final state $|\\gamma\\rangle$ to show that the two states are not equivalent through measurement? As a hint, think about how you could convert the superposition states $|\\beta\\rangle$ and $|\\gamma\\rangle$ into the basis states.</p>\n</blockquote>\n",
|
|
1969
|
+
"asMarkdown": "\nConsider how the oracle acts on two basis states:\n$$U_{7,phase} |111\\rangle = -|111\\rangle$$\n$$U_{7,phase} |110\\rangle = |110\\rangle$$\n\nYou can see that $U_{7,phase}$ does not change the input if it's a basis state (other than adding a global phase), and $U_{7,phase}$ does not change the norm of the state ($U_{7,phase}$ is a unitary operator). \n\nHowever, if we applied this oracle to a superposition state instead, what will that look like?\n\nSuppose that $|\\beta\\rangle$ is an equal superposition of the $|6\\rangle$ and $|7\\rangle$ states (encoded in big endian, with most significant bit first): \n$$|\\beta\\rangle = \\frac{1}{\\sqrt{2}} \\big(|110\\rangle + |111\\rangle\\big) = |11\\rangle \\otimes \\frac{1}{\\sqrt{2}} \\big(|0\\rangle + |1\\rangle\\big) = |11\\rangle \\otimes |+\\rangle = |11+\\rangle$$\n\nLet's consider how our operator $U_{7,phase}$ acts on this state:\n\n$$U_{7,phase} |\\beta\\rangle = U_{7,phase} \\Big[\\frac{1}{\\sqrt{2}} \\big(|110\\rangle + |111\\rangle\\big)\\Big]$$\n\n$$= \\frac{1}{\\sqrt{2}} \\big(U_{7,phase} |110\\rangle + U_{7,phase} |111\\rangle\\big)$$\n\n$$= \\frac{1}{\\sqrt{2}} \\big(|110\\rangle - |111\\rangle\\big) := |\\gamma\\rangle$$\n\nWas our input state modified during this operation? Let's simplify $|\\gamma\\rangle$:\n\n$$|\\gamma\\rangle = \\frac{1}{\\sqrt{2}} \\big(|110\\rangle - |111\\rangle\\big)$$\n\n$$= |11\\rangle \\otimes \\frac{1}{\\sqrt{2}} \\big(|0\\rangle - |1\\rangle\\big)$$\n\n$$= |11\\rangle \\otimes |-\\rangle = |11-\\rangle \\neq |\\beta\\rangle$$\n\nHere we see that the oracle modifies the input, if the input state was a *superposition* of the basis states, as a phase oracle will only modify the sign of the basis states. Thus when a superposition state is provided as input to an oracle, the input state can be modified via the application of the quantum oracle.\n\n> It is also worth noting that while the oracle modified the input when provided a superposition state, it did *not* modify the norm of that state. As an exercise, you can verify this yourself by taking the norm of $|\\beta\\rangle$ and $|\\gamma\\rangle$, which both will result in a value of $1$.\n>\n> As another exercise, consider how you could distinguish between the input and output state programmatically? Is there an operation that you could apply to the initial state $|\\beta\\rangle$ and the final state $|\\gamma\\rangle$ to show that the two states are not equivalent through measurement? As a hint, think about how you could convert the superposition states $|\\beta\\rangle$ and $|\\gamma\\rangle$ into the basis states."
|
|
1970
|
+
}
|
|
1971
|
+
]
|
|
1972
|
+
}
|
|
1973
|
+
},
|
|
1974
|
+
{
|
|
1975
|
+
"type": "lesson",
|
|
1976
|
+
"id": "oracles__marking_oracles",
|
|
1977
|
+
"title": "Marking Oracles",
|
|
1978
|
+
"items": [
|
|
1979
|
+
{
|
|
1980
|
+
"type": "text-content",
|
|
1981
|
+
"asHtml": "<p>A marking oracle $U_{mark}$ is an oracle that encodes the value of the classical function $f$ it implements in the <em>amplitude</em> of the qubit state. When provided an input array of qubits in the basis state $|\\vec{x}\\rangle$ and an output qubit in the basis state $|y\\rangle$, it flips the state of the output qubit if $f(x)=1$. (You can also represent this as addition modulo 2 between $f(x)$ and $y$.) Hence $U_{mark}$ is an operator that performs the following operation:</p>\n<p>$$U_{mark}|\\vec{x}\\rangle |y\\rangle = U_{mark}\\big(|\\vec{x}\\rangle \\otimes |y\\rangle\\big) = |\\vec{x}\\rangle \\otimes |y \\oplus f(x)\\rangle$$</p>\n<p>Again, since all quantum operations are linear, you can figure out the effect of this operation on superposition state knowing its effect on the basis states using its linearity. </p>\n<p>A marking oracle has distinct "input" and "output" qubits, but in general the effect of the oracle application is the change in the state of the whole system rather than of the "output" qubits only. We will look at this closer in a moment.</p>\n<h2 id=\"marking-oracle-for-alternating-bit-pattern-function\">Marking Oracle for Alternating Bit Pattern Function</h2>\n<p>Consider the function $f(x)$ that takes $3$ bits of input and returns $1$ if $x=101$ or $x=010$, and $0$ otherwise (it is the same function we've seen in demo 1.1).</p>\n<p>The marking oracle that implements this function will take an array of 3 qubits as an "input" register and an "output" qubit, and will flip the state of the output qubit if the input qubit was in basis state $|101\\rangle$ or $|010\\rangle$, and do nothing otherwise. Let's see the effect of this oracle on a superposition state.</p>\n",
|
|
1982
|
+
"asMarkdown": "\nA marking oracle $U_{mark}$ is an oracle that encodes the value of the classical function $f$ it implements in the *amplitude* of the qubit state. When provided an input array of qubits in the basis state $|\\vec{x}\\rangle$ and an output qubit in the basis state $|y\\rangle$, it flips the state of the output qubit if $f(x)=1$. (You can also represent this as addition modulo 2 between $f(x)$ and $y$.) Hence $U_{mark}$ is an operator that performs the following operation:\n\n$$U_{mark}|\\vec{x}\\rangle |y\\rangle = U_{mark}\\big(|\\vec{x}\\rangle \\otimes |y\\rangle\\big) = |\\vec{x}\\rangle \\otimes |y \\oplus f(x)\\rangle$$\n\nAgain, since all quantum operations are linear, you can figure out the effect of this operation on superposition state knowing its effect on the basis states using its linearity. \n\nA marking oracle has distinct \"input\" and \"output\" qubits, but in general the effect of the oracle application is the change in the state of the whole system rather than of the \"output\" qubits only. We will look at this closer in a moment.\n\n## Marking Oracle for Alternating Bit Pattern Function\n\nConsider the function $f(x)$ that takes $3$ bits of input and returns $1$ if $x=101$ or $x=010$, and $0$ otherwise (it is the same function we've seen in demo 1.1).\n\nThe marking oracle that implements this function will take an array of 3 qubits as an \"input\" register and an \"output\" qubit, and will flip the state of the output qubit if the input qubit was in basis state $|101\\rangle$ or $|010\\rangle$, and do nothing otherwise. Let's see the effect of this oracle on a superposition state."
|
|
1983
|
+
},
|
|
1984
|
+
{
|
|
1985
|
+
"type": "example",
|
|
1986
|
+
"id": "oracles__marking_oracle_alt_bit",
|
|
1987
|
+
"code": "namespace Kata {\n\n open Microsoft.Quantum.Diagnostics;\n\n // This operation implements the oracle; we will learn how to implement oracles later in the kata\n operation AlternatingBitPattern_MarkingOracle(x: Qubit[], y: Qubit) : Unit is Adj + Ctl {\n ApplyControlledOnBitString([false, true, false], X, x, y);\n ApplyControlledOnBitString([true, false, true], X, x, y);\n }\n\n @EntryPoint()\n operation MarkingOracle_Demo() : Unit {\n // Allocate the qubits in the |000⟩|0⟩ state\n use (x, y) = (Qubit[3], Qubit());\n // Prepare an equal superposition of all basis states in the input register\n ApplyToEachA(H, x);\n\n // Print the current state of the system; notice the amplitudes of each basis state\n Message(\"Starting state (equal superposition of all basis states ⊗ |0⟩):\");\n DumpMachine();\n\n // Apply the oracle\n AlternatingBitPattern_MarkingOracle(x, y);\n\n // Print the resulting state; notice which amplitudes changed\n Message(\"State after applying the marking oracle:\");\n DumpMachine();\n\n // Reset our state back to all zeros for deallocation\n ResetAll(x + [y]);\n }\n\n}\n"
|
|
1988
|
+
},
|
|
1989
|
+
{
|
|
1990
|
+
"type": "text-content",
|
|
1991
|
+
"asHtml": "<blockquote>\n<p>Let's compare the initial state to the final state from the above demo. \nIn the initial state we had a tensor product of an equal superposition of all 3-qubit basis states and the state $|0\\rangle$. In the final state, this is no longer the case. \nThe basis states $|010\\rangle \\otimes |0\\rangle$ and $|101\\rangle \\otimes |0\\rangle$ no longer have non-zero amplitudes, and instead $|010\\rangle \\otimes |1\\rangle$ and $|101\\rangle \\otimes |1\\rangle$ have non-zero amplitudes.</p>\n<p>This is exactly the result that we expect. Recall our function $f(x)$: $f(x)=1$ if and only if $x=010$ or $x=101$. The first three qubits (variable <code>x</code>) represent the input state $|x\\rangle$, and the last qubit (variable <code>y</code>) represents the output state $|y\\rangle$. Thus when we have the two basis states, $|x\\rangle=|010\\rangle$ or $|x\\rangle=|101\\rangle$, we will flip the state of the qubit $|y\\rangle$, causing these two initial states to be tensored with $|1\\rangle$ in the final state where originally they were tensored with $|0\\rangle$.</p>\n<p>Since the rest of the basis states correspond to $f(x) = 0$, all other basis states in the initial superposition remain unchanged.</p>\n</blockquote>\n<p>Now you will implement the same function you've seen in the first two exercises as a marking oracle $U_{7,mark}$.</p>\n",
|
|
1992
|
+
"asMarkdown": "\n> Let's compare the initial state to the final state from the above demo. \nIn the initial state we had a tensor product of an equal superposition of all 3-qubit basis states and the state $|0\\rangle$. In the final state, this is no longer the case. \nThe basis states $|010\\rangle \\otimes |0\\rangle$ and $|101\\rangle \\otimes |0\\rangle$ no longer have non-zero amplitudes, and instead $|010\\rangle \\otimes |1\\rangle$ and $|101\\rangle \\otimes |1\\rangle$ have non-zero amplitudes.\n>\n> This is exactly the result that we expect. Recall our function $f(x)$: $f(x)=1$ if and only if $x=010$ or $x=101$. The first three qubits (variable `x`) represent the input state $|x\\rangle$, and the last qubit (variable `y`) represents the output state $|y\\rangle$. Thus when we have the two basis states, $|x\\rangle=|010\\rangle$ or $|x\\rangle=|101\\rangle$, we will flip the state of the qubit $|y\\rangle$, causing these two initial states to be tensored with $|1\\rangle$ in the final state where originally they were tensored with $|0\\rangle$.\n>\n> Since the rest of the basis states correspond to $f(x) = 0$, all other basis states in the initial superposition remain unchanged.\n\nNow you will implement the same function you've seen in the first two exercises as a marking oracle $U_{7,mark}$."
|
|
1993
|
+
}
|
|
1994
|
+
]
|
|
1995
|
+
},
|
|
1996
|
+
{
|
|
1997
|
+
"type": "exercise",
|
|
1998
|
+
"id": "oracles__marking_oracle_seven",
|
|
1999
|
+
"title": "Implement a Marking Oracle",
|
|
2000
|
+
"description": {
|
|
2001
|
+
"type": "text-content",
|
|
2002
|
+
"asHtml": "<p><strong>Inputs:</strong></p>\n<ol>\n<li><p>3 qubits in an arbitrary state $|x\\rangle$ (input/query register)</p>\n</li>\n<li><p>A qubit in an arbitrary state $|y\\rangle$ (target qubit)</p>\n</li>\n</ol>\n<p><strong>Goal:</strong></p>\n<p>Flip the state of $|y\\rangle$ if the input register is in the \nstate $|111\\rangle$, and leave the state $|y\\rangle$ unchanged otherwise.</p>\n<p><strong>Examples:</strong></p>\n<ul>\n<li>If the query register is in the state $|111\\rangle$, flip the state of the target qubit $|y\\rangle$.</li>\n<li>If the query register is in the state $|010\\rangle$ or $|101\\rangle$, do nothing.</li>\n</ul>\n",
|
|
2003
|
+
"asMarkdown": "**Inputs:**\n\n 1. 3 qubits in an arbitrary state $|x\\rangle$ (input/query register)\n \n 2. A qubit in an arbitrary state $|y\\rangle$ (target qubit)\n\n**Goal:**\n\nFlip the state of $|y\\rangle$ if the input register is in the \nstate $|111\\rangle$, and leave the state $|y\\rangle$ unchanged otherwise.\n\n**Examples:**\n\n* If the query register is in the state $|111\\rangle$, flip the state of the target qubit $|y\\rangle$.\n* If the query register is in the state $|010\\rangle$ or $|101\\rangle$, do nothing.\n"
|
|
2004
|
+
},
|
|
2005
|
+
"sourceIds": [
|
|
2006
|
+
"KatasLibrary.qs",
|
|
2007
|
+
"oracles__common.qs",
|
|
2008
|
+
"oracles__marking_oracle_seven__verification.qs"
|
|
2009
|
+
],
|
|
2010
|
+
"placeholderCode": "namespace Kata {\n operation IsSeven_MarkingOracle(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
2011
|
+
"explainedSolution": {
|
|
2012
|
+
"type": "explained-solution",
|
|
2013
|
+
"items": [
|
|
2014
|
+
{
|
|
2015
|
+
"type": "solution",
|
|
2016
|
+
"id": "oracles__marking_oracle_seven_solution",
|
|
2017
|
+
"code": "namespace Kata {\n operation IsSeven_MarkingOracle(x: Qubit[], y: Qubit) : Unit is Adj + Ctl {\n Controlled X(x, y);\n }\n}\n"
|
|
2018
|
+
},
|
|
2019
|
+
{
|
|
2020
|
+
"type": "text-content",
|
|
2021
|
+
"asHtml": "<p>Consider how the oracle from this exercise acts on two input basis states and two "output" basis states:</p>\n<p>$$U_{7,mark} |111\\rangle |0\\rangle = |111\\rangle |0 \\oplus f(111)\\rangle = |111\\rangle |0 \\oplus 1\\rangle = |111\\rangle |1\\rangle$$</p>\n<p>$$U_{7,mark} |111\\rangle |1\\rangle = |111\\rangle |1 \\oplus f(111)\\rangle = |111\\rangle |1 \\oplus 1\\rangle = |111\\rangle |0\\rangle$$</p>\n<p>$$U_{7,mark} |110\\rangle |0\\rangle = |110\\rangle |0 \\oplus f(110)\\rangle = |110\\rangle |0 \\oplus 0\\rangle = |110\\rangle |0\\rangle$$</p>\n<p>$$U_{7,mark} |110\\rangle |1\\rangle = |110\\rangle |1 \\oplus f(110)\\rangle = |110\\rangle |1 \\oplus 0\\rangle = |110\\rangle |1\\rangle$$</p>\n<p>You can see that the state of the input qubit array is unchanged, and the state of the output qubit changes if $f(x) = 1$ and is unchanged if $f(x) = 0$ - this matches the definition of a marking oracle precisely.</p>\n<p>Now let's again apply this oracle to a superposition state $|\\alpha\\rangle$ such that $|x\\rangle$ is a superposition of the $|6\\rangle$ and $|7\\rangle$ basis states and $|y\\rangle = |0\\rangle$:\n$$|\\alpha\\rangle = \\frac{1}{\\sqrt{2}}\\big(|110\\rangle + |111\\rangle\\big)|0\\rangle = \n|11\\rangle \\otimes \\frac{1}{\\sqrt{2}} \\big(|0\\rangle + |1\\rangle\\big) \\otimes |0\\rangle = |11+\\rangle |0\\rangle$$</p>\n<p>Let's consider how our operator $U_{7,mark}$ acts on this state.</p>\n<blockquote>\n<p>Recall that oracles are linear operators, thus they can be applied to each term individually.</p>\n</blockquote>\n<p>$$U_{7,mark} |\\alpha\\rangle = \\frac{1}{\\sqrt{2}} \\big(U_{7,mark}|110\\rangle |0\\rangle + U_{7,mark}|111\\rangle |0\\rangle\\big)$$</p>\n<p>$$= \\frac{1}{\\sqrt{2}} \\big(|110\\rangle |0\\rangle + |111\\rangle |1\\rangle\\big) := |\\epsilon\\rangle$$</p>\n<p>Was our input state modified during this operation? Let's simplify the resulting state $|\\epsilon\\rangle$:</p>\n<p>$$|\\epsilon\\rangle = \\frac{1}{\\sqrt{2}} \\big(|110\\rangle |0\\rangle + |111\\rangle |1\\rangle\\big) = |11\\rangle \\otimes \\frac{1}{\\sqrt{2}} \\big(|0\\rangle |0\\rangle + |1\\rangle |1\\rangle\\big)$$</p>\n<p>$$= |11\\rangle \\otimes \\frac{1}{\\sqrt{2}} \\big(|00\\rangle + |11\\rangle\\big) = |11\\rangle \\otimes |\\Phi^+\\rangle = |11\\Phi^+\\rangle$$</p>\n<p>We have entangled the states of qubits $|x\\rangle$ and $|y\\rangle$! This is a common occurrence for marking oracles when the input is a superposition of basis states: after applying the oracle, the input $|x\\rangle$ will often become entangled with $|y\\rangle$. Thus, while applying the marking oracle to a basis state will leave the input array unchanged, applying the marking oracle to a superposition state will change the state of both the input array and the output qubit.</p>\n<blockquote>\n<p>As an exercise, what entangled state would we get in the previous example if $|y\\rangle = |1\\rangle$ instead of $|y\\rangle = |0\\rangle$?</p>\n<details>\n <summary><b>Answer</b></summary>\n$$U_{7,mark} |11+\\rangle |1\\rangle = |11\\rangle \\otimes \\frac1{\\sqrt2}\\big(|01\\rangle + |10\\rangle\\big) = |11\\rangle |\\Psi^+\\rangle$$\n</details></blockquote>\n",
|
|
2022
|
+
"asMarkdown": "\nConsider how the oracle from this exercise acts on two input basis states and two \"output\" basis states:\n\n$$U_{7,mark} |111\\rangle |0\\rangle = |111\\rangle |0 \\oplus f(111)\\rangle = |111\\rangle |0 \\oplus 1\\rangle = |111\\rangle |1\\rangle$$\n\n$$U_{7,mark} |111\\rangle |1\\rangle = |111\\rangle |1 \\oplus f(111)\\rangle = |111\\rangle |1 \\oplus 1\\rangle = |111\\rangle |0\\rangle$$\n\n$$U_{7,mark} |110\\rangle |0\\rangle = |110\\rangle |0 \\oplus f(110)\\rangle = |110\\rangle |0 \\oplus 0\\rangle = |110\\rangle |0\\rangle$$\n\n$$U_{7,mark} |110\\rangle |1\\rangle = |110\\rangle |1 \\oplus f(110)\\rangle = |110\\rangle |1 \\oplus 0\\rangle = |110\\rangle |1\\rangle$$\n\nYou can see that the state of the input qubit array is unchanged, and the state of the output qubit changes if $f(x) = 1$ and is unchanged if $f(x) = 0$ - this matches the definition of a marking oracle precisely.\n\nNow let's again apply this oracle to a superposition state $|\\alpha\\rangle$ such that $|x\\rangle$ is a superposition of the $|6\\rangle$ and $|7\\rangle$ basis states and $|y\\rangle = |0\\rangle$:\n$$|\\alpha\\rangle = \\frac{1}{\\sqrt{2}}\\big(|110\\rangle + |111\\rangle\\big)|0\\rangle = \n|11\\rangle \\otimes \\frac{1}{\\sqrt{2}} \\big(|0\\rangle + |1\\rangle\\big) \\otimes |0\\rangle = |11+\\rangle |0\\rangle$$\n\nLet's consider how our operator $U_{7,mark}$ acts on this state.\n\n> Recall that oracles are linear operators, thus they can be applied to each term individually.\n\n$$U_{7,mark} |\\alpha\\rangle = \\frac{1}{\\sqrt{2}} \\big(U_{7,mark}|110\\rangle |0\\rangle + U_{7,mark}|111\\rangle |0\\rangle\\big)$$\n\n$$= \\frac{1}{\\sqrt{2}} \\big(|110\\rangle |0\\rangle + |111\\rangle |1\\rangle\\big) := |\\epsilon\\rangle$$\n\nWas our input state modified during this operation? Let's simplify the resulting state $|\\epsilon\\rangle$:\n\n$$|\\epsilon\\rangle = \\frac{1}{\\sqrt{2}} \\big(|110\\rangle |0\\rangle + |111\\rangle |1\\rangle\\big) = |11\\rangle \\otimes \\frac{1}{\\sqrt{2}} \\big(|0\\rangle |0\\rangle + |1\\rangle |1\\rangle\\big)$$\n\n$$= |11\\rangle \\otimes \\frac{1}{\\sqrt{2}} \\big(|00\\rangle + |11\\rangle\\big) = |11\\rangle \\otimes |\\Phi^+\\rangle = |11\\Phi^+\\rangle$$\n\nWe have entangled the states of qubits $|x\\rangle$ and $|y\\rangle$! This is a common occurrence for marking oracles when the input is a superposition of basis states: after applying the oracle, the input $|x\\rangle$ will often become entangled with $|y\\rangle$. Thus, while applying the marking oracle to a basis state will leave the input array unchanged, applying the marking oracle to a superposition state will change the state of both the input array and the output qubit.\n\n>As an exercise, what entangled state would we get in the previous example if $|y\\rangle = |1\\rangle$ instead of $|y\\rangle = |0\\rangle$?\n>\n> <details>\n> <summary><b>Answer</b></summary>\n> $$U_{7,mark} |11+\\rangle |1\\rangle = |11\\rangle \\otimes \\frac1{\\sqrt2}\\big(|01\\rangle + |10\\rangle\\big) = |11\\rangle |\\Psi^+\\rangle$$\n> </details>"
|
|
2023
|
+
}
|
|
2024
|
+
]
|
|
2025
|
+
}
|
|
2026
|
+
},
|
|
2027
|
+
{
|
|
2028
|
+
"type": "lesson",
|
|
2029
|
+
"id": "oracles__phase_kickback",
|
|
2030
|
+
"title": "Phase Kickback",
|
|
2031
|
+
"items": [
|
|
2032
|
+
{
|
|
2033
|
+
"type": "text-content",
|
|
2034
|
+
"asHtml": "<p>Previously we considered applying marking oracles when the register $|x\\rangle$ was in a basis state or a superposition state, and the target qubit $|y\\rangle$ in a basis state. How might the effect of applying marking oracles change if the target is also in a superposition state? In this case we will observe <strong>phase kickback</strong> - the relative phase from the target qubit affecting ("kicked back" into) the state of the input qubits.</p>\n<p>In order to observe phase kickback, we use the target qubit $|y\\rangle=|-\\rangle$.</p>\n<blockquote>\n<p>This is the standard choice for two reasons. \nFirst, for phase kickback to occur, the target qubit must have a difference in relative phase between the basis states $|0\\rangle$ and $|1\\rangle$. \nSecond, the target qubit must be in an equal superposition, otherwise it will become entangled with the input register.</p>\n</blockquote>\n<p>Let's see the results of applying a marking oracle $U_{mark}$ which implements the function $f(x)$ to the input register $|x\\rangle$ and the target qubit in state $|-\\rangle$:</p>\n<ul>\n<li>If the input register $|x\\rangle$ is in a basis state:</li>\n</ul>\n<p>$$U_{mark} |x\\rangle |-\\rangle = \\frac1{\\sqrt2} \\big(U_{mark}|x\\rangle|0\\rangle - U_{mark}|x\\rangle |1\\rangle\\big)$$</p>\n<p>$$= \\frac1{\\sqrt2} \\big(|x\\rangle|0\\oplus f(x)\\rangle - |x\\rangle |1\\oplus f(x)\\rangle\\big)$$</p>\n<p>$$= \n\\begin{cases} \n\\frac1{\\sqrt2} \\big(|x\\rangle|0\\rangle - |x\\rangle |1\\rangle\\big) = |x\\rangle|-\\rangle \\text{ if } f(x) = 0 \\\\ \n\\frac1{\\sqrt2} \\big(|x\\rangle|1\\rangle - |x\\rangle |0\\rangle\\big) = -|x\\rangle|-\\rangle \\text{ if } f(x) = 1\n\\end{cases}\n$$</p>\n<p>$$= (-1)^{f(x)}|x\\rangle |-\\rangle$$</p>\n<ul>\n<li>If the input register is in a superposition state, say $|x\\rangle = \\frac1{\\sqrt2} \\big(|b_1\\rangle + |b_2\\rangle\\big)$, where $|b_1\\rangle$ and $|b_2\\rangle$ are basis states:</li>\n</ul>\n<p>$$U_{mark} |x\\rangle |-\\rangle = U_{mark} \\frac{1}{\\sqrt{2}} \\big(|b_1\\rangle + |b_2\\rangle\\big) |-\\rangle$$</p>\n<p>$$= \\frac{1}{\\sqrt{2}} \\big( U_{mark}|b_1\\rangle|-\\rangle + U_{mark}|b_2\\rangle|-\\rangle\\big)$$</p>\n<p>$$= \\frac{1}{\\sqrt{2}} \\big( (-1)^{f(b_1)}|b_1\\rangle + (-1)^{f(b_2)}|b_2\\rangle\\big) |-\\rangle$$</p>\n<p>We see that in both cases applying $U_{mark}$ does not change the state of the target qubit, but it does change the state of the input register. \nThus we can drop the target qubit without any repercussions after the application of the oracle. \nNotice that the input register is now in the following state:\n$$|\\psi\\rangle = \\frac{1}{\\sqrt{2}} \\big( (-1)^{f(b_1)}|b_1\\rangle + (-1)^{f(b_2)}|b_2\\rangle\\big),$$</p>\n<p>which looks exactly as if we applied a phase oracle to $|x\\rangle$ instead of applying a marking oracle to $|x\\rangle|-\\rangle$! This is a very important application of phase kickback: it allows to convert a marking oracle into a phase oracle - which you will implement in the next task.</p>\n<blockquote>\n<p>Another important application of this effect is <strong>phase estimation</strong> algorithm, which allows to estimate an eigenvalue of an eigenvector.</p>\n</blockquote>\n<p>Consider the following example using the $U_{7,mark}$ oracle. Let's begin with $|x\\rangle$ as an equal superposition of the $6$ and $7$ basis states and $|y\\rangle=|-\\rangle$, the overall state is:</p>\n<p>$$|\\eta\\rangle = \\Big[\\frac{1}{\\sqrt{2}}\\big(|110\\rangle + |111\\rangle\\big)\\Big] \\otimes \\frac{1}{\\sqrt{2}}\\big(|0\\rangle - |1\\rangle\\big)$$</p>\n<p>$$= \\frac{1}{2} \\big(|110\\rangle|0\\rangle + |111\\rangle|0\\rangle - |110\\rangle|1\\rangle - |111\\rangle|1\\rangle\\big)$$</p>\n<p>How does $U_{7,mark}$ act on this state?</p>\n<p>$$U_{7,mark}|\\eta\\rangle = U_{7,mark} \\frac{1}{2} \\big(|110\\rangle|0\\rangle + |111\\rangle|0\\rangle - |110\\rangle|1\\rangle - |111\\rangle|1\\rangle \\big)$$</p>\n<p>$$= \\frac{1}{2} \\big( U_{7,mark}|110\\rangle|0\\rangle + U_{7,mark}|111\\rangle|0\\rangle - U_{7,mark}|110\\rangle|1\\rangle - U_{7,mark}|111\\rangle|1\\rangle \\big)$$</p>\n<p>$$= \\frac{1}{2} \\big(|110\\rangle|0\\rangle + |111\\rangle|1\\rangle - |110\\rangle|1\\rangle - |111\\rangle|0\\rangle \\big) := |\\xi\\rangle$$</p>\n<p>Now we would like to observe how our input state $|\\eta\\rangle$ was modified by the oracle. Let's simplify the resulting state $|\\xi\\rangle$:</p>\n<p>$$|\\xi\\rangle = \\frac{1}{2} \\big(|110\\rangle|0\\rangle + |111\\rangle|1\\rangle - |110\\rangle|1\\rangle - |111\\rangle|0\\rangle\\big)$$</p>\n<p>$$= \\frac{1}{2} \\big(|110\\rangle|0\\rangle - |110\\rangle|1\\rangle - |111\\rangle|0\\rangle + |111\\rangle|1\\rangle \\big)$$</p>\n<p>$$= \\frac{1}{2} \\Big[|110\\rangle \\otimes \\big(|0\\rangle - |1\\rangle \\big) + |111\\rangle \\otimes \\big(|1\\rangle - |0\\rangle\\big)\\Big]$$</p>\n<p>$$= \\Big[\\frac{1}{\\sqrt{2}} \\big( |110\\rangle - |111\\rangle \\big) \\Big] \\otimes \\Big[ \\frac{1}{\\sqrt{2}} \\big( |0\\rangle - |1\\rangle \\big) \\Big]$$</p>\n<p>$$= \\Big[\\frac{1}{\\sqrt{2}} \\big( |110\\rangle - |111\\rangle \\big) \\Big] \\otimes |-\\rangle$$</p>\n<p>Finally, let's compare $|\\eta\\rangle$ and $|\\xi\\rangle$; below are the final equations repeated for your convenience:\n$$|\\eta\\rangle = \\Big[\\frac{1}{\\sqrt{2}}\\big(|110\\rangle + |111\\rangle\\big)\\Big] \\otimes |-\\rangle$$\n$$|\\xi\\rangle = \\Big[\\frac{1}{\\sqrt{2}}\\big(|110\\rangle - |111\\rangle\\big)\\Big] \\otimes |-\\rangle$$</p>\n<p>We can see that these two equations are identical, except for the $-1$ phase that appeared on the $|111\\rangle$ basis state (representing $7$). This is a specific example of the phase kickback effect, as the phase from $|-\\rangle$ has been <em>kicked back</em> into $|x\\rangle$.</p>\n<h2 id=\"🔎-analyze\">🔎 Analyze</h2>\n<p><strong>Distinguishing states</strong></p>\n<p>How could we distinguish the states $|\\eta\\rangle = |11+\\rangle |-\\rangle$ and $|\\xi\\rangle = |11-\\rangle |-\\rangle$? Take a moment to think.</p>\n<details>\n<summary><b>Solution</b></summary>\nRecall that we can only observe alterations to out input state by performing a measurement.\nIf we apply Hadamard gate to the third qubit, we will be able to distinguish between the input state and the output state. \n $$(I\\otimes I \\otimes H)|11+\\rangle = |110\\rangle \\\\ (I\\otimes I \\otimes H)|11-\\rangle = |111\\rangle$$ \nNow if we were to measure the third qubit, we'll be able to distinguish the starting state and the state after phase kickback occurred.\n</details>",
|
|
2035
|
+
"asMarkdown": "\nPreviously we considered applying marking oracles when the register $|x\\rangle$ was in a basis state or a superposition state, and the target qubit $|y\\rangle$ in a basis state. How might the effect of applying marking oracles change if the target is also in a superposition state? In this case we will observe **phase kickback** - the relative phase from the target qubit affecting (\"kicked back\" into) the state of the input qubits.\n\nIn order to observe phase kickback, we use the target qubit $|y\\rangle=|-\\rangle$.\n\n> This is the standard choice for two reasons. \n> First, for phase kickback to occur, the target qubit must have a difference in relative phase between the basis states $|0\\rangle$ and $|1\\rangle$. \n> Second, the target qubit must be in an equal superposition, otherwise it will become entangled with the input register.\n\nLet's see the results of applying a marking oracle $U_{mark}$ which implements the function $f(x)$ to the input register $|x\\rangle$ and the target qubit in state $|-\\rangle$:\n* If the input register $|x\\rangle$ is in a basis state:\n\n$$U_{mark} |x\\rangle |-\\rangle = \\frac1{\\sqrt2} \\big(U_{mark}|x\\rangle|0\\rangle - U_{mark}|x\\rangle |1\\rangle\\big)$$\n\n$$= \\frac1{\\sqrt2} \\big(|x\\rangle|0\\oplus f(x)\\rangle - |x\\rangle |1\\oplus f(x)\\rangle\\big)$$\n\n$$= \n\\begin{cases} \n\\frac1{\\sqrt2} \\big(|x\\rangle|0\\rangle - |x\\rangle |1\\rangle\\big) = |x\\rangle|-\\rangle \\text{ if } f(x) = 0 \\\\\\ \n\\frac1{\\sqrt2} \\big(|x\\rangle|1\\rangle - |x\\rangle |0\\rangle\\big) = -|x\\rangle|-\\rangle \\text{ if } f(x) = 1\n\\end{cases}\n$$\n\n$$= (-1)^{f(x)}|x\\rangle |-\\rangle$$\n\n\n* If the input register is in a superposition state, say $|x\\rangle = \\frac1{\\sqrt2} \\big(|b_1\\rangle + |b_2\\rangle\\big)$, where $|b_1\\rangle$ and $|b_2\\rangle$ are basis states:\n\n$$U_{mark} |x\\rangle |-\\rangle = U_{mark} \\frac{1}{\\sqrt{2}} \\big(|b_1\\rangle + |b_2\\rangle\\big) |-\\rangle$$\n\n$$= \\frac{1}{\\sqrt{2}} \\big( U_{mark}|b_1\\rangle|-\\rangle + U_{mark}|b_2\\rangle|-\\rangle\\big)$$\n\n$$= \\frac{1}{\\sqrt{2}} \\big( (-1)^{f(b_1)}|b_1\\rangle + (-1)^{f(b_2)}|b_2\\rangle\\big) |-\\rangle$$\n\nWe see that in both cases applying $U_{mark}$ does not change the state of the target qubit, but it does change the state of the input register. \nThus we can drop the target qubit without any repercussions after the application of the oracle. \nNotice that the input register is now in the following state:\n$$|\\psi\\rangle = \\frac{1}{\\sqrt{2}} \\big( (-1)^{f(b_1)}|b_1\\rangle + (-1)^{f(b_2)}|b_2\\rangle\\big),$$\n\nwhich looks exactly as if we applied a phase oracle to $|x\\rangle$ instead of applying a marking oracle to $|x\\rangle|-\\rangle$! This is a very important application of phase kickback: it allows to convert a marking oracle into a phase oracle - which you will implement in the next task.\n\n> Another important application of this effect is **phase estimation** algorithm, which allows to estimate an eigenvalue of an eigenvector.\n\nConsider the following example using the $U_{7,mark}$ oracle. Let's begin with $|x\\rangle$ as an equal superposition of the $6$ and $7$ basis states and $|y\\rangle=|-\\rangle$, the overall state is:\n\n$$|\\eta\\rangle = \\Big[\\frac{1}{\\sqrt{2}}\\big(|110\\rangle + |111\\rangle\\big)\\Big] \\otimes \\frac{1}{\\sqrt{2}}\\big(|0\\rangle - |1\\rangle\\big)$$\n\n$$= \\frac{1}{2} \\big(|110\\rangle|0\\rangle + |111\\rangle|0\\rangle - |110\\rangle|1\\rangle - |111\\rangle|1\\rangle\\big)$$\n\nHow does $U_{7,mark}$ act on this state?\n\n$$U_{7,mark}|\\eta\\rangle = U_{7,mark} \\frac{1}{2} \\big(|110\\rangle|0\\rangle + |111\\rangle|0\\rangle - |110\\rangle|1\\rangle - |111\\rangle|1\\rangle \\big)$$\n\n$$= \\frac{1}{2} \\big( U_{7,mark}|110\\rangle|0\\rangle + U_{7,mark}|111\\rangle|0\\rangle - U_{7,mark}|110\\rangle|1\\rangle - U_{7,mark}|111\\rangle|1\\rangle \\big)$$\n\n$$= \\frac{1}{2} \\big(|110\\rangle|0\\rangle + |111\\rangle|1\\rangle - |110\\rangle|1\\rangle - |111\\rangle|0\\rangle \\big) := |\\xi\\rangle$$\n\nNow we would like to observe how our input state $|\\eta\\rangle$ was modified by the oracle. Let's simplify the resulting state $|\\xi\\rangle$:\n\n$$|\\xi\\rangle = \\frac{1}{2} \\big(|110\\rangle|0\\rangle + |111\\rangle|1\\rangle - |110\\rangle|1\\rangle - |111\\rangle|0\\rangle\\big)$$\n\n$$= \\frac{1}{2} \\big(|110\\rangle|0\\rangle - |110\\rangle|1\\rangle - |111\\rangle|0\\rangle + |111\\rangle|1\\rangle \\big)$$\n\n$$= \\frac{1}{2} \\Big[|110\\rangle \\otimes \\big(|0\\rangle - |1\\rangle \\big) + |111\\rangle \\otimes \\big(|1\\rangle - |0\\rangle\\big)\\Big]$$\n\n$$= \\Big[\\frac{1}{\\sqrt{2}} \\big( |110\\rangle - |111\\rangle \\big) \\Big] \\otimes \\Big[ \\frac{1}{\\sqrt{2}} \\big( |0\\rangle - |1\\rangle \\big) \\Big]$$\n\n$$= \\Big[\\frac{1}{\\sqrt{2}} \\big( |110\\rangle - |111\\rangle \\big) \\Big] \\otimes |-\\rangle$$\n\nFinally, let's compare $|\\eta\\rangle$ and $|\\xi\\rangle$; below are the final equations repeated for your convenience:\n$$|\\eta\\rangle = \\Big[\\frac{1}{\\sqrt{2}}\\big(|110\\rangle + |111\\rangle\\big)\\Big] \\otimes |-\\rangle$$\n$$|\\xi\\rangle = \\Big[\\frac{1}{\\sqrt{2}}\\big(|110\\rangle - |111\\rangle\\big)\\Big] \\otimes |-\\rangle$$\n\nWe can see that these two equations are identical, except for the $-1$ phase that appeared on the $|111\\rangle$ basis state (representing $7$). This is a specific example of the phase kickback effect, as the phase from $|-\\rangle$ has been *kicked back* into $|x\\rangle$.\n\n## 🔎 Analyze\n\n**Distinguishing states**\n\nHow could we distinguish the states $|\\eta\\rangle = |11+\\rangle |-\\rangle$ and $|\\xi\\rangle = |11-\\rangle |-\\rangle$? Take a moment to think.\n\n<details>\n<summary><b>Solution</b></summary>\nRecall that we can only observe alterations to out input state by performing a measurement.\nIf we apply Hadamard gate to the third qubit, we will be able to distinguish between the input state and the output state. \n $$(I\\otimes I \\otimes H)|11+\\rangle = |110\\rangle \\\\ (I\\otimes I \\otimes H)|11-\\rangle = |111\\rangle$$ \nNow if we were to measure the third qubit, we'll be able to distinguish the starting state and the state after phase kickback occurred.\n</details>"
|
|
2036
|
+
}
|
|
2037
|
+
]
|
|
2038
|
+
},
|
|
2039
|
+
{
|
|
2040
|
+
"type": "exercise",
|
|
2041
|
+
"id": "oracles__marking_oracle_as_phase",
|
|
2042
|
+
"title": "Apply the Marking Oracle as a Phase Oracle",
|
|
2043
|
+
"description": {
|
|
2044
|
+
"type": "text-content",
|
|
2045
|
+
"asHtml": "<p><strong>Inputs:</strong></p>\n<ol>\n<li>A marking oracle implementing an unknown $N$-bit function $f(x)$.</li>\n<li>$N$ qubits in an arbitrary state (input/query register).</li>\n</ol>\n<p><strong>Goal:</strong></p>\n<p>Flip the phase of each basis state $|x\\rangle$ for which $f(x) = 1$. You can only access $f(x)$ via the marking oracle you are given.</p>\n<br/>\n<details>\n <summary><b>Need a hint?</b></summary>\n Recall that you can allocate extra qubits to assist in this operation. Is there a state that you could prepare with an auxiliary qubit which would help you to convert the marking oracle to a phase oracle?\n</details>\n",
|
|
2046
|
+
"asMarkdown": "**Inputs:**\n\n 1. A marking oracle implementing an unknown $N$-bit function $f(x)$.\n 2. $N$ qubits in an arbitrary state (input/query register).\n \n**Goal:**\n\nFlip the phase of each basis state $|x\\rangle$ for which $f(x) = 1$. You can only access $f(x)$ via the marking oracle you are given.\n\n<br/>\n<details>\n <summary><b>Need a hint?</b></summary>\n Recall that you can allocate extra qubits to assist in this operation. Is there a state that you could prepare with an auxiliary qubit which would help you to convert the marking oracle to a phase oracle?\n</details>\n"
|
|
2047
|
+
},
|
|
2048
|
+
"sourceIds": [
|
|
2049
|
+
"KatasLibrary.qs",
|
|
2050
|
+
"oracles__common.qs",
|
|
2051
|
+
"oracles__marking_oracle_as_phase__verification.qs"
|
|
2052
|
+
],
|
|
2053
|
+
"placeholderCode": "namespace Kata {\n operation ApplyMarkingOracleAsPhaseOracle(\n markingOracle : ((Qubit[], Qubit) => Unit is Adj + Ctl),\n qubits : Qubit[])\n : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
2054
|
+
"explainedSolution": {
|
|
2055
|
+
"type": "explained-solution",
|
|
2056
|
+
"items": [
|
|
2057
|
+
{
|
|
2058
|
+
"type": "solution",
|
|
2059
|
+
"id": "oracles__marking_oracle_as_phase_solution",
|
|
2060
|
+
"code": "namespace Kata {\n operation ApplyMarkingOracleAsPhaseOracle(\n markingOracle: ((Qubit[], Qubit) => Unit is Adj + Ctl),\n qubits: Qubit[])\n : Unit is Adj + Ctl {\n use minus = Qubit();\n within {\n X(minus);\n H(minus);\n } apply {\n markingOracle(qubits, minus);\n }\n }\n}\n"
|
|
2061
|
+
}
|
|
2062
|
+
]
|
|
2063
|
+
}
|
|
2064
|
+
},
|
|
2065
|
+
{
|
|
2066
|
+
"type": "lesson",
|
|
2067
|
+
"id": "oracles__conversion",
|
|
2068
|
+
"title": "Oracle Conversion",
|
|
2069
|
+
"items": [
|
|
2070
|
+
{
|
|
2071
|
+
"type": "text-content",
|
|
2072
|
+
"asHtml": "<p>In this demo we will use a reference implementation of <code>ApplyMarkingOracleAsPhaseOracle</code> operation to convert marking oracle <code>IsSeven_MarkingOracle</code> to a phase oracle. Then we will compare this converted oracle to the reference implementation of the phase oracle <code>IsSeven_PhaseOracle</code>. You already implemented these oracles in the previous tasks.</p>\n",
|
|
2073
|
+
"asMarkdown": "\nIn this demo we will use a reference implementation of `ApplyMarkingOracleAsPhaseOracle` operation to convert marking oracle `IsSeven_MarkingOracle` to a phase oracle. Then we will compare this converted oracle to the reference implementation of the phase oracle `IsSeven_PhaseOracle`. You already implemented these oracles in the previous tasks."
|
|
2074
|
+
},
|
|
2075
|
+
{
|
|
2076
|
+
"type": "example",
|
|
2077
|
+
"id": "oracles__oracle_converter_demo",
|
|
2078
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Arrays;\n\n @EntryPoint()\n operation OracleConverterDemo () : Unit {\n // Allocate the qubits in the state |000⟩\n use register = Qubit[3];\n // Prepare an equal superposition state\n ApplyToEachA(H, register);\n\n Message(\"The equal superposition state:\");\n DumpMachine();\n\n // Apply the `IsSeven_PhaseOracle` from the task on implementing a phase oracle\n IsSeven_PhaseOracle(register);\n\n // Dump the state after application of the oracle\n Message(\"The state after applying the phase oracle IsSeven_PhaseOracle:\");\n DumpMachine();\n\n // Reset the qubits for deallocation\n ResetAll(register);\n\n // Prepare an equal superposition state again\n ApplyToEachA(H, register);\n\n // Apply the `IsSeven_MarkingOracle` from the task on implementing a marking oracle\n // as a phase oracle\n ApplyMarkingOracleAsPhaseOracle(IsSeven_MarkingOracle, register);\n\n // Dump the state after application of the oracle\n Message(\"The state after applying the converted marking oracle IsSeven_MarkingOracle:\");\n DumpMachine();\n\n // reset the qubits for deallocation\n ResetAll(register);\n }\n\n operation IsSeven_PhaseOracle(x : Qubit[]) : Unit is Adj + Ctl {\n Controlled Z(Most(x), Tail(x));\n }\n\n operation IsSeven_MarkingOracle(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n Controlled X(x, y);\n }\n\n operation ApplyMarkingOracleAsPhaseOracle(\n markingOracle: ((Qubit[], Qubit) => Unit is Adj + Ctl),\n qubits: Qubit[]) : Unit is Adj + Ctl {\n \n use minus = Qubit();\n within {\n X(minus);\n H(minus);\n } apply {\n markingOracle(qubits, minus);\n }\n } \n}\n"
|
|
2079
|
+
},
|
|
2080
|
+
{
|
|
2081
|
+
"type": "text-content",
|
|
2082
|
+
"asHtml": "<blockquote>\n<p>Notice from the above demo that your phase oracle $U_{7,phase}$ behaves the same as the converted version of your marking oracle $U_{7,mark}$, both of which induce a phase flip on the basis state $|111\\rangle$!</p>\n</blockquote>\n<p>This way to convert a marking oracle to a phase oracle is useful because many quantum algorithms, such as Grover's search algorithm, rely on a phase oracle, but it is often easier to implement the function as a marking oracle. \nThis converter provides a way to implement the function of interest as a marking oracle and then convert it into a phase oracle, which could then be leveraged in a quantum algorithm.</p>\n",
|
|
2083
|
+
"asMarkdown": "\n> Notice from the above demo that your phase oracle $U_{7,phase}$ behaves the same as the converted version of your marking oracle $U_{7,mark}$, both of which induce a phase flip on the basis state $|111\\rangle$!\n\nThis way to convert a marking oracle to a phase oracle is useful because many quantum algorithms, such as Grover's search algorithm, rely on a phase oracle, but it is often easier to implement the function as a marking oracle. \nThis converter provides a way to implement the function of interest as a marking oracle and then convert it into a phase oracle, which could then be leveraged in a quantum algorithm."
|
|
2084
|
+
}
|
|
2085
|
+
]
|
|
2086
|
+
},
|
|
2087
|
+
{
|
|
2088
|
+
"type": "lesson",
|
|
2089
|
+
"id": "oracles__implementing_quantum_oracles",
|
|
2090
|
+
"title": "Implementing Quantum Oracles",
|
|
2091
|
+
"items": [
|
|
2092
|
+
{
|
|
2093
|
+
"type": "text-content",
|
|
2094
|
+
"asHtml": "<p>In this section you will implement a few more complicated quantum oracles. </p>\n<blockquote>\n<p>Notice that the operation declarations below require adjoint and controlled variants of the oracle to be automatically generated. This is common practice that makes testing and reusing the code easier. Typically Q# compiler will easily generate these variants, as long as you don't use mutable variables or operations that don't support these functors.</p>\n</blockquote>\n",
|
|
2095
|
+
"asMarkdown": "\nIn this section you will implement a few more complicated quantum oracles. \n\n> Notice that the operation declarations below require adjoint and controlled variants of the oracle to be automatically generated. This is common practice that makes testing and reusing the code easier. Typically Q# compiler will easily generate these variants, as long as you don't use mutable variables or operations that don't support these functors."
|
|
2096
|
+
}
|
|
2097
|
+
]
|
|
2098
|
+
},
|
|
2099
|
+
{
|
|
2100
|
+
"type": "exercise",
|
|
2101
|
+
"id": "oracles__or_oracle",
|
|
2102
|
+
"title": "Implement the OR Oracle",
|
|
2103
|
+
"description": {
|
|
2104
|
+
"type": "text-content",
|
|
2105
|
+
"asHtml": "<p><strong>Inputs:</strong></p>\n<ol>\n<li>$N$ qubits in an arbitrary state $|x\\rangle$ (input/query register).</li>\n<li>A qubit in an arbitrary state $|y\\rangle$ (target qubit).</li>\n</ol>\n<p><strong>Goal:</strong></p>\n<p>Flip the state of $|y\\rangle$ if the input register is in any basis state\nexcept for $|00...0\\rangle$ (the all zero state).</p>\n<p><strong>Examples:</strong></p>\n<ul>\n<li>If the query register is in the state $|10000001\\rangle$, $|11101101\\rangle$ or $|0010101\\rangle$, flip the state $|y\\rangle$.</li>\n<li>If the query register is in the state $|000\\rangle$, do nothing.</li>\n</ul>\n<br/>\n<details>\n <summary><b>Before implementing this oracle, answer the question: are you implementing a marking or a phase oracle?</b></summary>\n This is a marking oracle, because we are flipping the state of the target qubit $|y\\rangle$ based on the state of the input $|x\\rangle$.\n</details>\n\n<br/>\n<details>\n <summary><b>Need a hint?</b></summary>\n You need to flip the state of $|y\\rangle$ for every input except $|00...0\\rangle$, or, alternatively, flip it unconditionally and then flip it for the $|00...0\\rangle$ state. You may find the Q# library function <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.canon.controlledonint\" target=\"_blank\">ControlledOnInt</a> useful in your implementation.\n</details>\n",
|
|
2106
|
+
"asMarkdown": "**Inputs:**\n\n 1. $N$ qubits in an arbitrary state $|x\\rangle$ (input/query register).\n 2. A qubit in an arbitrary state $|y\\rangle$ (target qubit).\n\n**Goal:**\n\nFlip the state of $|y\\rangle$ if the input register is in any basis state\nexcept for $|00...0\\rangle$ (the all zero state).\n\n**Examples:**\n\n* If the query register is in the state $|10000001\\rangle$, $|11101101\\rangle$ or $|0010101\\rangle$, flip the state $|y\\rangle$.\n* If the query register is in the state $|000\\rangle$, do nothing.\n\n<br/>\n<details>\n <summary><b>Before implementing this oracle, answer the question: are you implementing a marking or a phase oracle?</b></summary>\n This is a marking oracle, because we are flipping the state of the target qubit $|y\\rangle$ based on the state of the input $|x\\rangle$.\n</details>\n\n<br/>\n<details>\n <summary><b>Need a hint?</b></summary>\n You need to flip the state of $|y\\rangle$ for every input except $|00...0\\rangle$, or, alternatively, flip it unconditionally and then flip it for the $|00...0\\rangle$ state. You may find the Q# library function <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.canon.controlledonint\" target=\"_blank\">ControlledOnInt</a> useful in your implementation.\n</details>\n"
|
|
2107
|
+
},
|
|
2108
|
+
"sourceIds": [
|
|
2109
|
+
"KatasLibrary.qs",
|
|
2110
|
+
"oracles__common.qs",
|
|
2111
|
+
"oracles__or_oracle__verification.qs"
|
|
2112
|
+
],
|
|
2113
|
+
"placeholderCode": "namespace Kata {\n operation Or_Oracle(x : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
2114
|
+
"explainedSolution": {
|
|
2115
|
+
"type": "explained-solution",
|
|
2116
|
+
"items": [
|
|
2117
|
+
{
|
|
2118
|
+
"type": "solution",
|
|
2119
|
+
"id": "oracles__or_oracle_solution",
|
|
2120
|
+
"code": "namespace Kata {\n operation Or_Oracle(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n}\n"
|
|
2121
|
+
},
|
|
2122
|
+
{
|
|
2123
|
+
"type": "text-content",
|
|
2124
|
+
"asHtml": "<p>Notice that you can modify the state of the input register during your computations (this is what <code>ControlledOnInt</code> function does under the hood). However, it is essential to undo those modifications ("uncompute" the changes), except the final one, so that the oracle will preserve the input if it is a basis state.</p>\n",
|
|
2125
|
+
"asMarkdown": "\nNotice that you can modify the state of the input register during your computations (this is what `ControlledOnInt` function does under the hood). However, it is essential to undo those modifications (\"uncompute\" the changes), except the final one, so that the oracle will preserve the input if it is a basis state."
|
|
2126
|
+
}
|
|
2127
|
+
]
|
|
2128
|
+
}
|
|
2129
|
+
},
|
|
2130
|
+
{
|
|
2131
|
+
"type": "exercise",
|
|
2132
|
+
"id": "oracles__kth_bit_oracle",
|
|
2133
|
+
"title": "Implement the K-th Bit Oracle",
|
|
2134
|
+
"description": {
|
|
2135
|
+
"type": "text-content",
|
|
2136
|
+
"asHtml": "<p><strong>Inputs:</strong></p>\n<ol>\n<li>$N$ qubits in an arbitrary state $|x\\rangle$ (input/query register).</li>\n<li>An integer $k$ such that $0 \\leq k < N$.</li>\n</ol>\n<p><strong>Goal:</strong></p>\n<p>Flip the sign of the input state $|x\\rangle$ if the $k$-th bit of $x$ is $1$.<br><strong>Implement this oracle without using auxiliary qubits.</strong></p>\n<p><strong>Examples:</strong></p>\n<ul>\n<li>If the query register is in the state $|010\\rangle$ and $k=0$, do nothing.</li>\n<li>If the query register is in the state $|010\\rangle$ and $k=1$, flip the sign of the basis state.</li>\n</ul>\n<br/>\n<details>\n <summary><b>Before implementing this oracle, answer the question: are you implementing a marking or a phase oracle?</b></summary>\n This is a phase oracle, because we are changing the phase of the input state $|x\\rangle$ based on the value of the function $f(x)$.\n</details>\n",
|
|
2137
|
+
"asMarkdown": "**Inputs:**\n\n 1. $N$ qubits in an arbitrary state $|x\\rangle$ (input/query register).\n 2. An integer $k$ such that $0 \\leq k < N$.\n\n**Goal:**\n\nFlip the sign of the input state $|x\\rangle$ if the $k$-th bit of $x$ is $1$. \n**Implement this oracle without using auxiliary qubits.**\n\n**Examples:**\n\n* If the query register is in the state $|010\\rangle$ and $k=0$, do nothing.\n* If the query register is in the state $|010\\rangle$ and $k=1$, flip the sign of the basis state.\n\n<br/>\n<details>\n <summary><b>Before implementing this oracle, answer the question: are you implementing a marking or a phase oracle?</b></summary>\n This is a phase oracle, because we are changing the phase of the input state $|x\\rangle$ based on the value of the function $f(x)$.\n</details>\n"
|
|
2138
|
+
},
|
|
2139
|
+
"sourceIds": [
|
|
2140
|
+
"KatasLibrary.qs",
|
|
2141
|
+
"oracles__common.qs",
|
|
2142
|
+
"oracles__kth_bit_oracle__verification.qs"
|
|
2143
|
+
],
|
|
2144
|
+
"placeholderCode": "namespace Kata {\n operation KthBit_Oracle(x : Qubit[], k : Int) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
2145
|
+
"explainedSolution": {
|
|
2146
|
+
"type": "explained-solution",
|
|
2147
|
+
"items": [
|
|
2148
|
+
{
|
|
2149
|
+
"type": "solution",
|
|
2150
|
+
"id": "oracles__kth_bit_oracle_solution",
|
|
2151
|
+
"code": "namespace Kata {\n operation KthBit_Oracle(x : Qubit[], k : Int) : Unit is Adj + Ctl {\n Z(x[k]);\n }\n}\n"
|
|
2152
|
+
},
|
|
2153
|
+
{
|
|
2154
|
+
"type": "text-content",
|
|
2155
|
+
"asHtml": "<p>Notice how the oracles - both phase and marking - can take extra "classical" parameters.</p>\n<p>Another key tool for implementing quantum oracles is allocating auxiliary qubits to assist in a computation. Below are some exercises where you will practice that.</p>\n",
|
|
2156
|
+
"asMarkdown": "\nNotice how the oracles - both phase and marking - can take extra \"classical\" parameters.\n\nAnother key tool for implementing quantum oracles is allocating auxiliary qubits to assist in a computation. Below are some exercises where you will practice that."
|
|
2157
|
+
}
|
|
2158
|
+
]
|
|
2159
|
+
}
|
|
2160
|
+
},
|
|
2161
|
+
{
|
|
2162
|
+
"type": "exercise",
|
|
2163
|
+
"id": "oracles__or_but_kth_oracle",
|
|
2164
|
+
"title": "Implement the OR Oracle of All Bits Except the K-th",
|
|
2165
|
+
"description": {
|
|
2166
|
+
"type": "text-content",
|
|
2167
|
+
"asHtml": "<p><strong>Inputs:</strong></p>\n<ol>\n<li>$N$ qubits in an arbitrary state $|x\\rangle$ (input/query register).</li>\n<li>An integer $k$ such that $0 \\leq k < N$.</li>\n</ol>\n<p><strong>Goal:</strong></p>\n<p>Flip the sign of the basis state $|x\\rangle$ if any of the bits of $x$ (not considering the $k$-th bit) are $1$ in input register. In other words, the input register with the $k$-th qubit excluded should not be in the all zero state to flip the sign of the input register. The state of the $k$-th qubit does not affect the result.</p>\n<p>Feel free to explore implementing this operation with or without auxiliary qubits.</p>\n<p><strong>Examples:</strong></p>\n<ul>\n<li>If the query register is in the state $|010\\rangle$ and $k=0$, flip the sign of the register.</li>\n<li>If the query register is in the state $|010\\rangle$ and $k=1$, do nothing.</li>\n</ul>\n<details>\n <summary><b>Before implementing this oracle, answer the question: are you implementing a marking or a phase oracle?</b></summary>\n This is a phase oracle, because we are changing the phase of the input state $|x\\rangle$ based on the value of the function $f(x)$.\n</details>\n\n<details>\n <summary><b>Need a hint?</b></summary>\n You can use the previously implemented oracles if needed by copying the code.\n <br/>\n You can use <a href=\"https://docs.microsoft.com/en-us/azure/quantum/user-guide/language/expressions/itemaccessexpressions\" target=\"_blank\">array slicing</a> to get parts of the array before and after the $k$-th element.\n</details>\n",
|
|
2168
|
+
"asMarkdown": "**Inputs:**\n\n 1. $N$ qubits in an arbitrary state $|x\\rangle$ (input/query register).\n 2. An integer $k$ such that $0 \\leq k < N$.\n\n**Goal:**\n\nFlip the sign of the basis state $|x\\rangle$ if any of the bits of $x$ (not considering the $k$-th bit) are $1$ in input register. In other words, the input register with the $k$-th qubit excluded should not be in the all zero state to flip the sign of the input register. The state of the $k$-th qubit does not affect the result.\n\nFeel free to explore implementing this operation with or without auxiliary qubits.\n\n**Examples:**\n\n* If the query register is in the state $|010\\rangle$ and $k=0$, flip the sign of the register.\n* If the query register is in the state $|010\\rangle$ and $k=1$, do nothing.\n\n<details>\n <summary><b>Before implementing this oracle, answer the question: are you implementing a marking or a phase oracle?</b></summary>\n This is a phase oracle, because we are changing the phase of the input state $|x\\rangle$ based on the value of the function $f(x)$.\n</details>\n\n<details>\n <summary><b>Need a hint?</b></summary>\n You can use the previously implemented oracles if needed by copying the code.\n <br/>\n You can use <a href=\"https://docs.microsoft.com/en-us/azure/quantum/user-guide/language/expressions/itemaccessexpressions\" target=\"_blank\">array slicing</a> to get parts of the array before and after the $k$-th element.\n</details>\n"
|
|
2169
|
+
},
|
|
2170
|
+
"sourceIds": [
|
|
2171
|
+
"KatasLibrary.qs",
|
|
2172
|
+
"oracles__common.qs",
|
|
2173
|
+
"oracles__or_but_kth_oracle__verification.qs"
|
|
2174
|
+
],
|
|
2175
|
+
"placeholderCode": "namespace Kata {\n operation OrOfBitsExceptKth_Oracle(x : Qubit[], k : Int)\n : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
2176
|
+
"explainedSolution": {
|
|
2177
|
+
"type": "explained-solution",
|
|
2178
|
+
"items": [
|
|
2179
|
+
{
|
|
2180
|
+
"type": "solution",
|
|
2181
|
+
"id": "oracles__or_but_kth_oracle_solution",
|
|
2182
|
+
"code": "namespace Kata {\n operation Or_Oracle(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation OrOfBitsExceptKth_Oracle(x: Qubit[], k: Int): Unit is Adj + Ctl {\n use minus = Qubit();\n within {\n X(minus);\n H(minus);\n } apply {\n Or_Oracle(x[...k-1] + x[k+1...], minus);\n }\n }\n}\n"
|
|
2183
|
+
}
|
|
2184
|
+
]
|
|
2185
|
+
}
|
|
2186
|
+
},
|
|
2187
|
+
{
|
|
2188
|
+
"type": "exercise",
|
|
2189
|
+
"id": "oracles__bit_pattern_oracle",
|
|
2190
|
+
"title": "Implement the Arbitrary Bit Pattern Oracle",
|
|
2191
|
+
"description": {
|
|
2192
|
+
"type": "text-content",
|
|
2193
|
+
"asHtml": "<p><strong>Inputs:</strong></p>\n<ol>\n<li>$N$ qubits in an arbitrary state $|x\\rangle$ (input/query register).</li>\n<li>A qubit in an arbitrary state $|y\\rangle$ (target qubit).</li>\n<li>A boolean array of length $N$ <code>pattern</code> representing a basis state; <code>true</code> and <code>false</code> elements correspond to $|1\\rangle$ and $|0\\rangle$, respectively.</li>\n</ol>\n<p><strong>Goal:</strong></p>\n<p>Flip the state of $|y\\rangle$ if the input register matches the basis state\nrepresented by <code>pattern</code>. </p>\n<p><strong>Examples:</strong></p>\n<ul>\n<li>If the query register is in the state $|010\\rangle$ and <code>pattern = [false, true, false]</code>, flip the state $|y\\rangle$.</li>\n<li>If the query register is in the state $|1001\\rangle$ and <code>pattern = [false, true, true, false]</code>, do nothing.</li>\n</ul>\n<br/>\n<details>\n <summary><b>Before implementing this oracle, answer the question: are you implementing a marking or a phase oracle?</b></summary>\n This is a marking oracle, because we are flipping the state of the target qubit $|y\\rangle$ based on the state of the input $|x\\rangle$.\n</details>\n\n<br/>\n<details>\n <summary><b>Need a hint?</b></summary>\n You need to flip the state of $|y\\rangle$ if $|x\\rangle$ matches the given pattern. You may find the Q# library function <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.canon.controlledonbitstring\" target=\"_blank\">ControlledOnBitString</a> useful in your implementation.\n</details>\n",
|
|
2194
|
+
"asMarkdown": "**Inputs:**\n\n 1. $N$ qubits in an arbitrary state $|x\\rangle$ (input/query register).\n 2. A qubit in an arbitrary state $|y\\rangle$ (target qubit).\n 3. A boolean array of length $N$ `pattern` representing a basis state; `true` and `false` elements correspond to $|1\\rangle$ and $|0\\rangle$, respectively.\n\n**Goal:**\n\nFlip the state of $|y\\rangle$ if the input register matches the basis state\nrepresented by `pattern`. \n\n**Examples:**\n\n* If the query register is in the state $|010\\rangle$ and `pattern = [false, true, false]`, flip the state $|y\\rangle$.\n* If the query register is in the state $|1001\\rangle$ and `pattern = [false, true, true, false]`, do nothing.\n \n<br/>\n<details>\n <summary><b>Before implementing this oracle, answer the question: are you implementing a marking or a phase oracle?</b></summary>\n This is a marking oracle, because we are flipping the state of the target qubit $|y\\rangle$ based on the state of the input $|x\\rangle$.\n</details>\n\n<br/>\n<details>\n <summary><b>Need a hint?</b></summary>\n You need to flip the state of $|y\\rangle$ if $|x\\rangle$ matches the given pattern. You may find the Q# library function <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.canon.controlledonbitstring\" target=\"_blank\">ControlledOnBitString</a> useful in your implementation.\n</details>\n"
|
|
2195
|
+
},
|
|
2196
|
+
"sourceIds": [
|
|
2197
|
+
"KatasLibrary.qs",
|
|
2198
|
+
"oracles__common.qs",
|
|
2199
|
+
"oracles__bit_pattern_oracle__verification.qs"
|
|
2200
|
+
],
|
|
2201
|
+
"placeholderCode": "namespace Kata {\n operation ArbitraryBitPattern_Oracle(x : Qubit[], y : Qubit, pattern : Bool[])\n : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
2202
|
+
"explainedSolution": {
|
|
2203
|
+
"type": "explained-solution",
|
|
2204
|
+
"items": [
|
|
2205
|
+
{
|
|
2206
|
+
"type": "solution",
|
|
2207
|
+
"id": "oracles__bit_pattern_oracle_solution",
|
|
2208
|
+
"code": "namespace Kata {\n operation ArbitraryBitPattern_Oracle(x: Qubit[], y: Qubit, pattern: Bool[])\n : Unit is Adj + Ctl {\n ApplyControlledOnBitString(pattern, X, x, y);\n }\n\n}\n"
|
|
2209
|
+
}
|
|
2210
|
+
]
|
|
2211
|
+
}
|
|
2212
|
+
},
|
|
2213
|
+
{
|
|
2214
|
+
"type": "exercise",
|
|
2215
|
+
"id": "oracles__bit_pattern_challenge",
|
|
2216
|
+
"title": "Implement the Arbitrary Bit Pattern Oracle (Challenge Version)",
|
|
2217
|
+
"description": {
|
|
2218
|
+
"type": "text-content",
|
|
2219
|
+
"asHtml": "<p><strong>Inputs:</strong></p>\n<ol>\n<li>$N$ qubits in an arbitrary state $|x\\rangle$ (input/query register).</li>\n<li>A boolean array of length $N$ <code>pattern</code> representing a basis state; <code>true</code> and <code>false</code> elements correspond to $|1\\rangle$ and $|0\\rangle$, respectively.</li>\n</ol>\n<p><strong>Goal:</strong></p>\n<p>Flip the sign of the input state $|x\\rangle$ if the input register matches the basis state\nrepresented by <code>pattern</code>.<br><strong>Implement this oracle without using auxiliary qubits</strong></p>\n<p><strong>Examples:</strong></p>\n<ul>\n<li>If the query register is in the state $|010\\rangle$ and <code>pattern = [false, true, false]</code>, flip the sign of the input register.</li>\n<li>If the query register is in the state $|1001\\rangle$ and <code>pattern = [false, true, true, false]</code>, do nothing.</li>\n</ul>\n<br/>\n<details>\n <summary><b>Before implementing this oracle, answer the question: are you implementing a marking or a phase oracle?</b></summary>\n This is a phase oracle, because we are changing the phase of the input state $|x\\rangle$ based on the value of the function $f(x)$.\n</details>\n\n<br/>\n<details>\n <summary><b>Need a hint?</b></summary>\n Can you transform the state of the input register based on the <code>pattern</code> value so as to have to flip the phase only for the $|1...1\\rangle$ state?\n</details>\n",
|
|
2220
|
+
"asMarkdown": "**Inputs:**\n\n 1. $N$ qubits in an arbitrary state $|x\\rangle$ (input/query register).\n 2. A boolean array of length $N$ `pattern` representing a basis state; `true` and `false` elements correspond to $|1\\rangle$ and $|0\\rangle$, respectively.\n\n**Goal:**\n \nFlip the sign of the input state $|x\\rangle$ if the input register matches the basis state\nrepresented by `pattern`. \n**Implement this oracle without using auxiliary qubits**\n\n**Examples:**\n\n * If the query register is in the state $|010\\rangle$ and `pattern = [false, true, false]`, flip the sign of the input register.\n * If the query register is in the state $|1001\\rangle$ and `pattern = [false, true, true, false]`, do nothing.\n \n<br/>\n<details>\n <summary><b>Before implementing this oracle, answer the question: are you implementing a marking or a phase oracle?</b></summary>\n This is a phase oracle, because we are changing the phase of the input state $|x\\rangle$ based on the value of the function $f(x)$.\n</details>\n\n<br/>\n<details>\n <summary><b>Need a hint?</b></summary>\n Can you transform the state of the input register based on the <code>pattern</code> value so as to have to flip the phase only for the $|1...1\\rangle$ state?\n</details>\n"
|
|
2221
|
+
},
|
|
2222
|
+
"sourceIds": [
|
|
2223
|
+
"KatasLibrary.qs",
|
|
2224
|
+
"oracles__common.qs",
|
|
2225
|
+
"oracles__bit_pattern_challenge__verification.qs"
|
|
2226
|
+
],
|
|
2227
|
+
"placeholderCode": "namespace Kata {\n operation ArbitraryBitPattern_Oracle_Challenge(x : Qubit[], pattern : Bool[])\n : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
2228
|
+
"explainedSolution": {
|
|
2229
|
+
"type": "explained-solution",
|
|
2230
|
+
"items": [
|
|
2231
|
+
{
|
|
2232
|
+
"type": "solution",
|
|
2233
|
+
"id": "oracles__bit_pattern_challenge_solution",
|
|
2234
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Arrays;\n\n operation ArbitraryBitPattern_Oracle_Challenge(\n x: Qubit[],\n pattern: Bool[])\n : Unit is Adj + Ctl {\n within {\n for i in IndexRange(x) {\n if not pattern[i] {\n X(x[i]);\n }\n }\n } apply {\n Controlled Z(Most(x), Tail(x));\n }\n }\n}\n"
|
|
2235
|
+
}
|
|
2236
|
+
]
|
|
2237
|
+
}
|
|
2238
|
+
},
|
|
2239
|
+
{
|
|
2240
|
+
"type": "exercise",
|
|
2241
|
+
"id": "oracles__meeting_oracle",
|
|
2242
|
+
"title": "Implement the Meeting Oracle",
|
|
2243
|
+
"description": {
|
|
2244
|
+
"type": "text-content",
|
|
2245
|
+
"asHtml": "<p>Suppose that you would like to schedule a meeting with your co-worker Jasmine. \nYou both work five day workweeks, and $|x\\rangle$ and $|jasmine\\rangle$ are 5-bit states represent your and Jasmine's schedules. \nThe schedules are indicators of a person being busy on that day: a $1$ bit means that person is busy on that day, and $0$ means they're free for a meeting that day. Implement a function that determines if you and Jasmine can schedule a meeting during the week, i.e., whether there is a day when both schedules have a $0$ simultaneously.</p>\n<p><strong>Inputs:</strong></p>\n<ol>\n<li>5 qubits in an arbitrary state $|x\\rangle$ representing your schedule for the week (input/query register).</li>\n<li>5 qubits in an arbitrary state $|jasmine\\rangle$ representing Jasmine's schedule for the week (input/query register).</li>\n<li>A qubit in an arbitrary state $|y\\rangle$ (target qubit).</li>\n</ol>\n<p><strong>Goal:</strong></p>\n<p>Flip the state of $|y\\rangle$ if you and Jasmine are both free on the same day for at least one day during the week. Recall that a $0$ means that a person is free on that day.</p>\n<p><strong>Examples:</strong></p>\n<ul>\n<li>If $|x\\rangle=|10101\\rangle$ and $|jasmine\\rangle=|01010\\rangle$, do nothing (there is no day on which you both are free).</li>\n<li>If $|x\\rangle=|10001\\rangle$ and $|jasmine\\rangle=|01010\\rangle$, flip the state $|y\\rangle$ (you are both free on Wednesday).</li>\n<li>If $|x\\rangle=|00000\\rangle$ and $|jasmine\\rangle=|00000\\rangle$, flip the state $|z\\rangle$ (you are both free all week).</li>\n<li>If $|x\\rangle=|11111\\rangle$ and $|jasmine\\rangle=|11111\\rangle$, do nothing (you are both busy all week).</li>\n</ul>\n<br/>\n<details>\n <summary><b>Before implementing this oracle, answer the question: are you implementing a marking or a phase oracle?</b></summary>\n This is a marking oracle, because we are flipping the state of the target qubit $|y\\rangle$ based on the state of the inputs $|x\\rangle$ and $|jasmine\\rangle$. Notice that even though we do not have the typical single-input-register situation that we saw earlier, this is still a marking oracle.\n</details>\n",
|
|
2246
|
+
"asMarkdown": "Suppose that you would like to schedule a meeting with your co-worker Jasmine. \nYou both work five day workweeks, and $|x\\rangle$ and $|jasmine\\rangle$ are 5-bit states represent your and Jasmine's schedules. \nThe schedules are indicators of a person being busy on that day: a $1$ bit means that person is busy on that day, and $0$ means they're free for a meeting that day. Implement a function that determines if you and Jasmine can schedule a meeting during the week, i.e., whether there is a day when both schedules have a $0$ simultaneously.\n\n**Inputs:**\n\n 1. 5 qubits in an arbitrary state $|x\\rangle$ representing your schedule for the week (input/query register).\n 2. 5 qubits in an arbitrary state $|jasmine\\rangle$ representing Jasmine's schedule for the week (input/query register).\n 3. A qubit in an arbitrary state $|y\\rangle$ (target qubit).\n\n**Goal:**\n\nFlip the state of $|y\\rangle$ if you and Jasmine are both free on the same day for at least one day during the week. Recall that a $0$ means that a person is free on that day.\n\n**Examples:**\n\n* If $|x\\rangle=|10101\\rangle$ and $|jasmine\\rangle=|01010\\rangle$, do nothing (there is no day on which you both are free).\n* If $|x\\rangle=|10001\\rangle$ and $|jasmine\\rangle=|01010\\rangle$, flip the state $|y\\rangle$ (you are both free on Wednesday).\n* If $|x\\rangle=|00000\\rangle$ and $|jasmine\\rangle=|00000\\rangle$, flip the state $|z\\rangle$ (you are both free all week).\n* If $|x\\rangle=|11111\\rangle$ and $|jasmine\\rangle=|11111\\rangle$, do nothing (you are both busy all week).\n \n<br/>\n<details>\n <summary><b>Before implementing this oracle, answer the question: are you implementing a marking or a phase oracle?</b></summary>\n This is a marking oracle, because we are flipping the state of the target qubit $|y\\rangle$ based on the state of the inputs $|x\\rangle$ and $|jasmine\\rangle$. Notice that even though we do not have the typical single-input-register situation that we saw earlier, this is still a marking oracle.\n</details>\n"
|
|
2247
|
+
},
|
|
2248
|
+
"sourceIds": [
|
|
2249
|
+
"KatasLibrary.qs",
|
|
2250
|
+
"oracles__common.qs",
|
|
2251
|
+
"oracles__meeting_oracle__verification.qs"
|
|
2252
|
+
],
|
|
2253
|
+
"placeholderCode": "namespace Kata {\n operation Meeting_Oracle(x : Qubit[], jasmine : Qubit[], z : Qubit)\n : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
2254
|
+
"explainedSolution": {
|
|
2255
|
+
"type": "explained-solution",
|
|
2256
|
+
"items": [
|
|
2257
|
+
{
|
|
2258
|
+
"type": "solution",
|
|
2259
|
+
"id": "oracles__meeting_oracle_solution",
|
|
2260
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Arrays;\n\n operation Or_Oracle(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation Meeting_Oracle(x: Qubit[], jasmine: Qubit[], z: Qubit): Unit is Adj + Ctl {\n use q = Qubit[Length(x)];\n within {\n for i in IndexRange(q) {\n // flip q[i] if both x and jasmine are free on the given day\n X(x[i]);\n X(jasmine[i]);\n CCNOT(x[i], jasmine[i], q[i]);\n }\n } apply {\n Or_Oracle(q, z);\n }\n }\n}\n"
|
|
2261
|
+
}
|
|
2262
|
+
]
|
|
2263
|
+
}
|
|
2264
|
+
},
|
|
2265
|
+
{
|
|
2266
|
+
"type": "lesson",
|
|
2267
|
+
"id": "oracles__testing_implementation",
|
|
2268
|
+
"title": "Testing an Oracle Implementation",
|
|
2269
|
+
"items": [
|
|
2270
|
+
{
|
|
2271
|
+
"type": "text-content",
|
|
2272
|
+
"asHtml": "<p>In this demo we show how you could test an oracle that you've implemented for your own problem. \nFor all of the previous oracles that you've implemented, we've been testing your oracle against a reference solution for that task. \nHowever, if you're designing an oracle for a new problem, you do not have a reference solution for it - if you did, there would be no point for you to program the oracle in the first place!</p>\n<p>A good way to test a quantum oracle of interest is to write a classical oracle that performs the same computation classically, and then compare the effect of your quantum oracle on the basis states with the output of the classical oracle for every input (or a lot of the inputs if you are constrained by runtime) to ensure that they match.</p>\n<p>Here we will compare the reference implementation of <code>Meeting_Classical</code> oracle to the classical code implementing the same function.</p>\n",
|
|
2273
|
+
"asMarkdown": "\nIn this demo we show how you could test an oracle that you've implemented for your own problem. \nFor all of the previous oracles that you've implemented, we've been testing your oracle against a reference solution for that task. \nHowever, if you're designing an oracle for a new problem, you do not have a reference solution for it - if you did, there would be no point for you to program the oracle in the first place!\n\nA good way to test a quantum oracle of interest is to write a classical oracle that performs the same computation classically, and then compare the effect of your quantum oracle on the basis states with the output of the classical oracle for every input (or a lot of the inputs if you are constrained by runtime) to ensure that they match.\n\nHere we will compare the reference implementation of `Meeting_Classical` oracle to the classical code implementing the same function."
|
|
2274
|
+
},
|
|
2275
|
+
{
|
|
2276
|
+
"type": "example",
|
|
2277
|
+
"id": "oracles__test_meeting_oracle",
|
|
2278
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Convert;\n\n // The classical function to perform the same computation\n function Meeting_Classical(x: Bool[], jasmine: Bool[]): Bool {\n for i in IndexRange(x) {\n if ((not x[i]) and (not jasmine[i])) {\n // They have a day that they can both meet\n return true;\n }\n }\n \n // At least one of them is busy every day of the week\n return false;\n }\n\n operation Or_Oracle(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation Meeting_Oracle(x: Qubit[], jasmine: Qubit[], z: Qubit): Unit is Adj + Ctl {\n use q = Qubit[Length(x)];\n within {\n for i in IndexRange(q) {\n // flip q[i] if both x and jasmine are free on the given day\n X(x[i]);\n X(jasmine[i]);\n CCNOT(x[i], jasmine[i], q[i]);\n }\n } apply {\n Or_Oracle(q, z);\n }\n }\n\n @EntryPoint()\n operation Test_Meeting_Oracle(): Unit {\n // There are 2^5 ways to arrange each of the schedules - let's try all of them\n for k in 0..((2^5)-1) { \n for j in 0..((2^5)-1) {\n // Convert your and Jasmine's schedules to bit arrays\n let binaryX = IntAsBoolArray(k, 5);\n let binaryJasmine = IntAsBoolArray(j, 5);\n \n // Calculate the function classically\n let classicalResult = Meeting_Classical(binaryX, binaryJasmine);\n \n // create a register of qubits so we can represent\n // your schedule, jasmine's schedule, and the output\n use (x, jasmine, target) = (Qubit[5], Qubit[5], Qubit());\n // Prepare the quantum schedules in basis states matching the binary schedules\n ApplyPauliFromBitString(PauliX, true, binaryX, x);\n ApplyPauliFromBitString(PauliX, true, binaryJasmine, jasmine);\n\n // Apply the quantum oracle\n Meeting_Oracle(x, jasmine, target);\n\n // Check that the result of the quantum algorithm matched that\n // of the classical algorithm\n if CheckZero(target) == classicalResult {\n Message($\"Failed on test case k = {k}, j = {j}. Classical result is not the same as target.\");\n }\n\n // Undo the preparation of basis states x and jasmine\n ApplyPauliFromBitString(PauliX, true, binaryX, x);\n ApplyPauliFromBitString(PauliX, true, binaryJasmine, jasmine);\n\n // Check that the oracle did not change its input states\n if not CheckAllZero(x) {\n Message($\"Failed on test case k = {k}, j = {j}. Input state of x changed.\"); \n }\n if not CheckAllZero(jasmine) {\n Message($\"Failed on test case k = {k}, j = {j}. Input state of jasmine changed.\"); \n }\n\n Reset(target);\n }\n }\n \n Message(\"Success!\");\n }\n\n}\n"
|
|
2279
|
+
}
|
|
2280
|
+
]
|
|
2281
|
+
},
|
|
2282
|
+
{
|
|
2283
|
+
"type": "lesson",
|
|
2284
|
+
"id": "oracles__conclusion",
|
|
2285
|
+
"title": "Conclusion",
|
|
2286
|
+
"items": [
|
|
2287
|
+
{
|
|
2288
|
+
"type": "text-content",
|
|
2289
|
+
"asHtml": "<p>Congratulations! In this kata you have learned to build quantum oracles. Here are a few key concepts to keep in mind:</p>\n<ul>\n<li>A quantum oracle is an "opaque box" operation that is used as input to another algorithm.</li>\n<li>Phase oracles encode the information in the relative phase of basis states $\\ket{0}$ and $\\ket{1}$. If $f(x)=0$, it does nothing, and if $f(x)=1$ it multiplies the phase of the basis states for which by $-1$.</li>\n<li>Marking oracles uses an extra qubit $\\ket{y}$ and encode the information in the state of that qubit. If $f(x)=0$, it does nothing, and if $f(x)=1$ it it flips the state of the qubit $\\ket{y}$.</li>\n</ul>\n<p><strong>Next Steps</strong></p>\n<p>We hope you enjoyed this kata! If you're looking to learn more about quantum oracles and Q#, here are some suggestions:</p>\n<ul>\n<li>To learn about the Grover's algorithm, you can check <a href=\"https://learn.microsoft.com/en-us/training/modules/solve-graph-coloring-problems-grovers-search/\" target=\"_blank\">Microsoft Learn module "Solve graph coloring problems by using Grover's search"</a>.</li>\n<li>To learn more about the Q# libraries, you can check the <a href=\"https://learn.microsoft.com/en-us/azure/quantum/user-guide/libraries/?tabs=tabid-clivscode\" target=\"_blank\">The Q# user guide</a>.</li>\n</ul>\n",
|
|
2290
|
+
"asMarkdown": "\nCongratulations! In this kata you have learned to build quantum oracles. Here are a few key concepts to keep in mind:\n* A quantum oracle is an \"opaque box\" operation that is used as input to another algorithm.\n* Phase oracles encode the information in the relative phase of basis states $\\ket{0}$ and $\\ket{1}$. If $f(x)=0$, it does nothing, and if $f(x)=1$ it multiplies the phase of the basis states for which by $-1$.\n* Marking oracles uses an extra qubit $\\ket{y}$ and encode the information in the state of that qubit. If $f(x)=0$, it does nothing, and if $f(x)=1$ it it flips the state of the qubit $\\ket{y}$.\n\n**Next Steps**\n\nWe hope you enjoyed this kata! If you're looking to learn more about quantum oracles and Q#, here are some suggestions:\n* To learn about the Grover's algorithm, you can check <a href=\"https://learn.microsoft.com/en-us/training/modules/solve-graph-coloring-problems-grovers-search/\" target=\"_blank\">Microsoft Learn module \"Solve graph coloring problems by using Grover's search\"</a>.\n* To learn more about the Q# libraries, you can check the <a href=\"https://learn.microsoft.com/en-us/azure/quantum/user-guide/libraries/?tabs=tabid-clivscode\" target=\"_blank\">The Q# user guide</a>."
|
|
2291
|
+
}
|
|
2292
|
+
]
|
|
2293
|
+
}
|
|
2294
|
+
]
|
|
2295
|
+
}
|
|
2296
|
+
],
|
|
2297
|
+
"globalCodeSources": [
|
|
2298
|
+
{
|
|
2299
|
+
"id": "KatasLibrary.qs",
|
|
2300
|
+
"code": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nnamespace Microsoft.Quantum.Katas {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Intrinsic;\n\n /// # Summary\n /// Given two operations, checks whether they act identically for all input states.\n /// This operation is implemented by using the Choi–Jamiołkowski isomorphism.\n ///\n /// N.B. Investigate whether this can be done using just 1 control qubit (GitHub issue #535).\n operation CheckOperationsEquivalence(\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl),\n inputSize: Int)\n : Bool {\n Fact(inputSize > 0, \"`inputSize` must be positive\");\n use (control, target) = (Qubit[inputSize], Qubit[inputSize]);\n within {\n // N.B. The order in which quantum registers are passed to this operation is important.\n EntangleRegisters(control, target);\n }\n apply {\n op(target);\n Adjoint reference(target);\n }\n\n let areEquivalent = CheckAllZero(control + target);\n ResetAll(control + target);\n areEquivalent\n }\n\n /// # Summary\n /// Given two operations, checks whether they act identically (including global phase) for all input states.\n /// This is done through controlled versions of the operations instead of plain ones which convert the global phase\n /// into a relative phase that can be detected.\n operation CheckOperationsEquivalenceStrict(\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl),\n inputSize: Int)\n : Bool {\n Fact(inputSize > 0, \"`inputSize` must be positive\");\n let controlledOp = register => Controlled op(register[...0], register[1...]);\n let controlledReference = register => Controlled reference(register[...0], register[1...]);\n let areEquivalent = CheckOperationsEquivalence(controlledOp, controlledReference, inputSize + 1);\n areEquivalent\n }\n\n /// # Summary\n /// Given two operations, checks whether they act identically on the zero state |0〉 ⊗ |0〉 ⊗ ... ⊗ |0〉 composed of\n /// `inputSize` qubits.\n operation CheckOperationsEquivalenceOnZeroState(\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl),\n inputSize: Int)\n : Bool {\n Fact(inputSize > 0, \"`inputSize` must be positive\");\n use target = Qubit[inputSize];\n op(target);\n Adjoint reference(target);\n let isCorrect = CheckAllZero(target);\n ResetAll(target);\n isCorrect\n }\n\n /// # Summary\n /// Given two operations, checks whether they act identically on the zero state |0〉 ⊗ |0〉 ⊗ ... ⊗ |0〉 composed of\n /// `inputSize` qubits.\n /// This operation introduces a control qubit to convert a global phase into a relative phase to be able to detect\n /// it.\n operation CheckOperationsEquivalenceOnZeroStateStrict(\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl),\n inputSize: Int)\n : Bool {\n Fact(inputSize > 0, \"`inputSize` must be positive\");\n use control = Qubit();\n use target = Qubit[inputSize];\n within {\n H(control);\n }\n apply {\n Controlled op([control], target);\n Adjoint Controlled reference([control], target);\n }\n\n let isCorrect = CheckAllZero([control] + target);\n ResetAll([control] + target);\n isCorrect\n }\n\n /// # Summary\n /// Shows the effect a quantum operation has on the quantum state.\n operation ShowEffectOnQuantumState(targetRegister : Qubit[], op : (Qubit[] => Unit is Adj + Ctl)) : Unit {\n Message(\"Quantum state before applying the operation:\");\n DumpMachine();\n\n // Apply the operation, dump the simulator state and \"undo\" the operation by applying the adjoint.\n Message(\"Quantum state after applying the operation:\");\n op(targetRegister);\n DumpMachine();\n Adjoint op(targetRegister);\n }\n\n /// # Summary\n /// Shows the comparison of the quantum state between a specific operation and a reference operation.\n operation ShowQuantumStateComparison(\n targetRegister : Qubit[],\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl))\n : Unit {\n Message(\"Initial quantum state:\");\n DumpMachine();\n\n // Apply the reference operation, dump the simulator state and \"undo\" the operation by applying the adjoint.\n reference(targetRegister);\n Message(\"Expected quantum state after applying the operation:\");\n DumpMachine();\n Adjoint reference(targetRegister);\n\n // Apply the specific operation, dump the simulator state and \"undo\" the operation by applying the adjoint.\n op(targetRegister);\n Message(\"Actual quantum state after applying the operation:\");\n DumpMachine();\n Adjoint op(targetRegister);\n }\n\n internal operation EntangleRegisters(\n control : Qubit[],\n target : Qubit[]) : Unit is Adj + Ctl {\n Fact(\n Length(control) == Length(target),\n $\"The length of qubit registers must be the same.\");\n\n for index in IndexRange(control) {\n H(control[index]);\n CNOT(control[index], target[index]);\n }\n }\n}\n"
|
|
2301
|
+
},
|
|
2302
|
+
{
|
|
2303
|
+
"id": "getting_started__flip_qubit__Verification.qs",
|
|
2304
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Katas;\n\n operation FlipQubit(q : Qubit): Unit is Adj + Ctl {\n X(q);\n }\n\n operation CheckSolution() : Bool {\n let solution = register => Kata.FlipQubit(register[0]);\n let reference = register => FlipQubit(register[0]);\n let isCorrect = CheckOperationsEquivalence(solution, reference, 1);\n\n // Output different feedback to the user depending on whether the solution was correct.\n if isCorrect {\n Message(\"Correct!\");\n Message(\"Congratulations! You have solved your first exercise.\");\n } else {\n Message(\"Incorrect.\");\n Message(\"Look out for hints when your solution is incorrect.\");\n Message(\"Hint: examine the effect your solution has on the |0〉 state and compare it with the effect it \" +\n \"is expected to have.\");\n use target = Qubit[1]; // |0〉\n ShowQuantumStateComparison(target, solution, reference);\n ResetAll(target);\n }\n isCorrect\n }\n}\n"
|
|
2305
|
+
},
|
|
2306
|
+
{
|
|
2307
|
+
"id": "qubit__learn_single_qubit_state__Verification.qs",
|
|
2308
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n use q = Qubit();\n\n // Prepare the state that will be passed to the solution.\n let angle = 0.5;\n Ry(angle, q);\n\n // Call the solution and get the answer.\n let (a, b) = Kata.LearnSingleQubitState(q);\n\n // Calculate the expected values based on the rotation angle.\n let (a_exp, b_exp) = (Cos(0.5 * angle), Sin(0.5 * angle));\n\n Reset(q);\n\n let isCorrect =\n (AbsD(a - a_exp) <= 0.001) and\n (AbsD(b - b_exp) <= 0.001);\n\n // Output different feedback to the user depending on whether the exercise was correct.\n if isCorrect {\n Message(\"All tests passed.\");\n } else {\n Message(\"At least one of the amplitudes was too far from the expected value.\");\n }\n\n isCorrect\n }\n}\n"
|
|
2309
|
+
},
|
|
2310
|
+
{
|
|
2311
|
+
"id": "qubit__learn_basis_state_amplitudes__Verification.qs",
|
|
2312
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n use qs = Qubit[2];\n\n // Prepare the state that will be passed to the solution.\n H(qs[0]);\n ApplyControlledOnInt(0, Ry(1.0, _), [qs[0]], qs[1]);\n ApplyControlledOnInt(1, Ry(2.0, _), [qs[0]], qs[1]);\n\n // Call the solution and get the answer.\n let (x1, x2) = Kata.LearnBasisStateAmplitudes(qs);\n\n // Calculate the expected values based on the rotation angle.\n // We convert |00⟩ + |10⟩ to |0⟩ Ry(1.0)|0⟩ + |1⟩ Ry(2.0)|0⟩, so \n // * the amplitude of |1⟩ = |10⟩ is 1st amp of Ry(2.0)|0⟩\n // * the amplitude of |2⟩ = |01⟩ is 2nd amp of Ry(1.0)|0⟩\n let (x1_exp, x2_exp) = (\n 1.0/Sqrt(2.0) * Cos(0.5 * 2.0),\n 1.0/Sqrt(2.0) * Sin(0.5 * 1.0));\n\n let isCorrect =\n (AbsD(x1 - x1_exp) <= 0.001) and\n (AbsD(x2 - x2_exp) <= 0.001);\n\n ResetAll(qs);\n\n // Output different feedback to the user depending on whether the exercise was correct.\n if isCorrect {\n Message(\"All tests passed.\");\n } else {\n Message(\"One of the amplitudes was too far from the expected value.\");\n }\n\n isCorrect\n }\n}\n"
|
|
2313
|
+
},
|
|
2314
|
+
{
|
|
2315
|
+
"id": "single_qubit_gates__y_gate__Verification.qs",
|
|
2316
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Katas;\n\n operation ApplyY(q : Qubit) : Unit is Adj + Ctl {\n Y(q);\n }\n\n operation CheckSolution() : Bool {\n let solution = register => Kata.ApplyY(register[0]);\n let reference = register => ApplyY(register[0]);\n let isCorrect = CheckOperationsEquivalenceStrict(solution, reference, 1);\n\n // Output different feedback to the user depending on whether the solution was correct.\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n Message(\"Hint: examine the effect your solution has on the |0〉 state and compare it with the effect it \" +\n \"is expected to have.\");\n use target = Qubit[1]; // |0〉\n ShowQuantumStateComparison(target, solution, reference);\n ResetAll(target);\n }\n isCorrect\n }\n}\n"
|
|
2317
|
+
},
|
|
2318
|
+
{
|
|
2319
|
+
"id": "single_qubit_gates__global_phase_i__Verification.qs",
|
|
2320
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Katas;\n\n operation GlobalPhaseI(q : Qubit) : Unit is Adj + Ctl {\n X(q);\n Z(q);\n Y(q);\n }\n\n operation CheckSolution() : Bool {\n let solution = register => Kata.GlobalPhaseI(register[0]);\n let reference = register => GlobalPhaseI(register[0]);\n let isCorrect = CheckOperationsEquivalenceStrict(solution, reference, 1);\n\n // Output different feedback to the user depending on whether the solution was correct.\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n Message(\"Hint: examine the effect your solution has on the |0〉 state and compare it with the effect it \" +\n \"is expected to have.\");\n use target = Qubit[1]; // |0〉\n ShowQuantumStateComparison(target, solution, reference);\n ResetAll(target);\n }\n isCorrect\n }\n}\n"
|
|
2321
|
+
},
|
|
2322
|
+
{
|
|
2323
|
+
"id": "single_qubit_gates__sign_flip_on_zero__Verification.qs",
|
|
2324
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Katas;\n\n operation SignFlipOnZero(q : Qubit) : Unit is Adj + Ctl {\n X(q);\n Z(q);\n X(q);\n }\n\n operation CheckSolution() : Bool {\n let solution = register => Kata.SignFlipOnZero(register[0]);\n let reference = register => SignFlipOnZero(register[0]);\n let isCorrect = CheckOperationsEquivalenceStrict(solution, reference, 1);\n\n // Output different feedback to the user depending on whether the exercise was correct.\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n Message(\"Hint: examine the effect your solution has on the |+〉 state and compare it with the effect it \" +\n \"is expected to have.\");\n use target = Qubit[1]; // |0〉\n H(target[0]); // |+〉\n ShowQuantumStateComparison(target, solution, reference);\n ResetAll(target);\n }\n isCorrect\n }\n}\n"
|
|
2325
|
+
},
|
|
2326
|
+
{
|
|
2327
|
+
"id": "single_qubit_gates__prepare_minus__Verification.qs",
|
|
2328
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Katas;\n\n operation PrepareMinus(q : Qubit) : Unit is Adj + Ctl {\n X(q);\n H(q);\n }\n\n operation CheckSolution() : Bool {\n let solution = register => Kata.PrepareMinus(register[0]);\n let reference = register => PrepareMinus(register[0]);\n let isCorrect = CheckOperationsEquivalenceOnZeroStateStrict(solution, reference, 1);\n\n // Output different feedback to the user depending on whether the exercise was correct.\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n Message(\"Hint: examine the effect your solution has on the |0〉 state and compare it with the effect it \" +\n \"is expected to have.\");\n use target = Qubit[1]; // |0〉\n ShowQuantumStateComparison(target, solution, reference);\n ResetAll(target);\n }\n isCorrect\n }\n}\n"
|
|
2329
|
+
},
|
|
2330
|
+
{
|
|
2331
|
+
"id": "single_qubit_gates__three_quarters_pi_phase__Verification.qs",
|
|
2332
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Katas;\n open Microsoft.Quantum.Diagnostics;\n\n operation ThreeQuartersPiPhase(q : Qubit) : Unit is Adj + Ctl {\n S(q);\n T(q);\n }\n\n operation CheckSolution() : Bool {\n let solution = register => Kata.ThreeQuartersPiPhase(register[0]);\n let reference = register => ThreeQuartersPiPhase(register[0]);\n let isCorrect = CheckOperationsEquivalenceStrict(solution, reference, 1);\n\n // Output different feedback to the user depending on whether the exercise was correct.\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n Message(\"The solution was incorrect for at least one test case.\");\n use target = Qubit[1];\n ShowQuantumStateComparison(target, solution, reference);\n ResetAll(target);\n }\n isCorrect\n }\n}\n"
|
|
2333
|
+
},
|
|
2334
|
+
{
|
|
2335
|
+
"id": "single_qubit_gates__prepare_rotated_state__Verification.qs",
|
|
2336
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Canon;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Katas;\n\n operation PrepareRotatedState (alpha : Double, beta : Double, q : Qubit) : Unit is Adj+Ctl {\n let phi = ArcTan2(beta, alpha);\n Rx(2.0 * phi, q);\n }\n\n operation CheckSolution() : Bool {\n for i in 0 .. 10 {\n let i = IntAsDouble(i);\n let alpha = Cos(i);\n let beta = Sin(i);\n let solution = register => Kata.PrepareRotatedState(alpha, beta, register[0]);\n let reference = register => PrepareRotatedState(alpha, beta, register[0]);\n let isCorrect = CheckOperationsEquivalenceOnZeroStateStrict(solution, reference, 1);\n if not isCorrect {\n Message(\"Incorrect.\");\n Message(\"The solution was incorrect for at least one test case.\");\n Message(\"Hint: examine the effect your solution has on the |0〉 state and compare it with the effect \" +\n \"it is expected to have.\");\n use target = Qubit[1]; // |0〉\n ShowQuantumStateComparison(target, solution, reference);\n ResetAll(target);\n return false;\n }\n }\n\n Message(\"Correct!\");\n Message(\"The solution was correct for all test cases.\");\n true\n }\n}\n"
|
|
2337
|
+
},
|
|
2338
|
+
{
|
|
2339
|
+
"id": "single_qubit_gates__prepare_arbitrary_state__Verification.qs",
|
|
2340
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Katas;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Convert;\n\n operation PrepareArbitraryState (alpha : Double, beta : Double, theta : Double, q : Qubit) : Unit is Adj+Ctl {\n let phi = ArcTan2(beta, alpha);\n Ry(2.0 * phi, q);\n R1(theta, q);\n }\n\n operation CheckSolution() : Bool {\n for i in 0 .. 10 {\n let i = IntAsDouble(i);\n let alpha = Cos(i);\n let beta = Sin(i);\n let theta = Sin(i);\n let solution = register => Kata.PrepareArbitraryState(alpha, beta, theta, register[0]);\n let reference = register => PrepareArbitraryState(alpha, beta, theta, register[0]);\n let isCorrect = CheckOperationsEquivalenceOnZeroStateStrict(solution, reference, 1);\n if not isCorrect {\n Message(\"Incorrect.\");\n Message(\"The solution was incorrect for at least one test case.\");\n Message(\"Hint: examine the effect your solution has on the |0〉 state and compare it with the effect \" +\n \"it is expected to have.\");\n use target = Qubit[1]; // |0〉\n ShowQuantumStateComparison(target, solution, reference);\n ResetAll(target);\n return false;\n }\n }\n\n Message(\"Correct!\");\n Message(\"The solution was correct for all test cases.\");\n true\n }\n}\n"
|
|
2341
|
+
},
|
|
2342
|
+
{
|
|
2343
|
+
"id": "multi_qubit_systems__common.qs",
|
|
2344
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n\n operation AssertEqualOnZeroState(\n testImpl: (Qubit[] => Unit is Ctl),\n refImpl : (Qubit[] => Unit is Adj+Ctl)) : Bool {\n\n use qs = Qubit[3];\n within {\n H(qs[0]);\n }\n apply {\n // apply operation that needs to be tested\n Controlled testImpl([qs[0]], qs[1..2]);\n\n // apply adjoint reference operation\n Adjoint Controlled refImpl([qs[0]], qs[1..2]);\n }\n\n // Implementation is correct when all qubits end up in |0⟩ state\n let isCorrect = CheckAllZero(qs);\n if not isCorrect {\n Message(\"The prepared state is not the same as reference state.\");\n }\n ResetAll(qs);\n isCorrect\n }\n\n}"
|
|
2345
|
+
},
|
|
2346
|
+
{
|
|
2347
|
+
"id": "multi_qubit_systems__prepare_basis_state__verification.qs",
|
|
2348
|
+
"code": "namespace Kata.Verification {\n operation PrepareBasisState_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n X(qs[0]);\n X(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareBasisState, PrepareBasisState_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}"
|
|
2349
|
+
},
|
|
2350
|
+
{
|
|
2351
|
+
"id": "multi_qubit_systems__prepare_superposition__verification.qs",
|
|
2352
|
+
"code": "namespace Kata.Verification {\n operation PrepareSuperposition_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n X(qs[1]);\n H(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareSuperposition, PrepareSuperposition_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}"
|
|
2353
|
+
},
|
|
2354
|
+
{
|
|
2355
|
+
"id": "multi_qubit_systems__prepare_with_real__verification.qs",
|
|
2356
|
+
"code": "namespace Kata.Verification {\n operation PrepareWithReal_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n X(qs[1]);\n H(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareWithReal, PrepareWithReal_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}"
|
|
2357
|
+
},
|
|
2358
|
+
{
|
|
2359
|
+
"id": "multi_qubit_systems__prepare_with_complex__verification.qs",
|
|
2360
|
+
"code": "namespace Kata.Verification {\n operation PrepareWithComplex_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n H(qs[1]);\n S(qs[0]);\n T(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareWithComplex, PrepareWithComplex_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}"
|
|
2361
|
+
},
|
|
2362
|
+
{
|
|
2363
|
+
"id": "multi_qubit_gates__compound_gate__Verification.qs",
|
|
2364
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Katas;\n\n operation CompoundGate (qs : Qubit[]) : Unit is Adj + Ctl {\n S(qs[0]);\n I(qs[1]); // this line can be omitted, since it doesn't change the qubit state\n Y(qs[2]);\n }\n\n operation CheckSolution() : Bool {\n let solution = Kata.CompoundGate;\n let reference = CompoundGate;\n let isCorrect = CheckOperationsEquivalence(solution, reference, 3);\n\n // Output different feedback to the user depending on whether the solution was correct.\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n Message(\"Hint: examine how your solution transforms the |000〉 state and compare it with the expected \" +\n \"transformation\");\n use target = Qubit[3]; // |000〉\n ShowQuantumStateComparison(target, solution, reference);\n ResetAll(target);\n }\n\n isCorrect\n }\n}"
|
|
2365
|
+
},
|
|
2366
|
+
{
|
|
2367
|
+
"id": "multi_qubit_gates__preparing_bell_state__Verification.qs",
|
|
2368
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Katas;\n\n operation BellState (qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n CNOT(qs[0], qs[1]);\n }\n\n operation CheckSolution() : Bool {\n let solution = Kata.BellState;\n let reference = BellState;\n let isCorrect = CheckOperationsEquivalenceOnZeroState(solution, reference, 2);\n\n // Output different feedback to the user depending on whether the solution was correct.\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect :(\");\n Message(\"Hint: examine how your solution transforms the |00〉 state and compare it with the expected \" +\n \"transformation\");\n use target = Qubit[2]; // |00〉\n ShowQuantumStateComparison(target, solution, reference);\n ResetAll(target);\n }\n\n isCorrect\n }\n}"
|
|
2369
|
+
},
|
|
2370
|
+
{
|
|
2371
|
+
"id": "multi_qubit_gates__qubit_swap__Verification.qs",
|
|
2372
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Katas;\n\n operation QubitSwap (qs : Qubit[], index1 : Int, index2 : Int) : Unit is Adj + Ctl {\n SWAP(qs[index1], qs[index2]);\n }\n\n operation CheckSolution() : Bool {\n for N in 2 .. 5 {\n for index1 in 0 .. N-2 {\n for index2 in index1+1 .. N-1 {\n let solution = register => Kata.QubitSwap(register, index1, index2);\n let reference = register => QubitSwap(register, index1, index2);\n if not CheckOperationsEquivalence(solution, reference, N) {\n Message(\"Incorrect.\");\n Message(\"At least one test case did not pass\");\n return false;\n }\n\n }\n }\n }\n\n Message(\"Correct!\");\n Message(\"All test cases passed.\");\n true\n }\n}"
|
|
2373
|
+
},
|
|
2374
|
+
{
|
|
2375
|
+
"id": "multi_qubit_gates__controlled_rotation__Verification.qs",
|
|
2376
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Katas;\n\n operation ControlledRotation (qs : Qubit[], theta : Double) : Unit is Adj + Ctl {\n let controll = qs[0];\n let target = qs[1];\n Controlled Rx([controll], (theta, target));\n }\n\n operation CheckSolution() : Bool {\n for i in 0 .. 20 {\n let angle = IntAsDouble(i) / 10.0;\n let solution = register => Kata.ControlledRotation(register, angle);\n let reference = register => ControlledRotation(register, angle);\n if not CheckOperationsEquivalence(solution, reference, 2) {\n Message(\"Incorrect.\");\n Message(\"At least one test case did not pass\");\n return false;\n }\n }\n\n Message(\"Correct!\");\n Message(\"All test cases passed.\");\n true\n }\n}"
|
|
2377
|
+
},
|
|
2378
|
+
{
|
|
2379
|
+
"id": "multi_qubit_gates__arbitrary_controls__Verification.qs",
|
|
2380
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Katas;\n\n operation MultiControls(controls : Qubit[], target : Qubit, controlBits : Bool[]) : Unit is Adj + Ctl {\n within {\n for index in 0 .. Length(controls) - 1 {\n if controlBits[index] == false {\n X(controls[index]);\n }\n }\n } apply {\n Controlled X(controls,target);\n }\n }\n\n operation CheckSolution() : Bool {\n for i in 0 .. (2 ^ 4) - 1 {\n let bits = IntAsBoolArray(i, 4);\n let solution = register => Kata.MultiControls(Most(register), Tail(register), bits);\n let reference = register => MultiControls(Most(register), Tail(register), bits);\n if not CheckOperationsEquivalence(solution, reference, 5) {\n Message(\"Incorrect.\");\n Message(\"At least one test case did not pass\");\n return false;\n }\n }\n\n Message(\"Correct!\");\n Message(\"All test cases passed.\");\n true\n }\n}"
|
|
2381
|
+
},
|
|
2382
|
+
{
|
|
2383
|
+
"id": "single_qubit_measurements__common.qs",
|
|
2384
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Random;\n\n // \"Framework\" operation for testing single-qubit tasks for distinguishing states of one qubit\n // with Bool return\n operation DistinguishTwoStates(\n statePrep: ((Qubit, Int) => Unit is Adj),\n testImpl : (Qubit => Bool),\n stateName : String[],\n checkFinalState : Bool) : Bool {\n\n let nTotal = 100;\n let nStates = 2;\n mutable misclassifications = Repeated(0, nStates);\n \n use q = Qubit();\n for i in 1 .. nTotal {\n // get a random bit to define whether qubit will be in a state corresponding to true return (1) or to false one (0)\n // state = 0 false return\n // state = 1 true return\n let state = DrawRandomInt(0, 1);\n\n // do state prep: convert |0⟩ to outcome with false return or to outcome with true return depending on state\n statePrep(q, state);\n\n // get the solution's answer and verify if NOT a match, then differentiate what kind of mismatch\n let ans = testImpl(q);\n if ans != (state == 1) {\n set misclassifications w/= state <- misclassifications[state] + 1;\n }\n \n // If the final state is to be verified, check if it matches the measurement outcome\n if checkFinalState {\n Adjoint statePrep(q, state);\n Fact(CheckZero(q), \"Returned Bool value does not match the expected qubit state.\");\n } else {\n Reset(q);\n }\n }\n \n mutable totalMisclassifications = 0;\n for i in 0 .. nStates - 1 {\n if misclassifications[i] != 0 {\n set totalMisclassifications += misclassifications[i];\n Message($\"Misclassified {stateName[i]} as {stateName[1 - i]} in {misclassifications[i]} test runs.\"); \n }\n }\n \n return totalMisclassifications == 0;\n }\n\n}\n"
|
|
2385
|
+
},
|
|
2386
|
+
{
|
|
2387
|
+
"id": "single_qubit_measurements__distinguish_0_and_1__verification.qs",
|
|
2388
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Intrinsic;\n\n //Distinguish |0❭ and |1❭\n operation StatePrep_IsQubitZero (q : Qubit, state : Int) : Unit is Adj {\n if state == 0 {\n // convert |0⟩ to |1⟩\n X(q);\n }\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = DistinguishTwoStates(\n StatePrep_IsQubitZero,\n Kata.IsQubitZero,\n [\"|1⟩\", \"|0⟩\"],\n false);\n if isCorrect {\n Message(\"All tests passed.\");\n }\n isCorrect\n }\n\n}\n"
|
|
2389
|
+
},
|
|
2390
|
+
{
|
|
2391
|
+
"id": "single_qubit_measurements__distinguish_plus_and_minus__verification.qs",
|
|
2392
|
+
"code": "namespace Kata.Verification {\n\n // Distinguish |+❭ and |-❭ using Measure operation\n operation StatePrep_IsQubitMinus (q : Qubit, state : Int) : Unit is Adj {\n if state == 1 {\n // convert |0⟩ to |-⟩\n X(q);\n H(q);\n } else {\n // convert |0⟩ to |+⟩\n H(q);\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n let isCorrect = DistinguishTwoStates(\n StatePrep_IsQubitMinus,\n Kata.IsQubitMinus,\n [\"|+⟩\", \"|-⟩\"],\n false);\n if isCorrect {\n Message(\"All tests passed.\");\n }\n isCorrect\n }\n\n}\n"
|
|
2393
|
+
},
|
|
2394
|
+
{
|
|
2395
|
+
"id": "single_qubit_measurements__distinguish_orthogonal_states_1__verification.qs",
|
|
2396
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Math;\n\n // Distinguish specific orthogonal states\n // |ψ₊⟩ = 0.6 * |0⟩ + 0.8 * |1⟩,\n // |ψ₋⟩ = -0.8 * |0⟩ + 0.6 * |1⟩.\n operation StatePrep_IsQubitPsiPlus(q: Qubit, state: Int): Unit is Adj {\n if state == 0 {\n // convert |0⟩ to |ψ₋⟩\n X(q);\n Ry(2.0 * ArcTan2(0.8, 0.6), q);\n } else {\n // convert |0⟩ to |ψ₊⟩\n Ry(2.0 * ArcTan2(0.8, 0.6), q);\n }\n }\n\n operation CheckSolution(): Bool {\n let isCorrect = DistinguishTwoStates(\n StatePrep_IsQubitPsiPlus,\n Kata.IsQubitPsiPlus, \n [\"|ψ₋⟩\", \"|ψ₊⟩\"],\n false);\n if isCorrect {\n Message(\"All tests passed.\");\n }\n isCorrect\n }\n\n}\n"
|
|
2397
|
+
},
|
|
2398
|
+
{
|
|
2399
|
+
"id": "single_qubit_measurements__distinguish_orthogonal_states_2__verification.qs",
|
|
2400
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n\n // Distinguish states |A❭ and |B❭\n // |A⟩ = cos(alpha) * |0⟩ - i sin(alpha) * |1⟩,\n // |B⟩ = - i sin(alpha) * |0⟩ + cos(alpha) * |1⟩.\n operation StatePrep_IsQubitA(alpha: Double, q: Qubit, state: Int): Unit is Adj {\n if state == 0 {\n // convert |0⟩ to |B⟩\n X(q);\n Rx(2.0 * alpha, q);\n } else {\n // convert |0⟩ to |A⟩\n Rx(2.0 * alpha, q);\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n for i in 0 .. 10 {\n let alpha = (PI() * IntAsDouble(i)) / 10.0;\n let isCorrect = DistinguishTwoStates(\n StatePrep_IsQubitA(alpha, _, _),\n Kata.IsQubitA(alpha, _), \n [$\"|B⟩ = -i sin({i}π/10)|0⟩ + cos({i}π/10)|1⟩\", $\"|A⟩ = cos({i}π/10)|0⟩ + i sin({i}π/10)|1⟩\"],\n false);\n if not isCorrect {\n return false;\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2401
|
+
},
|
|
2402
|
+
{
|
|
2403
|
+
"id": "single_qubit_measurements__a_b_basis_measurements__verification.qs",
|
|
2404
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n\n // Measure state in {|A❭, |B❭} basis\n // |A⟩ = cos(alpha) * |0⟩ - i sin(alpha) * |1⟩,\n // |B⟩ = - i sin(alpha) * |0⟩ + cos(alpha) * |1⟩.\n\n operation StatePrep_IsQubitA (alpha : Double, q : Qubit, state : Int) : Unit is Adj {\n if state == 0 {\n // convert |0⟩ to |B⟩\n X(q);\n Rx(2.0 * alpha, q);\n } else {\n // convert |0⟩ to |A⟩\n Rx(2.0 * alpha, q);\n }\n }\n\n // We can use the StatePrep_IsQubitA operation for the testing\n operation CheckSolution(): Bool {\n for i in 0 .. 10 {\n let alpha = (PI() * IntAsDouble(i)) / 10.0;\n let isCorrect = DistinguishTwoStates(\n StatePrep_IsQubitA(alpha, _, _), \n q => Kata.MeasureInABBasis(alpha, q) == Zero, \n [$\"|B⟩=(-i sin({i}π/10)|0⟩ + cos({i}π/10)|1⟩)\", $\"|A⟩=(cos({i}π/10)|0⟩ + i sin({i}π/10)|1⟩)\"],\n true);\n if not isCorrect {\n Message($\"Test failes for alpha={alpha}\");\n return false;\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2405
|
+
},
|
|
2406
|
+
{
|
|
2407
|
+
"id": "multi_qubit_measurements__full_measurements__verify.qs",
|
|
2408
|
+
"code": "namespace Kata.Verification {\n\n // Distinguish four basis states\n operation StatePrep_BasisStateMeasurement(qs : Qubit[], state : Int, dummyVar : Double) : Unit is Adj {\n if state / 2 == 1 {\n // |10⟩ or |11⟩\n X(qs[0]);\n }\n if state % 2 == 1 {\n // |01⟩ or |11⟩\n X(qs[1]);\n }\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = DistinguishStates_MultiQubit(\n 2,\n 4,\n StatePrep_BasisStateMeasurement,\n Kata.BasisStateMeasurement,\n false,\n [\"|00⟩\", \"|01⟩\", \"|10⟩\", \"|11⟩\"]);\n\n if (isCorrect) {\n Message(\"Correct!\");\n Message(\"All test cases passed.\");\n } else {\n Message(\"Incorrect!\");\n }\n\n isCorrect\n }\n}\n"
|
|
2409
|
+
},
|
|
2410
|
+
{
|
|
2411
|
+
"id": "multi_qubit_measurements__common.qs",
|
|
2412
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Canon;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Measurement;\n open Microsoft.Quantum.Random;\n\n // \"Framework\" operation for testing multi-qubit tasks for distinguishing states of an array of qubits\n // with Int return\n operation DistinguishStates_MultiQubit(\n nQubits: Int,\n nStates: Int,\n statePrep: ((Qubit[], Int, Double) => Unit is Adj),\n testImpl: (Qubit[] => Int),\n preserveState: Bool,\n stateNames: String[]): Bool {\n\n let nTotal = 100;\n // misclassifications will store the number of times state i has been classified as state j (dimension nStates^2)\n mutable misclassifications = [0, size = nStates * nStates];\n // unknownClassifications will store the number of times state i has been classified as some invalid state (index < 0 or >= nStates)\n mutable unknownClassifications = [0, size = nStates];\n \n use qs = Qubit[nQubits];\n for i in 1 .. nTotal {\n // get a random integer to define the state of the qubits\n let state = DrawRandomInt(0, nStates - 1);\n // get a random rotation angle to define the exact state of the qubits\n // for some exercises, this value might be a dummy variable which does not matter\n let alpha = DrawRandomDouble(0.0, 1.0) * PI();\n \n // do state prep: convert |0...0⟩ to outcome with return equal to state\n statePrep(qs, state, alpha);\n\n // get the solution's answer and verify that it's a match, if not, increase the exact mismatch count\n let ans = testImpl(qs);\n if ((ans >= 0) and (ans < nStates)) {\n // classification result is a valid state index - check if is it correct\n if ans != state {\n set misclassifications w/= ((state * nStates) + ans) <- (misclassifications[(state * nStates) + ans] + 1);\n }\n }\n else {\n // classification result is an invalid state index - file it separately\n set unknownClassifications w/= state <- (unknownClassifications[state] + 1); \n }\n\n if preserveState {\n // check that the state of the qubit after the operation is unchanged\n Adjoint statePrep(qs, state, alpha);\n if not CheckAllZero(qs) {\n Message(\"Test should preseve qubit state.\");\n ResetAll(qs);\n return false;\n }\n } else {\n // we're not checking the state of the qubit after the operation\n ResetAll(qs);\n }\n }\n ResetAll(qs);\n\n mutable totalMisclassifications = 0;\n for i in 0 .. nStates - 1 {\n for j in 0 .. nStates - 1 {\n if misclassifications[(i * nStates) + j] != 0 {\n set totalMisclassifications += misclassifications[i * nStates + j];\n Message($\"Misclassified {stateNames[i]} as {stateNames[j]} in {misclassifications[(i * nStates) + j]} test runs.\");\n }\n }\n if unknownClassifications[i] != 0 {\n set totalMisclassifications += unknownClassifications[i];\n Message($\"Misclassified {stateNames[i]} as Unknown State in {unknownClassifications[i]} test runs.\");\n }\n }\n totalMisclassifications == 0\n }\n}\n"
|
|
2413
|
+
},
|
|
2414
|
+
{
|
|
2415
|
+
"id": "multi_qubit_measurements__partial_measurements_for_system__verify.qs",
|
|
2416
|
+
"code": "namespace Kata.Verification {\n\n // Distinguish orthogonal states using partial measurements\n operation StatePrep_IsPlusPlusMinus(qs: Qubit[], state: Int, dummyVar: Double): Unit is Adj {\n if state == 0 {\n // prepare the state |++-⟩\n H(qs[0]);\n H(qs[1]);\n X(qs[2]);\n H(qs[2]);\n } else {\n // prepare the state |---⟩\n X(qs[0]);\n H(qs[0]);\n X(qs[1]);\n H(qs[1]);\n X(qs[2]);\n H(qs[2]);\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n return DistinguishStates_MultiQubit(\n 3,\n 2,\n StatePrep_IsPlusPlusMinus,\n Kata.IsPlusPlusMinus,\n false,\n [\"|++-⟩\", \"|---⟩\"]);\n }\n\n}\n"
|
|
2417
|
+
},
|
|
2418
|
+
{
|
|
2419
|
+
"id": "multi_qubit_measurements__state_modification__verify.qs",
|
|
2420
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n\n // State selection using partial measurements\n operation stateInitialize_StateSelction(alpha: Double, qs: Qubit[]): Unit {\n // Prepare the state to be input to the testImplementation\n // set the second qubit in a superposition a |0⟩ + b|1⟩\n // with a = cos alpha, b = sin alpha\n Ry(2.0 * alpha, qs[1]); \n\n H(qs[0]);\n // Apply CX gate\n CX(qs[0], qs[1]);\n }\n\n operation statePrepare_StateSelction(alpha: Double, Choice: Int, qs: Qubit[]): Unit is Adj {\n // The expected state of the second qubit for the exercise.\n\n // set the second qubit in a superposition a |0⟩ + b|1⟩\n // with a = cos alpha, b = sin alpha\n Ry(2.0 * alpha, qs[1]); \n if Choice == 1 { \n // if the Choice is 1, change the state to b|0⟩ + a|1⟩\n X(qs[1]);\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n use qs = Qubit[2];\n for i in 0 .. 5 {\n let alpha = (PI() * IntAsDouble(i)) / 5.0;\n\n //for Choice = 0 and 1,\n for Choice in 0 .. 1 {\n // Prepare the state to be input to the testImplementation\n stateInitialize_StateSelction(alpha, qs);\n\n // operate testImplementation\n Kata.StateSelction(qs, Choice);\n // reset the first qubit, since its state does not matter\n Reset(qs[0]);\n\n // apply adjoint reference operation and check that the result is correct\n Adjoint statePrepare_StateSelction(alpha, Choice, qs);\n \n if not CheckAllZero(qs) {\n ResetAll(qs);\n return false;\n }\n ResetAll(qs);\n }\n }\n ResetAll(qs);\n true\n }\n\n}\n"
|
|
2421
|
+
},
|
|
2422
|
+
{
|
|
2423
|
+
"id": "multi_qubit_measurements__state_preparation__verify.qs",
|
|
2424
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n\n // State preparation using partial measurements\n operation RefImpl_T4(qs: Qubit[]): Unit is Adj {\n // Rotate first qubit to (sqrt(2) |0⟩ + |1⟩) / sqrt(3)\n let theta = ArcSin(1.0 / Sqrt(3.0));\n Ry(2.0 * theta, qs[0]);\n\n // Split the state sqrt(2) |0⟩ ⊗ |0⟩ into |00⟩ + |01⟩\n ApplyControlledOnInt(0, H, [qs[0]], qs[1]);\n }\n\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n use qs = Qubit[2];\n\n // operate the test implementation\n Kata.PostSelection(qs);\n\n // apply adjoint reference operation and check that the result is |0⟩\n Adjoint RefImpl_T4(qs);\n let isCorrect = CheckAllZero(qs);\n ResetAll(qs);\n isCorrect\n }\n\n}\n"
|
|
2425
|
+
},
|
|
2426
|
+
{
|
|
2427
|
+
"id": "multi_qubit_measurements__joint_measurements__verify.qs",
|
|
2428
|
+
"code": "namespace Kata.Verification {\n\n // Two qubit parity Measurement\n operation StatePrep_ParityMeasurement(qs: Qubit[], state: Int, alpha: Double): Unit is Adj {\n // prep cos(alpha) * |0..0⟩ + sin(alpha) * |1..1⟩\n Ry(2.0 * alpha, qs[0]);\n for i in 1 .. Length(qs) - 1 {\n CNOT(qs[0], qs[i]);\n }\n \n if state == 1 {\n // flip the state of the first half of the qubits\n for i in 0 .. Length(qs) / 2 - 1 {\n X(qs[i]);\n }\n }\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n return DistinguishStates_MultiQubit(\n 2,\n 2,\n StatePrep_ParityMeasurement,\n Kata.ParityMeasurement,\n true,\n [\"α|00⟩ + β|11⟩\", \"α|01⟩ + β|10⟩\"]);\n }\n}\n"
|
|
2429
|
+
},
|
|
2430
|
+
{
|
|
2431
|
+
"id": "random_numbers__random_bit__verification.qs",
|
|
2432
|
+
"code": "namespace Kata.Verification {\n @EntryPoint()\n operation CheckSolution() : Bool {\n Message(\"Testing one random bit generation...\");\n let randomnessVerifier = () => CheckUniformDistribution(Kata.RandomBit, 0, 1, 1000);\n let isCorrect = IsSufficientlyRandom(randomnessVerifier);\n if isCorrect {\n Message(\"All tests passed.\");\t\n\t }\n isCorrect\n }\n\n}\n"
|
|
2433
|
+
},
|
|
2434
|
+
{
|
|
2435
|
+
"id": "random_numbers__common.qs",
|
|
2436
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n\n /// # Summary\n /// Helper operation that checks that the given RNG operation generates a uniform distribution.\n ///\n /// # Input\n /// ## randomGenerator\n /// Random number generation operation to be tested.\n /// The parameters to this operation are provided by the caller using Delay().\n /// ## min, max\n /// Minimal and maximal numbers in the range to be generated, inclusive.\n /// ## nRuns\n /// The number of random numbers to generate for test.\n ///\n /// # Output\n /// 0x0 if the generated distribution is uniform.\n /// 0x1 if a value was generated outside the specified range.\n /// 0x2 if the average of the distribution is outside the expected range.\n /// 0x3 if the median of the distribution is outside the expected range.\n /// 0x4 if the minimum count requirements were not met.\n operation CheckUniformDistribution (\n randomGenerator : (Unit => Int),\n min : Int,\n max : Int,\n nRuns : Int) \n : Int {\n let idealMean = 0.5 * IntAsDouble(max + min);\n let rangeDividedByTwo = 0.5 * IntAsDouble(max - min);\n // Variance = a*(a+1)/3, where a = (max-min)/2\n // For sample population : divide it by nRuns\n let varianceInSamplePopulation = (rangeDividedByTwo * (rangeDividedByTwo + 1.0)) / IntAsDouble(3 * nRuns);\n let standardDeviation = Sqrt(varianceInSamplePopulation);\n\n // lowRange : The lower bound of the median and average for generated dataset\n // highRange : The upper bound of the median and average for generated dataset\n // Set them with 3 units of std deviation for 99% accuracy.\n let lowRange = idealMean - 3.0 * standardDeviation;\n let highRange = idealMean + 3.0 * standardDeviation;\n\n let idealCopiesGenerated = IntAsDouble(nRuns) / IntAsDouble(max-min+1);\n let minimumCopiesGenerated = (0.8 * idealCopiesGenerated > 40.0) ? 0.8 * idealCopiesGenerated | 0.0;\n\n mutable counts = [0, size = max + 1];\n mutable average = 0.0;\n for i in 1..nRuns {\n let val = randomGenerator();\n if (val < min or val > max) {\n Message($\"Unexpected number generated. Expected values from {min} to {max}, generated {val}\");\n return 0x1;\n }\n set average += IntAsDouble(val);\n set counts w/= val <- counts[val] + 1;\n }\n\n set average = average / IntAsDouble(nRuns);\n if (average < lowRange or average > highRange) {\n Message($\"Unexpected average of generated numbers. Expected between {lowRange} and {highRange}, got {average}\");\n return 0x2;\n }\n\n let median = FindMedian (counts, max+1, nRuns);\n if (median < Floor(lowRange) or median > Ceiling(highRange)) {\n Message($\"Unexpected median of generated numbers. Expected between {Floor(lowRange)} and {Ceiling(highRange)}, got {median}.\");\n return 0x3;\n }\n\n for i in min..max {\n if counts[i] < Floor(minimumCopiesGenerated) {\n Message($\"Unexpectedly low number of {i}'s generated. Only {counts[i]} out of {nRuns} were {i}\");\n return 0x4;\n }\n }\n return 0x0;\n }\n\n operation FindMedian (counts : Int[], arrSize : Int, sampleSize : Int) : Int {\n mutable totalCount = 0;\n for i in 0 .. arrSize - 1 {\n set totalCount = totalCount + counts[i];\n if totalCount >= sampleSize / 2 {\n return i;\n }\n }\n return -1;\n }\n\n operation IsSufficientlyRandom(verifier : (Unit => Int)) : Bool {\n let results = RunRandomnessVerifier(verifier, 10);\n Tail(results) == 0x0\n }\n\n /// # Summary\n /// Helper operation that runs a randomness verifier up to a maximum number of times.\n /// A single run can fail with non-negligible probability even for a \"correct\" random generator.\n ///\n /// # Input\n /// ## verifier\n /// Operation which verifies the a random generator.\n /// ## maxAttempts\n /// Maximum number of times the verifier is run until a successful result occurs.\n ///\n /// # Output\n /// Array with the results of each verifier run.\n operation RunRandomnessVerifier(verifier : (Unit => Int), maxAttempts : Int) : Int[] {\n mutable attemptResults = [];\n mutable result = -1;\n repeat {\n set result = verifier();\n set attemptResults += [result];\n } until (result == 0 or Length(attemptResults) >= maxAttempts);\n\n attemptResults\n }\n}\n"
|
|
2437
|
+
},
|
|
2438
|
+
{
|
|
2439
|
+
"id": "random_numbers__random_two_bits__verification.qs",
|
|
2440
|
+
"code": "namespace Kata.Verification {\n @EntryPoint()\n operation CheckSolution(): Bool {\n Message(\"Testing two random bits generation...\");\n let randomnessVerifier = () => CheckUniformDistribution(Kata.RandomTwoBits, 0, 3, 1000);\n let isCorrect = IsSufficientlyRandom(randomnessVerifier);\n if isCorrect {\n Message(\"All tests passed.\");\n }\n isCorrect\n }\n\n}\n"
|
|
2441
|
+
},
|
|
2442
|
+
{
|
|
2443
|
+
"id": "random_numbers__random_n_bits__verification.qs",
|
|
2444
|
+
"code": "namespace Kata.Verification {\n @EntryPoint()\n operation CheckSolution(): Bool {\n // Test random number generation for 1, 2, 3, 10 bits\n let testCases = [(1, 1000), (2, 1000), (3, 1000), (10, 10000)];\n for (N, runs) in testCases {\n Message($\"Testing N = {N}...\");\n let max = (1 <<< N) - 1;\n let randomnessVerifier = () => CheckUniformDistribution(() =>\n Kata.RandomNBits(N), 0, max, runs);\n let isCorrect = IsSufficientlyRandom(randomnessVerifier);\n if not isCorrect {\n return false;\n }\n Message($\"Test passed for N = {N}\");\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2445
|
+
},
|
|
2446
|
+
{
|
|
2447
|
+
"id": "random_numbers__weighted_random_bit__verification.qs",
|
|
2448
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Convert;\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n for x in [0.0, 0.25, 0.5, 0.75, 1.0] {\n Message($\"Testing generating zero with {x*100.0}% probability...\");\n let randomnessVerifier = () => CheckXPercentZero(() => Kata.WeightedRandomBit(x), x);\n let isCorrect = IsSufficientlyRandom(randomnessVerifier);\n if not isCorrect {\n return false;\n }\n Message($\"Test passed for generating zero with {x*100.0}% probability\");\n }\n Message(\"All tests passed.\");\n true\n }\n\n /// # Summary\n /// Helper operation that checks that the given RNG operation generates zero with x percent probability\n /// # Input\n /// ## op\n /// Random number generation operation to be tested.\n /// ## x\n /// Probability of generating zero\n operation CheckXPercentZero (op : (Unit => Int), x : Double) : Int {\n mutable oneCount = 0;\n let nRuns = 1000;\n for N in 1..nRuns {\n let val = op();\n if (val < 0 or val > 1) {\n Message($\"Unexpected number generated. Expected 0 or 1, instead generated {val}\");\n return 0x1;\n }\n set oneCount += val;\n }\n\n let zeroCount = nRuns - oneCount;\n let goalZeroCount = (x == 0.0) ? 0 | (x == 1.0) ? nRuns | Floor(x * IntAsDouble(nRuns));\n // We don't have tests with probabilities near 0.0 or 1.0, so for those the matching has to be exact\n if (goalZeroCount == 0 or goalZeroCount == nRuns) {\n if zeroCount != goalZeroCount {\n Message($\"Expected {x * 100.0}% 0's, instead got {zeroCount} 0's out of {nRuns}\");\n return 0x2;\n }\n } else {\n if zeroCount < goalZeroCount - 4 * nRuns / 100 {\n Message($\"Unexpectedly low number of 0's generated: expected around {x * IntAsDouble(nRuns)} 0's, got {zeroCount} out of {nRuns}\");\n return 0x3;\n } elif zeroCount > goalZeroCount + 4 * nRuns / 100 {\n Message($\"Unexpectedly high number of 0's generated: expected around {x * IntAsDouble(nRuns)} 0's, got {zeroCount} out of {nRuns}\");\n return 0x4;\n }\n }\n return 0x0;\n }\n\n}\n"
|
|
2449
|
+
},
|
|
2450
|
+
{
|
|
2451
|
+
"id": "random_numbers__random_number__verification.qs",
|
|
2452
|
+
"code": "namespace Kata.Verification {\n @EntryPoint()\n operation CheckSolution(): Bool {\n let testCases = [(1, 3, 1000), (27, 312, 5000), (0, 3, 1000), (0, 1023, 10000)];\n for (min, max, runs) in testCases {\n Message($\"Testing for min = {min} and max = {max}...\");\n let randomnessVerifier = () => CheckUniformDistribution(() =>\n Kata.RandomNumberInRange(min, max), min, max, runs);\n let isCorrect = IsSufficientlyRandom(randomnessVerifier);\n if not isCorrect {\n return false;\n }\n\n Message($\"Test passed for min = {min} and max = {max}\");\n }\n Message(\"All tests passed.\");\n true\n }\n}\n"
|
|
2453
|
+
},
|
|
2454
|
+
{
|
|
2455
|
+
"id": "oracles__common.qs",
|
|
2456
|
+
"code": "namespace Kata.Verification {\n\n open Microsoft.Quantum.Diagnostics;\n\n /// # Summary\n /// Given two registers, prepares the maximally entangled state \n /// between each pair of qubits on the respective registers.\n /// All qubits must start in the |0⟩ state.\n ///\n /// The result is that corresponding pairs of qubits from each register are in the\n /// $\\bra{\\beta_{00}}\\ket{\\beta_{00}}$.\n ///\n /// # Input\n /// ## left\n /// A qubit array in the $\\ket{0\\cdots 0}$ state\n /// ## right\n /// A qubit array in the $\\ket{0\\cdots 0}$ state\n internal operation PrepareEntangledState (left : Qubit[], right : Qubit[]) : Unit\n is Adj + Ctl {\n\n for idxQubit in 0 .. Length(left) - 1\n {\n H(left[idxQubit]);\n Controlled X([left[idxQubit]], right[idxQubit]);\n }\n }\n \n // TODO: Maybe move this to Katas library (or reuse if there's a similar one)\n \n /// # Summary\n /// Given two operations, asserts that they act identically for all input states.\n ///\n /// This assertion is implemented by using the Choi–Jamiołkowski isomorphism to reduce\n /// the assertion to one of a qubit state assertion on two entangled registers.\n /// Thus, this operation needs only a single call to each operation being tested,\n /// but requires twice as many qubits to be allocated.\n /// This assertion can be used to ensure, for instance, that an optimized version of an\n /// operation acts identically to its naïve implementation, or that an operation\n /// which acts on a range of non-quantum inputs agrees with known cases.\n ///\n /// # Remarks\n /// This operation requires that the operation modeling the expected behavior is\n /// adjointable, so that the inverse can be performed on the target register alone.\n /// Formally, one can specify a transpose operation, which relaxes this requirement,\n /// but the transpose operation is not in general physically realizable for arbitrary\n /// quantum operations and thus is not included here as an option.\n ///\n /// # Input\n /// ## nQubits\n /// Number of qubits to pass to each operation.\n /// ## actual\n /// Operation to be tested.\n /// ## expected\n /// Operation defining the expected behavior for the operation under test.\n operation CheckOperationsEqualReferenced (nQubits : Int, actual : (Qubit[] => Unit), expected : (Qubit[] => Unit is Adj)) : Bool {\n // Prepare a reference register entangled with the target register.\n use (reference, target) = (Qubit[nQubits], Qubit[nQubits]) {\n PrepareEntangledState(reference, target);\n actual(target);\n Adjoint expected(target);\n Adjoint PrepareEntangledState(reference, target);\n let isCorrect = CheckAllZero(reference + target);\n ResetAll(target);\n ResetAll(reference);\n isCorrect\n }\n }\n\n // ------------------------------------------------------\n // Helper functions\n operation ApplyOracle (qs : Qubit[], oracle : ((Qubit[], Qubit) => Unit is Adj + Ctl)) : Unit is Adj + Ctl {\n let N = Length(qs);\n oracle(qs[0 .. N - 2], qs[N - 1]);\n }\n\n operation CheckTwoOraclesAreEqual (nQubits : Range,\n oracle1 : ((Qubit[], Qubit) => Unit is Adj + Ctl),\n oracle2 : ((Qubit[], Qubit) => Unit is Adj + Ctl)) : Bool {\n let sol = ApplyOracle(_, oracle1);\n let refSol = ApplyOracle(_, oracle2);\n\n for i in nQubits {\n if not CheckOperationsEqualReferenced(i + 1, sol, refSol) {\n return false;\n }\n }\n true\n }\n\n}\n"
|
|
2457
|
+
},
|
|
2458
|
+
{
|
|
2459
|
+
"id": "oracles__classical_oracles__verification.qs",
|
|
2460
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n\n function IsSeven_Reference(x: Bool[]): Bool {\n return BoolArrayAsInt(x) == 7;\n }\n\n @EntryPoint()\n function CheckSolution(): Bool {\n let N = 3;\n for k in 0..((2^N)-1) {\n let x = IntAsBoolArray(k, N);\n\n let actual = Kata.IsSeven(x);\n let expected = IsSeven_Reference(x);\n\n if actual != expected {\n Message($\"Failed on test case x = {x}: got {actual}, expected {expected}\");\n return false;\n }\n }\n Message(\"All tests passed.\");\n true\n }\n}\n"
|
|
2461
|
+
},
|
|
2462
|
+
{
|
|
2463
|
+
"id": "oracles__phase_oracle_seven__verification.qs",
|
|
2464
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Arrays;\n\n operation IsSeven_PhaseOracle_Reference(x : Qubit[]) : Unit is Adj + Ctl {\n Controlled Z(Most(x), Tail(x));\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n let N = 3;\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n Kata.IsSeven_PhaseOracle,\n IsSeven_PhaseOracle_Reference);\n if isCorrect {\n Message(\"All tests passed.\");\n } else {\n Message(\"Test failed: Operation is not the same as the reference operation.\");\n }\n isCorrect\n }\n}\n"
|
|
2465
|
+
},
|
|
2466
|
+
{
|
|
2467
|
+
"id": "oracles__marking_oracle_seven__verification.qs",
|
|
2468
|
+
"code": "namespace Kata.Verification {\n\n operation IsSeven_MarkingOracle_Reference(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n Controlled X(x, y);\n }\n\n // ------------------------------------------------------\n @EntryPoint()\n operation CheckSolution () : Bool {\n let isCorrect = CheckTwoOraclesAreEqual(\n 3..3,\n Kata.IsSeven_MarkingOracle,\n IsSeven_MarkingOracle_Reference);\n if isCorrect {\n Message(\"All tests passed.\");\n } else {\n Message(\"Test failed: Operation is not the same as the reference operation.\");\n }\n isCorrect\n }\n\n}\n"
|
|
2469
|
+
},
|
|
2470
|
+
{
|
|
2471
|
+
"id": "oracles__marking_oracle_as_phase__verification.qs",
|
|
2472
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n\n operation ApplyMarkingOracleAsPhaseOracle_Reference(\n markingOracle: ((Qubit[], Qubit) => Unit is Adj + Ctl),\n qubits: Qubit[]) : Unit is Adj + Ctl {\n \n use minus = Qubit();\n within {\n X(minus);\n H(minus);\n } apply {\n markingOracle(qubits, minus);\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n for N in 1..5 {\n for k in 0..(2^N-1) {\n let pattern = IntAsBoolArray(k, N);\n\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n qubits => Kata.ApplyMarkingOracleAsPhaseOracle(\n ApplyControlledOnBitString(pattern, X, _, _),\n qubits),\n qubits => ApplyMarkingOracleAsPhaseOracle_Reference(\n ApplyControlledOnBitString(pattern, X, _, _),\n qubits));\n if not isCorrect {\n Message($\"Failed on test pattern {pattern} for a bit pattern oracle.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2473
|
+
},
|
|
2474
|
+
{
|
|
2475
|
+
"id": "oracles__or_oracle__verification.qs",
|
|
2476
|
+
"code": "namespace Kata.Verification {\n operation Or_Oracle_Reference(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = CheckTwoOraclesAreEqual(1..7, Kata.Or_Oracle, Or_Oracle_Reference);\n if (isCorrect) {\n Message(\"All tests passed.\");\n } else {\n Message(\"Test failed: Operation is not the same as the reference operation.\");\n }\n isCorrect\n }\n}\n"
|
|
2477
|
+
},
|
|
2478
|
+
{
|
|
2479
|
+
"id": "oracles__kth_bit_oracle__verification.qs",
|
|
2480
|
+
"code": "namespace Kata.Verification {\n operation KthBit_Oracle_Reference(x: Qubit[], k: Int): Unit is Adj + Ctl {\n Z(x[k]);\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n for N in 1..5 {\n for k in 0..(N-1) {\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n Kata.KthBit_Oracle(_, k),\n KthBit_Oracle_Reference(_, k));\n if not isCorrect {\n Message($\"Failed on test case for NumberOfQubits = {N}, k = {k}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2481
|
+
},
|
|
2482
|
+
{
|
|
2483
|
+
"id": "oracles__or_but_kth_oracle__verification.qs",
|
|
2484
|
+
"code": "namespace Kata.Verification {\n\n operation Or_Oracle_Reference(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation OrOfBitsExceptKth_Oracle_Reference(x: Qubit[], k: Int): Unit is Adj + Ctl {\n use minus = Qubit();\n within {\n X(minus);\n H(minus);\n } apply {\n Or_Oracle_Reference(x[...k-1] + x[k+1...], minus);\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n for N in 1..5 {\n for k in 0..(N-1) {\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n Kata.OrOfBitsExceptKth_Oracle(_, k),\n OrOfBitsExceptKth_Oracle_Reference(_, k));\n if not isCorrect {\n Message($\"Failed on test case for NumberOfQubits = {N}, k = {k}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2485
|
+
},
|
|
2486
|
+
{
|
|
2487
|
+
"id": "oracles__bit_pattern_oracle__verification.qs",
|
|
2488
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n\n operation ArbitraryBitPattern_Oracle_Reference(x: Qubit[], y: Qubit, pattern: Bool[]): Unit is Adj + Ctl {\n ApplyControlledOnBitString(pattern, X, x, y);\n }\n\n // ------------------------------------------------------\n @EntryPoint()\n operation CheckSolution(): Bool {\n for N in 1..4 {\n for k in 0..((2^N)-1) {\n let pattern = IntAsBoolArray(k, N);\n\n let isCorrect = CheckTwoOraclesAreEqual(\n N..N,\n Kata.ArbitraryBitPattern_Oracle(_, _, pattern),\n ArbitraryBitPattern_Oracle_Reference(_, _, pattern));\n if not isCorrect {\n Message($\"Failed on pattern {pattern}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2489
|
+
},
|
|
2490
|
+
{
|
|
2491
|
+
"id": "oracles__bit_pattern_challenge__verification.qs",
|
|
2492
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Arrays;\n\n operation ArbitraryBitPattern_Oracle_Challenge_Reference(x: Qubit[], pattern: Bool[]): Unit is Adj + Ctl {\n within {\n for i in IndexRange(x) {\n if not pattern[i] {\n X(x[i]);\n }\n }\n } apply {\n Controlled Z(Most(x), Tail(x));\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n for N in 1..4 {\n for k in 0..((2^N)-1) {\n let pattern = IntAsBoolArray(k, N);\n\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n Kata.ArbitraryBitPattern_Oracle_Challenge(_, pattern),\n ArbitraryBitPattern_Oracle_Challenge_Reference(_, pattern));\n if not isCorrect {\n Message($\"Failed on pattern {pattern}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2493
|
+
},
|
|
2494
|
+
{
|
|
2495
|
+
"id": "oracles__meeting_oracle__verification.qs",
|
|
2496
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Convert;\n\n operation Or_Oracle_Reference(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation Meeting_Oracle_Reference(x: Qubit[], jasmine: Qubit[], z: Qubit): Unit is Adj + Ctl {\n use q = Qubit[Length(x)];\n within {\n for i in IndexRange(q) {\n // flip q[i] if both x and jasmine are free on the given day\n X(x[i]);\n X(jasmine[i]);\n CCNOT(x[i], jasmine[i], q[i]);\n }\n } apply {\n Or_Oracle_Reference(q, z);\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n for N in 1..4 {\n use jasmine = Qubit[N];\n for k in 0..(2^N-1) {\n let binaryJasmine = IntAsBoolArray(k, N);\n mutable isCorrect = false;\n within {\n ApplyPauliFromBitString(PauliX, true, binaryJasmine, jasmine);\n } apply {\n set isCorrect = CheckTwoOraclesAreEqual(\n 1..N,\n Kata.Meeting_Oracle(_, jasmine, _),\n Meeting_Oracle_Reference(_, jasmine, _));\n }\n if not isCorrect {\n Message($\"Failed on test case for N = {N}, k = {k}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2497
|
+
}
|
|
2498
|
+
]
|
|
2499
|
+
};
|