From eac7fd9436c8d8354e6da15522deeda60966c0ab Mon Sep 17 00:00:00 2001 From: Sourcery AI <> Date: Thu, 22 Jun 2023 08:51:08 +0000 Subject: [PATCH] 'Refactored by Sourcery' --- modea/Algorithms.py | 8 ++--- modea/Individual.py | 11 ++---- modea/Mutation.py | 13 ++----- modea/Parameters.py | 17 ++++----- modea/Recombination.py | 7 ++-- modea/Sampling.py | 11 +++--- modea/Utils.py | 79 +++++++++++++++++++++++------------------- tests/Mutation.py | 4 ++- tests/Utils.py | 14 ++++---- 9 files changed, 75 insertions(+), 89 deletions(-) diff --git a/modea/Algorithms.py b/modea/Algorithms.py index c874fdb..424610e 100644 --- a/modea/Algorithms.py +++ b/modea/Algorithms.py @@ -249,12 +249,10 @@ def runLocalRestartOptimizer(self,target=None, threshold=None): def determineRegime(self): large = self.budgets['large'] small = self.budgets['small'] - if large <= 0: + if large <= 0 or small > 0 and large <= small: self.regime = 'small' - elif small <= 0 or large > small: - self.regime = 'large' else: - self.regime = 'small' + self.regime = 'large' class OnePlusOneOptimizer(EvolutionaryOptimizer): @@ -421,7 +419,7 @@ class CustomizedES(EvolutionaryOptimizer): def __init__(self, n, fitnessFunction, budget, mu=None, lambda_=None, opts=None, values=None): if opts is None: - opts = dict() + opts = {} self.addDefaults(opts) self.n = n diff --git a/modea/Individual.py b/modea/Individual.py index 1b634a9..9f7eea5 100644 --- a/modea/Individual.py +++ b/modea/Individual.py @@ -51,10 +51,7 @@ def __copy__(self): return return_copy def __repr__(self): - return "".format( - str(np.round_(self.fitness,2)), - str(np.round_(self.genotype.flatten(), 2)), - ) + return f"" def __str__(self): return self.__repr__() @@ -96,11 +93,7 @@ def __init__(self, n, num_discrete, num_ints, num_floats=None): self.maxStepSize = 0.5 self.initStepSize = 0.2 - if n > 5: - self.baseStepSize = 1 / n - else: - self.baseStepSize = 0.175 # Random guess value, may need to be updated - + self.baseStepSize = 1 / n if n > 5 else 0.175 for x in range(self.n): # self.baseStepSizeMIES[x] = 1/(3 * num_options[x]) self.stepSizeOffsetMIES[x] = self.initStepSize - self.baseStepSize diff --git a/modea/Mutation.py b/modea/Mutation.py index d184c0f..b8bc275 100644 --- a/modea/Mutation.py +++ b/modea/Mutation.py @@ -105,10 +105,7 @@ def _getXi(): Randomly returns 5/7 or 7/5 with equal probability :return: float Xi """ - if bool(random.getrandbits(1)): - return 5/7 - else: - return 7/5 + return 5/7 if bool(random.getrandbits(1)) else 7/5 '''----------------------------------------------------------------------------- @@ -275,14 +272,10 @@ def MIES_MutateDiscrete(individual, begin, end, u, num_options, options): threshold = np.random.random_sample() # change discrete if threshold < individual.stepSizeMIES(x): - temparray = [] - for i in range(num_options[x]): - temparray.append(i) + temparray = list(range(num_options[x])) temparray.remove(individual.genotype[x]) individual.genotype[x] = random.choice(temparray) - for i in range(options[x][2]): - conditional_mask.append(individual.genotype[x]) - + conditional_mask.extend(individual.genotype[x] for _ in range(options[x][2])) return conditional_mask diff --git a/modea/Parameters.py b/modea/Parameters.py index e23d1a6..d3a61c4 100644 --- a/modea/Parameters.py +++ b/modea/Parameters.py @@ -72,7 +72,7 @@ def __init__(self, n, budget, sigma=None, if mu is None: mu = 0.5 elif mu > lambda_: - raise Exception("mu ({}) cannot be greater than lambda ({})".format(mu, lambda_)) + raise Exception(f"mu ({mu}) cannot be greater than lambda ({lambda_})") elif mu >= 1: mu /= lambda_ if sigma is None: @@ -208,7 +208,7 @@ def __init_values(self, values): def mu_int(self): """Integer value of mu""" if self.eff_lambda < 1: - raise Exception("Effective lambda ({}) should be at least 1!".format(self.eff_lambda)) + raise Exception(f"Effective lambda ({self.eff_lambda}) should be at least 1!") return int(1 + floor((self.eff_lambda-1) * self.mu)) @@ -272,7 +272,7 @@ def adaptCovarianceMatrix(self, evalcount): lambda_ = self.lambda_ self.p_sigma = (1-cs) * self.p_sigma + \ - sqrt(cs*(2-cs)*mueff) * dot(invsqrt_C, (wcm - wcm_old) / self.sigma) + sqrt(cs*(2-cs)*mueff) * dot(invsqrt_C, (wcm - wcm_old) / self.sigma) power = (2*evalcount/lambda_) if power < 1000: #TODO: Solve more neatly hsig = sum(self.p_sigma**2)/(1-(1-cs)**power)/n < 2 + 4/(n+1) @@ -284,8 +284,8 @@ def adaptCovarianceMatrix(self, evalcount): # Regular update of C self.C = (1 - c_1 - c_mu) * self.C \ - + c_1 * (outer(self.p_c, self.p_c) + (1-hsig) * cc * (2-cc) * self.C) \ - + c_mu * dot(offset, self.weights*offset.T) + + c_1 * (outer(self.p_c, self.p_c) + (1-hsig) * cc * (2-cc) * self.C) \ + + c_mu * dot(offset, self.weights*offset.T) if self.active and len(self.all_offspring) >= 2*self.mu_int: # Active update of C offset_bad = self.offset[:, -self.mu_int:] self.C -= c_mu * dot(offset_bad, self.weights*offset_bad.T) @@ -298,10 +298,7 @@ def adaptCovarianceMatrix(self, evalcount): self.sigma *= exp(self.alpha_s) else: exponent = (norm(self.p_sigma) / self.chiN - 1) * self.c_sigma / self.damps - if exponent < 1000: #TODO: Solve more neatly - self.sigma = self.sigma * exp(exponent) - else: - self.sigma = self.sigma_mean + self.sigma = self.sigma * exp(exponent) if exponent < 1000 else self.sigma_mean self.sigma_mean = self.sigma ### Update BD ### @@ -330,7 +327,7 @@ def adaptCovarianceMatrix(self, evalcount): self.sqrt_C = dot(e_vector, e_value**-1 * e_vector.T) except LinAlgError as e: # raise Exception(e) - print("Restarting, degeneration detected: {}".format(e)) + print(f"Restarting, degeneration detected: {e}") degenerated = True if degenerated: diff --git a/modea/Recombination.py b/modea/Recombination.py index 3cc6b0c..a2b6b00 100644 --- a/modea/Recombination.py +++ b/modea/Recombination.py @@ -41,8 +41,7 @@ def random(pop, param): :returns: A list of lambda individuals, each a copy of a randomly chosen individual from the population """ - new_population = [copy(choice(pop)) for _ in range(param.lambda_)] - return new_population + return [copy(choice(pop)) for _ in range(param.lambda_)] def onePlusOne(pop, param): @@ -77,9 +76,7 @@ def weighted(pop, param): new_ind = copy(pop[0]) new_ind.genotype = param.wcm new_population = [new_ind] - for _ in range(int(param.lambda_-1)): - new_population.append(copy(new_ind)) - + new_population.extend(copy(new_ind) for _ in range(int(param.lambda_-1))) return new_population diff --git a/modea/Sampling.py b/modea/Sampling.py index fdb0448..3153ce4 100644 --- a/modea/Sampling.py +++ b/modea/Sampling.py @@ -68,10 +68,7 @@ class QuasiGaussianSobolSampling(object): def __init__(self, n, shape='col', seed=None): self.n = n self.shape = (n,1) if shape == 'col' else (1,n) - if seed is None or seed < 2: - self.seed = np.random.randint(2, n**2) # seed=1 will give a null-vector as first result - else: - self.seed = seed + self.seed = np.random.randint(2, n**2) if seed is None or seed < 2 else seed def next(self): """ @@ -131,7 +128,7 @@ class OrthogonalSampling(object): """ def __init__(self, n, lambda_, shape='col', base_sampler=None): if n == 0 or lambda_ == 0: - raise ValueError("'n' ({}) and 'lambda_' ({}) cannot be zero".format(n, lambda_)) + raise ValueError(f"'n' ({n}) and 'lambda_' ({lambda_}) cannot be zero") self.n = n self.shape = (n,1) if shape == 'col' else (1,n) @@ -162,7 +159,7 @@ def __generateSamples(self): """ Draw new samples from the base_sampler, orthonormalize them and store to be drawn from """ samples = [] lengths = [] - for i in range(self.num_samples): + for _ in range(self.num_samples): sample = self.base_sampler.next() samples.append(sample) lengths.append(norm(sample)) @@ -184,8 +181,8 @@ def __gramSchmidt(self, vectors): for i in range(1, num_vectors): for j in range(i): vec_i = vectors[i] - vec_j = vectors[j] if lengths[j]: # This will prevent Runtimewarning (Division over zero) + vec_j = vectors[j] vectors[i] = vec_i - vec_j * (dot(vec_i.T, vec_j) / lengths[j] ** 2) lengths[i] = norm(vectors[i]) diff --git a/modea/Utils.py b/modea/Utils.py index 6f29c1c..65bd412 100644 --- a/modea/Utils.py +++ b/modea/Utils.py @@ -47,8 +47,11 @@ def getVals(init_values): :return: Dictionary containing name-indexed initial parameter values """ - values = {initializable_parameters[i]: val for i, val in enumerate(init_values) if val is not None} - return values + return { + initializable_parameters[i]: val + for i, val in enumerate(init_values) + if val is not None + } def getOpts(bitstring): """ @@ -58,8 +61,10 @@ def getOpts(bitstring): :return: Dictionary with all option names and the chosen option """ - opts = {option[0]: option[1][int(bitstring[i])] for i, option in enumerate(options)} - return opts + return { + option[0]: option[1][int(bitstring[i])] + for i, option in enumerate(options) + } def getBitString(opts): """ @@ -69,16 +74,12 @@ def getBitString(opts): :return: A list of integers that serve as index for the options tuple """ bitstring = [] - for i, option in enumerate(options): + for option in options: name, choices, _ = option - if name in opts: - if opts[name] in choices: - bitstring.append(choices.index(opts[name])) - else: - bitstring.append(0) + if name in opts and opts[name] in choices: + bitstring.append(choices.index(opts[name])) else: bitstring.append(0) - return bitstring def getFullOpts(opts): @@ -115,28 +116,44 @@ def getPrintName(opts): ortho = 'Orthogonal-' if opts['orthogonal'] else '' tpa = 'TPA-' if opts['tpa'] else '' seq = 'Sequential ' if opts['sequential'] else '' - ipop = '{}-'.format(opts['ipop']) if opts['ipop'] is not None else '' - weight = '${}$-weighted '.format(opts['weights_option']) if opts['weights_option'] is not None else '' + ipop = f"{opts['ipop']}-" if opts['ipop'] is not None else '' + weight = ( + f"${opts['weights_option']}$-weighted " + if opts['weights_option'] is not None + else '' + ) sel = 'Pairwise selection' if opts['selection'] == 'pairwise' else '' - sampler = 'a {} sampler'.format(opts['base-sampler']) if opts['base-sampler'] is not None else '' + sampler = ( + f"a {opts['base-sampler']} sampler" + if opts['base-sampler'] is not None + else '' + ) if len(sel) + len(sampler) > 0: append = ' with {}' - if len(sel) > 0 and len(sampler) > 0: - temp = '{} and {}'.format(sel, sampler) + if not sel or sampler == "": + temp = f'{sel}{sampler}' else: - temp = '{}{}'.format(sel, sampler) + temp = f'{sel} and {sampler}' append = append.format(temp) else: append = '' base_string = "{seq}{thres}{weight}{mirror}{ortho}{active}(mu{elitist}lambda)-{tpa}{ipop}CMA-ES{append}" - name = base_string.format(elitist=elitist, active=active, thres=thres, mirror=mirror, ortho=ortho, - tpa=tpa, seq=seq, ipop=ipop, weight=weight, append=append) - - return name + return base_string.format( + elitist=elitist, + active=active, + thres=thres, + mirror=mirror, + ortho=ortho, + tpa=tpa, + seq=seq, + ipop=ipop, + weight=weight, + append=append, + ) # TODO: make function of Individual base-class @@ -178,11 +195,7 @@ def reprToInt(representation): # TODO FIXME Hardcoded max_length = 11 factors = [2304, 1152, 576, 288, 144, 72, 36, 18, 9, 3, 1] - integer = 0 - for i in range(max_length): - integer += representation[i] * factors[i] - - return integer + return sum(representation[i] * factors[i] for i in range(max_length)) def intToRepr(integer): @@ -286,7 +299,7 @@ def __init__(self, fitnesses=None, target=1e-8, # # The interesting values to display or use as comparison self.ERT = ERT # Expected Running Time - self.FCE = FCE if FCE > target else target # Fixed Cost Error + self.FCE = max(FCE, target) self.std_dev_ERT = std_dev_ERT # Standard deviation of ERT self.std_dev_FCE = std_dev_FCE # Standard deviation of FCE # Summary/memory values to use for reproducability @@ -306,7 +319,7 @@ def __eq__(self, other): def __lt__(self, other): # Assuming minimalization problems, so A < B means A is better than B if self.ERT is not None and other.ERT is None: return True # If only one has an ERT, it is better by default - elif self.ERT is not None and other.ERT is not None and self.ERT < other.ERT: + elif self.ERT is not None and self.ERT < other.ERT: return True # If both have an ERT, we want the better one elif self.ERT is None and other.ERT is None and self.FCE < other.FCE: return True # If neither have an ERT, we want the better FCE @@ -315,14 +328,10 @@ def __lt__(self, other): # Assuming minimalization problems, so A < B means A i def __repr__(self): if self.min_fitnesses is not None: - kwargs = "target={},min_fitnesses={},min_indices={},num_successful={}".format( - self.target, self.min_fitnesses, self.min_indices, self.num_successful - ) + kwargs = f"target={self.target},min_fitnesses={self.min_fitnesses},min_indices={self.min_indices},num_successful={self.num_successful}" else: - kwargs = "target={},ERT={},FCE={},std_dev_ERT={},std_dev_FCE={}".format( - self.target, self.ERT, self.FCE, self.std_dev_ERT, self.std_dev_FCE - ) - return "ESFitness({})".format(kwargs) + kwargs = f"target={self.target},ERT={self.ERT},FCE={self.FCE},std_dev_ERT={self.std_dev_ERT},std_dev_FCE={self.std_dev_FCE}" + return f"ESFitness({kwargs})" def __unicode__(self): # TODO: pretty-print-ify diff --git a/tests/Mutation.py b/tests/Mutation.py index e5f9dc4..6263d43 100644 --- a/tests/Mutation.py +++ b/tests/Mutation.py @@ -22,7 +22,9 @@ def setUp(self): def test_in_bounds(self): vector = np.array([0, 1, 2, 3, 4]) result = vector - np.testing.assert_array_almost_equal(_keepInBounds(vector, self.lbound, self.ubound), result) + np.testing.assert_array_almost_equal( + _keepInBounds(result, self.lbound, self.ubound), result + ) def test_out_of_bounds(self): vector = np.array([10,11,12,13,14]) diff --git a/tests/Utils.py b/tests/Utils.py index f61892b..1cb89fa 100644 --- a/tests/Utils.py +++ b/tests/Utils.py @@ -24,7 +24,7 @@ def test_zip_case(self): self.assertDictEqual(expected_result, result) def test_nones(self): - self.assertDictEqual(getVals([None]*self.length), dict()) + self.assertDictEqual(getVals([None]*self.length), {}) def test_error(self): with self.assertRaises(IndexError): @@ -45,14 +45,14 @@ def test_incorrect_values(self): getOpts([3]*self.length) def test_input_too_long(self): - expected_output = dict(((opt[0], opt[1][0]) for opt in options)) + expected_output = {opt[0]: opt[1][0] for opt in options} self.assertDictEqual(getOpts([0]*(self.length+1)), expected_output) class GetBitStringTest(unittest.TestCase): def setUp(self): - self.default = dict(((opt[0], opt[1][0]) for opt in options)) + self.default = {opt[0]: opt[1][0] for opt in options} self.length = len(options) def test_base_case(self): @@ -66,7 +66,7 @@ class GetFullOptsTest(unittest.TestCase): def setUp(self): self.foo = {'foo': 1, 'bar': 2, 'spam': 3, 'eggs': 4} - self.default = dict(((opt[0], opt[1][0]) for opt in options)) + self.default = {opt[0]: opt[1][0] for opt in options} self.length = len(options) self.maxDiff = None @@ -82,7 +82,7 @@ def test_incomplete(self): def test_alternative(self): import copy - default = dict(((opt[0], opt[1][1]) for opt in options)) + default = {opt[0]: opt[1][1] for opt in options} modified_in_place = copy.copy(default) getFullOpts(modified_in_place) self.assertDictEqual(modified_in_place, default) @@ -98,11 +98,11 @@ def test_faulty(self): class GetPrintNameTest(unittest.TestCase): def test_default_case(self): - case = dict(((opt[0], opt[1][0]) for opt in options)) + case = {opt[0]: opt[1][0] for opt in options} self.assertEqual(getPrintName(case), '(mu,lambda)-CMA-ES') def test_alternative_case(self): - case = dict(((opt[0], opt[1][1]) for opt in options)) + case = {opt[0]: opt[1][1] for opt in options} self.assertEqual(getPrintName(case), 'Sequential Threshold $1/n$-weighted Mirrored-Orthogonal-Active-' '(mu+lambda)-TPA-IPOP-CMA-ES with Pairwise selection and a quasi-sobol sampler')