function theLastPairwiseDistanceComputationComparisonYoullEverNeed()
Funcs = {@matheburgMatrixMultiplication, ...
@DivakarVectorizedVariation1, ...
@DivakarVectorizedVariation2, ...
@pdist2, ...
@statinferbsxfun, ...
@Jonasndgrid};
ns = 2.^(1:11);
dims = [2,3;50,200].';
for i = 1:numel(dims)
d = dims(i);
subplot(size(dims,2), size(dims,1), i);
paramGenerators = arrayfun(@(n) @(){rand(n,d), rand(n,d)}, ns,'uni',0);
times = compareFunctions(Funcs, paramGenerators);
loglog(ns, times.');
legend(cellfun(@func2str,Funcs,'uni',0),'Location','NorthWest','Interpreter','none');
drawnow;
end
end
function times = compareFunctions(Funcs, paramGenerators)
times = [];
for i = 1:numel(paramGenerators)
for j = 1:numel(Funcs)
Params = feval(paramGenerators{i});
times(end+1) = timeit(@()feval(Funcs{j},Params{:}));
end
end
times = reshape(times,length(Funcs),[]);
end
%% // #################################
%% // HERE COME ALL THE FANCY FUNCTIONS
%% // #################################
function distMat = matheburgMatrixMultiplication(A,B)
numA = size(A,1);
numB = size(B,1);
d = size(A,2);
helpA = zeros(numA,3*d);
helpB = zeros(numB,3*d);
for idx = 1:d
helpA(:,3*idx-2:3*idx) = [ones(numA,1), -2*A(:,idx), A(:,idx).^2 ];
helpB(:,3*idx-2:3*idx) = [B(:,idx).^2 , B(:,idx), ones(numB,1)];
end
distMat
= sqrt(helpA
* helpB
');end
%%
function distMat = DivakarVectorizedVariation1(A,B)
[nA,dim] = size(A);
nB = size(B,1);
A_ext = ones(nA,dim*3);
A_ext(:,2:3:end) = -2*A;
A_ext(:,3:3:end) = A.^2;
B_ext = ones(nB,dim*3);
B_ext(:,1:3:end) = B.^2;
B_ext(:,2:3:end) = B;
distMat = sqrt(A_ext * B_ext.');
end
%%
function distMat = DivakarVectorizedVariation2(A,B)
[nA,dim] = size(A);
nB = size(B,1);
A_ext = [ones(nA*dim,1) -2*A(:) A(:).^2];
B_ext = [B(:).^2 B(:) ones(nB*dim,1)];
A_ext = reshape(permute(reshape(A_ext,nA,dim,[]),[1 3 2]),nA,[]);
B_ext = reshape(permute(reshape(B_ext,nB,dim,[]),[1 3 2]),nB,[]);
distMat
= sqrt(A_ext
* B_ext.
');end
%%
function distMat = statinferbsxfun(A,B)
distMat = sqrt(bsxfun(@plus,dot(A,A,2),dot(B,B,2)')-2*(A*B'));
end
%%
function distMat = Jonasndgrid(A,B)
n = size(A,1);
m = size(B,1);
[idxA,idxB] = ndgrid(1:n,1:m);
distMat = zeros(n,m);
distMat(:) = sqrt(sum((A(idxA,:) - B(idxB,:)).^2,2));
end
ZnVuY3Rpb24gdGhlTGFzdFBhaXJ3aXNlRGlzdGFuY2VDb21wdXRhdGlvbkNvbXBhcmlzb25Zb3VsbEV2ZXJOZWVkKCkKRnVuY3MgPSAge0BtYXRoZWJ1cmdNYXRyaXhNdWx0aXBsaWNhdGlvbiwgLi4uCiAgICAgICAgICBARGl2YWthclZlY3Rvcml6ZWRWYXJpYXRpb24xLCAuLi4KICAgICAgICAgIEBEaXZha2FyVmVjdG9yaXplZFZhcmlhdGlvbjIsIC4uLgogICAgICAgICAgQHBkaXN0MiwgLi4uCiAgICAgICAgICBAc3RhdGluZmVyYnN4ZnVuLCAuLi4KICAgICAgICAgIEBKb25hc25kZ3JpZH07CiAgICAKbnMgPSAyLl4oMToxMSk7CmRpbXMgPSBbMiwzOzUwLDIwMF0uJzsKZm9yIGkgPSAxOm51bWVsKGRpbXMpIAogICAgZCA9IGRpbXMoaSk7CiAgICBzdWJwbG90KHNpemUoZGltcywyKSwgc2l6ZShkaW1zLDEpLCBpKTsKICAgIHBhcmFtR2VuZXJhdG9ycyA9IGFycmF5ZnVuKEAobikgQCgpe3JhbmQobixkKSwgcmFuZChuLGQpfSwgbnMsJ3VuaScsMCk7CiAgICB0aW1lcyA9IGNvbXBhcmVGdW5jdGlvbnMoRnVuY3MsIHBhcmFtR2VuZXJhdG9ycyk7CiAgICBsb2dsb2cobnMsIHRpbWVzLicpOwogICAgbGVnZW5kKGNlbGxmdW4oQGZ1bmMyc3RyLEZ1bmNzLCd1bmknLDApLCdMb2NhdGlvbicsJ05vcnRoV2VzdCcsJ0ludGVycHJldGVyJywnbm9uZScpOwogICAgdGl0bGUoc3ByaW50ZignRElNID0gJWQnLGQpKTsKICAgIGRyYXdub3c7CmVuZAplbmQKCmZ1bmN0aW9uIHRpbWVzID0gY29tcGFyZUZ1bmN0aW9ucyhGdW5jcywgcGFyYW1HZW5lcmF0b3JzKQp0aW1lcyA9IFtdOwpmb3IgaSA9IDE6bnVtZWwocGFyYW1HZW5lcmF0b3JzKQogICAgZm9yIGogPSAxOm51bWVsKEZ1bmNzKQogICAgICAgIFBhcmFtcyA9IGZldmFsKHBhcmFtR2VuZXJhdG9yc3tpfSk7CiAgICAgICAgdGltZXMoZW5kKzEpID0gdGltZWl0KEAoKWZldmFsKEZ1bmNze2p9LFBhcmFtc3s6fSkpOwogICAgZW5kCmVuZAp0aW1lcyA9IHJlc2hhcGUodGltZXMsbGVuZ3RoKEZ1bmNzKSxbXSk7CmVuZAolJSAvLyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKJSUgLy8gSEVSRSBDT01FIEFMTCBUSEUgRkFOQ1kgRlVOQ1RJT05TCiUlIC8vICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwpmdW5jdGlvbiBkaXN0TWF0ID0gbWF0aGVidXJnTWF0cml4TXVsdGlwbGljYXRpb24oQSxCKQpudW1BID0gc2l6ZShBLDEpOwpudW1CID0gc2l6ZShCLDEpOwpkID0gc2l6ZShBLDIpOwpoZWxwQSA9IHplcm9zKG51bUEsMypkKTsKaGVscEIgPSB6ZXJvcyhudW1CLDMqZCk7CmZvciBpZHggPSAxOmQKICAgIGhlbHBBKDosMyppZHgtMjozKmlkeCkgPSBbb25lcyhudW1BLDEpLCAtMipBKDosaWR4KSwgQSg6LGlkeCkuXjIgXTsKICAgIGhlbHBCKDosMyppZHgtMjozKmlkeCkgPSBbQig6LGlkeCkuXjIgLCAgICBCKDosaWR4KSwgb25lcyhudW1CLDEpXTsKZW5kCmRpc3RNYXQgPSBzcXJ0KGhlbHBBICogaGVscEInKTsKZW5kCiUlCmZ1bmN0aW9uIGRpc3RNYXQgPSBEaXZha2FyVmVjdG9yaXplZFZhcmlhdGlvbjEoQSxCKQpbbkEsZGltXSA9IHNpemUoQSk7Cm5CID0gc2l6ZShCLDEpOwoKQV9leHQgPSBvbmVzKG5BLGRpbSozKTsKQV9leHQoOiwyOjM6ZW5kKSA9IC0yKkE7CkFfZXh0KDosMzozOmVuZCkgPSBBLl4yOwoKQl9leHQgPSBvbmVzKG5CLGRpbSozKTsKQl9leHQoOiwxOjM6ZW5kKSA9IEIuXjI7CkJfZXh0KDosMjozOmVuZCkgPSBCOwoKZGlzdE1hdCA9IHNxcnQoQV9leHQgKiBCX2V4dC4nKTsKZW5kCiUlCmZ1bmN0aW9uIGRpc3RNYXQgPSBEaXZha2FyVmVjdG9yaXplZFZhcmlhdGlvbjIoQSxCKQpbbkEsZGltXSA9IHNpemUoQSk7Cm5CID0gc2l6ZShCLDEpOwoKQV9leHQgPSBbb25lcyhuQSpkaW0sMSkgLTIqQSg6KSBBKDopLl4yXTsKQl9leHQgPSBbQig6KS5eMiBCKDopIG9uZXMobkIqZGltLDEpXTsKCkFfZXh0ID0gcmVzaGFwZShwZXJtdXRlKHJlc2hhcGUoQV9leHQsbkEsZGltLFtdKSxbMSAzIDJdKSxuQSxbXSk7CkJfZXh0ID0gcmVzaGFwZShwZXJtdXRlKHJlc2hhcGUoQl9leHQsbkIsZGltLFtdKSxbMSAzIDJdKSxuQixbXSk7CgpkaXN0TWF0ID0gc3FydChBX2V4dCAqIEJfZXh0LicpOwplbmQKJSUKZnVuY3Rpb24gZGlzdE1hdCA9IHN0YXRpbmZlcmJzeGZ1bihBLEIpCmRpc3RNYXQgPSBzcXJ0KGJzeGZ1bihAcGx1cyxkb3QoQSxBLDIpLGRvdChCLEIsMiknKS0yKihBKkInKSk7CmVuZAolJQpmdW5jdGlvbiBkaXN0TWF0ID0gSm9uYXNuZGdyaWQoQSxCKQpuID0gc2l6ZShBLDEpOwptID0gc2l6ZShCLDEpOwpbaWR4QSxpZHhCXSA9IG5kZ3JpZCgxOm4sMTptKTsKZGlzdE1hdCA9IHplcm9zKG4sbSk7CmRpc3RNYXQoOikgPSBzcXJ0KHN1bSgoQShpZHhBLDopIC0gQihpZHhCLDopKS5eMiwyKSk7CmVuZA==