Files
2025-02-Numerical/lib/nr/cpp/recipes/mnbrak.cpp
2025-09-12 18:55:25 +09:00

66 lines
1.1 KiB
C++

#include <cmath>
#include "nr.h"
using namespace std;
namespace {
inline void shft3(DP &a, DP &b, DP &c, const DP d)
{
a=b;
b=c;
c=d;
}
}
void NR::mnbrak(DP &ax, DP &bx, DP &cx, DP &fa, DP &fb, DP &fc,
DP func(const DP))
{
const DP GOLD=1.618034,GLIMIT=100.0,TINY=1.0e-20;
DP ulim,u,r,q,fu;
fa=func(ax);
fb=func(bx);
if (fb > fa) {
SWAP(ax,bx);
SWAP(fb,fa);
}
cx=bx+GOLD*(bx-ax);
fc=func(cx);
while (fb > fc) {
r=(bx-ax)*(fb-fc);
q=(bx-cx)*(fb-fa);
u=bx-((bx-cx)*q-(bx-ax)*r)/
(2.0*SIGN(MAX(fabs(q-r),TINY),q-r));
ulim=bx+GLIMIT*(cx-bx);
if ((bx-u)*(u-cx) > 0.0) {
fu=func(u);
if (fu < fc) {
ax=bx;
bx=u;
fa=fb;
fb=fu;
return;
} else if (fu > fb) {
cx=u;
fc=fu;
return;
}
u=cx+GOLD*(cx-bx);
fu=func(u);
} else if ((cx-u)*(u-ulim) > 0.0) {
fu=func(u);
if (fu < fc) {
shft3(bx,cx,u,cx+GOLD*(cx-bx));
shft3(fb,fc,fu,func(u));
}
} else if ((u-ulim)*(ulim-cx) >= 0.0) {
u=ulim;
fu=func(u);
} else {
u=cx+GOLD*(cx-bx);
fu=func(u);
}
shft3(ax,bx,cx,u);
shft3(fa,fb,fc,fu);
}
}