14 int Brent(
double (*Func)(
double,
void *),
void *param,
double x1,
15 double x2,
double abs_acc,
double rel_acc,
double *xroot)
40 double a=x1,b=x2,
c=x2,d,e,min1,min2;
41 double fa,fb,fc,p,
q,r,
s,tol1,xm;
43 fa = (*Func)(
a, param);
44 fb = (*Func)(b, param);
46 if ((fa > 0.0 && fb > 0.0) || (fa < 0.0 && fb < 0.0)){
48 if(
g_stepNumber > 0)
print (
"! Brent: initial interval does not contain root.\n");
53 for (iter=1; iter<=
MAX_ITER; iter++) {
54 if ((fb > 0.0 && fc > 0.0) || (fb < 0.0 && fc < 0.0)) {
59 if (fabs(fc) < fabs(fb)) {
68 tol1 = 2.0*2.0e-16*fabs(b);
70 tol1 = 2.0*2.0e-16*fabs(b) + 0.5*abs_acc;
75 if (fabs(xm) <= 0.5*abs_acc || fabs(xm) <= 0.5*rel_acc*fabs(b) ||
81 if (fabs(e) >= tol1 && fabs(fa) > fabs(fb)) {
89 p = s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0));
90 q = (q-1.0)*(r-1.0)*(s-1.0);
94 min1 = 3.0*xm*q-fabs(tol1*q);
96 if (2.0*p < (min1 < min2 ? min1 : min2)) {
109 if (fabs(d) > tol1) b += d;
110 else b +=
DSIGN(xm)*fabs(tol1);
111 fb=(*Func)(b, param);
114 print (
"! Brent: exceed maximum iterations.\n");
120 int Ridder(
double (*Func)(
double,
void *),
void *param,
121 double x1,
double x2,
double abs_acc,
double rel_acc,
150 double ans,fh,fl,fm,fnew,
s,xh,xl,xm,xnew;
153 fl = (*Func)(x1, param);
154 fh = (*Func)(x2, param);
156 if ((fl > 0.0 && fh < 0.0) || (fl < 0.0 && fh > 0.0)) {
163 fm = (*Func)(xm, param);
164 s = sqrt(fm*fm - fl*fh);
170 xnew = xm + (xm-xl)*((fl >= fh ? 1.0 : -1.0)*fm/
s);
171 delta = fabs(xnew-ans);
172 if (delta <= abs_acc || delta <= rel_acc*fabs(xnew)) {
178 fnew = (*Func)(ans, param);
189 }
else if (fl*fnew < 0.0) {
192 }
else if (fh*fnew < 0.0) {
196 print (
"! Ridder: never get here.\n");
197 print (
"! xl = %12.6e, fl = %12.6e\n",xl,fl);
198 print (
"! xh = %12.6e, fh = %12.6e\n",xh,fh);
199 print (
"! xm = %12.6e, fm = %12.6e\n",xm,fm);
200 print (
"! xnew = %12.6e, fnew = %12.6e\n",xnew,fnew);
201 print (
"! sqrt^2 = %12.6e\n",fm*fm - fl*fh);
206 if (delta <= abs_acc || delta <= rel_acc*fabs(xh)) {
213 print (
"! Ridder: exceed maximum iterations.\n");
240 void (*vecfunc)(
int ,
double [] ,
double [])){
258 for(i=0;i<
n;i++) df[i][j] = (f[i]-fv[i])/h;
263 void LineSearch (
int n,
double xold[],
double fold,
double g[],
264 double p[],
double x[],
double mf[],
double *f,
double stpmax,
265 int *
check,
void (*vecfunc)(
int ,
double [] ,
double [])){
271 double a, alam, alam2, alamin, b, disc, f2, rhs1;
272 double rhs2, slope, sum, temp, test, tmplam;
276 for(i=0;i<
n;i++) sum += p[i]*p[i];
279 for(i=0;i<
n;i++) p[i] *= stpmax/sum;
282 for(i=0;i<
n;i++) slope += g[i]*p[i];
285 print(
"! LineSearch: Roundoff problem in lnscrh\n");
291 temp = fabs(p[i])/
MAX(fabs(xold[i]), 1.0);
292 if (temp > test) test = temp;
298 for(i=0;i<
n;i++) x[i] = xold[i] + alam*p[i];
299 (*vecfunc)(
n, x, mf);
302 sum += mf[
i] * mf[
i];
306 for(i=0;i<
n;i++) x[i] = xold[i];
309 }
else if(*f < fold +
ALF*alam*slope)
return;
312 tmplam = -slope/(2.0*(*f-fold-slope));
314 rhs1 = *f - fold - alam*slope;
315 rhs2 = f2 - fold - alam2*slope;
316 a = (rhs1/(alam*alam) - rhs2/(alam2*alam2))/(alam - alam2);
317 b = (-alam2*rhs1/(alam*alam) + alam*rhs2/(alam2*alam2))/(alam - alam2);
318 if (a == 0.0) tmplam = -slope/(2.0*b);
320 disc = b*b - 3.0*a*slope;
321 if (disc < 0.0) tmplam = 0.5*alam;
322 else if (b <= 0.0) tmplam = (-b + sqrt(disc))/(3.0*a);
323 else tmplam = -slope/(b + sqrt(disc));
325 if (tmplam > 0.5*alam) tmplam = 0.5*alam;
330 alam =
MAX(tmplam, 0.1*alam);
336 void (*vecfunc)(
int,
double [],
double []))
342 int i, its,
j,
k, restrt, sing, skip;
343 double den, f, fold, stpmax, sum, temp, test;
344 static double *
c, *d, *fvcold, *g, *p, **qt, **r, *
s, *t, *w, *xold, *fguess;
349 print1 (
"! Broyden : Number of equations exceed the maximum limit\n");
367 (*vecfunc)(
n, x, fguess);
370 sum += fguess[
i] * fguess[
i];
378 if (fabs(fguess[i]) > test) test = fabs(fguess[i]);
379 if (test < 0.01*
TOLF) {
386 for (i=0;i<
n;i++) sum += x[i] * x[i];
387 stpmax =
STPMX*
MAX(sqrt(sum), (
double)n);
391 for(its = 1; its <=
MAXITS; its++){
397 print (
"! Broyden: singular Jacobian... Hard Luck !\n");
403 for(j=0;j<
n;j++) qt[i][j] = 0.0;
408 for(k=0; k < n-1; k++) {
410 for (j=0; j<
n; j++) {
413 sum += r[
i][
k]*qt[
i][
j];
417 qt[
i][
j] -= sum*r[
i][
k];
426 for (j=0;j<
i;j++) r[i][j] = 0.0;
431 for(i=0; i<
n; i++) s[i] = x[i] - xold[i];
434 for(j=i; j<
n; j++) sum += r[i][j] * s[j];
440 for(j=0; j<
n; j++) sum += qt[j][i] * t[j];
441 w[
i] = fguess[
i] - fvcold[
i] - sum;
442 if (fabs(w[i]) >=
EPS_FD_JAC*(fabs(fguess[i]) + fabs(fvcold[i]))) skip = 0;
450 for(j=0;j<
n;j++) sum += qt[i][j]*w[j];
455 for(i=0; i<
n;i++) den += s[i] * s[i];
456 for(i=0; i<
n;i++) s[i] /= den;
462 print (
"! Broyden: R is singular .. Hard Luck ! \n");
473 for(j=0; j<
n; j++) sum += qt[i][j] * fguess[j];
479 for(j=0; j<=
i; j++) sum += r[j][i] * g[j];
486 fvcold[
i] = fguess[
i];
492 for(j=0; j<
n; j++) sum += qt[i][j] * fguess[j];
501 LineSearch (n, xold, fold, g, p, x, fguess, &f, stpmax, check, vecfunc);
506 if (fabs(fguess[i]) > test) test = fabs(fguess[i]);
515 print(
"! Broyden: Already tried reinitializing \n");
521 temp = fabs(g[i]) *
MAX(fabs(x[i]), 1.0)/den;
522 if (temp > test) test = temp;
524 if (test <
TOLMIN)
return;
531 temp = (fabs(x[i] - xold[i])) /
MAX(fabs(x[i]), 1.0);
532 if (temp > test) test = temp;
535 print(
"! Brodyen: All is Well !! \n");
540 print(
"! Brodyen: MAXITS exceeded in Broyden\n");
void QRDecompose(double **a, int n, double *c, double *d, int *sing)
int g_maxRootIter
Maximum number of iterations for root finder.
void FDJacobian(int n, double x[], double fv[], double **df, void(*vecfunc)(int, double[], double[]))
void LineSearch(int n, double xold[], double fold, double g[], double p[], double x[], double mf[], double *f, double stpmax, int *check, void(*vecfunc)(int, double[], double[]))
void print1(const char *fmt,...)
void QRUpdate(double **r, double **qt, int n, double *u, double *v)
int Brent(double(*Func)(double, void *), void *param, double x1, double x2, double abs_acc, double rel_acc, double *xroot)
long int g_stepNumber
Gives the current integration step number.
void RSolve(double **a, int n, double *d, double *b)
void print(const char *fmt,...)
void Broyden(double x[], int n, int *check, void(*vecfunc)(int, double[], double[]))
#define ARRAY_1D(nx, type)
int Ridder(double(*Func)(double, void *), void *param, double x1, double x2, double abs_acc, double rel_acc, double *xroot)
#define ARRAY_2D(nx, ny, type)
#define QUIT_PLUTO(e_code)