# Path: openfermioncirq/optimization/algorithm.py
# class OptimizationAlgorithm(metaclass=abc.ABCMeta):
#     """An optimization algorithm for black-box objective functions.
# 
#     We use the convention that the optimization algorithm should try to minimize
#     (rather than maximize) the value of the objective function.
# 
#     In order to work with some routines that save optimization results,
#     instances of this class must be picklable. See
#     https://docs.python.org/3/library/pickle.html
#     for details.
# 
#     Attributes:
#         options: Options for the algorithm.
#     """
# 
#     def __init__(self, options: Optional[Any]=None) -> None:
#         """
#         Args:
#             options: Options for the algorithm.
#         """
#         # TODO options is probably always a Dict
#         self.options = options or self.default_options()
# 
#     def default_options(self):
#         """Default options for the algorithm."""
#         # TODO tailor default options to the particular problem (e.g. number of
#         #      parameters)
#         return {}
# 
#     @abc.abstractmethod
#     def optimize(self,
#                  black_box: BlackBox,
#                  initial_guess: Optional[numpy.ndarray]=None,
#                  initial_guess_array: Optional[numpy.ndarray]=None
#                  ) -> OptimizationResult:
#         """Perform the optimization and return the result.
# 
#         Args:
#             black_box: A BlackBox encapsulating the objective function.
#             initial_guess: An initial point at which to evaluate the objective
#                 function.
#             initial_guess_array: An array of initial points at which to evaluate
#                 the objective function, for algorithms that can use multiple
#                 initial points. This is a 2d numpy array with each row
#                 representing one initial point.
#         """
# 
#     @property
#     def name(self) -> str:
#         """A name for the optimization algorithm."""
#         return type(self).__name__
# 
# Path: openfermioncirq/testing/example_classes.py
# class ExampleAlgorithm(OptimizationAlgorithm):
#     """Evaluates 5 random points and returns the best answer found."""
# 
#     def optimize(self,
#                  black_box: BlackBox,
#                  initial_guess: Optional[numpy.ndarray]=None,
#                  initial_guess_array: Optional[numpy.ndarray]=None
#                  ) -> OptimizationResult:
#         opt = numpy.inf
#         opt_params = None
#         for _ in range(5):
#             guess = numpy.random.randn(black_box.dimension)
#             val = black_box.evaluate(guess)
#             if val < opt:
#                 opt = val
#                 opt_params = guess
#         return OptimizationResult(
#                 optimal_value=opt,
#                 optimal_parameters=cast(numpy.ndarray, opt_params),
#                 num_evaluations=1,
#                 cost_spent=0.0,
#                 status=0,
#                 message='success')
# 
# class ExampleBlackBox(BlackBox):
#     """Returns the sum of the squares of the inputs."""
# 
#     @property
#     def dimension(self) -> int:
#         return 2
# 
#     def _evaluate(self,
#                   x: numpy.ndarray) -> float:
#         return numpy.sum(x**2)


import numpy
import pytest
from openfermioncirq.optimization import OptimizationAlgorithm
from openfermioncirq.testing import ExampleAlgorithm, ExampleBlackBox
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.




def test_optimization_algorithm_options():
    algorithm = ExampleAlgorithm()
    assert algorithm.options == {}


def test_optimization_algorithm_optimize():
    black_box = ExampleBlackBox()

# Path: openfermioncirq/optimization/algorithm.py
# class OptimizationAlgorithm(metaclass=abc.ABCMeta):
#     """An optimization algorithm for black-box objective functions.
# 
#     We use the convention that the optimization algorithm should try to minimize
#     (rather than maximize) the value of the objective function.
# 
#     In order to work with some routines that save optimization results,
#     instances of this class must be picklable. See
#     https://docs.python.org/3/library/pickle.html
#     for details.
# 
#     Attributes:
#         options: Options for the algorithm.
#     """
# 
#     def __init__(self, options: Optional[Any]=None) -> None:
#         """
#         Args:
#             options: Options for the algorithm.
#         """
#         # TODO options is probably always a Dict
#         self.options = options or self.default_options()
# 
#     def default_options(self):
#         """Default options for the algorithm."""
#         # TODO tailor default options to the particular problem (e.g. number of
#         #      parameters)
#         return {}
# 
#     @abc.abstractmethod
#     def optimize(self,
#                  black_box: BlackBox,
#                  initial_guess: Optional[numpy.ndarray]=None,
#                  initial_guess_array: Optional[numpy.ndarray]=None
#                  ) -> OptimizationResult:
#         """Perform the optimization and return the result.
# 
#         Args:
#             black_box: A BlackBox encapsulating the objective function.
#             initial_guess: An initial point at which to evaluate the objective
#                 function.
#             initial_guess_array: An array of initial points at which to evaluate
#                 the objective function, for algorithms that can use multiple
#                 initial points. This is a 2d numpy array with each row
#                 representing one initial point.
#         """
# 
#     @property
#     def name(self) -> str:
#         """A name for the optimization algorithm."""
#         return type(self).__name__
# 
# Path: openfermioncirq/testing/example_classes.py
# class ExampleAlgorithm(OptimizationAlgorithm):
#     """Evaluates 5 random points and returns the best answer found."""
# 
#     def optimize(self,
#                  black_box: BlackBox,
#                  initial_guess: Optional[numpy.ndarray]=None,
#                  initial_guess_array: Optional[numpy.ndarray]=None
#                  ) -> OptimizationResult:
#         opt = numpy.inf
#         opt_params = None
#         for _ in range(5):
#             guess = numpy.random.randn(black_box.dimension)
#             val = black_box.evaluate(guess)
#             if val < opt:
#                 opt = val
#                 opt_params = guess
#         return OptimizationResult(
#                 optimal_value=opt,
#                 optimal_parameters=cast(numpy.ndarray, opt_params),
#                 num_evaluations=1,
#                 cost_spent=0.0,
#                 status=0,
#                 message='success')
# 
# class ExampleBlackBox(BlackBox):
#     """Returns the sum of the squares of the inputs."""
# 
#     @property
#     def dimension(self) -> int:
#         return 2
# 
#     def _evaluate(self,
#                   x: numpy.ndarray) -> float:
#         return numpy.sum(x**2)


# Path: openfermioncirq/optimization/algorithm_test.py
import numpy
import pytest
from openfermioncirq.optimization import OptimizationAlgorithm
from openfermioncirq.testing import ExampleAlgorithm, ExampleBlackBox

#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.




def test_optimization_algorithm_options():
    algorithm = ExampleAlgorithm()
    assert algorithm.options == {}


def test_optimization_algorithm_optimize():
    black_box = ExampleBlackBox()

    algorithm = ExampleAlgorithm()