<s> import abc <EOL> import logging <EOL> import math <EOL> from collections import defaultdict <EOL> from fn import _ <EOL> from fn . iters import map , filter <EOL> from . manipulator import Parameter <EOL> from . metatechniques import RecyclingMetaTechnique <EOL> from . technique import SequentialSearchTechnique , register <EOL> log = logging . getLogger ( __name__ ) <EOL> class SimplexTechnique ( SequentialSearchTechnique ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , seed_cfg = None , * args , ** kwargs ) : <EOL> super ( SimplexTechnique , self ) . __init__ ( * args , ** kwargs ) <EOL> self . centroid = None <EOL> self . last_simplex_points = None <EOL> self . seed_cfg = seed_cfg <EOL> self . simplex_points = [ ] <EOL> def calculate_centroid ( self ) : <EOL> """<STR_LIT>""" <EOL> sums = defaultdict ( float ) <EOL> counts = defaultdict ( int ) <EOL> for config in self . simplex_points : <EOL> cfg = config . data <EOL> for param in self . manipulator . parameters ( cfg ) : <EOL> if param . is_primitive ( ) : <EOL> sums [ param . name ] += param . get_unit_value ( cfg ) <EOL> counts [ param . name ] += <NUM_LIT:1> <EOL> centroid = self . manipulator . copy ( self . simplex_points [ <NUM_LIT:0> ] . data ) <EOL> for param in self . manipulator . parameters ( centroid ) : <EOL> if param . is_primitive ( ) : <EOL> param . set_unit_value ( centroid , <EOL> sums [ param . name ] / float ( counts [ param . name ] ) ) <EOL> return centroid <EOL> def cfg_to_str ( self , cfg ) : <EOL> params = list ( filter ( Parameter . is_primitive , <EOL> self . manipulator . parameters ( cfg ) ) ) <EOL> params . sort ( key = _ . name ) <EOL> return str ( tuple ( map ( lambda x : x . get_unit_value ( cfg ) , params ) ) ) <EOL> def debug_log ( self ) : <EOL> for i , config in enumerate ( self . simplex_points ) : <EOL> log . debug ( "<STR_LIT>" , i , self . cfg_to_str ( config . data ) ) <EOL> if self . centroid : <EOL> log . debug ( "<STR_LIT>" , self . cfg_to_str ( self . centroid ) ) <EOL> def linear_point ( self , p1 , p2 , scale ) : <EOL> """<STR_LIT>""" <EOL> return self . manipulator . linear_config ( <NUM_LIT:1.0> , p1 , scale , p1 , - scale , p2 ) <EOL> def convergence_criterea ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . rounds_since_novel_request > <NUM_LIT:3> * len ( self . simplex_points ) + <NUM_LIT:1> : <EOL> return True <EOL> if self . last_simplex_points == self . simplex_points : <EOL> return True <EOL> self . last_simplex_points = list ( self . simplex_points ) <EOL> return False <EOL> def initial_simplex_seed ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . seed_cfg is not None : <EOL> return self . seed_cfg <EOL> return self . manipulator . random ( ) <EOL> @ abc . abstractmethod <EOL> def initial_simplex ( self ) : <EOL> """<STR_LIT>""" <EOL> return [ ] <EOL> class RandomInitialMixin ( object ) : <EOL> """<STR_LIT>""" <EOL> def initial_simplex ( self ) : <EOL> cfg0 = self . initial_simplex_seed ( ) <EOL> params = self . manipulator . parameters ( cfg0 ) <EOL> return [ cfg0 ] + [ self . manipulator . random ( ) <EOL> for p in params <EOL> if p . is_primitive ( ) ] <EOL> class RightInitialMixin ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , initial_unit_edge_length = <NUM_LIT:0.1> , * args , ** kwargs ) : <EOL> assert initial_unit_edge_length <= <NUM_LIT:0.5> <EOL> self . initial_unit_edge_length = initial_unit_edge_length <EOL> super ( RightInitialMixin , self ) . __init__ ( * args , ** kwargs ) <EOL> def initial_simplex ( self ) : <EOL> cfg0 = self . initial_simplex_seed ( ) <EOL> simplex = [ cfg0 ] <EOL> params = self . manipulator . parameters ( cfg0 ) <EOL> params = filter ( lambda x : x . is_primitive ( ) , params ) <EOL> for p in params : <EOL> simplex . append ( self . manipulator . copy ( cfg0 ) ) <EOL> v = p . get_unit_value ( simplex [ - <NUM_LIT:1> ] ) <EOL> if v <= <NUM_LIT:0.5> : <EOL> v += self . initial_unit_edge_length <EOL> else : <EOL> v -= self . initial_unit_edge_length <EOL> p . set_unit_value ( simplex [ - <NUM_LIT:1> ] , v ) <EOL> return simplex <EOL> class RegularInitialMixin ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , initial_unit_edge_length = <NUM_LIT:0.1> , * args , ** kwargs ) : <EOL> assert initial_unit_edge_length <= <NUM_LIT:0.5> <EOL> self . initial_unit_edge_length = initial_unit_edge_length <EOL> super ( RegularInitialMixin , self ) . __init__ ( * args , ** kwargs ) <EOL> def initial_simplex ( self ) : <EOL> cfg0 = self . initial_simplex_seed ( ) <EOL> simplex = [ cfg0 ] <EOL> params = self . manipulator . parameters ( cfg0 ) <EOL> params = list ( filter ( lambda x : x . is_primitive ( ) , params ) ) <EOL> if len ( params ) == <NUM_LIT:0> : <EOL> return simplex <EOL> q = ( ( ( math . sqrt ( len ( params ) + <NUM_LIT:1.0> ) - <NUM_LIT:1.0> ) / ( len ( params ) * math . sqrt ( <NUM_LIT> ) ) ) <EOL> * self . initial_unit_edge_length ) <EOL> p = q + ( ( <NUM_LIT:1.0> / math . sqrt ( <NUM_LIT> ) ) * self . initial_unit_edge_length ) <EOL> base = [ x . get_unit_value ( cfg0 ) for x in params ] <EOL> for j in xrange ( len ( base ) ) : <EOL> if max ( p , q ) + base [ j ] > <NUM_LIT:1.0> : <EOL> base [ j ] *= - <NUM_LIT:1.0> <EOL> for i in xrange ( len ( params ) ) : <EOL> simplex . append ( self . manipulator . copy ( cfg0 ) ) <EOL> params [ i ] . set_unit_value ( simplex [ - <NUM_LIT:1> ] , abs ( base [ i ] + p ) ) <EOL> for j in xrange ( i + <NUM_LIT:1> , len ( params ) ) : <EOL> params [ j ] . set_unit_value ( simplex [ - <NUM_LIT:1> ] , abs ( base [ i ] + q ) ) <EOL> return simplex <EOL> class NelderMead ( SimplexTechnique ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , <EOL> alpha = <NUM_LIT> , <EOL> gamma = <NUM_LIT> , <EOL> beta = <NUM_LIT:0.5> , <EOL> sigma = <NUM_LIT:0.5> , <EOL> * args , ** kwargs ) : <EOL> self . alpha = alpha <EOL> self . gamma = gamma <EOL> self . beta = beta <EOL> self . sigma = sigma <EOL> super ( NelderMead , self ) . __init__ ( * args , ** kwargs ) <EOL> @ classmethod <EOL> def get_hyper_parameters ( cls ) : <EOL> return [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> def main_generator ( self ) : <EOL> objective = self . objective <EOL> driver = self . driver <EOL> self . simplex_points = list ( map ( driver . get_configuration , <EOL> self . initial_simplex ( ) ) ) <EOL> if len ( self . simplex_points ) <= <NUM_LIT:1> : <EOL> log . warning ( "<STR_LIT>" , self . name ) <EOL> return <EOL> log . debug ( "<STR_LIT>" ) <EOL> for p in self . simplex_points : <EOL> self . yield_nonblocking ( p ) <EOL> yield None <EOL> while not self . convergence_criterea ( ) : <EOL> self . simplex_points . sort ( cmp = objective . compare ) <EOL> self . limit = objective . limit_from_config ( self . simplex_points [ - <NUM_LIT:1> ] ) <EOL> self . centroid = self . calculate_centroid ( ) <EOL> if log . isEnabledFor ( logging . DEBUG ) : <EOL> self . debug_log ( ) <EOL> reflection = self . reflection_point ( ) <EOL> yield reflection <EOL> if objective . lt ( reflection , self . simplex_points [ <NUM_LIT:0> ] ) : <EOL> expansion = self . expansion_point ( reflection ) <EOL> yield expansion <EOL> if objective . lt ( expansion , reflection ) : <EOL> log . debug ( "<STR_LIT>" ) <EOL> self . simplex_points [ - <NUM_LIT:1> ] = expansion <EOL> else : <EOL> log . debug ( "<STR_LIT>" ) <EOL> self . simplex_points [ - <NUM_LIT:1> ] = reflection <EOL> elif objective . lt ( reflection , self . simplex_points [ <NUM_LIT:1> ] ) : <EOL> log . debug ( "<STR_LIT>" ) <EOL> self . simplex_points [ - <NUM_LIT:1> ] = reflection <EOL> else : <EOL> if objective . lte ( reflection , self . simplex_points [ - <NUM_LIT:1> ] ) : <EOL> contract_base = reflection <EOL> else : <EOL> contract_base = self . simplex_points [ - <NUM_LIT:1> ] <EOL> contraction = self . contraction_point ( contract_base ) <EOL> yield contraction <EOL> if objective . lte ( contraction , contract_base ) : <EOL> log . debug ( "<STR_LIT>" ) <EOL> self . simplex_points [ - <NUM_LIT:1> ] = contraction <EOL> else : <EOL> log . debug ( "<STR_LIT>" ) <EOL> self . perform_shrink_reduction ( ) <EOL> for p in self . simplex_points : <EOL> self . yield_nonblocking ( p ) <EOL> yield None <EOL> def reflection_point ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . driver . get_configuration ( <EOL> self . linear_point ( self . centroid , <EOL> self . simplex_points [ - <NUM_LIT:1> ] . data , <EOL> self . alpha ) ) <EOL> def expansion_point ( self , reflection ) : <EOL> """<STR_LIT>""" <EOL> return self . driver . get_configuration ( <EOL> self . linear_point ( self . centroid , <EOL> reflection . data , <EOL> - self . gamma ) ) <EOL> def contraction_point ( self , contract_base ) : <EOL> """<STR_LIT>""" <EOL> return self . driver . get_configuration ( <EOL> self . linear_point ( self . centroid , <EOL> contract_base . data , <EOL> - self . beta ) ) <EOL> def perform_shrink_reduction ( self ) : <EOL> """<STR_LIT>""" <EOL> for i in xrange ( <NUM_LIT:1> , len ( self . simplex_points ) ) : <EOL> self . simplex_points [ i ] = self . driver . get_configuration ( <EOL> self . linear_point ( self . simplex_points [ <NUM_LIT:0> ] . data , <EOL> self . simplex_points [ i ] . data , <EOL> - self . sigma ) ) <EOL> class Torczon ( SimplexTechnique ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , <EOL> alpha = <NUM_LIT:1.0> , <EOL> gamma = <NUM_LIT> , <EOL> beta = <NUM_LIT:0.5> , <EOL> * args , ** kwargs ) : <EOL> self . alpha = alpha <EOL> self . gamma = gamma <EOL> self . beta = beta <EOL> super ( Torczon , self ) . __init__ ( * args , ** kwargs ) <EOL> @ classmethod <EOL> def get_hyper_parameters ( cls ) : <EOL> return [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> def main_generator ( self ) : <EOL> objective = self . objective <EOL> driver = self . driver <EOL> self . simplex_points = list ( map ( driver . get_configuration , <EOL> self . initial_simplex ( ) ) ) <EOL> if len ( self . simplex_points ) <= <NUM_LIT:1> : <EOL> log . warning ( "<STR_LIT>" , self . name ) <EOL> return <EOL> log . debug ( "<STR_LIT>" ) <EOL> for p in self . simplex_points : <EOL> self . yield_nonblocking ( p ) <EOL> yield None <EOL> self . simplex_points . sort ( cmp = objective . compare ) <EOL> while not self . convergence_criterea ( ) : <EOL> self . limit = objective . limit_from_config ( self . simplex_points [ - <NUM_LIT:1> ] ) <EOL> if log . isEnabledFor ( logging . DEBUG ) : <EOL> self . debug_log ( ) <EOL> reflected = self . reflected_simplex ( ) <EOL> yield None <EOL> reflected . sort ( cmp = objective . compare ) <EOL> if reflected [ <NUM_LIT:0> ] is not self . simplex_points [ <NUM_LIT:0> ] : <EOL> expanded = self . expanded_simplex ( ) <EOL> yield None <EOL> expanded . sort ( cmp = objective . compare ) <EOL> if objective . lt ( expanded [ <NUM_LIT:0> ] , reflected [ <NUM_LIT:0> ] ) : <EOL> log . debug ( "<STR_LIT>" ) <EOL> self . simplex_points = expanded <EOL> else : <EOL> log . debug ( "<STR_LIT>" ) <EOL> self . simplex_points = reflected <EOL> else : <EOL> contracted = self . contracted_simplex ( ) <EOL> yield None <EOL> contracted . sort ( cmp = objective . compare ) <EOL> log . debug ( "<STR_LIT>" ) <EOL> self . simplex_points = contracted <EOL> def scaled_simplex ( self , scale ) : <EOL> """<STR_LIT>""" <EOL> simplex = list ( self . simplex_points ) <EOL> for i in xrange ( <NUM_LIT:1> , len ( simplex ) ) : <EOL> simplex [ i ] = self . driver . get_configuration ( <EOL> self . linear_point ( simplex [ <NUM_LIT:0> ] . data , simplex [ i ] . data , scale ) ) <EOL> self . yield_nonblocking ( simplex [ i ] ) <EOL> return simplex <EOL> def reflected_simplex ( self ) : <EOL> return self . scaled_simplex ( self . alpha ) <EOL> def expanded_simplex ( self ) : <EOL> return self . scaled_simplex ( self . gamma ) <EOL> def contracted_simplex ( self ) : <EOL> return self . scaled_simplex ( - self . beta ) <EOL> class RandomNelderMead ( RandomInitialMixin , NelderMead ) : <EOL> pass <EOL> class RightNelderMead ( RightInitialMixin , NelderMead ) : <EOL> pass <EOL> class RegularNelderMead ( RegularInitialMixin , NelderMead ) : <EOL> pass <EOL> class RandomTorczon ( RandomInitialMixin , Torczon ) : <EOL> pass <EOL> class RightTorczon ( RightInitialMixin , Torczon ) : <EOL> pass <EOL> class RegularTorczon ( RegularInitialMixin , Torczon ) : <EOL> pass <EOL> class MultiNelderMead ( RecyclingMetaTechnique ) : <EOL> def __init__ ( self ) : <EOL> super ( MultiNelderMead , self ) . __init__ ( [ RightNelderMead , RandomNelderMead , <EOL> RegularNelderMead ] ) <EOL> class MultiTorczon ( RecyclingMetaTechnique ) : <EOL> def __init__ ( self ) : <EOL> super ( MultiTorczon , self ) . __init__ ( [ RightTorczon , RandomTorczon , <EOL> RegularTorczon ] ) <EOL> register ( RandomNelderMead ( ) ) <EOL> register ( RegularNelderMead ( ) ) <EOL> register ( RightNelderMead ( ) ) <EOL> register ( MultiNelderMead ( ) ) <EOL> register ( RandomTorczon ( ) ) <EOL> register ( RegularTorczon ( ) ) <EOL> register ( RightTorczon ( ) ) <EOL> register ( MultiTorczon ( ) ) </s>
