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

Commit 32595ef

Browse files
authored
Merge pull request #1179 from manoelmarques/stable-0.7.5
[Stable] Qiskit Aqua Release 0.7.5
2 parents baeb4ae + 40613f5 commit 32595ef

File tree

9 files changed

+315
-4
lines changed

9 files changed

+315
-4
lines changed

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,18 @@ Changelog](http://keepachangelog.com/en/1.0.0/).
1515
> - **Fixed**: for any bug fixes.
1616
> - **Security**: in case of vulnerabilities.
1717
18-
[UNRELEASED](https://github.com/Qiskit/qiskit-aqua/compare/0.7.4...HEAD)
18+
[UNRELEASED](https://github.com/Qiskit/qiskit-aqua/compare/0.7.5...HEAD)
1919
========================================================================
2020

21+
[0.7.5](https://github.com/Qiskit/qiskit-aqua/compare/0.7.4...0.7.5) - 2020-08-07
22+
=================================================================================
23+
24+
Deprecated
25+
----------
26+
27+
- Properly deprecate quadratic program ising converter classes (#1178)
28+
29+
2130
[0.7.4](https://github.com/Qiskit/qiskit-aqua/compare/0.7.3...0.7.4) - 2020-08-06
2231
=================================================================================
2332

qiskit/aqua/VERSION.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.7.4
1+
0.7.5

qiskit/aqua/operators/list_ops/summed_op.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
""" SummedOp Class """
1616

1717
from typing import List, Union, cast
18+
import warnings
1819

1920
import numpy as np
2021

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

161162
return self.combo_fn(legacy_ops) * coeff
162163

164+
def print_details(self):
165+
"""
166+
Print out the operator in details.
167+
Returns:
168+
str: a formatted string describes the operator.
169+
"""
170+
warnings.warn("print_details() is deprecated and will be removed in "
171+
"a future release. Instead you can use .to_legacy_op() "
172+
"and call print_details() on it's output",
173+
DeprecationWarning)
174+
ret = self.to_legacy_op().print_details()
175+
return ret
176+
163177
def equals(self, other: OperatorBase) -> bool:
164178
"""Check if other is equal to self.
165179

qiskit/optimization/converters/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
IntegerToBinary
3333
QuadraticProgramToQubo
3434
LinearEqualityToPenalty
35+
QuadraticProgramToIsing
36+
IsingToQuadraticProgram
3537
3638
"""
3739

@@ -40,11 +42,15 @@
4042
from .inequality_to_equality import InequalityToEquality
4143
from .linear_equality_to_penalty import LinearEqualityToPenalty
4244
from .quadratic_program_to_qubo import QuadraticProgramToQubo
45+
from .quadratic_program_to_ising import QuadraticProgramToIsing
46+
from .ising_to_quadratic_program import IsingToQuadraticProgram
4347

4448

4549
__all__ = [
4650
"InequalityToEquality",
4751
"IntegerToBinary",
4852
"QuadraticProgramToQubo",
49-
"LinearEqualityToPenalty"
53+
"LinearEqualityToPenalty",
54+
"QuadraticProgramToIsing",
55+
"IsingToQuadraticProgram"
5056
]
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# This code is part of Qiskit.
4+
#
5+
# (C) Copyright IBM 2020.
6+
#
7+
# This code is licensed under the Apache License, Version 2.0. You may
8+
# obtain a copy of this license in the LICENSE.txt file in the root directory
9+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
10+
#
11+
# Any modifications or derivative works of this code must retain this
12+
# copyright notice, and modified files need to carry a notice indicating
13+
# that they have been altered from the originals.
14+
15+
16+
"""The converter from a ```Operator``` to ``QuadraticProgram``."""
17+
18+
from typing import Optional, Union
19+
import copy
20+
import warnings
21+
import numpy as np # pylint: disable=unused-import
22+
23+
from qiskit.aqua.operators import OperatorBase, WeightedPauliOperator
24+
from ..problems.quadratic_program import QuadraticProgram
25+
26+
27+
class IsingToQuadraticProgram:
28+
"""Convert a qubit operator into a quadratic program"""
29+
30+
def __init__(self, linear: bool = False) -> None:
31+
r"""
32+
Args:
33+
linear: If linear is True, :math:`x^2` is treated as a linear term
34+
since :math:`x^2 = x` for :math:`x \in \{0,1\}`.
35+
Else, :math:`x^2` is treat as a quadratic term.
36+
The default value is False.
37+
"""
38+
self._qubit_op = None
39+
self._offset = 0.0
40+
self._num_qubits = 0
41+
self._qubo_matrix = None # type: Optional[np.ndarray]
42+
self._qp = None # type: Optional[QuadraticProgram]
43+
self._linear = linear
44+
warnings.warn("The IsingToQuadraticProgram class is deprecated and "
45+
"will be removed in a future release. Use the "
46+
".from_ising() method on the QuadraticProgram class "
47+
"instead.", DeprecationWarning)
48+
49+
def encode(self, qubit_op: Union[OperatorBase, WeightedPauliOperator], offset: float = 0.0
50+
) -> QuadraticProgram:
51+
"""Convert a qubit operator and a shift value into a quadratic program
52+
53+
Args:
54+
qubit_op: The qubit operator to be converted into a
55+
:class:`~qiskit.optimization.problems.quadratic_program.QuadraticProgram`
56+
offset: The shift value of the qubit operator
57+
Returns:
58+
QuadraticProgram converted from the input qubit operator and the shift value
59+
Raises:
60+
QiskitOptimizationError: If there are Pauli Xs in any Pauli term
61+
QiskitOptimizationError: If there are more than 2 Pauli Zs in any Pauli term
62+
NotImplementedError: If the input operator is a ListOp
63+
"""
64+
self._qubit_op = qubit_op
65+
self._offset = copy.deepcopy(offset)
66+
self._num_qubits = qubit_op.num_qubits
67+
self._qp = QuadraticProgram()
68+
self._qp.from_ising(qubit_op, offset,
69+
linear=self._linear)
70+
return self._qp
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# This code is part of Qiskit.
4+
#
5+
# (C) Copyright IBM 2020.
6+
#
7+
# This code is licensed under the Apache License, Version 2.0. You may
8+
# obtain a copy of this license in the LICENSE.txt file in the root directory
9+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
10+
#
11+
# Any modifications or derivative works of this code must retain this
12+
# copyright notice, and modified files need to carry a notice indicating
13+
# that they have been altered from the originals.
14+
15+
"""The converter from an ```QuadraticProgram``` to ``Operator``."""
16+
17+
from typing import Tuple, Optional
18+
import warnings
19+
20+
from qiskit.aqua.operators import OperatorBase
21+
from ..problems.quadratic_program import QuadraticProgram
22+
23+
24+
class QuadraticProgramToIsing:
25+
"""Convert an optimization problem into a qubit operator."""
26+
27+
def __init__(self) -> None:
28+
"""Initialize the internal data structure."""
29+
self._src = None # type: Optional[QuadraticProgram]
30+
warnings.warn("The QuadraticProgramToIsing class is deprecated and "
31+
"will be removed in a future release. Use the "
32+
".to_ising() method on a QuadraticProgram object "
33+
"instead.", DeprecationWarning)
34+
35+
def encode(self, op: QuadraticProgram) -> Tuple[OperatorBase, float]:
36+
"""Convert a problem into a qubit operator
37+
38+
Args:
39+
op: The optimization problem to be converted. Must be an unconstrained problem with
40+
binary variables only.
41+
Returns:
42+
The qubit operator of the problem and the shift value.
43+
Raises:
44+
QiskitOptimizationError: If a variable type is not binary.
45+
QiskitOptimizationError: If constraints exist in the problem.
46+
"""
47+
48+
self._src = op
49+
return self._src.to_ising()

qiskit/optimization/problems/quadratic_program.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from collections import defaultdict
2020
from enum import Enum
2121
from math import fsum
22+
import warnings
2223

2324
from docplex.mp.constr import (LinearConstraint as DocplexLinearConstraint,
2425
QuadraticConstraint as DocplexQuadraticConstraint,
@@ -774,6 +775,30 @@ def export_as_lp_string(self) -> str:
774775
"""
775776
return self.to_docplex().export_as_lp_string()
776777

778+
def pprint_as_string(self) -> str:
779+
"""Returns the quadratic program as a string in Docplex's pretty print format.
780+
Returns:
781+
A string representing the quadratic program.
782+
"""
783+
warnings.warn("The pprint_as_string method is deprecated and will be "
784+
"removed in a future release. Instead use the"
785+
"to_docplex() method and run pprint_as_string() on that "
786+
"output", DeprecationWarning)
787+
return self.to_docplex().pprint_as_string()
788+
789+
def prettyprint(self, out: Optional[str] = None) -> None:
790+
"""Pretty prints the quadratic program to a given output stream (None = default).
791+
792+
Args:
793+
out: The output stream or file name to print to.
794+
if you specify a file name, the output file name is has '.mod' as suffix.
795+
"""
796+
warnings.warn("The prettyprint method is deprecated and will be "
797+
"removed in a future release. Instead use the"
798+
"to_docplex() method and run prettyprint() on that "
799+
"output", DeprecationWarning)
800+
self.to_docplex().prettyprint(out)
801+
777802
def read_from_lp_file(self, filename: str) -> None:
778803
"""Loads the quadratic program from a LP file.
779804
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
deprecations:
3+
- |
4+
The ising convert classes
5+
:class:`qiskit.optimization.converters.QuadraticProgramToIsing` and
6+
:class:`qiskit.optimization.converters.IsingToQuadraticProgram` have
7+
been deprecated and will be removed in a future release. Instead the
8+
:class:`qiskit.optimization.QuadraticProgram` methods
9+
:meth:`~qiskit.optimization.QuadraticProgram.to_ising` and
10+
:meth:`~qiskit.optimization.QuadraticPrgraom.from_ising` should be used
11+
instead.
12+
- |
13+
The ``pprint_as_string`` method for
14+
:class:`qiskit.optimization.QuadraticProgram` has been deprecated and will
15+
be removed in a future release. Instead you should just run
16+
``.pprint_as_string()`` on the output from
17+
:meth:`~qiskit.optimization.QuadraticProgram.to_docplex`
18+
- |
19+
The ``prettyprint`` method for
20+
:class:`qiskit.optimization.QuadraticProgram` has been deprecated and will
21+
be removed in a future release. Instead you should just run
22+
``.prettyprint()`` on the output from
23+
:meth:`~qiskit.optimization.QuadraticProgram.to_docplex`

test/optimization/test_converters.py

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
from qiskit.optimization.algorithms.admm_optimizer import ADMMParameters
2929
from qiskit.optimization.algorithms.optimization_algorithm import OptimizationResultStatus
3030
from qiskit.optimization.converters import (InequalityToEquality, IntegerToBinary,
31-
LinearEqualityToPenalty)
31+
LinearEqualityToPenalty, QuadraticProgramToIsing,
32+
IsingToQuadraticProgram)
3233
from qiskit.optimization.problems import Constraint, Variable
3334

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

563+
def test_empty_problem_deprecated(self):
564+
""" Test empty problem """
565+
op = QuadraticProgram()
566+
conv = InequalityToEquality()
567+
op = conv.encode(op)
568+
conv = IntegerToBinary()
569+
op = conv.encode(op)
570+
conv = LinearEqualityToPenalty()
571+
op = conv.encode(op)
572+
conv = QuadraticProgramToIsing()
573+
_, shift = conv.encode(op)
574+
self.assertEqual(shift, 0.0)
575+
576+
def test_valid_variable_type_deprecated(self):
577+
"""Validate the types of the variables for QuadraticProgramToIsing."""
578+
# Integer variable
579+
with self.assertRaises(QiskitOptimizationError):
580+
op = QuadraticProgram()
581+
op.integer_var(0, 10, "int_var")
582+
conv = QuadraticProgramToIsing()
583+
_ = conv.encode(op)
584+
# Continuous variable
585+
with self.assertRaises(QiskitOptimizationError):
586+
op = QuadraticProgram()
587+
op.continuous_var(0, 10, "continuous_var")
588+
conv = QuadraticProgramToIsing()
589+
_ = conv.encode(op)
590+
591+
def test_optimizationproblem_to_ising_deprecated(self):
592+
""" Test optimization problem to operators"""
593+
op = QuadraticProgram()
594+
for i in range(4):
595+
op.binary_var(name='x{}'.format(i))
596+
linear = {}
597+
for x in op.variables:
598+
linear[x.name] = 1
599+
op.maximize(0, linear, {})
600+
linear = {}
601+
for i, x in enumerate(op.variables):
602+
linear[x.name] = i + 1
603+
op.linear_constraint(linear, Constraint.Sense.EQ, 3, 'sum1')
604+
penalize = LinearEqualityToPenalty(penalty=1e5)
605+
op2ope = QuadraticProgramToIsing()
606+
op2 = penalize.encode(op)
607+
qubitop, offset = op2ope.encode(op2)
608+
609+
self.assertEqual(qubitop, QUBIT_OP_MAXIMIZE_SAMPLE)
610+
self.assertEqual(offset, OFFSET_MAXIMIZE_SAMPLE)
611+
612+
def test_ising_to_quadraticprogram_linear_deprecated(self):
613+
""" Test optimization problem to operators with linear=True"""
614+
op = QUBIT_OP_MAXIMIZE_SAMPLE
615+
offset = OFFSET_MAXIMIZE_SAMPLE
616+
617+
op2qp = IsingToQuadraticProgram(linear=True)
618+
quadratic = op2qp.encode(op, offset)
619+
620+
self.assertEqual(len(quadratic.variables), 4)
621+
self.assertEqual(len(quadratic.linear_constraints), 0)
622+
self.assertEqual(len(quadratic.quadratic_constraints), 0)
623+
self.assertEqual(quadratic.objective.sense, quadratic.objective.Sense.MINIMIZE)
624+
self.assertAlmostEqual(quadratic.objective.constant, 900000)
625+
626+
linear_matrix = np.zeros((1, 4))
627+
linear_matrix[0, 0] = -500001
628+
linear_matrix[0, 1] = -800001
629+
linear_matrix[0, 2] = -900001
630+
linear_matrix[0, 3] = -800001
631+
632+
quadratic_matrix = np.zeros((4, 4))
633+
quadratic_matrix[0, 1] = 400000
634+
quadratic_matrix[0, 2] = 600000
635+
quadratic_matrix[1, 2] = 1200000
636+
quadratic_matrix[0, 3] = 800000
637+
quadratic_matrix[1, 3] = 1600000
638+
quadratic_matrix[2, 3] = 2400000
639+
640+
np.testing.assert_array_almost_equal(
641+
quadratic.objective.linear.coefficients.toarray(), linear_matrix
642+
)
643+
np.testing.assert_array_almost_equal(
644+
quadratic.objective.quadratic.coefficients.toarray(), quadratic_matrix
645+
)
646+
647+
def test_ising_to_quadraticprogram_quadratic_deprecated(self):
648+
""" Test optimization problem to operators with linear=False"""
649+
op = QUBIT_OP_MAXIMIZE_SAMPLE
650+
offset = OFFSET_MAXIMIZE_SAMPLE
651+
652+
op2qp = IsingToQuadraticProgram(linear=False)
653+
quadratic = op2qp.encode(op, offset)
654+
655+
self.assertEqual(len(quadratic.variables), 4)
656+
self.assertEqual(len(quadratic.linear_constraints), 0)
657+
self.assertEqual(len(quadratic.quadratic_constraints), 0)
658+
self.assertEqual(quadratic.objective.sense, quadratic.objective.Sense.MINIMIZE)
659+
self.assertAlmostEqual(quadratic.objective.constant, 900000)
660+
661+
quadratic_matrix = np.zeros((4, 4))
662+
quadratic_matrix[0, 0] = -500001
663+
quadratic_matrix[0, 1] = 400000
664+
quadratic_matrix[0, 2] = 600000
665+
quadratic_matrix[0, 3] = 800000
666+
quadratic_matrix[1, 1] = -800001
667+
quadratic_matrix[1, 2] = 1200000
668+
quadratic_matrix[1, 3] = 1600000
669+
quadratic_matrix[2, 2] = -900001
670+
quadratic_matrix[2, 3] = 2400000
671+
quadratic_matrix[3, 3] = -800001
672+
673+
np.testing.assert_array_almost_equal(
674+
quadratic.objective.quadratic.coefficients.toarray(), quadratic_matrix
675+
)
676+
562677

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

0 commit comments

Comments
 (0)