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

Commit

Permalink
Native circuit library (#920)
Browse files Browse the repository at this point in the history
* remove param comparison

* make ry/ryrz use circlib

* Revert "make ry/ryrz use circlib"

This reverts commit b6d9801.

* deprecate feature maps and varforms (where possible)

* remove swaprz import

* add tests for VQE

* un-deprecate RawFeatureMap / FeatureMap

* test qsvm on circlib

* qsvm to use circlib circuit

* vqe2iqpe test on circuit and lib

* test vqc on circlib

* fix leftover deprecations

* test vqe on circlib and filter warnings

* qoem on circuits, add param dict to results

* use cirlib for tests, fix deprecation warnings

* unused import

* var form based to accept circuits

* num parameters check in varform setter

* update pylint dict, add Zoufal, rm not used ones

* fix deprecated arg: reps instead of depth

* fix spell

* num params check in energy_eval

* data_encoding -> data_preparation

* fix deprecation warnings, remove test_ry as redundant

* move IBMQ to local import?

* update to new circlib names

* update leftover tests to new names

* add changelog note

* fix last 2 deprecation warnings

* update deprecation warnings in feature_map

* fix Äquivalenzverbot typo

* steve's comments

Co-authored-by: Manoel Marques <manoel@us.ibm.com>
  • Loading branch information
Cryoris and manoelmarques authored Apr 30, 2020
1 parent c5e816c commit 97c9871
Show file tree
Hide file tree
Showing 35 changed files with 618 additions and 545 deletions.
7 changes: 4 additions & 3 deletions .pylintdict
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ ae
aer
Aer's
aerjob
Äquivalenzverbot
aij
al
algo
Expand Down Expand Up @@ -688,6 +689,7 @@ trotterized
trotterizing
trunc
ub
Über
ucc
uccd
UCCS
Expand Down Expand Up @@ -753,8 +755,6 @@ zmatrix
zv
ZZ
zzz
äguivalenzverbot
über
ucc
uccd
UCCS
Expand All @@ -763,5 +763,6 @@ versioning
vir
Watrous's
wf
vir
Ze
vir
Zoufal
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ Removed
- arithmetic circuits in qiskit/aqua/circuits (#895)
- boolean logic gates (#896)
- quantum Fourier transformation (#909)
- the RY, RYRZ and SwapRZ variational forms (#920)
- the PauliExpansion, First- and SecondOrderExpansion feature maps (#920)

Fixed
-----
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,8 @@ from qiskit.chemistry.components.initial_states import HartreeFock
init_state = HartreeFock(num_qubits, num_spin_orbitals, num_particles)

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

# setup and run VQE
from qiskit.aqua.algorithms import VQE
Expand Down
11 changes: 10 additions & 1 deletion qiskit/aqua/algorithms/classifiers/qsvm/qsvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"""The Quantum SVM algorithm."""

from typing import Dict, Optional, Union
import warnings
import logging
import sys

Expand All @@ -29,7 +30,7 @@
from qiskit.aqua import AquaError
from qiskit.aqua.utils.dataset_helper import get_num_classes
from qiskit.aqua.utils import split_dataset_to_data_and_labels
from qiskit.aqua.components.feature_maps import FeatureMap
from qiskit.aqua.components.feature_maps import FeatureMap, RawFeatureVector
from qiskit.aqua.components.multiclass_extensions import MulticlassExtension
from ._qsvm_estimator import _QSVM_Estimator
from ._qsvm_binary import _QSVM_Binary
Expand Down Expand Up @@ -129,6 +130,14 @@ def __init__(self, feature_map: Union[QuantumCircuit, FeatureMap],
self.feature_map_params_x = ParameterVector('x', self.feature_map.feature_dimension)
self.feature_map_params_y = ParameterVector('y', self.feature_map.feature_dimension)
else:
if not isinstance(feature_map, RawFeatureVector):
warnings.warn("""
The {} object as input for the QSVM is deprecated as of 0.7.0 and will
be removed no earlier than 3 months after the release.
You should pass a QuantumCircuit object instead.
See also qiskit.circuit.library.data_preparation for a collection
of suitable circuits.""".format(type(feature_map)),
DeprecationWarning, stacklevel=2)
self.feature_map_params_x = ParameterVector('x', feature_map.feature_dimension)
self.feature_map_params_y = ParameterVector('y', feature_map.feature_dimension)

Expand Down
28 changes: 15 additions & 13 deletions qiskit/aqua/algorithms/classifiers/vqc.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from qiskit.aqua.utils import split_dataset_to_data_and_labels
from qiskit.aqua.algorithms import VQAlgorithm
from qiskit.aqua.components.optimizers import Optimizer
from qiskit.aqua.components.feature_maps import FeatureMap
from qiskit.aqua.components.feature_maps import FeatureMap, RawFeatureVector
from qiskit.aqua.components.variational_forms import VariationalForm

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -85,12 +85,12 @@ def __init__(
# VariationalForm is not deprecated on level of the VQAlgorithm yet as UCCSD still
# derives from there, therefore we're adding a warning here
if isinstance(var_form, VariationalForm):
warnings.warn('The qiskit.aqua.components.variational_form.VariationalForm object as '
'input for the VQC is deprecated as of 0.7.0 and will be removed no '
'earlier than 3 months after the release. You should pass a '
'QuantumCircuit object instead. '
'See also qiskit.circuit.library.n_local for a collection of '
'suitable circuits.',
warnings.warn("""
The {} object as input for the VQC is deprecated as of 0.7.0 and will
be removed no earlier than 3 months after the release.
You should pass a QuantumCircuit object instead.
See also qiskit.circuit.library.n_local for a collection
of suitable circuits.""".format(type(feature_map)),
DeprecationWarning, stacklevel=2)

super().__init__(
Expand Down Expand Up @@ -532,12 +532,14 @@ def feature_map(self, feature_map: Union[FeatureMap, QuantumCircuit]):
self._feature_map_params = list(feature_map.parameters)
self._feature_map = feature_map
elif isinstance(feature_map, FeatureMap):
warnings.warn('The qiskit.aqua.components.feature_maps.FeatureMap object is deprecated '
'as of 0.7.0 and will be removed no earlier than 3 months after the '
'release. You should pass a QuantumCircuit object instead. '
'See also qiskit.circuit.library.data_preparation for a collection of '
'suitable circuits.',
DeprecationWarning, stacklevel=2)
# raw feature vector is not yet replaced
if not isinstance(feature_map, RawFeatureVector):
warnings.warn('The qiskit.aqua.components.feature_maps.FeatureMap object is '
'deprecated as of 0.7.0 and will be removed no earlier than 3 months '
'after the release. You should pass a QuantumCircuit object instead. '
'See also qiskit.circuit.library.data_preparation for a collection '
'of suitable circuits.',
DeprecationWarning, stacklevel=2)

self._num_qubits = feature_map.num_qubits
self._feature_map_params = ParameterVector('x', length=feature_map.feature_dimension)
Expand Down
39 changes: 23 additions & 16 deletions qiskit/aqua/algorithms/distribution_learners/qgan.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""
Quantum Generative Adversarial Network.
`Quantum Generative Adversarial Networks for learning and loading random distributions
<https://www.nature.com/articles/s41534-019-0223-2>`_
"""
"""Quantum Generative Adversarial Network."""

from typing import Optional, Union
import csv
Expand All @@ -26,13 +22,17 @@
import numpy as np
from scipy.stats import entropy

from qiskit.circuit import QuantumCircuit
from qiskit.providers import BaseBackend
from qiskit.aqua import QuantumInstance, AquaError, aqua_globals
from qiskit.aqua.algorithms import QuantumAlgorithm
from qiskit.aqua.components.neural_networks.discriminative_network import DiscriminativeNetwork
from qiskit.aqua.components.neural_networks.generative_network import GenerativeNetwork
from qiskit.aqua.components.neural_networks.quantum_generator import QuantumGenerator
from qiskit.aqua.components.neural_networks.numpy_discriminator import NumPyDiscriminator
from qiskit.aqua.components.optimizers import Optimizer
from qiskit.aqua.components.uncertainty_models import UnivariateVariationalDistribution
from qiskit.aqua.components.uncertainty_models import MultivariateVariationalDistribution
from qiskit.aqua.utils.dataset_helper import discretize_and_truncate
from qiskit.aqua.utils.validation import validate_min

Expand All @@ -42,11 +42,9 @@


class QGAN(QuantumAlgorithm):
"""
The Quantum Generative Adversarial Network algorithm.
"""The Quantum Generative Adversarial Network algorithm.
`qGAN <https://arxiv.org/abs/1904.00043>`__ is a hybrid quantum-classical algorithm used
for generative modeling tasks.
The qGAN [1] is a hybrid quantum-classical algorithm used for generative modeling tasks.
This adaptive algorithm uses the interplay of a generative
:class:`~qiskit.aqua.components.neural_networks.GenerativeNetwork` and a
Expand All @@ -59,6 +57,12 @@ class QGAN(QuantumAlgorithm):
samples. Eventually, the quantum generator learns the training data's underlying probability
distribution. The trained quantum generator loads a quantum state which is a model of the
target distribution.
**References:**
[1] Zoufal et al.,
`Quantum Generative Adversarial Networks for learning and loading random distributions
<https://www.nature.com/articles/s41534-019-0223-2>`_
"""

def __init__(self, data: np.ndarray, bounds: Optional[np.ndarray] = None,
Expand Down Expand Up @@ -188,16 +192,19 @@ def generator(self):
return self._generator

# pylint: disable=unused-argument
def set_generator(self, generator_circuit=None,
generator_init_params=None, generator_optimizer=None):
"""
Initialize generator.
def set_generator(self, generator_circuit: Optional[Union[QuantumCircuit,
UnivariateVariationalDistribution,
MultivariateVariationalDistribution]
] = None,
generator_init_params: Optional[np.ndarray] = None,
generator_optimizer: Optional[Optimizer] = None):
"""Initialize generator.
Args:
generator_circuit (VariationalForm): parameterized quantum circuit which sets
generator_circuit: parameterized quantum circuit which sets
the structure of the quantum generator
generator_init_params(numpy.ndarray): initial parameters for the generator circuit
generator_optimizer (Optimizer): optimizer to be used for the training of the generator
generator_init_params: initial parameters for the generator circuit
generator_optimizer: optimizer to be used for the training of the generator
"""
self._generator = QuantumGenerator(self._bounds, self._num_qubits,
generator_circuit, generator_init_params,
Expand Down
29 changes: 18 additions & 11 deletions qiskit/aqua/algorithms/minimum_eigen_solvers/vqe.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@

from qiskit import ClassicalRegister, QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.circuit.library import RealAmplitudes
from qiskit.providers import BaseBackend
from qiskit.aqua import QuantumInstance, AquaError
from qiskit.aqua.algorithms import QuantumAlgorithm
from qiskit.aqua.operators import (OperatorBase, ExpectationBase, ExpectationFactory, StateFn,
CircuitStateFn, LegacyBaseOperator, ListOp, I, CircuitSampler)
from qiskit.aqua.components.optimizers import Optimizer, SLSQP
from qiskit.aqua.components.variational_forms import VariationalForm, RY
from qiskit.aqua.components.variational_forms import VariationalForm
from qiskit.aqua.utils.validation import validate_min
from ..vq_algorithm import VQAlgorithm, VQResult
from .minimum_eigen_solver import MinimumEigensolver, MinimumEigensolverResult
Expand Down Expand Up @@ -117,10 +118,8 @@ def __init__(self,
"""
validate_min('max_evals_grouped', max_evals_grouped, 1)
if var_form is None:
# TODO after ansatz refactor num qubits can be set later so we do not have to have
# an operator to create a default
if operator is not None:
var_form = RY(operator.num_qubits)
var_form = RealAmplitudes()

if optimizer is None:
optimizer = SLSQP()
Expand Down Expand Up @@ -227,6 +226,7 @@ def _check_operator_varform(self):
# try to set the number of qubits on the variational form, if possible
try:
self.var_form.num_qubits = self.operator.num_qubits
self._var_form_params = list(self.var_form.parameters)
except AttributeError:
raise AquaError("The number of qubits of the variational form does not match "
"the operator, and the variational form does not allow setting "
Expand Down Expand Up @@ -311,8 +311,7 @@ def construct_circuit(self,
if not self.expectation:
self._try_set_expectation_value_from_factory()

observable_meas = self.expectation.convert(StateFn(self.operator,
is_measurement=True))
observable_meas = self.expectation.convert(StateFn(self.operator, is_measurement=True))
ansatz_circuit_op = CircuitStateFn(wave_function)
return observable_meas.compose(ansatz_circuit_op).reduce()

Expand All @@ -331,6 +330,8 @@ def _run(self) -> 'VQEResult':
if self.operator is None:
raise AquaError("The operator was never provided.")

self._check_operator_varform()

self._quantum_instance.circuit_summary = True

self._eval_count = 0
Expand All @@ -345,6 +346,7 @@ def _run(self) -> 'VQEResult':
self._ret['min_val'] = vqresult.optimal_value
self._ret['opt_params'] = vqresult.optimal_point
self._ret['eval_time'] = vqresult.optimizer_time
self._ret['opt_params_dict'] = vqresult.optimal_parameters

if self._ret['num_optimizer_evals'] is not None and \
self._eval_count >= self._ret['num_optimizer_evals']:
Expand Down Expand Up @@ -396,7 +398,6 @@ def compute_minimum_eigenvalue(
super().compute_minimum_eigenvalue(operator, aux_operators)
return self._run()

# This is the objective function to be passed to the optimizer that is used for evaluation
def _energy_evaluation(self, parameters: Union[List[float], np.ndarray]
) -> Union[float, List[float]]:
"""Evaluate energy at given parameters for the variational form.
Expand All @@ -408,11 +409,18 @@ def _energy_evaluation(self, parameters: Union[List[float], np.ndarray]
Returns:
Energy of the hamiltonian of each parameter.
Raises:
RuntimeError: If the variational form has no parameters.
"""
if not self._expect_op:
self._expect_op = self.construct_circuit(self._var_form_params)

num_parameters = self.var_form.num_parameters
if self._var_form.num_parameters == 0:
raise RuntimeError('The var_form cannot have 0 parameters.')

parameter_sets = np.reshape(parameters, (-1, num_parameters))
# Create dict associating each parameter with the lists of parameterization values for it
param_bindings = dict(zip(self._var_form_params, parameter_sets.transpose().tolist()))
Expand Down Expand Up @@ -448,10 +456,9 @@ def get_optimal_circuit(self) -> QuantumCircuit:
if 'opt_params' not in self._ret:
raise AquaError("Cannot find optimal circuit before running the "
"algorithm to find optimal params.")
if isinstance(self.var_form, QuantumCircuit):
param_dict = dict(zip(self._var_form_params, self._ret['opt_params']))
return self.var_form.assign_parameters(param_dict)
return self._var_form.construct_circuit(self._ret['opt_params'])
if isinstance(self.var_form, VariationalForm):
return self._var_form.construct_circuit(self._ret['opt_params'])
return self.var_form.assign_parameters(self._ret['opt_params_dict'])

def get_optimal_vector(self) -> Union[List[float], Dict[str, int]]:
"""Get the simulation outcome of the optimal circuit. """
Expand Down
23 changes: 15 additions & 8 deletions qiskit/aqua/algorithms/vq_algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

from qiskit.circuit import QuantumCircuit, ParameterVector
from qiskit.providers import BaseBackend
from qiskit.aqua import QuantumInstance, AquaError
from qiskit.aqua import QuantumInstance
from qiskit.aqua.algorithms import AlgorithmResult, QuantumAlgorithm
from qiskit.aqua.components.optimizers import Optimizer, SLSQP
from qiskit.aqua.components.variational_forms import VariationalForm
Expand Down Expand Up @@ -73,6 +73,7 @@ def __init__(self,
self._cost_fn = cost_fn
self._initial_point = initial_point
self._var_form = var_form
self._var_form_params = None
if var_form is not None:
self.var_form = var_form

Expand All @@ -97,12 +98,7 @@ def var_form(self, var_form: Optional[Union[QuantumCircuit, VariationalForm]]):
self._var_form_params = None
self._var_form = var_form
else:
raise ValueError(
"Unsupported type '{}' of var_form".format(
type(var_form) if var_form else var_form))

if var_form is not None and len(self._var_form_params) == 0:
raise AquaError('Passing a variational form with no parameters is not supported.')
raise ValueError('Unsupported type "{}" of var_form'.format(type(var_form)))

@property
def optimizer(self) -> Optional[Optimizer]:
Expand Down Expand Up @@ -164,7 +160,7 @@ def find_minimum(self,

nparms = var_form.num_parameters

if hasattr(var_form, 'parameter_bounds'):
if hasattr(var_form, 'parameter_bounds') and var_form.parameter_bounds is not None:
bounds = var_form.parameter_bounds
else:
bounds = [(None, None)] * nparms
Expand Down Expand Up @@ -210,6 +206,7 @@ def find_minimum(self,
result.optimizer_time = eval_time
result.optimal_value = opt_val
result.optimal_point = opt_params
result.optimal_parameters = dict(zip(self._var_form_params, opt_params))

return result

Expand Down Expand Up @@ -311,6 +308,16 @@ def optimal_point(self, value: np.ndarray) -> None:
""" Sets optimal point """
self.data['optimal_point'] = value

@property
def optimal_parameters(self) -> dict:
""" Returns the optimal parameters in a dictionary """
return self.get('optimal_parameters')

@optimal_parameters.setter
def optimal_parameters(self, value: dict) -> None:
""" Sets optimal parameters """
self.data['optimal_parameters'] = value

def __getitem__(self, key: object) -> object:
if key == 'num_optimizer_evals':
warnings.warn('num_optimizer_evals deprecated, use optimizer_evals property.',
Expand Down
Loading

0 comments on commit 97c9871

Please sign in to comment.