% Metoda potęgowa dla zadania własnego _____________________________

% Wyznacza najbliższą wartość własną macierzy kwadratowej w stosunku do
% podanego lambda_shift.
%
% Argumenty:
%     A: macierz kwadratowa.
%     x: wektor początkowy.
%     tol: dokłandość obliczeń.
%     lambda_shift: przesunięcie (wstępna lokalizacja pośredniej wartości własnej). 
% ____________________________________________________________


% Wczytanie argumentów _________________________________________
clc; clear
%A = [[1, 2, 0]; [2, 1, 1]; [0, 1, 0];];
%A = [6 5 -5; 2 6 -2; 2 5 -1];
%A = [3 0 0; -4 6 2; 16 -15 -5];
%A = [4 1 0; 1 4 1; 0 1 4];
%A = [5 4 3; -1 0 -3; 1 -2 1]; % dwukrotna wartość własna 4.
A = [2 1 0; 1 2 1; 0 1 2];
x = [7;-1;0];

%A = [10 -2 3 2 0; -2 10 -3 4 5; 3 -3 6 3 3; 2 4 3 6 6; 0 5 3 6 13];
%x = [1;2;3;4;5];

tol = 10^(-8);

iter = 0;
lambda = 0;

A_pierwotna = A; % zapisanie piewotnej macierzy A;

lambda_shift = 2.3; % przesunicie.
A = A - lambda_shift*eye(length(x));

A = A\eye(length(x)); % utworzenie macierzy odwrotnej.

while tol < norm(A*x-lambda*x)
    y = A*x;
    iter = iter +1;
    %lambda = dot(x,y)/dot(x,x);
    lambda = y(2)/x(2);,
    x = y;
    x = x/norm(x);
   
end

disp(lambda);
A = A_pierwotna; % powrót do pierwotnej macierzy A.
lambda = 1 / lambda; % obliczenie najmniejszej wartości własnej.
lambda = lambda + lambda_shift; % wycofanie przesunięcia.
disp('Norma macierzy:');
disp(norm(A*x-lambda*x));
disp('Liczba iteracji:')
disp(iter);
disp('Najbliższa wartość własna:')
disp(lambda);
disp('Odpowiadający jej wektor własny:');
disp(x);