odeint流观测及相关问题(odeint streaming observer and relat

2019-06-27 10:48发布

我有4个耦合方程的系统来解决和参数伽玛[I]进行迭代。 由于我很新的C ++,我的代码是一个非常基本的。 如果它看起来复杂,在某些地区优雅,那只是因为我已经从odeint的作者改编代码。 :)

这个问题是有关(http://stackoverflow.com/questions/12060111/using-odeint-function-definition/12066958#comment16253600_12066958),但不完全相同。 请不要删除。 :(

问题已被插入的代码行之间。

#include <iostream>
#include <iterator>
#include <algorithm>
#include <boost/numeric/odeint.hpp>
#include <cmath>
#include <vector>
#include <fstream>
#include <iomanip>

using namespace std;
using namespace boost::numeric::odeint;
class NLI_class {
private:
    double gamma;
public:
 NLI_class (double r) : gamma(r) {} 

 void operator()( vector<double> &u , vector<double> &du , double z ) {
            du[0] = u[0]*u[1]*cos(u[3]); //u1
            du[1] = -u[0]*u[0]*cos(u[3]); //u2
            du[2] = gamma * (2/(u[0]*u[0]) - 1/(u[1]*u[1])); //theta
            du[3] = gamma * (1.0/(u[0]*u[0])); //phi1
            du[4] = gamma * (1.0/(u[1]*u[1])); //phi2;

}
};

问题1:

在我原来的计划,我有这样的事情,以管道输出到一个CSV文件:

 inline void save(vector<double>& v, string filename)
  {
ofstream output(filename);
for(int i=0;i<v.size();++i){ 
    output << setprecision(64) << v[i] << endl;
}
   }

如何适应streaming_observer做什么我保存()呢? 基本上,我要生成的.csv每个迭代i文件。 在这一点上,我做它的丑陋的方式,即编译一切,打开Windows命令提示符,然后通过管道将EXE输出到一个文本文件中。 这会产生与存在抛出的所有迭代一个大文件。

这变得很痛苦来分析大量的迭代。

struct streaming_observer {

 std::ostream &m_out;
 streaming_observer( std::ostream &out ) : m_out( out ) {}

 void operator()( const vector<double> &x , double t ) const
 {
      m_out << t;
      for( size_t i=0 ; i < x.size() ; ++i )
          m_out << "\t" << x[i];
      m_out << "\n";
 }
};




    int main(){

vector<double> x( 5 );
vector<double> Gamma;
vector<double>delta;
const double  pi=acos(-1.0); 
short delta_n=5;
const double delta_step=(2*pi)/delta_n;
const double dz = 0.01;
const double  zeta = 3.0;
const double  theta_initial=0.0;
const double  u20=tanh(zeta); 
const double  u10=sqrt(1.0-(u20*u20)); 

double d=0.0;
double G=0.0;

for(int i=0;i<=delta_n;i++){
    //When i=0, the d=0.0 and G=0.0 are pushed into the vector.
    delta.push_back(d);  
    Gamma.push_back(G);
    // Compute delta and Gamma
    d=d+delta_step; 
    G=-u10*u10*u20*sin(theta_initial+d);
}

save(delta,"delta.csv");
save(Gamma,"Gamma.csv");

问题2:我这里得到的结果不与我有什么,我开始使用一个简单明确的欧拉法得到同意。 因此,我希望看到的RK4系数(优选其转储到一个文件)或中间步骤。 我怎样才能得到这些信息?

//Numeric Integration
    for (unsigned i = 0; i < Gamma.size(); ++i) {
        x[0] = u10;
        x[1] = u20;
        x[2] = 0.0;
        x[3] = 0.0;
        x[4] = 0.0;

        NLI_class nli_obj(Gamma[i]);
        integrate_const( runge_kutta4< vector<double > >(), nli_obj, x , 0.0 , 3.0 , dz,streaming_observer( std::cout ) );
}
    }

感谢您对所有那些谁帮助!

编辑:有没有办法让一个正在运行的错误估计是多少? 注意,U [0] * U [0] + U [1] * U [1]在所有时间= 1。

Answer 1:

问题1:

我不正是你需要什么样的输出的了解。 但是,如果你想写的结果在每次迭代后可以实现输出观察者是这样的:

struct output_observer
{
    string filename_;
    size_t count_;
    output_observer( const string &filename ) : filename_( filename ) , count_( 0 ) { }
    void operator()( const state_type &x , time_type dt )
    {
        char fn[512] = "";
        sprintf( fn , "%s_%04lu.csv" , filename_.c_str() , count_ );
        ofstream fout( fn );
        for( size_t i=0 ; i<x.size() ; ++i ) fout << x[i] << "\n";
        ++count_;
    }
};

你可以简单地将此观察员

integrate_const( runge_kutta4< vector<double > >() , nli_obj , x ,
    0.0 , 3.0 , dz , output_observer( "filename" ) );

这是所需的功能?

问题2 :

这是不可能看到runge_kutta4的中间体E步骤。 该系数的标准对那些经典的龙格-库塔方法: http://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods

问题3:

odeint有几个错误的步进器,其中估计在一个步骤中所做的错误。 您可以使用例如Runge_Kutta现金卡普算法;

runge_kutta_cash_karp54< state_type > rk;
state_type xerr;
rk.do_step( nli_obj , x , t , xerr );

这让一步,估计误差和XERR写入错误的结果。



文章来源: odeint streaming observer and related questions