Compare commits
16 Commits
507e5c80f8
...
21ce177d79
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21ce177d79 | ||
|
|
3711b0f088 | ||
|
|
969e944e6d | ||
|
|
1279c596b0 | ||
|
|
4576f9e088 | ||
|
|
aa013df77e | ||
|
|
1d4af3c87e | ||
|
|
bba6d26968 | ||
|
|
65eb545639 | ||
|
|
d1c2884763 | ||
|
|
f118201037 | ||
|
|
cf8216bc05 | ||
|
|
19442a3868 | ||
|
|
58930223b0 | ||
|
|
48d8b5b996 | ||
|
|
12c67f0c42 |
@@ -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
34
poetry.lock
generated
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user