From a5c9e10da47ab026404960f6d35e4e57bfeae93e Mon Sep 17 00:00:00 2001 From: Wong Zi Cheng <70616433+chmwzc@users.noreply.github.com> Date: Wed, 5 Feb 2025 03:50:45 +0000 Subject: [PATCH 1/3] Minor update to code blocks in tutorials --- doc/source/getting-started/quickstart.rst | 2 +- doc/source/tutorials/adaptive.rst | 55 ++++++----- doc/source/tutorials/ansatz.rst | 115 +++++++++++----------- doc/source/tutorials/hamiltonian.rst | 2 +- doc/source/tutorials/measurement.rst | 8 +- doc/source/tutorials/molecule.rst | 8 +- 6 files changed, 96 insertions(+), 94 deletions(-) diff --git a/doc/source/getting-started/quickstart.rst b/doc/source/getting-started/quickstart.rst index ee83b7b9..eed2105b 100644 --- a/doc/source/getting-started/quickstart.rst +++ b/doc/source/getting-started/quickstart.rst @@ -14,7 +14,7 @@ Here is an example of building the UCCD ansatz with the H2 molecule to test your import numpy as np from qibo.models import VQE - from qibochem.driver.molecule import Molecule + from qibochem.driver import Molecule from qibochem.ansatz import hf_circuit, ucc_circuit # Define the H2 molecule and obtain its 1-/2- electron integrals with PySCF diff --git a/doc/source/tutorials/adaptive.rst b/doc/source/tutorials/adaptive.rst index f3189f27..e00faa09 100644 --- a/doc/source/tutorials/adaptive.rst +++ b/doc/source/tutorials/adaptive.rst @@ -277,7 +277,7 @@ This can be carried out until the difference between each iteration is small (<0 print("\nFinal circuit:") - print(circuit.draw()) + circuit.draw() print("\nCircuit statistics:") print(circuit.summary()) @@ -316,32 +316,32 @@ Output: Energy has converged; exiting while loop Final circuit: - q0: ─X──────────────────────────────────────────────────────────────────── ... - q1: ─X──────────────────────────────────────────────────────────────────── ... - q2: ─X───o─H─o───RY─o─────RY───X─RY─────o─RY─o─X─H─o─────o─H─o───RY─o───── ... - q3: ─X───|───X───RY─|───X─RY─X─|─RY─X───|─RY─X─|───|─────|───X───RY─|───X─ ... - q4: ─────|──────────|───|────|─|────|───|──────|───|───o─X─────o────|───|─ ... - q5: ─────|──────────|───|────|─|────|───|──────|───|───|───────|────|───|─ ... - q6: ───o─X─────o────|───|────o─o────|───|──────o───X─o─|───────|────|───|─ ... - q7: ───X───H───X────X─H─o───────────o─H─X────────H───X─X───H───X────X─H─o─ ... - - q0: ... ────────────────────────────────────────────────────────────────────── ... - q1: ... ────────────────────────────────────────────────────────────────────── ... - q2: ... RY───X─RY─────o─RY─o─X─H─o─────o─H─o───RY─o─────RY───X─RY─────o─RY─o─X ... - q3: ... RY─X─|─RY─X───|─RY─X─|───|─────|───X───RY─|───X─RY─X─|─RY─X───|─RY─X─| ... - q4: ... ───o─o────|───|──────o───X─o───|──────────|───|────|─|────|───|──────| ... - q5: ... ──────────|───|────────────|─o─X─────o────|───|────o─o────|───|──────o ... - q6: ... ──────────|───|────────────|─X───H───X────X─H─o───────────o─H─X─────── ... - q7: ... ──────────o─H─X────────H───X────────────────────────────────────────── ... - - q0: ... ─────────o─H─o───RY─o─────RY───X─RY─────o─RY─o─X─H─o─── - q1: ... ─────────|───X───RY─|───X─RY─X─|─RY─X───|─RY─X─|───|─── - q2: ... ─H─o─────|──────────|───|────|─|────|───|──────|───|─── - q3: ... ───|─────|──────────|───|────|─|────|───|──────|───|─── - q4: ... ───|───o─X─────o────|───|────o─o────|───|──────o───X─o─ - q5: ... ───X─o─X───H───X────X─H─o───────────o─H─X────────H───X─ - q6: ... ─H───X───────────────────────────────────────────────── - q7: ... ─────────────────────────────────────────────────────── + 0: ─X──────────────────────────────────────────────────────────────────── ... + 1: ─X──────────────────────────────────────────────────────────────────── ... + 2: ─X───o─H─o───RY─o─────RY───X─RY─────o─RY─o─X─H─o─────o─H─o───RY─o───── ... + 3: ─X───|───X───RY─|───X─RY─X─|─RY─X───|─RY─X─|───|─────|───X───RY─|───X─ ... + 4: ─────|──────────|───|────|─|────|───|──────|───|───o─X─────o────|───|─ ... + 5: ─────|──────────|───|────|─|────|───|──────|───|───|───────|────|───|─ ... + 6: ───o─X─────o────|───|────o─o────|───|──────o───X─o─|───────|────|───|─ ... + 7: ───X───H───X────X─H─o───────────o─H─X────────H───X─X───H───X────X─H─o─ ... + + 0: ... ────────────────────────────────────────────────────────────────────── ... + 1: ... ────────────────────────────────────────────────────────────────────── ... + 2: ... RY───X─RY─────o─RY─o─X─H─o─────o─H─o───RY─o─────RY───X─RY─────o─RY─o─X ... + 3: ... RY─X─|─RY─X───|─RY─X─|───|─────|───X───RY─|───X─RY─X─|─RY─X───|─RY─X─| ... + 4: ... ───o─o────|───|──────o───X─o───|──────────|───|────|─|────|───|──────| ... + 5: ... ──────────|───|────────────|─o─X─────o────|───|────o─o────|───|──────o ... + 6: ... ──────────|───|────────────|─X───H───X────X─H─o───────────o─H─X─────── ... + 7: ... ──────────o─H─X────────H───X────────────────────────────────────────── ... + + 0: ... ─────────o─H─o───RY─o─────RY───X─RY─────o─RY─o─X─H─o─── + 1: ... ─────────|───X───RY─|───X─RY─X─|─RY─X───|─RY─X─|───|─── + 2: ... ─H─o─────|──────────|───|────|─|────|───|──────|───|─── + 3: ... ───|─────|──────────|───|────|─|────|───|──────|───|─── + 4: ... ───|───o─X─────o────|───|────o─o────|───|──────o───X─o─ + 5: ... ───X─o─X───H───X────X─H─o───────────o─H─X────────H───X─ + 6: ... ─H───X───────────────────────────────────────────────── + 7: ... ─────────────────────────────────────────────────────── Circuit statistics: Circuit depth = 78 @@ -353,6 +353,7 @@ Output: h: 24 x: 4 + Recall that the full UCCSD circuit for our system had a circuit depth of 1874, with more than 1000 CNOT gates required. In contrast, the use of a simpler circuit ansatz in conjunction with an adaptive approach allowed us to find a VQE energy that is within chemical accuracy, while using only 56 CNOT gates and with a final gate depth of only 78. diff --git a/doc/source/tutorials/ansatz.rst b/doc/source/tutorials/ansatz.rst index a9e7fd2b..8e760d95 100644 --- a/doc/source/tutorials/ansatz.rst +++ b/doc/source/tutorials/ansatz.rst @@ -22,14 +22,14 @@ For the H\ :sub:`2` case discussed in previous sections, a possible hardware eff nlayers = 1 circuit = he_circuit(nqubits, nlayers) - print(circuit.draw()) + circuit.draw() .. code-block:: output - q0: ─RY─RZ─o─────Z─ - q1: ─RY─RZ─Z─o───|─ - q2: ─RY─RZ───Z─o─|─ - q3: ─RY─RZ─────Z─o─ + 0: ─RY─RZ─o─────Z─ + 1: ─RY─RZ─Z─o───|─ + 2: ─RY─RZ───Z─o─|─ + 3: ─RY─RZ─────Z─o─ The energy of the state generated from the hardware efficient ansatz for the fermionic two-body Hamiltonian can then be estimated, using state vectors or samples. @@ -40,7 +40,7 @@ The following example demonstrates how the energy of the H2 molecule is affected import numpy as np from qibochem.driver import Molecule - from qibochem.measurement.expectation import expectation + from qibochem.measurement import expectation from qibochem.ansatz import he_circuit mol = Molecule([("H", (0.0, 0.0, 0.0)), ("H", (0.0, 0.0, 0.74804))]) @@ -103,7 +103,7 @@ An example of how to build a UCC doubles circuit ansatz for the :math:`H_2` mole .. code-block:: python - from qibochem.driver.molecule import Molecule + from qibochem.driver import Molecule from qibochem.ansatz import hf_circuit, ucc_circuit mol = Molecule([("H", (0.0, 0.0, 0.0)), ("H", (0.0, 0.0, 0.74804))]) @@ -118,25 +118,24 @@ An example of how to build a UCC doubles circuit ansatz for the :math:`H_2` mole circuit = hf_circuit(n_qubits, n_electrons) # Start with HF circuit circuit += ucc_circuit(n_qubits, [0, 1, 2, 3]) # Then add the double excitation circuit ansatz - print(circuit.draw()) + circuit.draw() .. code-block:: output - q0: ─X──H─────X─RZ─X─────H──RX─────X─RZ─X─────RX─RX─────X─RZ─X─────RX─H─── ... - q1: ─X──H───X─o────o─X───H──RX───X─o────o─X───RX─H────X─o────o─X───H──RX── ... - q2: ─RX───X─o────────o─X─RX─RX─X─o────────o─X─RX─H──X─o────────o─X─H──H──X ... - q3: ─H────o────────────o─H──H──o────────────o─H──H──o────────────o─H──H──o ... - - q0: ... ───X─RZ─X─────H──RX─────X─RZ─X─────RX─H──────X─RZ─X─────H──H──────X─RZ ... - q1: ... ─X─o────o─X───RX─H────X─o────o─X───H──RX───X─o────o─X───RX─H────X─o─── ... - q2: ... ─o────────o─X─H──RX─X─o────────o─X─RX─RX─X─o────────o─X─RX─H──X─o───── ... - q3: ... ────────────o─H──RX─o────────────o─RX─RX─o────────────o─RX─RX─o─────── ... + 0: ─X───H─────X─RZ─X─────H─SDG─H─────────X─RZ─X─────H─S─SDG─H─────X─RZ─X─ ... + 1: ─X───H───X─o────o─X───H─SDG─H───────X─o────o─X───H─S─H───────X─o────o─ ... + 2: ─SDG─H─X─o────────o─X─H─S───SDG─H─X─o────────o─X─H─S─H─────X─o──────── ... + 3: ─H─────o────────────o─H─H─────────o────────────o─H─H───────o────────── ... - q0: ... ─X─────H──RX─────X─RZ─X─────RX─ - q1: ... ─o─X───H──RX───X─o────o─X───RX─ - q2: ... ───o─X─H──H──X─o────────o─X─H── - q3: ... ─────o─RX─RX─o────────────o─RX─ + 0: ... ────H─S───H─────X─RZ─X─────H─SDG─H─────X─RZ─X─────H─S───H─────────X─RZ ... + 1: ... X───H─SDG─H───X─o────o─X───H─S───H───X─o────o─X───H─SDG─H───────X─o─── ... + 2: ... o─X─H─H─────X─o────────o─X─H─SDG─H─X─o────────o─X─H─S───SDG─H─X─o───── ... + 3: ... ──o─H─H─────o────────────o─H─SDG─H─o────────────o─H─S───SDG─H─o─────── ... + 0: ... ─X─────H─H───────────X─RZ─X─────H─SDG─H─────────X─RZ─X─────H─S─ + 1: ... ─o─X───H─S─H───────X─o────o─X───H─SDG─H───────X─o────o─X───H─S─ + 2: ... ───o─X─H─S─H─────X─o────────o─X─H─H─────────X─o────────o─X─H─── + 3: ... ─────o─H─S─SDG─H─o────────────o─H─S───SDG─H─o────────────o─H─S─ UCC with Qubit-Excitation-Based n-tuple Excitation @@ -149,7 +148,7 @@ An example for the :math:`H_2` molecule is given here: .. code-block:: python - from qibochem.driver.molecule import Molecule + from qibochem.driver import Molecule from qibochem.ansatz import hf_circuit, qeb_circuit mol = Molecule([("H", (0.0, 0.0, 0.0)), ("H", (0.0, 0.0, 0.74804))]) @@ -164,14 +163,14 @@ An example for the :math:`H_2` molecule is given here: circuit = hf_circuit(n_qubits, n_electrons) # Start with HF circuit circuit += qeb_circuit(n_qubits, [0, 1, 2, 3]) # Then add the double excitation circuit ansatz - print(circuit.draw()) + circuit.draw() .. code-block:: output - q0: ─X─X─────X─o──X─────X─ - q1: ─X─o───X───o────X───o─ - q2: ─────X─|─X─o──X─|─X─── - q3: ─────o─o───RY───o─o─── + 0: ─X─X─────X─o──X─────X─ + 1: ─X─o───X───o────X───o─ + 2: ─────X─|─X─o──X─|─X─── + 3: ─────o─o───RY───o─o─── .. _Basis rotation ansatz @@ -194,10 +193,11 @@ The orthonormal molecular orbitals :math:`\phi` are optimized by a direct minimi .. code-block:: python - import numpy as np - from qibochem.driver.molecule import Molecule - from qibochem.ansatz import basis_rotation, ucc - from qibo import Circuit, gates, models + from qibo.models import VQE + + from qibochem.driver import Molecule + from qibochem.ansatz import hf_circuit, basis_rotation + def basis_rotation_circuit(mol, parameters=0.0): @@ -206,51 +206,52 @@ The orthonormal molecular orbitals :math:`\phi` are optimized by a direct minimi vir = range(mol.nelec, mol.nso) U, kappa = basis_rotation.unitary(occ, vir, parameters=parameters) - gate_angles, final_U = basis_rotation.givens_qr_decompose(U) + gate_angles, _final_U = basis_rotation.givens_qr_decompose(U) gate_layout = basis_rotation.basis_rotation_layout(nqubits) - gate_list, ordered_angles = basis_rotation.basis_rotation_gates(gate_layout, gate_angles, kappa) + gate_list, _ordered_angles = basis_rotation.basis_rotation_gates( + gate_layout, gate_angles, kappa + ) - circuit = Circuit(nqubits) - for _i in range(mol.nelec): - circuit.add(gates.X(_i)) + circuit = hf_circuit(nqubits, mol.nelec) circuit.add(gate_list) return circuit, gate_angles - h3p = Molecule([('H', (0.0000, 0.0000, 0.0000)), - ('H', (0.0000, 0.0000, 0.8000)), - ('H', (0.0000, 0.0000, 1.6000))], - charge=1, multiplicity=1) + h3p = Molecule( + [ + ("H", (0.0000, 0.0000, 0.0000)), + ("H", (0.0000, 0.0000, 0.8000)), + ("H", (0.0000, 0.0000, 1.6000)), + ], + charge=1, + multiplicity=1, + ) h3p.run_pyscf(max_scf_cycles=1) e_init = h3p.e_hf h3p_sym_ham = h3p.hamiltonian("sym", h3p.oei, h3p.tei, 0.0, "jw") - hf_circuit, qubit_parameters = basis_rotation_circuit(h3p, parameters=0.1) + circuit, qubit_parameters = basis_rotation_circuit(h3p, parameters=0.1) - print(hf_circuit.draw()) + circuit.draw() - vqe = models.VQE(hf_circuit, h3p_sym_ham) + vqe = VQE(circuit, h3p_sym_ham) res = vqe.minimize(qubit_parameters) - print('energy of initial guess: ', e_init) - print('energy after vqe : ', res[0]) + print("energy of initial guess: ", e_init) + print("energy after vqe : ", res[0]) .. code-block:: output - q0: ─X─G─────────G─────────G───────── - q1: ─X─G─────G───G─────G───G─────G─── - q2: ─────G───G─────G───G─────G───G─── - q3: ─────G─────G───G─────G───G─────G─ - q4: ───────G───G─────G───G─────G───G─ - q5: ───────G─────────G─────────G───── basis rotation: using uniform value of 0.1 for each parameter value - energy of initial guess: -1.1977713400022736 - energy after vqe : -1.2024564133305427 - - - - + 0: ─X─G─────────G─────────G───────── + 1: ─X─G─────G───G─────G───G─────G─── + 2: ─────G───G─────G───G─────G───G─── + 3: ─────G─────G───G─────G───G─────G─ + 4: ───────G───G─────G───G─────G───G─ + 5: ───────G─────────G─────────G───── + energy of initial guess: -1.1977713400022745 + energy after vqe : -1.2025110984672576 .. rubric:: References diff --git a/doc/source/tutorials/hamiltonian.rst b/doc/source/tutorials/hamiltonian.rst index 99a69708..4109f0e1 100644 --- a/doc/source/tutorials/hamiltonian.rst +++ b/doc/source/tutorials/hamiltonian.rst @@ -26,7 +26,7 @@ Qibochem then uses these integrals and the `OpenFermion ` .. code-block:: python - from qibochem.driver.molecule import Molecule + from qibochem.driver import Molecule # Inline definition of H2 h2 = Molecule([('H', (0.0, 0.0, 0.0)), ('H', (0.0, 0.0, 0.74804))]) @@ -72,7 +72,7 @@ An example of how to apply this using Qibochem for the LiH molecule is given bel .. code-block:: python - from qibochem.driver.molecule import Molecule + from qibochem.driver import Molecule # Inline definition of H2 h2 = Molecule([('H', (0.0, 0.0, 0.0)), ('H', (0.0, 0.0, 0.74804))]) From ff6055b998e9b2059533ef00c6e98259fb357512 Mon Sep 17 00:00:00 2001 From: Wong Zi Cheng <70616433+chmwzc@users.noreply.github.com> Date: Wed, 5 Feb 2025 03:51:28 +0000 Subject: [PATCH 2/3] Update index sidebar --- doc/source/index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/source/index.rst b/doc/source/index.rst index 085a516e..19626efc 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -72,6 +72,8 @@ Contents Qibocal docs Qibosoq docs Qibochem docs + Qibotn docs + Qibo-cloud-backends docs Indices and tables ================== From 76a7c6e9f21685e528656815514bf08b948af742 Mon Sep 17 00:00:00 2001 From: Wong Zi Cheng <70616433+chmwzc@users.noreply.github.com> Date: Wed, 5 Feb 2025 03:55:34 +0000 Subject: [PATCH 3/3] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d0ad654f..019c20b3 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,8 @@ An example of building the UCCD ansatz with a H2 molecule import numpy as np from qibo.models import VQE -from qibochem.driver.molecule import Molecule -from qibochem.ansatz.hf_reference import hf_circuit -from qibochem.ansatz.ucc import ucc_circuit +from qibochem.driver import Molecule +from qibochem.ansatz import hf_circuit, ucc_circuit # Define the H2 molecule and obtain its 1-/2- electron integrals with PySCF h2 = Molecule([('H', (0.0, 0.0, 0.0)), ('H', (0.0, 0.0, 0.7))]) @@ -45,6 +44,7 @@ vqe = VQE(circuit, hamiltonian) initial_parameters = np.random.uniform(0.0, 2*np.pi, 8) best, params, extra = vqe.minimize(initial_parameters) +print(f"VQE result: {best:.10f}") ``` ## Citation policy