Skip to content

Commit

Permalink
import ramcmc
Browse files Browse the repository at this point in the history
  • Loading branch information
adamwang15 committed Jul 15, 2024
1 parent 9631e39 commit a05aeff
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 66 deletions.
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ LinkingTo:
bsvars,
Rcpp,
RcppArmadillo,
RcppProgress
RcppProgress,
ramcmc
Depends:
R (>= 2.10),
bsvars
Expand Down
70 changes: 70 additions & 0 deletions src/mcmc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@

#include <functional>
#include <iostream>
#include <RcppArmadillo.h>
#include "Rcpp/Rmath.h"
#include "progress.hpp"
#include "ramcmc.h"

using namespace arma;


// adaptive Metropolis algorithm for strictly positive parameters
// [[Rcpp:interfaces(cpp)]]
arma::mat metropolis(
const int& T,
const int& t0,
arma::vec x,
arma::mat Sigma,
const std::function<double(const arma::vec&)>& log_target
) {

int n = x.n_elem;

x = log(x);
vec xbar = x;
double s = 2.38 / sqrt(n);
double d = log_target(x) + sum(x);

double new_d, a;
vec new_x, diff;

mat X(n, T);
X.col(0) = x;

vec progress = round(linspace(0, T, 50));
Progress p(50, true);

for (int t = 1; t < T; t++) {
new_x = mvnrnd(x, s*s * Sigma);
new_d = log_target(exp(new_x)) + sum(new_x);
a = std::min(1.0, exp(new_d - d));

if (randu() < a) {
x = new_x;
d = new_d;
}
X.col(t) = x;

if (t <= t0) {
diff = x - xbar;
s += pow(t, -0.6) * (a - 0.234);
xbar += diff / (t + 1);
Sigma = Sigma * t / (t + 1) + diff * diff.t() * t / (t + 1) / (t + 1);
}

if (any(progress == t)) {
p.increment();
}
}

X = exp(X);
return X;
}







23 changes: 23 additions & 0 deletions src/mcmc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef _MCMC_H_
#define _MCMC_H_


#include <functional>
#include <iostream>
#include <RcppArmadillo.h>
#include "Rcpp/Rmath.h"
#include "progress.hpp"

using namespace arma;


arma::mat metropolis(
const int& T,
const int& t0,
arma::vec x,
arma::mat Sigma,
const std::function<double(const arma::vec&)>& log_target
);


#endif // _MCMC_H_
1 change: 1 addition & 0 deletions src/sample_hyper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <RcppArmadillo.h>

#include "utils.h"
#include "mcmc.h"

using namespace Rcpp;
using namespace arma;
Expand Down
65 changes: 0 additions & 65 deletions src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
#include <functional>
#include <iostream>
#include <RcppArmadillo.h>
#include "Rcpp/Rmath.h"
#include "progress.hpp"

using namespace arma;

Expand Down Expand Up @@ -79,66 +77,3 @@ arma::mat Df(
return result;
}


// adaptive Metropolis algorithm for strictly positive parameters
// [[Rcpp:interfaces(cpp)]]
arma::mat metropolis(
const int& T,
const int& t0,
arma::vec x,
arma::mat Sigma,
const std::function<double(const arma::vec&)>& log_target
) {

int n = x.n_elem;

x = log(x);
double s = 2.38 / sqrt(n);
double d = log_target(x) + sum(x);

double new_d, a;
vec new_x, xbar, diff;

mat X(n, T);
X.col(0) = x;

vec progress = round(linspace(0, T, 50));
Progress p(50, true);

for (int t = 1; t < T; t++) {
new_x = mvnrnd(x, s*s * Sigma);
new_d = log_target(exp(new_x)) + sum(new_x);
a = std::min(1.0, exp(new_d - d));

if (randu() < a) {
x = new_x;
d = new_d;
}
X.col(t) = x;


if (t == 1) {
xbar = mean(X.cols(0, t), 1);
Sigma = cov(X.cols(0, t).t());
} else if (t <= t0) {
diff = x - xbar;
s += pow(t, -0.6) * (a - 0.234);
xbar += diff / (t + 1);
Sigma = Sigma * t / (t + 1) + diff * diff.t() * t / (t + 1) / (t + 1);
}

if (any(progress == t)) {
p.increment();
}
}

X = exp(X);
return X;
}







0 comments on commit a05aeff

Please sign in to comment.