Reputation: 437
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
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
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