user1240679
user1240679

Reputation: 6979

Deduce a downward trend from a list of values

In of the functions in my program that is called every second I get a float value that represents some X strength.
These values keep on coming at intervals and I am looking to store a history of the last 30 values and check if there's a downward/decreasing trend in the values (there might be a 2 or 3 false positives as well, so those have to neglected).
If there's a downward trend and (If the most recent value minus the first value in the history) passes a threshold of 50 (say), I want to call another function. How can such a thing be implemented in C# which has such a structure to store history of 30 values and then analyse/deduce the downward trend?

Upvotes: 0

Views: 591

Answers (3)

Miserable Variable
Miserable Variable

Reputation: 28761

A Circular List is the best data structure to store last X values. There doesn't seem to be one in the standard library but there are several questions on SO how to build one.

You need to define "downward trend". It seems to me that according to your current definition ((If the most recent value minus the first value in the history) the sequence "100, 150, 155, 175, 180, 182" is a downward trend. With that definition you only need to the latest and first value in history from the circular list, simplifying it somewhat.

But you probably need a more elaborate algorithm to identify a downward trend.

Upvotes: 0

rpatel3001
rpatel3001

Reputation: 145

I don't know C# but I'd probably store the values as an List of some sort. Here's some pseudo code for the trend checking:

if last value - first value < threshold
    return
counter = 0
for int i = 1; i < 30; i++
    if val[i] > val[i-1]
        counter++
if counter < false_positive_threshold
    //do stuff

Upvotes: 0

Jim Mischel
Jim Mischel

Reputation: 134045

You have several choices. If you only need to call this once per second, you can use a Queue<float>, like this:

Queue<float> theQueue = new Queue<float>(30);

// once per second:
// if the queue is full, remove an item
if (theQueue.Count >= 30)
{
    theQueue.Dequeue();
}
// add the new item to the queue
theQueue.Enqueue(newValue);

// now analyze the items in the queue to detect a downward trend
foreach (float f in theQueue)
{
    // do your analysis
}

That's easy to implement and will be plenty fast enough to run once per second.

How you analyze the downward trend really depends on your definition.

It occurs to me that the Queue<float> enumerator might not be guaranteed to return things in the order that they were inserted. If it doesn't, then you'll have to implement your own circular buffer.

Upvotes: 2

Related Questions