Question about assigning value in a matrix.

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.

 Respuesta aceptada

Walter Roberson
Walter Roberson el 6 de Jun. de 2013
idx = sub2ind(size(A), [1 2 3 4], [2 3 2 1]);
A(idx) = 1;

3 comentarios

C Zeng
C Zeng el 6 de Jun. de 2013
Thanks, Walter! So sub2ind can find the index of A quickly by loops, right? I will definitely try this code. I like it!
Sean de Wolski
Sean de Wolski el 6 de Jun. de 2013
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...
C Zeng
C Zeng el 6 de Jun. de 2013
Oh, really? I always found that MATLAB is not efficient for large loops. That is why I tried to avoid large loops.

Iniciar sesión para comentar.

Más respuestas (2)

Azzi Abdelmalek
Azzi Abdelmalek el 6 de Jun. de 2013
A=zeros(4);
a=[1,2;
2,3;
3,2;
4,1];
idx= sub2ind(size(A),a(:,1),a(:,2));
A(idx)=1
Sean de Wolski
Sean de Wolski el 6 de Jun. de 2013

0 votos

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 comentarios

C Zeng
C Zeng el 6 de Jun. de 2013
Sean, let me do a simple experiment and let u know.
Azzi Abdelmalek
Azzi Abdelmalek el 6 de Jun. de 2013
The for loop, in this case, is almost twice faster
Sean de Wolski
Sean de Wolski el 6 de Jun. de 2013
Editada: Sean de Wolski el 6 de Jun. de 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
Sean de Wolski el 6 de Jun. de 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
C Zeng el 6 de Jun. de 2013
Oh, I see. Yes, you may be right. Interested in more speedup!
Sean de Wolski
Sean de Wolski el 7 de Jun. de 2013
For longer idx I am seeing the sub2ind approach be faster.
C Zeng
C Zeng el 7 de Jun. de 2013
Sean, yes, my test result also shows it. For 3^10 rows (I assume it is large): Using for loops takes ~565 seconds while sub2ind procedure takes ~446 seconds.
Do you think if there is room for improvement? Ideally I hope it can compute for 3^14.
Sean de Wolski
Sean de Wolski el 7 de Jun. de 2013
How many times do you have to do this? I ran it yesterday with 3^14 and it took circa 25 seconds.
C Zeng
C Zeng el 7 de Jun. de 2013
Editada: C Zeng el 7 de Jun. de 2013
2 times each, Sean. My problem is complex, M is a matrix with 3^10 rows, and around 400 columns. Here is the sample code:
for i=1:M1
pr=(rR(i:i+M-1)-1)/10; %pr is the vector of probabilities
prMatrix=zeros(M2);
for j=1:M2
prMatrix(j,j)=pr(j);
end
x=Y*prMatrix; % x is sample yield for each polnicy
x=round(x); % only consider yield as integer
% matrix computation(faster!)
%
TotalCollect=sum(x,2); % total collection for each policy
TotalCollect=TotalCollect+1;
TempMatrix=zeros(3^M2, n);
%{
for j=1:3^M2 %---slow!
TempMatrix(j,TotalCollect(j))=1;
end
%}
%use sub2ind procedure
row=(1:1:3^M2)';
idx=sub2ind(size(TempMatrix),row,TotalCollect);
TempMatrix(idx)=1;
%}
Pr=Pr+TempMatrix;
end
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
C Zeng el 7 de Jun. de 2013
Thanks, Sean!
Let me try it again. I have to run large data on server, because 3^12 is memory out here.
C Zeng
C Zeng el 13 de Jun. de 2013
Sean, thanks for your advice. My program got speedup. sub2ind will be faster if the size is large.

Iniciar sesión para comentar.

Categorías

Más información sobre Loops and Conditional Statements en Centro de ayuda y File Exchange.

Etiquetas

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by