@@ -0,0 +1,93 @@ | |||||
% | |||||
% Optimization Techniques Work 3 report | |||||
% | |||||
% authors: | |||||
% Χρήστος Χουτουρίδης ΑΕΜ 8997 | |||||
% cchoutou@ece.auth.gr | |||||
\documentclass[a4paper, 11pt]{AUTHReport} | |||||
% Document configuration | |||||
\AuthorName{Χρήστος Χουτουρίδης} | |||||
\AuthorAEM{8997} | |||||
\AuthorMail{cchoutou@ece.auth.gr} | |||||
%\CoAuthorName{CoAuthor Name} | |||||
%\CoAuthorAEM{AEM} | |||||
%\CoAuthorMail{CoAuthor Mail} | |||||
% \WorkGroup{Ομάδα Χ} | |||||
\DocTitle{3η Εργαστηριακή Άσκηση} | |||||
\DocSubTitle{Μέθοδος Μέγιστης Καθόδου με Προβολή} | |||||
\Department{Τμήμα ΗΜΜΥ. Τομέας Ηλεκτρονικής} | |||||
\ClassName{Τεχνικές Βελτιστοποίησης} | |||||
\InstructorName{Γ. Ροβιθάκης} | |||||
\InstructorMail{rovithak@auth.gr} | |||||
\CoInstructorName{Θ. Αφορόζη} | |||||
\CoInstructorMail{taforozi@ece.auth.gr} | |||||
\CurrentDate{\today} | |||||
\usepackage{enumitem} | |||||
\usepackage{tabularx} | |||||
\usepackage{array} | |||||
\usepackage{amssymb} | |||||
\usepackage{amsfonts} | |||||
\usepackage{amsmath} | |||||
\usepackage{commath} | |||||
\usepackage{float} | |||||
\begin{document} | |||||
\InsertTitle | |||||
%\tableofcontents | |||||
\sloppy | |||||
\section{Εισαγωγή} | |||||
Η παρούσα εργασία αφορά το πρόβλημα της ελαχιστοποίησης μιας δοσμένης συνάρτησης πολλών μεταβλητών $f: \mathbb{R}^n \rightarrow \mathbb{R}$ χωρίς περιορισμούς. | |||||
Για το σκοπό αυτό κάνουμε χρήση τριών μεθόδων. | |||||
Της μεθόδου μέγιστης καθόδου (Steepest Descent), της μεθόδου Newton, και της Levenberg-Marquardt. | |||||
Ακόμα για κάθε μία από αυτές θα υλοποιήσουμε τρεις διαφορετικές τεχνικές υπολογισμού βήματος. | |||||
\section{Παραδοτέα} | |||||
Τα παραδοτέα της εργασίας αποτελούνται από: | |||||
\begin{itemize} | |||||
\item Την παρούσα αναφορά. | |||||
\item Τον κατάλογο \textbf{scripts/}, που περιέχει τον κώδικα της MATLAB. | |||||
\item Το \href{https://git.hoo2.net/hoo2/OptimizationTechniques/src/branch/master/Work%203}{σύνδεσμο} με το αποθετήριο που περιέχει όλο το project με τον κώδικα της MATLAB, της αναφοράς και τα παραδοτέα. | |||||
\end{itemize} | |||||
\section{Προγραμματιστική προσέγγιση} | |||||
Για τον προγραμματισμό και εκτέλεση των μεθόδων της παρούσας εργασίας έγινε χρήση της MATLAB. | |||||
Στον κατάλογο \textbf{scripts}, περιέχονται όλες οι μέθοδοι και οι τεχνικές υπολογισμού βημάτων με τη μορφή συναρτήσεων καθώς και scripts που τις καλούν. | |||||
Για κάθε μία μέθοδο (ένα θέμα της εργασίας), υπάρχει το αντίστοιχο script που περιέχει τους υπολογισμούς, τις κλήσεις των μεθόδων και τη δημιουργία των διαγραμμάτων. | |||||
Για το πρώτο θέμα το αρχείο Script\_1\_Plots.m για το δεύτερο το Script\_2\_Steepest\_descent.m και ούτω καθεξής. | |||||
Στην παρούσα εργασία η υλοποίηση του κώδικα ακολουθεί την τεχνική της προηγούμενης εργασίας και “ομαδοποιεί” αρκετές λειτουργίες. | |||||
Πιο συγκεκριμένα. | |||||
\subsection{Symbolic expression functions} | |||||
Μία ακόμη προγραμματιστική τεχνική που ακολουθήθηκε είναι η χρήση \textbf{symbolic expression} για την αναπαράσταση των διαφορετικών αντικειμενικών συναρτήσεων. | |||||
Ο λόγος που επιλέχθηκε είναι η \textbf{δυνατότητα εξαγωγής ενός symbolic expression που αναπαριστά την κλίση $\nabla f$ και τον Εσσιανό $\nabla^2f$ μιας συνάρτησης} από την MATLAB, κάνοντας χρήση των εντολών \textit{gradient()} και \textit{hessian()}. | |||||
Αν αντίθετα χρησιμοποιούσαμε απλές συναρτήσεις, πολυώνυμα ή lambdas για την αναπαράσταση των αντικειμενικών συναρτήσεων, τότε για τον υπολογισμό της κλίσης και του Εσσιανού θα έπρεπε: | |||||
\begin{itemize} | |||||
\item Είτε να υπολογίζαμε αριθμητικά τις παραγώγους gradient και hessian μέσα στις μεθόδους, κάτι που θα εισήγαγε \textit{\textbf{αχρείαστο αριθμητικό σφάλμα}}. | |||||
\item Είτε να κάναμε χρήση δύο επιπλέων συναρτήσεων (ή πολυωνύμων) για την αναπαράσταση τους, κάτι που ουσιαστικά θα δημιουργούσε \textit{\textbf{πλεονασμό πληροφορίας εισόδου}} και άρα μεγαλύτερη πιθανότητα να κάνουμε λάθος. | |||||
\end{itemize} | |||||
Η αναπαράσταση όμως με χρήση symbolic expression είναι πιο “βαριά” όταν χρειάζεται να υπολογίσουμε την τιμή μιας συνάρτησης σε κάποιο σημείο (subs(expr, number)). | |||||
Αυτό είναι κάτι που χρειάζεται εκτενώς στον κώδικά μας. | |||||
Για το λόγο αυτό, ενώ η συνάρτηση δίνεται ως symbolic expression, μέσω αυτής υπολογίζονται αυτόματα η κλίση, ο Εσσιανός αλλά και οι “κανονικές” συναρτήσεις MATLAB που τις υλοποιούν. | |||||
Έτσι έχουμε την ακριβή αναπαράσταση της κλίσης και του Εσσιανού ως συναρτήσεις χωρίς να πληρώνουμε το κόστος της subs(). | |||||
\end{document} |
@@ -0,0 +1,19 @@ | |||||
function [flag] = BelongsTo(x, SetLimmits) | |||||
%Checks if the x vector belongs to Set | |||||
% | |||||
% x: A vector to project | |||||
% SetLimmits: The set to project. Each line/dimension off the set has to contain the limits | |||||
% of the set to that particular dimension | |||||
% flag: True if belongs | |||||
% | |||||
flag = true; % Have faith | |||||
for i = 1:size(SetLimmits, 2) | |||||
if x(i) < SetLimmits(i,1) | |||||
flag = false; | |||||
elseif x(i) > SetLimmits(i,2) | |||||
flag = false; | |||||
end | |||||
end | |||||
end | |||||
@@ -0,0 +1,33 @@ | |||||
% Given environment | |||||
clear; | |||||
% Setup the function under test | |||||
syms x [2 1] real; | |||||
fexpr = (1/3)*x(1)^2 +3*x(2)^2; | |||||
title_fun = "$f(x) = frac{1}{3}{x_1}^2 + 3{x_2}^2$"; | |||||
% Calculate the gradient and Hessian | |||||
grad_fexpr = gradient(fexpr, x); % Gradient of f | |||||
hessian_fexpr = hessian(fexpr, x); % Hessian of f | |||||
% Convert symbolic expressions to MATLAB functions | |||||
fun = matlabFunction(fexpr, 'Vars', {x}); % Function | |||||
grad_fun = matlabFunction(grad_fexpr, 'Vars', {x}); % Gradient | |||||
hessian_fun = matlabFunction(hessian_fexpr, 'Vars', {x}); % Hessian | |||||
% Minimum reference | |||||
%Freference = @(x) x(1).^5 .* exp(-x(1).^2 - x(2).^2); | |||||
%[Xmin, Fmin] = fminsearch(Freference, [-1, -1]); | |||||
% Amijo globals | |||||
global amijo_beta; % Step reduction factor in [0.1, 0.5] (typical range: [0.1, 0.8]) | |||||
global amijo_sigma; % Sufficient decrease constant in [1e-5, 0.1] (typical range: [0.01, 0.3]) | |||||
%fixed step size globals | |||||
global gamma_fixed_step | |||||
global image_width, | |||||
global image_height; | |||||
image_width = 960; | |||||
image_height = 640; |
@@ -0,0 +1,36 @@ | |||||
% Given environment | |||||
clear; | |||||
% Setup the function under test | |||||
syms x [2 1] real; | |||||
fexpr = (1/3)*x(1)^2 +3*x(2)^2; | |||||
title_fun = "$f(x) = \frac{1}{3}{x_1}^2 + 3{x_2}^2$"; | |||||
XSetLimmits = [-10, 5 ; -8, 12]; | |||||
% Calculate the gradient and Hessian | |||||
grad_fexpr = gradient(fexpr, x); % Gradient of f | |||||
hessian_fexpr = hessian(fexpr, x); % Hessian of f | |||||
% Convert symbolic expressions to MATLAB functions | |||||
fun = matlabFunction(fexpr, 'Vars', {x}); % Function | |||||
grad_fun = matlabFunction(grad_fexpr, 'Vars', {x}); % Gradient | |||||
hessian_fun = matlabFunction(hessian_fexpr, 'Vars', {x}); % Hessian | |||||
% Minimum reference | |||||
[Xmin, Fmin] = fminsearch(fun, [-1, -1]'); | |||||
Xmin = round(Xmin, 3); | |||||
Fmin = round(Fmin, 3); | |||||
% Amijo globals | |||||
global amijo_beta; % Step reduction factor in [0.1, 0.5] (typical range: [0.1, 0.8]) | |||||
global amijo_sigma; % Sufficient decrease constant in [1e-5, 0.1] (typical range: [0.01, 0.3]) | |||||
%fixed step size globals | |||||
global gamma_fixed_step | |||||
global image_width, | |||||
global image_height; | |||||
image_width = 960; | |||||
image_height = 640; |
@@ -0,0 +1,18 @@ | |||||
function [x_p] = ProjectionPoint(x, SetLimmits) | |||||
%Project the x vector to Set, returns a point of Set close(st) to x | |||||
% | |||||
% x: A vector to project | |||||
% SetLimmits: The set to project. Each line/dimension off the set has to contain the limits | |||||
% of the set to that particular dimension | |||||
%x_p: The projected point | |||||
% | |||||
x_p = x; | |||||
for i = 1:size(SetLimmits, 2) | |||||
if x(i) < SetLimmits(i,1) | |||||
x_p(i) = SetLimmits(i,1); | |||||
elseif x(i) > SetLimmits(i,2) | |||||
x_p(i) = SetLimmits(i,2); | |||||
end | |||||
end | |||||
end | |||||
@@ -0,0 +1,14 @@ | |||||
% Define environment (functions, gradients etc...) | |||||
GivenEnv | |||||
% | |||||
% We plot the function in the domain of x,y in [-3, 3]. | |||||
% We also plot the contour in order to get a sense of the min and maximum | |||||
% points in the x-y plane | |||||
% | |||||
% 3d plot the function | |||||
plot3dFun(fun, XSetLimmits(1, :), XSetLimmits(2, :), 100, title_fun, "figures/Plot_Function.png"); | |||||
% Plot isobaric lines | |||||
plotContour(fun, XSetLimmits(1, :), XSetLimmits(2, :), 100, title_fun, "figures/Plot_Contour.png"); |
@@ -0,0 +1,29 @@ | |||||
% Define environment (functions, gradients etc...) | |||||
GivenEnv | |||||
% Define parameters | |||||
max_iter = 1000; % Maximum iterations | |||||
tol = 1e-4; % Tolerance | |||||
% Point x0 = (1, 1) | |||||
% ========================================================================= | |||||
point = 1; | |||||
x0 = [5, -5]'; | |||||
point_str = "[" + x0(1) + ", " + x0(2) + "]"; | |||||
f = fun(x0); | |||||
gf = grad_fun(x0); | |||||
hf = hessian_fun(x0); | |||||
fprintf('Initial point (%d, %d), f = %f, grad = [%f;%f], hessian = [%f %f ; %f %f]=> Method applicable\n', x0, f, gf, hf); | |||||
for g=[0.1, 0.3, 0.5, 3, 5] | |||||
gamma_fixed_step = g; | |||||
[x_fixed, f_fixed, kk] = method_SteepDesc(fun, grad_fun, x0, tol, max_iter, 'fixed'); | |||||
fprintf('Fixed step g=%f: Initial point (%f, %f), steps:%d, Final (x1,x2)=(%f, %f), f(x1,x2)=%f\n', g, x0, kk, x_fixed(:, end), f_fixed(end)); | |||||
if g <= 1 | |||||
plotPointsOverContour(x_fixed, fun, XSetLimmits(1, :), XSetLimmits(2, :), 100, point_str + ": Steepest descent $\gamma$ = " + gamma_fixed_step, ""); | |||||
else | |||||
plotPointsOverContour(x_fixed, fun, [-500, 500], [-500, 500], 100, point_str + ": Steepest descent $\gamma$ = " + gamma_fixed_step, ""); | |||||
end | |||||
end | |||||
@@ -0,0 +1,32 @@ | |||||
% Define environment (functions, gradients etc...) | |||||
GivenEnv | |||||
% Settings | |||||
max_iter = 1000; % Maximum iterations | |||||
% Define parameters | |||||
% ========================================================================= | |||||
x0 = [5, -5]'; | |||||
gamma = 0.5; | |||||
sk_step = 5; | |||||
tol = 0.01; % Tolerance | |||||
point_str = "[" + x0(1) + ", " + x0(2) + "]"; | |||||
f = fun(x0); | |||||
gf = grad_fun(x0); | |||||
hf = hessian_fun(x0); | |||||
fprintf('Initial point (%d, %d), f = %f, grad = [%f;%f], hessian = [%f %f ; %f %f]=> Method applicable\n', x0, f, gf, hf); | |||||
gamma_fixed_step = gamma; | |||||
[x_fixed, f_fixed, kk] = method_SteepDesc_Proj(fun, grad_fun, x0, sk_step, XSetLimmits, tol, max_iter, 'fixed'); | |||||
fprintf('Fixed step g=%f: Initial point (%f, %f), steps:%d, Final (x1,x2)=(%f, %f), f(x1,x2)=%f\n', gamma_fixed_step, x0, kk, x_fixed(:, end), f_fixed(end)); | |||||
plotPointsOverContour(x_fixed, fun, XSetLimmits(1, :), XSetLimmits(2, :), 100, point_str + ": Steepest descent $\gamma$ = " + gamma_fixed_step, ""); | |||||
%[x_minimized, f_minimized, kk] = method_SteepDesc_Proj(fun, grad_fun, x0, sk_step, XSetLimmits, tol, max_iter, 'minimized'); | |||||
%fprintf('Minimized f: Initial point (%f, %f), steps:%d, Final (x1,x2)=(%f, %f), f(x1,x2)=%f\n', x0, kk, x_fixed(:, end), f_fixed(end)); | |||||
%plotPointsOverContour(x_fixed, fun, XSetLimmits(1, :), XSetLimmits(2, :), 100, point_str + ": Steepest descent minimized", ""); | |||||
@@ -0,0 +1,27 @@ | |||||
% Define environment (functions, gradients etc...) | |||||
GivenEnv | |||||
% Settings | |||||
max_iter = 1000; % Maximum iterations | |||||
% Define parameters | |||||
% ========================================================================= | |||||
x0 = [-5, 10]'; | |||||
gamma = 0.1; | |||||
sk_step = 55; | |||||
tol = 0.01; % Tolerance | |||||
point_str = "[" + x0(1) + ", " + x0(2) + "]"; | |||||
f = fun(x0); | |||||
gf = grad_fun(x0); | |||||
hf = hessian_fun(x0); | |||||
fprintf('Initial point (%d, %d), f = %f, grad = [%f;%f], hessian = [%f %f ; %f %f]=> Method applicable\n', x0, f, gf, hf); | |||||
gamma_fixed_step = gamma; | |||||
[x_fixed, f_fixed, kk] = method_SteepDesc_Proj(fun, grad_fun, x0, sk_step, XSetLimmits, tol, max_iter, 'fixed'); | |||||
fprintf('Fixed step g=%f: Initial point (%f, %f), steps:%d, Final (x1,x2)=(%f, %f), f(x1,x2)=%f\n', gamma_fixed_step, x0, kk, x_fixed(:, end), f_fixed(end)); | |||||
plotPointsOverContour(x_fixed, fun, XSetLimmits(1, :), XSetLimmits(2, :), 100, point_str + ": Steepest descent $\gamma$ = " + gamma_fixed_step, ""); | |||||
@@ -0,0 +1,27 @@ | |||||
% Define environment (functions, gradients etc...) | |||||
GivenEnv | |||||
% Settings | |||||
max_iter = 1000; % Maximum iterations | |||||
% Define parameters | |||||
% ========================================================================= | |||||
x0 = [8, -10]'; | |||||
gamma = 0.2; | |||||
sk_step = 0.1; | |||||
tol = 0.01; % Tolerance | |||||
point_str = "[" + x0(1) + ", " + x0(2) + "]"; | |||||
f = fun(x0); | |||||
gf = grad_fun(x0); | |||||
hf = hessian_fun(x0); | |||||
fprintf('Initial point (%d, %d), f = %f, grad = [%f;%f], hessian = [%f %f ; %f %f]=> Method applicable\n', x0, f, gf, hf); | |||||
gamma_fixed_step = gamma; | |||||
[x_fixed, f_fixed, kk] = method_SteepDesc_Proj(fun, grad_fun, x0, sk_step, XSetLimmits, tol, max_iter, 'fixed'); | |||||
fprintf('Fixed step g=%f: Initial point (%f, %f), steps:%d, Final (x1,x2)=(%f, %f), f(x1,x2)=%f\n', gamma_fixed_step, x0, kk, x_fixed(:, end), f_fixed(end)); | |||||
plotPointsOverContour(x_fixed, fun, XSetLimmits(1, :), XSetLimmits(2, :), 100, point_str + ": Steepest descent $\gamma$ = " + gamma_fixed_step, ""); | |||||
@@ -0,0 +1,49 @@ | |||||
function [a, b, k, n] = fmin_bisection(fun, alpha, beta, epsilon, lambda) | |||||
% Bisection method for finding the local minimum of a function. | |||||
% | |||||
% fun: 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 alpha > beta || 2*epsilon >= lambda || lambda <= 0 | |||||
error ('Input criteria not met') | |||||
end | |||||
% Init | |||||
a = alpha; | |||||
b = beta; | |||||
n = 0; | |||||
k=1; | |||||
while b(k) - a(k) > lambda | |||||
% bisect [a,b] | |||||
mid = (a(k) + b(k)) / 2; | |||||
x_1 = mid - epsilon; | |||||
x_2 = mid + epsilon; | |||||
% set new search interval | |||||
k = k + 1; | |||||
if fun(x_1) < fun(x_2) | |||||
a(k) = a(k-1); | |||||
b(k) = x_2; | |||||
else | |||||
a(k) = x_1; | |||||
b(k) = b(k-1); | |||||
end | |||||
end | |||||
end |
@@ -0,0 +1,32 @@ | |||||
function [gamma] = gamma_armijo(f, grad_f, dk, xk) | |||||
% Calculates the best step based on amijo method | |||||
% | |||||
% f(xk+ γk*dk) ≤ f(xk) + σ * γk * dk^T * ∇f(xk) | |||||
% γk = β*γk_0 | |||||
% | |||||
% f: Objective function | |||||
% grad_fun: Gradient function of f | |||||
% dk: Current value of selected direction -∇f or -inv{H}*∇f or -inv{H + lI}*∇f | |||||
% xk: Current point (x,y) | |||||
% beta: beta factor in [0.1, 0.5] | |||||
% signam: sigma factor in (0, 0.1] | |||||
global amijo_beta | |||||
global amijo_sigma | |||||
gf = grad_f(xk); | |||||
gamma = 1; % Start with a step size of 1 | |||||
% Perform Armijo line search | |||||
while f(xk + gamma * dk) > f(xk) + amijo_sigma * gamma * dk * gf | |||||
%while f(xk(1) + gamma * dk(1), xk(2) + gamma * dk(2)) > ... | |||||
% f(xk(1), xk(2)) + amijo_sigma * gamma * norm(dk)^2 | |||||
gamma = amijo_beta * gamma; % Reduce step size | |||||
if gamma < 1e-12 % Safeguard to prevent infinite reduction | |||||
warning('Armijo step size became too small.'); | |||||
break; | |||||
end | |||||
end | |||||
end |
@@ -0,0 +1,12 @@ | |||||
function [gamma] = gamma_fixed(~, ~, ~, ~) | |||||
% Return a fixed step | |||||
% | |||||
% This is for completion and code symmetry. | |||||
% | |||||
global gamma_fixed_step | |||||
% Perform line search | |||||
gamma = gamma_fixed_step; | |||||
end |
@@ -0,0 +1,24 @@ | |||||
function [gamma] = gamma_minimized(f, ~, dk, xk) | |||||
% Calculates the step based on minimizing f(xk− γk*dk) | |||||
% | |||||
% | |||||
% f: Objective function | |||||
% ~: Gradient function of f - Not used | |||||
% dk: Current value of selected direction -∇f or -inv{H}*∇f or -inv{H + lI}*∇f | |||||
% xk: Current point (x,y) | |||||
% Define the line search function fmin(g) = f(xk - g * dk) | |||||
fmin = @(g) f(xk) + g * dk; | |||||
% find g that minimizes fmin | |||||
e = 0.0001; | |||||
l = 0.001; | |||||
[a,b,k,~] = fmin_bisection(fmin, 0.0001, 1, e, l); % g in (0, 1] | |||||
gamma = 0.5*(a(k) + b(k)); | |||||
% Define the line search function fmin(g) = f(xk - g * dk) | |||||
%fmin = @(g) f(xk(1) - gamma * dk(1), xk(2) - gamma * dk(2)); | |||||
% find g that minimizes fmin | |||||
%gamma = fminbnd(g, 0, 1); | |||||
end |
@@ -0,0 +1,39 @@ | |||||
function [x_vals, f_vals, k] = method_SteepDesc(f, grad_f, xk, tol, max_iter, mode) | |||||
% f: Objective function | |||||
% grad_f: Gradient of the function | |||||
% xk: Initial point [x0; y0] | |||||
% tol: Tolerance for stopping criterion | |||||
% max_iter: Maximum number of iterations | |||||
% x_vals: Vector with the (x,y) values until minimum | |||||
% f_vals: Vector with f(x,y) values until minimum | |||||
% k: Number of iterations | |||||
if strcmp(mode, 'armijo') == 1 | |||||
gamma_f = @(f, grad_f, dk, xk) gamma_armijo(f, grad_f, dk, xk); | |||||
elseif strcmp(mode, 'minimized') == 1 | |||||
gamma_f = @(f, grad_f, dk, xk) gamma_minimized(f, grad_f, dk, xk); | |||||
else % mode == 'fixed' | |||||
gamma_f = @(f, grad_f, dk, xk) gamma_fixed(f, grad_f, dk, xk); | |||||
end | |||||
% Storage for iterations, begin with the first point | |||||
x_vals = xk; | |||||
f_vals = f(xk); | |||||
for k = 1:max_iter | |||||
% Check for convergence | |||||
if norm(grad_f(xk)) < tol | |||||
break; | |||||
end | |||||
dk = - grad_f(xk); % Steepset descent direction | |||||
gk = gamma_f(f, grad_f, dk, xk); % Calculate gamma | |||||
x_next = xk + gk * dk; % Update step | |||||
f_next = f(x_next); | |||||
xk = x_next; % Update point | |||||
x_vals = [x_vals, x_next]; % Store values | |||||
f_vals = [f_vals, f_next]; % Store function values | |||||
end | |||||
end |
@@ -0,0 +1,50 @@ | |||||
function [x_vals, f_vals, k] = method_SteepDesc_Proj(f, grad_f, xk, sk, limmits, tol, max_iter, mode) | |||||
% f: Objective function | |||||
% grad_f: Gradient of the function | |||||
% xk: Initial point [x0; y0] | |||||
% sk: Step size (fixed positive scalar) | |||||
% limits: Bounds of the feasible set for each dimension | |||||
% tol: Tolerance for stopping criterion | |||||
% max_iter: Maximum number of iterations | |||||
% x_vals: Vector with the (x,y) values until minimum | |||||
% f_vals: Vector with f(x,y) values until minimum | |||||
% k: Number of iterations | |||||
if strcmp(mode, 'armijo') == 1 | |||||
gamma_f = @(f, grad_f, dk, xk) gamma_armijo(f, grad_f, dk, xk); | |||||
elseif strcmp(mode, 'minimized') == 1 | |||||
gamma_f = @(f, grad_f, dk, xk) gamma_minimized(f, grad_f, dk, xk); | |||||
else % mode == 'fixed' | |||||
gamma_f = @(f, grad_f, dk, xk) gamma_fixed(f, grad_f, dk, xk); | |||||
end | |||||
% Project the first point if needed | |||||
xk = ProjectionPoint(xk, limmits); | |||||
% Storage for iterations, begin with the first point | |||||
x_vals = xk; | |||||
f_vals = f(xk); | |||||
for k = 1:max_iter | |||||
% Check for convergence | |||||
if norm(grad_f(xk)) < tol | |||||
break; | |||||
end | |||||
dk = - grad_f(xk); % Steepset descent direction | |||||
% First calculate xk-bar and project it if nessesary | |||||
xkbar = xk + sk * dk; | |||||
xkbar = ProjectionPoint(xkbar, limmits); | |||||
dk = (xkbar - xk); % Steepest descent projection direction | |||||
gk = gamma_f(f, grad_f, dk, xk); % Calculate gamma | |||||
x_next = xk + gk * dk; % Update step | |||||
f_next = f(x_next); | |||||
xk = x_next; % Update point | |||||
x_vals = [x_vals, x_next]; % Store values | |||||
f_vals = [f_vals, f_next]; % Store function values | |||||
end | |||||
end |
@@ -0,0 +1,42 @@ | |||||
function plot3dFun(fun, x_lim, y_lim, size, plot_title, filename) | |||||
% 3D plots a function | |||||
% fun: The function to plot | |||||
% x_lim: The range for x axis. ex: [-2, 2] | |||||
% y_lim: The range for y axis. ex: [0, 2] | |||||
% size: The number of points for each axis | |||||
% plot_title: The latex title for the plot | |||||
% | |||||
global image_width, | |||||
global image_height; | |||||
% Generate a grid for x and y | |||||
x_space = linspace(x_lim(1), x_lim(2), size); | |||||
y_space = linspace(y_lim(1), y_lim(2), size); | |||||
[X, Y] = meshgrid(x_space, y_space); | |||||
% Evaluate the function on the grid | |||||
for i = 1:size | |||||
for j = 1:size | |||||
% Pass each [x1; x2] as input to fun | |||||
Z(i, j) = fun([X(i, j); Y(i, j)]); | |||||
end | |||||
end | |||||
% 3D plot | |||||
figure('Name', 'f(x,y)', 'NumberTitle', 'off'); | |||||
set(gcf, 'Position', [100, 100, image_width, image_height]); % Set the figure size | |||||
surf(X, Y, Z); | |||||
% Customize the plot | |||||
xlabel('x1'); % Label for x-axis | |||||
ylabel('x2'); % Label for y-axis | |||||
zlabel('f(x, y)'); % Label for z-axis | |||||
title(plot_title, 'Interpreter', 'latex', 'FontSize', 16); % Title of the plot | |||||
colorbar; | |||||
% save the figure | |||||
if strcmp(filename, '') == 0 | |||||
print(gcf, filename, '-dpng', '-r300'); | |||||
end | |||||
end |
@@ -0,0 +1,41 @@ | |||||
function plotContour(fun, x_lim, y_lim, size, plot_title, filename) | |||||
% plot the contour of a function | |||||
% fun: The function to plot | |||||
% x_lim: The range for x axis. ex: [-2, 2] | |||||
% y_lim: The range for y axis. ex: [0, 2] | |||||
% size: The number of points for each axis | |||||
% plot_title: The latex title for the plot | |||||
% | |||||
global image_width, | |||||
global image_height; | |||||
% Generate a grid for x and y | |||||
x_space = linspace(x_lim(1), x_lim(2), size); | |||||
y_space = linspace(y_lim(1), y_lim(2), size); | |||||
[X, Y] = meshgrid(x_space, y_space); | |||||
% Evaluate the function on the grid | |||||
for i = 1:size | |||||
for j = 1:size | |||||
% Pass each [x1; x2] as input to fun | |||||
Z(i, j) = fun([X(i, j); Y(i, j)]); | |||||
end | |||||
end | |||||
% Contour | |||||
figure('Name', 'Contours of f(x1,x2)', 'NumberTitle', 'off'); | |||||
set(gcf, 'Position', [100, 100, image_width, image_height]); % Set the figure size | |||||
contour(X, Y, Z); | |||||
% Customize the plot | |||||
xlabel('x1'); % Label for x-axis | |||||
ylabel('x2'); % Label for y-axis | |||||
title(plot_title, 'Interpreter', 'latex', 'FontSize', 16); % Title of the plot | |||||
colorbar; | |||||
% save the figure | |||||
if strcmp(filename, '') == 0 | |||||
print(gcf, filename, '-dpng', '-r300'); | |||||
end | |||||
end |
@@ -0,0 +1,54 @@ | |||||
function plotConvCompare(points_1, title_1, points_2, title_2, points_3, title_3, Min_point, plot_title, filename) | |||||
% 3D plots a function | |||||
% points: The points to plot | |||||
% contur_fun: The function for contour plot | |||||
% x_lim: The range for x axis. ex: [-2, 2] | |||||
% y_lim: The range for y axis. ex: [0, 2] | |||||
% size: The number of points for each axis | |||||
% plot_title: The latex title for the plot | |||||
% filename: The filename to save the plot (if exists) | |||||
% | |||||
global image_width, | |||||
global image_height; | |||||
distances_1 = sqrt((points_1(1, :) - Min_point(1)).^2 + (points_1(2, :) - Min_point(2)).^2); | |||||
distances_2 = sqrt((points_2(1, :) - Min_point(1)).^2 + (points_2(2, :) - Min_point(2)).^2); | |||||
distances_3 = sqrt((points_3(1, :) - Min_point(1)).^2 + (points_3(2, :) - Min_point(2)).^2); | |||||
% 2D plot | |||||
figure('Name', 'Convergence compare', 'NumberTitle', 'off'); | |||||
set(gcf, 'Position', [100, 100, image_width, image_height]); % Set the figure size | |||||
title(plot_title, 'Interpreter', 'latex', 'FontSize', 16); % Title of the plot | |||||
% One | |||||
subplot(3, 1, 1); | |||||
plot(distances_1, '-o'); | |||||
% Customize the plot | |||||
ylabel(title_1, 'Interpreter', 'none'); | |||||
xlabel('Step'); | |||||
grid on | |||||
% One | |||||
subplot(3, 1, 2); | |||||
plot(distances_2, '-o'); | |||||
% Customize the plot | |||||
ylabel(title_2, 'Interpreter', 'none'); | |||||
xlabel('Step'); | |||||
grid on | |||||
% One | |||||
subplot(3, 1, 3); | |||||
plot(distances_3, '-o'); | |||||
% Customize the plot | |||||
ylabel(title_3, 'Interpreter', 'none'); | |||||
xlabel('Step'); | |||||
grid on | |||||
% save the figure | |||||
if strcmp(filename, '') == 0 | |||||
print(gcf, filename, '-dpng', '-r300'); | |||||
end | |||||
end |
@@ -0,0 +1,28 @@ | |||||
function plotItersOverGamma(gamma, iterations, plot_title, filename) | |||||
% 3D plots a function | |||||
% fun: The points to plot | |||||
% contur_fun: The function for contour plot | |||||
% x_lim: The range for x axis. ex: [-2, 2] | |||||
% y_lim: The range for y axis. ex: [0, 2] | |||||
% size: The number of points for each axis | |||||
% plot_title: The latex title for the plot | |||||
% filename: The filename to save the plot (if exists) | |||||
% | |||||
global image_width, | |||||
global image_height; | |||||
figure('Name', 'Iterations_over_gamma', 'NumberTitle', 'off'); | |||||
set(gcf, 'Position', [100, 100, image_width, image_height]); % Set the figure size | |||||
plot(gamma, iterations, '*r', 'LineWidth', 2); | |||||
% Customize the plot | |||||
title(plot_title, 'Interpreter', 'latex', 'FontSize', 16); % Title of the plot | |||||
xlabel('\gamma') ; | |||||
ylabel('Iterations'); | |||||
% save the figure | |||||
if strcmp(filename, '') == 0 | |||||
print(gcf, filename, '-dpng', '-r300'); | |||||
end | |||||
end |
@@ -0,0 +1,48 @@ | |||||
function plotPointsOverContour(points, contour_fun, x_lim, y_lim, size, plot_title, filename) | |||||
% 3D plots a function | |||||
% points: The points to plot | |||||
% contur_fun: The function for contour plot | |||||
% x_lim: The range for x axis. ex: [-2, 2] | |||||
% y_lim: The range for y axis. ex: [0, 2] | |||||
% size: The number of points for each axis | |||||
% plot_title: The latex title for the plot | |||||
% filename: The filename to save the plot (if exists) | |||||
% | |||||
global image_width, | |||||
global image_height; | |||||
% Generate a grid for x and y | |||||
x_space = linspace(x_lim(1), x_lim(2), size); | |||||
y_space = linspace(y_lim(1), y_lim(2), size); | |||||
[X, Y] = meshgrid(x_space, y_space); | |||||
% Evaluate the function on the grid | |||||
for i = 1:size | |||||
for j = 1:size | |||||
% Pass each [x1; x2] as input to fun | |||||
Z(i, j) = contour_fun([X(i, j); Y(i, j)]); | |||||
end | |||||
end | |||||
% 2D plot | |||||
figure('Name', '(x1,x2) convergence', 'NumberTitle', 'off'); | |||||
set(gcf, 'Position', [100, 100, image_width, image_height]); % Set the figure size | |||||
plot(points(1, :), points(2, :), '-or'); | |||||
hold on | |||||
contour(X, Y, Z); | |||||
% Customize the plot | |||||
xlim(x_lim); | |||||
ylim(y_lim); | |||||
xlabel('x1'); % Label for x-axis | |||||
ylabel('x2'); % Label for y-axis | |||||
grid on | |||||
title(plot_title, 'Interpreter', 'latex', 'FontSize', 16); % Title of the plot | |||||
colorbar; | |||||
% save the figure | |||||
if strcmp(filename, '') == 0 | |||||
print(gcf, filename, '-dpng', '-r300'); | |||||
end | |||||
end |