mirror of
https://github.com/dnlbauer/WHAM.git
synced 2026-09-11 06:35:30 +00:00
uncorr flag
This commit is contained in:
@@ -8,18 +8,12 @@ use rgsl::statistics;
|
||||
// Method for the Analysis of Simulated and Parallel Tempering Simulations, JCTC"
|
||||
fn statistical_ineff(timeseries: &[f64]) -> f64 {
|
||||
let n = timeseries.len();
|
||||
let mean = statistics::mean(timeseries, 1, timeseries.len());
|
||||
let d_mean = timeseries.iter().map(|x| x-mean).collect::<Vec<f64>>();
|
||||
let cov = statistics::covariance(timeseries, 1, timeseries, 1, n);
|
||||
let autocorr = autocorrelation(timeseries);
|
||||
|
||||
let mut g = 1.0;
|
||||
for t in 1..(n-1) {
|
||||
|
||||
// normalized autocorr C(t) = (<x_n*x_(n+t)> - <x_n>^2) / (<x_n^2> - <x_n>^2)
|
||||
let tmp = d_mean[0..n-t].iter().zip(d_mean[t..n].iter()).map(|(x, y)| x*y);
|
||||
let c: f64 = tmp.map(|x| x+x).sum::<f64>() / (2.0 * (n as f64-t as f64)*cov);
|
||||
|
||||
if c <= 0.0 { // terminate at first 0 (autocorr gets noisy from here)
|
||||
let c = autocorr[t-1];
|
||||
if c <= 0.0 {
|
||||
break;
|
||||
}
|
||||
g = g + (2.0*c*(1.0-t as f64/n as f64))
|
||||
@@ -31,6 +25,22 @@ fn statistical_ineff(timeseries: &[f64]) -> f64 {
|
||||
}
|
||||
}
|
||||
|
||||
// calculates the autocorrelation of a simeseries
|
||||
fn autocorrelation(timeseries: &[f64]) -> Vec<f64> {
|
||||
let n = timeseries.len();
|
||||
let mean = statistics::mean(timeseries, 1, timeseries.len());
|
||||
let d_mean = timeseries.iter().map(|x| x-mean).collect::<Vec<f64>>();
|
||||
let cov = statistics::covariance(timeseries, 1, timeseries, 1, n);
|
||||
|
||||
let mut autocorr = Vec::new();
|
||||
for t in 1..(n-1) {
|
||||
let tmp = d_mean[0..n-t].iter().zip(d_mean[t..n].iter()).map(|(x, y)| x*y);
|
||||
let c: f64 = tmp.map(|x| x+x).sum::<f64>() / (2.0 * (n as f64-t as f64)*cov);
|
||||
autocorr.push(c);
|
||||
}
|
||||
autocorr
|
||||
}
|
||||
|
||||
// The autocorrelation time of a timeseries can be deduced from the
|
||||
// `statistical_ineff` by (g-1)/2.0
|
||||
fn autocorrelation_time(g: f64) -> f64 {
|
||||
@@ -55,6 +65,23 @@ mod tests {
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn autocorrelation() {
|
||||
let timeseries = read_timeseries("example/1d_cyclic/COLVAR-2.5.xvg");
|
||||
let autocorr = super::autocorrelation(×eries);
|
||||
let expected = [
|
||||
0.6919008655979143, 0.5331719399671355,
|
||||
0.20472620956463589, -0.002850876458920514,
|
||||
-0.13842850077938146, -0.2652923552973232,
|
||||
-0.31427198272235385, -0.2617505151557693,
|
||||
-0.20594864730290338, -0.13310019091811812,
|
||||
-0.1887568901193426, -0.1944936625424933,
|
||||
-0.1963599673189461, -0.11391587833838003];
|
||||
for (actual, expected) in autocorr.iter().zip(expected.iter()) {
|
||||
assert!((actual-expected).abs() < 0.001);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn statistical_ineff() {
|
||||
let timeseries = read_timeseries("example/1d_cyclic/COLVAR-2.5.xvg");
|
||||
|
||||
Reference in New Issue
Block a user