21 #define TOL_CONV 1.0E-5
26 static void print_funcEval(FILE* fp,
double xval,
double fval,
int its)
29 fprintf(fp,
"...............................................................\n");
30 fprintf(fp,
".................. vcs_root1d Function Evaluation .............\n");
31 fprintf(fp,
".................. iteration = %5d ........................\n", its);
32 fprintf(fp,
".................. value = %12.5g ......................\n", xval);
33 fprintf(fp,
".................. funct = %12.5g ......................\n", fval);
34 fprintf(fp,
"...............................................................\n");
119 int vcsUtil_root1d(
double xmin,
double xmax,
size_t itmax,
120 VCS_FUNC_PTR func,
void* fptrPassthrough,
121 double FuncTargVal,
int varID,
122 double* xbest,
int printLvl)
124 static int callNum = 0;
125 const char* stre =
"vcs_root1d ERROR: ";
126 const char* strw =
"vcs_root1d WARNING: ";
127 bool converged =
false;
133 double x1, x2, xnew, f1, f2, fnew, slope;
137 bool foundPosF =
false;
138 bool foundNegF =
false;
139 bool foundStraddle =
false;
144 double c[9], f[3], xn1, xn2, x0 = 0.0, f0 = 0.0, root, theta, xquad;
149 sprintf(fileName,
"rootfd_%d.log", callNum);
150 fp = fopen(fileName,
"w");
151 fprintf(fp,
" Iter TP_its xval Func_val | Reasoning\n");
152 fprintf(fp,
"-----------------------------------------------------"
153 "-------------------------------\n");
157 plogf(
"WARNING: vcsUtil_root1d: printlvl >= 3, but debug mode not turned on\n");
161 plogf(
"%sxmin and xmax are bad: %g %g\n", stre, xmin, xmax);
165 if (x1 < xmin || x1 > xmax) {
166 x1 = (xmin + xmax) / 2.0;
168 f1 = func(x1, FuncTargVal, varID, fptrPassthrough, &err);
171 print_funcEval(fp, x1, f1, its);
172 fprintf(fp,
"%-5d %-5d %-15.5E %-15.5E\n", -2, 0, x1, f1);
178 }
else if (f1 > 0.0) {
187 x2 = x1 - (xmax - xmin) / 100.;
189 f2 = func(x2, FuncTargVal, varID, fptrPassthrough, &err);
192 print_funcEval(fp, x2, f2, its);
193 fprintf(fp,
"%-5d %-5d %-15.5E %-15.5E", -1, 0, x2, f2);
197 if (FuncTargVal != 0.0) {
198 fnorm = fabs(FuncTargVal) + 1.0E-13;
200 fnorm = 0.5*(fabs(f1) + fabs(f2)) + fabs(FuncTargVal);
205 }
else if (f2 > 0.0) {
216 foundStraddle = foundPosF && foundNegF;
230 slope = (f2 - f1) / (x2 - x1);
232 plogf(
"%s functions evals produced the same result, %g, at %g and %g\n",
234 xnew = 2*x2 - x1 + 1.0E-3;
236 xnew = x2 - f2 / slope;
240 fprintf(fp,
" | xlin = %-9.4g", xnew);
262 retn = vcsUtil_mlequ(c, 3, 3, f, 1);
266 root = f[1]* f[1] - 4.0 * f[0] * f[2];
268 xn1 = (- f[1] + sqrt(root)) / (2.0 * f[2]);
269 xn2 = (- f[1] - sqrt(root)) / (2.0 * f[2]);
270 if (fabs(xn2 - x2) < fabs(xn1 - x2) && xn2 > 0.0) {
275 theta = fabs(xquad - xnew) / fabs(xnew - x2);
277 xnew = theta * xnew + (1.0 - theta) * xquad;
281 fprintf(fp,
" | xquad = %-9.4g", xnew);
290 if ((DSIGN(xnew - x2) == DSIGN(x2 - x1)) &&
291 (DSIGN(x2 - x1) == DSIGN(x1 - x0))) {
295 fprintf(fp,
" | xquada = %-9.4g", xnew);
309 if ((xnew > x1 && xnew < x2) || (xnew < x1 && xnew > x2)) {
316 slope = fabs(x2 - x1) / 10.;
317 if (fabs(xnew - x1) < slope) {
318 xnew = x1 + DSIGN(xnew-x1) * slope;
321 fprintf(fp,
" | x10%% = %-9.4g", xnew);
325 if (fabs(xnew - x2) < slope) {
326 xnew = x2 + DSIGN(xnew-x2) * slope;
329 fprintf(fp,
" | x10%% = %-9.4g", xnew);
338 slope = 2.0 * fabs(x2 - x1);
339 if (fabs(slope) < fabs(xnew - x2)) {
340 xnew = x2 + DSIGN(xnew-x2) * slope;
343 fprintf(fp,
" | xlimitsize = %-9.4g", xnew);
351 xnew = x2 + (xmax - x2) / 2.0;
354 fprintf(fp,
" | xlimitmax = %-9.4g", xnew);
359 xnew = x2 + (x2 - xmin) / 2.0;
362 fprintf(fp,
" | xlimitmin = %-9.4g", xnew);
373 xnew = (xNegF + x2)/2;
376 xnew = (xNegF + x2)/2;
380 xnew = (xPosF + x2)/2;
383 xnew = (xPosF + x2)/2;
389 xnew = (xNegF + x2)/2;
392 xnew = (xNegF + x2)/2;
396 xnew = (xPosF + x2)/2;
399 xnew = (xPosF + x2)/2;
406 fprintf(fp,
" | xstraddle = %-9.4g", xnew);
412 fnew = func(xnew, FuncTargVal, varID, fptrPassthrough, &err);
416 print_funcEval(fp, xnew, fnew, its);
417 fprintf(fp,
"%-5d %-5d %-15.5E %-15.5E", its, 0, xnew, fnew);
445 if (! foundStraddle) {
450 foundStraddle =
true;
451 posStraddle = (xPosF > xNegF);
457 foundStraddle =
true;
458 posStraddle = (xPosF > xNegF);
469 if (fabs(fnew / fnorm) < 1.0E-5) {
473 }
while (! converged && its < itmax);
476 plogf(
"vcs_root1d success: convergence achieved\n");
480 fprintf(fp,
" | vcs_root1d success in %d its, fnorm = %g\n", its, fnorm);
484 retn = VCS_FAILED_CONVERGENCE;
486 plogf(
"vcs_root1d ERROR: maximum iterations exceeded without convergence\n");
490 fprintf(fp,
"\nvcs_root1d failure in %d its\n", its);