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!
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
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!
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
Cheers,
Jin