ACuriousMind
ACuriousMind

Reputation: 15

Vectorization of nested loops and if statements in MATLAB

I am fairly new to the concept of vectorization in MATLAB so please excuse my naivety in this regard. I was trying to vectorize the following MATLAB code which includes if statements within nested for loops:

h = zeros(dimV);
for a = 1 : dimV
    for b = 1 : dimV

        if a ~= b && C(a,b) == 1
           h(a,b) = C(a,b)*exp(-1i*A(a,b)*L(a,b))*(sin(k*L(a,b)))^-1;

        else if a == b

                for m = 1 : dimV
                    if m ~= a && C(a,m) == 1
                       h(a,b) = h(a,b) - C(a,m)*cot(k*L(a,m));
                    end
                end
            end

        end
    end
end

Here the variable dimV specifies the size of the matrix h and is fairly large, of the order of 100, and C is a symmetric square matrix (previously defined) of size dimV all of whose off-diagonal elements are either 0 or 1 and the diagonal elements are necesarrily 0. The elements of matrix L are also zero in the same positions as the zeros of the matrix C. Following the vectorization techniques that I found on this website and here, I was able to vectorize the code, albeit partially, and my MWE is as follows:

h = zeros(dimV);

idx = (C  == 1);
h(idx) = C(idx).*exp(-1i*A(idx).*L(idx)).*(sin(k*L(idx))).^-1;

for a = 1:dimV;   

    m = 1 : dimV;
    m = m(C(a,:) == 1);
    h(a,a) = - sum (C(a,m).*cot(k*L(a,m)));

end

My main problem is in converting the for loop in the variable a to a vector as I need the individual values of a to address the diagonal elements of h. I compared the evaluation time of both the code blocks using the MATLAB profiler and the latter version is only marginally faster and the improvement in efficiency is really insignificant. In fact the profiler showed that the line allocating the values to h(a,a) takes up nearly 50% of the execution time in the second case. So I was wondering if there is a more elegant way to rewrite the above code using the appropriate vectorization schemes, which would help improve its efficiency. I am really in a bit of bother about this and any I would be greatly appreciative of any help in this regard. Thank you so much.

Upvotes: 1

Views: 403

Answers (1)

Divakar
Divakar

Reputation: 221624

Vectorized Code -

diag_ind = 1:dimV+1:numel(C);
C_neq1 = C~=1;

parte1_2 = (sin(k.*L)).^-1;
parte1_2(C_neq1 & (L==0))=0;
parte1 = exp(-1i.*A.*L).*parte1_2;
parte1(C_neq1)=0;

h = parte1;

parte2 = cot(k*L);
parte2(C_neq1)=0;
parte2(diag_ind)=0;
h(diag_ind) = - sum(parte2,2);

Upvotes: 0

Related Questions