Reputation: 447
I have a system of diff eqs in a m*m matrix S. S[i,j] is a particular species concentration and is affected by S[i-1,j] and S[i,j-1]
I can get dx/dt of each entry at each step (returned by update_matrix) but then I need to integrate it to update my initial concentrations (x same as x_counts). However scipy's integrate.odeint does not accept matrices as input ( or return value and raises the object too deep error.
Any way I can tweak this to use the integrator on the matrix? I provided a piece of the code: diffeq returns dx/dt for each entry. update_matrix returns matrix B where B[i.j]=dx[i,j]/dt
def diffeq(x,i,j,coeffs):
if (i==1 and j==0):
return (-(coeffs.M(1,0)-coeffs.L(1,0)))+coeffs.d(1,0)-coeffs.get_phi()*x[1][0]
elif j==0:
return (-(coeffs.M(i,0)+coeffs.L(i,0)))*x[i][0]+coeffs.L(i-1,0)*x[i-1][0]+coeffs.d(i,j)-coeffs.get_phi()*x[i][0]
elif (i>1 and j>0):
return (-(coeffs.M(i,j)+coeffs.L(i,j)))*x[i][j]+coeffs.M(i,j-1)*x[i][j-1]+coeffs.L(i-1,j)*x[i-1][j]+coeffs.d(i,j)-coeffs.get_phi()*x[i][j]
elif i==1 and j>0:
return (-(coeffs.M(1,j)+coeffs.L(1,j)))*x[1][j]+coeffs.M(1,j-1)*x[1][j-1]+coeffs.d(1,j)-coeffs.get_phi()*x[1][j]
elif i==0 and j==1:
return -x[0][1]+coeffs.d(0,1)-coeffs.get_phi()*x[0][1]
elif i==0 and j>1:
return -j*x[0][j]+(j-1)*x[0][j-1]+coeffs.d(0,j)-coeffs.get_phi()*x[0][j]
def update_matrix(x,coeffs,m):
update_matrix=numpy.zeros((m,m))
for i in range(m+1):
for j in range(m+1-i):
update_matrix[m][m]=diffeq(x,i,j,coeffs)
return update_matrix
def run_simulation_R2(a,q,m):
x_counts=numpy.zeros((m,m))
x_counts[1][0]=1
x_counts[0][1]=1
coeffs=R2(a,q,m,x_counts)
t=range(0,100)
output = integrate.odeint(update_matrix, x_counts, t, args=(coeffs, m))
Upvotes: 2
Views: 1140
Reputation: 67427
If odeint
expects a vector, not a matrix, you are going to have to give it a vector. If you don't want to change the logic of your code to much, you can make x
be an (m**2,)
vector outside your functions, but still an (m, m)
matrix inside, by liberally applying .reshape(-1)
everywhere needed. You didn't provide us with enough information to test it fully, but something like this may work:
def update_matrix(x,coeffs,m):
x = x.reshape(m, m)
update_matrix=numpy.zeros((m,m))
for i in range(m+1):
for j in range(m+1-i):
update_matrix[m][m]=diffeq(x,i,j,coeffs)
return update_matrix.reshape(-1)
def run_simulation_R2(a,q,m):
x_counts=numpy.zeros((m,m))
x_counts[1][0]=1
x_counts[0][1]=1
coeffs=R2(a,q,m,x_counts)
t=range(0,100)
output = integrate.odeint(update_matrix, x_counts.reshape(-1), t,
args=(coeffs, m))
return output.reshape(m, m)
Upvotes: 3