90 lines
1.6 KiB
C++
90 lines
1.6 KiB
C++
#include <cmath>
|
|
#include "nr.h"
|
|
using namespace std;
|
|
|
|
namespace {
|
|
inline void get_psum(Mat_I_DP &p, Vec_O_DP &psum)
|
|
{
|
|
int n,m;
|
|
DP sum;
|
|
|
|
int mpts=p.nrows();
|
|
int ndim=p.ncols();
|
|
for (n=0;n<ndim;n++) {
|
|
for (sum=0.0,m=0;m<mpts;m++) sum += p[m][n];
|
|
psum[n]=sum;
|
|
}
|
|
}
|
|
}
|
|
|
|
extern int idum;
|
|
DP tt;
|
|
|
|
void NR::amebsa(Mat_IO_DP &p, Vec_IO_DP &y, Vec_O_DP &pb, DP &yb, const DP ftol,
|
|
DP funk(Vec_I_DP &), int &iter, const DP temptr)
|
|
{
|
|
int i,ihi,ilo,j,n;
|
|
DP rtol,yhi,ylo,ynhi,ysave,yt,ytry;
|
|
|
|
int mpts=p.nrows();
|
|
int ndim=p.ncols();
|
|
Vec_DP psum(ndim);
|
|
tt = -temptr;
|
|
get_psum(p,psum);
|
|
for (;;) {
|
|
ilo=0;
|
|
ihi=1;
|
|
ynhi=ylo=y[0]+tt*log(ran1(idum));
|
|
yhi=y[1]+tt*log(ran1(idum));
|
|
if (ylo > yhi) {
|
|
ihi=0;
|
|
ilo=1;
|
|
ynhi=yhi;
|
|
yhi=ylo;
|
|
ylo=ynhi;
|
|
}
|
|
for (i=3;i<=mpts;i++) {
|
|
yt=y[i-1]+tt*log(ran1(idum));
|
|
if (yt <= ylo) {
|
|
ilo=i-1;
|
|
ylo=yt;
|
|
}
|
|
if (yt > yhi) {
|
|
ynhi=yhi;
|
|
ihi=i-1;
|
|
yhi=yt;
|
|
} else if (yt > ynhi) {
|
|
ynhi=yt;
|
|
}
|
|
}
|
|
rtol=2.0*fabs(yhi-ylo)/(fabs(yhi)+fabs(ylo));
|
|
if (rtol < ftol || iter < 0) {
|
|
SWAP(y[0],y[ilo]);
|
|
for (n=0;n<ndim;n++)
|
|
SWAP(p[0][n],p[ilo][n]);
|
|
break;
|
|
}
|
|
iter -= 2;
|
|
ytry=amotsa(p,y,psum,pb,yb,funk,ihi,yhi,-1.0);
|
|
if (ytry <= ylo) {
|
|
ytry=amotsa(p,y,psum,pb,yb,funk,ihi,yhi,2.0);
|
|
} else if (ytry >= ynhi) {
|
|
ysave=yhi;
|
|
ytry=amotsa(p,y,psum,pb,yb,funk,ihi,yhi,0.5);
|
|
if (ytry >= ysave) {
|
|
for (i=0;i<mpts;i++) {
|
|
if (i != ilo) {
|
|
for (j=0;j<ndim;j++) {
|
|
psum[j]=0.5*(p[i][j]+p[ilo][j]);
|
|
p[i][j]=psum[j];
|
|
}
|
|
y[i]=funk(psum);
|
|
}
|
|
}
|
|
iter -= ndim;
|
|
get_psum(p,psum);
|
|
}
|
|
} else ++iter;
|
|
}
|
|
}
|