0

I am writing some code to model the motion of a spring. Given the initial position and velocity of the system, I am trying to calculate the position velocity at a certain time later.

To do this, I am approximating making the approximation x(t+e) = x(t) + ev(t). The position a short time 'e' seconds later is equal to the current position plus e times the velocity.

We can do the same for the velocity. v(t+e) = v(t) + ea(t). The new velocity is the same as the old velocity plus the product of acceleration and time. For a spring, a(t) = -x(t), so we instead have v(t+e) = v(t) - ex(t).

The idea of my programme is to print the position and velocity at certain 'steps' (the step is equal to e).

I defined functions for position and velocity, in accordance with the aforementioned equations.

#include <iostream>
using namespace std;

//Defining the initial state of the system
float initialPosition = 1;
float initialVelocity = 0;
float step = 0.1; 
float duration = 5;

int numberSteps = duration / step;


//Declaring the functions
float position(float t);
float velocity(float t);

//Outputting the position and velocity at time steps
int main() 
{
    cout << "Time \t" << "Position \t" << "Velocity \t" << endl;

    for(int i = 0; i < numberSteps; ++i)
    {
        cout << step * i << "\t" << position(step * i) << "\t \t" << velocity(step * i) << endl;
    }

    return 0;
}


float position(float t)
{
    if(t == 0)
    {
        return initialPosition;
    }
    else 
    {
        return position(t - step) + step * velocity(t - step);
    }
}

float velocity(float t)
{
    if(t == 0)
    {
        return initialVelocity;
    }
    else
    {
        return velocity(t - step) - step * position(t - step);
    }
}

The output I am getting (on textmate) is as follows

Time    Position    Velocity    
0          1            0
0.1        1         -0.1
0.2        0.99      -0.2
bootstrap.sh: line 10:   595 Segmentation fault: 11  "$A_OUT"

I have tried to figure out what the segmentation fault is, but many sources seem to say it has something to do with pointers (which I am not aware of, and haven't used in this programme). I spent an afternoon trying to configure gdb on my mac, to figure out the exact error, but to no avail.

EDIT I understand the problem with floats.

Replacing

if(t == 0){...}

with

if(t < 0.1 * step){...} 

seems to have done the trick.

Andriy Ivaneyko
  • 15,838
  • 3
  • 43
  • 65
lagrange103
  • 139
  • 3
  • 6
  • See [Comparing floating point number to zero](http://stackoverflow.com/questions/19837576/comparing-floating-point-number-to-zero). – Anto Jurković Jan 20 '16 at 07:44

3 Answers3

2

You have a neverlasting recursion of velocity and the program crashes when the stack is over. The wrong comparison is in line 45: if (f == 0) where f is float.

dmi
  • 1,423
  • 1
  • 7
  • 9
  • I don't understand what you mean by a 'neverlasting recursion of `velocity`' – lagrange103 Jan 20 '16 at 07:40
  • 1
    You have a condition in the line 45 whether to recursively call `velocity` or do something else. And in your case the condition does not work as you have expected and the function velocity always calls itself. This leads to the stack overflow. – dmi Jan 20 '16 at 07:47
1

Never ever use == comparisions with floating point numbers, 3 * 0.1 is 0.30000000000000004 so it looks like your program goes into infinite loop.

Instead try to model time in discrete domain (in other words use int) and compute real time like this float t = nQuants * quantDuration where quantDuration may be equal 0.1f or other small value.

csharpfolk
  • 3,778
  • 20
  • 26
1

the problem is the recursion, which doesn't stop (for 0 is never reached exactly)

change the compares "if (t == 0)" into "if (t <= 0)", and stop relying on floats, they're very unsafe (due to binary->float conversation)

Tommylee2k
  • 2,572
  • 1
  • 7
  • 21