Report started
- Add output parameter to methods for objective function calls - Adjust the code to reduce objective function calls to some methods
@@ -1,10 +1,11 @@
|
||||
%
|
||||
% The main script for the assignment.
|
||||
% * Calls the bisection method for different epsilon values (Question 1)
|
||||
% * Calls every method for different lambda values, in order to plot
|
||||
% the iterations needed. (All questions, part A)
|
||||
% * Calls every method for 3 different lambda values, in order to plot
|
||||
% the [a, b] convergence. (All questions part B)
|
||||
%
|
||||
%
|
||||
%
|
||||
%
|
||||
%
|
||||
|
||||
|
||||
disp (" ");
|
||||
disp (" ");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%
|
||||
% Keeping lambda (accuracy) fixed, test the iteration needed for different
|
||||
% epsilon values.
|
||||
% Calculate and plot the iteration needed for different epsilon values,
|
||||
% keeping lambda (accuracy) fixed.
|
||||
%
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ lambda = 0.01;
|
||||
de = 0.0001;
|
||||
epsilon = linspace(de, (lambda/2)-de, N);
|
||||
k = zeros(1,N); % preallocate k
|
||||
n = zeros(1,N); % preallocate n
|
||||
|
||||
|
||||
%
|
||||
@@ -39,15 +40,15 @@ set(gcf, 'Position', [100, 100, 1280, 600]); % Set the figure size to HD
|
||||
|
||||
for i = 1:length(funs)
|
||||
for j = 1:N
|
||||
[a, b, k(j)] = min_bisection(funs(i), a_0, b_0, epsilon(j), lambda);
|
||||
[a, b, k(j), n(j)] = min_bisection(funs(i), a_0, b_0, epsilon(j), lambda);
|
||||
end
|
||||
fprintf('%20s(%34s ): [a, b]= [%f, %f], iterations(min, max)= (%d, %d)\n', ...
|
||||
"min_bisection", char(funs(i)), a(end), b(end), k(1), k(N) );
|
||||
subplot(1, length(funs), i)
|
||||
plot(epsilon, k, '-b', 'LineWidth', 1.0)
|
||||
title(titles(i), 'Interpreter', 'latex')
|
||||
xlabel('epsilon')
|
||||
ylabel('Iterations')
|
||||
fprintf('%20s(%34s ): [a, b]= [%f, %f], iters(min, max)= (%d, %d), calls(min, max)= (%d, %d)\n', ...
|
||||
"min_bisection", char(funs(i)), a(end), b(end), k(1), k(N), n(1), n(N) );
|
||||
subplot(1, length(funs), i);
|
||||
plot(epsilon, n, '-b', 'LineWidth', 1.0);
|
||||
title(titles(i), 'Interpreter', 'latex', 'FontSize', 16);
|
||||
xlabel('epsilon');
|
||||
ylabel("Calls of f" + i);
|
||||
end
|
||||
|
||||
%
|
||||
@@ -59,4 +60,5 @@ fig_png = fullfile(fig_dir, "iter_over_epsilon_min_bisection" + ".png");
|
||||
%print(gcf, fig_epsc, '-depsc', '-r300');
|
||||
print(gcf, fig_png, '-dpng', '-r300');
|
||||
|
||||
|
||||
close(gcf);
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 79 KiB |
@@ -1,12 +1,15 @@
|
||||
function [] = interval_over_iterations(method)
|
||||
% Plot the [a,b] interval over the iterations for different lambda
|
||||
% values (min, mid, max))
|
||||
% Calculate and plot the [a,b] interval over the iterations for different
|
||||
% lambda values (min, mid, max)
|
||||
%
|
||||
% method: the minimum calculation method
|
||||
% method: the minimum calculation method, one of:
|
||||
% * bisections
|
||||
% * golden_section
|
||||
% * fibonacci
|
||||
% * bisection_der
|
||||
% return:
|
||||
% none
|
||||
%
|
||||
|
||||
|
||||
% Load the functions and interval
|
||||
@@ -22,7 +25,7 @@ end
|
||||
%
|
||||
% We need to test against the same lambda values for all the methods in
|
||||
% order to compare them. And since epsilon (which is related to lambda)
|
||||
% was given for bisection method, we base our calculations to that.
|
||||
% was given for the bisection method, we base our calculations to that.
|
||||
%
|
||||
%
|
||||
% epsilon: e = 0.001
|
||||
@@ -37,6 +40,7 @@ lambda_min = 0.0021;
|
||||
lambda_max = 0.1;
|
||||
lambda = linspace(lambda_min, lambda_max, N);
|
||||
k = zeros(1, N); % preallocate k
|
||||
n = zeros(1, N); % preallocate n
|
||||
|
||||
|
||||
%
|
||||
@@ -56,20 +60,20 @@ for i = 1:length(funs)
|
||||
figure('Name', "interval_over_iterations_" + char(method) + "_fun" + i, 'NumberTitle', 'off');
|
||||
set(gcf, 'Position', [100, 100, 1280, 720]); % Set the figure size to HD
|
||||
for j = 1:N
|
||||
[a, b, k(j)] = method(funs(i), a_0, b_0, epsilon, lambda(j));
|
||||
[a, b, k(j), n(j)] = method(funs(i), a_0, b_0, epsilon, lambda(j));
|
||||
|
||||
fprintf('%20s(%34s ): [a, b]= [%f, %f], @lambda=%f, iterations= %d\n', ...
|
||||
char(method), char(funs(i)), a(end), b(end), lambda(j), k(j) );
|
||||
|
||||
subplot(length(funs), 1, j)
|
||||
plot(1:length(a), a, 'ob')
|
||||
subplot(length(funs), 1, j);
|
||||
plot(1:length(a), a, 'ob');
|
||||
hold on
|
||||
plot(1:length(b), b, '*r')
|
||||
plot(1:length(b), b, '*r');
|
||||
if j == 1
|
||||
title(titles(i), 'Interpreter', 'latex')
|
||||
title(titles(i), 'Interpreter', 'latex', 'FontSize', 16);
|
||||
end
|
||||
xlabel("Iterations @lambda=" + lambda(j))
|
||||
ylabel('[a_k, b_k]')
|
||||
xlabel("Iterations @lambda=" + lambda(j));
|
||||
ylabel('[a_k, b_k]');
|
||||
end
|
||||
|
||||
% Print and save the figure
|
||||
@@ -78,5 +82,7 @@ for i = 1:length(funs)
|
||||
|
||||
%print(gcf, fig_epsc, '-depsc', '-r300');
|
||||
print(gcf, fig_png, '-dpng', '-r300');
|
||||
|
||||
close(gcf);
|
||||
end
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
function [] = iterations_over_lambda(method)
|
||||
% Plot iteration needed for different lambda values.
|
||||
%
|
||||
% Calculate and plot iteration needed for different lambda values.
|
||||
%
|
||||
% method: the minimum calculation method
|
||||
% * bisections
|
||||
% * golden_section
|
||||
% * fibonacci
|
||||
% * bisection_der
|
||||
% return:
|
||||
% none
|
||||
%
|
||||
|
||||
|
||||
% Load the functions and interval
|
||||
@@ -22,7 +24,7 @@ end
|
||||
%
|
||||
% We need to test against the same lambda values for all the methods in
|
||||
% order to compare them. And since epsilon (which is related to lambda)
|
||||
% was given for bisection method, we base our calculations to that.
|
||||
% was given for the bisection method, we base our calculations to that.
|
||||
%
|
||||
%
|
||||
% epsilon: e = 0.001
|
||||
@@ -37,6 +39,7 @@ lambda_min = 0.0021;
|
||||
lambda_max = 0.1;
|
||||
lambda = linspace(lambda_min, lambda_max, N);
|
||||
k = zeros(1, N); % preallocate k
|
||||
n = zeros(1, N); % preallocate n
|
||||
|
||||
|
||||
%
|
||||
@@ -56,16 +59,16 @@ set(gcf, 'Position', [100, 100, 1280, 600]); % Set the figure size to HD
|
||||
disp(" ");
|
||||
for i = 1:length(funs)
|
||||
for j = N:-1:1
|
||||
[a, b, k(j)] = method(funs(i), a_0, b_0, epsilon, lambda(j));
|
||||
[a, b, k(j), n(j)] = method(funs(i), a_0, b_0, epsilon, lambda(j));
|
||||
end
|
||||
|
||||
fprintf('%20s(%34s ): [a, b]= [%f, %f], iterations(min, max)= (%d, %d)\n', ...
|
||||
char(method), char(funs(i)), a(end), b(end), k(N), k(1) );
|
||||
subplot(1, length(funs), i)
|
||||
plot(lambda, k, '-b', 'LineWidth', 1.0)
|
||||
title(titles(i), 'Interpreter', 'latex')
|
||||
xlabel('lambda')
|
||||
ylabel('Iterations')
|
||||
fprintf('%20s(%34s ): [a, b]= [%f, %f], iters(min, max)= (%d, %d), calls(min, max)= (%d, %d)\n', ...
|
||||
char(method), char(funs(i)), a(end), b(end), k(N), k(1), n(N), n(1) );
|
||||
subplot(1, length(funs), i);
|
||||
plot(lambda, n, '-b', 'LineWidth', 1.0);
|
||||
title(titles(i), 'Interpreter', 'latex', 'FontSize', 16);
|
||||
xlabel('lambda');
|
||||
ylabel("Calls of f" + i);
|
||||
end
|
||||
|
||||
|
||||
@@ -78,6 +81,6 @@ fig_png = fullfile(fig_dir, "iter_over_lambda_" + char(method) + ".png");
|
||||
%print(gcf, fig_epsc, '-depsc', '-r300');
|
||||
print(gcf, fig_png, '-dpng', '-r300');
|
||||
|
||||
|
||||
close(gcf);
|
||||
|
||||
|
||||
@@ -1,18 +1,31 @@
|
||||
function [a, b, k] = min_bisection(fun_expression, alpha, beta, epsilon, lambda)
|
||||
function [a, b, k, n] = min_bisection(fun_expr, alpha, beta, epsilon, lambda)
|
||||
% Bisection method for finding the local minimum of a function.
|
||||
%
|
||||
% Detailed explanation goes here
|
||||
% fun_expr: (symbolic expression over x) The symbolic expression of the
|
||||
% objective function
|
||||
% alpha: (number) The starting point of the interval in which we seek
|
||||
% for minimum
|
||||
% beta: (number) The ending point of the interval in which we seek
|
||||
% for minimum
|
||||
% epsilon: (number) The epsilon value (distance from midpoint)
|
||||
% lambda: (number) The lambda value (accuracy)
|
||||
%
|
||||
% return:
|
||||
% a: (vector) Starting points of the interval for each iteration
|
||||
% b: (vector) Ending points of the interval for each iteration
|
||||
% k: (number) The number of iterations
|
||||
% n: (number) The calls of objective function fun_expr
|
||||
%
|
||||
|
||||
% Error checking
|
||||
if 2*epsilon >= lambda || lambda <= 0
|
||||
error ('Convergence criteria not met')
|
||||
if alpha > beta || 2*epsilon >= lambda || lambda <= 0
|
||||
error ('Input criteria not met')
|
||||
end
|
||||
|
||||
% Init
|
||||
a = alpha;
|
||||
b = beta;
|
||||
fun = matlabFunction(fun_expression);
|
||||
fun = matlabFunction(fun_expr);
|
||||
|
||||
k=1;
|
||||
|
||||
@@ -31,4 +44,7 @@ while b(k) - a(k) > lambda
|
||||
a(k) = x_1;
|
||||
b(k) = b(k-1);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% Set objective function calls
|
||||
n = 2*k;
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
function [a, b, k] = min_bisection_der(fun_expression, alpha, beta, epsilon, lambda)
|
||||
function [a, b, k, n] = min_bisection_der(fun_expression, alpha, beta, epsilon, lambda)
|
||||
% Bisection using derivatives method for finding the local minimum of a
|
||||
% function.
|
||||
%
|
||||
% Detailed explanation goes here
|
||||
% fun_expr: (symbolic expression over x) The symbolic expression of the
|
||||
% objective function
|
||||
% alpha: (number) The starting point of the interval in which we seek
|
||||
% for minimum
|
||||
% beta: (number) The ending point of the interval in which we seek
|
||||
% for minimum
|
||||
% epsilon: (number) The epsilon value
|
||||
% **note:**
|
||||
% epsilon in not used in this method, but it is part of the
|
||||
% method calling interface.
|
||||
% lambda: (number) The lambda value (accuracy)
|
||||
%
|
||||
% return:
|
||||
% a: (vector) Starting points of the interval for each iteration
|
||||
% b: (vector) Ending points of the interval for each iteration
|
||||
% k: (number) The number of iterations
|
||||
% n: (number) The calls of objective function fun_expr
|
||||
%
|
||||
|
||||
% Error checking
|
||||
if lambda <= 0
|
||||
error ('Convergence criteria not met')
|
||||
if alpha > beta || lambda <= 0
|
||||
error ('Input criteria not met')
|
||||
end
|
||||
|
||||
% Init output vectors
|
||||
@@ -33,4 +50,8 @@ while b(k) - a(k) > lambda
|
||||
b(k) = x_mid;
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% Update the objctive function calls. In this case the derivative of the
|
||||
% function ;)
|
||||
n = k;
|
||||
|
||||
@@ -1,22 +1,38 @@
|
||||
function [a, b, N] = min_fibonacci(fun_expression, alpha, beta, epsilon, lambda)
|
||||
function [a, b, N, nn] = min_fibonacci(fun_expression, alpha, beta, epsilon, lambda)
|
||||
% Fibonacci method for finding the local minimum of a function.
|
||||
%
|
||||
% fun_expr: (symbolic expression over x) The symbolic expression of the
|
||||
% objective function
|
||||
% alpha: (number) The starting point of the interval in which we seek
|
||||
% for minimum
|
||||
% beta: (number) The ending point of the interval in which we seek
|
||||
% for minimum
|
||||
% epsilon: (number) The epsilon value (the interval of the last step)
|
||||
% lambda: (number) The lambda value (accuracy)
|
||||
%
|
||||
% return:
|
||||
% a: (vector) Starting points of the interval for each iteration
|
||||
% b: (vector) Ending points of the interval for each iteration
|
||||
% N: (number) The number of iterations needed.
|
||||
% nn: (number) The calls of objective function fun_expr
|
||||
%
|
||||
|
||||
% Error checking
|
||||
if alpha > beta || lambda <= 0 || epsilon <= 0
|
||||
error ('Input criteria not met')
|
||||
end
|
||||
|
||||
% Use Binet's formula instead of matlab's recursive fibonacci
|
||||
% implementation
|
||||
fibonacci = @(n) ( ((1 + sqrt(5))^n - (1 - sqrt(5))^n) / (2^n * sqrt(5)) );
|
||||
|
||||
% Error checking
|
||||
if lambda <= 0 || epsilon <= 0
|
||||
error ('Convergence criteria not met')
|
||||
end
|
||||
|
||||
% Init variables
|
||||
a = alpha;
|
||||
b = beta;
|
||||
fun = matlabFunction(fun_expression);
|
||||
|
||||
% calculate number of iterations
|
||||
N=0;
|
||||
N = 0;
|
||||
while fibonacci(N) < (b(1) - a(1)) / lambda
|
||||
N = N + 1;
|
||||
end
|
||||
@@ -52,3 +68,7 @@ else
|
||||
a(N) = x_1;
|
||||
b(N) = b(N-1);
|
||||
end
|
||||
|
||||
% Set objective function calls
|
||||
nn = 2*N -2;
|
||||
|
||||
|
||||
@@ -1,10 +1,28 @@
|
||||
function [a, b, k] = min_golden_section(fun_expression, alpha, beta, epsilon, lambda)
|
||||
function [a, b, k, n] = min_golden_section(fun_expression, alpha, beta, epsilon, lambda)
|
||||
% Golden section method for finding the local minimum of a function.
|
||||
%
|
||||
% fun_expr: (symbolic expression over x) The symbolic expression of the
|
||||
% objective function
|
||||
% alpha: (number) The starting point of the interval in which we seek
|
||||
% for minimum
|
||||
% beta: (number) The ending point of the interval in which we seek
|
||||
% for minimum
|
||||
% epsilon: (number) The epsilon value
|
||||
% **note:**
|
||||
% epsilon in not used in this method, but it is part of the
|
||||
% method calling interface.
|
||||
% lambda: (number) The lambda value (accuracy)
|
||||
%
|
||||
% return:
|
||||
% a: (vector) Starting points of the interval for each iteration
|
||||
% b: (vector) Ending points of the interval for each iteration
|
||||
% k: (number) The number of iterations
|
||||
% n: (number) The calls of objective function fun_expr
|
||||
%
|
||||
|
||||
|
||||
% Error checking
|
||||
if lambda <= 0
|
||||
error ('Convergence criteria not met')
|
||||
if alpha > beta || lambda <= 0
|
||||
error ('Input criteria not met')
|
||||
end
|
||||
|
||||
% Init variables
|
||||
@@ -19,18 +37,28 @@ k=1;
|
||||
x_1 = a(k) + (1 - gamma)*(b(k) - a(k));
|
||||
x_2 = a(k) + gamma*(b(k) - a(k));
|
||||
|
||||
f1 = fun(x_1);
|
||||
f2 = fun(x_2);
|
||||
while b(k) - a(k) > lambda
|
||||
% set new search interval
|
||||
k = k + 1;
|
||||
if fun(x_1) < fun(x_2)
|
||||
if f1 < f2
|
||||
a(k) = a(k-1);
|
||||
b(k) = x_2;
|
||||
x_2 = x_1;
|
||||
f2 = f1;
|
||||
x_1 = a(k) + (1 - gamma)*(b(k) - a(k));
|
||||
f1 = fun(x_1);
|
||||
else
|
||||
a(k) = x_1;
|
||||
b(k) = b(k-1);
|
||||
x_1 = x_2;
|
||||
f1 = f2;
|
||||
x_2 = a(k) + gamma*(b(k) - a(k));
|
||||
f2 = fun(x_2);
|
||||
end
|
||||
end
|
||||
|
||||
% Set objective function calls
|
||||
n = k+1;
|
||||
|
||||
|
||||