Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to get rid of loop for this scenario?

44 views
Skip to first unread message

Jin Tang

unread,
Feb 19, 2003, 9:31:53 PM2/19/03
to
I have to improve the speed of one Matlab program. To do this, I want
to get rid of the for-loop. But I don't know how to achieve it.


The simplified scenario is like this: I have a zero matrix A (let's
say 6 by 6). I want to change some consecutive elements in each
column to other numbers (known). I know the starting row index of
those elements I want to change for each column and these indexes for
different columns are different.


The most obvious way is to use for-loop for each column and replace
those elements in each column with target numbers. But is there any
way to avoid using for-loop? I cannot tolerate the speed using
for-loop. Or is there any way to improve the speed? Thanks a lot!

Brett Shoelson

unread,
Feb 19, 2003, 10:53:35 PM2/19/03
to


Your question is a bit vague, but if I follow, then sub2ind will help:


a = zeros(6);
b = floor(rand(36,1)*100);
[rows,cols] = meshgrid(1:6,1:6);
inds=sub2ind(size(a),rows,cols);
a(inds)=b;


Cheers,
Brett

Jin Tang

unread,
Feb 20, 2003, 1:21:37 PM2/20/03
to
Thank you very much for your help, Brett. I am sorry that I didn't
make it very clear on the question.


Let's say I have the matrix A as zeros (6 by 6):
0 0 0 0 0 0
0 0 0 0 0 0
A= 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0


Also, I have another column vector B=[6 1 3]'
I want to replace three consecutive elements in each column of A by
the data vector B.


The positions of these three elements in each column are different.
But I know the starting index of these elements for each column,
which is expressed as a vector C=[2 4 1 3 2 1]. In other words, for
first column of A, the starting index for B is 2; for second column
of A, starting index for B is 4; for third column of A, the starting
index for B is 1; ... so on.


The final matrix A should look like this:
0 0 6 0 0 6
6 0 1 0 6 1
1 0 3 6 1 3
A= 3 6 0 1 3 0
0 1 0 3 0 0
0 3 0 0 0 0


I can use for-loop to finish this task. Is there any other ways to
avoid using for-loop?


Hope I am clear this time. Thanks!

Brett Shoelson

unread,
Feb 20, 2003, 2:28:31 PM2/20/03
to
SNIP

Again, use SUB2IND. You know the starting points for the the substitution,
in terms of their rows and columns. Use sub2ind to get the indices for these
starting points:

>> inds = sub2ind(size(A),C,[1:6])

inds =

2 10 13 21 26 31

Now the trick is to supplement each element with its next two neighbors. The
easiest way to do this is to download from MATLAB Central a function called
LINSPACEV (Duane Hanselman's extension into n-dimensions of my 2-D extension
of linspace).

>> inds1 = linspacev(inds,inds+2,3)

inds1 =

2 10 13 21 26 31
3 11 14 22 27 32
4 12 15 23 28 33


(There are other ways of creating these indices. You could use CUMSUM, for
instance):
>> inds2=cumsum([inds(:) ones(length(inds),2)],2)

inds2 =

2 3 4
10 11 12
13 14 15
21 22 23
26 27 28
31 32 33

Now use REPMAT to create copies of B (in a form appropriate for your
indices):
If you use linspacev:

>> vals1 = repmat(B,1,6)

vals1 =

6 6 6 6 6 6
1 1 1 1 1 1
3 3 3 3 3 3

Or if you use cumsum:
>> vals2 = repmat(B',6,1)

vals2 =

6 1 3
6 1 3
6 1 3
6 1 3
6 1 3
6 1 3

(Or, for either: inds = sort(inds(:)); vals = repmat(B,6,1);)

And substitute:

A(inds1) = vals1; (OR A(inds2) = vals2);
>> A(inds1) = vals1

A =

0 0 6 0 0 6
6 0 1 0 6 1
1 0 3 6 1 3

3 6 0 1 3 0
0 1 0 3 0 0
0 3 0 0 0 0

Cheers,
Brett


Brett Shoelson

unread,
Feb 20, 2003, 2:37:40 PM2/20/03
to
Followup comment:
that should be linspacen, not linspacev. (Linspacev was my 2-D version,
which would also have worked had I not withdrawn it when Duane extended to n
dimensions.)
Also, the content of my post might be more instructive for learning
vectorization than for avoiding a loop (particularly with the JIT
accelerator). You're probably not going to get much of a speed boost by
vectorizing a loop from 1:6 over a 6x6 matrix. Still, it's well worth
learning/practicing these things.
Cheers again,
Brett


Jin Tang

unread,
Feb 20, 2003, 8:19:30 PM2/20/03
to
Thank you so much for your warm help and detailed explaination,
Brett. They are really useful for my questions. Although the method
will not improve speed for 6 by 6 matrix, it helps me a lot when I
use it for 2000 by 2000 matrix. Besides, it is a new technique worth
studying for me. I can use the same idea to avoid using for-loop in
other similar situations. Thanks a lot!


Cheers,
Jin

0 new messages