Generate unevenly-spaced synthetic time series

7 visualizaciones (últimos 30 días)
Vince Clementi
Vince Clementi el 26 de Abr. de 2019
Editada: Adam Danz el 26 de Abr. de 2019
Hello,
I have created a synthetic time series (x) over time (tsyn), but I need to remake this so that the spacing between points in tsyn is both uneven and random between 1 and 5.
tsyn = 1:1600;
x = 2*sin(2*pi*tsyn/100)+1*sin(2*pi*tsyn/41)+0.5*sin(2*pi*tsyn/21);
figure;
plot(tsyn,x);
I thought it would be something like the below code, but that didn't work.
tsyn = 1:randn(1:5):1600;
Any advice?
  3 comentarios
John D'Errico
John D'Errico el 26 de Abr. de 2019
I assumed non-integer, because randn is floating point, and that is what was attempted for use. But integer increments are a possibility. You never know. :)
Adam Danz
Adam Danz el 26 de Abr. de 2019
Editada: Adam Danz el 26 de Abr. de 2019
Ah, I just saw this. I updated my solution to cover both possibilities.

Iniciar sesión para comentar.

Respuestas (2)

Adam Danz
Adam Danz el 26 de Abr. de 2019
Editada: Adam Danz el 26 de Abr. de 2019
If your samples are not integers
You can set the maximum sample, the [min, max] of your bounds, and the starting number. tsyn is a monotonically increasing vector with random intervals from a bounded, uniform distribution starting at your specified starting value and ending at or just before your maximum sample.
maxSample = 1600; %maximum value allowed
bounds = [1,5]; %bounds to the uniformly distribution random intervals between samples (inclusive)
startNum = 1; %first sample (starting point)
% Create samples at random intervals
minSamples = floor(maxSample / bounds(1)); %you'll end up with at least this many samples
randIntervals = (rand(minSamples,1) * range(bounds)) + bounds(1);
tsyn = [startNum; cumsum(randIntervals)+startNum];
tsyn(tsyn > maxSample) = []; %get rid of extra values
figure
histogram(diff(tsyn), bounds(1):bounds(2))
xlabel('Intervals')
ylabel('Frequency')
set(gca, 'Xtick', bounds(1):bounds(2))
If your samples should be intergers
Replace the "randIntervals =" line above with the one below
randIntervals = randi(range(bounds)+1, minSamples, 1)+bounds(1)-1;
Test
And if you need convinced that the intervals are randomly distributed between your bounds:
figure
histogram(diff(tsyn), bounds(1):bounds(2)+1)
xlabel('Intervals')
ylabel('Frequency')
set(gca, 'Xtick', bounds(1):bounds(2))

John D'Errico
John D'Errico el 26 de Abr. de 2019
Editada: John D'Errico el 26 de Abr. de 2019
It failed, because the colon operator does not accept a random increment. Anyway, randn(1:5) does not generate a random number between 1 and 5 anyway. I'd suggest you need to read the getting started tutorials.
Doing what you have asked is not trivial however. One approach would use Poisson arrivals. But I recall that would imply an exponential interarrival time. And you are asking for a uniformly distributed interarrival time.
Simplest would be to use Roger Stafford's randfixedsum, available for free download from the File Exchange.
If the spacing is to be from 1 to 5, then the average spacing is 3. Over the interval [1,1600], that means you would expect
(1600-1)/3
ans =
533
So you want to find a set of 533 random numbers, uniformly distributed on the interval [1,5] that sum to 1599.
delta = randfixedsum(533,1,1599,1,5)';
tsyn = cumsum([1,delta]);
As you can see, this set has the desired properties. It runs from 1 to 1600.
tsyn(1)
ans =
1
tsyn(end)
ans =
1600
As well, it is uniformly distributed in terms of the inter-arrivals. (Well approximately so. With a larger sample size, it will be closer to uniform.)
min(diff(tsyn))
ans =
1.00672171800682
max(diff(tsyn))
ans =
4.99817125723121
hist(diff(tsyn),10)
You can find randfixedsum here:

Community Treasure Hunt

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

Start Hunting!

Translated by