Reputation: 5
I have a 300 x 4 matrix called X created by the odeint function. In the second column are y-values and I would like to cut the matrix when the y-value dips below 0. As a first step I was attempting to create a function that would read the second column and spit out the row number where the column first dips below 0.
X = odeint(func, X0, t)
Yval = X[:,1]
def indexer():
i = 0
if Yval[i] > 0:
i = i + 1
if Yval[i] < 0:
return i
Which is not working and conceptually I know this is wrong, I just couldn't think of another way to do this. Is there a way to cut out all the rows that contain and follow the first <0 y value?
This is my entire code:
import numpy as np
import math
from scipy.integrate import odeint
g = 9.8
theta = (45 * math.pi)/180
v0 = 10.0
k = 0.3
x0 = 0
y0 = 0
vx0 = v0*math.sin(theta)
vy0 = v0*math.cos(theta)
def func(i_state,time):
f = np.zeros(4)
f[0] = i_state[2]
f[1] = i_state[3]
f[2] = -k*(f[0]**2 + f[1]**2)**(.5)*f[0]
f[3] = -g - k*(f[0]**2 + f[1]**2)**(.5)*f[1]
return f
X0 = [x0, y0, vx0, vy0]
t0 = 0
tf = 3
timestep = 0.01
nsteps = (tf - t0)/timestep
t = np.linspace(t0, tf, num = nsteps)
X = odeint(func, X0, t)
Yval = X[:,1]
def indexer():
i = 0
if Yval[i] > 0:
i = i + 1
if Yval[i] < 0:
return i
Upvotes: 0
Views: 385
Reputation: 1375
You could do something like this:
newVals = []
i = 0
while( i < len(X) and X[i][1] >= 0):
newVals.append(X[i])
i += 1
This would go through X
and append values to the list newVals
until you either reach the end of the list (i < len(X)
) or you reach your condition (X[i][1] >= 0
).
Upvotes: 0
Reputation: 3892
Maybe you could use the takewhile
function from the itertools
package:
from itertools import takewhile
first_elements = list(takewhile(lambda x: x[1] >= 0, X))
Where X
is your matrix. I used x[1]
in the lambda
predicate to compare the numbers in the second column.
Here, first_elements
will be the rows of the matrix before the first row that contains a value less than zero. You can use len(first_elements)
to know what the cutoff point was.
I converted it to a list but you don't have to if you are just going to iterate through the result.
I hope this works.
Upvotes: 2