Calculate function over all column permutations

I have this code:

abs(mean(exp(1i*( a(:,1) - a(:,2) ))))

      

where a

is a double 550 by 129 matrix. How do I write the code using this code to replace a(:,1)

with a(:,2)

and then a(:,3)

etc., because I need every column to subtract from every other column?

+3


source to share


4 answers


Another method using matrix multiplication:

E = exp(1i*a);
result = abs(E.'*(1./E)/size(E,1));

      

Explanation:

You can rewrite the expression

exp(1i*( a - b) ))

      

as

exp(1i*a)/exp(1i*b)

      



So

exp(1i*a)*(1/exp(1i*b))

      

and mean(x)

sum(x)/n

Using this, you can accomplish your task using very fast matrix multiplication.

Comparison result between different methods in Octave:

Matrix Multiplication:
Elapsed time is 0.0133181 seconds.

BSXFUN:
Elapsed time is 1.33882 seconds.

REPMAT:
Elapsed time is 1.43535 seconds.

FOR LOOP:
Elapsed time is 3.10798 seconds.

      

Here is the code for comparing different methods.

+6


source


Looped is a simple trick; let the outer loop run on all indices as well as the inner loop.



a = rand(550,129);
out = zeros(size(a,2),size(a,2));
for ii = 1:size(a,2)
    for jj = 1:size(a,2)
        out(ii,jj) = abs(mean(exp(1i*(a(:,ii)-a(:,jj)))));
    end
end

      

+3


source


No loops, one line:

result = permute(abs(mean(exp(1i*bsxfun(@minus, a, permute(a, [1 3 2]))),1)), [2 3 1]);

      

This computes all line difference pairs as a 3D array, where the second and third dimensions refer to the two row indices in the original 2D arrays; then applies the required operations on the first dimension; and finally rearranges the dimensions to get the 2D array result.

+3


source


a little off topic, but you can do it with indexing too

a = rand(550,129);
c = repmat(1:size(a,2),1,size(a,2));
c(2,:) = imresize(1:size(a,2), [1 length(c)], 'nearest');
out = abs(mean(exp(1i*( a(:,c(1,:)) - a(:,c(2,:)) ))));
out = reshape(out,[size(a,2) size(a,2)]); % 129x129 format

      

+2


source







All Articles