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

3 visualizzazioni (ultimi 30 giorni)
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 Commenti
Butterflyfish
Butterflyfish il 8 Dic 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 il 8 Dic 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.

Accedi per commentare.

Risposta accettata

Image Analyst
Image Analyst il 8 Dic 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 Commenti
Butterflyfish
Butterflyfish il 17 Gen 2020
Modificato: Butterflyfish il 17 Gen 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!

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Just for fun in Help Center e File Exchange

Prodotti


Release

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by