use exp(F) and exp(U) for wham iterations - huge performance increase!

This commit is contained in:
Daniel Bauer
2018-10-18 00:13:54 +02:00
parent b064ecea6d
commit 6b9661bd13
3 changed files with 10176 additions and 10153 deletions

View File

@@ -1,101 +1,127 @@
#x Free Energy Probability
-3.108600 7.118164 0.003561
-3.045800 5.331288 0.007290
-2.983000 3.879239 0.013048
-2.920200 2.968658 0.018796
-2.857400 1.942493 0.028362
-2.794600 1.418407 0.034994
-2.731800 1.169397 0.038668
-2.669000 0.843023 0.044073
-2.606200 0.636020 0.047887
-2.543400 0.720123 0.046299
-2.480600 1.066434 0.040297
-2.417800 1.509855 0.033734
-2.355000 2.015549 0.027544
-2.292200 2.226943 0.025306
-2.229400 2.573176 0.022026
-2.166600 2.591946 0.021861
-2.103800 2.476836 0.022893
-2.041000 2.513953 0.022555
-1.978200 2.470033 0.022956
-1.915400 2.227585 0.025299
-1.852600 2.105310 0.026570
-1.789800 1.778780 0.030286
-1.727000 1.447127 0.034593
-1.664200 0.906384 0.042968
-1.601400 0.304263 0.054699
-1.538600 0.247397 0.055960
-1.475800 0.000000 0.061795
-1.413000 0.536141 0.049843
-1.350200 1.428046 0.034859
-1.287400 2.398149 0.023627
-1.224600 3.784647 0.013552
-1.161800 5.696582 0.006297
-1.099000 7.656157 0.002870
-1.036200 9.954999 0.001142
-0.973400 12.357406 0.000436
-0.910600 14.954253 0.000154
-0.847800 17.745325 0.000050
-0.785000 20.559459 0.000016
-0.722200 22.783557 0.000007
-0.659400 25.175862 0.000003
-0.596600 26.419977 0.000002
-0.533800 27.885996 0.000001
-0.471000 29.029330 0.000001
-0.408200 30.366552 0.000000
-0.345400 31.615248 0.000000
-0.282600 32.781711 0.000000
-0.219800 33.731373 0.000000
-0.157000 34.476008 0.000000
-0.094200 35.387294 0.000000
-0.031400 35.579750 0.000000
0.031400 35.520188 0.000000
0.094200 35.344757 0.000000
0.157000 34.886453 0.000000
0.219800 33.633992 0.000000
0.282600 32.686504 0.000000
0.345400 31.211770 0.000000
0.408200 29.680443 0.000000
0.471000 28.032233 0.000001
0.533800 26.439591 0.000002
0.596600 24.432458 0.000003
0.659400 22.309884 0.000008
0.722200 20.186031 0.000019
0.785000 18.295037 0.000040
0.847800 16.221223 0.000093
0.910600 14.251901 0.000204
0.973400 12.562343 0.000402
1.036200 11.184019 0.000698
1.099000 10.040667 0.001103
1.161800 9.369054 0.001444
1.224600 9.095382 0.001612
1.287400 9.256025 0.001511
1.350200 9.814058 0.001208
1.413000 10.945197 0.000768
1.475800 12.518888 0.000409
1.538600 14.409735 0.000191
1.601400 16.451956 0.000084
1.664200 18.589157 0.000036
1.727000 20.669496 0.000016
1.789800 22.804783 0.000007
1.852600 24.531682 0.000003
1.915400 26.182604 0.000002
1.978200 27.279432 0.000001
2.041000 28.571373 0.000001
2.103800 29.328963 0.000000
2.166600 29.897732 0.000000
2.229400 30.320901 0.000000
2.292200 30.065385 0.000000
2.355000 29.809130 0.000000
2.417800 29.340595 0.000000
2.480600 28.473341 0.000001
2.543400 27.679348 0.000001
2.606200 26.453155 0.000002
2.669000 24.424644 0.000003
2.731800 22.285929 0.000008
2.794600 19.958403 0.000021
2.857400 17.606287 0.000053
2.920200 15.420135 0.000128
2.983000 13.069596 0.000328
3.045800 11.036083 0.000740
3.108600 9.015655 0.001664
#Coor Free +/- Prob +/-
-3.108600 7.109190 -nan 0.003556 -nan
-3.045800 5.311412 -nan 0.007311 -nan
-2.983000 3.849095 -nan 0.013139 -nan
-2.920200 2.933168 -nan 0.018968 -nan
-2.857400 1.907181 -nan 0.028620 -nan
-2.794600 1.385773 -nan 0.035274 -nan
-2.731800 1.139312 -nan 0.038937 -nan
-2.669000 0.814751 -nan 0.044348 -nan
-2.606200 0.609195 -nan 0.048157 -nan
-2.543400 0.694709 -nan 0.046534 -nan
-2.480600 1.042492 -nan 0.040478 -nan
-2.417800 1.487426 -nan 0.033865 -nan
-2.355000 1.994612 -nan 0.027634 -nan
-2.292200 2.207453 -nan 0.025374 -nan
-2.229400 2.555138 -nan 0.022072 -nan
-2.166600 2.575426 -nan 0.021894 -nan
-2.103800 2.461877 -nan 0.022913 -nan
-2.041000 2.500517 -nan 0.022561 -nan
-1.978200 2.458051 -nan 0.022949 -nan
-1.915400 2.217054 -nan 0.025276 -nan
-1.852600 2.096290 -nan 0.026530 -nan
-1.789800 1.771307 -nan 0.030222 -nan
-1.727000 1.441175 -nan 0.034499 -nan
-1.664200 0.901911 -nan 0.042825 -nan
-1.601400 0.301267 -nan 0.054485 -nan
-1.538600 0.245895 -nan 0.055708 -nan
-1.475800 0.000000 -nan 0.061480 -nan
-1.413000 0.537640 -nan 0.049559 -nan
-1.350200 1.431041 -nan 0.034639 -nan
-1.287400 2.402640 -nan 0.023464 -nan
-1.224600 3.790635 -nan 0.013450 -nan
-1.161800 5.704072 -nan 0.006246 -nan
-1.099000 7.665152 -nan 0.002845 -nan
-1.036200 9.965495 -nan 0.001131 -nan
-0.973400 12.369366 -nan 0.000432 -nan
-0.910600 14.967624 -nan 0.000152 -nan
-0.847800 17.760111 -nan 0.000050 -nan
-0.785000 20.575788 -nan 0.000016 -nan
-0.722200 22.801620 -nan 0.000007 -nan
-0.659400 25.195750 -nan 0.000003 -nan
-0.596600 26.441571 -nan 0.000002 -nan
-0.533800 27.909051 -nan 0.000001 -nan
-0.471000 29.053664 -nan 0.000001 -nan
-0.408200 30.392176 -nan 0.000000 -nan
-0.345400 31.642366 -nan 0.000000 -nan
-0.282600 32.810590 -nan 0.000000 -nan
-0.219800 33.762125 -nan 0.000000 -nan
-0.157000 34.508470 -nan 0.000000 -nan
-0.094200 35.421120 -nan 0.000000 -nan
-0.031400 35.614610 -nan 0.000000 -nan
0.031400 35.555913 -nan 0.000000 -nan
0.094200 35.381388 -nan 0.000000 -nan
0.157000 34.924243 -nan 0.000000 -nan
0.219800 33.673332 -nan 0.000000 -nan
0.282600 32.727755 -nan 0.000000 -nan
0.345400 31.255053 -nan 0.000000 -nan
0.408200 29.725589 -nan 0.000000 -nan
0.471000 28.078949 -nan 0.000001 -nan
0.533800 26.487669 -nan 0.000002 -nan
0.596600 24.481873 -nan 0.000003 -nan
0.659400 22.360728 -nan 0.000008 -nan
0.722200 20.238391 -nan 0.000018 -nan
0.785000 18.348925 -nan 0.000039 -nan
0.847800 16.276613 -nan 0.000090 -nan
0.910600 14.308785 -nan 0.000198 -nan
0.973400 12.620723 -nan 0.000390 -nan
1.036200 11.243896 -nan 0.000678 -nan
1.099000 10.102041 -nan 0.001071 -nan
1.161800 9.431925 -nan 0.001401 -nan
1.224600 9.159750 -nan 0.001563 -nan
1.287400 9.321889 -nan 0.001464 -nan
1.350200 9.881419 -nan 0.001170 -nan
1.413000 11.014057 -nan 0.000743 -nan
1.475800 12.589255 -nan 0.000395 -nan
1.538600 14.481607 -nan 0.000185 -nan
1.601400 16.525295 -nan 0.000082 -nan
1.664200 18.663885 -nan 0.000035 -nan
1.727000 20.745586 -nan 0.000015 -nan
1.789800 22.882359 -nan 0.000006 -nan
1.852600 24.611022 -nan 0.000003 -nan
1.915400 26.263981 -nan 0.000002 -nan
1.978200 27.362886 -nan 0.000001 -nan
2.041000 28.656631 -nan 0.000001 -nan
2.103800 29.415584 -nan 0.000000 -nan
2.166600 29.985317 -nan 0.000000 -nan
2.229400 30.409211 -nan 0.000000 -nan
2.292200 30.154379 -nan 0.000000 -nan
2.355000 29.898976 -nan 0.000000 -nan
2.417800 29.431664 -nan 0.000000 -nan
2.480600 28.566154 -nan 0.000001 -nan
2.543400 27.774399 -nan 0.000001 -nan
2.606200 26.550657 -nan 0.000001 -nan
2.669000 24.524409 -nan 0.000003 -nan
2.731800 22.387526 -nan 0.000008 -nan
2.794600 20.061389 -nan 0.000020 -nan
2.857400 17.710243 -nan 0.000051 -nan
2.920200 15.524401 -nan 0.000122 -nan
2.983000 13.172725 -nan 0.000313 -nan
3.045800 11.135246 -nan 0.000708 -nan
3.108600 9.106349 -nan 0.001597 -nan
#Window Free +/-
#0 0.000000 -nan
#1 -4.304935 -nan
#2 -11.772646 -nan
#3 -18.486638 -nan
#4 -22.834670 -nan
#5 -24.172759 -nan
#6 -22.273996 -nan
#7 -17.239462 -nan
#8 -10.107963 -nan
#9 -5.386748 -nan
#10 -10.219397 -nan
#11 -18.470489 -nan
#12 -25.454944 -nan
#13 -3.099544 -nan
#14 -10.785962 -nan
#15 -19.937669 -nan
#16 -27.163650 -nan
#17 -31.721722 -nan
#18 -33.474006 -nan
#19 -32.952581 -nan
#20 -32.029659 -nan
#21 -32.180907 -nan
#22 -33.041061 -nan
#23 -32.813126 -nan
#24 -30.673600 -nan

