function rankonemulttiming
% Measurement of runtimes for different ways of multiplying a vector with a
% matrix of the form $\Va\cdot\Vb^T$, where $\Va$ and $\Vb$ are column
% vectors, a so-called tensor product matrix. 
N = 1000;                     % Maximal size of vectors
a = rand(N,1); b = rand(N,1); % Initialize random column vectors of length $N$
v = rand(N,1);

res = []; % matrix for recording times
% conduct timings for vectors of different size $n$
for n=10:10:N 
    t1 = realmax; for j=1:3, tic; w1 = rankonemultslow(a(1:n),b(1:n),v(1:n)); t1 = min(toc,t1); end
    t2 = realmax; for j=1:3, tic; w2 = rankonemultfast(a(1:n),b(1:n),v(1:n)); t2 = min(toc,t2); end
    norm(w1-w2), % Check for agreement of results
    res = [res; n, t1, t2];
end

% Create plots of runtimes. 
figure; 
plot(res(:,1),res(:,2),'b+',res(:,1),res(:,3),'r.');
xlabel('{\bf vector length n}','fontsize',14);
ylabel('{\bf runtime [s]}','fontsize',14);
title('runtime measurements for multiplication with tensor product matrix');
legend('(a*b^T)*v','a*(b^T*v)','location','best');
 
% print -depsc2 '../../LANMFigures/rankonemulttiming.eps'; 
end

% The following two functions perform algebraically equivalent operations,
% however at vastly different computationl cost. Note the different order of
% multiplications implied by the positions of the brackets.

function  w = rankonemultslow(a,b,v), w = a*b'*v; end
function  w = rankonemultfast(a,b,v), w = a*(b'*v); end



