📄 amoeba.c
字号:
#include <math.h>
#define NMAX 5000
#define ALPHA 1.0
#define BETA 0.5
#define GAMMA 2.0
#define GET_PSUM for (j=1;j<=ndim;j++) { for (i=1,sum=0.0;i<=mpts;i++)\
sum += p[i][j]; psum[j]=sum;}
void amoeba(p,y,ndim,ftol,funk,nfunk)
float **p,y[],ftol,(*funk)();
int ndim,*nfunk;
{
int i,j,ilo,ihi,inhi,mpts=ndim+1;
float ytry,ysave,sum,rtol,amotry(),*psum,*vector();
void nrerror(),free_vector();
psum=vector(1,ndim);
*nfunk=0;
GET_PSUM
for (;;) {
ilo=1;
ihi = y[1]>y[2] ? (inhi=2,1) : (inhi=1,2);
for (i=1;i<=mpts;i++) {
if (y[i] < y[ilo]) ilo=i;
if (y[i] > y[ihi]) {
inhi=ihi;
ihi=i;
} else if (y[i] > y[inhi])
if (i != ihi) inhi=i;
}
rtol=2.0*fabs(y[ihi]-y[ilo])/(fabs(y[ihi])+fabs(y[ilo]));
if (rtol < ftol) break;
if (*nfunk >= NMAX) nrerror("Too many iterations in AMOEBA");
ytry=amotry(p,y,psum,ndim,funk,ihi,nfunk,-ALPHA);
if (ytry <= y[ilo])
ytry=amotry(p,y,psum,ndim,funk,ihi,nfunk,GAMMA);
else if (ytry >= y[inhi]) {
ysave=y[ihi];
ytry=amotry(p,y,psum,ndim,funk,ihi,nfunk,BETA);
if (ytry >= ysave) {
for (i=1;i<=mpts;i++) {
if (i != ilo) {
for (j=1;j<=ndim;j++) {
psum[j]=0.5*(p[i][j]+p[ilo][j]);
p[i][j]=psum[j];
}
y[i]=(*funk)(psum);
}
}
*nfunk += ndim;
GET_PSUM
}
}
}
free_vector(psum,1,ndim);
}
float amotry(p,y,psum,ndim,funk,ihi,nfunk,fac)
float **p,*y,*psum,(*funk)(),fac;
int ndim,ihi,*nfunk;
{
int j;
float fac1,fac2,ytry,*ptry,*vector();
void nrerror(),free_vector();
ptry=vector(1,ndim);
fac1=(1.0-fac)/ndim;
fac2=fac1-fac;
for (j=1;j<=ndim;j++) ptry[j]=psum[j]*fac1-p[ihi][j]*fac2;
ytry=(*funk)(ptry);
++(*nfunk);
if (ytry < y[ihi]) {
y[ihi]=ytry;
for (j=1;j<=ndim;j++) {
psum[j] += ptry[j]-p[ihi][j];
p[ihi][j]=ptry[j];
}
}
free_vector(ptry,1,ndim);
return ytry;
}
#undef ALPHA
#undef BETA
#undef GAMMA
#undef NMAX
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -