add numerical recipes library
This commit is contained in:
89
lib/nr/cpp/recipes/amebsa.cpp
Normal file
89
lib/nr/cpp/recipes/amebsa.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user