mcmc.py | mcmc.py | |||
---|---|---|---|---|
skipping to change at line 77 | skipping to change at line 77 | |||
log L ~ -0.5 * sum_i Vi - 0.5 sum_i (xi-m)^2/Vi | log L ~ -0.5 * sum_i Vi - 0.5 sum_i (xi-m)^2/Vi | |||
""" | """ | |||
#return -0.5*self.compute_chi(params) | #return -0.5*self.compute_chi(params) | |||
#adding a constant | #adding a constant | |||
return -0.5*self.compute_chi(params) | return -0.5*self.compute_chi(params) | |||
def logpriors(self, params): | def logpriors(self, params): | |||
""" | """ | |||
Define uniform prior. | Define uniform prior. | |||
Make sure we're inside the preset boundaries | Make sure we're inside the preset boundaries | |||
use gaussian priors if provided | ||||
:param params: | :param params: | |||
:return: | :return: | |||
""" | """ | |||
if params is None: | if params is None: | |||
self.logger.error("Param is None " ) | self.logger.error("Param is None " ) | |||
in_boundaries = (params >= self.min_boundaries) * (params <= self.m ax_boundaries) | in_boundaries = (params >= self.min_boundaries) * (params <= self.m ax_boundaries) | |||
if (in_boundaries==False).as_vector().any(): | if (in_boundaries==False).as_vector().any(): | |||
return -np.inf | return -np.inf | |||
else: | else: | |||
self.model.sanitize_parameters(params) | self.model.sanitize_parameters(params) | |||
return 0.0 | if self.gprior_parameters is None : | |||
return 0.0 | ||||
else: | ||||
mu = self.gprior_parameters[0] | ||||
sig= self.gprior_parameters[1] | ||||
# Gprior = np.array(stats.norm.logpdf(params, loc=mu, scale | ||||
=sig) * has_gaussian_prior) | ||||
Gprior = np.array(-0.5 * (mu-params)**2/sig**2) | ||||
return np.nansum(Gprior) | ||||
#for PyMultinest | #for PyMultinest | |||
def pyloglike(self, cube, ndim, nparams): | def pyloglike(self, cube, ndim, nparams): | |||
""" | """ | |||
wrap for pymultinest | wrap for pymultinest | |||
""" | """ | |||
vect = [cube[i] for i in range(ndim)] | vect = [cube[i] for i in range(ndim)] | |||
params = self.model.Parameters().from_ndarray(vect) | params = self.model.Parameters().from_ndarray(vect) | |||
self.model.sanitize_parameters(params) | self.model.sanitize_parameters(params) | |||
return self.loglike(params) | return self.loglike(params) | |||
#return self.loglike(params) | ||||
def pycube(self, cube, ndim, nparams): | def pycube(self, cube, ndim, nparams): | |||
""" | """ | |||
Transforms samples `u` drawn from the unit cube to samples to those | Transforms samples `u` drawn from the unit cube to samples to those | |||
from our uniform prior | from our uniform prior | |||
for pymultinest | for pymultinest | |||
""" | """ | |||
if self.gprior_parameters is not None: | ||||
mu = self.gprior_parameters[0] | ||||
sig = self.gprior_parameters[1] | ||||
has_gaussian_prior = np.isfinite(mu) | ||||
else: | ||||
has_gaussian_prior = np.ones_like(self.initial_parameters)==0 | ||||
for i in range(ndim): | for i in range(ndim): | |||
cube[i] = (self.max_boundaries - self.min_boundaries)[i] * cube | if has_gaussian_prior[i]: | |||
[i] + self.min_boundaries[i] | #cube[i] = stats.norm(loc=mu[i], scale=sig[i]).ppf(cube[i]) | |||
cube[i] = Phi_ppf(cube[i], loc=mu[i], scale=sig[i]) | ||||
else: | ||||
cube[i] = (self.max_boundaries - self.min_boundaries)[i] * | ||||
cube[i] + self.min_boundaries[i] | ||||
#for ultranest | ||||
#For Dynesty | #For Dynesty | |||
def ptform(self, u): | def ptform(self, u): | |||
"""Transforms samples `u` drawn from the unit cube to samples to th ose | """Transforms samples `u` drawn from the unit cube to samples to th ose | |||
from our uniform prior | from our uniform prior | |||
for Dynesty | for Dynesty | |||
""" | """ | |||
return (self.max_boundaries - self.min_boundaries) * u + self.min_b oundaries | return (self.max_boundaries - self.min_boundaries) * u + self.min_b oundaries | |||
skipping to change at line 211 | skipping to change at line 232 | |||
# Some useful vars | # Some useful vars | |||
count_alpha_ok = 0 | count_alpha_ok = 0 | |||
count_min = 0 | count_min = 0 | |||
total_iterations = 0 | total_iterations = 0 | |||
ki_min = sys.maxsize # that way, it can only go down | ki_min = sys.maxsize # that way, it can only go down | |||
galaxy = self.initial_parameters | galaxy = self.initial_parameters | |||
galaxy_old = galaxy.copy() | galaxy_old = galaxy.copy() | |||
galaxy_new = galaxy_old.copy() | galaxy_new = galaxy_old.copy() | |||
chi_old = self.compute_chi(galaxy) | #chi_old = self.compute_chi(galaxy) | |||
#lnprob = self.lnprob(galaxy) | lnprob_old = self.lnprob(galaxy) | |||
self.logger.critical("Running GalPak MHSampler with Sampling %s" % (sampling_method)) | self.logger.critical("Running GalPak MHSampler with Sampling %s" % (sampling_method)) | |||
names_param = list(galaxy.names) | names_param = list(galaxy.names) | |||
names_param.append('reduced_chi') | names_param.append('reduced_chi') | |||
# names_param = [ | # names_param = [ | |||
# 'x', 'y', 'z', 'flux', 'radius', 'inclination', 'pa', | # 'x', 'y', 'z', 'flux', 'radius', 'inclination', 'pa', | |||
# 'turnover_radius', 'maximum_velocity', 'velocity_dispersion', | # 'turnover_radius', 'maximum_velocity', 'velocity_dispersion', | |||
# 'reduced_chi', | # 'reduced_chi', | |||
# ] | # ] | |||
skipping to change at line 260 | skipping to change at line 281 | |||
in_boundaries = (galaxy_new >= self.min_boundaries) * (galaxy_n ew <= self.max_boundaries) | in_boundaries = (galaxy_new >= self.min_boundaries) * (galaxy_n ew <= self.max_boundaries) | |||
if in_boundaries.all(): | if in_boundaries.all(): | |||
# Computing convolved model with new parameters | # Computing convolved model with new parameters | |||
chi_new = self.compute_chi(galaxy_new) | chi_new = self.compute_chi(galaxy_new) | |||
if chi_new<1e-3: | if chi_new<1e-3: | |||
#print chi_new,galaxy_new | #print chi_new,galaxy_new | |||
self.logger.error('Chi2 is 0, quit') | self.logger.error('Chi2 is 0, quit') | |||
exit() | exit() | |||
lnprob_new = self.lnprob(galaxy_new) | ||||
# Compute ratio of likelihood a posteriori | # Compute ratio of likelihood a posteriori | |||
# exp( old-new / 2 ) | # exp( old-new / 2 ) | |||
likelihood = safe_exp(-0.5 * (chi_new - chi_old)) | ||||
#likelihood = safe_exp(-0.5 * (chi_new - chi_old) ) | ||||
likelihood = safe_exp(lnprob_new - lnprob_old) | ||||
# likelihood > 1 => new is better | # likelihood > 1 => new is better | |||
# likelihood < 1 => accept or reject | # likelihood < 1 => accept or reject | |||
alpha = np.random.rand() | alpha = np.random.rand() | |||
# Conservation test | # Conservation test | |||
if alpha < likelihood: | if alpha < likelihood: | |||
count_alpha_ok += 1 | count_alpha_ok += 1 | |||
rate = count_alpha_ok * 100. / total_iterations | rate = count_alpha_ok * 100. / total_iterations | |||
# Save minimum | # Save minimum | |||
if ki_min > chi_new: | if ki_min > chi_new: | |||
ki_min = chi_new | ki_min = chi_new | |||
count_min = count_alpha_ok | count_min = count_alpha_ok | |||
galaxy_old = galaxy_new | galaxy_old = galaxy_new | |||
chi_old = chi_new | #chi_old = chi_new | |||
lnprob_old = lnprob_new | ||||
# vect = np.append(galaxy_new, chi_new / self.Ndegree) | # vect = np.append(galaxy_new, chi_new / self.Ndegree) | |||
#chain[count_alpha_ok - 1] = np.float32(vect) | #chain[count_alpha_ok - 1] = np.float32(vect) | |||
# chain.add_row(vect) | # chain.add_row(vect) | |||
self.chain_rows.append(list(galaxy_new) + | self.chain_rows.append(list(galaxy_new) + | |||
[chi_new / self.Ndegree]) | [chi_new / self.Ndegree]) | |||
if self.verbose: | if self.verbose: | |||
# Check that parameters are not too close to the bo undaries | # Check that parameters are not too close to the bo undaries | |||
too_close_to_max = np.abs((galaxy_new - self.max_bo undaries) / self.max_boundaries) < self.eps | too_close_to_max = np.abs((galaxy_new - self.max_bo undaries) / self.max_boundaries) < self.eps | |||
skipping to change at line 349 | skipping to change at line 374 | |||
Normal: Gaussian proposal | Normal: Gaussian proposal | |||
""" | """ | |||
if sampling == 'Cauchy': | if sampling == 'Cauchy': | |||
random_uniforms = np.random.uniform(-np.pi / 2., np.pi / 2., si ze=len(params)) | random_uniforms = np.random.uniform(-np.pi / 2., np.pi / 2., si ze=len(params)) | |||
galaxy_new = params + scale * np.tan(random_uniforms) | galaxy_new = params + scale * np.tan(random_uniforms) | |||
elif sampling == 'Normal': | elif sampling == 'Normal': | |||
galaxy_new = np.random.normal(params, scale, size=len(params)) | galaxy_new = np.random.normal(params, scale, size=len(params)) | |||
elif sampling == 'AdaptiveCauchy': | elif sampling == 'AdaptiveCauchy': | |||
random_uniforms = np.random.uniform(-np.pi / 2., np.pi / 2., si ze=len(params)) | random_uniforms = np.random.uniform(-np.pi / 2., np.pi / 2., si ze=len(params)) | |||
#@fixme should be covariance | #@fixme should be covariance | |||
if len(self.chain_rows)>1500: | if len(self.chain_rows) > 2500: | |||
scale = np.sqrt(np.std(np.array(self.chain_rows)[-1500:, :- | ||||
1], axis=0)) ** 2 / len(params) | ||||
elif len(self.chain_rows)>1500: | ||||
scale = np.sqrt(np.std(np.array(self.chain_rows)[-750:,:-1] , axis=0) )**2 / len(params) | scale = np.sqrt(np.std(np.array(self.chain_rows)[-750:,:-1] , axis=0) )**2 / len(params) | |||
elif len(self.chain_rows) > 500: | elif len(self.chain_rows) > 500: | |||
scale = np.sqrt(np.std(np.array(self.chain_rows)[-250:, :-1 ], axis=0) * 1.25 ) ** 2 / len(params) | scale = np.sqrt(np.std(np.array(self.chain_rows)[-250:, :-1 ], axis=0) * 0.8 ) ** 2 / len(params) | |||
elif len(self.chain_rows) > 50: | elif len(self.chain_rows) > 50: | |||
scale = np.sqrt(np.std(np.array(self.chain_rows)[-50:, :-1] , axis=0) * 1.5) ** 2 / len(params) | scale = np.sqrt(np.std(np.array(self.chain_rows)[-50:, :-1] , axis=0) * 0.5) ** 2 / len(params) | |||
galaxy_new = params + scale * np.tan(random_uniforms) | galaxy_new = params + scale * np.tan(random_uniforms) | |||
else: | else: | |||
raise Exception("Not implemented. Should be %s" %(self.SAMPLING _VALID)) | raise Exception("Not implemented. Should be %s" %(self.SAMPLING _VALID)) | |||
return galaxy_new | return galaxy_new | |||
def _init_sampling_scale(self, random_scale, should_guess_flags): | def _init_sampling_scale(self, random_scale, should_guess_flags): | |||
dim_d = np.size(self.cube.data) | dim_d = np.size(self.cube.data) | |||
dim_p = len(self.galaxy) | dim_p = len(self.galaxy) | |||
End of changes. 13 change blocks. | ||||
11 lines changed or deleted | 40 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |