How to select several intervals from a vector?

I have a vector (Y). I want to select a region from this vector. If this is a single region it is easy
X=Y(i_from:i_to);
What if I have several regions (the number of regions is not fixed)?
So I want to make the vector
[Y(i_from_1:i_to_1) ,Y(i_from_2:i_to_2), ........ ,Y(i_from_n:i_to_n)]
where n is not fixed.
Is there a fast and simple way? i_from and i_to values are in a n*2 matrix.
I can of course do a for cycle, but looking for a simpler method.

 Respuesta aceptada

Kristoffer
Kristoffer el 10 de Oct. de 2023

2 votos

You can make a vector containing the values specified by the intervals in Y using:
cell2mat(arrayfun(@(A,B) A:B, Y(:,1)', Y(:,2)', 'uniform', 0))

3 comentarios

Csaba
Csaba el 26 de Abr. de 2024
Editada: Csaba el 26 de Abr. de 2024
This is not what I want.
Let say I have
Y=1:2:30;
intervals=[1,3;...
11,15];
Then the desired output would be:
[1,3,5,21,23,25,27,29]
If you change Y to intervals in @Kristoffer's expression, we get your desired output
Y=1:2:30;
intervals=[1,3;...
11,15];
Y(cell2mat(arrayfun(@(A,B) A:B, intervals(:,1)', intervals(:,2)', 'uniform', 0)))
ans = 1x8
1 3 5 21 23 25 27 29
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Csaba
Csaba el 26 de Abr. de 2024
OK, this works. Thank you!

Iniciar sesión para comentar.

Más respuestas (1)

DGM
DGM el 26 de Nov. de 2021
Editada: DGM el 26 de Nov. de 2021
Idk. Here's three ways. They all use loops. Is there something more elegant? Prrrrobably. Is it faster? Probably depends. I'm sure there's more to be said about the topic. I'll leave that for others.
A = rand(1,1000);
bex = randi([1 1000],50,2);
timeit(@() loopappending(A,bex))
ans = 1.9935e-04
timeit(@() loopindexing(A,bex))
ans = 1.5171e-04
timeit(@() loopcell(A,bex))
ans = 1.1135e-04
% simply append subvectors
function B = loopappending(A,bex)
B = [];
for b = 1:size(bex,1)
B = [B A(bex(b,1):sign(diff(bex(b,:))):bex(b,2))];
end
end
% preallocate and use direct indexing
function B = loopindexing(A,bex)
B = zeros(1,sum(abs(diff(bex,1,2))+1)); % preallocate
endpoints = [0; cumsum(abs(diff(bex,1,2))+1)];
for b = 1:size(bex,1)
B(endpoints(b)+1:endpoints(b+1)) = A(bex(b,1):sign(diff(bex(b,:))):bex(b,2));
end
end
% throw output into cell array and then rearrange
function B = loopcell(A,bex)
B = cell(1,size(bex,1));
for b = 1:size(bex,1)
B{b} = A(bex(b,1):sign(diff(bex(b,:))):bex(b,2));
end
B = horzcat(B{:});
end

1 comentario

Csaba
Csaba el 26 de Nov. de 2021
Yes, cycles are an obvious solution. I am using that recently.
I am looking for a more elegant and faster method.

Iniciar sesión para comentar.

Categorías

Más información sobre Loops and Conditional Statements en Centro de ayuda y File Exchange.

Productos

Versión

R2019b

Preguntada:

el 26 de Nov. de 2021

Comentada:

el 26 de Abr. de 2024

Community Treasure Hunt

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

Start Hunting!

Translated by