Skip to content

Commit

Permalink
Merge branch 'main' into dev/docs
Browse files Browse the repository at this point in the history
  • Loading branch information
damarkian authored Sep 6, 2023
2 parents 7a58546 + 4eb43e5 commit ef67e09
Show file tree
Hide file tree
Showing 9 changed files with 600 additions and 478 deletions.
4 changes: 4 additions & 0 deletions .github/.codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Reference docs at https://docs.codecov.com/docs/codecovyml-reference

codecov:
require_ci_to_pass: yes
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ jobs:
with:
os: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}
poetry-extras: "--with docs,tests,analysis --all-extras"
poetry-extras: --with docs,tests,analysis --all-extras
secrets: inherit
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ repos:
- id: isort
args: ["--profile", "black"]
- repo: https://github.com/asottile/pyupgrade
rev: v3.9.0
rev: v3.10.1
hooks:
- id: pyupgrade
956 changes: 536 additions & 420 deletions poetry.lock

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ classifiers = [
packages = [{ include = "qibochem", from = "src" }]

[tool.poetry.dependencies]
python = "^3.9"
python = ">3.9,<3.12"
qibo = "^0.1.10"
openfermion = "^1.5"
pyscf = "^2.2.1"
pyscf = "^2.3.0"
scipy = "^1.10.1"

[build-system]
requires = ["poetry-core"]
Expand Down
50 changes: 0 additions & 50 deletions src/qibochem/driver/molecule.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,56 +385,6 @@ def hamiltonian(
return ham_type # Yummy!
raise NameError(f"Unknown {ham_type}!") # Shouldn't ever reach here

@staticmethod
def expectation(
circuit: qibo.models.Circuit, hamiltonian: SymbolicHamiltonian, from_samples=False, n_shots=1000
) -> float:
"""
Calculate expectation value of Hamiltonian using either the state vector from running a
circuit, or the frequencies of the resultant binary string results
Args:
circuit (qibo.models.Circuit): Quantum circuit ansatz
hamiltonian (SymbolicHamiltonian): Molecular Hamiltonian
from_samples: Whether the expectation value calculation uses samples or the simulated
state vector. Default: False, state vector simulation
n_shots: Number of times the circuit is run for the from_samples=True case
Returns:
Hamiltonian expectation value (float)
"""
if from_samples:
raise NotImplementedError("expectation function only works with state vector")
# TODO: Rough code for expectation_from_samples if issue resolved
# Yet to test!!!!!
#
# from functools import reduce
# total = 0.0
# Iterate over each term in the Hamiltonian
# for term in hamiltonian.terms:
# # Get the basis rotation gates and target qubits from the Hamiltonian term
# qubits = [factor.target_qubit for factor in term.factors]
# basis = [type(factor.gate) for factor in term.factors]
# # Run a copy of the initial circuit to get the output frequencies
# _circuit = circuit.copy()
# _circuit.add(gates.M(*qubits, basis=basis))
# result = _circuit(nshots=n_shots)
# frequencies = result.frequencies(binary=True)
# # Only works for Z terms, raises an error if ham_term has X/Y terms
# total += SymbolicHamiltonian(
# reduce(lambda x, y: x*y, term.factors, 1)
# ).expectation_from_samples(frequencies, qubit_map=qubits)
# return total

# Expectation value from state vector simulation
result = circuit(nshots=1)
state_ket = result.state()
return hamiltonian.expectation(state_ket)

@staticmethod
def eigenvalues(hamiltonian):
"""
Expand Down
49 changes: 49 additions & 0 deletions src/qibochem/measurement/expectation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# from qibo import gates
# from qibo.models import Circuit

import qibo
from qibo.hamiltonians import SymbolicHamiltonian

from qibochem.measurement.basis_rotate import measure_rotate_basis


Expand Down Expand Up @@ -67,3 +70,49 @@ def circuit_expectation_shots(qc, of_qubham, nshots=1000):
istring += 1

return expectation


def expectation(
circuit: qibo.models.Circuit, hamiltonian: SymbolicHamiltonian, from_samples=False, n_shots=1000
) -> float:
"""
Calculate expectation value of Hamiltonian using either the state vector from running a
circuit, or the frequencies of the resultant binary string results
Args:
circuit (qibo.models.Circuit): Quantum circuit ansatz
hamiltonian (SymbolicHamiltonian): Molecular Hamiltonian
from_samples: Whether the expectation value calculation uses samples or the simulated
state vector. Default: False, state vector simulation
n_shots: Number of times the circuit is run for the from_samples=True case
Returns:
Hamiltonian expectation value (float)
"""
if from_samples:
raise NotImplementedError("expectation function only works with state vector")
# TODO: Rough code for expectation_from_samples if issue resolved
# Yet to test!!!!!
#
# from functools import reduce
# total = 0.0
# Iterate over each term in the Hamiltonian
# for term in hamiltonian.terms:
# # Get the basis rotation gates and target qubits from the Hamiltonian term
# qubits = [factor.target_qubit for factor in term.factors]
# basis = [type(factor.gate) for factor in term.factors]
# # Run a copy of the initial circuit to get the output frequencies
# _circuit = circuit.copy()
# _circuit.add(gates.M(*qubits, basis=basis))
# result = _circuit(nshots=n_shots)
# frequencies = result.frequencies(binary=True)
# # Only works for Z terms, raises an error if ham_term has X/Y terms
# total += SymbolicHamiltonian(
# reduce(lambda x, y: x*y, term.factors, 1)
# ).expectation_from_samples(frequencies, qubit_map=qubits)
# return total

# Expectation value from state vector simulation
result = circuit(nshots=1)
state_ket = result.state()
return hamiltonian.expectation(state_ket)
7 changes: 4 additions & 3 deletions tests/test_hf_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from qibochem.ansatz.hf_reference import hf_circuit
from qibochem.driver.molecule import Molecule
from qibochem.measurement.expectation import expectation


def test_jw_circuit():
Expand All @@ -25,7 +26,7 @@ def test_jw_circuit():

# Molecular Hamiltonian and the HF expectation value
hamiltonian = h2.hamiltonian()
hf_energy = h2.expectation(circuit, hamiltonian)
hf_energy = expectation(circuit, hamiltonian)

# assert h2.e_hf == pytest.approx(hf_energy)
assert h2_ref_energy == pytest.approx(hf_energy)
Expand All @@ -47,7 +48,7 @@ def test_bk_circuit_1():

# Molecular Hamiltonian and the HF expectation value
hamiltonian = h2.hamiltonian(ferm_qubit_map="bk")
hf_energy = h2.expectation(circuit, hamiltonian)
hf_energy = expectation(circuit, hamiltonian)

# assert h2.e_hf == pytest.approx(hf_energy)
assert h2_ref_energy == pytest.approx(hf_energy)
Expand All @@ -67,6 +68,6 @@ def test_bk_circuit_2():

# Molecular Hamiltonian and the HF expectation value
hamiltonian = lih.hamiltonian(ferm_qubit_map="bk")
hf_energy = lih.expectation(circuit, hamiltonian)
hf_energy = expectation(circuit, hamiltonian)

assert lih.e_hf == pytest.approx(hf_energy)
3 changes: 2 additions & 1 deletion tests/test_molecule.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from qibo import gates, models

from qibochem.driver.molecule import Molecule
from qibochem.measurement.expectation import expectation


def test_run_pyscf():
Expand Down Expand Up @@ -52,7 +53,7 @@ def test_expectation_value():
circuit.add(gates.X(_i) for _i in range(sum(h2.nelec)))
# Molecular Hamiltonian and the HF expectation value
hamiltonian = h2.hamiltonian()
hf_energy = h2.expectation(circuit, hamiltonian)
hf_energy = expectation(circuit, hamiltonian)

# assert h2.e_hf == pytest.approx(hf_energy)
assert h2_ref_energy == pytest.approx(hf_energy)

0 comments on commit ef67e09

Please sign in to comment.