MATLAB: Is it possible to replace ranges of a matrix elements using indices from two vectors

indexingMATLABmatrixvectorzeros

Hi,
I have a matrix of size 5×5 all the elements of which are zeros. I would like to replace some of these zeros with ones. The elements that I want to replace are referenced by two vectors a & b each of size (5 x 1). These two vectors point to the beginning and ending column indices of the range to be replaced. These ranges vary from one row to another. I tried using X(:,a:b)=1, but it only uses the first value in these vectors. I don't know how to modify my code so that the ranges vary by each row.
> X=zeros(5,5)
X =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
> a=[2,3,1,3,4]'
a =
2
3
1
3
4
> b=[4,3,2,4,5]'
b =
4
3
2
4
5
> X(:,a:b)=1
X =
0 1 1 1 0
0 1 1 1 0
0 1 1 1 0
0 1 1 1 0
0 1 1 1 0
How can I get the result look like this?
X =
0 1 1 1 0
0 0 1 0 0
1 1 0 0 0
0 0 1 1 0
0 0 0 1 1
Thanks! Hawre

Best Answer

Modified FOR loop for speed...
N = 5;
X = false(N);
for ii = 1:N
X(ii,a(ii):b(ii)) = 1;
end
X = double(X); % Convert to double.
Note that if logicals will work for your application, then the last line is not needed.
%
%
%
EDIT In response to your extra request for a vectorized solution.
X2 = zeros(N,N);
C = b-a+1;
R = zeros(1,sum(C));
R([0;cumsum(C(1:N-1))]+1) = 1;
C = arrayfun(@colon,a,b,'un',0); % Or try MCOLON
C = [C{:}]; % Not necessary with MCOLON
X2(cumsum(R)+(C-1)*N) = 1;
MCOLON might speed up the call to ARRAYfUN. Using ARRAYFUN as above, this is much slower than the FOR loop for 5000-by-5000 X (N=5000), and occasionally runs out of memory. I tested the above using:
N = 5000;
a = ceil(rand(N,1)*N);
b = min(a+round(rand(N,1)*N),N);