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

Replace the InitialState components by circuits #1374

Merged
merged 28 commits into from
Oct 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
fb4fc42
make chemistry initial states circuits
Cryoris Oct 16, 2020
26299e7
put VSCF circuit in new file
Cryoris Oct 16, 2020
1ba963d
update several tests
Cryoris Oct 16, 2020
b6e2022
fix type change to tuple
Cryoris Oct 18, 2020
546e0ae
merge hf initial state and circuit
Cryoris Oct 19, 2020
4eebf01
merge initstate+circuit
Cryoris Oct 19, 2020
2b8f57f
merge initstate+circuit
Cryoris Oct 19, 2020
8cec413
update EOH
Cryoris Oct 20, 2020
131e5aa
update hhl and qaia
Cryoris Oct 20, 2020
1f696f2
update chc and uvcc
Cryoris Oct 20, 2020
72d3b31
deprecate InitialState components
Cryoris Oct 20, 2020
8019dbb
update varformbased test
Cryoris Oct 20, 2020
96d5eb8
fix running tests & mypy
Cryoris Oct 20, 2020
ac2970d
add reno
Cryoris Oct 20, 2020
e0f7553
update more tests
Cryoris Oct 20, 2020
22b77d1
Merge branch 'master' into initial-state
Cryoris Oct 20, 2020
9a09cf7
do not convert sqlist to array
Cryoris Oct 20, 2020
e8fff1b
fix iqpe test
Cryoris Oct 20, 2020
b94f78e
Merge branch 'master' into initial-state
Cryoris Oct 26, 2020
888047a
fix variable renaming from merge
Cryoris Oct 26, 2020
608aade
move to circuit.lib and use tuple
Cryoris Oct 27, 2020
cbf9fac
Merge branch 'master' into initial-state
Cryoris Oct 27, 2020
3dd1eb7
fix mypy
Cryoris Oct 27, 2020
89ae9ae
Merge branch 'initial-state' of github.com:Cryoris/qiskit-aqua into i…
Cryoris Oct 27, 2020
aeb35de
make _build_bitstr public functions
Cryoris Oct 28, 2020
174c88e
fix misspelling
Cryoris Oct 29, 2020
0be3a42
Merge branch 'master' into initial-state
Cryoris Oct 29, 2020
7ed93bb
Merge branch 'master' into initial-state
Cryoris Oct 29, 2020
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
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,15 @@ from qiskit.aqua.components.optimizers import L_BFGS_B
optimizer = L_BFGS_B()

# setup the initial state for the variational form
from qiskit.chemistry.components.initial_states import HartreeFock
from qiskit.chemistry.circuit.library import HartreeFock
init_state = HartreeFock(num_spin_orbitals, num_particles)

# setup the variational form for VQE
from qiskit.circuit.library import TwoLocal
var_form = TwoLocal(num_qubits, ['ry', 'rz'], 'cz', initial_state=init_state)
var_form = TwoLocal(num_qubits, ['ry', 'rz'], 'cz')

# add the initial state
var_form.compose(init_state, front=True)
Comment on lines -231 to +234
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is a required change in that initial_state will not accommodate a QuantumCircuit? If it is now done this way it seems the var form will not have visibility to the initial state as it had when it was passed directly and it would prepend it itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had a workaround in place where the NLocal circuits expected a InitialState. I'll add support for passing a QuantumCircuit and deprecate the InitialStates once this is merged. We can update the readme sample to use the kwarg again.


# setup and run VQE
from qiskit.aqua.algorithms import VQE
Expand Down
10 changes: 7 additions & 3 deletions qiskit/aqua/algorithms/education/eoh.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import logging

