clearvars;
close all;
clc;

%% Definitions
s(:,1) = [1 -1 -1 -1]'; % s1
s(:,2) = [-2 2 0 2]'; % s2
s(:,3) = [1 -1 1 -1]'; % s3
s(:,4) = [-2 -2 -2 -2]'; %s4
M = size(s,1);

%% a
sorting = [3 4 2 1]; %decides in which order the Gram-Schmidt procedure is performed

psi = []; % basis vectors
for i = 1:M % for all M signals
  s_hat = zeros(M,1); % projection
  for j = 1:size(psi,2) % for all current basis vectors
    s_hat = s_hat + s(:,sorting(i))'*psi(:,j) * psi(:,j); % projection onto one basis vector
  end
  e = s(:,sorting(i))-s_hat; % projection error
  if norm(e)>10*eps % numerical issues ( in general: norm(e) > 0 )
    psi = [psi, e/norm(e)]; % add new basis vector to psi
  end
end
fprintf('Basis vectors:\n'); 
disp(psi); % of course these depend on the order of the signal vectors used for Gram Schmidt (see sorting)

%% b
N = size(psi,2);
fprintf('\nDimensionality of S=span(s1, s2, s3, s4) is %d\n\n',N);

%% c
p = zeros(N, M);
for i = 1:M
  for j = 1:N
    p(j,i) = s(:,i)'*psi(:,j);
  end
end

fprintf('Vectorial representation:\n');
disp(p)
