NAGライブラリを使ってパラメータ制限がある積分関数をフィットする

サマリー

このチュートリアルを始める前に、NAGライブラリを使った積分フィットを読むことをお薦めします。そして、プログラミングに関する部分については、2つのチュートリアルは基本的に同じで、異なる点は、ここでは積分制限を持つフィットパラメータでのOrigin Cのフィット関数を定義することを学びますが、前のチュートリアルでは、積分制限での独立変数を定義します。また、ここでは別のNAG積分関数が使われています。

必要なOriginのバージョン:8.0 SR6

学習する項目

このチュートリアルでは、以下の項目について説明します。

  • NAGの積分ルーチンを使って、定積分でのフィット関数を作成します。
  • パラメータの積分制限を持つフィット関数を作成します。
  • log関数を使って、フィット関数から大きな戻り値のスケールに合わせます。

サンプルとステップ

例えば、次のモデルを使って、このページの一番下にあるサンプルデータ をフィットしましょう。

y=\int_{c}^{d} \frac { \cosh { ((x_i + b^2 \cdot x^2) /(b + x))}}{a+(x_i^2+x^2)}\, dx_i

x_i \, を使って積分の独立変数を示していますが、 x \, はフィッティングの独立変数を示していることに注意して下さい。モデルのパラメータx \,, x \,, x \,, x \, は、サンプルデータから取得したいフィットパラメータです。データを準備するには、サンプルデータをOriginのワークシートにコピーする必要があります。フィットの手順は、前のチュートリアルと同じように行います。

フィット関数オーガナイザでフィット関数を定義する

F9 を押して、フィット関数オーガナイザを開き、最初のチュートリアルと同様に、ユーザ定義の積分フィット関数 nag_integration_fitting_cosh をカテゴリーFittingWithIntegral に追加します。

   
関数名: nag_integration_fitting_cosh
実現方式: ユーザ定義
独立変数: x
従属変数: y
パラメータの名前: a, b, c, d
定義形式: Origin C
関数:  

関数」ボックスの近くにあるボタン(アイコン)をクリックしてコードビルダを開き、次のようにフィット関数を定義して、コンパイルします。(Note:コンパイル後に関数を保存して関数オーガナイザダイアログに戻る事を忘れないでください。)

#include <origin.h>
// ここにincludeファイルを追加します。
// 例えば、NAGライブラリからの関数でフィットする場合、
// ここにNAG関数のヘッダファイルを追加します。
#include <oc_nag8.h>
 
 
// このファイルに定義したい他のOrigin C関数に対するコードをここに追加し、
// フィット関数でアクセスできるようにします。
struct user
{
        double a, b, fitX;  // fitX はフィット関数の独立変数です。
 
};
static double NAG_CALL f_callback(double x, Nag_User *comm)  // x は被積分関数の独立変数です。
{
 
        struct user *sp = (struct user *)(comm->p);
 
        double aa, bb, fitX; // 一時変数としてNag_User 通信構造体のパラメータとして受け入れます
        aa = sp->a;
        bb = sp->b;
        fitX = sp->fitX;
 
        return cosh((x*x+bb*bb*fitX*fitX)/(bb+fitX))/(aa+(x*x+fitX*fitX));
}
 
// 他のファイルがワークスペースにロードされ、コンパイルされていれば、
//  そのファイルで定義されているC関数にアクセスでき、関数は上記でインクルードした
//ヘッダファイルにプロトタイプがあります。
 
// 関数コード内でNLSFオブジェクトのプロパティとメソッドにアクセスできます。
 
// 関数の定義には、C言語のシンタックスを使います。
// 例えば、パラメータ名がP1の場合、関数定義に p1 と使うことはできません。
// 分数を使用する場合には、1/2のような整数の除算は0になり、0.5ではありません。
// 正しい値にするには、0.5または1/2.0を使います。
 
// より詳細な情報およびサンプルは、Originヘルプファイルの「ユーザ定義フィット関数」
// を参照してください。
 
//----------------------------------------------------------
// 
void _nlsfnag_integration_fitting(
// フィットパラメータ:
double a, double b, double c, double d,
// 独立変数:
double x,
// 従属変数:
double& y)
{
        // 編集可能部分の開始
        double epsabs = 0.00001, epsrel = 0.0000001, result, abserr;
        Integer max_num_subint = 500;  
        // epsabsとepsrel、およびこの値を使って必要な精度に向上できるので、
        // 必要な積分の精度を制御できます。
 
        Nag_QuadProgress qp;
        static NagError fail;
 
        // integrand のパラメータを初期化するのにcall_back 関数を利用でき、
        // 上記を行うには Nag_User 通信構造体を通して行います。
        Nag_User comm;  
        struct user s;
        s.a = a;
        s.b = b;
        s.fitX = x;
        comm.p = (Pointer)&s;
 
        d01sjc(f_callback, c, d, epsabs, epsrel, max_num_subint, &result, &abserr, &qp, &comm, &fail);
 
 
        // エラーメッセージを出力することで、エラーを調査するには、以下の行のコメントを解除します。
        // if (fail.code != NE_NOERROR)
        // printf("%s\n", fail.message);
 
 
        // 次の3つのエラー以外は、入力パラメータが不正であるか 
        //アロケーションエラーに当たります:  NE_INT_ARG_LT  NE_BAD_PARAM   NE_ALLOC_FAIL
        // メモリーリークを避けるため、積分ルーチンを呼ぶ前にメモリのアロケーションを
        // 解放する必要があります。
        if (fail.code != NE_INT_ARG_LT && fail.code != NE_BAD_PARAM && fail.code != NE_ALLOC_FAIL)
        {
                NAG_FREE(qp.sub_int_beg_pts);
                NAG_FREE(qp.sub_int_end_pts);
                NAG_FREE(qp.sub_int_result);
                NAG_FREE(qp.sub_int_error);
        }
 
 
        y = log(result); 
        // 積分の対数結果を返すのは容量が大きくなることもあるので、 
        // 必ずしも行う必要はありません 
 
        // 編集可能部分の終了
}

上記のコードでは、フィット関数 _nlsfnag_integration_fitting_coshの本体の外側で被積分関数をコールバック関数 f_callback として定義しています。被積分関数を変数 a, b , fitX でパラメータ化し、それらを Nag_User 構造体を使ってコールバック関数に渡します。その後、NAG積分ルーチン d01sjcを使って、積分を実行します。上記以外にも求積ルーチンを希望に合わせて利用する事ができます。現在のサンプルでは、フィット関数に対数スケールを使います。(サンプルデータは、既に対数関数でスケーリングされています。)

コードをコンパイルし、ダイアログに戻り、フィット関数オーガナイザでフィット関数を保存し、「解析:フィット」メニューから「非線形曲線フィット」ダイアログを開きます。そして、「設定」タブの「関数選択」ページで、このユーザ定義のフィット関数を選択することができます。

パラメータの初期値をセットする

ユーザ定義のフィット関数なので、パラメータの初期値を指定する必要があります。非線形曲線フィットダイアログの「パラメータ」タブで手動でセットすることもできます。今回の例では、パラメータの初期値を x \,, x \,, x \,, x \,のようにセットします。パラメータが初期化されると、以下に示すようにフィットを実行して、フィット結果を取得することができます。

サンプルデータ

サンプルデータ 結果
X Y FitResultCosh.PNG
-5 498.19046
-4.33333 329.43196
-3.66667 210.28005
-3 126.55799
-2.33333 69.01544
-1.66667 31.3555
-1 9.1393
-0.33333 -0.84496
0.33333 -0.99914
1 6.86736