double nb_est_alpha ( tab_t *tab ) { // Find upper and lower bouds for a(lpha). double a = 1.0; double a_lo; double a_hi; if (eval_nb_f(a, tab) < 0) { a /= 2; while (eval_nb_f(a, tab) < 0) a /= 2; a_lo = a; a_hi = a*2; } else { a *= 2; while (eval_nb_f(a, tab) > 0) a *= 2; a_lo = a/2; a_hi = a; } // Input is pathological. if (a_lo > 128) return -1.0; double new_a = (a_lo + a_hi) / 2; for (int i = 0 ; i < ZINM_MAXITER ; i++) { a = (new_a < a_lo || new_a > a_hi) ? (a_lo + a_hi) / 2 : new_a; double f = eval_nb_f(a, tab); if (f < 0) a_hi = a; else a_lo = a; if ((a_hi - a_lo) < ZINM_TOL) break; double dfda = eval_nb_dfda(a, tab); new_a = a - f / dfda; } return a; }
void test_eval_nb_f (void) { // 0:14, 1:5, 2:4, 3:1, 5:1 int x[25] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,2,2,2,2,3,5 }; tab_t *tab = tabulate(x, 25); test_assert(fabs(eval_nb_f(1.0, tab)+0.12747262) < 1e-6); test_assert(fabs(eval_nb_f(1.1, tab)+0.24215981) < 1e-6); test_assert(fabs(eval_nb_f(1.2, tab)+0.31636395) < 1e-6); test_assert(fabs(eval_nb_f(1.3, tab)+0.36350700) < 1e-6); test_assert(fabs(eval_nb_f(1.4, tab)+0.39225466) < 1e-6); test_assert(fabs(eval_nb_f(1.5, tab)+0.40834322) < 1e-6); test_assert(fabs(eval_nb_f(2.0, tab)+0.39975512) < 1e-6); free(tab); return; }