%% SUPER-EFFICIENT HOUSEHOLDER

% Store Householder vectors in A

% There is *almost* space to store each v in the zeroed entried of A.
% One way (there are others) we can make space by scaling v so that 
% its first nonzero entry is the same as A(k,k).

%% Setup

clc

t = (-1:.5:1)';
A = [1+0*t t t.^2];
b = [1 .5 0 .5 2]';

A = [4 0 -4 2 ; -10 6 2 3]';
b = ones(4,1);

[m, n] = size(A);

A_orig = A;
I = eye(m,n);

%% Solve
for k = 1:n
    a = [zeros(k-1,1) ; A(k:end,k)];
    v = a + sign(a(k))*norm(a,2)*I(:,k)
    H = eye(m) - 2*v*v'/(v'*v)
    Akk = A(k,k) - 2*v(k)*(v'*A(:,k))/(v'*v);
    v = v/v(k)*Akk;         % Set v_k(k) = A(k,k)
    A(k:end,k) = v(k:end);  % Store v_k in lower part of A
    A(:,k+1:end) = A(:,k+1:end) - 2*v*(v'*A(:,k+1:end))/(v'*v)
    b = b - 2*v*(v'*b)/(v'*v);
    error
end
R = triu(A(1:n,1:n));
x = R\b(1:n) 

A

%% Recover QR

Q = eye(m,n);
for k = n:-1:1
    v = [zeros(k-1,1) ; A(k:end,k)];
    Q = Q - 2*v*(v'*Q)/(v'*v);
end

Q*R - A_orig
    