Question about assigning value in a matrix.
Afficher commentaires plus anciens
Hi, all, again, I want to do the work quickly: I have a large matrix A, and I want to assign value in some entry in each row.
For example:
A=zeros(4);
a=[1,2;
2,3;
3,2;
4,1];
I want (1,2), (2,3),(3,2), (4,1) of matrix A be 1. How shall I make it work in no more than 3 commands?
What I am doing now is using loops:
for i=1:4
A(a(i,1),a(i,2)=1;
end
However, as i is very large like 3^14, the program is very slow. So I wonder is there a way to speed the programming?
Thanks.
Réponse acceptée
Plus de réponses (2)
Azzi Abdelmalek
le 6 Juin 2013
A=zeros(4);
a=[1,2;
2,3;
3,2;
4,1];
idx= sub2ind(size(A),a(:,1),a(:,2));
A(idx)=1
1 commentaire
C Zeng
le 6 Juin 2013
Sean de Wolski
le 6 Juin 2013
0 votes
I've always found for-loops to be significantly faster than sub2ind and ind2sub. Especially as the number of indices gets large.
It's been a few years since I was timing it for my own work though...
12 commentaires
C Zeng
le 6 Juin 2013
Azzi Abdelmalek
le 6 Juin 2013
The for loop, in this case, is almost twice faster
Sean de Wolski
le 6 Juin 2013
Modifié(e) : Sean de Wolski
le 6 Juin 2013
function testFORIND2SUB
n = 1000;
idx = ceil(rand(n,2)*n); %two dimensions
[t1,t2] = deal(0);
for ii = 1:100
A = magic(n);
tic
for jj = 1:n
A(idx(jj,1),idx(jj,2)) = 0;
end
t1=t1+toc;
A = magic(n);
%With SUB2IND
tic
idxLinear = sub2ind([n n],idx(:,1),idx(:,2));
A(idxLinear) = 0;
t2 = t2+toc;
end
t2./t1
So for 1000x2 I'm seeing a 60% speed up.
Sean de Wolski
le 6 Juin 2013
Now this might be somewhere that MEXing this with MATLAB Coder could buy you even more speedup. I'll try that tomorrow.
C Zeng
le 6 Juin 2013
Sean de Wolski
le 7 Juin 2013
For longer idx I am seeing the sub2ind approach be faster.
C Zeng
le 7 Juin 2013
Sean de Wolski
le 7 Juin 2013
How many times do you have to do this? I ran it yesterday with 3^14 and it took circa 25 seconds.
Sean de Wolski
le 7 Juin 2013
Well a few things real quick:
prMatrix = diag(pr);
Skips the first for-loop and call to zeros()
Second, you migh twant to consider taking the outer for-loop and converting it to a parfor with the Parallel Computing Toolbox. This would allow this to work in Parallel, over a few workers and speed things up that way.
Alternatively, just run it over the weekend or overnight, at two times total and 556 seconds, that's still only 20 minutes...
C Zeng
le 7 Juin 2013
C Zeng
le 13 Juin 2013
Catégories
En savoir plus sur Loops and Conditional Statements dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!