Reputation: 4862
I'm currently implementing a software that measures certain values over time. The user may choose to measure the value 100 times over a duration of 28 days. (Just to give an example)
Linear distribution is not a problem, but I am currently trying to get a logarithmical distribution of the points over the time span.
The straight-forward implementation would be to iterate over the points and thus I'll need an exponential function. (I've gotten this far!)
My current algorithm (C#) is as follows:
long tRelativeLocation = 0;
double tValue;
double tBase = PhaseTimeSpan.Ticks;
int tLastPointMinute = 0;
TimeSpan tSpan;
for (int i = 0; i < NumberOfPoints; i++)
{
tValue = Math.Log(i + 1, NumberOfPoints);
tValue = Math.Pow(tBase, tValue);
tRelativeLocation = (long)tValue;
tSpan = new TimeSpan(tRelativeLocation);
tCurrentPoint = new DefaultMeasuringPointTemplate(tRelativeLocation);
tPoints.Add(tCurrentPoint);
}
this gives me a rather "good" result for 28 days and 100 points.
The first 11 points are all at 0 seconds,
12th point at 1 sec,
20th at 50 sec,
50th at 390 min,
95th at 28605 mins
99 th at 37697 mins (which makes 43 hours to the last point)
My question is: Does anybody out there have a good idea how to get the first 20-30 points further apart from each other, maybe getting the last 20-30 a bit closer together?
I understand that I will eventually have to add some algorithm that sets the first points apart by at least one minute or so, because I won't be able to get that kind of behaviour into a strictly mathematical algorithm.
Something like this:
if (((int)tSpan.TotalMinutes) <= tLastPointMinute)
{
tSpan = new TimeSpan((tLastPointMinute +1) * 600000000L);
tRelativeLocation = tSpan.Ticks;
tLastPointMinute = (int)tSpan.TotalMinutes;
}
However, I'd like to get a slightly better distribution overall.
Any cool ideas from you math cracks out there would be greatly appreciated!
Upvotes: 2
Views: 1068
Reputation: 269
From a practical point of view, the log function squeezes your time point near the origin already. A power function squeezes them even more. How about simple multiplication?
tValue = Math.Log(i + 1, NumberOfPoints);
tValue = tBase * tValue;
Another way to flatten the curve is start farther from the origin.
for (int i = 0; i < NumberOfPoints; i++)
{
tValue = Math.Log(i + 10, NumberOfPoints + 9);
The range of tvalue is still 0 to 1.
How about this to have a minimum space of 1 second at the beginning?
double nextTick = 0;
for (int i = 0; i < NumberOfPoints; i++)
{
tValue = Math.Log(i + 1, NumberOfPoints);
tValue = Math.Pow(tBase, tValue);
if (tValue < nextTick) tValue = nextTick;
nextTick++;
Upvotes: 1
Reputation: 18802
I am not exactly sure what you are trying to do, your code does not seem to match your example (it could be that I am screwing up the arithmetic). If you want your samples to have a minimum separation of 1 sec, and each point at a location of x times the last point (except for the first) then you want to find x such that x^(n - 1) = span. This is just x = exp(log(span) / (n - 1)). Then your points would be at x^i for(i = 0; i < n; i++)
Upvotes: 1
Reputation: 51565
The distribution curve you choose depends on what you're measuring.
A straight line, a sine wave, a polynomial or exponential curve may individually be the best distribution curve for a given set of measurements.
Once you've decided on the distribution curve, you calculate the missing data points by calculating the y value for any given time value (x value), using the mathematical formula of the curve.
As an example, for a straight line, all you need is one data point and the slope of the line. Let's say at time 0 the measured value is 10, and the measurement goes up by 2 every minute. The formula would by y = 2 * x + 10. if we wanted to calculate the measurement when x = 5 (minutes), the formula gives us a measurement of 20.
For a logarithmic curve, you'd use a logarithm formula. For simplicity, let's say that the actual measurements give us a formula of y = 2 ** x + 12; You plug in the time values (x values) you want to calculate, and calculate the measurements (y values).
Realize that you are introducing calculation errors by calculating data points instead of measuring. You should mark the calculated data points in some manner to help the person reading your graph differentiate them from actual measurements.
Upvotes: 1