From 3d31bb3a7662d3a3552a7ce84a712e01549a2f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Zaragoza=20Cort=C3=A9s?= Date: Tue, 20 Feb 2024 11:55:18 -0800 Subject: [PATCH] Simplify `@[exercise]` macro used in katas (#1174) This change simplifies the `@[exercise]` macro by removing required properties and using fixed names for files that are always needed (e.g. index.md, solution.md, Placeholder.qs, Verification.qs). The core change is in npm/generate_katas_content.js. The rest is updating the katas markdown filesto use the simplified macro version. --------- Co-authored-by: Mariia Mykhailova --- katas/content/getting_started/index.md | 11 +- katas/content/multi_qubit_gates/index.md | 98 +++++------ .../{common.qs => Common.qs} | 0 .../{measuring_one.qs => MeasuringOne.qs} | 0 ...bilities.qs => MultiQubitProbabilities.qs} | 0 ...nts_demo.qs => PartialMeasurementsDemo.qs} | 0 .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{solution_alt.qs => SolutionAlt.qs} | 0 .../{verify.qs => Verification.qs} | 0 .../full_measurements/solution.md | 11 +- .../content/multi_qubit_measurements/index.md | 105 ++++++----- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verify.qs => Verification.qs} | 0 .../joint_measurements/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verify.qs => Verification.qs} | 0 .../solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verify.qs => Verification.qs} | 0 .../state_modification/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verify.qs => Verification.qs} | 0 .../state_preparation/solution.md | 17 +- katas/content/multi_qubit_systems/index.md | 59 +++---- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../learn_basis_state_amplitudes/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../prepare_basis_state/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../prepare_superposition/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../prepare_with_complex/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../prepare_with_real/solution.md | 2 +- .../content/oracles/{common.qs => Common.qs} | 0 ...acle_alt_bit.qs => MarkingOracleAltBit.qs} | 0 ...nverter_demo.qs => OracleConverterDemo.qs} | 0 ...oracle_alt_bit.qs => PhaseOracleAltBit.qs} | 0 ...meeting_oracle.qs => TestMeetingOracle.qs} | 0 .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../oracles/bit_pattern_challenge/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../oracles/bit_pattern_oracle/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../oracles/classical_oracles/solution.md | 2 +- katas/content/oracles/index.md | 163 ++++++++---------- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../oracles/kth_bit_oracle/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../marking_oracle_as_phase/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../oracles/marking_oracle_seven/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../oracles/meeting_oracle/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../oracles/or_but_kth_oracle/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../or_oracle/{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 katas/content/oracles/or_oracle/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../oracles/phase_oracle_seven/solution.md | 2 +- katas/content/qubit/index.md | 30 ++-- .../random_numbers/{common.qs => Common.qs} | 0 katas/content/random_numbers/index.md | 58 +++---- .../{placeholder.qs => Placeholder.qs} | 0 .../random_bit/{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../random_numbers/random_bit/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../random_numbers/random_n_bits/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../random_numbers/random_number/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../random_two_bits/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../weighted_random_bit/solution.md | 2 +- katas/content/single_qubit_gates/index.md | 116 ++++++------- .../{common.qs => Common.qs} | 0 .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../a_b_basis_measurements/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../distinguish_0_and_1/solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../solution.md | 2 +- .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../distinguish_plus_and_minus/solution.md | 2 +- .../{example.qs => Example.qs} | 0 .../single_qubit_measurements/index.md | 59 +++---- .../{example.qs => Example.qs} | 0 .../{common.qs => Common.qs} | 0 .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../{placeholder.qs => Placeholder.qs} | 0 .../{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 katas/content/superposition_kata/index.md | 47 ++--- .../{placeholder.qs => Placeholder.qs} | 0 .../minus_state/{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 .../{placeholder.qs => Placeholder.qs} | 0 .../plus_state/{solution.qs => Solution.qs} | 0 .../{verification.qs => Verification.qs} | 0 npm/generate_katas_content.js | 36 ++-- 158 files changed, 375 insertions(+), 491 deletions(-) rename katas/content/multi_qubit_measurements/{common.qs => Common.qs} (100%) rename katas/content/multi_qubit_measurements/{measuring_one.qs => MeasuringOne.qs} (100%) rename katas/content/multi_qubit_measurements/{multi_qubit_probabilities.qs => MultiQubitProbabilities.qs} (100%) rename katas/content/multi_qubit_measurements/{partial_measurements_demo.qs => PartialMeasurementsDemo.qs} (100%) rename katas/content/multi_qubit_measurements/full_measurements/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/multi_qubit_measurements/full_measurements/{solution.qs => Solution.qs} (100%) rename katas/content/multi_qubit_measurements/full_measurements/{solution_alt.qs => SolutionAlt.qs} (100%) rename katas/content/multi_qubit_measurements/full_measurements/{verify.qs => Verification.qs} (100%) rename katas/content/multi_qubit_measurements/joint_measurements/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/multi_qubit_measurements/joint_measurements/{solution.qs => Solution.qs} (100%) rename katas/content/multi_qubit_measurements/joint_measurements/{verify.qs => Verification.qs} (100%) rename katas/content/multi_qubit_measurements/partial_measurements_for_system/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/multi_qubit_measurements/partial_measurements_for_system/{solution.qs => Solution.qs} (100%) rename katas/content/multi_qubit_measurements/partial_measurements_for_system/{verify.qs => Verification.qs} (100%) rename katas/content/multi_qubit_measurements/state_modification/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/multi_qubit_measurements/state_modification/{solution.qs => Solution.qs} (100%) rename katas/content/multi_qubit_measurements/state_modification/{verify.qs => Verification.qs} (100%) rename katas/content/multi_qubit_measurements/state_preparation/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/multi_qubit_measurements/state_preparation/{solution.qs => Solution.qs} (100%) rename katas/content/multi_qubit_measurements/state_preparation/{verify.qs => Verification.qs} (100%) rename katas/content/multi_qubit_systems/learn_basis_state_amplitudes/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/multi_qubit_systems/learn_basis_state_amplitudes/{solution.qs => Solution.qs} (100%) rename katas/content/multi_qubit_systems/learn_basis_state_amplitudes/{verification.qs => Verification.qs} (100%) rename katas/content/multi_qubit_systems/prepare_basis_state/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/multi_qubit_systems/prepare_basis_state/{solution.qs => Solution.qs} (100%) rename katas/content/multi_qubit_systems/prepare_basis_state/{verification.qs => Verification.qs} (100%) rename katas/content/multi_qubit_systems/prepare_superposition/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/multi_qubit_systems/prepare_superposition/{solution.qs => Solution.qs} (100%) rename katas/content/multi_qubit_systems/prepare_superposition/{verification.qs => Verification.qs} (100%) rename katas/content/multi_qubit_systems/prepare_with_complex/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/multi_qubit_systems/prepare_with_complex/{solution.qs => Solution.qs} (100%) rename katas/content/multi_qubit_systems/prepare_with_complex/{verification.qs => Verification.qs} (100%) rename katas/content/multi_qubit_systems/prepare_with_real/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/multi_qubit_systems/prepare_with_real/{solution.qs => Solution.qs} (100%) rename katas/content/multi_qubit_systems/prepare_with_real/{verification.qs => Verification.qs} (100%) rename katas/content/oracles/{common.qs => Common.qs} (100%) rename katas/content/oracles/{marking_oracle_alt_bit.qs => MarkingOracleAltBit.qs} (100%) rename katas/content/oracles/{oracle_converter_demo.qs => OracleConverterDemo.qs} (100%) rename katas/content/oracles/{phase_oracle_alt_bit.qs => PhaseOracleAltBit.qs} (100%) rename katas/content/oracles/{test_meeting_oracle.qs => TestMeetingOracle.qs} (100%) rename katas/content/oracles/bit_pattern_challenge/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/oracles/bit_pattern_challenge/{solution.qs => Solution.qs} (100%) rename katas/content/oracles/bit_pattern_challenge/{verification.qs => Verification.qs} (100%) rename katas/content/oracles/bit_pattern_oracle/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/oracles/bit_pattern_oracle/{solution.qs => Solution.qs} (100%) rename katas/content/oracles/bit_pattern_oracle/{verification.qs => Verification.qs} (100%) rename katas/content/oracles/classical_oracles/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/oracles/classical_oracles/{solution.qs => Solution.qs} (100%) rename katas/content/oracles/classical_oracles/{verification.qs => Verification.qs} (100%) rename katas/content/oracles/kth_bit_oracle/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/oracles/kth_bit_oracle/{solution.qs => Solution.qs} (100%) rename katas/content/oracles/kth_bit_oracle/{verification.qs => Verification.qs} (100%) rename katas/content/oracles/marking_oracle_as_phase/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/oracles/marking_oracle_as_phase/{solution.qs => Solution.qs} (100%) rename katas/content/oracles/marking_oracle_as_phase/{verification.qs => Verification.qs} (100%) rename katas/content/oracles/marking_oracle_seven/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/oracles/marking_oracle_seven/{solution.qs => Solution.qs} (100%) rename katas/content/oracles/marking_oracle_seven/{verification.qs => Verification.qs} (100%) rename katas/content/oracles/meeting_oracle/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/oracles/meeting_oracle/{solution.qs => Solution.qs} (100%) rename katas/content/oracles/meeting_oracle/{verification.qs => Verification.qs} (100%) rename katas/content/oracles/or_but_kth_oracle/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/oracles/or_but_kth_oracle/{solution.qs => Solution.qs} (100%) rename katas/content/oracles/or_but_kth_oracle/{verification.qs => Verification.qs} (100%) rename katas/content/oracles/or_oracle/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/oracles/or_oracle/{solution.qs => Solution.qs} (100%) rename katas/content/oracles/or_oracle/{verification.qs => Verification.qs} (100%) rename katas/content/oracles/phase_oracle_seven/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/oracles/phase_oracle_seven/{solution.qs => Solution.qs} (100%) rename katas/content/oracles/phase_oracle_seven/{verification.qs => Verification.qs} (100%) rename katas/content/random_numbers/{common.qs => Common.qs} (100%) rename katas/content/random_numbers/random_bit/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/random_numbers/random_bit/{solution.qs => Solution.qs} (100%) rename katas/content/random_numbers/random_bit/{verification.qs => Verification.qs} (100%) rename katas/content/random_numbers/random_n_bits/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/random_numbers/random_n_bits/{solution.qs => Solution.qs} (100%) rename katas/content/random_numbers/random_n_bits/{verification.qs => Verification.qs} (100%) rename katas/content/random_numbers/random_number/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/random_numbers/random_number/{solution.qs => Solution.qs} (100%) rename katas/content/random_numbers/random_number/{verification.qs => Verification.qs} (100%) rename katas/content/random_numbers/random_two_bits/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/random_numbers/random_two_bits/{solution.qs => Solution.qs} (100%) rename katas/content/random_numbers/random_two_bits/{verification.qs => Verification.qs} (100%) rename katas/content/random_numbers/weighted_random_bit/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/random_numbers/weighted_random_bit/{solution.qs => Solution.qs} (100%) rename katas/content/random_numbers/weighted_random_bit/{verification.qs => Verification.qs} (100%) rename katas/content/single_qubit_measurements/{common.qs => Common.qs} (100%) rename katas/content/single_qubit_measurements/a_b_basis_measurements/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/single_qubit_measurements/a_b_basis_measurements/{solution.qs => Solution.qs} (100%) rename katas/content/single_qubit_measurements/a_b_basis_measurements/{verification.qs => Verification.qs} (100%) rename katas/content/single_qubit_measurements/distinguish_0_and_1/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/single_qubit_measurements/distinguish_0_and_1/{solution.qs => Solution.qs} (100%) rename katas/content/single_qubit_measurements/distinguish_0_and_1/{verification.qs => Verification.qs} (100%) rename katas/content/single_qubit_measurements/distinguish_orthogonal_states_1/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/single_qubit_measurements/distinguish_orthogonal_states_1/{solution.qs => Solution.qs} (100%) rename katas/content/single_qubit_measurements/distinguish_orthogonal_states_1/{verification.qs => Verification.qs} (100%) rename katas/content/single_qubit_measurements/distinguish_orthogonal_states_2/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/single_qubit_measurements/distinguish_orthogonal_states_2/{solution.qs => Solution.qs} (100%) rename katas/content/single_qubit_measurements/distinguish_orthogonal_states_2/{verification.qs => Verification.qs} (100%) rename katas/content/single_qubit_measurements/distinguish_plus_and_minus/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/single_qubit_measurements/distinguish_plus_and_minus/{solution.qs => Solution.qs} (100%) rename katas/content/single_qubit_measurements/distinguish_plus_and_minus/{verification.qs => Verification.qs} (100%) rename katas/content/single_qubit_measurements/implementing_measurement/{example.qs => Example.qs} (100%) rename katas/content/single_qubit_measurements/measurement_statistics/{example.qs => Example.qs} (100%) rename katas/content/superposition_kata/{common.qs => Common.qs} (100%) rename katas/content/superposition_kata/even_sup_two_qubits/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/superposition_kata/even_sup_two_qubits/{solution.qs => Solution.qs} (100%) rename katas/content/superposition_kata/even_sup_two_qubits/{verification.qs => Verification.qs} (100%) rename katas/content/superposition_kata/even_sup_two_qubits_phase_flip/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/superposition_kata/even_sup_two_qubits_phase_flip/{solution.qs => Solution.qs} (100%) rename katas/content/superposition_kata/even_sup_two_qubits_phase_flip/{verification.qs => Verification.qs} (100%) rename katas/content/superposition_kata/minus_state/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/superposition_kata/minus_state/{solution.qs => Solution.qs} (100%) rename katas/content/superposition_kata/minus_state/{verification.qs => Verification.qs} (100%) rename katas/content/superposition_kata/plus_state/{placeholder.qs => Placeholder.qs} (100%) rename katas/content/superposition_kata/plus_state/{solution.qs => Solution.qs} (100%) rename katas/content/superposition_kata/plus_state/{verification.qs => Verification.qs} (100%) diff --git a/katas/content/getting_started/index.md b/katas/content/getting_started/index.md index 102b62aac3..2a1f0117a5 100644 --- a/katas/content/getting_started/index.md +++ b/katas/content/getting_started/index.md @@ -60,11 +60,8 @@ _The Japanese word for "form", a pattern of learning and practicing new skills._ @[exercise]({ "id": "getting_started__flip_qubit", "title": "Flip a Qubit", - "descriptionPath": "./flip_qubit/index.md", - "codePaths": [ - "../KatasLibrary.qs", - "./flip_qubit/Verification.qs" - ], - "placeholderSourcePath": "./flip_qubit/Placeholder.qs", - "solutionPath": "./flip_qubit/solution.md" + "path": "./flip_qubit/", + "qsDependencies": [ + "../KatasLibrary.qs" + ] }) diff --git a/katas/content/multi_qubit_gates/index.md b/katas/content/multi_qubit_gates/index.md index 1c3df1d4c4..acc25d0df1 100644 --- a/katas/content/multi_qubit_gates/index.md +++ b/katas/content/multi_qubit_gates/index.md @@ -8,11 +8,13 @@ This kata continues the introduction to quantum gates, focusing on applying quantum gates to multi-qubit systems. **This kata covers the following topics:** + - Applying quantum gates to a part of the system - `CNOT` and `SWAP` gates - Controlled gates **What you should know to start working on this kata:** + - Basic linear algebra - The concept of qubit and multi-qubit systems - Single-qubit and multi-qubit quantum gates @@ -72,13 +74,10 @@ It is more complex when a multi-qubit gate is applied to a subset of qubits that @[exercise]({ "id": "multi_qubit_gates__compound_gate", "title": "Compound Gate", - "descriptionPath": "./compound_gate/index.md", - "codePaths": [ - "../KatasLibrary.qs", - "./compound_gate/Verification.qs" - ], - "placeholderSourcePath": "./compound_gate/Placeholder.qs", - "solutionPath": "./compound_gate/solution.md" + "path": "./compound_gate/", + "qsDependencies": [ + "../KatasLibrary.qs" + ] }) @[section]({ @@ -128,13 +127,10 @@ The `CNOT` gate is self-adjoint: applying it for the second time reverses its ef @[exercise]({ "id": "multi_qubit_gates__preparing_bell_state", "title": "Preparing a Bell State", - "descriptionPath": "./preparing_bell_state/index.md", - "codePaths": [ - "../KatasLibrary.qs", - "./preparing_bell_state/Verification.qs" - ], - "placeholderSourcePath": "./preparing_bell_state/Placeholder.qs", - "solutionPath": "./preparing_bell_state/solution.md" + "path": "./preparing_bell_state/", + "qsDependencies": [ + "../KatasLibrary.qs" + ] }) @[section]({ @@ -159,11 +155,11 @@ $$ \begin{bmatrix} 0 \\\ 1 \\\ 0 \\\ 0 \end{bmatrix}\begin{bmatrix} 0 & 1 & 0 & 0 \end{bmatrix} + \begin{bmatrix} 0 \\\ 0 \\\ 1 \\\ 0 \end{bmatrix}\begin{bmatrix} 0 & 0 & 0 & 1 \end{bmatrix} + \begin{bmatrix} 0 \\\ 0 \\\ 0 \\\ 1 \end{bmatrix}\begin{bmatrix} 0 & 0 & 1 & 0 \end{bmatrix} = -$$ $$ -\begin{bmatrix} 1 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ \end{bmatrix} + -\begin{bmatrix} 0 & 0 & 0 & 0 \\\ 0 & 1 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ \end{bmatrix} + -\begin{bmatrix} 0 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 1 \\\ 0 & 0 & 0 & 0 \\\ \end{bmatrix} + +$$ +\begin{bmatrix} 1 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ \end{bmatrix} + +\begin{bmatrix} 0 & 0 & 0 & 0 \\\ 0 & 1 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ \end{bmatrix} + +\begin{bmatrix} 0 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 1 \\\ 0 & 0 & 0 & 0 \\\ \end{bmatrix} + \begin{bmatrix} 0 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ 0 & 0 & 0 & 0 \\\ 0 & 0 & 1 & 0 \\\ \end{bmatrix} = $$ $$\begin{bmatrix} 1 & 0 & 0 & 0 \\\ 0 & 1 & 0 & 0 \\\ 0 & 0 & 0 & 1 \\\ 0 & 0 & 1 & 0 \\\ \end{bmatrix}$$ @@ -171,7 +167,7 @@ $$\begin{bmatrix} 1 & 0 & 0 & 0 \\\ 0 & 1 & 0 & 0 \\\ 0 & 0 & 0 & 1 \\\ 0 & 0 & This representation can be used to carry out calculations in Dirac notation without ever switching back to matrix representation: $$ -\text{CNOT}|10\rangle = +\text{CNOT}|10\rangle = \big(|00\rangle\langle00| + |01\rangle\langle01| + |10\rangle\langle11| + |11\rangle\langle10|\big)|10\rangle =$$ $$|00\rangle\langle00|10\rangle + |01\rangle\langle01|10\rangle + |10\rangle\langle11|10\rangle + |11\rangle\langle10|10\rangle =$$ $$|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) =$$ @@ -222,8 +218,9 @@ $$A = \sum_{i=0}^{2^N-1} x_i|\psi_i\rangle\langle\psi_i|$$ Let's use our `CNOT` gate as a simple example. The $\\text{CNOT}$ gate has four eigenvectors. - * 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). - * 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: + +- 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). +- 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: $$\text{CNOT}|00\rangle = |00\rangle$$ $$\text{CNOT}|01\rangle = |01\rangle$$ @@ -270,13 +267,10 @@ The `SWAP` gate acts on two qubits, and, as the name implies, swaps their quantu @[exercise]({ "id": "multi_qubit_gates__qubit_swap", "title": "Qubit SWAP", - "descriptionPath": "./qubit_swap/index.md", - "codePaths": [ - "../KatasLibrary.qs", - "./qubit_swap/Verification.qs" - ], - "placeholderSourcePath": "./qubit_swap/Placeholder.qs", - "solutionPath": "./qubit_swap/solution.md" + "path": "./qubit_swap/", + "qsDependencies": [ + "../KatasLibrary.qs" + ] }) @[section]({ @@ -355,18 +349,21 @@ However, as $N$ gets larger, creating a full size matrix can be extremely unwiel These can be represented as applying the following gates on the 3 qubits. 1. $\text{SWAP} \otimes I$ + $$ x_{000}|000\rangle + x_{001}|001\rangle + x_{100}|010\rangle + x_{101}|011\rangle + x_{010}|100\rangle + x_{011}|101\rangle + x_{110}|110\rangle + x_{111}|111\rangle $$ 2. $I \otimes \text{CNOT}$ + $$ x_{000}|000\rangle + x_{001}|001\rangle + x_{101}|010\rangle + x_{100}|011\rangle + x_{010}|100\\rangle + x_{011}|101\rangle + x_{111}|110\rangle + x_{110}|111\rangle $$ 3. $\text{SWAP} \otimes I$ + $$ 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 @@ -380,6 +377,7 @@ $$\text{CINOT} = (\text{SWAP} \otimes I)(I \otimes \text{CNOT})(\text{SWAP} \oti > 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. > > We can also spell out all gates applied explicitly (this makes for a much longer code, though): +> > ```qsharp operation CINOT (qs: Qubit[]) : Unit { // First step @@ -467,13 +465,10 @@ In other cases, you'll need to define the controlled version of an operation man @[exercise]({ "id": "multi_qubit_gates__controlled_rotation", "title": "Controlled Rotation", - "descriptionPath": "./controlled_rotation/index.md", - "codePaths": [ - "../KatasLibrary.qs", - "./controlled_rotation/Verification.qs" - ], - "placeholderSourcePath": "./controlled_rotation/Placeholder.qs", - "solutionPath": "./controlled_rotation/solution.md" + "path": "./controlled_rotation/", + "qsDependencies": [ + "../KatasLibrary.qs" + ] }) @[section]({ @@ -513,9 +508,10 @@ For example, an **anti-controlled** `U` gate (sometimes called **zero-controlled It is also possible to define control conditions in other bases, for example, applying the gate if the control qubit is in the $|+\rangle$ state. All the variants of controlled gates can be expressed in terms of the controls described in previous sections, using the following sequence of steps: -* First, apply a transformation on control qubits that will transform the state you want to use as control into the $|1...1\rangle$ state. -* Apply the regular controlled version of the gate. -* Finally, undo the transformation on control qubits from the first step using the adjoint version of it. + +- First, apply a transformation on control qubits that will transform the state you want to use as control into the $|1...1\rangle$ state. +- Apply the regular controlled version of the gate. +- Finally, undo the transformation on control qubits from the first step using the adjoint version of it. > Why do we need this last step? Remember that controlled gates are defined in terms of their effect on the basis states: > 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. @@ -548,6 +544,7 @@ All the variants of controlled gates can be expressed in terms of the controls d > Let's apply the anti-controlled `X` gate to the $|00\rangle$ state step by step: +> > 1. Transform the state of the control qubit to $|1\rangle$: we can do that by applying the $X$ gate to the first qubit: > $$|00\rangle \rightarrow |10\rangle$$ > 2. Apply the regular `CNOT` gate: @@ -562,6 +559,7 @@ Finally, let's take a look at a very useful operation $00$ $\left( \frac{1}{3}\right)^2 = \frac{1}{9}$ - + $01$ $\left( \frac{2}{3}\right)^2 = \frac{4}{9}$ - + $10$ $\left( 0\right)^2 = 0$ - + $11$ $\left( \frac{2}{3}\right)^2 = \frac{4}{9}$ - + -## Multi-Qubit Measurement Outcome Probabilities II +## Multi-Qubit Measurement Outcome Probabilities II Suppose that a two-qubit system is known to be in the following state: $$\ket \psi = \frac{2}{3}\ket {00} + \frac{1}{3} \ket {01} + \frac{2}{3}\ket {11}$$ @@ -134,11 +134,11 @@ After this, the probabilities of measuring each of the four basis vectors is giv $++$ $\left( \frac{5}{6}\right)^2 = \frac{25}{36}$ - + $+-$ $\left( -\frac{1}{6}\right)^2 = \frac{1}{36}$ - + $-+$ $\left( \frac{1}{6}\right)^2 = \frac{1}{36}$ @@ -146,12 +146,13 @@ After this, the probabilities of measuring each of the four basis vectors is giv $--$ $\left( \frac{1}{2}\right)^2 = \frac{1}{4}$ - + ### Code-Based Solution We can also use Q# to solve this problem. It can be achieved in three steps: + 1. Prepare the state $\ket \psi$. 2. 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. 3. View probabilities of each basis state with the `DumpMachine` function. Thanks to the previous step, the following state equivalence holds: @@ -164,11 +165,11 @@ We can also use Q# to solve this problem. It can be achieved in three steps: $\ket {++}$ $\ket {00}$ - + $\ket {+-}$ $\ket {01}$ - + $\ket {-+}$ $\ket {10}$ @@ -176,7 +177,7 @@ We can also use Q# to solve this problem. It can be achieved in three steps: $\ket {--}$ $\ket {11}$ - + 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! @@ -189,7 +190,7 @@ The amplitudes of the computational basis states after the transformation are th @[example]({ "id": "multi_qubit_measurements__multi_qubit_probabilities_2_example", - "codePath": "./multi_qubit_probabilities.qs" + "codePath": "./MultiQubitProbabilities.qs" }) ## Measuring Each Qubit in a System Sequentially @@ -219,7 +220,7 @@ The simulated probabilities will be different for each run of `DemoBasisMeasurem @[example]({ "id": "multi_qubit_measurements__measuring_one_at_a_time", - "codePath": "./measuring_one.qs" + "codePath": "./MeasuringOne.qs" }) ## Using Full Measurements to Identify the State of the System @@ -229,12 +230,9 @@ Full measurements can also be used to identify the state of the system, if it is @[exercise]({ "id": "multi_qubit_measurements__full_measurements", "title": "Distinguish Four Basis States", - "descriptionPath": "./full_measurements/index.md", - "placeholderSourcePath": "./full_measurements/placeholder.qs", - "solutionPath": "./full_measurements/solution.md", - "codePaths": [ - "./full_measurements/verify.qs", - "./common.qs", + "path": "./full_measurements/", + "qsDependencies": [ + "./Common.qs", "../KatasLibrary.qs" ] }) @@ -255,13 +253,16 @@ $$P_i = |b_i\rangle \langle b_i| \otimes \mathbb{1}_{n-m} $$ where $\mathbb{1}_{n-m}$ is the identity operator over the remaining $(n-m)$ qubits. The symbol $\otimes$ represents the tensor product or the Kronecker product of two matrices. It is different from the usual matrix multiplication. -In the current context, $|b_i\rangle \langle b_i| \otimes \mathbb{1}_{n-m}$ simply means that +In the current context, $|b_i\rangle \langle b_i| \otimes \mathbb{1}_{n-m}$ simply means that + - The operator $|b_i\rangle \langle b_i|$ acts only on the $m$ qubits being measured. - The effect of $P_i$ on the remaining qubits is $\mathbb{1}_{n-m} $, i.e., the identity operator. Analogous to the case for measurements for single-qubit systems, the rules for partial measurement probabilities and outcomes can be summarized as follows: + - 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$. - 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 + $$ \frac{P_i |\psi\rangle}{\big|P_i |\psi\rangle\big|}. $$ @@ -297,12 +298,12 @@ If only the first qubit is measured in the computational basis, what are the pro
Solution -A 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 +A 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 $$\big|P_0 \ket{\psi}\big|^2 = \big|\frac{1}{\sqrt{12}} \left(3\ket {00} + \ket{01}\right) \big|^2 = \frac{5}{6}$$ -and +and $$\frac{P_0 \ket{\psi}}{\big|P_0 \ket{\psi}\big|} = \frac{1}{\sqrt{10}} \left( 3\ket{00} + \ket{01}\right)$$ -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 +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 $$\frac{P_1 \ket{\psi}}{\big|P_1 \ket{\psi}\big|} = \frac{1}{\sqrt{2}} \left(\ket{10} + \ket{11}\right)$$ @@ -316,12 +317,12 @@ $$\frac{P_1 \ket{\psi}}{\big|P_1 \ket{\psi}\big|} = \frac{1}{\sqrt{2}} \left(\ke $0$ $\frac{5}{6}$ $\frac{1}{\sqrt{10}} \left( 3\ket{00} + \ket{01}\right)$ - + $1$ $\frac{1}{6}$ $\frac{1}{\sqrt{2}} \left(\ket{10} + \ket{11}\right)$ - +
@@ -336,7 +337,7 @@ The simulated and theoretical measurement probabilities are not expected to matc @[example]({ "id": "multi_qubit_measurements__partial_measurements_demo", - "codePath": "./partial_measurements_demo.qs" + "codePath": "./PartialMeasurementsDemo.qs" }) ## Using Partial Measurements to Identify the State of the System @@ -346,12 +347,9 @@ In certain situations, it is possible to distinguish between orthogonal states o @[exercise]({ "id": "multi_qubit_measurements__partial_measurements_for_system", "title": "Distinguish Orthogonal States Using Partial Measurements", - "descriptionPath": "./partial_measurements_for_system/index.md", - "placeholderSourcePath": "./partial_measurements_for_system/placeholder.qs", - "solutionPath": "./partial_measurements_for_system/solution.md", - "codePaths": [ - "./partial_measurements_for_system/verify.qs", - "./common.qs", + "path": "./partial_measurements_for_system/", + "qsDependencies": [ + "./Common.qs", "../KatasLibrary.qs" ] }) @@ -388,10 +386,11 @@ On the other hand, if the system is entangled, then the measurement outcomes wil **Sequential measurements on an entangled state and a separable state** Consider two two-qubit states: + - The Bell state $|\Phi^{+}\rangle = \frac{1}{\sqrt{2}} \big (|00\rangle + |11\rangle\big)$. - A state $\ket \Theta = \frac{1}{2} \big( \ket{00} + \ket{01} + \ket{10} + \ket{11} \big)$. -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. +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.
Solution @@ -409,12 +408,9 @@ For certain multi-qubit systems prepared in a superposition state, it is possibl @[exercise]({ "id": "multi_qubit_measurements__state_modification", "title": "State Selection Using Partial Measurements", - "descriptionPath": "./state_modification/index.md", - "placeholderSourcePath": "./state_modification/placeholder.qs", - "solutionPath": "./state_modification/solution.md", - "codePaths": [ - "./state_modification/verify.qs", - "./common.qs", + "path": "./state_modification/", + "qsDependencies": [ + "./Common.qs", "../KatasLibrary.qs" ] }) @@ -431,12 +427,9 @@ You could prepare a simpler state involving additional qubits, which, when measu @[exercise]({ "id": "multi_qubit_measurements__state_preparation_using_partial_measurements", "title": "State Preparation Using Partial Measurements", - "descriptionPath": "./state_preparation/index.md", - "placeholderSourcePath": "./state_preparation/placeholder.qs", - "solutionPath": "./state_preparation/solution.md", - "codePaths": [ - "./state_preparation/verify.qs", - "./common.qs", + "path": "./state_preparation/", + "qsDependencies": [ + "./Common.qs", "../KatasLibrary.qs" ] }) @@ -449,6 +442,7 @@ You could prepare a simpler state involving additional qubits, which, when measu 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 `Measure` operation. Let's review single-qubit measurements in a different light before discussing joint measurements. ## Single-Qubit Pauli Measurement + 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 `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. For 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 @@ -506,6 +500,7 @@ In general, any measurement on a single qubit which results in two outcomes corr Joint measurements are a generalization of this principle for multi-qubit matrices. ## Parity Measurements + 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. 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 `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. @@ -561,12 +556,9 @@ Similarly, a parity measurement on a higher number of qubits can be implemented @[exercise]({ "id": "multi_qubit_measurements__two_qubit_parity_measurement", "title": "Two-Qubit Parity Measurement", - "descriptionPath": "./joint_measurements/index.md", - "placeholderSourcePath": "./joint_measurements/placeholder.qs", - "solutionPath": "./joint_measurements/solution.md", - "codePaths": [ - "./joint_measurements/verify.qs", - "./common.qs", + "path": "./joint_measurements/", + "qsDependencies": [ + "./Common.qs", "../KatasLibrary.qs" ] }) @@ -622,7 +614,7 @@ $$XX \ket{-+} = -\ket{-+}$$ 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. -The 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 +The 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 $$P_{+1} ( \gamma \ket{++} + \delta \ket{--} ) =$$ $$( \gamma \ket{++} + \delta \ket{--} )P_{+1} ( \mu \ket{-+} + \nu \ket{+-} ) = 0$$ @@ -643,8 +635,9 @@ Thus, this state has an even parity in the Hadamard basis. It follows that an $X }) Congratulations! In this kata you learned how to apply measurements on multi-qubit systems. Here are a few key concepts to keep in mind: -* Full measurements: you measure all the qubits simultaneously in an orthogonal basis ($2^n$ possible outcomes). -* Partial measurements: you measure $m$ qubits out of $n$, for $m< n$ ($2^m$ possible outcomes). -* Joint measurement: Pauli measurement of all $n$ qubits ($2$ possible outcomes). + +- Full measurements: you measure all the qubits simultaneously in an orthogonal basis ($2^n$ possible outcomes). +- Partial measurements: you measure $m$ qubits out of $n$, for $m< n$ ($2^m$ possible outcomes). +- Joint measurement: Pauli measurement of all $n$ qubits ($2$ possible outcomes). Next, you will implement a quantum algorithm to generate random numbers in "Quantum Random Number Generation" kata. diff --git a/katas/content/multi_qubit_measurements/joint_measurements/placeholder.qs b/katas/content/multi_qubit_measurements/joint_measurements/Placeholder.qs similarity index 100% rename from katas/content/multi_qubit_measurements/joint_measurements/placeholder.qs rename to katas/content/multi_qubit_measurements/joint_measurements/Placeholder.qs diff --git a/katas/content/multi_qubit_measurements/joint_measurements/solution.qs b/katas/content/multi_qubit_measurements/joint_measurements/Solution.qs similarity index 100% rename from katas/content/multi_qubit_measurements/joint_measurements/solution.qs rename to katas/content/multi_qubit_measurements/joint_measurements/Solution.qs diff --git a/katas/content/multi_qubit_measurements/joint_measurements/verify.qs b/katas/content/multi_qubit_measurements/joint_measurements/Verification.qs similarity index 100% rename from katas/content/multi_qubit_measurements/joint_measurements/verify.qs rename to katas/content/multi_qubit_measurements/joint_measurements/Verification.qs diff --git a/katas/content/multi_qubit_measurements/joint_measurements/solution.md b/katas/content/multi_qubit_measurements/joint_measurements/solution.md index 2543560a41..2c4b8034fc 100644 --- a/katas/content/multi_qubit_measurements/joint_measurements/solution.md +++ b/katas/content/multi_qubit_measurements/joint_measurements/solution.md @@ -11,5 +11,5 @@ In Q#, the operation Q# has a built-in repeat-until-success (RUS) loop, which comes in handy in this case. +> Q# has a built-in repeat-until-success (RUS) loop, which comes in handy in this case. > * 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. > * `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. > * 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. @@ -27,5 +26,5 @@ This technique is sometimes called post-selection. @[solution]({ "id": "multi_qubit_measurements__state_preparation_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/multi_qubit_systems/index.md b/katas/content/multi_qubit_systems/index.md index 75d0f41427..18c485b767 100644 --- a/katas/content/multi_qubit_systems/index.md +++ b/katas/content/multi_qubit_systems/index.md @@ -77,7 +77,7 @@ The coefficients of the basis vectors define how "close" is the system state to > 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**: > -> $$\frac{1}{\sqrt{2}}\begin{bmatrix} 1 \\\ 0 \\\ 0 \\\ 1 \end{bmatrix}, +> $$\frac{1}{\sqrt{2}}\begin{bmatrix} 1 \\\ 0 \\\ 0 \\\ 1 \end{bmatrix}, \frac{1}{\sqrt{2}}\begin{bmatrix} 1 \\\ 0 \\\ 0 \\\ -1 \end{bmatrix}, \frac{1}{\sqrt{2}}\begin{bmatrix} 0 \\\ 1 \\\ 1 \\\ 0 \end{bmatrix}, \frac{1}{\sqrt{2}}\begin{bmatrix} 0 \\\ 1 \\\ -1 \\\ 0 \end{bmatrix}$$ @@ -98,7 +98,6 @@ $$ You can see that the first qubit is in state $\frac{1}{\sqrt{2}}\big(|0\rangle + |1\rangle\big)$ and the second qubit is in state $|0\rangle$. The multi-qubit states that allow such representation are known as **separable states**, or product states, because you can separate the global state into the tensor product of individual subsystems. - ## 🔎 Analyze Show that the state is separable: @@ -112,7 +111,7 @@ $$ To separate the state into a tensor product of two single-qubit states, we need to represent it in the following way: $$ -\begin{bmatrix} \alpha \gamma \\\ \alpha \delta \\\ \beta \gamma \\\ \beta \delta \end{bmatrix} = +\begin{bmatrix} \alpha \gamma \\\ \alpha \delta \\\ \beta \gamma \\\ \beta \delta \end{bmatrix} = \begin{bmatrix} \alpha \\\ \beta \end{bmatrix} \otimes \begin{bmatrix} \gamma \\\ \delta \end{bmatrix} $$ @@ -236,7 +235,6 @@ $$|\phi^-\rangle = \frac{1}{\sqrt{2}}\big(|00\rangle - |11\rangle\big)$$ $$|\psi^+\rangle = \frac{1}{\sqrt{2}}\big(|01\rangle + |10\rangle\big)$$ $$|\psi^-\rangle = \frac{1}{\sqrt{2}}\big(|01\rangle - |10\rangle\big)$$ - >## Endianness > > 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$. @@ -293,9 +291,9 @@ $$|\psi^-\rangle = \frac{1}{\sqrt{2}}\big(|01\rangle - |10\rangle\big)$$ 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. These demos use the function `DumpMachine` to print the state of the quantum simulator. -When dealing with multi-qubit systems, `DumpMachine` prints information about each basis state that has a non-zero amplitude, one basis state per row, the same as it does for single-qubit systems. -The basis states are represented as bit strings, one bit per the qubit allocated, with the leftmost bit corresponding -to the qubit that was allocated the earliest. (If the qubits were allocated at once as an array, the leftmost bit corresponds +When dealing with multi-qubit systems, `DumpMachine` prints information about each basis state that has a non-zero amplitude, one basis state per row, the same as it does for single-qubit systems. +The basis states are represented as bit strings, one bit per the qubit allocated, with the leftmost bit corresponding +to the qubit that was allocated the earliest. (If the qubits were allocated at once as an array, the leftmost bit corresponds to the first element of the array.) @[example]({"id": "multi_qubit_systems__multi_qubit_systems_demo", "codePath": "./examples/MultiQubitSystems.qs"}) @@ -313,13 +311,10 @@ If they are not in zero state by that time, they can potentially be still entang @[exercise]({ "id": "multi_qubit_systems__learn_basis_state_amplitudes", "title": "Learn Basis State Amplitudes Using DumpMachine", - "descriptionPath": "./learn_basis_state_amplitudes/index.md", - "codePaths": [ - "../KatasLibrary.qs", - "./learn_basis_state_amplitudes/verification.qs" - ], - "placeholderSourcePath": "./learn_basis_state_amplitudes/placeholder.qs", - "solutionPath": "./learn_basis_state_amplitudes/solution.md" + "path": "./learn_basis_state_amplitudes/", + "qsDependencies": [ + "../KatasLibrary.qs" + ] }) @[section]({ @@ -336,48 +331,36 @@ Array elements are indexed starting with 0, the first array element corresponds @[exercise]({ "id": "multi_qubit_systems__prepare_basis_state", "title": "Prepare a Basis State", - "descriptionPath": "./prepare_basis_state/index.md", - "placeholderSourcePath": "./prepare_basis_state/placeholder.qs", - "solutionPath": "./prepare_basis_state/solution.md", - "codePaths": [ - "../KatasLibrary.qs", - "./prepare_basis_state/verification.qs" + "path": "./prepare_basis_state/", + "qsDependencies": [ + "../KatasLibrary.qs" ] }) @[exercise]({ "id": "multi_qubit_systems__prepare_superposition", "title": "Prepare a Superposition of Two Basis States", - "descriptionPath": "./prepare_superposition/index.md", - "placeholderSourcePath": "./prepare_superposition/placeholder.qs", - "solutionPath": "./prepare_superposition/solution.md", - "codePaths": [ - "../KatasLibrary.qs", - "./prepare_superposition/verification.qs" + "path": "./prepare_superposition/", + "qsDependencies": [ + "../KatasLibrary.qs" ] }) @[exercise]({ "id": "multi_qubit_systems__prepare_with_real", "title": " Prepare a Superposition with Real Amplitudes", - "descriptionPath": "./prepare_with_real/index.md", - "placeholderSourcePath": "./prepare_with_real/placeholder.qs", - "solutionPath": "./prepare_with_real/solution.md", - "codePaths": [ - "../KatasLibrary.qs", - "./prepare_with_real/verification.qs" + "path": "./prepare_with_real/", + "qsDependencies": [ + "../KatasLibrary.qs" ] }) @[exercise]({ "id": "multi_qubit_systems__prepare_with_complex", "title": "Prepare a Superposition with Complex Amplitudes", - "descriptionPath": "./prepare_with_complex/index.md", - "placeholderSourcePath": "./prepare_with_complex/placeholder.qs", - "solutionPath": "./prepare_with_complex/solution.md", - "codePaths": [ - "../KatasLibrary.qs", - "./prepare_with_complex/verification.qs" + "path": "./prepare_with_complex/", + "qsDependencies": [ + "../KatasLibrary.qs" ] }) diff --git a/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/placeholder.qs b/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/Placeholder.qs similarity index 100% rename from katas/content/multi_qubit_systems/learn_basis_state_amplitudes/placeholder.qs rename to katas/content/multi_qubit_systems/learn_basis_state_amplitudes/Placeholder.qs diff --git a/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/solution.qs b/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/Solution.qs similarity index 100% rename from katas/content/multi_qubit_systems/learn_basis_state_amplitudes/solution.qs rename to katas/content/multi_qubit_systems/learn_basis_state_amplitudes/Solution.qs diff --git a/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/verification.qs b/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/Verification.qs similarity index 100% rename from katas/content/multi_qubit_systems/learn_basis_state_amplitudes/verification.qs rename to katas/content/multi_qubit_systems/learn_basis_state_amplitudes/Verification.qs diff --git a/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/solution.md b/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/solution.md index f2d3271962..880d4cd5db 100644 --- a/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/solution.md +++ b/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/solution.md @@ -3,5 +3,5 @@ After that, you can hardcode the values into your solution. @[solution]({ "id": "multi_qubit_systems__learn_basis_state_amplitudes_solution", - "codePath": "./solution.qs" + "codePath": "./Solution.qs" }) diff --git a/katas/content/multi_qubit_systems/prepare_basis_state/placeholder.qs b/katas/content/multi_qubit_systems/prepare_basis_state/Placeholder.qs similarity index 100% rename from katas/content/multi_qubit_systems/prepare_basis_state/placeholder.qs rename to katas/content/multi_qubit_systems/prepare_basis_state/Placeholder.qs diff --git a/katas/content/multi_qubit_systems/prepare_basis_state/solution.qs b/katas/content/multi_qubit_systems/prepare_basis_state/Solution.qs similarity index 100% rename from katas/content/multi_qubit_systems/prepare_basis_state/solution.qs rename to katas/content/multi_qubit_systems/prepare_basis_state/Solution.qs diff --git a/katas/content/multi_qubit_systems/prepare_basis_state/verification.qs b/katas/content/multi_qubit_systems/prepare_basis_state/Verification.qs similarity index 100% rename from katas/content/multi_qubit_systems/prepare_basis_state/verification.qs rename to katas/content/multi_qubit_systems/prepare_basis_state/Verification.qs diff --git a/katas/content/multi_qubit_systems/prepare_basis_state/solution.md b/katas/content/multi_qubit_systems/prepare_basis_state/solution.md index 08abd60e60..a220494a7e 100644 --- a/katas/content/multi_qubit_systems/prepare_basis_state/solution.md +++ b/katas/content/multi_qubit_systems/prepare_basis_state/solution.md @@ -8,5 +8,5 @@ Applying an **X** gate to a qubit in the $|0\rangle$ state transforms the qubit @[solution]({ "id": "multi_qubit_systems__prepare_basis_state_solution", -"codePath": "solution.qs" +"codePath": "Solution.qs" }) diff --git a/katas/content/multi_qubit_systems/prepare_superposition/placeholder.qs b/katas/content/multi_qubit_systems/prepare_superposition/Placeholder.qs similarity index 100% rename from katas/content/multi_qubit_systems/prepare_superposition/placeholder.qs rename to katas/content/multi_qubit_systems/prepare_superposition/Placeholder.qs diff --git a/katas/content/multi_qubit_systems/prepare_superposition/solution.qs b/katas/content/multi_qubit_systems/prepare_superposition/Solution.qs similarity index 100% rename from katas/content/multi_qubit_systems/prepare_superposition/solution.qs rename to katas/content/multi_qubit_systems/prepare_superposition/Solution.qs diff --git a/katas/content/multi_qubit_systems/prepare_superposition/verification.qs b/katas/content/multi_qubit_systems/prepare_superposition/Verification.qs similarity index 100% rename from katas/content/multi_qubit_systems/prepare_superposition/verification.qs rename to katas/content/multi_qubit_systems/prepare_superposition/Verification.qs diff --git a/katas/content/multi_qubit_systems/prepare_superposition/solution.md b/katas/content/multi_qubit_systems/prepare_superposition/solution.md index 5179aaadd3..0155f07fdf 100644 --- a/katas/content/multi_qubit_systems/prepare_superposition/solution.md +++ b/katas/content/multi_qubit_systems/prepare_superposition/solution.md @@ -14,5 +14,5 @@ $$ H|1\rangle = \frac{1}{\sqrt2}\begin{bmatrix} 1 & 1 \\\ 1 & -1 \end{bmatrix} \ @[solution]({ "id": "multi_qubit_systems__prepare_superposition_solution", -"codePath": "solution.qs" +"codePath": "Solution.qs" }) diff --git a/katas/content/multi_qubit_systems/prepare_with_complex/placeholder.qs b/katas/content/multi_qubit_systems/prepare_with_complex/Placeholder.qs similarity index 100% rename from katas/content/multi_qubit_systems/prepare_with_complex/placeholder.qs rename to katas/content/multi_qubit_systems/prepare_with_complex/Placeholder.qs diff --git a/katas/content/multi_qubit_systems/prepare_with_complex/solution.qs b/katas/content/multi_qubit_systems/prepare_with_complex/Solution.qs similarity index 100% rename from katas/content/multi_qubit_systems/prepare_with_complex/solution.qs rename to katas/content/multi_qubit_systems/prepare_with_complex/Solution.qs diff --git a/katas/content/multi_qubit_systems/prepare_with_complex/verification.qs b/katas/content/multi_qubit_systems/prepare_with_complex/Verification.qs similarity index 100% rename from katas/content/multi_qubit_systems/prepare_with_complex/verification.qs rename to katas/content/multi_qubit_systems/prepare_with_complex/Verification.qs diff --git a/katas/content/multi_qubit_systems/prepare_with_complex/solution.md b/katas/content/multi_qubit_systems/prepare_with_complex/solution.md index df9e0a3348..fd4124d942 100644 --- a/katas/content/multi_qubit_systems/prepare_with_complex/solution.md +++ b/katas/content/multi_qubit_systems/prepare_with_complex/solution.md @@ -22,5 +22,5 @@ $$ \begin{bmatrix} 1 & 0 \\\ 0 & e^{i\pi/4} \end{bmatrix} \cdot \frac{1}{\sqrt2} @[solution]({ "id": "multi_qubit_systems__prepare_with_complex_solution", -"codePath": "solution.qs" +"codePath": "Solution.qs" }) diff --git a/katas/content/multi_qubit_systems/prepare_with_real/placeholder.qs b/katas/content/multi_qubit_systems/prepare_with_real/Placeholder.qs similarity index 100% rename from katas/content/multi_qubit_systems/prepare_with_real/placeholder.qs rename to katas/content/multi_qubit_systems/prepare_with_real/Placeholder.qs diff --git a/katas/content/multi_qubit_systems/prepare_with_real/solution.qs b/katas/content/multi_qubit_systems/prepare_with_real/Solution.qs similarity index 100% rename from katas/content/multi_qubit_systems/prepare_with_real/solution.qs rename to katas/content/multi_qubit_systems/prepare_with_real/Solution.qs diff --git a/katas/content/multi_qubit_systems/prepare_with_real/verification.qs b/katas/content/multi_qubit_systems/prepare_with_real/Verification.qs similarity index 100% rename from katas/content/multi_qubit_systems/prepare_with_real/verification.qs rename to katas/content/multi_qubit_systems/prepare_with_real/Verification.qs diff --git a/katas/content/multi_qubit_systems/prepare_with_real/solution.md b/katas/content/multi_qubit_systems/prepare_with_real/solution.md index 195c251cae..1b3b0613cd 100644 --- a/katas/content/multi_qubit_systems/prepare_with_real/solution.md +++ b/katas/content/multi_qubit_systems/prepare_with_real/solution.md @@ -10,5 +10,5 @@ For the second qubit we can use the same transformation we've seen in the "Prepa @[solution]({ "id": "multi_qubit_systems__prepare_with_real_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/oracles/common.qs b/katas/content/oracles/Common.qs similarity index 100% rename from katas/content/oracles/common.qs rename to katas/content/oracles/Common.qs diff --git a/katas/content/oracles/marking_oracle_alt_bit.qs b/katas/content/oracles/MarkingOracleAltBit.qs similarity index 100% rename from katas/content/oracles/marking_oracle_alt_bit.qs rename to katas/content/oracles/MarkingOracleAltBit.qs diff --git a/katas/content/oracles/oracle_converter_demo.qs b/katas/content/oracles/OracleConverterDemo.qs similarity index 100% rename from katas/content/oracles/oracle_converter_demo.qs rename to katas/content/oracles/OracleConverterDemo.qs diff --git a/katas/content/oracles/phase_oracle_alt_bit.qs b/katas/content/oracles/PhaseOracleAltBit.qs similarity index 100% rename from katas/content/oracles/phase_oracle_alt_bit.qs rename to katas/content/oracles/PhaseOracleAltBit.qs diff --git a/katas/content/oracles/test_meeting_oracle.qs b/katas/content/oracles/TestMeetingOracle.qs similarity index 100% rename from katas/content/oracles/test_meeting_oracle.qs rename to katas/content/oracles/TestMeetingOracle.qs diff --git a/katas/content/oracles/bit_pattern_challenge/placeholder.qs b/katas/content/oracles/bit_pattern_challenge/Placeholder.qs similarity index 100% rename from katas/content/oracles/bit_pattern_challenge/placeholder.qs rename to katas/content/oracles/bit_pattern_challenge/Placeholder.qs diff --git a/katas/content/oracles/bit_pattern_challenge/solution.qs b/katas/content/oracles/bit_pattern_challenge/Solution.qs similarity index 100% rename from katas/content/oracles/bit_pattern_challenge/solution.qs rename to katas/content/oracles/bit_pattern_challenge/Solution.qs diff --git a/katas/content/oracles/bit_pattern_challenge/verification.qs b/katas/content/oracles/bit_pattern_challenge/Verification.qs similarity index 100% rename from katas/content/oracles/bit_pattern_challenge/verification.qs rename to katas/content/oracles/bit_pattern_challenge/Verification.qs diff --git a/katas/content/oracles/bit_pattern_challenge/solution.md b/katas/content/oracles/bit_pattern_challenge/solution.md index 4dd44d9336..c505afc0bf 100644 --- a/katas/content/oracles/bit_pattern_challenge/solution.md +++ b/katas/content/oracles/bit_pattern_challenge/solution.md @@ -1,4 +1,4 @@ @[solution]({ "id": "oracles__bit_pattern_challenge_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/oracles/bit_pattern_oracle/placeholder.qs b/katas/content/oracles/bit_pattern_oracle/Placeholder.qs similarity index 100% rename from katas/content/oracles/bit_pattern_oracle/placeholder.qs rename to katas/content/oracles/bit_pattern_oracle/Placeholder.qs diff --git a/katas/content/oracles/bit_pattern_oracle/solution.qs b/katas/content/oracles/bit_pattern_oracle/Solution.qs similarity index 100% rename from katas/content/oracles/bit_pattern_oracle/solution.qs rename to katas/content/oracles/bit_pattern_oracle/Solution.qs diff --git a/katas/content/oracles/bit_pattern_oracle/verification.qs b/katas/content/oracles/bit_pattern_oracle/Verification.qs similarity index 100% rename from katas/content/oracles/bit_pattern_oracle/verification.qs rename to katas/content/oracles/bit_pattern_oracle/Verification.qs diff --git a/katas/content/oracles/bit_pattern_oracle/solution.md b/katas/content/oracles/bit_pattern_oracle/solution.md index 51157c82dd..fa7ed46b55 100644 --- a/katas/content/oracles/bit_pattern_oracle/solution.md +++ b/katas/content/oracles/bit_pattern_oracle/solution.md @@ -1,4 +1,4 @@ @[solution]({ "id": "oracles__bit_pattern_oracle_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/oracles/classical_oracles/placeholder.qs b/katas/content/oracles/classical_oracles/Placeholder.qs similarity index 100% rename from katas/content/oracles/classical_oracles/placeholder.qs rename to katas/content/oracles/classical_oracles/Placeholder.qs diff --git a/katas/content/oracles/classical_oracles/solution.qs b/katas/content/oracles/classical_oracles/Solution.qs similarity index 100% rename from katas/content/oracles/classical_oracles/solution.qs rename to katas/content/oracles/classical_oracles/Solution.qs diff --git a/katas/content/oracles/classical_oracles/verification.qs b/katas/content/oracles/classical_oracles/Verification.qs similarity index 100% rename from katas/content/oracles/classical_oracles/verification.qs rename to katas/content/oracles/classical_oracles/Verification.qs diff --git a/katas/content/oracles/classical_oracles/solution.md b/katas/content/oracles/classical_oracles/solution.md index 28adc46cc3..b228ba5b39 100644 --- a/katas/content/oracles/classical_oracles/solution.md +++ b/katas/content/oracles/classical_oracles/solution.md @@ -1,4 +1,4 @@ @[solution]({ "id": "oracles__classical_oracles_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/oracles/index.md b/katas/content/oracles/index.md index cf95233e14..5f16cfd090 100644 --- a/katas/content/oracles/index.md +++ b/katas/content/oracles/index.md @@ -39,13 +39,10 @@ Some classical problems (typically 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$. @@ -79,8 +76,8 @@ $$U_{phase} |\vec{x}\rangle = (-1)^{f(x)}|\vec{x}\rangle$$ 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$. -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 *superposition* of basis states, its effect becomes noticeable. -Remember 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. +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 *superposition* of basis states, its effect becomes noticeable. +Remember 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. 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. @@ -93,19 +90,20 @@ Consider the function $f(x)$ that takes $3$ bits of input and returns $1$ if $x= 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. -@[example]({"id": "oracles__phase_oracle_alt_bit", "codePath": "./phase_oracle_alt_bit.qs"}) +@[example]({"id": "oracles__phase_oracle_alt_bit", "codePath": "./PhaseOracleAltBit.qs"}) We introduced the function `ApplyControlledOnBitString` provided by the Q# Standard library. It 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. - + The sequence of steps that implement this variant are: + 1. 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$. 2. Apply the regular controlled version of the gate. 3. Apply the $X$ gate to the same qubits to return them to their original state. Due to this conjugation pattern, the time complexity of this function is $2N$, where N is the number of control qubits. -> Notice that the input state in the demo above is an equal superposition of all basis states. +> Notice that the input state in the demo above is an equal superposition of all basis states. After 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! > 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! @@ -114,13 +112,10 @@ In the next exercise you will implement the classical oracle that you've impleme @[exercise]({ "id": "oracles__phase_oracle_seven", "title": "Implement a Phase Oracle", - "descriptionPath": "./phase_oracle_seven/index.md", - "placeholderSourcePath": "./phase_oracle_seven/placeholder.qs", - "solutionPath": "./phase_oracle_seven/solution.md", - "codePaths": [ + "path": "./phase_oracle_seven/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs", - "./phase_oracle_seven/verification.qs" + "./Common.qs" ] }) @@ -133,7 +128,7 @@ A marking oracle $U_{mark}$ is an oracle that encodes the value of the classical $$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$$ -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. +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. 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. @@ -143,10 +138,10 @@ Consider the function $f(x)$ that takes $3$ bits of input and returns $1$ if $x= 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. -@[example]({"id": "oracles__marking_oracle_alt_bit", "codePath": "./marking_oracle_alt_bit.qs"}) +@[example]({"id": "oracles__marking_oracle_alt_bit", "codePath": "./MarkingOracleAltBit.qs"}) -> Let's compare the initial state to the final state from the above demo. -In 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. +> Let's compare the initial state to the final state from the above demo. +In 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. The 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. > > 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$. @@ -158,13 +153,10 @@ Now you will implement the same function you've seen in the first two exercises @[exercise]({ "id": "oracles__marking_oracle_seven", "title": "Implement a Marking Oracle", - "descriptionPath": "./marking_oracle_seven/index.md", - "placeholderSourcePath": "./marking_oracle_seven/placeholder.qs", - "solutionPath": "./marking_oracle_seven/solution.md", - "codePaths": [ + "path": "./marking_oracle_seven/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs", - "./marking_oracle_seven/verification.qs" + "./Common.qs" ] }) @@ -177,28 +169,28 @@ Previously we considered applying marking oracles when the register $|x\rangle$ In order to observe phase kickback, we use the target qubit $|y\rangle=|-\rangle$. -> This is the standard choice for two reasons. -> 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$. +> This is the standard choice for two reasons. +> 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$. > Second, the target qubit must be in an equal superposition, otherwise it will become entangled with the input register. 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$: -* If the input register $|x\rangle$ is in a basis state: + +- If the input register $|x\rangle$ is in a basis state: $$U_{mark} |x\rangle |-\rangle = \frac1{\sqrt2} \big(U_{mark}|x\rangle|0\rangle - U_{mark}|x\rangle |1\rangle\big)$$ $$= \frac1{\sqrt2} \big(|x\rangle|0\oplus f(x)\rangle - |x\rangle |1\oplus f(x)\rangle\big)$$ -$$= -\begin{cases} -\frac1{\sqrt2} \big(|x\rangle|0\rangle - |x\rangle |1\rangle\big) = |x\rangle|-\rangle \text{ if } f(x) = 0 \\\ +$$= +\begin{cases} +\frac1{\sqrt2} \big(|x\rangle|0\rangle - |x\rangle |1\rangle\big) = |x\rangle|-\rangle \text{ if } f(x) = 0 \\\ \frac1{\sqrt2} \big(|x\rangle|1\rangle - |x\rangle |0\rangle\big) = -|x\rangle|-\rangle \text{ if } f(x) = 1 \end{cases} $$ $$= (-1)^{f(x)}|x\rangle |-\rangle$$ - -* 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: +- 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: $$U_{mark} |x\rangle |-\rangle = U_{mark} \frac{1}{\sqrt{2}} \big(|b_1\rangle + |b_2\rangle\big) |-\rangle$$ @@ -206,8 +198,8 @@ $$= \frac{1}{\sqrt{2}} \big( U_{mark}|b_1\rangle|-\rangle + U_{mark}|b_2\rangle| $$= \frac{1}{\sqrt{2}} \big( (-1)^{f(b_1)}|b_1\rangle + (-1)^{f(b_2)}|b_2\rangle\big) |-\rangle$$ -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. -Thus we can drop the target qubit without any repercussions after the application of the oracle. +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. +Thus we can drop the target qubit without any repercussions after the application of the oracle. Notice that the input register is now in the following state: $$|\psi\rangle = \frac{1}{\sqrt{2}} \big( (-1)^{f(b_1)}|b_1\rangle + (-1)^{f(b_2)}|b_2\rangle\big),$$ @@ -256,21 +248,18 @@ How could we distinguish the states $|\eta\rangle = |11+\rangle |-\rangle$ and $
Solution Recall that we can only observe alterations to out input state by performing a measurement. -If we apply Hadamard gate to the third qubit, we will be able to distinguish between the input state and the output state. - $$(I\otimes I \otimes H)|11+\rangle = |110\rangle \\ (I\otimes I \otimes H)|11-\rangle = |111\rangle$$ +If we apply Hadamard gate to the third qubit, we will be able to distinguish between the input state and the output state. + $$(I\otimes I \otimes H)|11+\rangle = |110\rangle \\ (I\otimes I \otimes H)|11-\rangle = |111\rangle$$ Now if we were to measure the third qubit, we'll be able to distinguish the starting state and the state after phase kickback occurred.
@[exercise]({ "id": "oracles__marking_oracle_as_phase", "title": "Apply the Marking Oracle as a Phase Oracle", - "descriptionPath": "./marking_oracle_as_phase/index.md", - "placeholderSourcePath": "./marking_oracle_as_phase/placeholder.qs", - "solutionPath": "./marking_oracle_as_phase/solution.md", - "codePaths": [ + "path": "./marking_oracle_as_phase/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs", - "./marking_oracle_as_phase/verification.qs" + "./Common.qs" ] }) @@ -281,11 +270,11 @@ Now if we were to measure the third qubit, we'll be able to distinguish the star In 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. -@[example]({"id": "oracles__oracle_converter_demo", "codePath": "./oracle_converter_demo.qs"}) +@[example]({"id": "oracles__oracle_converter_demo", "codePath": "./OracleConverterDemo.qs"}) > 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$! -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. +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. This 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. @[section]({ @@ -293,85 +282,67 @@ This converter provides a way to implement the function of interest as a marking "title": "Implementing Quantum Oracles" }) -In this section you will implement a few more complicated quantum oracles. +In this section you will implement a few more complicated quantum oracles. > 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. @[exercise]({ "id": "oracles__or_oracle", "title": "Implement the OR Oracle", - "descriptionPath": "./or_oracle/index.md", - "placeholderSourcePath": "./or_oracle/placeholder.qs", - "solutionPath": "./or_oracle/solution.md", - "codePaths": [ + "path": "./or_oracle/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs", - "./or_oracle/verification.qs" + "./Common.qs" ] }) @[exercise]({ "id": "oracles__kth_bit_oracle", "title": "Implement the K-th Bit Oracle", - "descriptionPath": "./kth_bit_oracle/index.md", - "placeholderSourcePath": "./kth_bit_oracle/placeholder.qs", - "solutionPath": "./kth_bit_oracle/solution.md", - "codePaths": [ + "path": "./kth_bit_oracle/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs", - "./kth_bit_oracle/verification.qs" + "./Common.qs" ] }) @[exercise]({ "id": "oracles__or_but_kth_oracle", "title": "Implement the OR Oracle of All Bits Except the K-th", - "descriptionPath": "./or_but_kth_oracle/index.md", - "placeholderSourcePath": "./or_but_kth_oracle/placeholder.qs", - "solutionPath": "./or_but_kth_oracle/solution.md", - "codePaths": [ + "path": "./or_but_kth_oracle/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs", - "./or_but_kth_oracle/verification.qs" + "./Common.qs" ] }) @[exercise]({ "id": "oracles__bit_pattern_oracle", "title": "Implement the Arbitrary Bit Pattern Oracle", - "descriptionPath": "./bit_pattern_oracle/index.md", - "placeholderSourcePath": "./bit_pattern_oracle/placeholder.qs", - "solutionPath": "./bit_pattern_oracle/solution.md", - "codePaths": [ + "path": "./bit_pattern_oracle/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs", - "./bit_pattern_oracle/verification.qs" + "./Common.qs" ] }) @[exercise]({ "id": "oracles__bit_pattern_challenge", "title": "Implement the Arbitrary Bit Pattern Oracle (Challenge Version)", - "descriptionPath": "./bit_pattern_challenge/index.md", - "placeholderSourcePath": "./bit_pattern_challenge/placeholder.qs", - "solutionPath": "./bit_pattern_challenge/solution.md", - "codePaths": [ + "path": "./bit_pattern_challenge/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs", - "./bit_pattern_challenge/verification.qs" + "./Common.qs" ] }) @[exercise]({ "id": "oracles__meeting_oracle", "title": "Implement the Meeting Oracle", - "descriptionPath": "./meeting_oracle/index.md", - "placeholderSourcePath": "./meeting_oracle/placeholder.qs", - "solutionPath": "./meeting_oracle/solution.md", - "codePaths": [ + "path": "./meeting_oracle/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs", - "./meeting_oracle/verification.qs" + "./Common.qs" ] }) @@ -380,15 +351,15 @@ In this section you will implement a few more complicated quantum oracles. "title": "Testing an Oracle Implementation" }) -In this demo we show how you could test an oracle that you've implemented for your own problem. -For all of the previous oracles that you've implemented, we've been testing your oracle against a reference solution for that task. +In this demo we show how you could test an oracle that you've implemented for your own problem. +For all of the previous oracles that you've implemented, we've been testing your oracle against a reference solution for that task. However, 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! 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. Here we will compare the reference implementation of `Meeting_Oracle` to the classical code implementing the same function. -@[example]({"id": "oracles__test_meeting_oracle", "codePath": "./test_meeting_oracle.qs"}) +@[example]({"id": "oracles__test_meeting_oracle", "codePath": "./TestMeetingOracle.qs"}) @[section]({ "id": "oracles__conclusion", @@ -396,12 +367,14 @@ Here we will compare the reference implementation of `Meeting_Oracle` to the cla }) Congratulations! In this kata you have learned to build quantum oracles. Here are a few key concepts to keep in mind: -* A quantum oracle is an "opaque box" operation that is used as input to another algorithm. -* Phase oracles encode the information in the relative phase of basis states. If $f(x)=0$, the oracle doesn't change the basis state $\ket{x}$, and if $f(x)=1$ it multiplies the phase of the basis state $\ket{x}$ by $-1$. -* Marking oracles use an extra qubit $\ket{y}$ and encode the information in the state of that qubit. If $f(x)=0$, it doen't change the state of the qubit $\ket{y}$ for the basis state $\ket{x}$, and if $f(x)=1$ it flips the state of the qubit $\ket{y}$ for the basis state $\ket{x}$. + +- A quantum oracle is an "opaque box" operation that is used as input to another algorithm. +- Phase oracles encode the information in the relative phase of basis states. If $f(x)=0$, the oracle doesn't change the basis state $\ket{x}$, and if $f(x)=1$ it multiplies the phase of the basis state $\ket{x}$ by $-1$. +- Marking oracles use an extra qubit $\ket{y}$ and encode the information in the state of that qubit. If $f(x)=0$, it doen't change the state of the qubit $\ket{y}$ for the basis state $\ket{x}$, and if $f(x)=1$ it flips the state of the qubit $\ket{y}$ for the basis state $\ket{x}$. **Next Steps** We hope you enjoyed this kata! If you're looking to learn more about quantum oracles and Q#, here are some suggestions: -* To learn about the Grover's algorithm, you can check Microsoft Learn module "Solve graph coloring problems by using Grover's search". -* To learn more about the Q# libraries, you can check the The Q# user guide. + +- To learn about the Grover's algorithm, you can check Microsoft Learn module "Solve graph coloring problems by using Grover's search". +- To learn more about the Q# libraries, you can check the The Q# user guide. diff --git a/katas/content/oracles/kth_bit_oracle/placeholder.qs b/katas/content/oracles/kth_bit_oracle/Placeholder.qs similarity index 100% rename from katas/content/oracles/kth_bit_oracle/placeholder.qs rename to katas/content/oracles/kth_bit_oracle/Placeholder.qs diff --git a/katas/content/oracles/kth_bit_oracle/solution.qs b/katas/content/oracles/kth_bit_oracle/Solution.qs similarity index 100% rename from katas/content/oracles/kth_bit_oracle/solution.qs rename to katas/content/oracles/kth_bit_oracle/Solution.qs diff --git a/katas/content/oracles/kth_bit_oracle/verification.qs b/katas/content/oracles/kth_bit_oracle/Verification.qs similarity index 100% rename from katas/content/oracles/kth_bit_oracle/verification.qs rename to katas/content/oracles/kth_bit_oracle/Verification.qs diff --git a/katas/content/oracles/kth_bit_oracle/solution.md b/katas/content/oracles/kth_bit_oracle/solution.md index cf790c4029..bdf4ae1fb0 100644 --- a/katas/content/oracles/kth_bit_oracle/solution.md +++ b/katas/content/oracles/kth_bit_oracle/solution.md @@ -1,6 +1,6 @@ @[solution]({ "id": "oracles__kth_bit_oracle_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) Notice how the oracles - both phase and marking - can take extra "classical" parameters. diff --git a/katas/content/oracles/marking_oracle_as_phase/placeholder.qs b/katas/content/oracles/marking_oracle_as_phase/Placeholder.qs similarity index 100% rename from katas/content/oracles/marking_oracle_as_phase/placeholder.qs rename to katas/content/oracles/marking_oracle_as_phase/Placeholder.qs diff --git a/katas/content/oracles/marking_oracle_as_phase/solution.qs b/katas/content/oracles/marking_oracle_as_phase/Solution.qs similarity index 100% rename from katas/content/oracles/marking_oracle_as_phase/solution.qs rename to katas/content/oracles/marking_oracle_as_phase/Solution.qs diff --git a/katas/content/oracles/marking_oracle_as_phase/verification.qs b/katas/content/oracles/marking_oracle_as_phase/Verification.qs similarity index 100% rename from katas/content/oracles/marking_oracle_as_phase/verification.qs rename to katas/content/oracles/marking_oracle_as_phase/Verification.qs diff --git a/katas/content/oracles/marking_oracle_as_phase/solution.md b/katas/content/oracles/marking_oracle_as_phase/solution.md index aa0d79d9b2..881bcd581b 100644 --- a/katas/content/oracles/marking_oracle_as_phase/solution.md +++ b/katas/content/oracles/marking_oracle_as_phase/solution.md @@ -1,4 +1,4 @@ @[solution]({ "id": "oracles__marking_oracle_as_phase_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/oracles/marking_oracle_seven/placeholder.qs b/katas/content/oracles/marking_oracle_seven/Placeholder.qs similarity index 100% rename from katas/content/oracles/marking_oracle_seven/placeholder.qs rename to katas/content/oracles/marking_oracle_seven/Placeholder.qs diff --git a/katas/content/oracles/marking_oracle_seven/solution.qs b/katas/content/oracles/marking_oracle_seven/Solution.qs similarity index 100% rename from katas/content/oracles/marking_oracle_seven/solution.qs rename to katas/content/oracles/marking_oracle_seven/Solution.qs diff --git a/katas/content/oracles/marking_oracle_seven/verification.qs b/katas/content/oracles/marking_oracle_seven/Verification.qs similarity index 100% rename from katas/content/oracles/marking_oracle_seven/verification.qs rename to katas/content/oracles/marking_oracle_seven/Verification.qs diff --git a/katas/content/oracles/marking_oracle_seven/solution.md b/katas/content/oracles/marking_oracle_seven/solution.md index ba98965484..abd01f6465 100644 --- a/katas/content/oracles/marking_oracle_seven/solution.md +++ b/katas/content/oracles/marking_oracle_seven/solution.md @@ -1,6 +1,6 @@ @[solution]({ "id": "oracles__marking_oracle_seven_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) Consider how the oracle from this exercise acts on two input basis states and two "output" basis states: diff --git a/katas/content/oracles/meeting_oracle/placeholder.qs b/katas/content/oracles/meeting_oracle/Placeholder.qs similarity index 100% rename from katas/content/oracles/meeting_oracle/placeholder.qs rename to katas/content/oracles/meeting_oracle/Placeholder.qs diff --git a/katas/content/oracles/meeting_oracle/solution.qs b/katas/content/oracles/meeting_oracle/Solution.qs similarity index 100% rename from katas/content/oracles/meeting_oracle/solution.qs rename to katas/content/oracles/meeting_oracle/Solution.qs diff --git a/katas/content/oracles/meeting_oracle/verification.qs b/katas/content/oracles/meeting_oracle/Verification.qs similarity index 100% rename from katas/content/oracles/meeting_oracle/verification.qs rename to katas/content/oracles/meeting_oracle/Verification.qs diff --git a/katas/content/oracles/meeting_oracle/solution.md b/katas/content/oracles/meeting_oracle/solution.md index b327ea36db..6955a386f9 100644 --- a/katas/content/oracles/meeting_oracle/solution.md +++ b/katas/content/oracles/meeting_oracle/solution.md @@ -1,4 +1,4 @@ @[solution]({ "id": "oracles__meeting_oracle_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/oracles/or_but_kth_oracle/placeholder.qs b/katas/content/oracles/or_but_kth_oracle/Placeholder.qs similarity index 100% rename from katas/content/oracles/or_but_kth_oracle/placeholder.qs rename to katas/content/oracles/or_but_kth_oracle/Placeholder.qs diff --git a/katas/content/oracles/or_but_kth_oracle/solution.qs b/katas/content/oracles/or_but_kth_oracle/Solution.qs similarity index 100% rename from katas/content/oracles/or_but_kth_oracle/solution.qs rename to katas/content/oracles/or_but_kth_oracle/Solution.qs diff --git a/katas/content/oracles/or_but_kth_oracle/verification.qs b/katas/content/oracles/or_but_kth_oracle/Verification.qs similarity index 100% rename from katas/content/oracles/or_but_kth_oracle/verification.qs rename to katas/content/oracles/or_but_kth_oracle/Verification.qs diff --git a/katas/content/oracles/or_but_kth_oracle/solution.md b/katas/content/oracles/or_but_kth_oracle/solution.md index ad8b90ba84..6405bacb06 100644 --- a/katas/content/oracles/or_but_kth_oracle/solution.md +++ b/katas/content/oracles/or_but_kth_oracle/solution.md @@ -1,4 +1,4 @@ @[solution]({ "id": "oracles__or_but_kth_oracle_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/oracles/or_oracle/placeholder.qs b/katas/content/oracles/or_oracle/Placeholder.qs similarity index 100% rename from katas/content/oracles/or_oracle/placeholder.qs rename to katas/content/oracles/or_oracle/Placeholder.qs diff --git a/katas/content/oracles/or_oracle/solution.qs b/katas/content/oracles/or_oracle/Solution.qs similarity index 100% rename from katas/content/oracles/or_oracle/solution.qs rename to katas/content/oracles/or_oracle/Solution.qs diff --git a/katas/content/oracles/or_oracle/verification.qs b/katas/content/oracles/or_oracle/Verification.qs similarity index 100% rename from katas/content/oracles/or_oracle/verification.qs rename to katas/content/oracles/or_oracle/Verification.qs diff --git a/katas/content/oracles/or_oracle/solution.md b/katas/content/oracles/or_oracle/solution.md index 8f154b072c..4420f08518 100644 --- a/katas/content/oracles/or_oracle/solution.md +++ b/katas/content/oracles/or_oracle/solution.md @@ -1,6 +1,6 @@ @[solution]({ "id": "oracles__or_oracle_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) Notice 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. diff --git a/katas/content/oracles/phase_oracle_seven/placeholder.qs b/katas/content/oracles/phase_oracle_seven/Placeholder.qs similarity index 100% rename from katas/content/oracles/phase_oracle_seven/placeholder.qs rename to katas/content/oracles/phase_oracle_seven/Placeholder.qs diff --git a/katas/content/oracles/phase_oracle_seven/solution.qs b/katas/content/oracles/phase_oracle_seven/Solution.qs similarity index 100% rename from katas/content/oracles/phase_oracle_seven/solution.qs rename to katas/content/oracles/phase_oracle_seven/Solution.qs diff --git a/katas/content/oracles/phase_oracle_seven/verification.qs b/katas/content/oracles/phase_oracle_seven/Verification.qs similarity index 100% rename from katas/content/oracles/phase_oracle_seven/verification.qs rename to katas/content/oracles/phase_oracle_seven/Verification.qs diff --git a/katas/content/oracles/phase_oracle_seven/solution.md b/katas/content/oracles/phase_oracle_seven/solution.md index 2171be5f21..dae0d2224d 100644 --- a/katas/content/oracles/phase_oracle_seven/solution.md +++ b/katas/content/oracles/phase_oracle_seven/solution.md @@ -1,6 +1,6 @@ @[solution]({ "id": "oracles__phase_oracle_seven_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) Consider how the oracle acts on two basis states: diff --git a/katas/content/qubit/index.md b/katas/content/qubit/index.md index 71274a7231..69bab8b44b 100644 --- a/katas/content/qubit/index.md +++ b/katas/content/qubit/index.md @@ -129,7 +129,6 @@ Several ket symbols have a generally accepted use, so you will see them often: We will learn more about Dirac notation in the next katas, as we introduce quantum gates and multi-qubit systems. - @[section]({ "id": "qubit__relative_and_global_phase", "title": "Relative and Global Phase" @@ -138,7 +137,7 @@ We will learn more about Dirac notation in the next katas, as we introduce quant 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 = \atan2(y, x)$. > `atan2` is a useful function available in most programming languages. It takes two arguments and returns an angle $\theta$ -> between $-\pi$ and $\pi$ that has $\cos \theta = x$ and $\sin \theta = y$. Unlike using $\tan^{-1}(\frac{y}{x})$, `atan2` computes +> between $-\pi$ and $\pi$ that has $\cos \theta = x$ and $\sin \theta = y$. Unlike using $\tan^{-1}(\frac{y}{x})$, `atan2` computes > the correct quadrant for the angle, since it preserves information about the signs of both sine and cosine of the angle. 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 the phase of $|0\rangle$ is $\atan2(\frac12, \frac12) = \frac{\pi}{4}$, and the phase of $|1\rangle$ is $\atan2(\frac12, -\frac12) = -\frac{\pi}{4}$. The difference between these two phases is known as **relative phase**. @@ -166,15 +165,15 @@ Before we continue, let's learn some techniques to visualize the quantum state o ### Display the Quantum State of a Single-Qubit Program -Let's start with a simple scenario: a program that acts on a single qubit. +Let's start with a simple scenario: a program that acts on a single qubit. The state of the quantum system used by this program can be represented as a complex vector of length 2, or, using Dirac notation, $$\begin{bmatrix} \alpha \\\ \beta \end{bmatrix} = \alpha|0\rangle + \beta|1\rangle$$ -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. +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. You 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$. -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. +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. You 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! The `DumpMachine` function from the `Microsoft.Quantum.Diagnostics` namespace 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. @@ -222,23 +221,20 @@ For example, the state $|0\rangle$ would be represented as follows: @[exercise]({ "id": "qubit__learn_single_qubit_state", "title": "Learn the State of a Single Qubit Using DumpMachine", - "descriptionPath": "./learn_single_qubit_state/index.md", - "codePaths": [ - "../KatasLibrary.qs", - "./learn_single_qubit_state/Verification.qs" - ], - "placeholderSourcePath": "./learn_single_qubit_state/Placeholder.qs", - "solutionPath": "./learn_single_qubit_state/solution.md" + "path": "./learn_single_qubit_state/", + "qsDependencies": [ + "../KatasLibrary.qs" + ] }) - @[section]({ "id": "qubit__conclusion", "title": "Conclusion" }) Congratulations! In this kata you learned the basics of qubits and qubit states. Here are a few key concepts to keep in mind: -* A qubit is a basic unit of quantum information, analogous to a bit in classical computing. -* 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. -* 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. -* 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. + +- A qubit is a basic unit of quantum information, analogous to a bit in classical computing. +- 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. +- 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. +- 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. diff --git a/katas/content/random_numbers/common.qs b/katas/content/random_numbers/Common.qs similarity index 100% rename from katas/content/random_numbers/common.qs rename to katas/content/random_numbers/Common.qs diff --git a/katas/content/random_numbers/index.md b/katas/content/random_numbers/index.md index f3fe9b9318..ab7d4d1a3f 100644 --- a/katas/content/random_numbers/index.md +++ b/katas/content/random_numbers/index.md @@ -2,7 +2,7 @@ @[section]({"id": "random_numbers__overview", "title": "Overview"}) -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 here. +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 here. 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. @@ -32,78 +32,64 @@ This knowledge is sufficient to implement a simple random number generator! @[exercise]({ "id": "random_numbers__random_bit", "title": "Generate a Single Random Bit", - "descriptionPath": "./random_bit/index.md", - "placeholderSourcePath": "./random_bit/placeholder.qs", - "solutionPath": "./random_bit/solution.md", - "codePaths": [ - "./random_bit/verification.qs", + "path": "./random_bit/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs" + "./Common.qs" ] }) @[exercise]({ "id": "random_numbers__random_two_bits", "title": "Generate a Random Two-Bit Number", - "descriptionPath": "./random_two_bits/index.md", - "placeholderSourcePath": "./random_two_bits/placeholder.qs", - "solutionPath": "./random_two_bits/solution.md", - "codePaths": [ - "./random_two_bits/verification.qs", + "path": "./random_two_bits/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs" + "./Common.qs" ] }) @[exercise]({ "id": "random_numbers__random_n_bits", "title": "Generate a Number of Arbitrary Size", - "descriptionPath": "./random_n_bits/index.md", - "placeholderSourcePath": "./random_n_bits/placeholder.qs", - "solutionPath": "./random_n_bits/solution.md", - "codePaths": [ - "./random_n_bits/verification.qs", + "path": "./random_n_bits/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs" + "./Common.qs" ] }) @[exercise]({ "id": "random_numbers__weighted_random_bit", "title": "Generate a Weighted Bit", - "descriptionPath": "./weighted_random_bit/index.md", - "placeholderSourcePath": "./weighted_random_bit/placeholder.qs", - "solutionPath": "./weighted_random_bit/solution.md", - "codePaths": [ - "./weighted_random_bit/verification.qs", + "path": "./weighted_random_bit/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs" + "./Common.qs" ] }) @[exercise]({ "id": "random_numbers__random_number", "title": "Generate a Random Number Between Min and Max", - "descriptionPath": "./random_number/index.md", - "placeholderSourcePath": "./random_number/placeholder.qs", - "solutionPath": "./random_number/solution.md", - "codePaths": [ - "./random_number/verification.qs", + "path": "./random_number/", + "qsDependencies": [ "../KatasLibrary.qs", - "./common.qs" + "./Common.qs" ] }) @[section]({"id": "random_numbers__whats_next", "title": "What's Next?"}) Congratulations! In this kata you have created a random number generator. Here are a few key concepts to keep in mind: -* This code will generate truly random numbers when executed on a true quantum computer. Random numbers obtained when executing on a simulator are only as good as the source of randomness used by the simulator. -* 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. -* The Q# BitSizeI function returns the number of bits needed to write an integer in binary. + +- This code will generate truly random numbers when executed on a true quantum computer. Random numbers obtained when executing on a simulator are only as good as the source of randomness used by the simulator. +- 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. +- The Q# BitSizeI function returns the number of bits needed to write an integer in binary. **Next Steps** 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: -* To learn about superposition, interference and entanglement by using Q#, you can check the Microsoft Learn module "Explore the key concepts of quantum computing by using Q#". -* For another look at quantum random number generation, you can check out the Microsoft Learn module "Create your first Q# program by using the Quantum Development Kit". +- To learn about superposition, interference and entanglement by using Q#, you can check the Microsoft Learn module "Explore the key concepts of quantum computing by using Q#". +- For another look at quantum random number generation, you can check out the Microsoft Learn module "Create your first Q# program by using the Quantum Development Kit". diff --git a/katas/content/random_numbers/random_bit/placeholder.qs b/katas/content/random_numbers/random_bit/Placeholder.qs similarity index 100% rename from katas/content/random_numbers/random_bit/placeholder.qs rename to katas/content/random_numbers/random_bit/Placeholder.qs diff --git a/katas/content/random_numbers/random_bit/solution.qs b/katas/content/random_numbers/random_bit/Solution.qs similarity index 100% rename from katas/content/random_numbers/random_bit/solution.qs rename to katas/content/random_numbers/random_bit/Solution.qs diff --git a/katas/content/random_numbers/random_bit/verification.qs b/katas/content/random_numbers/random_bit/Verification.qs similarity index 100% rename from katas/content/random_numbers/random_bit/verification.qs rename to katas/content/random_numbers/random_bit/Verification.qs diff --git a/katas/content/random_numbers/random_bit/solution.md b/katas/content/random_numbers/random_bit/solution.md index cff2a472ff..6f875fbba3 100644 --- a/katas/content/random_numbers/random_bit/solution.md +++ b/katas/content/random_numbers/random_bit/solution.md @@ -19,5 +19,5 @@ Now, both 0 and 1 measurement outcomes occur with equal probablity of $|\frac{1} @[solution]({ "id": "random_numbers__random_bit_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/random_numbers/random_n_bits/placeholder.qs b/katas/content/random_numbers/random_n_bits/Placeholder.qs similarity index 100% rename from katas/content/random_numbers/random_n_bits/placeholder.qs rename to katas/content/random_numbers/random_n_bits/Placeholder.qs diff --git a/katas/content/random_numbers/random_n_bits/solution.qs b/katas/content/random_numbers/random_n_bits/Solution.qs similarity index 100% rename from katas/content/random_numbers/random_n_bits/solution.qs rename to katas/content/random_numbers/random_n_bits/Solution.qs diff --git a/katas/content/random_numbers/random_n_bits/verification.qs b/katas/content/random_numbers/random_n_bits/Verification.qs similarity index 100% rename from katas/content/random_numbers/random_n_bits/verification.qs rename to katas/content/random_numbers/random_n_bits/Verification.qs diff --git a/katas/content/random_numbers/random_n_bits/solution.md b/katas/content/random_numbers/random_n_bits/solution.md index ffa0e26d82..86709c716c 100644 --- a/katas/content/random_numbers/random_n_bits/solution.md +++ b/katas/content/random_numbers/random_n_bits/solution.md @@ -4,5 +4,5 @@ Since the maximum value of the number written with N bits is $2^N - 1$, we don't @[solution]({ "id": "random_numbers__random_n_bits_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/random_numbers/random_number/placeholder.qs b/katas/content/random_numbers/random_number/Placeholder.qs similarity index 100% rename from katas/content/random_numbers/random_number/placeholder.qs rename to katas/content/random_numbers/random_number/Placeholder.qs diff --git a/katas/content/random_numbers/random_number/solution.qs b/katas/content/random_numbers/random_number/Solution.qs similarity index 100% rename from katas/content/random_numbers/random_number/solution.qs rename to katas/content/random_numbers/random_number/Solution.qs diff --git a/katas/content/random_numbers/random_number/verification.qs b/katas/content/random_numbers/random_number/Verification.qs similarity index 100% rename from katas/content/random_numbers/random_number/verification.qs rename to katas/content/random_numbers/random_number/Verification.qs diff --git a/katas/content/random_numbers/random_number/solution.md b/katas/content/random_numbers/random_number/solution.md index e005b0c7fc..5ad530e74b 100644 --- a/katas/content/random_numbers/random_number/solution.md +++ b/katas/content/random_numbers/random_number/solution.md @@ -4,5 +4,5 @@ We'll generate an $N$-bit random number by calling the `RandomNBits` operation, @[solution]({ "id": "random_numbers__random_number_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/random_numbers/random_two_bits/placeholder.qs b/katas/content/random_numbers/random_two_bits/Placeholder.qs similarity index 100% rename from katas/content/random_numbers/random_two_bits/placeholder.qs rename to katas/content/random_numbers/random_two_bits/Placeholder.qs diff --git a/katas/content/random_numbers/random_two_bits/solution.qs b/katas/content/random_numbers/random_two_bits/Solution.qs similarity index 100% rename from katas/content/random_numbers/random_two_bits/solution.qs rename to katas/content/random_numbers/random_two_bits/Solution.qs diff --git a/katas/content/random_numbers/random_two_bits/verification.qs b/katas/content/random_numbers/random_two_bits/Verification.qs similarity index 100% rename from katas/content/random_numbers/random_two_bits/verification.qs rename to katas/content/random_numbers/random_two_bits/Verification.qs diff --git a/katas/content/random_numbers/random_two_bits/solution.md b/katas/content/random_numbers/random_two_bits/solution.md index 74d1047569..e57bb2150e 100644 --- a/katas/content/random_numbers/random_two_bits/solution.md +++ b/katas/content/random_numbers/random_two_bits/solution.md @@ -3,5 +3,5 @@ We can generate two random bits by calling the `RandomBit` operation twice, mult @[solution]({ "id": "random_numbers__random_two_bits_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/random_numbers/weighted_random_bit/placeholder.qs b/katas/content/random_numbers/weighted_random_bit/Placeholder.qs similarity index 100% rename from katas/content/random_numbers/weighted_random_bit/placeholder.qs rename to katas/content/random_numbers/weighted_random_bit/Placeholder.qs diff --git a/katas/content/random_numbers/weighted_random_bit/solution.qs b/katas/content/random_numbers/weighted_random_bit/Solution.qs similarity index 100% rename from katas/content/random_numbers/weighted_random_bit/solution.qs rename to katas/content/random_numbers/weighted_random_bit/Solution.qs diff --git a/katas/content/random_numbers/weighted_random_bit/verification.qs b/katas/content/random_numbers/weighted_random_bit/Verification.qs similarity index 100% rename from katas/content/random_numbers/weighted_random_bit/verification.qs rename to katas/content/random_numbers/weighted_random_bit/Verification.qs diff --git a/katas/content/random_numbers/weighted_random_bit/solution.md b/katas/content/random_numbers/weighted_random_bit/solution.md index c9bb29efc5..d42d884b45 100644 --- a/katas/content/random_numbers/weighted_random_bit/solution.md +++ b/katas/content/random_numbers/weighted_random_bit/solution.md @@ -28,5 +28,5 @@ The `Ry` operation applies a given rotation about the $Y$-axis (i.e., in the $ZX @[solution]({ "id": "random_numbers__weighted_random_bit_solution", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/single_qubit_gates/index.md b/katas/content/single_qubit_gates/index.md index e411933613..e7745931f3 100644 --- a/katas/content/single_qubit_gates/index.md +++ b/katas/content/single_qubit_gates/index.md @@ -27,7 +27,7 @@ There are certain properties common to all quantum gates. This section will intr ## Matrix Representation -Quantum gates are represented as $2^N \times 2^N$ unitary matrices, where $N$ is the number of qubits the gate operates on. +Quantum gates are represented as $2^N \times 2^N$ unitary matrices, where $N$ is the number of qubits the gate operates on. As a quick reminder, a unitary matrix is a square matrix whose inverse is its adjoint, thus $U^* U = UU^* = UU^{-1} = \mathbb{I}$. Single-qubit gates are represented by $2 \times 2$ matrices. Our example for this section, the $X$ gate, is represented by the following matrix: @@ -68,14 +68,14 @@ $$ 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. -Applying several quantum gates in sequence is equivalent to performing several of these multiplications. -For 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). +Applying several quantum gates in sequence is equivalent to performing several of these multiplications. +For 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). Matrix 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$. >Note that matrix multiplication isn’t commutative, thus $(BA) \neq \(AB)$. -All quantum gates are reversible - there is another gate which will undo any given gate's transformation, returning the qubit to its original state. -This 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. +All quantum gates are reversible - there is another gate which will undo any given gate's transformation, returning the qubit to its original state. +This 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. Quantum gates are represented by unitary matrices, so the inverse of a gate is its adjoint; these terms are also used interchangeably in quantum computing. ## Effects on Basis States @@ -183,7 +183,7 @@ $$X|0\rangle = \big(|0\rangle\langle1| + |1\rangle\langle0|\big)|0\rangle = |0\r > > Two vectors are orthogonal to each other if their inner product equals $0$. This means that $\langle0|1\rangle = \langle 1|0\rangle = 0$. -In general case, a matrix +In general case, a matrix $$A = \begin{bmatrix} a_{00} & a_{01} \\\ a_{10} & a_{11} \end{bmatrix}$$ will have the following ket-bra representation: $$A = a_{00} |0\rangle\langle0| + a_{01} |0\rangle\langle1| + a_{10} |1\rangle\langle0| + a_{11} |1\rangle\langle1|$$ @@ -298,10 +298,10 @@ The Pauli gates, named after @[exercise]({ "id": "single_qubit_gates__prepare_minus", "title": "Prepare Minus", - "descriptionPath": "./prepare_minus/index.md", - "codePaths": [ - "../KatasLibrary.qs", - "./prepare_minus/Verification.qs" - ], - "placeholderSourcePath": "./prepare_minus/Placeholder.qs", - "solutionPath": "./prepare_minus/solution.md" + "path": "./prepare_minus/", + "qsDependencies": [ + "../KatasLibrary.qs" + ] }) @[section]({ @@ -469,19 +457,16 @@ The next two gates are known as phase shift gates. They apply a phase to the $|1 -> 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: +> 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: $$T^2 = S, S^2 = Z$$ @[exercise]({ "id": "single_qubit_gates__three_quarters_pi_phase", "title": "Three-Fourths Phase", - "descriptionPath": "./three_quarters_pi_phase/index.md", - "codePaths": [ - "../KatasLibrary.qs", - "./three_quarters_pi_phase/Verification.qs" - ], - "placeholderSourcePath": "./three_quarters_pi_phase/Placeholder.qs", - "solutionPath": "./three_quarters_pi_phase/solution.md" + "path": "./three_quarters_pi_phase/", + "qsDependencies": [ + "../KatasLibrary.qs" + ] }) @[section]({ @@ -489,11 +474,11 @@ $$T^2 = S, S^2 = Z$$ "title": "Rotation Gates" }) -The next few gates are parametrized: their exact behavior depends on a numeric parameter - an angle $\theta$, given in radians. -These 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)$. +The next few gates are parametrized: their exact behavior depends on a numeric parameter - an angle $\theta$, given in radians. +These 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)$. Note that for the first three gates the parameter $\theta$ is multiplied by $\frac{1}{2}$ within the gate's matrix. -> 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. +> 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. > 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. > If you are curious about it, you can learn more in this Wikipedia article. @@ -550,36 +535,30 @@ You have already encountered some special cases of the $R_1$ gate: $$T = R_1(\frac{\pi}{4}), S = R_1(\frac{\pi}{2}), Z = R_1(\pi)$$ -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: +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: $$R_1(\theta) = e^{i\theta/2}R_z(\theta)$$ -In addition, the rotation gates are very closely related to their respective Pauli gates: +In addition, the rotation gates are very closely related to their respective Pauli gates: $$X = iR_x(\pi), Y = iR_y(\pi), Z = iR_z(\pi)$$ @[exercise]({ "id": "single_qubit_gates__prepare_rotated_state", "title": "Prepare Rotated State", - "descriptionPath": "./prepare_rotated_state/index.md", - "codePaths": [ - "../KatasLibrary.qs", - "./prepare_rotated_state/Verification.qs" - ], - "placeholderSourcePath": "./prepare_rotated_state/Placeholder.qs", - "solutionPath": "./prepare_rotated_state/solution.md" + "path": "./prepare_rotated_state/", + "qsDependencies": [ + "../KatasLibrary.qs" + ] }) @[exercise]({ "id": "single_qubit_gates__prepare_arbitrary_state", "title": "Prepare Arbitrary State", - "descriptionPath": "./prepare_arbitrary_state/index.md", - "codePaths": [ - "../KatasLibrary.qs", - "./prepare_arbitrary_state/Verification.qs" - ], - "placeholderSourcePath": "./prepare_arbitrary_state/Placeholder.qs", - "solutionPath": "./prepare_arbitrary_state/solution.md" + "path": "./prepare_arbitrary_state/", + "qsDependencies": [ + "../KatasLibrary.qs" + ] }) @[section]({ @@ -588,10 +567,11 @@ $$X = iR_x(\pi), Y = iR_y(\pi), Z = iR_z(\pi)$$ }) 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: -* Single-qubit gates act on individual qubits and are represented by $2 \times 2$ unitary matrices. -* The effect of a gate applied to a qubit can be calculated by multiplying the corresponding matrix by the state vector of the qubit. -* Applying several quantum gates in sequence is equivalent to performing several matrix multiplications. -* Any square matrix can be represented as a linear combination of the outer products of vectors. The outer product is the matrix product of $|\phi\rangle$ and $\langle\psi|$, denoted as $|\phi\rangle\langle\psi|$. -* Pauli gates, identity and Hadamard gates, phase shift gates, and rotation gates are examples of single-qubit gates. All of them are available in Q#. + +- Single-qubit gates act on individual qubits and are represented by $2 \times 2$ unitary matrices. +- The effect of a gate applied to a qubit can be calculated by multiplying the corresponding matrix by the state vector of the qubit. +- Applying several quantum gates in sequence is equivalent to performing several matrix multiplications. +- Any square matrix can be represented as a linear combination of the outer products of vectors. The outer product is the matrix product of $|\phi\rangle$ and $\langle\psi|$, denoted as $|\phi\rangle\langle\psi|$. +- Pauli gates, identity and Hadamard gates, phase shift gates, and rotation gates are examples of single-qubit gates. All of them are available in Q#. Next, you will learn about multi-qubit systems in the “Multi-Qubit Systems” kata. diff --git a/katas/content/single_qubit_measurements/common.qs b/katas/content/single_qubit_measurements/Common.qs similarity index 100% rename from katas/content/single_qubit_measurements/common.qs rename to katas/content/single_qubit_measurements/Common.qs diff --git a/katas/content/single_qubit_measurements/a_b_basis_measurements/placeholder.qs b/katas/content/single_qubit_measurements/a_b_basis_measurements/Placeholder.qs similarity index 100% rename from katas/content/single_qubit_measurements/a_b_basis_measurements/placeholder.qs rename to katas/content/single_qubit_measurements/a_b_basis_measurements/Placeholder.qs diff --git a/katas/content/single_qubit_measurements/a_b_basis_measurements/solution.qs b/katas/content/single_qubit_measurements/a_b_basis_measurements/Solution.qs similarity index 100% rename from katas/content/single_qubit_measurements/a_b_basis_measurements/solution.qs rename to katas/content/single_qubit_measurements/a_b_basis_measurements/Solution.qs diff --git a/katas/content/single_qubit_measurements/a_b_basis_measurements/verification.qs b/katas/content/single_qubit_measurements/a_b_basis_measurements/Verification.qs similarity index 100% rename from katas/content/single_qubit_measurements/a_b_basis_measurements/verification.qs rename to katas/content/single_qubit_measurements/a_b_basis_measurements/Verification.qs diff --git a/katas/content/single_qubit_measurements/a_b_basis_measurements/solution.md b/katas/content/single_qubit_measurements/a_b_basis_measurements/solution.md index 0ea30e767a..8a95bb25c3 100644 --- a/katas/content/single_qubit_measurements/a_b_basis_measurements/solution.md +++ b/katas/content/single_qubit_measurements/a_b_basis_measurements/solution.md @@ -11,5 +11,5 @@ The final rotation ensures that the state of the qubit is in the state correspon @[solution]({ "id": "single_qubit_measurements__a_b_basis_measurements_solution", "exerciseId": "a_b_basis_measurements", - "codePath": "solution.qs" + "codePath": "Solution.qs" }) diff --git a/katas/content/single_qubit_measurements/distinguish_0_and_1/placeholder.qs b/katas/content/single_qubit_measurements/distinguish_0_and_1/Placeholder.qs similarity index 100% rename from katas/content/single_qubit_measurements/distinguish_0_and_1/placeholder.qs rename to katas/content/single_qubit_measurements/distinguish_0_and_1/Placeholder.qs diff --git a/katas/content/single_qubit_measurements/distinguish_0_and_1/solution.qs b/katas/content/single_qubit_measurements/distinguish_0_and_1/Solution.qs similarity index 100% rename from katas/content/single_qubit_measurements/distinguish_0_and_1/solution.qs rename to katas/content/single_qubit_measurements/distinguish_0_and_1/Solution.qs diff --git a/katas/content/single_qubit_measurements/distinguish_0_and_1/verification.qs b/katas/content/single_qubit_measurements/distinguish_0_and_1/Verification.qs similarity index 100% rename from katas/content/single_qubit_measurements/distinguish_0_and_1/verification.qs rename to katas/content/single_qubit_measurements/distinguish_0_and_1/Verification.qs diff --git a/katas/content/single_qubit_measurements/distinguish_0_and_1/solution.md b/katas/content/single_qubit_measurements/distinguish_0_and_1/solution.md index 132de40ed8..5770535151 100644 --- a/katas/content/single_qubit_measurements/distinguish_0_and_1/solution.md +++ b/katas/content/single_qubit_measurements/distinguish_0_and_1/solution.md @@ -5,5 +5,5 @@ In Q# the operation + + // Aggregate the exercise sources. The verification source file is Verification.qs and additional dependecies are + // explicitly listed as source code file paths in the qsDependencies property. + let resolvedVerificationFile = join(exercisePath, "Verification.qs"); + const resolvedDependencies = properties.qsDependencies.map((path) => join(kataPath, path), ); - const sourceIds = aggregateSources(resolvedCodePaths, globalCodeSources); + const resolvedSources = [resolvedVerificationFile].concat( + resolvedDependencies, + ); + const sourceIds = aggregateSources(resolvedSources, globalCodeSources); + + // Get the placeholder code from the Placeholder.qs file in the exercise folder. const placeholderCode = tryReadFile( - join(kataPath, properties.placeholderSourcePath), - `Could not read placeholder code for exercise '${properties.id}'`, + join(exercisePath, "Placeholder.qs"), + `Could not read Placeholder.qs file for exercise '${properties.id}'`, ); + + // Get the solution from the solution.md file in the exercise folder. const explainedSolution = createExplainedSolution( - join(kataPath, properties.solutionPath), + join(exercisePath, "solution.md"), ); return {