Vitalis Hommel
Vitalis Hommel

Reputation: 1040

How to convert time dependent values into rising, staying and falling?

I have an array like this

time_in_seconds;value
2.353463;0
2.453463;10
2.553463;10
2.653463;9
2.853463;0
3.353463;0
5.353463;2

I would like to populate a List<Times> with

public class Times
{
  public double[] time_rising_start {get;set;}
  public double[] time_rising_end {get;set;}
  public double[] time_staying_end {get;set;}
  public double[] time_falling_end {get;set;}
}

where

double[] time = new double[2];
time[0] = time_start
time[1] = time_start_value

respectively

double[] time = new double[2];
time[0] = time_end
time[1] = time_end_value

There are many approaches, I am looking for an intelligent way to summarize this into rising, staying and falling. That means

2.353463;0
2.453463;10

is rising, 0 -> 10

2.453463;10
2.553463;10

is staying, 10 -> 10

2.553463;10
2.653463;9
2.853463;0

is falling, 10 -> 9 -> 0

2.853463;0
3.353463;0

is staying, 0 -> 0

etc.

time_rising_start and time_falling_end should always be at value = 0. In the mentioned example, it is

  time_rising_start = 2.353463;
  time_rising_end = 2.453463;
  time_staying_end = 2.553463;
  time_falling_end = 2.853463;

next object

  time_rising_start = 3.353463;
  ...

It should be able to handle slight changes like value

0
10
11
10
11
12
7
3
0

should amount to

0 <- time_rising_start
10 <- time_rising_end
11
10
11
12 <- time_staying_end
7
3
0 <- time_falling_end

Comparing to the previous value is easy. I would look if it was lower then it's rising etc.. But as this is not so simple I am looking for an efficient approach.

Upvotes: 0

Views: 81

Answers (1)

Ian Mercer
Ian Mercer

Reputation: 39277

Create a set of states (an enum for example): Initial, Rising, Falling, Steady.

Track the state and the last seen value current and current_time.

In pseudo code:

state = Initial 
current = first value
current_time = first time

foreach (value,time) after first
 switch on the state
  case Initial:
    if (value > current_value) { ... output rising, state = Rising }
    else ...
    current = value
  case Rising:
    if (value > current_value) { // do nothing, still rising }
    ...

As each value is processed the state machine needs to decide if a change of state is needed and whether to output something. In some states, some values will do nothing but advance to the next value. At the end you may need to output one more value.

This is a classic state machine implementation. There are more advanced state machines (hierarchical ones). Every developer should learn how a state machine works and how to implement one because they are quite common.

UML State Machines is a good reference on the topic.

Upvotes: 3

Related Questions