Compare commits

...

16 Commits

Author SHA1 Message Date
Stefano Carrazza
21ce177d79 Merge pull request #142 from qiboteam/dependabot/pip/urllib3-2.7.0
Some checks failed
Build wheels / build (ubuntu-latest, 3.11) (push) Has been cancelled
Build wheels / build (ubuntu-latest, 3.12) (push) Has been cancelled
Build wheels / build (ubuntu-latest, 3.13) (push) Has been cancelled
docs / evaluate-label (push) Has been cancelled
Tests / check (push) Has been cancelled
docs / deploy-docs (push) Has been cancelled
Tests / build (ubuntu-latest, 3.11) (push) Has been cancelled
Tests / build (ubuntu-latest, 3.12) (push) Has been cancelled
Tests / build (ubuntu-latest, 3.13) (push) Has been cancelled
chore(deps-dev): bump urllib3 from 2.6.3 to 2.7.0
2026-05-13 10:52:30 +04:00
dependabot[bot]
3711b0f088 chore(deps-dev): bump urllib3 from 2.6.3 to 2.7.0
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.6.3 to 2.7.0.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.6.3...2.7.0)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.7.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-13 06:27:43 +00:00
Mattia Robbiano
969e944e6d Merge pull request #131 from qiboteam/fix_contraction
refactor: use direct TN contraction for symbolic expectation values
2026-05-05 01:59:49 +00:00
mattia-robbiano
1279c596b0 Merge remote-tracking branch 'origin/main' into fix_contraction
Merge fix_contraction branch with latest changes from main.
2026-05-04 17:18:36 +02:00
Stefano Carrazza
4576f9e088 Merge pull request #141 from qiboteam/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2026-04-28 09:22:47 +08:00
pre-commit-ci[bot]
aa013df77e [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/pycqa/isort: 8.0.1 → 9.0.0a3](https://github.com/pycqa/isort/compare/8.0.1...9.0.0a3)
2026-04-27 21:58:40 +00:00
Stefano Carrazza
1d4af3c87e Merge pull request #140 from qiboteam/dependabot/pip/mako-1.3.11
chore(deps): bump mako from 1.3.10 to 1.3.11
2026-04-20 07:50:48 +02:00
dependabot[bot]
bba6d26968 chore(deps): bump mako from 1.3.10 to 1.3.11
Bumps [mako](https://github.com/sqlalchemy/mako) from 1.3.10 to 1.3.11.
- [Release notes](https://github.com/sqlalchemy/mako/releases)
- [Changelog](https://github.com/sqlalchemy/mako/blob/main/CHANGES)
- [Commits](https://github.com/sqlalchemy/mako/commits)

---
updated-dependencies:
- dependency-name: mako
  dependency-version: 1.3.11
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-20 05:09:54 +00:00
Stefano Carrazza
65eb545639 Merge pull request #139 from qiboteam/dependabot/pip/pytest-9.0.3
chore(deps-dev): bump pytest from 8.4.2 to 9.0.3
2026-04-15 08:56:33 +00:00
dependabot[bot]
d1c2884763 chore(deps-dev): bump pytest from 8.4.2 to 9.0.3
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.4.2 to 9.0.3.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.4.2...9.0.3)

---
updated-dependencies:
- dependency-name: pytest
  dependency-version: 9.0.3
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-15 04:05:52 +00:00
mattia-robbiano
f118201037 fix: setting user defined optimizer 2026-02-27 16:12:55 +02:00
pre-commit-ci[bot]
cf8216bc05 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-02-18 09:12:13 +00:00
mattia-robbiano
19442a3868 fix: forgot to reset state object in computing different observables 2026-02-18 10:11:57 +01:00
mattia-robbiano
58930223b0 fix: forgot to reset state object in computing different observables 2026-02-18 10:05:58 +01:00
pre-commit-ci[bot]
48d8b5b996 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-02-18 08:37:01 +00:00
mattia-robbiano
12c67f0c42 refactor: use direct TN contraction for symbolic expectation values 2026-02-18 09:32:34 +01:00
4 changed files with 33 additions and 57 deletions

View File

@@ -14,7 +14,7 @@ repos:
hooks: hooks:
- id: black - id: black
- repo: https://github.com/pycqa/isort - repo: https://github.com/pycqa/isort
rev: 8.0.1 rev: 9.0.0a3
hooks: hooks:
- id: isort - id: isort
args: ["--profile", "black"] args: ["--profile", "black"]

34
poetry.lock generated
View File

@@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 2.3.3 and should not be changed by hand. # This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand.
[[package]] [[package]]
name = "alabaster" name = "alabaster"
@@ -1733,14 +1733,14 @@ files = [
[[package]] [[package]]
name = "mako" name = "mako"
version = "1.3.10" version = "1.3.11"
description = "A super-fast templating language that borrows the best ideas from the existing templating languages." description = "A super-fast templating language that borrows the best ideas from the existing templating languages."
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["main"] groups = ["main"]
files = [ files = [
{file = "mako-1.3.10-py3-none-any.whl", hash = "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59"}, {file = "mako-1.3.11-py3-none-any.whl", hash = "sha256:e372c6e333cf004aa736a15f425087ec977e1fcbd2966aae7f17c8dc1da27a77"},
{file = "mako-1.3.10.tar.gz", hash = "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28"}, {file = "mako-1.3.11.tar.gz", hash = "sha256:071eb4ab4c5010443152255d77db7faa6ce5916f35226eb02dc34479b6858069"},
] ]
[package.dependencies] [package.dependencies]
@@ -2770,7 +2770,7 @@ files = [
[package.dependencies] [package.dependencies]
latexcodec = ">=1.0.4" latexcodec = ">=1.0.4"
pyyaml = ">=3.1" pyyaml = ">=3.01"
[[package]] [[package]]
name = "pybtex-docutils" name = "pybtex-docutils"
@@ -2848,20 +2848,20 @@ diagrams = ["jinja2", "railroad-diagrams"]
[[package]] [[package]]
name = "pytest" name = "pytest"
version = "8.4.2" version = "9.0.3"
description = "pytest: simple powerful testing with Python" description = "pytest: simple powerful testing with Python"
optional = false optional = false
python-versions = ">=3.9" python-versions = ">=3.10"
groups = ["tests"] groups = ["tests"]
files = [ files = [
{file = "pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79"}, {file = "pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9"},
{file = "pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01"}, {file = "pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c"},
] ]
[package.dependencies] [package.dependencies]
colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""}
iniconfig = ">=1" iniconfig = ">=1.0.1"
packaging = ">=20" packaging = ">=22"
pluggy = ">=1.5,<2" pluggy = ">=1.5,<2"
pygments = ">=2.7.2" pygments = ">=2.7.2"
@@ -3906,14 +3906,14 @@ markers = {dev = "python_version == \"3.11\""}
[[package]] [[package]]
name = "urllib3" name = "urllib3"
version = "2.6.3" version = "2.7.0"
description = "HTTP library with thread-safe connection pooling, file post, and more." description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false optional = false
python-versions = ">=3.9" python-versions = ">=3.10"
groups = ["docs"] groups = ["dev", "docs"]
files = [ files = [
{file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, {file = "urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897"},
{file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, {file = "urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c"},
] ]
[package.extras] [package.extras]
@@ -3941,4 +3941,4 @@ qmatchatea = ["qmatchatea"]
[metadata] [metadata]
lock-version = "2.1" lock-version = "2.1"
python-versions = ">=3.11,<3.14" python-versions = ">=3.11,<3.14"
content-hash = "ffcf3cfc548f248b95a0ef4c341c5ce07329be8d5f2a79f207be42f2c54b8cbf" content-hash = "c481f345e729c8a67b6869092ce73b465f6ae8ad9594be8b8ff7590fdeeba60b"

View File

@@ -54,7 +54,7 @@ ipython = "^8.34.0"
optional = true optional = true
[tool.poetry.group.tests.dependencies] [tool.poetry.group.tests.dependencies]
pytest = "^8.0.0" pytest = ">=8,<10"
pytest-cov = "^4.1.0" pytest-cov = "^4.1.0"
pytest-env = "^1.1.3" pytest-env = "^1.1.3"

View File

@@ -210,7 +210,8 @@ def exp_value_observable_symbolic(
This method takes a Qibo circuit, converts it to a Quimb tensor network circuit, and evaluates the expectation value This method takes a Qibo circuit, converts it to a Quimb tensor network circuit, and evaluates the expectation value
of a Hamiltonian specified by three lists of strings: operators, sites, and coefficients. of a Hamiltonian specified by three lists of strings: operators, sites, and coefficients.
The expectation value is computed by summing the contributions from each term in the Hamiltonian, where each term's The expectation value is computed by summing the contributions from each term in the Hamiltonian, where each term's
expectation is calculated using Quimb's `local_expectation` function. expectation is calculated applying gates to the tensor network representation of the circuit and contracting it
with the respective bra.
Each operator string must act on all different qubits, i.e., for each term, the corresponding sites tuple must contain unique qubit indices. Each operator string must act on all different qubits, i.e., for each term, the corresponding sites tuple must contain unique qubit indices.
Example: operators_list = ['xyz', 'xyz'], sites_list = [(1,2,3), (1,2,3)], coeffs_list = [1, 2] Example: operators_list = ['xyz', 'xyz'], sites_list = [(1,2,3), (1,2,3)], coeffs_list = [1, 2]
@@ -230,6 +231,7 @@ def exp_value_observable_symbolic(
float float
The real part of the expectation value of the Hamiltonian on the given circuit state. The real part of the expectation value of the Hamiltonian on the given circuit state.
""" """
# Validate that no term acts multiple times on the same qubit (no repeated indices in a sites tuple) # Validate that no term acts multiple times on the same qubit (no repeated indices in a sites tuple)
for sites in sites_list: for sites in sites_list:
if len(sites) != len(set(sites)): if len(sites) != len(set(sites)):
@@ -238,29 +240,25 @@ def exp_value_observable_symbolic(
f"Invalid Hamiltonian term sites {sites}: repeated qubit indices are not allowed " f"Invalid Hamiltonian term sites {sites}: repeated qubit indices are not allowed "
"within a single term (e.g. (0,0,0) is invalid).", "within a single term (e.g. (0,0,0) is invalid).",
) )
quimb_circuit = self._qibo_circuit_to_quimb(
circuit_tn = self._qibo_circuit_to_quimb(
circuit, circuit,
quimb_circuit_type=self.circuit_ansatz, quimb_circuit_type=self.circuit_ansatz,
gate_opts={"max_bond": self.max_bond_dimension, "cutoff": self.svd_cutoff}, gate_opts={"max_bond": self.max_bond_dimension, "cutoff": self.svd_cutoff},
) ).psi
bra = circuit_tn.copy().H
expectation_value = 0.0 expectation_value = 0.0
for opstr, sites, coeff in zip(operators_list, sites_list, coeffs_list): for opstr, sites, coeff in zip(operators_list, sites_list, coeffs_list):
ket = circuit_tn.copy()
ops = self._string_to_quimb_operator(opstr)
coeff = coeff.real coeff = coeff.real
for label, site in zip(opstr, sites):
op_matrix = qu.pauli(label.upper())
ket.gate_(op_matrix, site)
exp_value = (bra & ket).contract(optimize=self.contraction_optimizer).real
expectation_value = expectation_value + coeff * exp_value
exp_values = quimb_circuit.local_expectation( return expectation_value
ops,
where=sites,
backend=self.backend,
optimize=self.contractions_optimizer,
simplify_sequence="R",
)
expectation_value = expectation_value + coeff * exp_values
return self.real(expectation_value)
def _qibo_circuit_to_quimb( def _qibo_circuit_to_quimb(
@@ -313,27 +311,6 @@ def _qibo_circuit_to_quimb(
return circ return circ
def _string_to_quimb_operator(self, op_str):
"""
Convert a Pauli string (e.g. 'xzy') to a Quimb operator using '&' chaining.
Parameters
----------
op_str : str
A string like 'xzy', where each character is one of 'x', 'y', 'z', 'i'.
Returns
-------
qu_op : quimb.Qarray
The corresponding Quimb operator.
"""
op_str = op_str.lower()
op = qu.pauli(op_str[0])
for c in op_str[1:]:
op = op & qu.pauli(c)
return op
CLASSES_ROOTS = {"numpy": "Numpy", "torch": "PyTorch", "jax": "Jax"} CLASSES_ROOTS = {"numpy": "Numpy", "torch": "PyTorch", "jax": "Jax"}
METHODS = { METHODS = {
@@ -343,7 +320,6 @@ METHODS = {
"execute_circuit": execute_circuit, "execute_circuit": execute_circuit,
"exp_value_observable_symbolic": exp_value_observable_symbolic, "exp_value_observable_symbolic": exp_value_observable_symbolic,
"_qibo_circuit_to_quimb": _qibo_circuit_to_quimb, "_qibo_circuit_to_quimb": _qibo_circuit_to_quimb,
"_string_to_quimb_operator": _string_to_quimb_operator,
"circuit_ansatz": circuit_ansatz, "circuit_ansatz": circuit_ansatz,
} }