File diff suppressed because it is too large Load Diff

View File

@@ -53,25 +53,25 @@ fn calc_bin_probability(bin: usize, ds: &Dataset, F: &[f64]) -> f64 {
let mut bin_count: f64 = 0.0;
for (window, h) in ds.histograms.iter().enumerate() {
bin_count += h.bins[bin];
let bias = -ds.kT*ds.calc_bias(bin, window).ln();
let bias_offset = ((F[window] - bias) / ds.kT).exp();
denom_sum += (h.num_points as f64) * bias_offset;
let bias = ds.calc_bias(bin, window);
denom_sum += (h.num_points as f64) * bias * F[window];
}
bin_count / denom_sum
bin_count / denom_sum
}
// estimate the bias offset F of the histogram based on given probabilities
// This evaluates the second WHAM equation for each window
fn calc_window_F(window: usize, ds: &Dataset, P: &[f64]) -> f64 {
(0..ds.num_bins).zip(P.iter()) // zip bins and P
let f: f64 = (0..ds.num_bins).zip(P.iter()) // zip bins and P
.filter_map(|bin_and_prob: (usize, &f64)| {
if bin_and_prob.1 == &0.0 { // skip zeros for speed
None
} else {
Some(bin_and_prob.1 * ds.calc_bias(bin_and_prob.0, window))
let bias = ds.calc_bias(bin_and_prob.0, window);
Some(bin_and_prob.1 * bias)
}
}).sum()
}).sum();
1.0/f
}
// One full WHAM iteration includes calculation of new probabilities P and
@@ -169,24 +169,31 @@ pub fn run(cfg: &Config) -> Result<(), Box<Error>>{
println!("{}",&histograms);
// allocate only once for better performance
let mut F_prev: Vec<f64> = vec![f64::INFINITY; histograms.num_windows];
let mut F: Vec<f64> = vec![0.0; histograms.num_windows];
let mut F_prev: Vec<f64> = vec![f64::NAN; histograms.num_windows];
let mut F: Vec<f64> = vec![1.0; histograms.num_windows];
let mut F_tmp: Vec<f64> = vec![f64::NAN; histograms.num_windows];
let mut P: Vec<f64> = vec![f64::NAN; histograms.num_bins];
let mut A: Vec<f64> = vec![f64::NAN; histograms.num_bins];
// perform WHAM until convergence
let mut iteration = 0;
while !is_converged(&F_prev, &F, cfg.tolerance) && iteration < cfg.max_iterations {
let mut converged = false;
while !converged && iteration < cfg.max_iterations {
iteration += 1;
// store F values before the next iteration
F_prev.copy_from_slice(&F[..]);
F_prev.copy_from_slice(&F);
// perform wham iteration and update F
perform_wham_iteration(&histograms, &F_prev, &mut F, &mut P);
// output some stats during calculation
if iteration % 10 == 0 {
println!("Iteration {}: dF={}", &iteration, &diff_avg(&F_prev, &F));
F_tmp.copy_from_slice(&F);
F.iter_mut().map(|f| *f=-histograms.kT*f.ln()).count();
F_prev.iter_mut().map(|f| *f=-histograms.kT*f.ln()).count();
converged = is_converged(&F_prev, &F, cfg.tolerance);
println!("Iteration {}: dF={}", &iteration, &diff_avg(&F_prev, &F));
F.copy_from_slice(&F_tmp);
}
// Dump free energy and bias offsets
@@ -235,6 +242,7 @@ fn dump_state(ds: &Dataset, F: &[f64], F_prev: &[f64], P: &[f64], A: &[f64]) {
mod tests {
use super::histogram::{Dataset,Histogram};
use std::f64;
use super::k_B;
macro_rules! assert_delta {
($x:expr, $y:expr, $d:expr) => {
@@ -242,6 +250,14 @@ mod tests {
}
}
fn create_test_ds() -> Dataset {
let h1 = Histogram::new(10, vec![0.0, 1.0, 1.0, 8.0, 0.0]);
let h2 = Histogram::new(10, vec![0.0, 0.0, 8.0, 1.0, 1.0]);
Dataset::new(5, vec![5], vec![1.0], vec![0.0], vec![4.0],
vec![1.0, 1.0], vec![10.0, 10.0], 300.0*k_B, vec![h1, h2], false)
}
#[test]
fn is_converged() {
let new = vec![1.0,1.0];
@@ -255,23 +271,23 @@ mod tests {
assert!(!converged);
}
fn create_test_ds() -> Dataset {
let h1 = Histogram::new(10, vec![0.0, 0.0, 3.0, 4.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
let h2 = Histogram::new(20, vec![0.0, 0.0, 0.0, 3.0, 2.0, 5.0, 10.0, 0.0, 0.0, 0.0, 0.0]);
Dataset::new(4, vec![1], vec![1.0], vec![0.0], vec![4.0],
vec![1.0, 2.0], vec![10.0, 10.0], 2.479, vec![h1, h2], false)
#[test]
fn calc_bin_probability() {
let ds = create_test_ds();
let F = vec![1.0; ds.num_bins] ;
let expected = vec!(0.0, 0.0825296687031316, 40.92355847097493,
124226.70003377, 2308526035.5283747);
for b in 0..ds.num_bins {
let p = super::calc_bin_probability(b, &ds, &F);
assert_delta!(expected[b], p, 0.0000001);
}
}
fn assert_near(a: f64, b: f64, tolerance: f64) {
let d = (a-b).abs();
assert!(d <= tolerance, "Values are not close: {}, {}, d={}", &a, &b, &d);
}
#[test]
#[test]
fn calc_bias_offset() {
let ds = create_test_ds();
let probability = vec!(0.959, 0.331, 0.656, 46.750);
let expected = vec!(0.786289183, 1.10629119);
let probability = vec!(0.0, 0.1, 0.2, 0.3, 0.4);
let expected = vec!(15.927477169990633, 15.927477169990633);
for window in 0..ds.num_windows {
let F = super::calc_window_F(window, &ds, &probability);
assert_delta!(expected[window], F, 0.0000001);
@@ -279,39 +295,20 @@ mod tests {
}
#[test]
#[ignore] // TODO
fn calc_bin_probability() {
let ds = create_test_ds();
let F = vec!(0.0, 0.0);
let expected = vec!(0.959, 0.331, 0.656, 46.750);
for b in 0..4 {
let p = super::calc_bin_probability(b, &ds, &F);
assert_near(expected[b], p, 0.001);
}
let F = vec!(1.0, 1.0);
let expected = vec!(0.641, 0.221, 0.439, 31.232);
for b in 0..4 {
let p = super::calc_bin_probability(b, &ds, &F);
assert_near(expected[b], p, 0.001);
}
}
#[test]
#[ignore] // TODO
fn perform_wham_iteration() {
let ds = create_test_ds();
let prev_F = vec![0.0; ds.num_windows];
let mut F = vec![0.0; ds.num_windows];
let prev_F = vec![1.0; ds.num_windows];
let mut F = vec![f64::NAN; ds.num_windows];
let mut P = vec![f64::NAN; ds.num_bins];
super::perform_wham_iteration(&ds, &prev_F, &mut F, &mut P);
let expected_F = vec!(0.5948, -0.2513);
let expected_P = vec!(0.959, 0.331, 0.656, 46.750);
let expected_F = vec!(1.0, 1.0);
let expected_P = vec!(0.0, 0.0825296687031316, 40.92355847097493,
124226.70003377, 2308526035.5283747);
for bin in 0..ds.num_bins {
assert_near(expected_P[bin], P[bin], 0.01)
assert_delta!(expected_P[bin], P[bin], 0.01)
}
for window in 0..ds.num_windows {
assert_near(expected_F[window], F[window], 0.01)
assert_delta!(expected_F[window], F[window], 0.01)
}
}