Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ target-version = "py311"
line-length = 100

[tool.ruff.lint]
extend-select = ["I", "PERF"]
extend-select = ["I", "PERF", "UP"]
preview = false #TODO: set back to true

[tool.ruff.lint.isort]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import random
import warnings
from collections.abc import Callable
from functools import partial
from typing import Callable, Dict, List, Tuple, Union

import matplotlib.pyplot as plt
import networkx as nx
import numpy as np
from networkx.algorithms import approximation

# Type alias for measurement data structure (see AdaptiveShotAllocator.measurements)
MeasurementData = List[List[Dict[Tuple[int, int], int]]]
MeasurementData = list[list[dict[tuple[int, int], int]]]

"""
Helper functions for Pauli operator commutation and Bayesian statistics calculations.
Expand Down Expand Up @@ -48,9 +48,7 @@ def commute(a: str, b: str, qwc: bool = True) -> bool:
# BAYESIAN STATISTICS (closed formulas from Appendix B of arXiv:2110.15339v6)


def term_variance_estimate(
term_idx: int, measurements: Union[MeasurementData, None] = None
) -> float:
def term_variance_estimate(term_idx: int, measurements: MeasurementData | None = None) -> float:
"""
Estimate variance for a single Pauli term.
See Eq 14 in Appendix B of "Adaptive Estimation of Quantum Observables (arXiv:2110.15339v6)
Expand All @@ -69,9 +67,7 @@ def term_variance_estimate(
return 4 * ((x0 + 1) * (x1 + 1)) / ((x0 + x1 + 2) * (x0 + x1 + 3))


def terms_covariance_estimate(
i: int, j: int, measurements: Union[MeasurementData, None] = None
) -> float:
def terms_covariance_estimate(i: int, j: int, measurements: MeasurementData | None = None) -> float:
"""
Estimate covariance between two Pauli terms.
See Eq 25-6 in Appendix B of "Adaptive Estimation of Quantum Observables (arXiv:2110.15339v6)
Expand Down Expand Up @@ -139,14 +135,14 @@ class AdaptiveShotAllocator:
"""

num_terms: int
paulis: List[str]
coeffs: List[float]
paulis: list[str]
coeffs: list[float]
graph: nx.Graph
cliq: List[List[int]]
cliq: list[list[int]]
measurements: MeasurementData
shots: Union[List[int], None]
shots: list[int] | None

def __init__(self, paulis: List[str], coeffs: List[float]) -> None:
def __init__(self, paulis: list[str], coeffs: list[float]) -> None:
"""
Initialize the AdaptiveShotAllocator with Pauli terms and their coefficients.

Expand Down Expand Up @@ -327,7 +323,7 @@ def _update_graph_weights(self) -> None:
)
self.graph[i][j]["weight"] = weight

def incremental_shot_allocation(self, num_shots: int) -> List[int]:
def incremental_shot_allocation(self, num_shots: int) -> list[int]:
"""
Propose allocation of measurement shots to cliques using greedy minimization of
the estimated error.
Expand Down Expand Up @@ -415,9 +411,7 @@ def error_estimate(self) -> float:

return np.sqrt(variance_estimate)

def expectation_from_measurements(
self, measurements: Union[MeasurementData, None] = None
) -> float:
def expectation_from_measurements(self, measurements: MeasurementData | None = None) -> float:
"""
Calculate the energy expectation value from measurement results
for the different Pauli string observables.
Expand Down Expand Up @@ -515,7 +509,7 @@ def _validate_measurements(self, measurements: MeasurementData) -> bool:
)
return True

def shots_from_measurements(self, measurements: MeasurementData) -> List[int]:
def shots_from_measurements(self, measurements: MeasurementData) -> list[int]:
"""
Extract the number of shots allocated to each clique from measurement data.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
experiments on Amazon Braket.
"""

from typing import List, Union

from braket.aws import AwsDevice
from braket.circuits import Circuit, Observable
from braket.devices import LocalSimulator
Expand All @@ -29,10 +27,10 @@ def observable_from_string(pauli_string: str) -> Observable:


def run_fixed_allocation(
device: Union[LocalSimulator, AwsDevice],
device: LocalSimulator | AwsDevice,
circuit: Circuit,
estimator: AdaptiveShotAllocator,
shot_allocation: List[int],
shot_allocation: list[int],
) -> MeasurementData:
"""
Run experiment with a specific shot allocation.
Expand Down Expand Up @@ -96,7 +94,7 @@ def run_fixed_allocation(


def run_adaptive_allocation(
device: Union[LocalSimulator, AwsDevice],
device: LocalSimulator | AwsDevice,
circuit: Circuit,
estimator: AdaptiveShotAllocator,
shots_per_round: int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
from collections import Counter
from typing import List, Tuple

import numpy as np

Expand All @@ -26,7 +25,7 @@ def create_bell_inequality_circuits(
angle_A: float = 0,
angle_B: float = np.pi / 3,
angle_C: float = 2 * np.pi / 3,
) -> List[Circuit]:
) -> list[Circuit]:
"""Create the three circuits for Bell's inequality. Default angles will give maximum violation
of Bell's inequality.

Expand All @@ -48,10 +47,10 @@ def create_bell_inequality_circuits(


def run_bell_inequality(
circuits: List[Circuit],
circuits: list[Circuit],
device: Device,
shots: int = 1_000,
) -> List[QuantumTask]:
) -> list[QuantumTask]:
"""Submit three Bell circuits to a device.

Args:
Expand All @@ -67,8 +66,8 @@ def run_bell_inequality(


def get_bell_inequality_results(
tasks: List[QuantumTask], verbose: bool = True
) -> Tuple[List[Counter], float, float, float]:
tasks: list[QuantumTask], verbose: bool = True
) -> tuple[list[Counter], float, float, float]:
"""Return Bell task results after post-processing.

Args:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
# 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.
from typing import Dict

import numpy as np

Expand Down Expand Up @@ -61,7 +60,7 @@ def bernstein_vazirani_circuit(hidden_string: str) -> Circuit:
return bv_circuit


def get_bernstein_vazirani_results(task: QuantumTask) -> Dict[str, float]:
def get_bernstein_vazirani_results(task: QuantumTask) -> dict[str, float]:
"""Return the probabilities and corresponding bitstrings.

Args:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
# language governing permissions and limitations under the License.

from collections import Counter
from typing import List, Tuple

import numpy as np

Expand All @@ -32,7 +31,7 @@ def create_chsh_inequality_circuits(
a2: float = 0,
b1: float = np.pi / 4,
b2: float = 3 * np.pi / 4,
) -> List[Circuit]:
) -> list[Circuit]:
"""Create the four circuits for CHSH inequality. Default angles will give maximum violation of
the inequality.

Expand All @@ -55,10 +54,10 @@ def create_chsh_inequality_circuits(


def run_chsh_inequality(
circuits: List[Circuit],
circuits: list[Circuit],
device: Device,
shots: int = 1_000,
) -> List[QuantumTask]:
) -> list[QuantumTask]:
"""Submit four CHSH circuits to a device.

Args:
Expand All @@ -74,8 +73,8 @@ def run_chsh_inequality(


def get_chsh_results(
tasks: List[QuantumTask], verbose: bool = True
) -> Tuple[float, List[Counter], float, float, float]:
tasks: list[QuantumTask], verbose: bool = True
) -> tuple[float, list[Counter], float, float, float]:
"""Return CHSH task results after post-processing.

Args:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
# 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.
from typing import Dict

import numpy as np

Expand Down Expand Up @@ -109,7 +108,7 @@ def deutsch_jozsa(oracle: Circuit) -> Circuit:
return circ


def get_deutsch_jozsa_results(task: QuantumTask) -> Dict[str, float]:
def get_deutsch_jozsa_results(task: QuantumTask) -> dict[str, float]:
"""Return the probabilities and corresponding bitstrings.

Args:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import Tuple

from braket.circuits import Circuit, circuit


Expand Down Expand Up @@ -99,7 +97,7 @@ def multi_control_not_constructor(
n_qubit: int,
decompose_ccnot: bool,
is_outermost_call: bool = True,
) -> Tuple[Circuit, int]:
) -> tuple[Circuit, int]:
"""Recursive constructor of a multi-contol Not circuit (generalized Toffoli gate).
Ref: https://arxiv.org/abs/1904.01671

Expand Down
8 changes: 4 additions & 4 deletions src/braket/experimental/algorithms/hhl/hhl.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
[2] Wikipedia: https://en.wikipedia.org/wiki/HHL_algorithm
"""

