how to find minima of a 3d surface using Nelder-Mead?
Mostra commenti meno recenti
I have function to generate a response surface function of the RMSError of a model. I need to then use the Nelder-Mead (Downhill Simplex) method to find the global minima. I can't figure out how to connect the two pieces (the response surface function and the Nelder-Mead code).
My first problem is calculating the centroid in line 27 of the Nelder-Mead code.
Any help would be appreciated, especially with explicit suggestions. I see what I need to do but not how.
Code is below, data is attached.
Code for RMSE Response Surface Function:
function [err_rmse] = RMSERespSurf(TimeDay, Precipmmday)
SynthK=0.1;
SynthSmax=20;
Baseflow = zeros(size(TimeDay));
Storage = zeros(size(TimeDay));
for nt = 2:length(Precipmmday)
Baseflow (nt) = (Storage(nt)+Precipmmday(nt))*SynthK;
Storage(nt) = (Storage(nt-1)+Precipmmday(nt-1))*(1-SynthK);
end
SynthStorage = Storage;
% SynthStorage (:,1) =[];
SynthSpill=SynthStorage - SynthSmax;
SynthSpill(SynthSpill<0)=0;
SynthStorage(SynthStorage>SynthSmax)=SynthSmax;
SynthBaseflow = Baseflow;
SynthOutflow = SynthBaseflow + SynthSpill;
% temp model variables
ModelBaseflow = zeros(size(TimeDay));
ModelStorage = zeros(size(TimeDay));
ModelSpill = zeros(size(TimeDay));
% grid is the resolution of parameter space (grid x grid)
grid = 100;
% preallocate space for error calcs
err_rmse = zeros(grid);
% define parameters
Smax = linspace(10,100,grid);
K = linspace(0.05,0.5,grid);
% loop for Smax
for ns = 1:length(Smax)
% loop for K
for nk = 1:length(K)
% loop for timeseries (k1)
for nt = 2:length(TimeDay)
% calculate recursive time series
ModelBaseflow(nt) = (ModelStorage(nt-1)+Precipmmday(nt-1))*K(nk);
ModelStorage(nt) = (ModelStorage(nt-1)+Precipmmday(nt-1))*(1-K(nk));
end
% calculate secondary variables (not recursive, but depend on
% baseflow and storage)
ModelSpill = ModelStorage - Smax(ns);
ModelSpill(ModelSpill<0)=0;
ModelStorage(ModelStorage>Smax(ns)) = Smax(ns);
ModelOutflow = ModelBaseflow + ModelSpill;
% calculate errors
Difference = ModelOutflow-SynthOutflow;
err_rmse(ns,nk) = rms(Difference);
end
end
surf(Smax, K, err_rmse);
ylabel('k')
xlabel('Smax')
zlabel('err_rmse')
Code for Nelder-Mead:
function [Minima]=Nelder_Mead_MultiDimMatrixForm(RMSERespSurf)
clc;
StdVal=10; %any value for convergence
n=3; %value of N+1
P=1; %reflection coefficient
Chi=2; %expansion coefficient
Gamma=0.5; %contraction coefficient
Sig=0.5; %shrink coefficient
SortVertices = CreateInitialSimplex(n);
tic;
i=1;
minmas=0;
while(StdVal >= 0.00001)
SortVertices = BubbleSort(SortVertices,n);
Centroid = CalculateCentroid(SortVertices,n);
StdVal = CalculateStd(SortVertices,n);
minmas(i)=SortVertices(1).value; i=i+1;
% Simplex_2D(SortVertices); drawnow;
Reflect.coord = (1+P).*Centroid.coord - P.*SortVertices(n).coord; %Reflect
Reflect.value = RMSERespSurf(Reflect);
if(SortVertices(1).value <= Reflect.value && Reflect.value < SortVertices(n-1).value)
SortVertices(n)=Reflect;
continue; %if the above criterion is sattisfied, then terminate the iteration
end
if(Reflect.value < SortVertices(1).value) %Expand
Expand.coord = (1-Chi).*Centroid.coord+Chi.*Reflect.coord;
Expand.value = RMSERespSurf(Expand);
if(Expand.value < Reflect.value)
SortVertices(n) = Expand;
continue;
else
SortVertices(n) = Reflect;
continue;
end
end
if(SortVertices(n-1).value <= Reflect.value) %Contract
ContractOut.coord = (1-Gamma).*Centroid.coord + Gamma.*Reflect.coord; %Contract Outside
ContractOut.value = RMSERespSurf(ContractOut);
ContractIn.coord = (1-Gamma).*Centroid.coord + Gamma.*SortVertices(n).coord; %Contract Inside
ContractIn.value= RMSERespSurf(ContractIn);
if(SortVertices(n-1).value <= Reflect.value && Reflect.value < SortVertices(n).value && ContractOut.value <= Reflect.value)
SortVertices(n) = ContractOut;
continue;
elseif(SortVertices(n).value <= Reflect.value && ContractIn.value < SortVertices(n).value) %Contract Inside
SortVertices(n) = ContractIn;
continue;
else
for i=2:n
SortVertices(i).coord = (1-Sig).*SortVertices(1).coord + Sig.*SortVertices(i).coord;
SortVertices(i).value = RMSERespSurf(SortVertices(i));
end
end
end
end
toc
Minima=SortVertices(1);
% plot(minmas);
% a=text(50,250, strcat('No: of iterations = ', num2str(i)));
% set(a, 'FontName', 'Arial', 'FontWeight', 'bold', 'FontSize', 18, 'Color', 'red');
% xlabel('iterations');
% ylabel('error');
% title('Error Vs Iterations');
end
function [value]= RMSERespSurf(V) %Write your function in matrix form
%in case of any of the three trial functions un comment two lines
x=V.coord(1); y=V.coord(2); %Rosenbrock's Function
value=(1-x)^2+100*(y-x^2)^2;
% x1=V.coord(1);x2=V.coord(2);x3=V.coord(3);x4=V.coord(4); %Powell's Quadratic Function
% value=(x1+10*x2)^2+5*(x3-x4)^2+(x2-2*x3)^4+10*(x1-x4)^4;
% x1=V.coord(1); x2=V.coord(2); x3=V.coord(3); %Fletcher and Powell's Helical Valley Function
% theta=atan2(x1,x2);
% value=100*(x3-10*theta)^2+(sqrt(x1^2+x2^2)-1)^2+x3^2;
% value=([1,-1;0,1]*V.coord-[4;1])'*V.coord; %f(x,y)=x^2-4*x+y^2-y-x*y;
% value=([1,0,-1;0,1,0;1,0,1]*V.coord-[3;10;-7])'*V.coord; %f(x,y,z)=x^2+y^2+z^2-3*x-10*y+7
end
function [Vertices]=CreateInitialSimplex(n)
ExpectMin=rand((n-1),1).*50;
Vertices(1).coord=ExpectMin; % expected minima
Vertices(1).value=RMSERespSurf(Vertices(1));
for i=2:n
Vertices(i).coord=ExpectMin+50.*rand((n-1),1); %100 is the scale factor
Vertices(i).value=RMSERespSurf(Vertices(i));
end
end
function [SortVertices]=BubbleSort(Vertices,n)
while(n~=0)
for i=1:n-1
if(Vertices(i).value<=Vertices(i+1).value)
continue;
else
temp=Vertices(i);
Vertices(i)=Vertices(i+1);
Vertices(i+1)=temp;
end
end
n=n-1;
end
SortVertices=Vertices;
end
function [Centroid]=CalculateCentroid(Vertices,n)
Sum=zeros((n-1),1);
for i=1:n-1
Sum=Sum+Vertices(i).coord;
end
Centroid.coord=Sum./(n-1);
Centroid.value=f(Centroid);
end
function[StdVal]=CalculateStd(Vertices,n) % this is the tolerance value, the standard deviation of the converging values
for i=1:n
ValueArray(i)=Vertices(i).value;
end
StdVal=std(ValueArray,1);
end
2 Commenti
Star Strider
il 26 Ott 2014
You can actually save yourself a significant amount of work, unless you are supposed to program your own Nelder-Mead routine.
Vert
il 26 Ott 2014
Risposta accettata
Più risposte (0)
Categorie
Scopri di più su Speed and Area Optimization in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!