Optimization of a complex function using Powell's Method
5 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
I'm trying to optimize a function to get optimized initial values using powell's method. The function is complex.
I'm quite new to MATLAB and am not really sure what i'm doing, so please bear with me.
Here's the code that I'm working on:
function minimize
global X FUNC V
X = -1+i;
A = [-1 1];
FUNC = @residual;
powell(0.1, 1.0e-6)
function F = dEqs(y,x)
%parameters
E = 0.15/27.211; %Hartree 1 Hartree = 27.211 eV
V0 = 0.3/27.211; %Hartree
m = 1; %Hartree units
hbar = 1; %Hartree units;
kappa = sqrt(2*m*(E-V0)/(hbar^2)); %Hartree units
F = [y(2), kappa^2*y(1)];
% Boundary residual.
function r = residual(A)
global X FUNC V
%parameters
E = 0.15/27.211; %Hartree 1 Hartree = 27.211 eV
V0 = 0.3/27.211; %Hartree
m = 1; %Hartree units
hbar = 1; %Hartree units;
kappa = sqrt(2*m*(E-V0)/(hbar^2)); %Hartree units
[xSol, ySol] = runK4([1+(A(1)+i*A(2)) i*kappa*(1-(A(1)+i*A(2)))]);
r = ySol(end,1)+(i/kappa)*ySol(end,2);
function [xSol, ySol] = runK4(y)
global XSTART XSTOP H
x = XSTART;
i = 1;
xSol(1) = XSTART;
ySol(1,:) = y;
while (XSTOP-x > 1e-12)
i = i+1;
H = min(H,XSTOP-x); %Smallest elements in array
%C = min(A,B) returns an array the same size as A and B with the
%smallest elements taken from A or B. The dimensions of A and B
%must match, or they may be scalar
y = runge_kutta(y,x,H,@dEqs);
x = x+H;
xSol(i) = x;
ySol(i,:) = y; % Store current soln.
end
function xout = runge_kutta(x,t,tau,derivsRK)
% Runge-Kutta integrator (4th order)
% Input arguments -
% x = current value of dependent variable
% t = independent variable (usually time)
% tau = step size (usually timestep)
% derivsRK = right hand side of the ODE. It returns dx/dt
% param = extra parameters passed to derivsRK
% Output arguments -
% xout = new value of x after a step of size tau
half_tau = 0.5*tau;
F1 = feval(derivsRK,x,t);
t_half = t+half_tau;
xtemp = x+half_tau*F1;
F2 = feval(derivsRK,xtemp,t_half);
xtemp = x+half_tau*F2;
F3 = feval(derivsRK,xtemp,t_half);
t_full = t+tau;
xtemp = x+tau*F3;
F4 = feval(derivsRK,xtemp,t_full);
xout = x+tau/6.*(F1+F4+2.*(F2+F3));
return;
function [xMin,fMin,nCyc] = powell(h,tol)
% Powell's method for minimizing f(x1,x2,...,xn).
% USAGE: [xMin,fMin,nCyc] = powell(h,tol)
% INPUT:
% h = initial search increment (default = 0.1).
% tol = error tolerance (default = 1.0e-6).
% GLOBALS (must be declared GLOBAL in calling program):
% X = starting point
% FUNC = handle of function that returns f.
% OUTPUT:
% xMin = minimum point
% fMin = miminum value of f
% nCyc = number of cycles to convergence
global X FUNC V
%if nargin < 2; tol = 1.0e-6; end
%if nargin < 1; h = 0.1; end
if size(X,2) > 1; X = X'; end % X must be column vector
n = length(X); % Number of design variables
df = zeros(n,1); % Decreases of f stored here
u = eye(n); % Columns of u store search directions V
for j = 1:30 % Allow up to 30 cycles
xOld = X;
fOld = feval(FUNC,xOld);
% First n line searches record the decrease of f
for i = 1:n
V = u(1:n,i);
[a,b] = goldBracket(@fLine,0.0,h);
[s,fMin] = goldSearch(@fLine,a,b);
df(i) = fOld - fMin;
fOld = fMin;
X = X + s*V;
end
% Last line search in the cycle
V = X - xOld;
[a,b] = goldBracket(@fLine,0.0,h);
[s,fMin] = goldSearch(@fLine,a,b);
X = X + s*V;
% Check for convergence
if sqrt(dot(X-xOld,X-xOld)/n) < tol
xMin = X; nCyc = j; return
end
% Identify biggest decrease of f & update search
% directions
iMax = 1; dfMax = df(1);
for i = 2:n
if df(i) > dfMax
iMax = i; dfMax = df(i);
end
end
for i = iMax:n-1
u(1:n,i) = u(1:n,i+1);
end
u(1:n,n) = V;
end
error('Powell method did not converge')
function z = fLine(s) % F in the search direction V
global X FUNC V
z = feval(FUNC,X+s*V);
function [a,b] = goldBracket(func,x1,h)
% Brackets the minimum point of f(x).
% USAGE: [a,b] = goldBracket(func,xStart,h)
% INPUT:
% func = handle of function that returns f(x).
% x1 = starting value of x.
% h = initial step size used in search.
% OUTPUT:
% a, b = limits on x at the minimum point.
c = 1.618033989;
f1 = feval(func,x1);
x2 = x1 + h; f2 = feval(func,x2);
% Determine downhill direction & change sign of h if needed.
if f2 > f1
h = -h;
x2 = x1 + h; f2 = feval(func,x2);
% Check if minimum is between x1 - h and x1 + h
if f2 > f1
a = x2; b = x1 - h; return
end
end
% Search loop
for i = 1:100
h = c*h;
x3 = x2 + h; f3 = feval(func,x3);
if f3 > f2
a = x1; b = x3; return
end
x1 = x2; f1 = f2; x2 = x3; f2 = f3;
end
error('goldbracket did not find minimum')
function [xMin,fMin] = goldSearch(func,a,b,tol)
% Golden section search for the minimum of f(x).
% The minimum point must be bracketed in a <= x <= b.
% USAGE: [fMin,xMin] = goldSearch(func,xStart,h)
% INPUT:
% func = handle of function that returns f(x).
% a, b = limits of the interval containing the minimum.
% tol = error tolerance (default is 1.0e-6).
% OUTPUT:
% fMin = minimum value of f(x).
% xMin = value of x at the minimum point.
if nargin < 4; tol = 1.0e-6; end
nIter = ceil(-2.078087*log(tol/abs(b-a)));
R = 0.618033989;
C = 1.0 - R;
% First telescoping
x1 = R*a + C*b;
x2 = C*a + R*b;
f1 = feval(func,x1);
f2 = feval(func,x2);
% Main loop
for i =1:nIter
if f1 > f2
a = x1; x1 = x2; f1 = f2;
x2 = C*a + R*b;
f2 = feval(func,x2);
else
b = x2; x2 = x1; f2 = f1;
x1 = R*a + C*b;
f1 = feval(func,x1);
end
end
if f1 < f2; fMin = f1; xMin = x1;
else; fMin = f2; xMin = x2;
end
What I'm trying to do is to find an optimized A. I am trying to split up A into real and imaginary parts. But I'm not sure if I'm doing it right. I got the powell code from my teacher and am not sure if I'm using it correctly too... Please help!
Thank you.
0 comentarios
Respuestas (0)
Ver también
Categorías
Más información sobre Functions en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!