warning off MATLAB:nearlySingularMatrix

% Esercizio 3.1 :
%
% Vogliamo confrontare il metodo di Gram-Schmidt classico (CGS), con quello modificato (MGS). Sapendo che le differenze 
% dal punto di vista numerico risultano evidenti quando il condizionamento di A è elevato, provare entrambi gli algoritmi 
% nei casi di fattorizzazione QR di una matrice A ben-condizionata ed una mal-condizionata.
%
% Per costruire una matrice con un ben preciso numero di condizionamento si può, ad esempio, sfruttare il fatto che 
% il numero di condizionamento è pari al rapporto tra il massimo ed il minimo valore singolare della matrice. Allora, 
% costruendo la matrice dalla sua SVD, si ha:
% [U,X] = qr(randn([100,1]));
% [V,X] = qr(randn(100));
% S = diag(2.^(-1:-1:-100));
% A = U*S*V';
% Ovviamente, dalla scelta di S dipende il numero di condizionamento di A.
%
% Nota: i valori diagonali di R sono legati in modo quasi proporzionale ai valori singolari. Quindi, nell'esercizio proposto,
%       ci si deve aspettare, al crescere dell'indice colonna "i", di trovare valori sempre più piccoli di R(i,i) , fino 
%       ad arrivare vicino alla precisione di macchina. In verità, ciò accade per MGS, mentre l'errore di arrotondamento 
%       impedisce a CGS di calcolare valori inferiori a 10^(-8).



% Esercizio 3.2 :
%
% Quando A è vicina ad essere singolare, il metodo MGS può produrre vettori q(:,j) che non sono ortogonali fra loro. 
% In tal caso è meglio utilizzare trasformazioni ortogonali, come Householder. 
%
% Generare una matrice A dalla sua SVD in modo che sia prossima alla singolarità (cioè abbia almeno 
% un valore singolare molto piccolo) e calcolarne la fattorizzazione QR con l'algoritmo MGS e con le trasformazioni di Householder.
% Verificarne quindi l'ortogonalità delle matrici Q così calcolate:
% norm(Q'*Q - eye(size(A,1)));

