4

簡単な質問で申し訳ありませんが、odeint の状態変数の進化をダウンサンプリングするための「ベスト プラクティス」はありますか?

以下に、この記事 ( http://www.codeproject.com/Articles/268589/odeint-v2-Solving-ordinary-differential-equations )

struct streaming_observer
{
     std::ostream &m_out;

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

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

// ...

integrate_const( runge_kutta4< state_type >() , lorenz , x , 0.0 , 10.0 , dt , streaming_observer( std::cout ) );

オブザーバーをどのように変更して、10 ステップごとに状態のみをログに記録しますか (たとえば)。ifステートメントを入れるよりもエレガントな解決策があるかどうか疑問に思っています:

struct streaming_observer
{
  std::ostream &m_out;
  int count;

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

  void operator()( const state_type &x , double t ) const
  {
    if( count == 10 )  {
      count = 1;
      m_out << t;
      for( size_t i=0 ; i < x.size() ; ++i )
        m_out << "\t" << x[i];
        m_out << "\n";
      }
      else {
        count++;
      }
   }
};
4

2 に答える 2

3

私は同じ問題を抱えていて、あなたとまったく同じように解決しました。ただし、ステップサイズ制御でステッパーを使用することを検討してから、必要な間隔でオブザーバーが呼び出されるように dt で integrate_const を使用することもできます。ステップ サイズ制御でステッパーを使用する場合 (さらに良い: dopri5 のような高密度出力)、integrate_const は許容誤差に従ってステップ サイズを調整しますが、オブザーバーが時間 t0 + n*dt で呼び出されることを保証します。

于 2013-12-04T10:08:49.770 に答える
2

実際、私はあなたがしたのとまったく同じようにします。ストライディングを行うための小さなアダプターを作成することもできます。

template< typename Obs >
struct striding_observer {
    size_t stride , count;
    Observer obs;
    striding_observer( size_t s , Obs o ) : stride(s) , count(1) , obs(o) { }
    template< typename S , typename T >
    void operator()( State const& s , Time const& t ) {
        if( count == stride ) {
            obs( s , t );
            count = 1;
        } else {
            ++count;
        }
    }
};

template< typename Obs >
striding_observer< Obs > make_striding_observer( size_t stride , Obs o ) {
    return striding_observer< Obs >( stride , o );
}

次に、ストライディングはオプションであり、構成可能です。次に、最初の例を次のように書くことができます

integrate_const( runge_kutta4< state_type >() ,
    lorenz , x , 0.0 , 10.0 , dt ,
    make_striding_observer( 10 , streaming_observer( std::cout ) ) );
于 2013-12-04T07:12:11.500 に答える