from typing import Any, Dict, List, Optional
from typing import Any

import numpy as np
from qiskit.circuit import QuantumCircuit
Expand All @@ -47,7 +47,7 @@ def hhl_circuit(
matrix: np.ndarray,
b_vector: np.ndarray,
num_clock_qubits: int = 2,
scaling_factor: Optional[float] = None,
scaling_factor: float | None = None,
) -> Circuit:
"""Construct the full HHL circuit for solving Ax = b.

Expand Down Expand Up @@ -147,7 +147,7 @@ def get_hhl_results(
b_vector: np.ndarray,
num_clock_qubits: int = 2,
verbose: bool = False,
) -> Dict[str, Any]:
) -> dict[str, Any]:
"""Post-process results from an HHL run.

Extracts the solution state by post-selecting on the ancilla qubit
Expand Down Expand Up @@ -330,7 +330,7 @@ def _compute_hamiltonian_simulation(matrix: np.ndarray, t: float) -> np.ndarray:

def _decompose_controlled_unitary(
unitary: np.ndarray,
targets: List[int],
targets: list[int],
) -> Circuit:
"""Decompose a controlled-U gate into native 1q/2q gates via Qiskit transpilation.

Expand Down
26 changes: 13 additions & 13 deletions src/braket/experimental/algorithms/qc_qmc/classical_qmc.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import copy
import multiprocessing as mp
import os
from collections.abc import Callable
from dataclasses import dataclass
from typing import Callable, List, Tuple

import pennylane as qml
from openfermion.circuits.low_rank import low_rank_two_body_decomposition
Expand All @@ -17,11 +17,11 @@ class ChemicalProperties:
nuclear_repulsion: float # nuclear repulsion energy
v_0: np.ndarray # one-body term stored as np.ndarray with mean-field subtraction
h_chem: np.ndarray # one-body term stored as np.ndarray, without mean-field subtraction
v_gamma: List[np.ndarray] # 1j * l_gamma
l_gamma: List[np.ndarray] # Cholesky vector decomposed from two-body terms
v_gamma: list[np.ndarray] # 1j * l_gamma
l_gamma: list[np.ndarray] # Cholesky vector decomposed from two-body terms
mf_shift: np.ndarray # mean-field shift
lambda_l: List[np.ndarray] # eigenvalues of Cholesky vectors
u_l: List[np.ndarray] # eigenvectors of Cholesky vectors
lambda_l: list[np.ndarray] # eigenvalues of Cholesky vectors
u_l: list[np.ndarray] # eigenvectors of Cholesky vectors


def classical_qmc(
Expand All @@ -31,7 +31,7 @@ def classical_qmc(
trial: np.ndarray,
prop: ChemicalProperties,
max_pool: int = 8,
) -> Tuple[float, float]:
) -> tuple[float, float]:
"""Classical Auxiliary-Field Quantum Monte Carlo.

