views:

107

answers:

3

Hi folks.

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!

+1  A: 

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.

Gilbert Le Blanc
Hi Gilbert. Thanks for taking the time to answer me. I do have a working algorithm and I do have some mathematical understanding. What I am searching for is an improved version of my current algorithm that delivers me a "better" curve for a logarithmical (points over time) / exponential (time over points) curve than the one I use at the moment. I know that this is a rather difficult question as one has to dig deeper into my algorithm. If there are any open questions, pleas don't hesitate to ask. I may not have made clear all of my thoughts and requirements. (Sorry for that!)
yas4891
@yas4891: Your curve is only going to be as good as your data points. Knowing what curve to use is more important. Here's a Wikipedia article on curve fitting: http://en.wikipedia.org/wiki/Curve_fitting
Gilbert Le Blanc
Oh OK. I don't want to find the perfect curve for a number of taken measuring points. I'd rather have a "curve / formula" that tells me WHEN to best take each measuring point. The data then taken by the application at that point in time is of no concern to my problem. I hope this helps to clarify my problem
yas4891
@yas4891: Basically, you want to take more x (time) measurements where y changes rapidly, and you can take fewer x measurements where y changes slowly. Rapidly and slowly are relative to the curve you're using. The ideal would be a measurement for each delta y, where delta y is a constant. I hope this helps.
Gilbert Le Blanc
wouldn't that result in a linear curve? I mean that is a constant relation between delta y and x - isn't it? (I really wonder how I achieved A grades in math during exams :-) )
yas4891
@yas4891: No, delta y does not imply a constant x, except in the case of a straight line. In a curve, the x measurements would be close together where the curve is steep, and further apart where the curve is closer to level.
Gilbert Le Blanc
+1  A: 

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++)

deinst
I cleaned up the code (dleeted unnecessary chunks). The code gives me the results I've written above.
yas4891
+1  A: 

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++;
Paul E.
Paul: Thank you. The idea with the offset did help me a lot. With some more fine-tuning I will make this work pretty decendly. Thanks a lot
yas4891