Randomly select a set number of samples (of size n) without overlap, nor replacement, in a signal

3 vues (au cours des 30 derniers jours)
I have a sound signal and I would like to randomly select 5 units of 10 seconds in that signal, but with no overlap, and with no replacement. It looks like I cannot use the function datasample because it only sample 1 sample in the vector (whereas I need: n = 10 seconds * sampling frequency).
If it is possible, I also would like a buffer length of b samples in between each unit sampled.
Any help much appreciated! Thank you!
  3 commentaires
Butterflyfish
Butterflyfish le 8 Déc 2019
Sorry for the misunderstanding. Let's say the signal is 10 minutes total. I would like to sample 5 units of data randomly in the signal (vector). Each unit would need to be 10 seconds and at least a distance of b between them. The units should not overlap.
Turlough Hughes
Turlough Hughes le 8 Déc 2019
Find out how many 10 second segments you have, assign a number to each segment and use randperm to get a random 5 samples non repeating. Can you attach the data to the question.

Connectez-vous pour commenter.

Réponse acceptée

Image Analyst
Image Analyst le 8 Déc 2019
Try this:
% Set up the signal and sampling parameters
samplingFrequency = 100; % Samples per second.
totalSeconds = 6000 % 6000
totalSamples = ceil(totalSeconds * samplingFrequency)
numRequiredSeconds = 10;
numRequiredSamples = ceil(numRequiredSeconds * samplingFrequency)
signal = rand(1, totalSamples);
numRequiredSegments = 5
segmentCount = 0;
iterations = 0;
maxIterations = 100000; % Some huge number where if we reach this, we will assume that the required number of segments can't be found randomly.
% Now look for acceptable non-overlapping segments.
while segmentCount < numRequiredSegments && iterations < maxIterations
% Get a random starting and stopping points for one segment.
thisStartingIndex = randi(totalSamples, 1);
thisStoppingIndex = thisStartingIndex + numRequiredSamples - 1;
% See if any indexes in this range overlap any prior indexes.
okay = true;
if iterations > 0
for k = 1 : iterations
% See if starting index is inside any existing segment.
if thisStartingIndex >= startingIndexes(k) && thisStartingIndex <= stoppingIndexes(k)
okay = false;
end
% See if stopping index is inside any existing segment.
if thisStoppingIndex >= startingIndexes(k) && thisStoppingIndex <= stoppingIndexes(k)
okay = false;
end
end
end
if okay
% If we get to here, the segment is okay - no overlapping with prior segments.
% Record the starting and stopping index of this segment, since it's okay.
segmentCount = segmentCount + 1; % Increment the index of this particular segment.
startingIndexes(segmentCount) = thisStartingIndex;
stoppingIndexes(segmentCount) = thisStoppingIndex;
fprintf('Found a good segment on iteration #%d. Starting Index = %d. Stopping Index = %d.\n', ...
iterations, thisStartingIndex, thisStoppingIndex);
end
% Increment the loop counter.
iterations = iterations + 1;
fprintf('Done with iteration #%d.\n', iterations);
end
% Optional: sort
[startingIndexes, sortOrder] = sort(startingIndexes, 'ascend');
stoppingIndexes = stoppingIndexes(sortOrder);
% Display sorted indexes in the command window.
for k = 1 : length(startingIndexes)
fprintf('Segment #%d: Starting Index = %d. Stopping Index = %d.\n', ...
k, startingIndexes(k), stoppingIndexes(k));
end
You'll see in the command window:
Segment #1: Starting Index = 132291. Stopping Index = 133290.
Segment #2: Starting Index = 202347. Stopping Index = 203346.
Segment #3: Starting Index = 371253. Stopping Index = 372252.
Segment #4: Starting Index = 568586. Stopping Index = 569585.
Segment #5: Starting Index = 582577. Stopping Index = 583576.
  5 commentaires
Image Analyst
Image Analyst le 17 Jan 2020
Can you attach the file that is causing this problems?
Butterflyfish
Butterflyfish le 17 Jan 2020
Modifié(e) : Butterflyfish le 17 Jan 2020
Sorry I erased my last comment by mistake. So the problem is now that I get segments smaller than the required number of samples. Which give me this output, for example:
Found a good segment on iteration #0. Starting Index = 18586722. Stopping Index = 19909721.
Done with iteration #0.
Found a good segment on iteration #1. Starting Index = 16550163. Stopping Index = 17873162.
Done with iteration #1.
Found a good segment on iteration #2. Starting Index = 13293809. Stopping Index = 14616808.
Done with iteration #2.
Found a good segment on iteration #3. Starting Index = 26312898. Stopping Index = 26460000.
Done with iteration #3.
Done with iteration #4.
Done with iteration #5.
Done with iteration #6.
Found a good segment on iteration #7. Starting Index = 21787214. Stopping Index = 23110213.
Done with iteration #7.
Segment #1: Starting Index = 13293809. Stopping Index = 14616808.
Segment #2: Starting Index = 16550163. Stopping Index = 17873162.
Segment #3: Starting Index = 18586722. Stopping Index = 19909721.
Segment #4: Starting Index = 21787214. Stopping Index = 23110213.
Segment #5: Starting Index = 26312898. Stopping Index = 26460000.
Unable to perform assignment because the indices on the left side are not compatible with the size of the right
side.
Error in test (line 71)
segments(:,k) = soundfile(startingIndexes(k):stoppingIndexes(k),1);
Here is a folder with the script and a signal as an example:
Many thanks for your help ! Invaluable!

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Just for fun dans Help Center et File Exchange

Produits


Version

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by