Args:
Expand Down Expand Up @@ -82,7 +82,7 @@ def hartree_fock_energy(trial: np.ndarray, prop: ChemicalProperties) -> float:
return e_hf


def full_imag_time_evolution_wrapper(args: Tuple) -> Callable:
def full_imag_time_evolution_wrapper(args: tuple) -> Callable:
return full_imag_time_evolution(*args)


Expand All @@ -94,7 +94,7 @@ def full_imag_time_evolution(
e_shift: float,
walker: np.ndarray,
weight: float,
) -> Tuple[List[float], float]:
) -> tuple[list[float], float]:
"""Imaginary time evolution of a single walker.

Args:
Expand Down Expand Up @@ -128,7 +128,7 @@ def imag_time_propogator(
weight: float,
prop: ChemicalProperties,
e_shift: float,
) -> Tuple[float, np.ndarray, float]:
) -> tuple[float, np.ndarray, float]:
"""Propagate a walker by one time step.

Args:
Expand Down Expand Up @@ -203,7 +203,7 @@ def local_energy(h1e: np.ndarray, eri: np.ndarray, green_funcs: np.ndarray, enuc
return e1 + e2 + enuc


def reortho(A: np.ndarray) -> Tuple[np.ndarray, float]:
def reortho(A: np.ndarray) -> tuple[np.ndarray, float]:
"""Reorthogonalise a MxN matrix A. Performs a QR decomposition of A. Note that for consistency
elsewhere we want to preserve detR > 0 which is not guaranteed. We thus factor the signs of the
diagonal of R into Q.
Expand Down Expand Up @@ -309,13 +309,13 @@ def chemistry_preparation(

def propagate_walker(
x: np.ndarray,
v_0: List[np.ndarray],
v_gamma: List[np.ndarray],
v_0: list[np.ndarray],
v_gamma: list[np.ndarray],
mf_shift: np.ndarray,
dtau: float,
trial: np.ndarray,
walker: np.ndarray,
green_funcs: List[np.ndarray],
green_funcs: list[np.ndarray],
) -> np.ndarray:
r"""Update the walker forward in imaginary time.

Expand Down
Loading
Loading