Calculate double sum in matlab efficiently?

I am looking for the best way to program this summation factor. As input, I have two vectors v_mnand x_mnwith elements (M*N)x1.

The relation has the form:

formula

A vector x_mnis a vector 0-1, therefore, when x_mn=1, the walkie-talkie is rgiven above and when is the x_mn=0ratio 0.

Vector v_mnis a vector containing real numbers.

I used the denominator, but it takes many times.

function r_ij = denominator(v_mn, M, N, i, j)
%here x_ij=1, to get r_ij.
S = [];
for m = 1:M
  for n = 1:N
    if (m ~= i)
      if (n ~= j)
        S = [S v_mn(i, n)];
      else
        S = [S 0];
      end
    else
      S = [S 0];
    end
  end
end
r_ij = 1+S;
end

Can you give a good way to do this in Matlab. You can ignore the ratio and give me a denominator that is more complex.

EDIT: , . i j - 1..M 1..N . , r - (M*N). i j. , x_ij=1. , v_mn , .

+4
4

S-. ,

S = zeros(m*n, 1) 

. , :

if (m ~= i)
   if (n ~= j)
      S(m*M + n) = v_mn(i, n);

, , , .

, mex, c/++, matlab.

http://www.mathworks.com.au/help/matlab/matlab_external/introducing-mex-files.html

+3

, /.

m n, /:

clc

%# some arbitrary test parameters
M = 250;
N = 1000;
v = rand(M,N);   %# (you call it v_mn)
x = rand(M,N);   %# (you call it x_mn)

m0 = randi(M,1); %# m of interest
n0 = randi(N,1); %# n of interest 


%# "Naive" version
tic
S1 = 0;
for mm = 1:M %# (you call this m')
    if mm == m0, continue; end
    for nn = 1:N %# (you call this n')
        if nn == n0, continue; end
        S1 = S1 + v(m0,nn) * x(mm,nn);
    end
end
r1 = v(m0,n0)*x(m0,n0) / (1+S1);
toc


%# MATLAB version: use matrix multiplication!
tic

ninds = [1:m0-1 m0+1:M];
minds = [1:n0-1 n0+1:N];
S2 = sum( x(minds, ninds) * v(m0, ninds).' );
r2 = v(m0,n0)*x(m0,n0) / (1+S2);

toc


%# Test if values are equal
abs(r1-r2) < 1e-12

:

Elapsed time is 0.327004 seconds.   %# loop-version
Elapsed time is 0.002455 seconds.   %# version with matrix multiplication
ans =  
     1                              %# and yes, both are equal

, ~ 133 ×

, m n. m n, () :

r = zeros(M,N);
for m0 = 1:M   
    xx = x([1:m0-1 m0+1:M], :);
    vv = v(m0,:).';
    for n0 = 1:N
        ninds    = [1:n0-1 n0+1:N];        
        denom    = 1 + sum( xx(:,ninds) * vv(ninds) );
        r(m0,n0) = v(m0,n0)*x(m0,n0)/denom;        
    end
end

~ 15 M = 250, N= 1000 (R2010a).

: , , :

denom = zeros(M,N);
for mm = 1:M    
    xx = x([1:mm-1 mm+1:M],:);
    denom(mm,:) = sum( xx*v(mm,:).' ) - sum( bsxfun(@times, xx, v(mm,:)) );    
end
denom = denom + 1;

r_mn = x.*v./denom;

1 N = 250 M = 1000:)

+5

, , , , , . , S . , V X, , ( , X , ).

- ( i, j m, n, ):

function result = denominator(V,X,m,n)

% use the size of V to determine M and N
[M,N] = size(V);

% initialize the summed value to one (to account for one at the end)
result = 1;

% outer loop
for i=1:M
    % ignore the case where m==i
    if i~=m
        for j=1:N
            % ignore the case where n==j
            if j~=n
                result = result + V(m,j)*X(i,j);
            end
         end
     end
 end

, if for, j. , !

+3

Matlab, . , ". ^" ". *" , Matlab , , , .

, . -, m- $V_ {nm} $, .

, , , - $X_ {nm} $ , . n. , .

function result = denominator_vectorized(V,X,m,n)

% get the part of V with the first index m
Vm = V(m,:)';
% remove the parts of X you don't want to iterate over. Note that, since I
% am inside the function, I am only editing the value of X within the scope
% of this function.
X(m,:) = 0;
X(:,n) = 0;

%do the matrix multiplication and the summation at once
result = 1-sum(X*Vm);

, , , :

function result = denominator(V,X,m,n)

% use the size of V to determine M and N
[M,N] = size(V);

% initialize the summed value to one (to account for one at the end)
result = 1;

% outer loop
for i=1:M
% ignore the case where m==i
if i~=m
    for j=1:N
        % ignore the case where n==j
        if j~=n
            result = result + V(m,j)*X(i,j);
        end
     end
 end
end

:

V=rand(10000,10000);
X=rand(10000,10000);
disp('looped version')
tic
denominator(V,X,1,1)
toc
disp('matrix operation')
tic
denominator_vectorized(V,X,1,1)
toc

:

looped version

ans =

   2.5197e+07

Elapsed time is 4.648021 seconds.
matrix operation

ans =

   2.5197e+07

Elapsed time is 0.563072 seconds.

. . Parallel Computing Toolbox ​​ CUDA, Matlab - !

EDIT: The last bit is not quite right. You still need to take a few steps to perform operations with CUDA equipment, but not many. See Matlab Documentation.

+3
source

Source: https://habr.com/ru/post/1544822/


All Articles