1

I have a dynamic dataset of length n, which is greater than or equal to one. The dataset contains m-dimensional position and velocity values for discrete time.

import numpy as np

times      = np.array([t1, t2, ..., tn])
positions  = np.array([[p11, p12, ..., p1m],
                       [p21, p22, ..., p2m],
                                ...        ,
                       [pn1, pn2, ..., pnm]])
velocities = np.array([[v11, v12, ..., v1m],
                       [v21, v22, ..., v2m],
                                ...        ,
                       [vn1, vn2, ..., vnm]])

I would like to calculate the position and velocity value for any time, including if the value is outside of the range of the dataset. I can achieve a simple linear interpolation for the velocity using,

interp_vel = [np.interp(t, times, v) for v in velocities.T]

Instead of applying the same method to find the position, I would like to utilize the velocity samples in my calculation.

Pranav Hosangadi
  • 23,755
  • 7
  • 44
  • 70
Alex
  • 47
  • 5
  • Unrelated: instead of a list comprehension to interpolate each column individually, [`scipy.interpolate.interp1d`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html#scipy.interpolate.interp1d) can do them all together – Pranav Hosangadi Feb 24 '23 at 20:18
  • 2
    Position should be the integral of your velocity measurements, though there will be some error in that over time if you only have discrete measurements, and you would need to know the initial position. – Pete Feb 24 '23 at 20:28

2 Answers2

1

Using both the positions and the velocities it's possible to define a cubic spline that passes through 2 points with known gradient at each point. I'm not sure whether this is practicable for your question but it may help find solution.

import numpy as np
from collections.abc import Iterable
 
x0 = 5.0
dx0 = -2.5
t0 = 0.5

x1 = 5.5
dx1 = 1.2
t1 = 0.75

def cubic_spline( t0, x0, dx0, t1, x1, dx1 ):
    """  Solve for a, b, c and d 
                a * t0**3 +     b * t0**2 + c * to +d = x0
            3 * a * t0**2 + 2 * b * t0    + c         = dx0
                a * t1**3 +     b * t1**2 + c * to +d = x1
            3 * a * t1**2 + 2 * b * t1    + c         = dx1
    """
    t02 = t0 * t0
    t03 = t02 * t0
    t12 = t1 * t1
    t13 = t12 * t1

    coeffs = np.array( [[   t03,   t02, t0, 1 ],
                        [ 3*t02, 2*t0,   1, 0 ],
                        [   t13,   t12, t1, 1 ],
                        [ 3*t12, 2*t1,   1, 0 ]])

    rhs = [ x0, dx0, x1, dx1 ]
    return np.linalg.inv( coeffs ).dot( rhs )

def use_spline( abcd, t ):
    """ abcd is an array of length 4 
        t is a scalar or sequence of floats. """
    if isinstance( t, Iterable):
        v = np.vander( t, 4 )
    else:
        v = np.vander( [t], 4 )
    return ( abcd * v ).sum( axis = 1 )

abcd = cubic_spline( t0, x0, dx0, t1, x1, dx1 )

print( use_spline( abcd, [ 0.5, .55, .6, .65, .7, .75 ] ) )
# [5.     4.9624 5.0572 5.2208 5.3896 5.5   ]

You'd need an abcd for each time period. It's probably worth exploring scipy.interpolate to see if anything easier will work. The spline versions I could see didn't use the gradient, just the points.

Tls Chris
  • 3,564
  • 1
  • 9
  • 24
  • There is a scipy.iterpolate that takes points and gradients in a cubic spline. `CubicHermiteSpline` https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.CubicHermiteSpline.html – Tls Chris Feb 26 '23 at 14:44
0

Using simple physics equation you could use something similar to this:

pos_new = pos_old + delta_t * speed_old
jeandemeusy
  • 226
  • 3
  • 12
  • `speed_old` should be the average – cards Feb 24 '23 at 21:17
  • This would only utilize 1 of the n data samples. How could I utilize the other n-1 samples effectively? – Alex Feb 24 '23 at 21:17
  • In the instance I had the data points at t = [-inf, -1, 1, inf] and wanted to interpolate t=0, taking the average of each velocity would not accurately reflect the velocity at t=0 – Alex Feb 24 '23 at 21:24
  • @Alex it s not clear what you want to do: interpolation of velocity, time? Please, add relevant information by editing the question not with comments. What about using _v**2 = u**2 + 2ads_? – cards Feb 24 '23 at 21:31