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

Commit

Permalink
Replace the InitialState components by circuits (#1374)
Browse files Browse the repository at this point in the history
* make chemistry initial states circuits

* put VSCF circuit in new file

* update several tests

* fix type change to tuple

* merge hf initial state and circuit

* merge initstate+circuit

* update EOH

* update hhl and qaia

* update chc and uvcc

* deprecate InitialState components

* update varformbased test

* fix running tests & mypy

* add reno

* fix iqpe test

* fix variable renaming from merge

* move to circuit.lib and use tuple

- move the initial state circuit to chemistry.circuit.library
- globally replace num_particles by a tuple instead of list of integers

* make _build_bitstr public functions
  • Loading branch information
Cryoris authored Oct 30, 2020
1 parent e581d80 commit d88d0ad
Show file tree
Hide file tree
Showing 55 changed files with 710 additions and 216 deletions.
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)

# 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

0 comments on commit d88d0ad

Please sign in to comment.