def _fit_pso(self, n_particles, n_iterations, pool, verbose): """ Executes the PSO """ low_bounds, high_bounds = self._param_class.bounds( self._re_optimize, self._re_optimize_scale) pso = ParticleSwarmOptimizer(self.fast_rayshooting.logL, low_bounds, high_bounds, n_particles, pool, args=[self._tol_source]) best, info = pso.optimize( n_iterations, verbose, early_stop_tolerance=self._pso_convergence_mean) if verbose: print('PSO done... ') print('source plane chi^2: ', self.fast_rayshooting.source_plane_chi_square(best)) print('total chi^2: ', self.fast_rayshooting.chi_square(best)) kwargs = self._param_class.args_to_kwargs(best) return kwargs
def pso(self, n_particles, n_iterations, lower_start=None, upper_start=None, threadCount=1, init_pos=None, mpi=False, print_key='PSO'): """ Return the best fit for the lens model on catalogue basis with particle swarm optimizer. :param n_particles: number of particles in the sampling process :param n_iterations: number of iterations of the swarm :param lower_start: numpy array, lower end parameter of the values of the starting particles :param upper_start: numpy array, upper end parameter of the values of the starting particles :param threadCount: number of threads in the computation (only applied if mpi=False) :param init_pos: numpy array, position of the initial best guess model :param mpi: bool, if True, makes instance of MPIPool to allow for MPI execution :param print_key: string, prints the process name in the progress bar (optional) :return: kwargs_result (of best fit), [lnlikelihood of samples, positions of samples, velocity of sampels) """ if lower_start is None or upper_start is None: lower_start, upper_start = np.array(self.lower_limit), np.array(self.upper_limit) print("PSO initialises its particles with default values") else: lower_start = np.maximum(lower_start, self.lower_limit) upper_start = np.minimum(upper_start, self.upper_limit) pool = choose_pool(mpi=mpi, processes=threadCount, use_dill=True) if mpi is True and pool.is_master(): print('MPI option chosen for PSO.') pso = ParticleSwarmOptimizer(self.chain.logL, lower_start, upper_start, n_particles, pool=pool) if init_pos is None: init_pos = (upper_start - lower_start) / 2 + lower_start pso.set_global_best(init_pos, [0]*len(init_pos), self.chain.logL(init_pos)) if pool.is_master(): print('Computing the %s ...' % print_key) time_start = time.time() result, [chi2_list, pos_list, vel_list] = pso.optimize(n_iterations) if pool.is_master(): kwargs_return = self.chain.param.args2kwargs(result) print(pso.global_best.fitness * 2 / (max( self.chain.effective_num_data_points(**kwargs_return), 1)), 'reduced X^2 of best position') print(pso.global_best.fitness, 'logL') print(self.chain.effective_num_data_points(**kwargs_return), 'effective number of data points') print(kwargs_return.get('kwargs_lens', None), 'lens result') print(kwargs_return.get('kwargs_source', None), 'source result') print(kwargs_return.get('kwargs_lens_light', None), 'lens light result') print(kwargs_return.get('kwargs_ps', None), 'point source result') print(kwargs_return.get('kwargs_special', None), 'special param result') time_end = time.time() print(time_end - time_start, 'time used for ', print_key) print('===================') return result, [chi2_list, pos_list, vel_list]
def test_optimize(self): """ :return: :rtype: """ low = np.zeros(2) high = np.ones(2) def func(p): return -np.random.rand() pso = ParticleSwarmOptimizer(func, low, high, 10) max_iter = 10 result, [chi2_list, pos_list, vel_list] = pso.optimize(max_iter) assert result is not None assert chi2_list is not None assert pos_list is not None assert vel_list is not None assert len(result) == 2 assert len(chi2_list) == max_iter assert len(pos_list) == max_iter assert len(pos_list[0]) == 2 assert len(vel_list) == max_iter assert len(vel_list[0]) == 2 assert np.all(chi2_list) != 0 assert pso.global_best.fitness != -np.inf
def pso(self, n_particles=10, n_iterations=10, lowerLimit=-0.2, upperLimit=0.2, threadCount=1, mpi=False, print_key='default'): """ returns the best fit for the lense model on catalogue basis with particle swarm optimizer """ init_pos = self.chain.get_args(self.chain.kwargs_data_init) num_param = self.chain.num_param lowerLimit = [lowerLimit] * num_param upperLimit = [upperLimit] * num_param pool, is_master = choose_pool(mpi=mpi, processes=threadCount, use_dill=True) pso = ParticleSwarmOptimizer(self.chain, lowerLimit, upperLimit, n_particles, pool=pool) if init_pos is not None: pso.set_global_best(init_pos, [0]*len(init_pos), self.chain.likelihood(init_pos)) if is_master: print('Computing the %s ...' % print_key) time_start = time.time() result, [chi2_list, pos_list, vel_list] = pso.optimize(n_iterations) kwargs_data = self.chain.update_data(result) if is_master: time_end = time.time() print("Shifts found: ", result) print(time_end - time_start, 'time used for ', print_key) return kwargs_data, [chi2_list, pos_list, vel_list]
def test_setup(self): """ :return: :rtype: """ low = np.zeros(2) high = np.ones(2) pso = ParticleSwarmOptimizer(None, low, high, 10) assert pso.swarm is not None assert len(pso.swarm) == 10 position = [part.position for part in pso.swarm] assert (position >= low).all() assert (position <= high).all() velocity = [part.velocity for part in pso.swarm] assert (velocity == np.zeros(2)).all() fitness = [part.fitness == 0 for part in pso.swarm] assert all(fitness) assert pso.global_best.fitness == -np.inf
def test_sample(self): """ :return: :rtype: """ np.random.seed(42) n_particle = 100 n_iterations = 100 def ln_probability(x): return -np.array(x)**2 pso = ParticleSwarmOptimizer(func=ln_probability, low=[-10], high=[10], particle_count=n_particle) init_pos = np.array([1]) pso.global_best.position = init_pos pso.global_best.velocity = [0] * len(init_pos) pso.global_best.fitness = ln_probability(init_pos) x2_list = [] vel_list = [] pos_list = [] time_start = time.time() if pso.is_master(): print('Computing the PSO...') num_iter = 0 for swarm in pso.sample(n_iterations): x2_list.append(pso.global_best.fitness * 2) vel_list.append(pso.global_best.velocity) pos_list.append(pso.global_best.position) num_iter += 1 if pso.is_master(): if num_iter % 10 == 0: print(num_iter) result = pso.global_best.position time_end = time.time() print(time_end - time_start) print(result) npt.assert_almost_equal(result[0], 0, decimal=6)