Skip to content

Commit

Permalink
Merge branch 'main' into controlflow/stochastic_swap
Browse files Browse the repository at this point in the history
  • Loading branch information
ewinston committed Oct 4, 2022
2 parents 9d16884 + 53e215c commit 56029b1
Show file tree
Hide file tree
Showing 54 changed files with 1,872 additions and 230 deletions.
1 change: 1 addition & 0 deletions qiskit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
sys.modules["qiskit._accelerate.sparse_pauli_op"] = qiskit._accelerate.sparse_pauli_op
sys.modules["qiskit._accelerate.results"] = qiskit._accelerate.results
sys.modules["qiskit._accelerate.optimize_1q_gates"] = qiskit._accelerate.optimize_1q_gates
sys.modules["qiskit._accelerate.sampled_exp_val"] = qiskit._accelerate.sampled_exp_val


# Extend namespace for backwards compat
Expand Down
15 changes: 14 additions & 1 deletion qiskit/algorithms/eigensolvers/vqd.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def compute_eigenvalues(

eval_time = time() - start_time

self._update_vqd_result(result, opt_result, eval_time, self.ansatz)
self._update_vqd_result(result, opt_result, eval_time, self.ansatz.copy())

if aux_operators is not None:
aux_value = estimate_observables(
Expand Down Expand Up @@ -388,6 +388,7 @@ def _build_vqd_result() -> VQDResult:
result.optimizer_times = []
result.eigenvalues = []
result.optimizer_results = []
result.optimal_circuits = []
return result

@staticmethod
Expand All @@ -400,6 +401,7 @@ def _update_vqd_result(result, opt_result, eval_time, ansatz) -> VQDResult:
result.optimizer_times.append(eval_time)
result.eigenvalues.append(opt_result.fun + 0j)
result.optimizer_results.append(opt_result)
result.optimal_circuits.append(ansatz)
return result


Expand All @@ -414,6 +416,7 @@ def __init__(self) -> None:
self._optimal_points = None
self._optimal_parameters = None
self._optimizer_results = None
self._optimal_circuits = None

@property
def cost_function_evals(self) -> Sequence[int] | None:
Expand Down Expand Up @@ -474,3 +477,13 @@ def optimizer_results(self) -> Sequence[OptimizerResult] | None:
def optimizer_results(self, value: Sequence[OptimizerResult]) -> None:
"""Sets optimizer results"""
self._optimizer_results = value

@property
def optimal_circuits(self) -> list[QuantumCircuit]:
"""The optimal circuits. Along with the optimal parameters,
these can be used to retrieve the different eigenstates."""
return self._optimal_circuits

@optimal_circuits.setter
def optimal_circuits(self, optimal_circuits: list[QuantumCircuit]) -> None:
self._optimal_circuits = optimal_circuits
9 changes: 8 additions & 1 deletion qiskit/algorithms/minimum_eigensolvers/sampling_vqe.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,12 @@ def compute_minimum_eigenvalue(
aux_operators_evaluated = None

return self._build_sampling_vqe_result(
optimizer_result, aux_operators_evaluated, best_measurement, final_state, optimizer_time
self.ansatz.copy(),
optimizer_result,
aux_operators_evaluated,
best_measurement,
final_state,
optimizer_time,
)

def _get_evaluate_energy(
Expand Down Expand Up @@ -306,6 +311,7 @@ def evaluate_energy(parameters):

def _build_sampling_vqe_result(
self,
ansatz: QuantumCircuit,
optimizer_result: OptimizerResult,
aux_operators_evaluated: ListOrDict[tuple[complex, tuple[complex, int]]],
best_measurement: dict[str, Any],
Expand All @@ -323,6 +329,7 @@ def _build_sampling_vqe_result(
result.optimizer_result = optimizer_result
result.best_measurement = best_measurement["best"]
result.eigenstate = final_state
result.optimal_circuit = ansatz
return result


Expand Down
6 changes: 5 additions & 1 deletion qiskit/algorithms/minimum_eigensolvers/vqe.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@ def compute_minimum_eigenvalue(
else:
aux_operators_evaluated = None

return self._build_vqe_result(optimizer_result, aux_operators_evaluated, optimizer_time)
return self._build_vqe_result(
self.ansatz, optimizer_result, aux_operators_evaluated, optimizer_time
)

@classmethod
def supports_aux_operators(cls) -> bool:
Expand Down Expand Up @@ -308,11 +310,13 @@ def _check_operator_ansatz(self, operator: BaseOperator | PauliSumOp):

def _build_vqe_result(
self,
ansatz: QuantumCircuit,
optimizer_result: OptimizerResult,
aux_operators_evaluated: ListOrDict[tuple[complex, tuple[complex, int]]],
optimizer_time: float,
) -> VQEResult:
result = VQEResult()
result.optimal_circuit = ansatz.copy()
result.eigenvalue = optimizer_result.fun
result.cost_function_evals = optimizer_result.nfev
result.optimal_point = optimizer_result.x
Expand Down
33 changes: 18 additions & 15 deletions qiskit/algorithms/observables_evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,24 @@ def estimate_observables(
else:
observables_list = observables

observables_list = _handle_zero_ops(observables_list)
quantum_state = [quantum_state] * len(observables)
if parameter_values is not None:
parameter_values = [parameter_values] * len(observables)
try:
estimator_job = estimator.run(quantum_state, observables_list, parameter_values)
expectation_values = estimator_job.result().values
except Exception as exc:
raise AlgorithmError("The primitive job failed!") from exc

metadata = estimator_job.result().metadata
# Discard values below threshold
observables_means = expectation_values * (np.abs(expectation_values) > threshold)
# zip means and metadata into tuples
observables_results = list(zip(observables_means, metadata))
if len(observables_list) > 0:
observables_list = _handle_zero_ops(observables_list)
quantum_state = [quantum_state] * len(observables)
if parameter_values is not None:
parameter_values = [parameter_values] * len(observables)
try:
estimator_job = estimator.run(quantum_state, observables_list, parameter_values)
expectation_values = estimator_job.result().values
except Exception as exc:
raise AlgorithmError("The primitive job failed!") from exc

metadata = estimator_job.result().metadata
# Discard values below threshold
observables_means = expectation_values * (np.abs(expectation_values) > threshold)
# zip means and metadata into tuples
observables_results = list(zip(observables_means, metadata))
else:
observables_results = []

return _prepare_result(observables_results, observables)

Expand Down
14 changes: 14 additions & 0 deletions qiskit/algorithms/variational_algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
from abc import ABC, abstractmethod
import numpy as np

from qiskit.circuit import QuantumCircuit

from .algorithm_result import AlgorithmResult
from .optimizers import OptimizerResult

Expand Down Expand Up @@ -61,6 +63,7 @@ def __init__(self) -> None:
self._optimal_point = None
self._optimal_parameters = None
self._optimizer_result = None
self._optimal_circuit = None

@property
def optimizer_evals(self) -> Optional[int]:
Expand Down Expand Up @@ -121,3 +124,14 @@ def optimizer_result(self) -> Optional[OptimizerResult]:
def optimizer_result(self, value: OptimizerResult) -> None:
"""Sets optimizer result"""
self._optimizer_result = value

@property
def optimal_circuit(self) -> QuantumCircuit:
"""The optimal circuits. Along with the optimal parameters,
these can be used to retrieve the minimum eigenstate.
"""
return self._optimal_circuit

@optimal_circuit.setter
def optimal_circuit(self, optimal_circuit: QuantumCircuit) -> None:
self._optimal_circuit = optimal_circuit
7 changes: 5 additions & 2 deletions qiskit/circuit/commutation_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ def commute(
"""
# We don't support commutation of conditional gates for now due to bugs in
# CommutativeCancellation. See gh-8553.
if getattr(op1, "condition") is not None or getattr(op2, "condition") is not None:
if (
getattr(op1, "condition", None) is not None
or getattr(op2, "condition", None) is not None
):
return False

# These lines are adapted from dag_dependency and say that two gates over
Expand All @@ -103,7 +106,7 @@ def commute(
if (
getattr(op, "_directive", False)
or op.name in {"measure", "reset", "delay"}
or op.is_parameterized()
or (getattr(op, "is_parameterized", False) and op.is_parameterized())
):
return False

Expand Down
4 changes: 2 additions & 2 deletions qiskit/circuit/quantumcircuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -1834,7 +1834,7 @@ def draw(
# safely forward-referenced.
ax: Optional[typing.Any] = None,
initial_state: bool = False,
cregbundle: bool = True,
cregbundle: bool = None,
wire_order: list = None,
):
"""Draw the quantum circuit. Use the output parameter to choose the drawing format:
Expand Down Expand Up @@ -1916,7 +1916,7 @@ def draw(
initial_state (bool): Optional. Adds ``|0>`` in the beginning of the wire.
Default is False.
cregbundle (bool): Optional. If set True, bundle classical registers.
Default is True.
Default is True, except for when ``output`` is set to ``"text"``.
wire_order (list): Optional. A list of integers used to reorder the display
of the bits. The list must have an entry for every bit with the bits
in the range 0 to (num_qubits + num_clbits).
Expand Down
10 changes: 10 additions & 0 deletions qiskit/compiler/transpiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
from qiskit.transpiler.exceptions import TranspilerError
from qiskit.transpiler.instruction_durations import InstructionDurations, InstructionDurationsType
from qiskit.transpiler.passes import ApplyLayout
from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig
from qiskit.transpiler.passmanager_config import PassManagerConfig
from qiskit.transpiler.preset_passmanagers import (
level_0_pass_manager,
Expand Down Expand Up @@ -80,6 +81,7 @@ def transpile(
unitary_synthesis_method: str = "default",
unitary_synthesis_plugin_config: dict = None,
target: Target = None,
hls_config: Optional[HLSConfig] = None,
init_method: str = None,
optimization_method: str = None,
) -> Union[QuantumCircuit, List[QuantumCircuit]]:
Expand Down Expand Up @@ -260,6 +262,11 @@ def callback_func(**kwargs):
the ``backend`` argument, but if you have manually constructed a
:class:`~qiskit.transpiler.Target` object you can specify it manually here.
This will override the target from ``backend``.
hls_config: An optional configuration class
:class:`~qiskit.transpiler.passes.synthesis.HLSConfig` that will be passed directly
to :class:`~qiskit.transpiler.passes.synthesis.HighLevelSynthesis` transformation pass.
This configuration class allows to specify for various high-level objects the lists of
synthesis algorithms and their parameters.
init_method: The plugin name to use for the ``init`` stage. By default an external
plugin is not used. You can see a list of installed plugins by
using :func:`~.list_stage_plugins` with ``"init"`` for the stage
Expand Down Expand Up @@ -334,6 +341,7 @@ def callback_func(**kwargs):
unitary_synthesis_method,
unitary_synthesis_plugin_config,
target,
hls_config,
init_method,
optimization_method,
)
Expand Down Expand Up @@ -586,6 +594,7 @@ def _parse_transpile_args(
unitary_synthesis_method,
unitary_synthesis_plugin_config,
target,
hls_config,
init_method,
optimization_method,
) -> Tuple[List[Dict], Dict]:
Expand Down Expand Up @@ -676,6 +685,7 @@ def _parse_transpile_args(
"unitary_synthesis_method": unitary_synthesis_method,
"unitary_synthesis_plugin_config": unitary_synthesis_plugin_config,
"target": target,
"hls_config": hls_config,
}.items():
if isinstance(value, list):
unique_dict[key] = value
Expand Down
3 changes: 2 additions & 1 deletion qiskit/converters/circuit_to_dag.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# that they have been altered from the originals.

"""Helper function for converting a circuit to a dag"""
import copy

from qiskit.dagcircuit.dagcircuit import DAGCircuit

Expand Down Expand Up @@ -60,7 +61,7 @@ def circuit_to_dag(circuit):

for instruction in circuit.data:
dagcircuit.apply_operation_back(
instruction.operation.copy(), instruction.qubits, instruction.clbits
copy.deepcopy(instruction.operation), instruction.qubits, instruction.clbits
)

dagcircuit.duration = circuit.duration
Expand Down
3 changes: 2 additions & 1 deletion qiskit/converters/dag_to_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# that they have been altered from the originals.

"""Helper function for converting a dag to a circuit."""
import copy

from qiskit.circuit import QuantumCircuit, CircuitInstruction

Expand Down Expand Up @@ -59,7 +60,7 @@ def dag_to_circuit(dag):
circuit.calibrations = dag.calibrations

for node in dag.topological_op_nodes():
circuit._append(CircuitInstruction(node.op.copy(), node.qargs, node.cargs))
circuit._append(CircuitInstruction(copy.deepcopy(node.op), node.qargs, node.cargs))

circuit.duration = dag.duration
circuit.unit = dag.unit
Expand Down
5 changes: 4 additions & 1 deletion qiskit/quantum_info/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,7 @@
XXDecomposer,
)

from .analysis import hellinger_distance, hellinger_fidelity
from .analysis import (
hellinger_distance,
hellinger_fidelity,
)
2 changes: 1 addition & 1 deletion qiskit/quantum_info/analysis/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2018.
# (C) Copyright IBM 2017, 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand Down
12 changes: 10 additions & 2 deletions qiskit/result/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@
ProbDistribution
QuasiDistribution
Expectation values
==================
.. autosummary::
:toctree: ../stubs/
sampled_expectation_value
Mitigation
==========
.. autosummary::
Expand All @@ -54,8 +62,8 @@
from .utils import marginal_memory
from .counts import Counts

from .distributions.probability import ProbDistribution
from .distributions.quasi import QuasiDistribution
from .distributions import QuasiDistribution, ProbDistribution
from .sampled_expval import sampled_expectation_value
from .mitigation.base_readout_mitigator import BaseReadoutMitigator
from .mitigation.correlated_readout_mitigator import CorrelatedReadoutMitigator
from .mitigation.local_readout_mitigator import LocalReadoutMitigator
2 changes: 2 additions & 0 deletions qiskit/result/distributions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@
"""
Distributions
"""
from .probability import ProbDistribution
from .quasi import QuasiDistribution
Loading

0 comments on commit 56029b1

Please sign in to comment.