Skip to content
This repository has been archived by the owner on Dec 7, 2021. It is now read-only.

Check operator is empty before using it #680

Merged
merged 4 commits into from
Sep 12, 2019
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ Changelog](http://keepachangelog.com/en/1.0.0/).
[UNRELEASED](https://github.com/Qiskit/qiskit-aqua/compare/0.6.0...HEAD)
========================================================================

Fixed
-------

- A bug where `UCCSD` might generate an empty operator and try to evolve it. (#680)


[0.6.0](https://github.com/Qiskit/qiskit-aqua/compare/0.5.5...0.6.0) - 2019-08-22
=================================================================================

Expand Down
16 changes: 16 additions & 0 deletions qiskit/aqua/operators/matrix_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from scipy import linalg as scila
from qiskit import QuantumCircuit # pylint: disable=unused-import

from qiskit.aqua import AquaError
from .base_operator import BaseOperator

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -240,7 +241,12 @@ def evaluate_with_result(self, result, statevector_mode=True,
Returns:
float: the mean value
float: the standard deviation
Raises:
AquaError: if Operator is empty
"""
if self.is_empty():
raise AquaError("Operator is empty, check the operator.")

del use_simulator_operator_mode # unused
avg, std_dev = 0.0, 0.0
quantum_state = np.asarray(result.get_statevector(circuit_name_prefix + 'psi'))
Expand All @@ -257,7 +263,12 @@ def evaluate_with_statevector(self, quantum_state):
Returns:
float: the mean value
float: the standard deviation
Raises:
AquaError: if Operator is empty
"""
if self.is_empty():
raise AquaError("Operator is empty, check the operator.")

avg = np.vdot(quantum_state, self._matrix.dot(quantum_state))
return avg, 0.0

Expand Down Expand Up @@ -322,8 +333,13 @@ def evolve(self, state_in, evo_time=0, num_time_slices=0, expansion_mode='trotte
numpy.array: Return the matrix vector multiplication result.
Raises:
ValueError: Invalid arguments
AquaError: if Operator is empty
"""
from .op_converter import to_weighted_pauli_operator

if self.is_empty():
raise AquaError("Operator is empty, check the operator.")

# pylint: disable=no-member
if num_time_slices < 0 or not isinstance(num_time_slices, int):
raise ValueError('Number of time slices should be a non-negative integer.')
Expand Down
27 changes: 25 additions & 2 deletions qiskit/aqua/operators/weighted_pauli_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ def __init__(self, paulis, basis=None, z2_symmetries=None, atol=1e-12, name=None
[(pauli[1], [i]) for i, pauli in enumerate(paulis)] if basis is None else basis
# combine the paulis and remove those with zero weight
self.simplify()
self._z2_symmetries = z2_symmetries
self._aer_paulis = None
self._atol = atol

Expand Down Expand Up @@ -594,7 +593,11 @@ def evaluate_with_statevector(self, quantum_state):
Returns:
float: the mean value
float: the standard deviation
Raises:
AquaError: if Operator is empty
"""
if self.is_empty():
raise AquaError("Operator is empty, check the operator.")
# convert to matrix first?
from .op_converter import to_matrix_operator
mat_op = to_matrix_operator(self)
Expand Down Expand Up @@ -627,10 +630,14 @@ def construct_evaluation_circuit(self, wave_function, statevector_mode,
circuit_name_prefix + Pauli string

Raises:
AquaError: if Operator is empty
AquaError: Can not find quantum register with `q` as the name and do not provide
quantum register explicitly
AquaError: The provided qr is not in the wave_function
"""
if self.is_empty():
raise AquaError("Operator is empty, check the operator.")

from qiskit.aqua.utils.run_circuits import find_regs_by_name

if qr is None:
Expand Down Expand Up @@ -685,7 +692,12 @@ def evaluation_instruction(self, statevector_mode, use_simulator_operator_mode=F

Returns:
dict: Pauli-instruction pair.

Raises:
AquaError: if Operator is empty
"""
if self.is_empty():
raise AquaError("Operator is empty, check the operator.")
instructions = {}
qr = QuantumRegister(self.num_qubits)
qc = QuantumCircuit(qr)
Expand Down Expand Up @@ -729,7 +741,12 @@ def evaluate_with_result(self, result, statevector_mode, use_simulator_operator_
Returns:
float: the mean value
float: the standard deviation

Raises:
AquaError: if Operator is empty
"""
if self.is_empty():
raise AquaError("Operator is empty, check the operator.")

avg, std_dev, variance = 0.0, 0.0, 0.0
if statevector_mode:
Expand Down Expand Up @@ -837,7 +854,11 @@ def evolve(self, state_in=None, evo_time=0, num_time_slices=1, quantum_registers
QuantumCircuit: The constructed circuit.
Raises:
AquaError: quantum_registers must be in the provided state_in circuit
AquaError: if operator is empty
"""
if self.is_empty():
raise AquaError("Operator is empty, can not evolve.")

if state_in is not None and quantum_registers is not None:
if not state_in.has_register(quantum_registers):
raise AquaError("quantum_registers must be in the provided state_in circuit.")
Expand Down Expand Up @@ -877,8 +898,10 @@ def evolve_instruction(self, evo_time=0, num_time_slices=1,
Raises:
ValueError: Number of time slices should be a non-negative integer
NotImplementedError: expansion mode not supported

AquaError: if operator is empty
"""
if self.is_empty():
raise AquaError("Operator is empty, can not build evolve instruction.")
# pylint: disable=no-member
if num_time_slices <= 0 or not isinstance(num_time_slices, int):
raise ValueError('Number of time slices should be a non-negative integer.')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,24 @@ def __init__(self, num_qubits, depth, num_orbitals, num_particles,

self._logging_construct_circuit = True

@property
def single_excitations(self):
"""
Getter of single excitation list
Returns:
list[list[int]]: single excitation list
"""
return self._single_excitations

@property
def double_excitations(self):
"""
Getter of double excitation list
Returns:
list[list[int]]: double excitation list
"""
return self._double_excitations

def _build_hopping_operators(self):
if logger.isEnabledFor(logging.DEBUG):
TextProgressBar(sys.stderr)
Expand All @@ -179,7 +197,20 @@ def _build_hopping_operators(self):
self._num_particles, self._qubit_mapping,
self._two_qubit_reduction, self._z2_symmetries),
num_processes=aqua_globals.num_processes)
hopping_ops = [qubit_op for qubit_op in results if qubit_op is not None]
hopping_ops = []
s_e_list = []
d_e_list = []
for op, index in results:
if op is not None and not op.is_empty():
hopping_ops.append(op)
if len(index) == 2: # for double excitation
s_e_list.append(index)
else: # for double excitation
d_e_list.append(index)

self._single_excitations = s_e_list
self._double_excitations = d_e_list

num_parameters = len(hopping_ops) * self._depth
return hopping_ops, num_parameters

Expand Down Expand Up @@ -215,7 +246,7 @@ def _build_hopping_operator(index, num_orbitals, num_particles, qubit_mapping,
if qubit_op is None:
logger.debug('Excitation (%s) is skipped since it is not commuted '
'with symmetries', ','.join([str(x) for x in index]))
return qubit_op
return qubit_op, index

def construct_circuit(self, parameters, q=None):
"""
Expand Down