Skip to content

fetch from origin #127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 18 additions & 9 deletions qiskit/optimization/algorithms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,34 +28,43 @@
:nosignatures:

OptimizationAlgorithm
MultiStartOptimizer

Algorithms
==========
Algorithms and results
======================

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

ADMMOptimizationResult
ADMMOptimizer
ADMMParameters
ADMMState
CobylaOptimizer
CplexOptimizer
GroverOptimizationRawResult
GroverOptimizer
MinimumEigenOptimizerResult
MinimumEigenOptimizer
OptimizationResult
OptimizationResultStatus
RecursiveMinimumEigenOptimizer
SlsqpOptimizer

"""

from .optimization_algorithm import OptimizationResult
from .optimization_algorithm import OptimizationAlgorithm
from .admm_optimizer import ADMMOptimizer
from .cplex_optimizer import CplexOptimizer
from .admm_optimizer import ADMMOptimizer, ADMMOptimizationResult, ADMMState, ADMMParameters
from .cobyla_optimizer import CobylaOptimizer
from .minimum_eigen_optimizer import MinimumEigenOptimizer
from .cplex_optimizer import CplexOptimizer
from .grover_optimizer import GroverOptimizer, GroverOptimizationRawResult
from .minimum_eigen_optimizer import MinimumEigenOptimizer, MinimumEigenOptimizerResult
from .multistart_optimizer import MultiStartOptimizer
from .optimization_algorithm import (OptimizationAlgorithm, OptimizationResult,
OptimizationResultStatus)
from .recursive_minimum_eigen_optimizer import RecursiveMinimumEigenOptimizer
from .grover_optimizer import GroverOptimizer, GroverOptimizationResults
from .slsqp_optimizer import SlsqpOptimizer

__all__ = ["ADMMOptimizer", "OptimizationAlgorithm", "OptimizationResult", "CplexOptimizer",
"CobylaOptimizer", "MinimumEigenOptimizer", "RecursiveMinimumEigenOptimizer",
"GroverOptimizer", "GroverOptimizationResults", "SlsqpOptimizer"]
"GroverOptimizer", "GroverOptimizationRawResult", "SlsqpOptimizer"]
40 changes: 21 additions & 19 deletions qiskit/optimization/algorithms/admm_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import logging
import time
import warnings
from typing import List, Optional, Any, Tuple, cast
from typing import List, Optional, Tuple

import numpy as np
from qiskit.aqua.algorithms import NumPyMinimumEigensolver
Expand Down Expand Up @@ -174,19 +174,21 @@ def __init__(self,
class ADMMOptimizationResult(OptimizationResult):
""" ADMMOptimization Result."""

def __init__(self, x: Optional[Any] = None, fval: Optional[Any] = None,
state: Optional[ADMMState] = None, results: Optional[Any] = None,
variables: Optional[List[Variable]] = None) -> None:
super().__init__(x=x,
variables=variables,
fval=fval,
results=results or state)
self._state = state
def __init__(self, x: np.ndarray, fval: float, variables: List[Variable],
state: ADMMState) -> None:
"""
Args:
x: the optimal value found by ADMM.
fval: the optimal function value.
variables: the list of variables of the optimization problem.
state: the internal computation state of ADMM.
"""
super().__init__(x=x, fval=fval, variables=variables, raw_results=state)

@property
def state(self) -> Optional[ADMMState]:
def state(self) -> ADMMState:
""" returns state """
return self._state
return self._raw_results


class ADMMOptimizer(OptimizationAlgorithm):
Expand Down Expand Up @@ -277,6 +279,7 @@ def solve(self, problem: QuadraticProgram) -> ADMMOptimizationResult:
# map integer variables to binary variables
from ..converters.integer_to_binary import IntegerToBinary
int2bin = IntegerToBinary()
original_variables = problem.variables
problem = int2bin.convert(problem)

# we deal with minimization in the optimizer, so turn the problem to minimization
Expand Down Expand Up @@ -363,16 +366,15 @@ def solve(self, problem: QuadraticProgram) -> ADMMOptimizationResult:
# flip the objective sign again if required
objective_value = objective_value * sense

# convert back integer to binary
base_result = OptimizationResult(solution, objective_value, original_variables)
base_result = int2bin.interpret(base_result)

# third parameter is our internal state of computations.
result = ADMMOptimizationResult(x=solution,
fval=objective_value,
state=self._state,
results={"integer_to_binary_converter": copy.deepcopy(
int2bin)},
variables=problem.variables)
result = ADMMOptimizationResult(x=base_result.x, fval=base_result.fval,
variables=base_result.variables,
state=self._state)

# convert back integer to binary
result = cast(ADMMOptimizationResult, int2bin.interpret(result))
# debug
self._log.debug("solution=%s, objective=%s at iteration=%s",
solution, objective_value, iteration)
Expand Down
4 changes: 2 additions & 2 deletions qiskit/optimization/algorithms/cobyla_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@

from .multistart_optimizer import MultiStartOptimizer
from .optimization_algorithm import OptimizationResult
from ..problems.quadratic_program import QuadraticProgram
from ..problems.constraint import Constraint
from ..exceptions import QiskitOptimizationError
from ..infinity import INFINITY
from ..problems.constraint import Constraint
from ..problems.quadratic_program import QuadraticProgram


class CobylaOptimizer(MultiStartOptimizer):
Expand Down
6 changes: 3 additions & 3 deletions qiskit/optimization/algorithms/cplex_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

"""The CPLEX optimizer wrapped to be used within Qiskit's optimization module."""

