def __init__(self, data, function, nfunc, **kwargs): """ Set up likelihood object's hyperparameter values. """ self.adaptive = kwargs.pop('adaptive', False) self.use_hyper = kwargs.pop('use_hyper', function.__name__[:2] == 'nn') if kwargs: raise TypeError('Unexpected **kwargs: {0}'.format(kwargs)) self.data = data assert data['x_error_sigma'] is None or data['x2'] is None, ( 'Not yet set up to deal with x errors in 2d') self.function = function self.nfunc = nfunc if self.function.__name__[:2] == 'nn': assert isinstance(self.nfunc, list) assert len(nfunc) >= 2, nfunc if data['x2'] is None: assert nfunc[0] == 1 else: assert nfunc[0] == 2 self.ndim = nn.nn_num_params(self.nfunc) if self.function.__name__ == 'nn_adl': assert self.adaptive self.ndim += 1 elif self.function.__name__ == 'adfam_gg_ta_1d': assert self.adaptive self.ndim = self.nfunc * len(bf.get_bf_param_names(bf.gg_1d)) self.ndim += 1 # For adaptive family parameter else: self.ndim = self.nfunc * len(bf.get_bf_param_names(function)) if self.adaptive: self.ndim += 1 if self.use_hyper: self.ndim += 1
def get_param_latex_names(self): """Get list of parameter names as str.""" if self.function.__name__[:2] == 'nn': return nn.get_nn_param_latex_names(self.nfunc, use_hyper=self.use_hyper) elif self.function.__name__ == 'adfam_gg_ta_1d': return self.get_param_names() else: bf_params = bf.get_param_latex_names( bf.get_bf_param_names(self.function)) param_names = [] for param in bf_params: assert param[-1] == '$' if param[-2] == '}': for i in range(self.nfunc): param_names.append(param[:-2] + ',' + str(i + 1) + '}$') else: for i in range(self.nfunc): param_names.append('{0}_{1}$'.format( param[:-1], i + 1)) if self.adaptive: param_names = ['$N$'] + param_names assert len(param_names) == self.ndim return param_names
def test_get_data_args(self): """Check right number of args is supplied.""" for data_func in [bf.gg_1d, bf.gg_2d, bf.ta_1d]: for nfunc in [1, 2, 3]: args = bsr.data.get_data_args(data_func, nfunc) self.assertEqual(len(args), nfunc * len(bf.get_bf_param_names(data_func))) self.assertRaises(AssertionError, bsr.data.get_data_args, bf.gg_1d, 100)
def get_param_names(self): """Get list of parameter names as str.""" if self.function.__name__[:2] == 'nn': return nn.get_nn_param_names(self.nfunc, use_hyper=self.use_hyper) else: if self.function.__name__ == 'adfam_gg_ta_1d': bf_params = bf.get_bf_param_names(bf.gg_1d) else: bf_params = bf.get_bf_param_names(self.function) param_names = [] for param in bf_params: for i in range(self.nfunc): param_names.append('{0}_{1}'.format(param, i + 1)) if self.adaptive: param_names = ['N'] + param_names if self.function.__name__ == 'adfam_gg_ta_1d': param_names = ['T'] + param_names assert len(param_names) == self.ndim return param_names
def test_sum_basis_func(self): """Check summing basis funcs, including adaptive.""" nfunc = 2 basis_func = bf.gg_1d x1 = 0.5 x2 = None # make params state = np.random.get_state() # save initial random state np.random.seed(0) nargs = len(bf.get_bf_param_names(basis_func)) theta = np.random.random((nargs * nfunc) + 1) # check adaptive using all funcs theta[0] = nfunc out = bf.sum_basis_funcs(basis_func, theta, nfunc, x1, x2=x2, adaptive=True) self.assertAlmostEqual(out, 1.152357037165534) # check adaptive using 1 func is consistent theta[0] = 1 out = bf.sum_basis_funcs(basis_func, theta, nfunc, x1, x2=x2, adaptive=True) self.assertAlmostEqual(out, basis_func(x1, *theta[1::nfunc])) # check error handling if theta[0] is nan theta[0] = np.nan out = bf.sum_basis_funcs(basis_func, theta, nfunc, x1, x2=x2, adaptive=True) self.assertTrue(np.isnan(out)) # return to original random state np.random.set_state(state)
def get_default_prior(func, nfunc, **kwargs): """Construct a default set of priors for the basis function.""" adaptive = kwargs.pop('adaptive', False) sigma_w = kwargs.pop('sigma_w', 5) if kwargs: raise TypeError('Unexpected **kwargs: {0}'.format(kwargs)) # specify default priors if func.__name__ == 'nn_adl': assert isinstance(nfunc, list) assert len(nfunc) == 3 assert adaptive nfunc_1l = [nfunc[0], nfunc[-1]] return AdFamPrior([ get_default_prior(nn.nn_1l, nfunc_1l, adaptive=adaptive), get_default_prior(nn.nn_2l, nfunc, adaptive=adaptive) ]) elif func.__name__[:2] == 'nn': # Neural network prior. Here nfunc is a list of numbers of nodes # Note all physical coordinates are scaled by hyperparameter (final # parameter in prior) and hence use sigma=1 assert isinstance(nfunc, list) assert len(nfunc) >= 2 prior_blocks = [] block_sizes = [] # Add sorted adaptive parameter on output weights prior_blocks.append( dyPolyChord.python_priors.Gaussian(1.0, adaptive=adaptive, sort=True, half=len(nfunc) == 2)) if adaptive: block_sizes.append(nfunc[-1] + 1) else: block_sizes.append(nfunc[-1]) # Priors on remaining weights prior_blocks.append(dyPolyChord.python_priors.Gaussian(1.0)) block_sizes.append(nn.nn_num_params(nfunc) - nfunc[-1]) # Priors on hyperparameter prior_blocks.append( dyPolyChord.python_priors.PowerUniform(0.1, 20, power=-2)) block_sizes.append(1) return dyPolyChord.python_priors.BlockPrior(prior_blocks, block_sizes) elif func.__name__ == 'adfam_gg_ta_1d': assert adaptive # Need to explicitly provide all args rather than use **kwargs as # kwargs is now empty due to poping return AdFamPrior([ get_default_prior(bf.gg_1d, nfunc, adaptive=adaptive), get_default_prior(bf.ta_1d, nfunc, adaptive=adaptive) ]) elif func.__name__ in ['gg_1d', 'gg_2d', 'ta_1d', 'ta_2d']: if func.__name__ in ['gg_1d', 'gg_2d']: priors_dict = { 'a': dyPolyChord.python_priors.Exponential(1.0, adaptive=adaptive, sort=True), 'mu': dyPolyChord.python_priors.Uniform(0.0, 1.0), # 0.03 is approx pixel size in 32x32 'sigma': dyPolyChord.python_priors.Uniform(0.03, 1.0), 'beta': dyPolyChord.python_priors.Exponential(0.5) } if func.__name__ == 'gg_2d': # reduce max sigma from 1.0 to 0.5 for 2d case priors_dict['sigma'] = dyPolyChord.python_priors.Uniform( 0.03, 0.5) for param in ['mu', 'sigma', 'beta']: priors_dict[param + '1'] = priors_dict[param] priors_dict[param + '2'] = priors_dict[param] del priors_dict[param] # del so error thrown if used priors_dict['omega'] = dyPolyChord.python_priors.Uniform( -0.25 * np.pi, 0.25 * np.pi) elif func.__name__ in ['ta_1d', 'ta_2d']: priors_dict = { 'a': dyPolyChord.python_priors.Gaussian(sigma_w, adaptive=adaptive, sort=True, half=True), 'w_0': dyPolyChord.python_priors.Gaussian(sigma_w), 'w_1': dyPolyChord.python_priors.Gaussian(sigma_w), 'w_2': dyPolyChord.python_priors.Gaussian(sigma_w) } # Get a list of the priors we want args = bf.get_bf_param_names(func) prior_blocks = [priors_dict[arg] for arg in args] block_sizes = [nfunc] * len(args) if adaptive: block_sizes[0] += 1 return dyPolyChord.python_priors.BlockPrior(prior_blocks, block_sizes) else: raise AssertionError('not yet set up for {}'.format(func.__name__))
def test_names(self): """Check the parameter naming functions.""" for func in [bf.gg_1d, bf.gg_2d, bf.ta_1d, bf.ta_2d]: names = bf.get_bf_param_names(func) self.assertEqual(len(names), len(bf.get_param_latex_names(names)))
def get_data_args(data_func, nfuncs): """Returns default arguments for generating data.""" if data_func.__name__ == 'gg_1d': # first arg is sorted if nfuncs == 1: data_args = [{'a': 0.75, 'mu': 0.4, 'sigma': 0.3, 'beta': 2.0}] elif nfuncs == 2: data_args = [{ 'a': 0.2, 'mu': 0.4, 'sigma': 0.6, 'beta': 5.0 }, { 'a': 0.55, 'mu': 0.4, 'sigma': 0.2, 'beta': 4.0 }] elif nfuncs == 3: data_args = [{ 'a': 0.2, 'mu': 0.4, 'sigma': 0.6, 'beta': 5.0 }, { 'a': 0.35, 'mu': 0.6, 'sigma': 0.07, 'beta': 2.0 }, { 'a': 0.55, 'mu': 0.32, 'sigma': 0.14, 'beta': 6.0 }] elif nfuncs == 4: data_args = [{ 'a': 0.2, 'mu': 0.3, 'sigma': 0.5, 'beta': 5.0 }, { 'a': 0.4, 'mu': 0.65, 'sigma': 0.07, 'beta': 2.0 }, { 'a': 0.6, 'mu': 0.25, 'sigma': 0.1, 'beta': 6.0 }, { 'a': 0.9, 'mu': 0.95, 'sigma': 0.1, 'beta': 6.0 }] elif data_func.__name__ == 'ta_1d': # first arg is sorted if nfuncs == 1: data_args = [{'a': 0.8, 'w_0': 0.0, 'w_1': 1.5}] elif nfuncs == 2: data_args = [{ 'a': 0.7, 'w_0': -1, 'w_1': 3 }, { 'a': 0.9, 'w_0': 2, 'w_1': -3 }] elif nfuncs == 3: data_args = [{ 'a': 0.6, 'w_0': -7, 'w_1': 8 }, { 'a': 1, 'w_0': -1, 'w_1': 3 }, { 'a': 1.4, 'w_0': 2, 'w_1': -3 }] elif data_func.__name__ == 'gg_2d': # the order is (with first arg sorted): # [a_1, mu1_1, mu2_1, s1_1, s2_1, b1_1, b2_1, rot angle] if nfuncs == 1: data_args = [{ 'a': 0.8, 'mu1': 0.6, 'mu2': 0.6, 'sigma1': 0.1, 'sigma2': 0.2, 'beta1': 2, 'beta2': 2, 'omega': 0.1 * np.pi }] elif nfuncs == 2: data_args = [{ 'a': 0.5, 'mu1': 0.5, 'mu2': 0.4, 'sigma1': 0.4, 'sigma2': 0.2, 'beta1': 2, 'beta2': 2, 'omega': 0 }, { 'a': 0.8, 'mu1': 0.5, 'mu2': 0.6, 'sigma1': 0.1, 'sigma2': 0.1, 'beta1': 2, 'beta2': 2, 'omega': 0 }] elif nfuncs == 3: data_args = [{ 'a': 0.5, 'mu1': 0.3, 'mu2': 0.7, 'sigma1': 0.2, 'sigma2': 0.2, 'beta1': 2, 'beta2': 2, 'omega': 0 }, { 'a': 0.7, 'mu1': 0.7, 'mu2': 0.6, 'sigma1': 0.15, 'sigma2': 0.15, 'beta1': 2, 'beta2': 2, 'omega': 0 }, { 'a': 0.9, 'mu1': 0.4, 'mu2': 0.3, 'sigma1': 0.1, 'sigma2': 0.1, 'beta1': 2, 'beta2': 2, 'omega': 0 }] try: data_args_list = [] for name in bf.get_bf_param_names(data_func): data_args_list += [d[name] for d in data_args] return data_args_list except NameError: raise AssertionError('no data args found! func={} nfuncs={}'.format( data_func.__name__, nfuncs))