Created
May 16, 2012 13:56
-
-
Save libbkmz/2710524 to your computer and use it in GitHub Desktop.
Lab2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function [ptr,fval] = finmin( func, start, step, eps, varargin ) | |
nargs = length(varargin); | |
f_hl = matlabFunction(func); | |
grad = gradient(func); | |
max_iter = 400; | |
fin_dif = 0; | |
%% gradient cell array for speed optimisation purposes | |
grad_arr = [sym()]; | |
for i=1:length(start) | |
grad_arr(i) = grad(i); | |
end | |
grad_hl_arr = num2cell(grad_arr); | |
for i=1:length(grad_hl_arr) | |
grad_hl_arr{i} = matlabFunction( grad_arr(i) ); | |
end | |
%% getting vararign params | |
if nargs == 0 | |
delta = eps; | |
elseif nargs == 1 | |
delta = varargin{1}; | |
elseif nargs == 2 | |
delta = varargin{1}; | |
max_iter = varargin{2}; | |
elseif nargs == 3 | |
delta = varargin{1}; | |
max_iter = varargin{2}; | |
fin_dif = varargin{3}; | |
elseif nargs == 5 | |
delta = varargin{1}; | |
max_iter = varargin{2}; | |
fin_dif = varargin{3}; | |
lb = varargin{4}; | |
ub = varargin{5}; | |
end | |
%% function wrappers | |
function r = func_wrapper(ptr) | |
cell_ptr = num2cell(ptr); | |
r = f_hl(cell_ptr{1:length(cell_ptr)}); | |
end | |
function r = gradient_wrapper(i, x, h) | |
vars = symvar(grad_arr(i)); | |
args = {}; | |
if fin_dif == 0 | |
for j = 1:length(vars) | |
for k = 1:length(x) | |
if vars(j) == strcat('x', num2str(k)) | |
args{length(args) + 1} = x(k); | |
% TODO: remove matlab warning | |
break; | |
end | |
end | |
end | |
r = grad_hl_arr{i}(args{1:length(args)}); | |
else | |
r = (func_wrapper(x + step) - func_wrapper(x))/step; | |
end | |
end | |
function draw_wrapper(ptr, ptr_n) | |
cell_ptr = num2cell(ptr); | |
plot(cell_ptr{1:length(cell_ptr)}, 'x'); | |
end | |
function draw_plot(xV, yV, step); | |
[x,y] = meshgrid(-yV:step:yV); | |
z = f_hl(x,y); | |
contour(x,y,z,32); | |
surf(x,y,z); | |
end | |
function r = f_min_search_wrapper(h, ptr, g) | |
z = num2cell(ptr + h*g); | |
r = f_hl(z{1:length(z)}); | |
end | |
%% prepare for computation | |
ptr = start | |
hold on | |
draw_plot(4, 4, 0.1); | |
%% options for fminunc | |
options = optimset('Display', 'off') ; | |
options.LargeScale = 'off'; | |
for index=1:max_iter | |
%% computing gradient | |
g = zeros([1 length(ptr)]); | |
for i = 1:length(ptr) | |
g(i) = -gradient_wrapper(i, ptr, step); | |
end | |
%% searcing optimal step | |
% step = fminunc(@(h)f_min_search_wrapper(h, ptr, g), step, options); | |
% step = step/sqrt(2); | |
%% main computing | |
ptr_n = ptr + (step) * g; | |
%% check result condition to exit loop | |
if abs(norm(ptr_n) - norm(ptr)) < delta | |
fprintf('DELTA condition worked\n'); | |
break; | |
elseif abs(func_wrapper(ptr_n) - func_wrapper(ptr)) < eps | |
fprintf('EPS condition worked\n'); | |
break; | |
end | |
%% drawing point | |
draw_wrapper(ptr, ptr_n); | |
%% reflection boundaries | |
%% prepare for next itaretion+ | |
ptr = ptr_n; | |
fprintf('iteration %i\n', index); | |
fprintf('\tptr = %.4f\n', ptr); | |
fprintf('\tf(ptr) = %.4f\n', func_wrapper(ptr)); | |
end | |
%% drawing last red point | |
cell_ptr = num2cell(ptr); | |
plot(cell_ptr{1:length(cell_ptr)},'r*'); | |
hold off | |
%% returning variables | |
fval = func_wrapper(ptr); | |
x = ptr; | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment