Skip to content

Commit

Permalink
Allow SNR optimizer to use candidate point in initial array (#4393)
Browse files Browse the repository at this point in the history
* allow SNR optimizer to use the candidate point in the initial array of test points
  • Loading branch information
GarethCabournDavies authored Jun 28, 2023
1 parent b889bb3 commit 2a3926c
Showing 1 changed file with 73 additions and 12 deletions.
85 changes: 73 additions & 12 deletions bin/pycbc_optimize_snr
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,28 @@ def compute_minus_network_snr_pso(v, *argv, **kwargs):
return -nsnr_array


def optimize_di(bounds, cli_args, extra_args):
bounds = [
def normalize_initial_point(initial_point, bounds):
return (initial_point - bounds[:,0]) / (bounds[:,1] - bounds[:,0])

def optimize_di(bounds, cli_args, extra_args, initial_point):
bounds = numpy.array([
bounds['mchirp'],
bounds['eta'],
bounds['spin1z'],
bounds['spin2z']
]
])


# Currently only implemented for random seed initial array
rng = numpy.random.mtrand._rand
population_shape=(cli_args.di_popsize, 4)
population = rng.uniform(size=population_shape)
if cli_args.include_candidate_in_optimizer:
# Re-normalize the initial point into the correct range
point_init = normalize_initial_point(initial_point, bounds)
# add the initial point to the population
population = numpy.concatenate((population[:-1], point_init))

results = differential_evolution(
compute_minus_network_snr,
bounds,
Expand All @@ -146,12 +161,13 @@ def optimize_di(bounds, cli_args, extra_args):
mutation=(0.5, 1),
recombination=0.7,
callback=callback_func,
args=extra_args
args=extra_args,
init=population
)
return results.x


def optimize_shgo(bounds, cli_args, extra_args):
def optimize_shgo(bounds, cli_args, extra_args, initial_point): # pylint: disable=unused-argument
bounds = [
bounds['mchirp'],
bounds['eta'],
Expand All @@ -168,30 +184,48 @@ def optimize_shgo(bounds, cli_args, extra_args):
)
return results.x

def normalize_population(population, min_bounds, max_bounds):
norm_pop = min_bounds + population * (max_bounds - min_bounds)

return norm_pop

def optimize_pso(bounds, cli_args, extra_args):
def optimize_pso(bounds, cli_args, extra_args, initial_point):
options = {
'c1': cli_args.pso_c1,
'c2': cli_args.pso_c2,
'w': cli_args.pso_w
}
min_bounds = [
min_bounds = numpy.array([
bounds['mchirp'][0],
bounds['eta'][0],
bounds['spin1z'][0],
bounds['spin2z'][0]
]
max_bounds = [
])
max_bounds = numpy.array([
bounds['mchirp'][1],
bounds['eta'][1],
bounds['spin1z'][1],
bounds['spin2z'][1]
]
])

# Manually generate the initial points, this is the same as the default
# method, but allows us to make some modifications
population = numpy.random.uniform(
low=0.0, high=1.0, size=(cli_args.pso_particles, 4)
)
population = normalize_population(population, min_bounds, max_bounds)

if cli_args.include_candidate_in_optimizer:
# add the initial point to the population
population = numpy.concatenate((population[:-1],
initial_point))

optimizer = ps.single.GlobalBestPSO(
n_particles=cli_args.pso_particles,
dimensions=4,
options=options,
bounds=(min_bounds, max_bounds)
bounds=(min_bounds, max_bounds),
init_pos=population
)
_, results = optimizer.optimize(
compute_minus_network_snr_pso,
Expand Down Expand Up @@ -284,6 +318,14 @@ parser.add_argument('--pso-c2', type=float, default=2.0,
parser.add_argument('--pso-w', type=float, default=0.01,
help='Only relevant for --optimizer pso: '
'The hyperparameter w: the inertia parameter.')
parser.add_argument('--include-candidate-in-optimizer', action='store_true',
help='Include parameters of the candidate event in the '
'initialised array for the optimizer. Only relevant for '
'--optimizer pso or differential_evolution')
parser.add_argument('--seed', type=int,
help='Seed to supply to the random generation of initial '
'array to pass to the optimizer. Only relevant for '
'--optimizer pso or differential_evolution')

scheme.insert_processing_option_group(parser)
fft.insert_fft_option_group(parser)
Expand All @@ -296,6 +338,9 @@ if args.optimizer == 'pso' and ps == None:
parser.error('You need to install pyswarms to use the pso optimizer.')
pycbc.init_logging(args.verbose)

if args.seed:
numpy.random.seed(args.seed)

scheme.verify_processing_options(args, parser)
fft.verify_fft_options(args, parser)

Expand Down Expand Up @@ -375,11 +420,27 @@ bounds = {
'spin2z': (minspin2z, maxspin2z)
}

if args.include_candidate_in_optimizer:
# Initial point from found candidate
mchirp_init = cv.mchirp_from_mass1_mass2(fp['mass1'][()], fp['mass2'][()])
eta_init = cv.eta_from_mass1_mass2(fp['mass1'][()], fp['mass2'][()])
spin1z_init = fp['spin1z'][()]
spin2z_init = fp['spin2z'][()]

initial_point = numpy.array([
mchirp_init,
eta_init,
spin1z_init,
spin2z_init,
])[numpy.newaxis]
else:
initial_point = None

with scheme_context:
logging.info('Starting optimization')

optimize_func = optimize_funcs[args.optimizer]
opt_params = optimize_func(bounds, args, extra_args)
opt_params = optimize_func(bounds, args, extra_args, initial_point)

logging.info('Optimization complete')

Expand Down

0 comments on commit 2a3926c

Please sign in to comment.