2

can I know how can I replace values in specific matrix position without using for loop in MATLAB? I initialize matrix a that I would like to replace its value on specified row and column for each no. This has to be done a few time within num for loop. The num for loop is important here because I would want the update the value in the original code.

The real code is more complicated, I am simplifying the code for this question.

I have the code as follow:

a = zeros(2,10,15);



for num = 1:10

    b = [2 2 1 1 2 2 2 1 2 2 2 2 1 2 2]; 
    c = [8.0268 5.5218 2.9893 5.7105 7.5969 7.5825 7.0740 4.6471 ...
    6.3481 14.7424 13.5594 10.6562 7.3160 -4.4648 30.6280];

    d = [1 1 1 2 1 1 1 1 1 1 3 1 6 1 1];

    for no = 1:15
        a(b(no),d(no),no) = c(1,no,:)
    end

end

A sample output for, say no 13 is as follows:

a(:,:,13) =

  Columns 1 through 8

         0         0         0         0         0      7.3160       0         0
         0         0         0         0         0         0         0         0

  Columns 9 through 10

         0         0
         0         0

Thank you so much for any help I could get.

0

4 Answers 4

5

It can be done using sub2ind, which casts the subs to a linear index. Following your vague variable names, it would look like this (omitting the useless loop over num):

a = zeros(2,10,15);
b = [2 2 1 1 2 2 2 1 2 2 2 2 1 2 2]; 
d = [1 1 1 2 1 1 1 1 1 1 3 1 6 1 1];
c = [8.0268 5.5218 2.9893 5.7105 7.5969 7.5825 7.0740 4.6471 ...
6.3481 14.7424 13.5594 10.6562 7.3160 -4.4648 30.6280];

% // we vectorize the loop over no:
no = 1:15;
a(sub2ind(size(a), b, d, no)) = c;
Sign up to request clarification or add additional context in comments.

2 Comments

@loss you're welcome. As Divakar pointed out: for raw speed you can strip down sub2ind to the only compute the linear indices for the 3-dimensional case directly. Doesn't get more readable though ;-). Also depending on what really happens within the num loop, you can probably extract some code out of that loop.
Noted @Nras. I will try all the codes and see which is suitable inside the loop.
4

Apart from the sub2ind based approach as suggested in Nras's solution, you can use a "raw version" of sub2ind to reduce a function call if performance is very critical. The related benchmarks comparing sub2ind and it's raw version is listed in another solution. Here's the implementation to solve your case -

no = 1:15
a = zeros(2,10,15);
[m,n,r] = size(a)
a((no-1)*m*n + (d-1)*m + b) = c

Also for pre-allocation, you can use a much faster approach as listed in Undocumented MATLAB blog post on Preallocation performance with -

a(2,10,15) = 0;

Comments

1

The function sub2ind is your friend here:

a = zeros(2,10,15);

x = [2 2 1 1 2 2 2 1 2 2 2 2 1 2 2];
y = [1 1 1 2 1 1 1 1 1 1 3 1 6 1 1];
z = 1:15;

dat = [8.0268 5.5218 2.9893 5.7105 7.5969 7.5825 7.0740 4.6471 ...
    6.3481 14.7424 13.5594 10.6562 7.3160 -4.4648 30.6280];

inds = sub2ind(size(a), x, y, z);

a(inds) = dat;

Comments

1

Matlab provides a function 'sub2ind' may do what you expected.

with variable as the same you posted:

idx = sub2ind(size(a),b,d,[1:15]); % return the index of row a column b and page [1:15]
a(idx) = c;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.