from typing import Optional
import logging
from typing import Optional

from .optimization_algorithm import OptimizationAlgorithm, OptimizationResult
from ..exceptions import QiskitOptimizationError
Expand Down Expand Up @@ -136,9 +136,9 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult:

# create results
result = OptimizationResult(x=sol.get_values(),
variables=problem.variables,
fval=sol.get_objective_value(),
results=sol)
variables=problem.variables,
raw_results=sol)

# return solution
return result
52 changes: 26 additions & 26 deletions qiskit/optimization/algorithms/grover_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,20 @@

import copy
import logging
from typing import Optional, Dict, Union, Tuple
import math
from typing import Optional, Dict, Union, Tuple

import numpy as np

from qiskit import QuantumCircuit
from qiskit.providers import BaseBackend
from qiskit.aqua import QuantumInstance, aqua_globals
from qiskit.aqua.algorithms.amplitude_amplifiers.grover import Grover
from qiskit.providers import BaseBackend

from .optimization_algorithm import OptimizationAlgorithm, OptimizationResult
from ..problems.quadratic_program import QuadraticProgram
from ..converters.quadratic_program_to_qubo import QuadraticProgramToQubo
from ..converters.quadratic_program_to_negative_value_oracle import \
QuadraticProgramToNegativeValueOracle

from ..converters.quadratic_program_to_qubo import QuadraticProgramToQubo
from ..problems.quadratic_program import QuadraticProgram

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -133,7 +132,7 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult:
n_value = self._num_value_qubits

# Variables for tracking the solutions encountered.
num_solutions = 2**n_key
num_solutions = 2 ** n_key
keys_measured = []

# Variables for result object.
Expand All @@ -143,7 +142,7 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult:

# Variables for stopping if we've hit the rotation max.
rotations = 0
max_rotations = int(np.ceil(100*np.pi/4))
max_rotations = int(np.ceil(100 * np.pi / 4))

# Initialize oracle helper object.
orig_constant = problem_.objective.constant
Expand All @@ -164,7 +163,7 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult:
while not improvement_found:
# Determine the number of rotations.
loops_with_no_improvement += 1
rotation_count = int(np.ceil(aqua_globals.random.uniform(0, m-1)))
rotation_count = int(np.ceil(aqua_globals.random.uniform(0, m - 1)))
rotations += rotation_count

# Apply Grover's Algorithm to find values below the threshold.
Expand Down Expand Up @@ -196,7 +195,7 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult:
threshold = optimum_value
else:
# Using Durr and Hoyer method, increase m.
m = int(np.ceil(min(m * 8/7, 2**(n_key / 2))))
m = int(np.ceil(min(m * 8 / 7, 2 ** (n_key / 2))))
logger.info('No Improvement. M: %s', m)

