function [x, error]=Gaussian_Elimination(A,b)

% Function that solves a system of lineal equations Ax=b via Gaussian
% Elimination with regressive substitution and Partial Pivoting
%
% Input Data:
%               A: Matrix nxn of coefficients
%               b: Column Vector nx1 
%
% Output Data:
%               x: Column Vector nx1 of unknowns
%               error: norm of the difference between numerical
%                      and analytical solution
%

[m,n] = size (A);
% generates vector b by suming all row members of matrix A
for i=1:n
    bt(i,1)=sum(A(i,:));
end
% error if matrix A is non-square
if m~=n
    error('Matrix A is non-square')
    return 
end

% combine A and b into the augmented system
Ab = [A b];
Abt = [A bt];
% loop for Gaussian elimination with partial pivoting
for i=1:n-1
   % selection of the best pivot for the Gaussian elimination
    [value,l] = max(abs(Ab(i:n,i)));
    q = l + i - 1;
    if q~=i
        Ab([i q],:) = Ab([q i],:);
        Abt([i q],:) = Abt([q i],:);
    end
    % continue with Gaussian elimination
    for k=i+1:n
        m(k,i)=(Ab(k,i)/Ab(i,i));
        mt(k,i)=(Abt(k,i)/Abt(i,i));
        for j=i:n+1
            Ab(k,j) = Ab(k,j) - m(k,i)*Ab(i,j);
            Abt(k,j) = Abt(k,j) - mt(k,i)*Abt(i,j);
        end
    end
end

% commence regressive substitution to obtain our solution vector x
x(n) = Ab(n, n+1)/Ab(n,n);
xt(n) = Abt(n, n+1)/Abt(n,n);
for i=n-1:-1:1
    x(i) = (Ab(i,n+1) - Ab(i,i+1)*x(i+1))/Ab(i,i);
    xt(i) = (Abt(i,n+1) - Abt(i,i+1)*xt(i+1))/Abt(i,i);
end

% transposes row vector solution to column vector solution
x = x';
xt = xt';

% checks the accuracy of our solution by computing the norm of the
% difference of the the approximated and exact solution.
x_exact = ones(n,1);
for i=1:n
    y(i)=(xt(i)-x_exact(i))^2;
end
error = sqrt(sum(y));

% display resuls
%disp(['The approximation error is ',num2str(error),', and the solution vector x is:']);
x;