This repository has been archived on 2024-10-22. You can view files and clone it, but cannot push or open issues or pull requests.
OM/Claudio_Maggioni_2/main.m
Claudio Maggioni (maggicl) 421192b7e5 hw3: done all but 1.5 and 2.5
2021-04-22 16:39:35 +02:00

137 lines
3.4 KiB
Matlab

0%% Homework 2 - Optimization Methods
% Author: Claudio Maggioni
%
% Note: exercises are not in the right order due to matlab constraints of
% functions inside of scripts.
clear
clc
close all
plots = 1;
%% 1.4 - Solution for 1D Poisson for N=1000 using CG
n = 1000;
[A, b] = build_poisson(n);
A(2, 1) = 0;
A(n-1, n) = 0;
[x, ys, gnorms] = CGSolve(A, b, zeros(n,1), n, 1e-8);
display(x);
%% 1.5 - Plots for the 1D Poisson solution
if plots
plot(0:(size(ys,1)-1), ys);
sgtitle("Objective function values per iteration");
axis([-1 500 -inf +inf]);
%matlab2tikz('showInfo', false, './obvalues.tex');
figure;
semilogy(0:(size(gnorms,1)-1), gnorms);
sgtitle("Log of gradient norm per iteration");
axis([-1 500 -inf +inf]);
%matlab2tikz('showInfo', false, './gnorms.tex');
end
%% 2.1 - Matrix definitions
A1 = diag([1:10]);
A2 = diag(ones(1,10));
A3 = diag([1, 1, 1, 3, 4, 5, 5, 5, 10, 10]);
A4 = diag([1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0]);
%% 2.2 - Application of CG for each AX/b couple
rng(0); % random seed fixed due to reproducibility purposes
b = rand(10,1);
display(b);
n = 10;
[x1, ys1, gnorms1, xs1] = CGSolve(A1, b, zeros(n,1), n, 1e-8);
[x2, ys2, gnorms2, xs2] = CGSolve(A2, b, zeros(n,1), n, 1e-8);
[x3, ys3, gnorms3, xs3] = CGSolve(A3, b, zeros(n,1), n, 1e-8);
[x4, ys4, gnorms4, xs4] = CGSolve(A4, b, zeros(n,1), n, 1e-8);
%% 2.3 - Logarithm energy norm of the error computation
if plots
enl_plot(x1, xs1, A1);
sgtitle("Log energy norm of the error per iter. (matrix A1)");
%matlab2tikz('showInfo', false, './a1.tex');
enl_plot(x2, xs2, A2);
sgtitle("Log energy norm of the error per iter. (matrix A2)");
%matlab2tikz('showInfo', false, './a2.tex');
enl_plot(x3, xs3, A3)
sgtitle("Log energy norm of the error per iter. (matrix A3)");
%matlab2tikz('showInfo', false, './a3.tex');
enl_plot(x4, xs4, A4);
sgtitle("Log energy norm of the error per iter. (matrix A4)");
%matlab2tikz('showInfo', false, './a4.tex');
end
function enl_plot(xsol, xs, A)
enls = zeros(size(xs, 2), 1);
for i = 1:size(xs, 2)
x = xs(:, i);
enls(i) = log((xsol - x)' * A * (xsol - x));
end
figure;
plot(0:(size(xs, 2)-1), enls, '-k.');
axis([-1 11 -35 +2]);
end
%% 1.1 - Build the Poisson matrix A and vector b
function [A,b] = build_poisson(n)
A = diag(2 * ones(1,n));
A(1,1) = 1;
A(n,n) = 1;
for i = 2:n-1
A(i, i+1) = -1;
A(i, i-1) = -1;
end
h = 1 / (n - 1);
b = h^2 * ones(n, 1);
b(1) = 0;
b(n) = 0;
end
%% 1.3 - Implementation of Conjugate Gradient
function [x, ys, gnorms, xs] = CGSolve(A, b, x, max_itr, tol)
ys = zeros(max_itr + 1, 1);
gnorms = zeros(max_itr + 1, 1);
xs = zeros(size(x, 1), max_itr + 1);
r = A * x - b;
p = -r;
gnorms(1) = norm(p, 2);
xs(:, 1) = x;
ys(1) = 1/2 * dot(A*x, x) - dot(b, x);
for i = 1:(max_itr+1)
alpha = -r' * p / (p' * A * p);
x = x + alpha * p;
r = A * x - b;
beta = (r' * A * p) / (p' * A * p);
p = -r + beta * p;
gnorms(i+1) = norm(p, 2);
xs(:, i+1) = x;
ys(i+1) = 1/2 * dot(A*x, x) - dot(b, x);
if gnorms(i+1) < tol
ys = ys(1:(i+1));
gnorms = gnorms(1:(i+1));
xs = xs(:, 1:(i+1));
break
end
end
end