3

OK, here's a programming/physics puzzle in, let's say Java (although it doesn't really matter - but for consistency, we will use Java).

I have an array of doubles where each element represents the successive derivates of an object's position. So:

d[0] // position
d[1] // velocity
d[2] // accelleration

etc ...

There will be at least 1 and potentially any number of elements (but in practice, probably not more than 5). All elements beyond the end of the array are assumed to be zero.

We also have a double t for time.

So if d.length were 3 then very specifically:

d[0] += d[1] * t + d[2] * t * t / 2
d[1] += d[2] * t

But how can we write an iterative solution (no recursion!) that will update all of the elements of the array for time t for any length of a?

Votes should be awarded for efficiency and conciseness.

EDIT: The laws of motion are on the physics pages of this site, but basically each term has the form:

power(t,n) / factorial(n)

So the next term of the first equation would be d[3] * t*t*t / 6

If you are not familiar with these equations, please don't ask me to explain.

A test case:

final static double[] D = { 5.0, 4.0, 3.0, 2.0, 1.0 };
double t = 10.0

should give:

[945.0, 300.66666666666663, 73.0, 12.0, 1.0]

Second element may vary due to precision errors.

rghome
  • 8,529
  • 8
  • 43
  • 62

2 Answers2

2

I think something like this works.

int length = d.length;
for (int i = 0; i < length - 1; i++) {
    double temp = 0;
    for (int j = length - 1; j > i; j--)
        temp = (temp + d[j]) * t / (j - i);
    d[i] += temp;
}
Paul Boddington
  • 37,127
  • 10
  • 65
  • 116
  • This gives slightly worse rounding errors than the other solutions: [945.0, 300.66666666666674, 73.0, 12.0, 1.0] – rghome Mar 20 '15 at 23:46
  • @rghome It will do yes. The way to calculate powers like `t * t * t * t * t` accurately is to use `Math.pow` (because each successive multiplication introduces another error). So if you want accuracy you actually can't reuse previously calculated answers for `t`, `t * t`, `t * t * t`, `t * t * t * t`. If accuracy is what you want, I don't think you can do better than calculate each of `t`, `t * t / 2`, `t * t * t / 6` from scratch, but I could be wrong. – Paul Boddington Mar 20 '15 at 23:59
  • I got smaller rounding errors doing the divide first, but maybe that will depend on the test case. – rghome Mar 21 '15 at 17:03
1

Updated:

for (int i = 0; i < d.length - 1; i++) {
    d[i] = 0;
    int f = 1;
    double p = 1;
    for (int j = i+1; j < d.length; j++) {
        f *= j - i;
        p *= t;
        d[i] += d[j] * p / f;
    }
}
axblount
  • 2,639
  • 23
  • 27
  • Up-vote for the first answer, but I reckon it should be possible to avoid recalculating the factorial and the power in the inner loop at least. Maybe even in the outer loop. – rghome Mar 20 '15 at 21:30