0

私の質問は数値レシピに関するものです。共役勾配ソルバー「frprmn.cpp」を使用して、データやその他のパラメーターに依存する問題の負の対数尤度関数を最小化しようとしています。対数尤度を評価するためにすべての関連パラメーターとデータを利用できるようにするために、クラスを作成しました。対数尤度関数と勾配関数の両方がそのクラスのメンバー関数です。これらの関数を引数として frprmn を呼び出すと、エラー メッセージが表示されます。

タイプ 'DP (kalman_yield_only::)(Vec_I_DP&) {aka double (kalman_yield_only::)(const NRVec&)}' の引数は 'DP (*)(Vec_I_DP&){aka double (*)(const NRVec&)}' と一致しません

目的の対数尤度関数と勾配関数は、kalman_yield_only.cpp という名前のファイルで次のように定義されています。このファイルでは、kalman_yield_only という名前のクラスも定義されています。

DP kalman_yield_only::llh(Vec_I_DP& theta)
{
    ...code...;
    DP L_num=...;
    return L_num;
}

勾配関数は次のとおりです。

void kalman_yield_only::llh_grad(Vec_I_DP& theta, Vec_O_DP& grad)
{
    ...code...;
}

同じファイルには、ソルバーを呼び出すメンバー関数もあります。

void kalman_yield_only::optimizer(Vec_IO_DP& theta)
{   
    const double ftol = 1e-6;
    double fret;
    int iter;
    NR::frprmn(theta,ftol,iter,fret,kalman_yield_only::llh,kalman_yield_only::llh_grad);
}

次に、全体がメインで呼び出されます

int main(int arg, char* pszArgs[])
{
    ...code for data and parameters...;
    kalman_yield_only ks(...data and parameters...);
    ...code for theta...;
    ks.optimizer(theta);
    ...code for doing stuff with theta...;
    return 0;
}

kalman_yield_only.h には次の行があります

class kalman_yield_only
{
 public:
  kalman_yield_only(Mat_IO_DP& , Mat_IO_DP& , Vec_IO_DP& , Vec_IO_DP& , Mat_IO_DP& ,   Mat_IO_DP& , DP& , DP& , DP& , DP& , DP&, Vec_IO_DP& );

// All sorts of data and parameter object declarations...

  // Member functions
  DP llh(Vec_I_DP &);
  void llh_grad(Vec_I_DP & , Vec_O_DP & );
  void optimizer(Vec_IO_DP& );
};

kalman_yield_only.cpp の対応するコンストラクターは次のように読み取ります。

kalman_yield_only::kalman_yield_only(Mat_IO_DP& Y_in, Mat_IO_DP& Z_in, Vec_IO_DP& vH_in, Vec_IO_DP& c_in, Mat_IO_DP& mT_in, Mat_IO_DP& Q_in, DP& maxZ_in, DP& maxT_in, DP& maxQ_in, DP& maxc_in, DP& tol_in, Vec_IO_DP& Maturities_in )
{
    … code...;
}

関数呼び出しで NR:: および kalman_yield_only:: プレフィックスを追加および削除するすべての順列を試してみましたが、役に立たなかったと思います。同じコンパイラとメイクファイル インフラストラクチャを使用して数値レシピからサンプル ファイル「xfrprmn.cpp」をコンパイルすると、問題なくコンパイルおよび実行されます。目的ルーチンと勾配ルーチンがクラスのメンバー関数であることを除けば、自分のコードと大きな違いは見られません。どんな助けでも大歓迎です。

4

2 に答える 2

0

タイプ 'DP (kalman_yield_only::)(Vec_I_DP&) {aka double (kalman_yield_only::)(const NRVec&)}' の引数は 'DP (*)(Vec_I_DP&){aka double (*)(const NRVec&)}' と一致しません

これは、関数が必要な場所でメソッド (非表示の this ポインターが必要) を使用しようとしていることを意味します。C++ の Numerical Recipes は、実際には C++ ではありません。グローバル/静的変数を使用する必要があるためです!!!!

渡す関数がテンプレート引数になるように Numerical レシピを編集すると思います。つまり、ベクトル引数が必要で double を返す以外は、使用する場所では定義されていません。

    template<typename FUNCTION>
    frprmn(..., const FUNCTION &_rF, ....)
    {
            ...
    }

そのように frprmn を記述しても、通常の関数ポインターを渡すことができます。

次に、すべての情報を含むクラスの operator() として関数を定義します。

    struct YourClass
    {
            double operator()(const NRVec&) const;
    };
于 2013-11-03T21:34:52.057 に答える