# Path: pyswarms/utils/search/base_search.py
# class SearchBase(object):
#     def assertions(self):
#         """Assertion method to check :code:`optimizer` input
# 
#         Raises
#         ------
#         TypeError
#             When :code:`optimizer` does not have an `'optimize'` attribute.
#         """
#         # Check type of optimizer object
#         if not hasattr(self.optimizer, "optimize"):
#             raise TypeError(
#                 "Parameter `optimizer` must have an " "`'optimize'` attribute."
#             )
# 
#     def __init__(
#         self,
#         optimizer,
#         n_particles,
#         dimensions,
#         options,
#         objective_func,
#         iters,
#         bounds=None,
#         velocity_clamp=(0, 1),
#     ):
#         """Initialize the Search
# 
#         Attributes
#         ----------
#         optimizer: pyswarms.single
#             either LocalBestPSO or GlobalBestPSO
#         n_particles : int
#             number of particles in the swarm.
#         dimensions : int
#             number of dimensions in the space.
#         options : dict with keys :code:`{'c1', 'c2', 'w', 'k', 'p'}`
#             a dictionary containing the parameters for the specific
#             optimization technique
# 
#                 * c1 : float
#                     cognitive parameter
#                 * c2 : float
#                     social parameter
#                 * w : float
#                     inertia parameter
#                 * k : int
#                     number of neighbors to be considered. Must be a
#                     positive integer less than :code:`n_particles`
#                 * p: int {1,2}
#                     the Minkowski p-norm to use. 1 is the
#                     sum-of-absolute values (or L1 distance) while 2 is
#                     the Euclidean (or L2) distance.
# 
#         objective_func: function
#             objective function to be evaluated
#         iters: int
#             number of iterations
#         bounds : tuple of np.ndarray, optional (default is None)
#             a tuple of size 2 where the first entry is the minimum bound
#             while the second entry is the maximum bound. Each array must
#             be of shape :code:`(dimensions,)`.
#         velocity_clamp : tuple (default is :code:`None`)
#             a tuple of size 2 where the first entry is the minimum velocity
#             and the second entry is the maximum velocity. It
#             sets the limits for velocity clamping.
#         """
# 
#         # Assign attributes
#         self.optimizer = optimizer
#         self.n_particles = n_particles
#         self.dims = dimensions
#         self.options = options
#         self.bounds = bounds
#         self.vclamp = velocity_clamp
#         self.objective_func = objective_func
#         self.iters = iters
#         # Invoke assertions
#         self.assertions()
# 
#     def generate_score(self, options):
#         """Generate score for optimizer's performance on objective function
# 
#         Parameters
#         ----------
# 
#         options: dict
#             a dict with the following keys: {'c1', 'c2', 'w', 'k', 'p'}
#         """
# 
#         # Intialize optimizer
#         f = self.optimizer(
#             self.n_particles,
#             self.dims,
#             options,
#             self.bounds,
#             velocity_clamp=self.vclamp,
#         )
# 
#         # Return score
#         return f.optimize(self.objective_func, self.iters)[0]
# 
#     def search(self, maximum=False):
#         """Compare optimizer's objective function performance scores
#         for all combinations of provided parameters
# 
#         Parameters
#         ----------
# 
#         maximum: bool
#             a bool defaulting to False, returning the minimum value for the
#             objective function. If set to True, will return the maximum value
#             for the objective function.
#         """
# 
#         # Generate the grid of all hyperparameter value combinations
#         grid = self.generate_grid()
# 
#         # Calculate scores for all hyperparameter combinations
#         scores = [self.generate_score(i) for i in grid]
# 
#         # Default behavior
#         idx, self.best_score = min(enumerate(scores), key=op.itemgetter(1))
# 
#         # Catches the maximum bool flag
#         if maximum:
#             idx, self.best_score = max(enumerate(scores), key=op.itemgetter(1))
# 
#         # Return optimum hyperparameter value property from grid using index
#         self.best_options = op.itemgetter(idx)(grid)
#         return self.best_score, self.best_options


import itertools
from pyswarms.utils.search.base_search import SearchBase
to produce a grid of all possible combinations. These combinations are then
tested to produce a list of objective function scores. The search method
default returns the minimum objective function score and hyperparameters that
yield the minimum score, yet maximum score can also be evaluated.

>>> options = {'c1': [1, 2, 3],
               'c2': [1, 2, 3],
               'w' : [2, 3, 5],
               'k' : [5, 10, 15],
               'p' : 1}
>>> g = GridSearch(LocalBestPSO, n_particles=40, dimensions=20,
                   options=options, objective_func=sphere, iters=10)