# Check if we've already seen this value.
Expand Down Expand Up @@ -225,16 +224,17 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult:
opt_x = [1 if s == '1' else 0 for s in ('{0:%sb}' % n_key).format(optimum_key)]

# Build the results object.
grover_results = GroverOptimizationResults(operation_count, n_key, n_value, func_dict)
grover_results = GroverOptimizationRawResult(operation_count, n_key, n_value, func_dict)
fval = solutions[optimum_key]
if sense == problem_.objective.Sense.MAXIMIZE:
fval = -fval
result = OptimizationResult(x=opt_x, variables=problem.variables, fval=fval,
results={"grover_results": grover_results,
"qubo_converter": copy.deepcopy(self._qubo_converter),
"negative_value_oracle_converter": copy.deepcopy(
opt_prob_converter)
})
result = OptimizationResult(x=opt_x, fval=fval, variables=problem.variables,
raw_results={"grover_results": grover_results,
"qubo_converter": copy.deepcopy(
self._qubo_converter),
"negative_value_oracle_converter": copy.deepcopy(
opt_prob_converter)
})

# cast binaries back to integers
result = self._qubo_converter.interpret(result)
Expand All @@ -247,7 +247,7 @@ def _measure(self, circuit: QuantumCircuit) -> str:
freq = sorted(probs.items(), key=lambda x: x[1], reverse=True)

# Pick a random outcome.
freq[len(freq)-1] = (freq[len(freq)-1][0], 1.0 - sum([x[1] for x in freq[0:len(freq)-1]]))
freq[-1] = (freq[-1][0], 1.0 - sum(x[1] for x in freq[0:len(freq) - 1]))
idx = aqua_globals.random.choice(len(freq), 1, p=[x[1] for x in freq])[0]
logger.info('Frequencies: %s', freq)

Expand All @@ -261,7 +261,7 @@ def _get_probs(self, qc: QuantumCircuit) -> Dict[str, float]:
state = np.round(result.get_statevector(qc), 5)
keys = [bin(i)[2::].rjust(int(np.log2(len(state))), '0')[::-1]
for i in range(0, len(state))]
probs = [np.round(abs(a)*abs(a), 5) for a in state]
probs = [np.round(abs(a) * abs(a), 5) for a in state]
hist = dict(zip(keys, probs))
else:
state = result.get_counts(qc)
Expand All @@ -276,13 +276,13 @@ def _get_probs(self, qc: QuantumCircuit) -> Dict[str, float]:
@staticmethod
def _twos_complement(v: int, n_bits: int) -> str:
"""Converts an integer into a binary string of n bits using two's complement."""
assert -2**n_bits <= v < 2**n_bits
assert -2 ** n_bits <= v < 2 ** n_bits

if v < 0:
v += 2**n_bits
v += 2 ** n_bits
bin_v = bin(v)[2:]
else:
format_string = '{0:0'+str(n_bits)+'b}'
format_string = '{0:0' + str(n_bits) + 'b}'
bin_v = format_string.format(v)

return bin_v
Expand Down Expand Up @@ -315,14 +315,14 @@ def _get_qubo_solutions(function_dict: Dict[Union[int, Tuple[int, int]], int], n
constant = 0
if -1 in function_dict:
constant = function_dict[-1]
format_string = '{0:0'+str(n_key)+'b}'
format_string = '{0:0' + str(n_key) + 'b}'

# Iterate through every key combination.
if print_solutions:
print("QUBO Solutions:")
print("==========================")
solutions = {}
for i in range(2**n_key):
for i in range(2 ** n_key):
solution = constant

# Convert int to a list of binary variables.
Expand Down Expand Up @@ -355,8 +355,8 @@ def _get_qubo_solutions(function_dict: Dict[Union[int, Tuple[int, int]], int], n
return solutions


class GroverOptimizationResults:
"""A results object for Grover Optimization methods."""
class GroverOptimizationRawResult:
"""A raw result object for Grover Optimization methods."""

def __init__(self, operation_counts: Dict[int, Dict[str, int]],
n_input_qubits: int, n_output_qubits: int,
Expand Down
Loading