double BasicCircular::perturb_hyperparameters(RNG& rng) { double logH = 0.; int which = rng.rand_int(3); if(which == 0) { xc += size*rng.randh(); yc += size*rng.randh(); xc = DNest4::mod(xc - x_min, x_max - x_min) + x_min; yc = DNest4::mod(yc - y_min, y_max - y_min) + y_min; } else if(which == 1) { width = log(width); width += log(1E3)*rng.randh(); width = DNest4::mod(width - log(1E-2*size), log(1E3)) + log(1E-2*size); width = exp(width); } else if(which == 2) { mu = log(mu); mu += log(mu_max/mu_min)*rng.randh(); mu = DNest4::mod(mu - log(mu_min), log(mu_max/mu_min)) + log(mu_min); mu = exp(mu); } return logH; }
double Sinusoid::perturb_parameters(RNG& rng) { double logH = 0.0; // Perturb one of the three parameters int which = rng.rand_int(3); if(which == 0) { A = log(A); logH -= -0.5*pow(A/0.1, 2); A += 0.1*rng.randh(); logH += -0.5*pow(A/0.1, 2); A = exp(A); } else if(which == 1) { log10_period += rng.randh(); wrap(log10_period, -1.0, 0.0); } else { phi += 2 * M_PI * rng.randh(); wrap(phi, 0.0, 2 * M_PI); } return logH; }
double MyConditionalPrior::perturb_hyperparameters(RNG& rng) { double logH = 0.0; int which = rng.rand_int(4); if(which == 0) { logH += cauchy.perturb(location_log_period, rng); } else if(which == 1) { scale_log_period += 5.0*rng.randh(); wrap(scale_log_period, 0.0, 5.0); } else if(which == 2) { logH += cauchy.perturb(location_log_amplitude, rng); } else { scale_log_amplitude += 5.0*rng.randh(); wrap(scale_log_amplitude, 0.0, 5.0); } return logH; }
double Sinusoid::perturb(RNG& rng) { double logH = 0.0; if(rng.rand() < 0.5) { // Perturb one of the three parameters int which = rng.rand_int(3); if(which == 0) { A = 1.0 - exp(-A); A += rng.randh(); wrap(A, 0.0, 1.0); A = -log(1.0 - A); } else if(which == 1) { log10_period += 3.0 * rng.randh(); wrap(log10_period, log10(1E-3 * t_range), log10(t_range)); } else { phi += 2 * M_PI * rng.randh(); wrap(phi, 0.0, 2 * M_PI); } } else { // Perturb some of the ns. if(rng.rand() <= 0.5) { // Just change one int which = rng.rand_int(N); logH -= -0.5*pow(n[which], 2); n[which] += rng.randh(); logH += -0.5*pow(n[which], 2); } else { // Potentially regenerate many int reps = pow(N, rng.rand()); for(int i=0; i<reps; ++i) n[rng.rand_int(N)] = rng.randn(); } } assemble(); return logH; }
double Pareto::perturb_hyperparameters(RNG& rng) { double logH = 0.; int which = rng.rand_int(2); if(which == 0) { f0 = log(f0); f0 += log(f0_max/f0_min)*rng.randh(); f0 = mod(f0 - log(f0_min), log(f0_max/f0_min)) + log(f0_min); f0 = exp(f0); } else { alpha += 4.*rng.randh(); alpha = mod(alpha - 1., 4.) + 1.; } return logH; }
double Gravity::perturb(RNG& rng) { double logH = 0.; int which = rng.rand_int(x.size()); int what = rng.rand_int(6); // Remove effect of this particle increment(which, -1); if(what == 0) { x[which] += 20.*rng.randh(); x[which] = mod(x[which] + 10., 20.) - 10.; } else if(what == 1) { y[which] += 20.*rng.randh(); y[which] = mod(y[which] + 10., 20.) - 10.; } else if(what == 2) { z[which] += 20.*rng.randh(); z[which] = mod(z[which] + 10., 20.) - 10.; } else if(what == 3) { vx[which] += 20.*rng.randh(); vx[which] = mod(vx[which] + 10., 20.) - 10.; } else if(what == 4) { vy[which] += 20.*rng.randh(); vy[which] = mod(vy[which] + 10., 20.) - 10.; } else { vz[which] += 20.*rng.randh(); vz[which] = mod(vz[which] + 10., 20.) - 10.; } if(x[which]*x[which] + y[which]*y[which] + z[which]*z[which] > 100.) logH = -1E250; if(vx[which]*vx[which] + vy[which]*vy[which] + vz[which]*vz[which] > 100.) logH = -1E250; increment(which, +1); staleness++; if(staleness >= 100) refresh(); compute_scalars(); return logH; }
double MyModel::perturb(RNG& rng) { double logH = 0.; if(rng.rand() <= 0.75) { logH += objects.perturb(rng); calculate_image(); } else { sigma = log(sigma); sigma += log(1E6)*rng.randh(); sigma = mod(sigma - log(1.), log(1E6)) + log(1.); sigma = exp(sigma); } return logH; }
double MyConditionalPrior::perturb_hyperparameters(RNG& rng) { double logH = 0.0; int which = rng.rand_int(2); if(which == 0) { Cauchy c; A_min = log(A_min); logH += c.perturb(A_min, rng); A_min = exp(A_min); } else { mu += 3.0*rng.randh(); wrap(mu, 0.0, 3.0); } return logH; }
double MyModel::perturb(RNG& rng) { double logH = 0.; if(rng.rand() <= 0.75) { logH += objects.perturb(rng); objects.consolidate_diff(); calculate_mu(); } else { sigma = log(sigma); sigma += log(1E6)*rng.randh(); sigma = mod(sigma - log(1E-3), log(1E6)) + log(1E-3); sigma = exp(sigma); } return logH; }
double Sinusoid::perturb(RNG& rng) { double logH = 0.0; int proposal_type = 1;//rng.rand_int(4); if(proposal_type == 0) { // Perturb parameters, changing data along with it std::vector<double> mu_old = mu; logH += perturb_parameters(rng); calculate_mu(); double n; for(size_t i=0; i<N; ++i) { n = (y[i] - mu_old[i]) / sigma; y[i] = mu[i] + sigma * n; } calculate_logl(); } else if(proposal_type == 1) { // Perturb parameters, keeping data constant // (aka Metropolis step of the posterior!) logH -= logl; logH += perturb_parameters(rng); calculate_mu(); calculate_logl(); logH += logl; } else if(proposal_type == 2) { // Just change one datum int which = rng.rand_int(N); logH -= -0.5*pow((y[which] - mu[which])/sigma, 2); y[which] += sigma * rng.randh(); logH += -0.5*pow((y[which] - mu[which])/sigma, 2); calculate_logl(); } else { // Potentially regenerate many of the data points int reps = pow(N, rng.rand()); int which; for(int i=0; i<reps; ++i) { which = rng.rand_int(N); y[which] = mu[which] + sigma * rng.randn(); } calculate_logl(); } return logH; }