I have data represents positions(x, y, z) as a double array. I want to calculate x', y', z' which represent the velocities. I'm dealing with real time project, so I need efficient way to calculate the derivative of stream data from a file or coming from another computer over the Internet. I've read a chapter about numerical derivatives. It seems that there are a lot of things should be concerned for implementing the derivatives. I need a library for this purpose. Any suggestions?
@naraku9333,
Yes you are right but I don't differentiate a value (it gonna be zero) however, I have a set of data which represents a function. I have done it with Matlab and it gave me the velocities with perfect results however, I need to do the exact process in C++. Reading data which represents position from a file and calculate the first derivative.
Is that data dx,dy,dy (an infinitesimal change) , if so then you can just divide it by a very small number say epsilon = 0.1e-10 or even 0.1e-18.
Does that helps?
Please be more specific about your needs.
This might be of your interest . https://projects.coin-or.org/CppAD
@naruku
you can differentiate value,they are called differentials.
@amhndu,
Thank you,
Actually, I don't know the analytical form of the function. I have a device that gives me position of x, y, z with a given time ( from starting the application until stopping it). So, I need numerical estimation for the derivative of this function which represents the velocities dx, dy, dz ( with assuming the time is given).
what do you mean by saying divide them by a very small number? With Matlab, it is trivial. I need only to invoke diff() and this function returns the first derivative of the function without knowing the analytical form of it.
My device is running at rate 1kHz.
Every 1ms I'm getting new data. I have f(xn) and t, but what about f(x_n-1)? Does it represent the last data? My understanding for n-1 is the last data.
Let's say f(xn) = 0.212 and after 1ms I've got f(xn) = 1.234. Now
f(x_n-1) = 0.212
f(xn) = 1.234
t = 1m
f'(xn) = ( 1.234 - 0.212 ) / 1m ??? I'm getting huge data.
@amhndu,
I'm still confused with cppad and I need a little time to use it properly. But if the case as you mentioned, so why I need to use it?
What are you dividing by here? If you're getting new data every 1ms, you should be doing f'(xn) = (1.234-0.212)/.0001 = 10,220.
f'(xn) = (1.234-0.212)/.001 = 1022 m/s. (Unit correction by Alreddor.)
If, like you said, you are receiving data every 1ms, and an object moves from a point 0.212m from the origin to 1.234m from the origin, it's velocity is very large (1ms is a very small amount of time.) So you should expect a large number if those two data points are truly 1ms apart.
@Thumper,
Sorry my bad. Yes you are right since the difference is very very small in time from changing an object from position to another. About 1ms, this is what the manual of the device is saying about the servo Loop of the device
Ah. Well it depends on what you're doing with that servo and what you're measuring as to how you calculate the time difference between two position points. Can you elaborate more on your project?
@Thumper,
Basically, I have a device (manipulator) running with very high speed 1kHz. This device is supported with API that allows the user to get its info (positions of end-effector, velocities, joint angles, ...). I have stored positions in a file (x, y, z) and by Matlab I've got the first derivative which represents the velocities. Why do I need to calculate the velocities? I have a mathematical model and control algorithms to control another device(slave). Now, I need to send the positions of the Master and in the slave side I need to calculate the velocities which are required to the control algorithm. But I'm stuck with that in C++. I'm using C++ because I'm dealing with real time process.
Thumper has a decimal place wrong for the time. It should be t = .001
Even then the velocity would still be 1022 meters/sec. You would be breaking the sound barrier. Is it possible you have the wrong units on your positions? Centimeters or millimeters instead of meters?
The formula is velocity = ( currentPosition - previousPosition ) / timeInterval
(For a sequence of values xn separated by time t, as before.)
Rather than using (Alg #1)
f'(x) = ( f(xn) - f(xn-1) ) / t
or the n/n+1 variant, you might want to consider using (Alg #2)
f'(x) = ( f(xn+1) - f(xn-1) ) / 2t
This gives better accuracy in the most part (it's the solution of the quadratric polynominal interpolation, which amounts in this case to taking the mean of the values calculated using n-1/n and n/n+1)
@andywestken
I would like to implement this
- Alg#3 = 4/3 (f(xn+1) - f(xn-1)) / 2t - 1/3 (f(xn+2) - f(xn-2)) / 4t
In C++ programming, where should I start? Also, about t, I'm sending data over the Internet using UDP, so is it ok to set t as 0.001. I'm assuming there is no delay and there is no dropped packet. I will be happy at least to start the project then enhance it by considering the delay time and dropped packet.
This is my code
1 2 3 4 5 6 7 8 9 10
double FirstDerivative(double a[5])
{
double firstDer(0);
double t(0.001);
for (int i = 0; i < 5; ++i)
{
firstDer = ((double)(4/3*2*t))*(a[i+1] - a[i-1]) -
((double)(1/3*4*t))*(a[i+2] - a[i-2]);
}
}
double FirstDerivative(double currentData[5])
{
double firstDer(0.0);
double t(0.001);
// no loop here as 5 points is just enough to calculate the derivative
// of one elem (the middle one). If you do use a loop, it has to start
// at 2 and end 2 elems before the end (so i - 2 and i + 2 are always
// valid indexes for the array.)
size_t i(2);
firstDer = ( 4.0 / 3.0 * (a[i + 1] - a[i - 1]) / (2.0 * t)
- 1.0 / 3.0 * (a[i + 2] - a[i - 2]) / (4.0 * t) );
// Rather than use (double)4 you can just use 4.0. The .0 tells the
// compiler you mean a double (if you need a float instead, append
// an f, like 3.0f )
return firstDer;
}