from typing import Optional, Union, Dict, Any
from qiskit import QuantumRegister
from qiskit import QuantumRegister, QuantumCircuit
from qiskit.providers import BaseBackend
from qiskit.providers import Backend
from qiskit.aqua import QuantumInstance
Expand All @@ -42,7 +42,7 @@ class EOH(QuantumAlgorithm):
"""

def __init__(self, operator: LegacyBaseOperator,
initial_state: InitialState,
initial_state: Union[InitialState, QuantumCircuit],
evo_operator: LegacyBaseOperator,
evo_time: float = 1,
num_time_slices: int = 1,
Expand Down Expand Up @@ -84,7 +84,11 @@ def construct_circuit(self):
QuantumCircuit: the circuit.
"""
quantum_registers = QuantumRegister(self._operator.num_qubits, name='q')
qc = self._initial_state.construct_circuit('circuit', quantum_registers)
if isinstance(self._initial_state, QuantumCircuit):
qc = QuantumCircuit(quantum_registers)
qc.compose(self._initial_state, inplace=True)
else:
qc = self._initial_state.construct_circuit('circuit', quantum_registers)

qc += self._evo_operator.evolve(
evo_time=self._evo_time,
Expand Down
7 changes: 5 additions & 2 deletions qiskit/aqua/algorithms/linear_solvers/hhl.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def __init__(
truncate_powerdim: bool = False,
truncate_hermitian: bool = False,
eigs: Optional[Eigenvalues] = None,
init_state: Optional[InitialState] = None,
init_state: Optional[Union[QuantumCircuit, InitialState]] = None,
reciprocal: Optional[Reciprocal] = None,
num_q: int = 0,
num_a: int = 0,
Expand Down Expand Up @@ -206,7 +206,10 @@ def construct_circuit(self, measurement: bool = False) -> QuantumCircuit:
qc = QuantumCircuit(q)

# InitialState
qc += self._init_state.construct_circuit("circuit", q)
if isinstance(self._init_state, QuantumCircuit):
qc.compose(self._init_state, inplace=True)
elif self._init_state is not None:
qc += self._init_state.construct_circuit("circuit", q)

# EigenvalueEstimation (QPE)
qc += self._eigs.construct_circuit("circuit", q)
Expand Down
7 changes: 5 additions & 2 deletions qiskit/aqua/algorithms/minimum_eigen_solvers/iqpe.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class IQPE(QuantumAlgorithm, MinimumEigensolver):

def __init__(self,
operator: Optional[Union[OperatorBase, LegacyBaseOperator]] = None,
state_in: Optional[InitialState] = None,
state_in: Optional[Union[QuantumCircuit, InitialState]] = None,
num_time_slices: int = 1,
num_iterations: int = 1,
expansion_mode: str = 'suzuki',
Expand Down Expand Up @@ -192,7 +192,10 @@ def construct_circuit(self,
self._ancillary_register = a
self._state_register = q
qc = QuantumCircuit(q)
qc += self._state_in.construct_circuit('circuit', q)
if isinstance(self._state_in, QuantumCircuit):
qc.append(self._state_in, q)
else:
qc += self._state_in.construct_circuit('circuit', q)
# hadamard on a[0]
qc.add_register(a)
qc.h(a[0])
Expand Down
3 changes: 2 additions & 1 deletion qiskit/aqua/algorithms/minimum_eigen_solvers/qaoa/qaoa.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import logging
import numpy as np

from qiskit.circuit import QuantumCircuit
from qiskit.providers import BaseBackend
from qiskit.providers import Backend
from qiskit.aqua import QuantumInstance
Expand Down Expand Up @@ -67,7 +68,7 @@ def __init__(self,
operator: Union[OperatorBase, LegacyBaseOperator] = None,
optimizer: Optimizer = None,
p: int = 1,
initial_state: Optional[InitialState] = None,
initial_state: Optional[Union[QuantumCircuit, InitialState]] = None,
mixer: Union[OperatorBase, LegacyBaseOperator] = None,
initial_point: Optional[np.ndarray] = None,
gradient: Optional[Union[GradientBase, Callable[[Union[np.ndarray, List]],
Expand Down
12 changes: 7 additions & 5 deletions qiskit/aqua/algorithms/minimum_eigen_solvers/qaoa/var_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@

"""Global X phases and parameterized problem hamiltonian."""

from typing import Optional
from typing import Optional, Union

import numpy as np

from qiskit import QuantumCircuit
from qiskit.aqua.operators import (OperatorBase, X, I, H, CircuitStateFn,
EvolutionFactory, LegacyBaseOperator)
from qiskit.aqua.components.variational_forms import VariationalForm
Expand All @@ -31,7 +32,7 @@ class QAOAVarForm(VariationalForm):
def __init__(self,
cost_operator: OperatorBase,
p: int,
initial_state: Optional[InitialState] = None,
initial_state: Optional[Union[QuantumCircuit, InitialState]] = None,
mixer_operator: Optional[OperatorBase] = None):
"""
Constructor, following the QAOA paper https://arxiv.org/abs/1411.4028
Expand Down Expand Up @@ -81,9 +82,10 @@ def construct_circuit(self, parameters, q=None):
))

# initialize circuit, possibly based on given register/initial state
if self._initial_state is not None:
stateVector = CircuitStateFn(self._initial_state.construct_circuit('circuit'))
circuit = stateVector.to_circuit_op()
if isinstance(self._initial_state, QuantumCircuit):
circuit = CircuitStateFn(self._initial_state)
elif self._initial_state is not None:
circuit = CircuitStateFn(self._initial_state.construct_circuit('circuit'))
else:
circuit = (H ^ self._num_qubits)

Expand Down
2 changes: 1 addition & 1 deletion qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class QPE(QuantumAlgorithm, MinimumEigensolver):

def __init__(self,
operator: Optional[Union[OperatorBase, LegacyBaseOperator]] = None,
state_in: Optional[InitialState] = None,
state_in: Optional[Union[InitialState, QuantumCircuit]] = None,
iqft: Optional[QuantumCircuit] = None,
num_time_slices: int = 1,
num_ancillae: int = 1,
Expand Down
10 changes: 6 additions & 4 deletions qiskit/aqua/circuits/phase_estimation_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

"""Quantum Phase Estimation Circuit."""

from typing import Optional, List
from typing import Optional, List, Union
import numpy as np

from qiskit import QuantumRegister, QuantumCircuit, ClassicalRegister
Expand All @@ -33,7 +33,7 @@ class PhaseEstimationCircuit:
def __init__(
self,
operator: Optional[WeightedPauliOperator] = None,
state_in: Optional[InitialState] = None,
state_in: Optional[Union[QuantumCircuit, InitialState]] = None,
iqft: Optional[QuantumCircuit] = None,
num_time_slices: int = 1,
num_ancillae: int = 1,
Expand All @@ -48,7 +48,7 @@ def __init__(
"""
Args:
operator: the hamiltonian Operator object
state_in: the InitialState component
state_in: the InitialState component or a quantum circuit
representing the initial quantum state
iqft: the Inverse Quantum Fourier Transform as circuit or
Aqua component
Expand Down Expand Up @@ -158,7 +158,9 @@ def construct_circuit(
qc.add_register(aux)

# initialize state_in
if self._state_in is not None:
if isinstance(self._state_in, QuantumCircuit):
qc.append(self._state_in.to_gate(), q)
elif isinstance(self._state_in, InitialState):
qc.data += self._state_in.construct_circuit('circuit', q).data
elif self._state_in_circuit_factory is not None:
self._state_in_circuit_factory.build(qc, q, aux)
Expand Down
5 changes: 5 additions & 0 deletions qiskit/aqua/components/initial_states/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ def __init__(self,
self._state_vector = normalize_vector(state_vector)
self._state = None

@staticmethod
def _replacement():
return 'Custom(state_vector=vector) is the same as a circuit where the ' \
+ '``initialize(vector/np.linalg.norm(vector))`` method has been called.'

def construct_circuit(self, mode='circuit', register=None):
# pylint: disable=import-outside-toplevel
from qiskit import BasicAer
Expand Down
12 changes: 12 additions & 0 deletions qiskit/aqua/components/initial_states/initial_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
form or in eoh as a trial state to evolve
"""

import warnings
from typing import Optional
# below to allow it for python 3.6.1
try:
Expand All @@ -39,6 +40,17 @@ class InitialState(ABC):
def __init__(self) -> None:
super().__init__()

warnings.warn('The {} class is deprecated as of Aqua 0.9 and will be removed no earlier '
'than 3 months after the release date. Instead, all algorithms and circuits '
'accept a plain QuantumCircuit. {}'.format(
self.__class__.__name__, self._replacement(),
),
category=DeprecationWarning, stacklevel=2)

@staticmethod
def _replacement():
return ''

@abstractmethod
def construct_circuit(self,
mode: str = 'circuit',
Expand Down
8 changes: 8 additions & 0 deletions qiskit/aqua/components/initial_states/var_form_based.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"""The variational form based initial state"""

from typing import Union, List, Dict
import warnings
import numpy as np
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
Expand Down Expand Up @@ -51,6 +52,13 @@ def __init__(self,
self._var_form = var_form
self._var_form_params = params

warnings.warn('The {} class is deprecated as of Aqua 0.9 and will be removed no earlier '
'than 3 months after the release date. Instead, all algorithms and circuits '
'accept a plain QuantumCircuit.'.format(
self.__class__.__name__
),
category=DeprecationWarning, stacklevel=2)

def construct_circuit(self, mode='circuit', register=None):
"""
Construct the statevector of desired initial state.
Expand Down
4 changes: 4 additions & 0 deletions qiskit/aqua/components/initial_states/zero.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ def __init__(self, num_qubits: int) -> None:
validate_min('num_qubits', num_qubits, 1)
self._num_qubits = num_qubits

@staticmethod
def _replacement():
return 'Zero(num_qubits) is the same as a empty QuantumCircuit(num_qubits).'

def construct_circuit(self, mode='circuit', register=None):
if mode == 'vector':
return np.array([1.0] + [0.0] * (np.power(2, self._num_qubits) - 1))
Expand Down
2 changes: 1 addition & 1 deletion qiskit/aqua/operators/legacy/weighted_pauli_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -1250,7 +1250,7 @@ def two_qubit_reduction(operator, num_particles):
"Return the empty operator back.")
return operator

if isinstance(num_particles, list):
if isinstance(num_particles, (tuple, list)):
num_alpha = num_particles[0]
num_beta = num_particles[1]
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from ....components.variational_forms import UCCSD
from ....transformations import Transformation
from ....transformations.fermionic_transformation import FermionicTransformation
from ....components.initial_states import HartreeFock
from ....circuit.library import HartreeFock

from .minimum_eigensolver_factory import MinimumEigensolverFactory

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from qiskit.aqua.algorithms import MinimumEigensolver, VQE
from qiskit.aqua.operators import Z2Symmetries
from qiskit.chemistry import QiskitChemistryError
from qiskit.chemistry.components.initial_states import HartreeFock
from qiskit.chemistry.circuit.library import HartreeFock
from qiskit.chemistry.components.variational_forms import UCCSD
from qiskit.chemistry.core import (Hamiltonian, TransformationType, QubitMappingType,
ChemistryOperator, MolecularGroundStateResult)
Expand Down
39 changes: 39 additions & 0 deletions qiskit/chemistry/circuit/library/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2020.
#
# 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
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""
===================================================================
Chemistry Circuit Library (:mod:`qiskit.chemistry.circuit.library`)
===================================================================

A collection of circuits used as building blocks or inputs of algorithms in chemistry.

.. currentmodule:: qiskit.chemistry.circuit.library

Initial states
==============

.. autosummary::
:toctree: ../stubs/
:nosignatures:

HartreeFock
VSCF

"""

from .initial_states import (
HartreeFock,
VSCF
)

__all__ = ['HartreeFock', 'VSCF']
18 changes: 18 additions & 0 deletions qiskit/chemistry/circuit/library/initial_states/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2020.
#
# 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
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Initial state circuits."""

from .hartree_fock import HartreeFock
from .vscf import VSCF

__all__ = ['HartreeFock', 'VSCF']
Loading