필터 지우기
필터 지우기

Linearly increasing groups of indices

조회 수: 1 (최근 30일)
Nils
Nils 2013년 3월 11일
Hello, I think I can explain my question most easily with an example. If I only want to access every 10th element in an array a, then I can easily do this by a(1:10:end). But let's say that I am instead looking for groups of entries whose indices all are increasing with 10 all the way to the final index. For instance, access the entries with indices 1,3,4,11,13,14,21,23,24... Naturally a([1 3 4]:10:end) does not accomplish this. Is there a way that I through indexing could do this without a loop?
Thanks in advance!
  댓글 수: 1
Nils
Nils 2013년 3월 12일
Actually, this is only to be done offline with a few matrices of moderate dimensions (part of setting up an MPC problem) so I was looking for something that was syntactically convenient and not necessarily the fastest. Thanks all for good suggestions. I appreciate your time and creativity!

댓글을 달려면 로그인하십시오.

채택된 답변

Jan
Jan 2013년 3월 11일
편집: Jan 2013년 3월 12일
A = 1:100;
B = reshape(A, 10, 10);
C = reshape(B([1,3,4], :), 1, []);
[EDITED] Perhaps Bruno's tool can help: FEX: mcolon.
[EDITED 2] Another approach, which does not limit the size of the input to be a multiple of the step width:
A = 1:100;
index = false(1, numel(A));
index(1:10:end) = true;
index(3:10:end) = true;
index(4:10:end) = true;
C = A(index);
Note: This is equivalent to Sean's approach, but avoids the sorting by using logical indexing.
If you want to write this more compact, use a function to conceal the details:
function C = (A, start, step)
len = numel(A);
index = false(1, len);
for k = 1:length(start)
index(start(k):step:len) = true;
end
C = A(index);
  댓글 수: 4
Jan
Jan 2013년 3월 12일
편집: Jan 2013년 3월 12일
@Nils: Correct, if numel(A) is not a multiple of 10, the reshaping fails.
I do not think that this is a natural problem. But this is caused by my personal experiences only, because I haven't had such a demand in the last 35 years, and haven't read an equivalent question in the forums in the last 10 years.
But see [EDITED].
@Sean: Of course RESHAPE is such fast, because it performs almost nothing. Only the tiny vector of dimensions is changed after chekcing, that the product of the new dimensions equals the number of elements. Therefore in my opinion STRUCT2CELL is faster, because it does tocuh the data - at least I have though that. But surprisingly the internal representation of structs and cells differs in one detail only: The struct has an additional #fields*64 char array for the field names. So even here the speed is a result of a smart representation of the data.
Finally I think, a*ones(n,m) is the fastest operation: My measurements seem, like this avoids even the multiplication, such that it is faster than repmat(a, n, m).
Sorry for comparing apples with beers.
Sean de Wolski
Sean de Wolski 2013년 3월 12일
@Nils, you can always just use a for-loop if numel(A) is not a multiple of 10.
I would be very surprised if this is the bottleneck in your code.

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Sean de Wolski
Sean de Wolski 2013년 3월 11일
A = 1:100;
A(sort([1:10:end, 3:10:end,4:10:end])) = pi
Of course a for-loop might be faster.
  댓글 수: 2
Nils
Nils 2013년 3월 11일
Of course that's not a bad answer at all! I was hoping for some built-in indexing syntax though, that supported this operation.
Jan
Jan 2013년 3월 11일
Sorting is expensive. This works only, if all subvectors have the same length:
n = length(A);
index = [1:10:n; 3:10:n; 4:10:n];
A(index(:))

댓글을 달려면 로그인하십시오.


Andrei Bobrov
Andrei Bobrov 2013년 3월 12일
out = bsxfun(@plus,[1;3;4],0:10:10*(floor(x(end)/10)-1));

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by