>>> best_score, best_options = g.search()
>>> best_score
0.498641604188
>>> best_options['c1']
1
>>> best_options['c2']
1
"""

# Import from __future__
from __future__ import absolute_import, print_function, with_statement

# Import standard library

# Import from pyswarms
# Import from package



# Path: pyswarms/utils/search/base_search.py
# class SearchBase(object):
#     def assertions(self):
#         """Assertion method to check :code:`optimizer` input
# 
#         Raises
#         ------
#         TypeError
#             When :code:`optimizer` does not have an `'optimize'` attribute.
#         """
#         # Check type of optimizer object
#         if not hasattr(self.optimizer, "optimize"):
#             raise TypeError(
#                 "Parameter `optimizer` must have an " "`'optimize'` attribute."
#             )
# 
#     def __init__(
#         self,
#         optimizer,
#         n_particles,
#         dimensions,
#         options,
#         objective_func,
#         iters,
#         bounds=None,
#         velocity_clamp=(0, 1),
#     ):
#         """Initialize the Search
# 
#         Attributes
#         ----------
#         optimizer: pyswarms.single
#             either LocalBestPSO or GlobalBestPSO
#         n_particles : int
#             number of particles in the swarm.
#         dimensions : int
#             number of dimensions in the space.
#         options : dict with keys :code:`{'c1', 'c2', 'w', 'k', 'p'}`
#             a dictionary containing the parameters for the specific
#             optimization technique
# 
#                 * c1 : float
#                     cognitive parameter
#                 * c2 : float
#                     social parameter
#                 * w : float
#                     inertia parameter
#                 * k : int
#                     number of neighbors to be considered. Must be a
#                     positive integer less than :code:`n_particles`
#                 * p: int {1,2}
#                     the Minkowski p-norm to use. 1 is the
#                     sum-of-absolute values (or L1 distance) while 2 is
#                     the Euclidean (or L2) distance.
# 
#         objective_func: function
#             objective function to be evaluated
#         iters: int
#             number of iterations
#         bounds : tuple of np.ndarray, optional (default is None)
#             a tuple of size 2 where the first entry is the minimum bound
#             while the second entry is the maximum bound. Each array must
#             be of shape :code:`(dimensions,)`.
#         velocity_clamp : tuple (default is :code:`None`)
#             a tuple of size 2 where the first entry is the minimum velocity
#             and the second entry is the maximum velocity. It
#             sets the limits for velocity clamping.
#         """
# 
#         # Assign attributes
#         self.optimizer = optimizer
#         self.n_particles = n_particles
#         self.dims = dimensions
#         self.options = options
#         self.bounds = bounds
#         self.vclamp = velocity_clamp
#         self.objective_func = objective_func
#         self.iters = iters
#         # Invoke assertions
#         self.assertions()
# 
#     def generate_score(self, options):
#         """Generate score for optimizer's performance on objective function
# 
#         Parameters
#         ----------
# 
#         options: dict
#             a dict with the following keys: {'c1', 'c2', 'w', 'k', 'p'}
#         """
# 
#         # Intialize optimizer
#         f = self.optimizer(
#             self.n_particles,
#             self.dims,
#             options,
#             self.bounds,
#             velocity_clamp=self.vclamp,
#         )
# 
#         # Return score
#         return f.optimize(self.objective_func, self.iters)[0]
# 
#     def search(self, maximum=False):
#         """Compare optimizer's objective function performance scores
#         for all combinations of provided parameters
# 
#         Parameters
#         ----------
# 
#         maximum: bool
#             a bool defaulting to False, returning the minimum value for the
#             objective function. If set to True, will return the maximum value
#             for the objective function.
#         """
# 
#         # Generate the grid of all hyperparameter value combinations
#         grid = self.generate_grid()
# 
#         # Calculate scores for all hyperparameter combinations
#         scores = [self.generate_score(i) for i in grid]
# 
#         # Default behavior
#         idx, self.best_score = min(enumerate(scores), key=op.itemgetter(1))
# 
#         # Catches the maximum bool flag
#         if maximum:
#             idx, self.best_score = max(enumerate(scores), key=op.itemgetter(1))
# 
#         # Return optimum hyperparameter value property from grid using index
#         self.best_options = op.itemgetter(idx)(grid)
#         return self.best_score, self.best_options


# Path: pyswarms/utils/search/grid_search.py
import itertools
from pyswarms.utils.search.base_search import SearchBase

to produce a grid of all possible combinations. These combinations are then
tested to produce a list of objective function scores. The search method
default returns the minimum objective function score and hyperparameters that
yield the minimum score, yet maximum score can also be evaluated.

>>> options = {'c1': [1, 2, 3],
               'c2': [1, 2, 3],
               'w' : [2, 3, 5],
               'k' : [5, 10, 15],
               'p' : 1}
>>> g = GridSearch(LocalBestPSO, n_particles=40, dimensions=20,
                   options=options, objective_func=sphere, iters=10)
>>> best_score, best_options = g.search()
>>> best_score
0.498641604188
>>> best_options['c1']
1
>>> best_options['c2']
1
"""

# Import from __future__
from __future__ import absolute_import, print_function, with_statement

# Import standard library

# Import from pyswarms
# Import from package



class GridSearch(SearchBase):