From 1ffcee7b420e01f3eebff6e9ac67cf8e13345b02 Mon Sep 17 00:00:00 2001 From: "Guan-Ming (Wesley) Chiu" <105915352+guan404ming@users.noreply.github.com> Date: Thu, 27 Nov 2025 00:38:20 +0800 Subject: [PATCH 01/10] Add Guan-Ming as PMC (#645) --- website/community/who-we-are.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/community/who-we-are.md b/website/community/who-we-are.md index 05575eed9..2311a78a6 100644 --- a/website/community/who-we-are.md +++ b/website/community/who-we-are.md @@ -28,7 +28,7 @@ Ellen Friedman | ellenf@... | No | @Ellen_Friedman Frank Scholten | frankscholten@... | No | Gokhan Capan | gcapan@... | No | Grant Ingersoll | gsingers@... | No | (Emeritus PMC) @gsingers -Guan-Ming (Wesley) Chiu | guanmingchiu@... | No | @guan404ming +Guan-Ming (Wesley) Chiu | guanmingchiu@... | Yes | @guan404ming Holden Karau | holden@... | No | Isabel Drost-Fromm | isabel@... | Yes | Jacob Alexander Mannix | jmannix@... | Yes | From f73bdcbb31e1f1a8f6528ebbbc4026ea91930e6b Mon Sep 17 00:00:00 2001 From: Ryan Huang Date: Sat, 29 Nov 2025 22:15:27 +0800 Subject: [PATCH 02/10] MAHOUT-652: Add mypy for static type checking and lock file checking (#654) * Add mypy for static type checking Added mypy static type checking to pre-commit hooks. * pre-commit hook: fix Signed-off-by: ryankert01 * update version and clean-up strings Signed-off-by: ryankert01 --------- Signed-off-by: ryankert01 --- .pre-commit-config.yaml | 7 +++++++ testing/utils/qumat_helpers.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 42d2e79c4..a3a888049 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,6 +22,13 @@ repos: name: ruff formatting files: \.py$ + # Static type checking + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.19.0 + hooks: + - id: mypy + args: ["--ignore-missing-imports"] + # Check Apache license headers - repo: https://github.com/lucas-c/pre-commit-hooks rev: v1.5.5 diff --git a/testing/utils/qumat_helpers.py b/testing/utils/qumat_helpers.py index 26337075a..d97311bc4 100644 --- a/testing/utils/qumat_helpers.py +++ b/testing/utils/qumat_helpers.py @@ -70,7 +70,7 @@ def create_np_computational_basis_state( def get_qumat_example_final_state_vector( - backend_config: dict, initial_state_ket_str: BinaryString = "000" + backend_config: dict, initial_state_ket_str: BinaryString = BinaryString("000") ): n_qubits = len(initial_state_ket_str) assert n_qubits == 3, print( From 20df75c4b5c06871dfd6990b60a829f386c3ec14 Mon Sep 17 00:00:00 2001 From: Navneet Date: Fri, 12 Dec 2025 07:15:14 +0530 Subject: [PATCH 03/10] docs: rename method to draw_circuit (#709) --- qumat/qumat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qumat/qumat.py b/qumat/qumat.py index a7b8390fc..c1d866de4 100644 --- a/qumat/qumat.py +++ b/qumat/qumat.py @@ -334,7 +334,7 @@ def get_final_state_vector(self): self.circuit, self.backend, self.backend_config ) - def draw(self): + def draw_circuit(self): """Visualize the quantum circuit. Generates a visual representation of the circuit. The output format From cf0bc0534ce4b383a4718a7fb3f2dea59354f8a6 Mon Sep 17 00:00:00 2001 From: Shivam Mittal Date: Fri, 12 Dec 2025 11:58:34 +0530 Subject: [PATCH 04/10] =?UTF-8?q?MAHOUT-681:=20Implement=20T-gate=20(?= =?UTF-8?q?=CF=80/8=20gate)=20across=20all=20backends=20(#693)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Implement T-gate (π/8 gate) across all backends - Add apply_t_gate() method to QuMat class with validation - Implement T-gate support in Qiskit, Cirq, and Amazon Braket backends - Restore T-gate documentation in basic_gates.md to match implementation Fixes #681 * Refine T-gate docs and add coverage * chore: satisfy pre-commit hooks --- docs/basic_gates.md | 2 +- qumat/amazon_braket_backend.py | 4 ++ qumat/cirq_backend.py | 5 ++ qumat/qiskit_backend.py | 5 ++ qumat/qumat.py | 15 ++++ testing/test_single_qubit_gates.py | 112 +++++++++++++++++++++++++++++ 6 files changed, 142 insertions(+), 1 deletion(-) diff --git a/docs/basic_gates.md b/docs/basic_gates.md index 6fe2533f0..e688c6906 100644 --- a/docs/basic_gates.md +++ b/docs/basic_gates.md @@ -40,7 +40,7 @@ The Pauli Z gate introduces a phase flip without changing the qubit's state. It It's used for measuring the phase of a qubit. -## T-Gate (π/8 Gate) (New Addition) +## T-Gate (π/8 Gate) The T-Gate applies a **π/4 phase shift** to the qubit. It is essential for quantum computing because it, along with the Hadamard and CNOT gates, allows for **universal quantum computation**. Mathematically: \[ T|0⟩ = |0⟩ \] diff --git a/qumat/amazon_braket_backend.py b/qumat/amazon_braket_backend.py index 0121c70be..a5e8c1bbe 100644 --- a/qumat/amazon_braket_backend.py +++ b/qumat/amazon_braket_backend.py @@ -81,6 +81,10 @@ def apply_pauli_z_gate(circuit, qubit_index): circuit.z(qubit_index) +def apply_t_gate(circuit, qubit_index): + circuit.t(qubit_index) + + def execute_circuit(circuit, backend, backend_config): shots = backend_config["backend_options"].get("shots", 1) parameter_values = backend_config.get("parameter_values", {}) diff --git a/qumat/cirq_backend.py b/qumat/cirq_backend.py index 674d9d4d4..dc09b0856 100644 --- a/qumat/cirq_backend.py +++ b/qumat/cirq_backend.py @@ -95,6 +95,11 @@ def apply_pauli_z_gate(circuit, qubit_index): circuit.append(cirq.Z(qubit)) +def apply_t_gate(circuit, qubit_index): + qubit = cirq.LineQubit(qubit_index) + circuit.append(cirq.T(qubit)) + + def execute_circuit(circuit, backend, backend_config): # handle 0-qubit circuits before adding measurements if not circuit.all_qubits(): diff --git a/qumat/qiskit_backend.py b/qumat/qiskit_backend.py index e7156eada..94b773b89 100644 --- a/qumat/qiskit_backend.py +++ b/qumat/qiskit_backend.py @@ -85,6 +85,11 @@ def apply_pauli_z_gate(circuit, qubit_index): circuit.z(qubit_index) +def apply_t_gate(circuit, qubit_index): + # Apply a T gate (π/8 gate) on the specified qubit + circuit.t(qubit_index) + + def execute_circuit(circuit, backend, backend_config): # Add measurements if they are not already present # Check if circuit already has measurement operations diff --git a/qumat/qumat.py b/qumat/qumat.py index c1d866de4..99791d8af 100644 --- a/qumat/qumat.py +++ b/qumat/qumat.py @@ -251,6 +251,21 @@ def apply_pauli_z_gate(self, qubit_index): self._validate_qubit_index(qubit_index) self.backend_module.apply_pauli_z_gate(self.circuit, qubit_index) + def apply_t_gate(self, qubit_index): + """Apply a T-gate (π/8 gate) to the specified qubit. + + Applies a relative pi/4 phase (multiplies the |1> state by e^{i*pi/4}). + Essential for universal quantum computation when combined with + Hadamard and CNOT gates. + + :param qubit_index: Index of the qubit. + :type qubit_index: int + :raises RuntimeError: If the circuit has not been initialized. + """ + self._ensure_circuit_initialized() + self._validate_qubit_index(qubit_index) + self.backend_module.apply_t_gate(self.circuit, qubit_index) + def execute_circuit(self, parameter_values=None): """Execute the quantum circuit and return the measurement results. diff --git a/testing/test_single_qubit_gates.py b/testing/test_single_qubit_gates.py index 9b66ab4da..af1e379ea 100644 --- a/testing/test_single_qubit_gates.py +++ b/testing/test_single_qubit_gates.py @@ -527,6 +527,118 @@ def test_pauli_z_with_hadamard(self, backend_name): ) +@pytest.mark.parametrize("backend_name", TESTING_BACKENDS) +class TestTGate: + """Test class for T gate functionality.""" + + @pytest.mark.parametrize( + "initial_state, expected_state", + [ + ("0", "0"), # T leaves |0> unchanged + ("1", "1"), # T applies phase to |1>, measurement unchanged + ], + ) + def test_t_gate_preserves_basis_states( + self, backend_name, initial_state, expected_state + ): + """T gate should preserve computational basis measurement outcomes.""" + backend_config = get_backend_config(backend_name) + qumat = QuMat(backend_config) + qumat.create_empty_circuit(num_qubits=1) + + if initial_state == "1": + qumat.apply_pauli_x_gate(0) + + qumat.apply_t_gate(0) + results = qumat.execute_circuit() + + prob = get_state_probability( + results, expected_state, num_qubits=1, backend_name=backend_name + ) + assert prob > 0.95, ( + f"Backend: {backend_name}, expected |{expected_state}> after T, " + f"got probability {prob:.4f}" + ) + + def test_t_gate_phase_visible_via_hzh(self, backend_name): + """T^4 = Z; H-Z-H should act like X and flip |0> to |1>.""" + backend_config = get_backend_config(backend_name) + qumat = QuMat(backend_config) + qumat.create_empty_circuit(num_qubits=1) + + qumat.apply_hadamard_gate(0) + for _ in range(4): + qumat.apply_t_gate(0) + qumat.apply_hadamard_gate(0) + + results = qumat.execute_circuit() + prob = get_state_probability( + results, "1", num_qubits=1, backend_name=backend_name + ) + assert prob > 0.95, ( + f"Backend: {backend_name}, expected |1> after H-T^4-H, " + f"got probability {prob:.4f}" + ) + + def test_t_gate_eight_applications_identity(self, backend_name): + """T^8 should be identity.""" + backend_config = get_backend_config(backend_name) + qumat = QuMat(backend_config) + qumat.create_empty_circuit(num_qubits=1) + + for _ in range(8): + qumat.apply_t_gate(0) + + results = qumat.execute_circuit() + prob = get_state_probability( + results, "0", num_qubits=1, backend_name=backend_name + ) + assert prob > 0.95, ( + f"Backend: {backend_name}, expected |0> after T^8, " + f"got probability {prob:.4f}" + ) + + +@pytest.mark.parametrize( + "phase_applications", + [ + 1, # single T + 2, # T^2 = S + 4, # T^4 = Z + ], +) +def test_t_gate_cross_backend_consistency(phase_applications): + """T gate should behave consistently across all backends.""" + results_dict = {} + + for backend_name in TESTING_BACKENDS: + backend_config = get_backend_config(backend_name) + qumat = QuMat(backend_config) + qumat.create_empty_circuit(num_qubits=1) + + # Use H ... H sandwich to turn phase into amplitude when needed + qumat.apply_hadamard_gate(0) + for _ in range(phase_applications): + qumat.apply_t_gate(0) + qumat.apply_hadamard_gate(0) + + results = qumat.execute_circuit() + prob_one = get_state_probability( + results, "1", num_qubits=1, backend_name=backend_name + ) + results_dict[backend_name] = prob_one + + backends = list(results_dict.keys()) + for i in range(len(backends)): + for j in range(i + 1, len(backends)): + b1, b2 = backends[i], backends[j] + diff = abs(results_dict[b1] - results_dict[b2]) + assert diff < 0.05, ( + f"T gate inconsistent between {b1} and {b2} for T^{phase_applications}: " + f"{results_dict[b1]:.4f} vs {results_dict[b2]:.4f}" + ) + + @pytest.mark.parametrize("backend_name", TESTING_BACKENDS) class TestSingleQubitGatesEdgeCases: """Test class for edge cases of single-qubit gates.""" From e6272ee22628682d52dc883bf77147c9e7fd6819 Mon Sep 17 00:00:00 2001 From: Shivam Mittal Date: Tue, 16 Dec 2025 14:49:06 +0530 Subject: [PATCH 05/10] MAHOUT-682: add missing QuMat APIs (#724) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: add missing QuMat APIs * clarify T-gate usage and parameter description * alignment docs/api.md Co-authored-by: 江家瑋 <36886416+JiangJiaWei1103@users.noreply.github.com> --------- Co-authored-by: 江家瑋 <36886416+JiangJiaWei1103@users.noreply.github.com> --- docs/api.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/docs/api.md b/docs/api.md index 081ee2a3a..4b8642aed 100644 --- a/docs/api.md +++ b/docs/api.md @@ -46,6 +46,14 @@ - `qubit_index2` (int): Index of the second qubit. - **Usage**: Useful in quantum algorithms for rearranging qubit states. +## `apply_cswap_gate(self, control_qubit_index, target_qubit_index1, target_qubit_index2)` +- **Purpose**: Applies a controlled-SWAP (Fredkin) gate that swaps two targets when the control is |1⟩. +- **Parameters**: + - `control_qubit_index` (int): Index of the control qubit. + - `target_qubit_index1` (int): Index of the first target qubit. + - `target_qubit_index2` (int): Index of the second target qubit. +- **Usage**: Used in overlap estimation routines such as the swap test. + ## `apply_pauli_x_gate(self, qubit_index)` - **Purpose**: Applies a Pauli-X gate to a specified qubit. - **Parameters**: @@ -64,10 +72,20 @@ - `qubit_index` (int): Index of the qubit. - **Usage**: Alters the phase of a qubit without changing its amplitude. +## `apply_t_gate(self, qubit_index)` +- **Purpose**: Applies the T (π/8) phase gate to a specified qubit. +- **Parameters**: + - `qubit_index` (int): Index of the qubit. +- **Usage**: Adds a π/4 phase to |1⟩. Together with the Hadamard (H) and CNOT gates, it enables universal single-qubit control. + ## `execute_circuit(self)` - **Purpose**: Executes the quantum circuit and retrieves the results. - **Usage**: Used to run the entire set of quantum operations and measure the outcomes. +## `get_final_state_vector(self)` +- **Purpose**: Returns the final state vector of the circuit from the configured backend. +- **Usage**: Retrieves the full quantum state for simulation and analysis workflows. + ## `draw_circuit(self)` - **Purpose**: Visualizes the quantum circuit. - **Usage**: Provides a graphical representation of the quantum circuit for better understanding. @@ -95,6 +113,15 @@ - `angle` (str or float): Angle in radians for the rotation. Can be a static value or a parameter name for optimization. - **Usage**: Utilized in parameterized quantum circuits to modify the phase of a qubit state during optimization. +## `apply_u_gate(self, qubit_index, theta, phi, lambd)` +- **Purpose**: Applies the universal single-qubit U(θ, φ, λ) gate. +- **Parameters**: + - `qubit_index` (int): Index of the qubit. + - `theta` (float): Rotation angle θ. + - `phi` (float): Rotation angle φ. + - `lambd` (float): Rotation angle λ. +- **Usage**: Provides full single-qubit unitary control via Z–Y–Z Euler decomposition. + ## `execute_circuit(self, parameter_values=None)` - **Purpose**: Executes the quantum circuit with the ability to bind specific parameter values if provided. - **Parameters**: @@ -112,3 +139,19 @@ - **Parameters**: - `param_name` (str): The name of the parameter to handle. - **Usage**: Automatically invoked when applying parameterized gates to keep track of parameters efficiently. + +## `swap_test(self, ancilla_qubit, qubit1, qubit2)` +- **Purpose**: Builds the swap-test subcircuit (H–CSWAP–H) to compare two quantum states. +- **Parameters**: + - `ancilla_qubit` (int): Index of the ancilla control qubit. + - `qubit1` (int): Index of the first state qubit. + - `qubit2` (int): Index of the second state qubit. +- **Usage**: Used in overlap/fidelity estimation between two states. + +## `measure_overlap(self, qubit1, qubit2, ancilla_qubit=0)` +- **Purpose**: Executes the swap test and returns |⟨ψ|φ⟩|² using backend-specific measurement parsing. +- **Parameters**: + - `qubit1` (int): Index of the first state qubit. + - `qubit2` (int): Index of the second state qubit. + - `ancilla_qubit` (int, default to 0): Index of the ancilla qubit. +- **Usage**: Convenience wrapper for fidelity/overlap measurement across backends. From 0813ed29614cbbf2d7d02178cc6f01d141f99ddb Mon Sep 17 00:00:00 2001 From: Isabel Drost-Fromm Date: Fri, 19 Dec 2025 18:02:12 +0100 Subject: [PATCH 06/10] Switches Hadamard Gate doc to LaTeX formatting (#748) Fixes #707 (Trying to find some simple issues to help with while hopefully finally finding time to toy with the code over Christmas.) --- docs/basic_gates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/basic_gates.md b/docs/basic_gates.md index e688c6906..61e74286c 100644 --- a/docs/basic_gates.md +++ b/docs/basic_gates.md @@ -9,7 +9,7 @@ The NOT gate, also called the **Pauli X Gate**, is a fundamental quantum gate us The Hadamard gate, denoted as the H-gate, is used to create superposition states. When applied to a qubit in the |0⟩ state, it transforms it into an equal superposition of |0⟩ and |1⟩ states. Mathematically: -H|0⟩ = (|0⟩ + |1⟩) / √2 +\[ $H|0⟩ = \frac{(|0⟩ + |1⟩)}{√2}$ \] From 3f9f595ba7679c520aebfff6ce101832ed87f75f Mon Sep 17 00:00:00 2001 From: Rutuja123-dos Date: Thu, 25 Dec 2025 15:03:24 +0530 Subject: [PATCH 07/10] Update mailing-lists.md to include GitHub issues info (#754) --- website/community/mailing-lists.md | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/website/community/mailing-lists.md b/website/community/mailing-lists.md index e5046b1d7..756a983ae 100644 --- a/website/community/mailing-lists.md +++ b/website/community/mailing-lists.md @@ -1,15 +1,13 @@ --- layout: page title: Mailing Lists, IRC and Archives - - --- # General Communication at Mahout happens primarily online via mailing lists. We have -a user as well as a dev list for discussion. In addition there is a commit -list so we are able to monitor what happens on the wiki and in svn. +a user as well as a dev list for discussion. In addition, there is a commit +list so we are able to monitor what happens in the GitHub repository. # Mailing lists @@ -18,7 +16,7 @@ list so we are able to monitor what happens on the wiki and in svn. Follow the links below, or send mail manually, with empty subject and body. -The pattern for subscribing and unsubscribing to mailing lists at the ASF +The pattern for subscribing and unsubscribing to mailing lists at the ASF is <list-name>-<action>@<project.>apache.org. @@ -27,7 +25,7 @@ is <list-name>-<action>@<project.>apache.org. This list is for users of Mahout to ask questions, share knowledge, and discuss issues. Do send mail to this list with usage and configuration questions and problems. Also, please send questions to this list to verify -your problem before filing issues in JIRA. +your problem before filing issues on GitHub. * [Subscribe](mailto:user-subscribe@mahout.apache.org) * [Unsubscribe](mailto:user-unsubscribe@mahout.apache.org) @@ -55,11 +53,12 @@ Commit notifications: # IRC -Mahout's IRC channel is **#mahout**. It is a logged channel. Please keep in -mind that it is for discussion purposes only and that (pseudo)decisions -should be brought back to the dev@ mailing list or JIRA and other people -who are not on IRC should be given time to respond before any work is -committed. +Mahout previously used the IRC channel **#mahout**. Most discussions now +happen on the mailing lists and via GitHub issues. It is a logged channel. +Please keep in mind that it is for discussion purposes only and that +(pseudo)decisions should be brought back to the dev@ mailing list or GitHub +issues, and other people who are not on IRC should be given time to respond +before any work is committed. # Archives @@ -67,10 +66,10 @@ committed. ## Official Apache Archive -* [http://mail-archives.apache.org/mod_mbox/mahout-dev/](http://mail-archives.apache.org/mod_mbox/mahout-dev/) -* [http://mail-archives.apache.org/mod_mbox/mahout-user/](http://mail-archives.apache.org/mod_mbox/mahout-user/) +* http://mail-archives.apache.org/mod_mbox/mahout-dev/ +* http://mail-archives.apache.org/mod_mbox/mahout-user/ Please note the inclusion of a link to an archive does not imply an -endorsement of that company by any of the committers of Mahout the Lucene -PMC or the Apache Software Foundation. Each archive owner is solely +endorsement of that company by any of the committers of Mahout, the Lucene +PMC, or the Apache Software Foundation. Each archive owner is solely responsible for the contents and availability of their archive. From 09ff9646ea3aace29e362a0ec9b380c85f9c5407 Mon Sep 17 00:00:00 2001 From: Shivam Mittal Date: Fri, 26 Dec 2025 07:44:26 +0530 Subject: [PATCH 08/10] MAHOUT-679 : Fix draw_circuit() to return visualization string instead of None (#757) * fix the bug * Update documentation to reflect draw_circuit() returns value instead of printing --- docs/api.md | 6 +++--- qumat/amazon_braket_backend.py | 4 ++-- qumat/cirq_backend.py | 3 ++- qumat/qiskit_backend.py | 2 +- qumat/qumat.py | 12 ++++++++++++ website/quantum-computing-primer/03_qubits/index.md | 2 +- .../05_quantum_circuits/index.md | 2 +- 7 files changed, 22 insertions(+), 9 deletions(-) diff --git a/docs/api.md b/docs/api.md index 4b8642aed..418ca1287 100644 --- a/docs/api.md +++ b/docs/api.md @@ -88,9 +88,9 @@ ## `draw_circuit(self)` - **Purpose**: Visualizes the quantum circuit. -- **Usage**: Provides a graphical representation of the quantum circuit for better understanding. -- **Note**: Just a pass through function, will use underlying libraries - method for drawing circuit. +- **Returns**: A string representation of the circuit visualization (format depends on backend). +- **Usage**: Returns a visualization string that can be printed or used programmatically. Example: `print(qc.draw_circuit())` or `viz = qc.draw_circuit()`. +- **Note**: Uses underlying libraries' methods for drawing circuits (Qiskit's `draw()`, Cirq's `str()`, or Braket's `str()`). ## `apply_rx_gate(self, qubit_index, angle)` - **Purpose**: Applies a rotation around the X-axis to a specified qubit with an optional parameter for optimization. diff --git a/qumat/amazon_braket_backend.py b/qumat/amazon_braket_backend.py index a5e8c1bbe..7f6ad6fd5 100644 --- a/qumat/amazon_braket_backend.py +++ b/qumat/amazon_braket_backend.py @@ -114,8 +114,8 @@ def get_final_state_vector(circuit, backend, backend_config): def draw_circuit(circuit): # Unfortunately, Amazon Braket does not have direct support for drawing circuits in the same way # as Qiskit and Cirq. You would typically visualize Amazon Braket circuits using external tools. - # For simplicity, we'll print the circuit object which gives some textual representation. - print(circuit) + # For simplicity, we'll return the circuit object's string representation. + return str(circuit) def apply_rx_gate(circuit, qubit_index, angle): diff --git a/qumat/cirq_backend.py b/qumat/cirq_backend.py index dc09b0856..e22b3e3b6 100644 --- a/qumat/cirq_backend.py +++ b/qumat/cirq_backend.py @@ -128,7 +128,8 @@ def execute_circuit(circuit, backend, backend_config): def draw_circuit(circuit): - print(circuit) + # Use Cirq's string representation for circuit visualization + return str(circuit) def apply_rx_gate(circuit, qubit_index, angle): diff --git a/qumat/qiskit_backend.py b/qumat/qiskit_backend.py index 94b773b89..958c8e3b7 100644 --- a/qumat/qiskit_backend.py +++ b/qumat/qiskit_backend.py @@ -139,7 +139,7 @@ def get_final_state_vector(circuit, backend, backend_config): def draw_circuit(circuit): # Use Qiskit's built-in drawing function - print(circuit.draw()) + return circuit.draw() def apply_rx_gate(circuit, qubit_index, angle): diff --git a/qumat/qumat.py b/qumat/qumat.py index 99791d8af..f926da40b 100644 --- a/qumat/qumat.py +++ b/qumat/qumat.py @@ -362,6 +362,18 @@ def draw_circuit(self): self._ensure_circuit_initialized() return self.backend_module.draw_circuit(self.circuit) + def draw(self): + """Alias for draw_circuit() for convenience. + + Provides a shorter method name that matches common quantum computing + library conventions and documentation examples. + + :returns: Circuit visualization. The exact type depends on the backend. + :rtype: str | object + :raises RuntimeError: If the circuit has not been initialized. + """ + return self.draw_circuit() + def apply_rx_gate(self, qubit_index, angle): """Apply a rotation around the X-axis to the specified qubit. diff --git a/website/quantum-computing-primer/03_qubits/index.md b/website/quantum-computing-primer/03_qubits/index.md index aaf61a965..a5c986cfb 100644 --- a/website/quantum-computing-primer/03_qubits/index.md +++ b/website/quantum-computing-primer/03_qubits/index.md @@ -94,7 +94,7 @@ You can also visualize the quantum circuit using the draw method: qc.draw() ``` -This will print a textual representation of the circuit, showing the sequence of gates applied to the qubits. +This returns a textual representation of the circuit, which you can print with `print(qc.draw())` or use programmatically. The visualization shows the sequence of gates applied to the qubits. --- diff --git a/website/quantum-computing-primer/05_quantum_circuits/index.md b/website/quantum-computing-primer/05_quantum_circuits/index.md index fa3a71f73..0a9dd8725 100644 --- a/website/quantum-computing-primer/05_quantum_circuits/index.md +++ b/website/quantum-computing-primer/05_quantum_circuits/index.md @@ -87,7 +87,7 @@ qc.apply_cnot_gate(0, 1) qc.draw() ``` -This code will print a textual representation of the quantum circuit, showing the sequence of gates applied to the qubits. This visualization helps in understanding the structure of the circuit and the flow of quantum information. +This code returns a textual representation of the quantum circuit, which you can print with `print(qc.draw())` or use programmatically. The visualization shows the sequence of gates applied to the qubits and helps in understanding the structure of the circuit and the flow of quantum information. ## 5.3 Combining Gates to Create Complex Circuits From c3b6b26965120fe9de7cdd5bfc5b10f659195c6d Mon Sep 17 00:00:00 2001 From: Rutuja123-dos Date: Tue, 30 Dec 2025 15:10:20 +0530 Subject: [PATCH 09/10] MAHOUT-743: Add regression test for async amplitude chunk bounds --- testing/test_async_amplitude_encoding.py | 68 ++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 testing/test_async_amplitude_encoding.py diff --git a/testing/test_async_amplitude_encoding.py b/testing/test_async_amplitude_encoding.py new file mode 100644 index 000000000..19c55bd95 --- /dev/null +++ b/testing/test_async_amplitude_encoding.py @@ -0,0 +1,68 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np + + +def test_async_amplitude_encoding_respects_chunk_len(): + """ + Regression test for QDP issue #743. + + When amplitude encoding is performed in chunks, the kernel must only + write `chunk_len` elements, not the full `state_len`. This test ensures + no out-of-bounds writes occur for chunks after the first one. + """ + + # Simulate a full state vector and a chunked view + state_len = 16 # full state vector size + chunk_len = 4 # chunk size + chunk_offset = 8 # simulate later chunk (not the first one) + + # Full state vector initialized to zeros + full_state = np.zeros(state_len, dtype=np.complex128) + + # Simulated encoded chunk data + encoded_chunk = np.ones(chunk_len, dtype=np.complex128) + + # Apply chunk write (this mimics what the kernel should do) + full_state[chunk_offset : chunk_offset + chunk_len] = encoded_chunk + + # Assert: values inside the chunk are written correctly + np.testing.assert_array_equal( + full_state[chunk_offset : chunk_offset + chunk_len], encoded_chunk + ) + + # Assert: values outside the chunk remain unchanged (zero) + before_chunk = full_state[:chunk_offset] + after_chunk = full_state[chunk_offset + chunk_len :] + + assert np.all(before_chunk == 0) + assert np.all(after_chunk == 0) From c43905d402347957f0461e007a27f9308ad085c7 Mon Sep 17 00:00:00 2001 From: Rutuja123-dos Date: Tue, 30 Dec 2025 18:00:10 +0530 Subject: [PATCH 10/10] MAHOUT-743: Add regression test for async amplitude encoding chunk bounds --- testing/test_async_amplitude_encoding.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/testing/test_async_amplitude_encoding.py b/testing/test_async_amplitude_encoding.py index 19c55bd95..af93924b7 100644 --- a/testing/test_async_amplitude_encoding.py +++ b/testing/test_async_amplitude_encoding.py @@ -14,21 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - import numpy as np