function [p,y,nfunk] = amoeba(funk, p, y, ndim, ftol, NMAX) %function [p,y,nfunk] = amoeba(funk, p, y, ndim, ftol, NMAX) % % funk - the name of the function that you want to minimize % p - the N+1-by-N matrix, row stands for the vertices, column stands for % the variables % y - the function values of N+1 vertices % ndim - the number of variables % ftol - functional convergence tolerance % NMAX - the maximum number of function evaluations % % OUTPUT % p,y has the same meaning % nfunk - the number of function evaluations % nfunk = 0; TINY = 1e-20; mpts = ndim + 1; psum = sum(p,1); while (1==1) ilo = 1; if y(1)>y(2) inhi = 2; ihi = 1; else inhi = 1; ihi = 2; end for i=1:mpts if (y(i) <= y(ilo)) ilo = i; end if (y(i) > y(ihi)) inhi = ihi; ihi = i; elseif (y(i) > y(inhi)) && (i ~= ihi) inhi = i; end end rtol = 2.0 * abs(y(ihi)-y(ilo))/(abs(y(ihi)) + abs(y(ilo))+TINY); if (rtol < eps) [y(1),y(ilo)] = swap(y(1),y(ilo)); [p(1,:),p(ilo,:)] = swap(p(1,:),p(ilo,:)); break; end if (nfunk >= NMAX) break; end nfunk = nfunk + 2; [ytry, p, y, psum] = amotry(funk,p,y,psum,ndim,ihi,-1.0); if (ytry <= y(ilo)) [ytry, p, y, psum] = amotry(funk,p,y,psum,ndim,ihi,2.0); elseif (ytry >= y(inhi)) ysave=y(ihi); [ytry, p, y, psum] = amotry(funk,p,y,psum,ndim,ihi,0.5); if (ytry >= ysave) for i=1:mpts if (i ~= ilo) psum=0.5*(p(i,:) + p(ilo,:)); p(i,:)=psum; y(i)=feval(@funk,psum); end end nfunk = nfunk + ndim; psum = sum(p,1); end else nfunk = nfunk - 2; end end function [ytry, p, y, psum] = amotry(funk, p, y, psum, ndim,ihi, fac) fac1 = (1.0-fac) / ndim; fac2 = fac1 - fac; ptry = psum .* fac1 - p(ihi,:) .* fac2; ytry = feval(funk,ptry); if (ytry < y(ihi)) y(ihi) = ytry; psum = psum + ptry - p(ihi,:); p(ihi,1:ndim)= ptry; end function [a,b]=swap(a,b) swapv=a; a=b; b=swapv;
for i=1:MP for j=1:NP if i == j+1 p(i,j) = 1.0; else p(i,j) = 0.0; end x(j)=p(i,j); end y(i)=func(x); end disp(sprintf('%3s %10s %12s %12s %14s\n\n','i','x[i]','y[i]','z[i]','function')); for i=1:MP ss1 = [sprintf('%3d ',i)]; for j=1:NP ss1 = [ss1 sprintf('%12.6f ',p(i,j))]; end ss1 = [ss1 sprintf('%12.6f\n',y(i))]; disp(ss1); end [p,y,nfunc] = amoeba(@func,p,y,ndim,eps,1000); disp(sprintf('\nNumber of function evaluations: %3d\n',nfunc)); disp(sprintf('Vertices of final 3-d simplex and\n')); disp(sprintf('function values at the vertices:\n\n')); disp(sprintf('%3s %10s %12s %12s %14s\n\n','i','x[i]','y[i]','z[i]','function')); for i=1:MP ss1 = [sprintf('%3d ',i)]; for j=1:NP ss1 = [ss1 sprintf('%12.6f ',p(i,j))]; end ss1 = [ss1 sprintf('%12.6f\n',y(i))]; disp(ss1); end disp(sprintf('\nTrue minimum is at (0.5,0.6,0.7)\n'));
function [res] = func(x) res = 0.6 - bessj0((x(1)-0.5)^2 + (x(2)-0.6)^2 + (x(3)-0.7)^2); function [ans] = bessj0(x) ax=abs(x); if (ax < 8.0) y=x*x; ans1=57568490574.0+y*(-13362590354.0+y*(651619640.7 ... +y*(-11214424.18+y*(77392.33017+y*(-184.9052456))))); ans2=57568490411.0+y*(1029532985.0+y*(9494680.718 ... +y*(59272.64853+y*(267.8532712+y*1.0)))); ans=ans1/ans2; else z=8.0/ax; y=z*z; xx=ax-0.785398164; ans1=1.0+y*(-0.1098628627e-2+y*(0.2734510407e-4 ... +y*(-0.2073370639e-5+y*0.2093887211e-6))); ans2 = -0.1562499995e-1+y*(0.1430488765e-3 ... +y*(-0.6911147651e-5+y*(0.7621095161e-6 ... -y*0.934935152e-7))); ans=sqrt(0.636619772/ax)*(cos(xx)*ans1-z*sin(xx)*ans2); end