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

Commit

Permalink
Merge pull request #1179 from manoelmarques/stable-0.7.5
Browse files Browse the repository at this point in the history
[Stable] Qiskit Aqua Release 0.7.5
  • Loading branch information
woodsp-ibm authored Aug 7, 2020
2 parents baeb4ae + 40613f5 commit 32595ef
Show file tree
Hide file tree
Showing 9 changed files with 315 additions and 4 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,18 @@ Changelog](http://keepachangelog.com/en/1.0.0/).
> - **Fixed**: for any bug fixes.
> - **Security**: in case of vulnerabilities.
[UNRELEASED](https://github.com/Qiskit/qiskit-aqua/compare/0.7.4...HEAD)
[UNRELEASED](https://github.com/Qiskit/qiskit-aqua/compare/0.7.5...HEAD)
========================================================================

[0.7.5](https://github.com/Qiskit/qiskit-aqua/compare/0.7.4...0.7.5) - 2020-08-07
=================================================================================

Deprecated
----------

- Properly deprecate quadratic program ising converter classes (#1178)


[0.7.4](https://github.com/Qiskit/qiskit-aqua/compare/0.7.3...0.7.4) - 2020-08-06
=================================================================================

Expand Down
2 changes: 1 addition & 1 deletion qiskit/aqua/VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.7.4
0.7.5
14 changes: 14 additions & 0 deletions qiskit/aqua/operators/list_ops/summed_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
""" SummedOp Class """

from typing import List, Union, cast
import warnings

import numpy as np

Expand Down Expand Up @@ -160,6 +161,19 @@ def to_legacy_op(self, massive: bool = False) -> LegacyBaseOperator:

return self.combo_fn(legacy_ops) * coeff

def print_details(self):
"""
Print out the operator in details.
Returns:
str: a formatted string describes the operator.
"""
warnings.warn("print_details() is deprecated and will be removed in "
"a future release. Instead you can use .to_legacy_op() "
"and call print_details() on it's output",
DeprecationWarning)
ret = self.to_legacy_op().print_details()
return ret

def equals(self, other: OperatorBase) -> bool:
"""Check if other is equal to self.
Expand Down
8 changes: 7 additions & 1 deletion qiskit/optimization/converters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
IntegerToBinary
QuadraticProgramToQubo
LinearEqualityToPenalty
QuadraticProgramToIsing
IsingToQuadraticProgram
"""

Expand All @@ -40,11 +42,15 @@
from .inequality_to_equality import InequalityToEquality
from .linear_equality_to_penalty import LinearEqualityToPenalty
from .quadratic_program_to_qubo import QuadraticProgramToQubo
from .quadratic_program_to_ising import QuadraticProgramToIsing
from .ising_to_quadratic_program import IsingToQuadraticProgram


__all__ = [
"InequalityToEquality",
"IntegerToBinary",
"QuadraticProgramToQubo",
"LinearEqualityToPenalty"
"LinearEqualityToPenalty",
"QuadraticProgramToIsing",
"IsingToQuadraticProgram"
]
70 changes: 70 additions & 0 deletions qiskit/optimization/converters/ising_to_quadratic_program.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-

# 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.


"""The converter from a ```Operator``` to ``QuadraticProgram``."""

from typing import Optional, Union
import copy
import warnings
import numpy as np # pylint: disable=unused-import

from qiskit.aqua.operators import OperatorBase, WeightedPauliOperator
from ..problems.quadratic_program import QuadraticProgram


class IsingToQuadraticProgram:
"""Convert a qubit operator into a quadratic program"""

def __init__(self, linear: bool = False) -> None:
r"""
Args:
linear: If linear is True, :math:`x^2` is treated as a linear term
since :math:`x^2 = x` for :math:`x \in \{0,1\}`.
Else, :math:`x^2` is treat as a quadratic term.
The default value is False.
"""
self._qubit_op = None
self._offset = 0.0
self._num_qubits = 0
self._qubo_matrix = None # type: Optional[np.ndarray]
self._qp = None # type: Optional[QuadraticProgram]
self._linear = linear
warnings.warn("The IsingToQuadraticProgram class is deprecated and "
"will be removed in a future release. Use the "
".from_ising() method on the QuadraticProgram class "
"instead.", DeprecationWarning)

def encode(self, qubit_op: Union[OperatorBase, WeightedPauliOperator], offset: float = 0.0
) -> QuadraticProgram:
"""Convert a qubit operator and a shift value into a quadratic program
Args:
qubit_op: The qubit operator to be converted into a
:class:`~qiskit.optimization.problems.quadratic_program.QuadraticProgram`
offset: The shift value of the qubit operator
Returns:
QuadraticProgram converted from the input qubit operator and the shift value
Raises:
QiskitOptimizationError: If there are Pauli Xs in any Pauli term
QiskitOptimizationError: If there are more than 2 Pauli Zs in any Pauli term
NotImplementedError: If the input operator is a ListOp
"""
self._qubit_op = qubit_op
self._offset = copy.deepcopy(offset)
self._num_qubits = qubit_op.num_qubits
self._qp = QuadraticProgram()
self._qp.from_ising(qubit_op, offset,
linear=self._linear)
return self._qp
49 changes: 49 additions & 0 deletions qiskit/optimization/converters/quadratic_program_to_ising.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-

# 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.

"""The converter from an ```QuadraticProgram``` to ``Operator``."""

from typing import Tuple, Optional
import warnings

from qiskit.aqua.operators import OperatorBase
from ..problems.quadratic_program import QuadraticProgram


class QuadraticProgramToIsing:
"""Convert an optimization problem into a qubit operator."""

def __init__(self) -> None:
"""Initialize the internal data structure."""
self._src = None # type: Optional[QuadraticProgram]
warnings.warn("The QuadraticProgramToIsing class is deprecated and "
"will be removed in a future release. Use the "
".to_ising() method on a QuadraticProgram object "
"instead.", DeprecationWarning)

def encode(self, op: QuadraticProgram) -> Tuple[OperatorBase, float]:
"""Convert a problem into a qubit operator
Args:
op: The optimization problem to be converted. Must be an unconstrained problem with
binary variables only.
Returns:
The qubit operator of the problem and the shift value.
Raises:
QiskitOptimizationError: If a variable type is not binary.
QiskitOptimizationError: If constraints exist in the problem.
"""

self._src = op
return self._src.to_ising()
25 changes: 25 additions & 0 deletions qiskit/optimization/problems/quadratic_program.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from collections import defaultdict
from enum import Enum
from math import fsum
import warnings

from docplex.mp.constr import (LinearConstraint as DocplexLinearConstraint,
QuadraticConstraint as DocplexQuadraticConstraint,
Expand Down Expand Up @@ -774,6 +775,30 @@ def export_as_lp_string(self) -> str:
"""
return self.to_docplex().export_as_lp_string()

def pprint_as_string(self) -> str:
"""Returns the quadratic program as a string in Docplex's pretty print format.
Returns:
A string representing the quadratic program.
"""
warnings.warn("The pprint_as_string method is deprecated and will be "
"removed in a future release. Instead use the"
"to_docplex() method and run pprint_as_string() on that "
"output", DeprecationWarning)
return self.to_docplex().pprint_as_string()

def prettyprint(self, out: Optional[str] = None) -> None:
"""Pretty prints the quadratic program to a given output stream (None = default).
Args:
out: The output stream or file name to print to.
if you specify a file name, the output file name is has '.mod' as suffix.
"""
warnings.warn("The prettyprint method is deprecated and will be "
"removed in a future release. Instead use the"
"to_docplex() method and run prettyprint() on that "
"output", DeprecationWarning)
self.to_docplex().prettyprint(out)

def read_from_lp_file(self, filename: str) -> None:
"""Loads the quadratic program from a LP file.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
deprecations:
- |
The ising convert classes
:class:`qiskit.optimization.converters.QuadraticProgramToIsing` and
:class:`qiskit.optimization.converters.IsingToQuadraticProgram` have
been deprecated and will be removed in a future release. Instead the
:class:`qiskit.optimization.QuadraticProgram` methods
:meth:`~qiskit.optimization.QuadraticProgram.to_ising` and
:meth:`~qiskit.optimization.QuadraticPrgraom.from_ising` should be used
instead.
- |
The ``pprint_as_string`` method for
:class:`qiskit.optimization.QuadraticProgram` has been deprecated and will
be removed in a future release. Instead you should just run
``.pprint_as_string()`` on the output from
:meth:`~qiskit.optimization.QuadraticProgram.to_docplex`
- |
The ``prettyprint`` method for
:class:`qiskit.optimization.QuadraticProgram` has been deprecated and will
be removed in a future release. Instead you should just run
``.prettyprint()`` on the output from
:meth:`~qiskit.optimization.QuadraticProgram.to_docplex`
117 changes: 116 additions & 1 deletion test/optimization/test_converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
from qiskit.optimization.algorithms.admm_optimizer import ADMMParameters
from qiskit.optimization.algorithms.optimization_algorithm import OptimizationResultStatus
from qiskit.optimization.converters import (InequalityToEquality, IntegerToBinary,
LinearEqualityToPenalty)
LinearEqualityToPenalty, QuadraticProgramToIsing,
IsingToQuadraticProgram)
from qiskit.optimization.problems import Constraint, Variable

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -559,6 +560,120 @@ def test_linear_equality_to_penalty_decode(self):
self.assertListEqual(infeasible_result.variable_names, ['x', 'y', 'z'])
self.assertDictEqual(infeasible_result.variables_dict, {'x': 1.0, 'y': 1.0, 'z': 1.0})

def test_empty_problem_deprecated(self):
""" Test empty problem """
op = QuadraticProgram()
conv = InequalityToEquality()
op = conv.encode(op)
conv = IntegerToBinary()
op = conv.encode(op)
conv = LinearEqualityToPenalty()
op = conv.encode(op)
conv = QuadraticProgramToIsing()
_, shift = conv.encode(op)
self.assertEqual(shift, 0.0)

def test_valid_variable_type_deprecated(self):
"""Validate the types of the variables for QuadraticProgramToIsing."""
# Integer variable
with self.assertRaises(QiskitOptimizationError):
op = QuadraticProgram()
op.integer_var(0, 10, "int_var")
conv = QuadraticProgramToIsing()
_ = conv.encode(op)
# Continuous variable
with self.assertRaises(QiskitOptimizationError):
op = QuadraticProgram()
op.continuous_var(0, 10, "continuous_var")
conv = QuadraticProgramToIsing()
_ = conv.encode(op)

def test_optimizationproblem_to_ising_deprecated(self):
""" Test optimization problem to operators"""
op = QuadraticProgram()
for i in range(4):
op.binary_var(name='x{}'.format(i))
linear = {}
for x in op.variables:
linear[x.name] = 1
op.maximize(0, linear, {})
linear = {}
for i, x in enumerate(op.variables):
linear[x.name] = i + 1
op.linear_constraint(linear, Constraint.Sense.EQ, 3, 'sum1')
penalize = LinearEqualityToPenalty(penalty=1e5)
op2ope = QuadraticProgramToIsing()
op2 = penalize.encode(op)
qubitop, offset = op2ope.encode(op2)

self.assertEqual(qubitop, QUBIT_OP_MAXIMIZE_SAMPLE)
self.assertEqual(offset, OFFSET_MAXIMIZE_SAMPLE)

def test_ising_to_quadraticprogram_linear_deprecated(self):
""" Test optimization problem to operators with linear=True"""
op = QUBIT_OP_MAXIMIZE_SAMPLE
offset = OFFSET_MAXIMIZE_SAMPLE

op2qp = IsingToQuadraticProgram(linear=True)
quadratic = op2qp.encode(op, offset)

self.assertEqual(len(quadratic.variables), 4)
self.assertEqual(len(quadratic.linear_constraints), 0)
self.assertEqual(len(quadratic.quadratic_constraints), 0)
self.assertEqual(quadratic.objective.sense, quadratic.objective.Sense.MINIMIZE)
self.assertAlmostEqual(quadratic.objective.constant, 900000)

linear_matrix = np.zeros((1, 4))
linear_matrix[0, 0] = -500001
linear_matrix[0, 1] = -800001
linear_matrix[0, 2] = -900001
linear_matrix[0, 3] = -800001

quadratic_matrix = np.zeros((4, 4))
quadratic_matrix[0, 1] = 400000
quadratic_matrix[0, 2] = 600000
quadratic_matrix[1, 2] = 1200000
quadratic_matrix[0, 3] = 800000
quadratic_matrix[1, 3] = 1600000
quadratic_matrix[2, 3] = 2400000

np.testing.assert_array_almost_equal(
quadratic.objective.linear.coefficients.toarray(), linear_matrix
)
np.testing.assert_array_almost_equal(
quadratic.objective.quadratic.coefficients.toarray(), quadratic_matrix
)

def test_ising_to_quadraticprogram_quadratic_deprecated(self):
""" Test optimization problem to operators with linear=False"""
op = QUBIT_OP_MAXIMIZE_SAMPLE
offset = OFFSET_MAXIMIZE_SAMPLE

op2qp = IsingToQuadraticProgram(linear=False)
quadratic = op2qp.encode(op, offset)

self.assertEqual(len(quadratic.variables), 4)
self.assertEqual(len(quadratic.linear_constraints), 0)
self.assertEqual(len(quadratic.quadratic_constraints), 0)
self.assertEqual(quadratic.objective.sense, quadratic.objective.Sense.MINIMIZE)
self.assertAlmostEqual(quadratic.objective.constant, 900000)

quadratic_matrix = np.zeros((4, 4))
quadratic_matrix[0, 0] = -500001
quadratic_matrix[0, 1] = 400000
quadratic_matrix[0, 2] = 600000
quadratic_matrix[0, 3] = 800000
quadratic_matrix[1, 1] = -800001
quadratic_matrix[1, 2] = 1200000
quadratic_matrix[1, 3] = 1600000
quadratic_matrix[2, 2] = -900001
quadratic_matrix[2, 3] = 2400000
quadratic_matrix[3, 3] = -800001

np.testing.assert_array_almost_equal(
quadratic.objective.quadratic.coefficients.toarray(), quadratic_matrix
)


if __name__ == '__main__':
unittest.main()

0 comments on commit 32595ef

Please sign in to comment.