pbhuter
pbhuter

Reputation: 437

Appending to NumPy (Python) Array

For starters, I am doing a Runge-Kutta on a three-DOF NumPy array. My array looks like this:

states = [[X], [Vx], [Y], [Vy], [Z], [Vz]]

I run my Runge-Kutta, and get my four K values, which I transpose with [newaxis]. So when I try to append the new states to my states array as follows:

states = append(states, states[:,i] + (K1.T + 2 * K2.T + 2 * K3.T + K4.T)/6, 1)

where "i" is a counter that starts at 0 and counts up for each iteration.

However, when I run my code my resulting states array is not two columns of six elements. It appears that I am appending a row vector instead of a column vector to my states array. I ran the code with two elements (X, Vx) in the column, and everything appended just fine (or at least my result made sense).

I have tried forcing the result of my Runge-Kutta to be a column vector, but that messes up my calculation of the K-values. I have tried variations of my append code, and still have the same result.

This is a clone of a Matlab code, and I have been unable to find anything on NumPy arrays and indexing that helps me.

Any help is appreciated.

Thanks.

UPDATE: states[:,0] = [[0], [2300], [0], [0], [-1600], [500]] - original states[:,1] = [[2300], [2100], [0], [0], [-2100], [450]] - append states = [[0, 2300], [2300, 2100], [0, 0], [0, 0], [-1600, -2100], [500, 450]] - final These are column vectors.

Upvotes: 0

Views: 608

Answers (2)

Hugo Cavalcante
Hugo Cavalcante

Reputation: 89

You should not append arrays, if you can avoid, due to efficiency issues. Appending means changing the allocated memory size, which can run into non-contiguous memory space, hence inefficient allocation or reallocation would be necessary. These can slow down your program a lot, specially for large arrays.

If you are implementing a fixed time-step Runge-Kutta you know beforehand how many points your solution is going to have at time T. It's N = (T-t0)/h+1, where T is the final time, t0 the initial time, and h the time step. You can initialize your array with zeros (using states = np.zeros((N,3))) and fill the values as you go, associating the index i to the time t[i] = t0 +i*h. This would be inside the loop: states[:,i+1] = states[:,i] + RK4_step(states[:,i]), where RK4_step(states[:,i]) is a function returning an array (column) with your variation of the state values in one step of the Runge-Kutta method.

Even if your time-step is variable you should still do that, but with nonuniform times t[i] = t0 +i*h.

Or, you could use numpy.integrate.ode_int(), which returns the solution of an ODE at the required times.

Upvotes: 0

MSeifert
MSeifert

Reputation: 152860

You should stack them instead of appending them.

Taken from the numpy documentation you should one of the stack methods, for example: np.vstack:

a = np.array([1, 2, 3])
b = np.array([2, 3, 4])
c = np.vstack((a,b))
print(c)
# array([[1, 2, 3],
#        [2, 3, 4]])

or depending on your resulting data there is also np.hstack (stack along first axis) and np.dstack (stack along third axis).

Upvotes: 1

Related Questions