python新手:移植ODE模型

时间:2015-08-22 16:22:43

标签: python matlab ode

我正在尝试将我的MATLAB代码移植到python,但我遇到了一些索引问题。我下面粘贴的代码是我计划使用scipy.integrate.odeint解决的ode模型。

我遇到的第一个问题是代码z[i-np.arange(0,(i-1))的索引问题(MATLAB中的等价物是z(i-[1:(i-1)])

尝试使用ode模型的python函数:

def myModel(z,t,k,R,R2,N):

k1=k[0]
k2=k[1]
k3=k[2]

V=1/1.5*(75*z[0]+np.dot((75+57*np.arange(1,np.size(z)-2)),z[1:-2])+114*z[-2])+18*z[-1]

dzdt=np.zeros(N+2)

dzdt[0]=( 1/V*(-2*k1*z[0]*sum(z[0:-2])              
+2*k2*z[-1]*sum(z[1:-2])) ) 

dzdt[1]=( 1/V*(-2*k1*z[1]*sum(z[0:-2])          
+k1*z[0]*z[0]                               
-k2*z[1]*z[-1]                      
-k3*z[1]*V                                      
+2*k2*z[-1]*sum(z[2:-2])              
+k2*z[-2]*z[-1]) )

for i in range(2,len(z)-3):
    dzdt[i]=( 1/V*(-2*k1*z[i]*sum(z[0:-2])          
    +k1*np.dot(z[0:i],z[-(len(z)-i+1)::-1])     
    -k2*z[i]*z[-1]*i                        
    +2*k2*z[-1]*sum(z[i+1:-2])) ) 

dzdt[-3]=( 1/V*(            
+k1*np.dot(z[0:i],z[-(len(z)-i+1)::-1])
-k2*z[i]*z[-1]*i) )

dzdt[-2]=1/V*(k3*z[1]*V-k2*z[-1]*z[-2])
dzdt[-1]=1/V*(k1*sum(z[0:-2])**2-k2*z[-1]*np.dot(np.arange(0,len(z)-2),z[0:-2])+k3*z[1]*V-k2*z[-1]*z[-2]-V*(R*z[-1]/(sum(z))-R2))


return dzdt    

ode模型的原始MATLAB函数:

function dzdt=ode(t,z,k,R,R2)


k1=k(1);
k2=k(2);
k3=k(3);


V=1/1.5*(75*z(1)+(75+57*[1:length(z)-3])*z(2:end-2)+114*z(end-1))+18*z(end);

dzdt=zeros(size(z));

dzdt(1)=1/V*(-2*k1*z(1)*sum(z(1:end-2)) ...             
    +2*k2*z(end)*sum(z(2:end-2)));                  

dzdt(2)=1/V*(-2*k1*z(2)*sum(z(1:end-2)) ...         
    +k1*z(1)*z(1) ...       
    -k2*z(2)*z(end) ...                     
    -k3*z(2)*V ...                                      
    +2*k2*z(end)*sum(z(3:end-2)) ...         
    +k2*z(end-1)*z(end));

for i=3:length(z)-3
    dzdt(i)=1/V*(-2*k1*z(i)*sum(z(1:end-2)) ...         
        +k1*z(1:i-1)'*z(i-[1:(i-1)]) ...        
        -k2*z(i)*z(end)*(i-1) ...                       
        +2*k2*z(end)*sum(z(i+1:end-2)));                       
end

dzdt(end-2)=1/V*( ...           
    +k1*z(1:i-1)'*z(i-[1:(i-1)]) ...        
    -k2*z(i)*z(end)*(i-1) ...                       
    );                          
dzdt(end-1)=1/V*(k3*z(2)*V-k2*z(end)*z(end-1));
dzdt(end)=1/V*(k1*sum(z(1:end-2))^2-k2*z(end)*[0:length(z)-3]*z(1:end-2)+k3*z(2)*V-k2*z(end)*z(end-1)-V*(R*z(end)/(sum(z))-R2));

end

提前感谢任何建议

1 个答案:

答案 0 :(得分:0)

我会给你两个提示:

  • 在Python中,你不能像在matlab中那样乘以向量。如果V是数组/列表,V'*V将返回matlab中的逐元素产品。在Python(numpy)中,您可以使用numpy.dot来计算两个向量的点积。
  • 您可以使用以下格式在numpy中切片向量:v [start:stop:step]。见the documentation about slicing。例如,v[::-1]为您提供反向向量。

为了说明这一切:

import numpy
a=numpy.array([1,2,3])
b=numpy.array([4,5,6])
a*b              # returns array([ 4, 10, 18])
numpy.dot(a,b)   # returns 32
sum(a*b)         # returns 32

结合上述提示,您不再需要arange

最后一点:社区很乐意帮助您解决问题,但我们免费提供编码服务。尝试展示你尝试过的东西,并尽量展示你的问题,而不是给我们很多线。这将导致更少的downvotes和更多的答案。