1
votes

How would one superimpose rows of different lengths onto a matrix in Matlab? That is, I would like the first x number of elements and the last y number of elements in row z of matrix A to be zero with x and y specified in two column vectors of length Z (so corresponding to the number of rows of matrix A). I can only think of a solution in terms of a simple loop but am looking for a more elegant solution avoiding the use of a loop as this piece of code needs to be run thousands of times in a main loop.

Edit

As confirmed by @randomatlabuser, this is what the asker wants to do without a loop:

M = 1e4; N = 1e3; A = randn(M, N);
x = randi([0, N], [M, 1]);
y = randi([0, N], [M, 1]);
for hh = 1:M
  A(hh, 1:x(hh)) = 0;
  A(hh, (N - y(hh) + 1):N) = 0;
end
2
And how do you want to fill the remaining (nonzero) vaules? Could you give a simple example?Luis Mendo
A would already be filled, but I want to replace the first x and last y number of elements of each row with zeros, where x and y are different for each row and defined in two column vectors.user3029330
Are x and y the same in all iterations of the main loop?Luis Mendo
@user3029330 Next time if you already have a working solution you want to improve on, please include it to prevent any confusion or double work.Dennis Jaheruddin

2 Answers

1
votes

You can do it this way:

A = rand(4,6); %// example data
x = [1; 2; 1; 3]; %// example data
y = [1; 2; 1; 2]; %// example data

[M N] = size(A);
col = 1:N;
B = A.* ( bsxfun(@gt, col, x) & bsxfun(@le, col, (N-y)) );

The result in this example is:

>> A

A =

    0.0168    0.8797    0.7367    0.9859    0.5385    0.9745
    0.9274    0.4161    0.0567    0.0649    0.7961    0.1616
    0.3935    0.8690    0.8386    0.0308    0.5494    0.5525
    0.7615    0.1895    0.0002    0.0919    0.7167    0.6101

>> B

B =

         0    0.8797    0.7367    0.9859    0.5385         0
         0         0    0.0567    0.0649         0         0
         0    0.8690    0.8386    0.0308    0.5494         0
         0         0         0    0.0919         0         0

If x and y are the same in all iterations of your main loop, you can save time by computing the mask before the loop:

[M N] = size(A);
col = 1:N;
mask = bsxfun(@gt, col, x) & bsxfun(@le, col, (N-y));

and then at each iteration you only have to apply the pre-computed mask:

B = A.*mask;
1
votes

What you want to do is:

M = 1e4; N = 1e3; A = randn(M, N);
x = randi([0, N], [M, 1]);
y = randi([0, N], [M, 1]);
for hh = 1:M
  A(hh, 1:x(hh)) = 0;
  A(hh, (N - y(hh) + 1):N) = 0;
end

but without a loop, right?