# Efficient Code for Filling Rows of an Array involving Indices Ranges

2 Ansichten (letzte 30 Tage)
Ray am 2 Okt. 2014
Kommentiert: Matt J am 5 Okt. 2014
Hello,
I have an array A of zeros. I need to set a range of column indices for each row of A to ones. These ranges are determined by elements of another vector B, specifying start and end indices for the ranges for each row. For example, this is what I'm trying to figure out:
The first row of B indicates that the first row of A should have ones from columns 1 to 3. The second row of B indicates that the second row of A should have ones from columns 2 to 4 etc.
I could code this with a for-loop that goes through each of the rows and creates indices with the colon operator however, I'm hoping for a smarter, more efficient way to do it than that.
Can anyone help me with this or any suggestions?
Thanks.
##### 0 Kommentare-2 ältere Kommentare anzeigen-2 ältere Kommentare ausblenden

Melden Sie sich an, um zu kommentieren.

### Akzeptierte Antwort

Matt J am 3 Okt. 2014
Bearbeitet: Matt J am 3 Okt. 2014
e=1:size(A,2);
A = bsxfun(@ge,e,B(:,1)) & bsxfun(@le,e,B(:,2));
##### 2 KommentareKeine anzeigenKeine ausblenden
Mohammad Abouali am 3 Okt. 2014
nice
Matt J am 3 Okt. 2014
Thanks. The syntax is brief, but I still think a for-loop will be more efficient.

Melden Sie sich an, um zu kommentieren.

### Weitere Antworten (4)

Ray am 5 Okt. 2014
Hi All,
I implemented the above and acquired the average execution times for each approach:
The for-loop approach is the most efficient.
On a larger matrix (50000x20) the results are similar however, the approach suggested by Guillaume takes a bit longer ~0.2 seconds.
Thanks to everyone for their replies and help.
##### 1 Kommentar-1 ältere Kommentare anzeigen-1 ältere Kommentare ausblenden
Matt J am 5 Okt. 2014
This was with a for-loop across columns, correct?

Melden Sie sich an, um zu kommentieren.

Guillaume am 2 Okt. 2014
Bearbeitet: Guillaume am 2 Okt. 2014
I don't think there's a more efficient way of doing it than with a loop. The following would work, but it's arguable that it does not involve loops because of the cellfun, and it's certainly convoluted:
A=A';
bounds = sub2ind(size(A), B', repmat(1:size(B, 1), size(B, 2), 1));
indices = cellfun(@(b) b(1):b(2), num2cell(bounds, 1), 'UniformOutput', false);
A([indices{:}]) = 1;
A=A';
##### 1 Kommentar-1 ältere Kommentare anzeigen-1 ältere Kommentare ausblenden
Matt J am 3 Okt. 2014
I don't think there's a more efficient way of doing it than with a loop.
I don't think so either, nor do I expect a loop's performance to be bad.

Melden Sie sich an, um zu kommentieren.

Joseph Cheng am 2 Okt. 2014
Bearbeitet: Joseph Cheng am 2 Okt. 2014
so... it is certainly a brain teaser to do this without a loop. so far i'm up to this.
A=zeros(3,4);
B = [1 3;2 4;1 1];
a=A';
B=B+repmat([0:4:4*(size(B,1)-1)]',1,2)
a(B)=1
a=a'
which leaves just filling in the zeros between ones without looping.
##### 0 Kommentare-2 ältere Kommentare anzeigen-2 ältere Kommentare ausblenden

Melden Sie sich an, um zu kommentieren.

Matt J am 3 Okt. 2014
[M,N]=size(A);
e=(1:M).';
idx1=sub2ind([M,N], e, B(:,1));
idx2a=B(:,2)<N;
idx2b=sub2ind([M,N], e(idx2a), B(idx2a,2)+1);
A(idx1)=1;
A(idx2b)=-1;
A=cumsum(A,2)
##### 0 Kommentare-2 ältere Kommentare anzeigen-2 ältere Kommentare ausblenden

Melden Sie sich an, um zu kommentieren.

### Kategorien

Mehr zu Logical finden Sie in Help Center und File Exchange

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by