5

I've got this pretty big list of acceleration samples (about 300k) which I plot with matplotlib. My goal is to also plot the velocity and get its maximum value.

Is there a way to integrate the acceleration list in order to get a velocity list?

Javier
  • 801
  • 3
  • 10
  • 24

4 Answers4

4

I think you're looking for scipy.integrate.cumtrapz. It will be much faster than the above for-loop implementations. See this answer here. The basic idea is to take the cumulative sum (instead of just plain sum) of the normal trapezoidal formula:

def cumtrapz_example(y, x):
     return np.cumsum(0.5*((x[1:]-x[:-1])*(y[1:]+y[:-1])))

Instead of

def trapz_example(y, x):
     return np.sum(0.5*((x[1:]-x[:-1])*(y[1:]+y[:-1])))

This lesson on Numerical Integration in Python is also helpful.

dsholes
  • 453
  • 2
  • 4
  • 10
3

Yes, there is a way! It's called "Numerical Integration", and that phrase should enable you to find the tools you need or to make them yourself.

The wikipedia article has some great examples of implementing integration on discrete data. For example, you could start with the rectangle rule or trapezoidal rule:

https://en.wikipedia.org/wiki/Numerical_integration

Just like any integration, there will be an unknown constant (the initial velocity).

Here's one of many possible solutions using Python: scipy.integrate:

https://docs.scipy.org/doc/scipy/reference/tutorial/integrate.html

Cinghiale
  • 164
  • 1
  • 5
2

With some assumptions, it can be simple. For example,

1) if your samples are equidistant in time, 2) you know the time between each measurement, 3) and initial velocity is zero,

you can simply sum from the beginning of list to the current time, like this:

acceleration_list = [1,2,3,4,5]
velocity_list = [sum(acceleration_list[:i]) for i in range(len(acceleration_list))]

The above assumes that samples are taken every second (or whatever unit of time you want). If the sampling time is different, modify like

time_between_samples = 0.1
acceleration_list = [1,2,3,4,5]
velocity_list = [sum(acceleration_list[:i]) * time_between_samples for i in range(len(acceleration_list))]
Gena Kukartsev
  • 1,515
  • 2
  • 17
  • 19
  • Those assumptions are perfectly correct. But this takes so much time it turns impractical... – Javier Oct 22 '16 at 20:44
0

So. This is the way I'm doing the job assuming a sampling rate of 10 Hz.

acceleration = [1, 2, 3, 4, 5, 6, 7, 8, 9]
velocity = [0]
time = 0.1
for acc in acceleration:
    velocity.append(velocity[-1] + acc * time)
del velocity[0]
Javier
  • 801
  • 3
  • 10
  • 24