我注意到,与RK4算法或Mathematica的实现相比,odeint使用的内存非常少。对于相同的步长,odeint使用大约3.11GB,而我的程序使用7GB,使用Mathematica,我必须手动将页面文件大小增加到40GB,否则就会耗尽内存。(编辑:CPU使用率仅为18%)
我很好奇这是怎么可能的,因为当我保存结果时,在所有三种情况下,数据文件的大小几乎相同。
然而,说到执行时间,odeint似乎比我的程序或Mathematica慢了一个数量级。这种权衡正常吗?我用超级noob的方式做事。
编辑:2**步长与执行时间**
- 0.0005=2:55.59~24.44小时,500步
- 0.001=1:29.14~12.5小时,500步
- 0.005=0:17.19~2.5小时,500步
- 0.01=8.34~1hr10min,500步
例如:
void Classical(vector<vector<double> >& u1,vector<vector<double> >& u2,vector<vector<double> >& phi1,vector<double>& delta,vector<vector<double> >& theta,vector<vector<double> >& phi2, vector<double>& Gamma,vector<double>& z,double h,double u10,double u20,double theta_initial){
for(int i=0;i<delta.size();++i){
double v1=u10;
double v2=u20;
double ph1=0.0;
double ph2=0.0;
double angle=delta[i]; //OK
u1.push_back ( vector<double>() );
u2.push_back ( vector<double>() );
phi1.push_back ( vector<double>() );
phi2.push_back ( vector<double>() );
theta.push_back ( vector<double>() );
for(int j=0;j<z.size();++j){
double k1=0.0; double k2=0.0;double k3=0.0;double k4=0.0;
double L1=0.0; double L2=0.0;double L3=0.0;double L4=0.0;
double m1=0.0; double m2=0.0;double m3=0.0;double m4=0.0;
double n1=0.0; double n2=0.0;double n3=0.0;double n4=0.0;
k1=h*(v2*v2-1.0)*cos((angle));
L1=h*( (2.0/(1.0-(v2*v2))) - (1.0/(v2*v2)) )*Gamma[i];
m1=h*(1.0/(1.0-(v2*v2)))*Gamma[i];
n1=h*(1.0/((v2*v2)))*Gamma[i];
k2=h*((v2+k1/2)*(v2+k1/2)-1)*cos(((angle+L1/2)));
L2=h*( (2.0/(1-((v2+k1/2)*(v2+k1/2)))) - (1/((v2+k1/2)*(v2+k1/2))) )*Gamma[i];
m2=h*(1/(1-((v2+k1/2)*(v2+k1/2))))*Gamma[i];
n2=h*(1/(((v2+k1/2)*(v2+k1/2))))*Gamma[i];
k3=h*((v2+k2/2)*(v2+k2/2)-1)*cos(((angle+L2/2)));
L3=h*( (2.0/(1-((v2+k2/2)*(v2+k2/2)))) - (1/((v2+k2/2)*(v2+k2/2))) )*Gamma[i];
m3=h*(1/(1-((v2+k2/2)*(v2+k2/2))))*Gamma[i];
n3=h*(1/(((v2+k2/2)*(v2+k2/2))))*Gamma[i];
k4=h*((v2+k3)*(v2+k3)-1)*cos(((angle+L3)));
L4=h*( (2.0/(1-((v2+k3)*(v2+k3)))) - (1/((v2+k3)*(v2+k3))) )*Gamma[i];
m4=h*(1/(1-((v2+k3)*(v2+k3))))*Gamma[i];
n4=h*(1/(((v2+k3)*(v2+k3))))*Gamma[i];
v2=v2+(k1/6)+(k2/3)+(k3/3)+(k4/6);
angle=angle + (L1/6)+(L2/3)+(L3/3)+(L4/6);
ph1=ph1+(m1/6)+(m2/3)+(m3/3)+(m4/6);
ph2=ph2+(n1/6)+(n2/3)+(n3/3)+(n4/6);
v1=sqrt(1.0-(v2*v2));
u1[i].push_back(v1);
u2[i].push_back(v2);
theta[i].push_back(angle);
phi1[i].push_back(ph1);
phi2[i].push_back(ph2);
}
}
}
我认为您应该以发布方式编译程序,以实现编译器优化。odeint使用了大量的模板代码,在调试模式下编译时速度相当慢。在发布方式上,性能将提高几个数量级。