New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Header-only patch #29
Merged
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
.Rproj.user | ||
.Rhistory | ||
.RData | ||
.DS_store | ||
src/*.o | ||
src/*.so | ||
src/*.dll |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -76,5 +76,98 @@ namespace smc { | |
/// Returns the empirical covariance matrix based on the current weighted particle set. | ||
arma::mat GetEmpCov(void) const {return empCov;} | ||
}; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, you could debate whether all of what follows belongs inline in headers; much of this is prototypical code that a user would need to replicate to implement a different adaptation scheme, but again I don't feel particularly strongly either way. |
||
/// Computes the difference between the conditional ESS given the specified temperature difference and the desired conditional ESS. | ||
inline double staticModelAdapt::CESSdiff(const arma::vec & logweight, const arma::vec & loglike, double tempDiff, double desiredCESS){ | ||
double logsum1 = stableLogSumWeights(logweight + tempDiff*loglike); | ||
double logsum2 = stableLogSumWeights(logweight + 2*tempDiff*loglike); | ||
|
||
return exp(log(static_cast<double>(logweight.n_rows)) + 2*logsum1 - logsum2) - desiredCESS; | ||
} | ||
|
||
///Performs the bisection method to find the temperature within (temp_curr,1) which gives the desired conditional ESS. | ||
inline double staticModelAdapt::bisection(double curr, const arma::vec & logweight, const arma::vec & loglike, double desiredCESS, double epsilon){ | ||
double a = curr; | ||
double b = 1.0; | ||
double f_a = CESSdiff(logweight,loglike,a-curr,desiredCESS); | ||
double f_b = CESSdiff(logweight,loglike,b-curr,desiredCESS); | ||
if (f_a*f_b>0){ | ||
Rcpp::stop("Bisection method to choose the next temperature failed"); | ||
} else{ | ||
double m, f_m, err; | ||
m = (a+b)/2.0; | ||
f_m = CESSdiff(logweight,loglike,m-curr,desiredCESS); | ||
err = 10.0; | ||
while (err > epsilon){ | ||
if (f_m<0.0){ | ||
b = m; | ||
f_b = f_m; | ||
} else{ | ||
a = m; | ||
f_a = f_m; | ||
} | ||
m = (a+b)/2.0; | ||
f_m = CESSdiff(logweight,loglike,m-curr,desiredCESS); | ||
err = std::abs(f_m); | ||
} | ||
return m; | ||
} | ||
} | ||
|
||
/// Chooses the next temperature such that a desired conditional ESS is maintained. | ||
/// | ||
/// \param logweight An armadillo vector containing the logarithm of the current particle weights. | ||
/// \param loglike An armadillo vector containing the log likelihood of the current particle values. | ||
/// \param desiredCESS The target conditional ESS for the next temperature (generally fixed). | ||
/// \param epsilon The tolerance for the bisection method (maximum difference between desired and actual conditional ESS). | ||
inline void staticModelAdapt::ChooseTemp(const arma::vec & logweight, const arma::vec & loglike, double desiredCESS, double epsilon) { | ||
double temp_curr = temp.back(); | ||
if (CESSdiff(logweight,loglike,1.0-temp_curr,desiredCESS)>=-epsilon){ | ||
temp.push_back(1.0); | ||
} else { | ||
temp.push_back(bisection(temp_curr, logweight, loglike, desiredCESS, epsilon)); | ||
} | ||
} | ||
|
||
/// Calculates the empirical covariance matrix based on the current weighted particle set. | ||
/// | ||
/// \param theta An [Nxd] armadillo matrix of doubles for the current particle values, where N is | ||
/// the number of particles and d is the dimension of the parameter. | ||
/// \param logweight An armadillo vector containing the logarithm of the current particle weights. | ||
inline void staticModelAdapt::calcEmpCov(const arma::mat & theta, const arma::vec & logweight){ | ||
int N = logweight.n_rows; | ||
arma::vec normWeights = exp(logweight - stableLogSumWeights(logweight)); | ||
|
||
arma::mat diff = theta - arma::ones(N,1)*arma::mean(theta,0); | ||
empCov = diff.t()*diagmat(normWeights)*diff; | ||
} | ||
|
||
/// Calculates the Cholesky decomposition of the empirical covariance matrix based on the current weighted particle set. | ||
/// | ||
/// \param theta An [Nxd] armadillo matrix of doubles for the current particle values, where N is | ||
/// the number of particles and d is the dimension of the parameter | ||
/// \param logweight An armadillo vector of the logarithm of the current particle weights | ||
inline void staticModelAdapt::calcCholCov(const arma::mat & theta, const arma::vec logweight){ | ||
calcEmpCov(theta,logweight); | ||
cholCov = arma::chol(empCov); | ||
} | ||
|
||
/// Calculates the number of MCMC repeats based on the results of the most recent set of MCMC moves. | ||
/// | ||
/// \param acceptProb The proportion of accepted MCMC steps in the most recent iteration. | ||
/// \param desiredAcceptProb The desired probability of a successful move for each particle. | ||
/// \param initialN The initial number of MCMC repeats. | ||
/// \param maxReps The maximum number of MCMC repeats. | ||
inline int staticModelAdapt::calcMcmcRepeats(double acceptProb, double desiredAcceptProb, int initialN, int maxReps){ | ||
if (acceptProb + 1.0 <= 1e-9){ | ||
return initialN; | ||
} else if (acceptProb - 1.0 >= -1e-9){ | ||
return 1; | ||
} else if (acceptProb <= 1e-9){ | ||
return maxReps; | ||
} else { | ||
return std::min(maxReps,static_cast<int>(std::ceil(log(1.0-desiredAcceptProb)/log(1.0-acceptProb)))); | ||
} | ||
} | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a vague aesthetic objection to non-templated code in header files, but that's because I'm a dinosaur. With inline functions I guess it doesn't matter anyway, so I don't have a problem with it if @eddelbuettel is happy. I can see at least small advantages in keeping the library side of the code header only if it doesn't cause other problems.