aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPjotr Prins2021-08-25 11:52:28 +0200
committerPjotr Prins2021-08-25 11:52:28 +0200
commit58647bfbc8e1441c570bc6c5a4723ca39513f096 (patch)
tree8c9b20ba0a4f4d091d5c7fdfdce03b10597c62c2 /src
parentb0c7f0ed464b134d1fdf6acd050f122a5ca96801 (diff)
downloadpangemma-58647bfbc8e1441c570bc6c5a4723ca39513f096.tar.gz
Make sure P_yy=0 does not fail. Fix undefined iter in loop. Make sure there is cleanup on exit
Diffstat (limited to 'src')
-rw-r--r--src/lmm.cpp40
1 files changed, 22 insertions, 18 deletions
diff --git a/src/lmm.cpp b/src/lmm.cpp
index cc2bd33..7bc446d 100644
--- a/src/lmm.cpp
+++ b/src/lmm.cpp
@@ -846,7 +846,8 @@ double LogRL_f(double l, void *params) {
}
index_ww = GetabIndex(n_cvt + 2, n_cvt + 2, n_cvt);
double P_yy = gsl_matrix_safe_get(Pab, nc_total, index_ww);
- // if (P_yy > 0.0 && P_yy < 0.00000001) P_yy = 0.00000001; // control potential round-off
+ // P_yy is positive and may get zeroed printf("P_yy=%f",P_yy);
+ if (P_yy == 0.0) P_yy = 0.00000001; // control potential round-off
double c = 0.5 * df * (safe_log(df) - safe_log(2 * M_PI) - 1.0);
f = c - 0.5 * logdet_h - 0.5 * logdet_hiw - 0.5 * df * safe_log(P_yy);
@@ -1938,6 +1939,10 @@ void MatrixCalcLR(const gsl_matrix *U, const gsl_matrix *UtX,
void CalcLambda(const char func_name, FUNC_PARAM &params, const double l_min,
const double l_max, const size_t n_region, double &lambda,
double &logf) {
+ // wipe return values
+ logf = nan("NAN");
+ lambda = nan("NAN");
+
if (func_name != 'R' && func_name != 'L' && func_name != 'r' &&
func_name != 'l') {
cout << "func_name only takes 'R' or 'L': 'R' for "
@@ -2013,25 +2018,21 @@ void CalcLambda(const char func_name, FUNC_PARAM &params, const double l_min,
FDF.fdf = &LogL_dev12;
}
- const gsl_root_fsolver_type *T_f;
- gsl_root_fsolver *s_f;
- T_f = gsl_root_fsolver_brent;
- s_f = gsl_root_fsolver_alloc(T_f);
-
- const gsl_root_fdfsolver_type *T_fdf;
- gsl_root_fdfsolver *s_fdf;
- T_fdf = gsl_root_fdfsolver_newton;
- s_fdf = gsl_root_fdfsolver_alloc(T_fdf);
+ const gsl_root_fsolver_type *T_f = gsl_root_fsolver_brent;
+ const gsl_root_fsolver *s_f = gsl_root_fsolver_alloc(T_f);
+ const gsl_root_fdfsolver_type *T_fdf = gsl_root_fdfsolver_newton;
+ const gsl_root_fdfsolver *s_fdf = gsl_root_fdfsolver_alloc(T_fdf);
for (vector<double>::size_type i = 0; i < lambda_lh.size(); ++i) {
lambda_l = lambda_lh[i].first;
lambda_h = lambda_lh[i].second;
- gsl_root_fsolver_set(s_f, &F, lambda_l, lambda_h);
+ gsl_root_fsolver_set((gsl_root_fsolver*)s_f, &F, lambda_l, lambda_h);
auto handler = gsl_set_error_handler_off();
+ iter = 0;
do {
iter++;
- status = gsl_root_fsolver_iterate(s_f);
+ status = gsl_root_fsolver_iterate((gsl_root_fsolver*)s_f);
if (status != GSL_SUCCESS && status != GSL_CONTINUE) {
warning_msg("Brent did not converge");
break;
@@ -2047,23 +2048,24 @@ void CalcLambda(const char func_name, FUNC_PARAM &params, const double l_min,
} while (status == GSL_CONTINUE && iter < max_iter);
iter = 0;
-
- gsl_root_fdfsolver_set(s_fdf, &FDF, l);
+ gsl_root_fdfsolver_set((gsl_root_fdfsolver*)s_fdf, &FDF, l);
do {
iter++;
- status = gsl_root_fdfsolver_iterate(s_fdf);
+ status = gsl_root_fdfsolver_iterate((gsl_root_fdfsolver*)s_fdf);
if (status != GSL_SUCCESS && status != GSL_CONTINUE) {
debug_msg("Newton did not converge");
break;
}
l_temp = l;
- l = gsl_root_fdfsolver_root(s_fdf);
+ l = gsl_root_fdfsolver_root((gsl_root_fdfsolver*)s_fdf);
status = gsl_root_test_delta(l, l_temp, 0, 1e-5);
if (status != GSL_SUCCESS && status != GSL_CONTINUE) {
debug_msg("Newton did not converge");
break;
}
} while (status == GSL_CONTINUE && iter < max_iter && l > l_min && l < l_max);
+
+ // cleanup
gsl_set_error_handler(handler);
if (status == GSL_CONTINUE) {
@@ -2074,6 +2076,8 @@ void CalcLambda(const char func_name, FUNC_PARAM &params, const double l_min,
// make sure results are invalid
logf = nan("NAN");
lambda = nan("NAN");
+ gsl_root_fsolver_free((gsl_root_fsolver*)s_f);
+ gsl_root_fdfsolver_free((gsl_root_fdfsolver*)s_fdf);
return;
}
@@ -2099,8 +2103,8 @@ void CalcLambda(const char func_name, FUNC_PARAM &params, const double l_min,
} else {
}
}
- gsl_root_fsolver_free(s_f);
- gsl_root_fdfsolver_free(s_fdf);
+ gsl_root_fsolver_free((gsl_root_fsolver*)s_f);
+ gsl_root_fdfsolver_free((gsl_root_fdfsolver*)s_fdf);
if (func_name == 'R' || func_name == 'r') {
logf_l = LogRL_f(l_min, &params);