I am attempting to test some discrete time functions against their continuous counterparts and I am surprised by how inaccurate the discrete versions are coming out.
I am modeling the displacement, velocity, and acceleration of an ideal string struck by a mass as per: https://www.dsprelated.com/freebooks/pasp/Ideal_String_Struck_Mass.html
This gives displacement as:
$y(t) = \frac{v*m}{2R}*(1-e^{\frac{-2Rt}{m}})$
Velocity as a function of time is:
$v(t) = v*e^{\frac{-2Rt}{m}}$
Acceleration can be derived from velocity:
$a(t) = \frac{-2Rve^{\frac{-2Rt}{m}}}{m}$
A discrete time formula for velocity using the displacement output from the first continuous function is:
$v(s) = sy(s)$
$v[n] = \frac{y[n] - y[n-1]}{T}$
A discrete formula for acceleration from displacement is:
$a(s) = s^{2}y(s)$
$a[n] = \frac{y[n-2] - 2y[n-1] + y[n]}{T^{2}}$
Mostly the discrete formulas seem to give normal output that matches the continuous equations. It seems close at the start and finish. However, at some points it's shocking how far off it is.
Here's some basic code to test this:
displacement_2 = displacement_1;
displacement_1 = displacement;
displacement = ((velocity * mass)/ (2 * impedance)) * (1 - exp(-2 * impedance * timer / mass));
velocityContinuous = velocity * exp((-2 * impedance * timer) / mass);
velocityDiscrete = (displacement - displacement_1) / deltaTime;
accelContinuous = (-2 * impedance * velocity * exp((-2 * impedance * timer) / mass)) / mass;
accelDiscrete = (displacement_2 - (2 * displacement_1) + displacement)/(deltaTime*deltaTime);
timer = timer + deltaTime;
...
deltaTime = 1/sampleRate;
velocity = 8.f;
impedance = 0.5f;
mass = 0.004f;
At some points I'll get output like:
velocityContinuous: 2.81216 velocityDiscrete: 3.47256
velocityContinuous: 2.78302 velocityDiscrete: 3.45452
...
accelContinuous: -840.176 accelDiscrete: -1089.63
accelContinuous: -831.469 accelDiscrete: -1083.97
...
That's a pretty massive error. Is this normal? Or have I done something wrong? Sample rate is 96 kHz.
On another note, accelDiscrete puts out 0 first sample, then an insanely large number of the wrong sign second sample, then "correct" output after that. velocityDiscrete puts out 0 first sample then normal output. I assume this is because displacement_2 and displacement_1 are 0 at initialization and it can't calculate properly from them. Is there any typical fix for this type of behavior, particularly accelDiscrete which is putting out a crazy number on the second sample?