コンボリューションしながらフィットする


サマリー

指数データに曲線フィットを実行するとき、データに含まれる機器の応答を考慮する必要があるかもしれません。これを行う1つの方法は、データにデコンボリューションを実行し、機器の応答データを除去し、2番目のステップとして曲線フィットを実行します。しかし、結果がデータ内に存在するノイズの影響を受けやすいので、デコンボリューションは常に信頼できるとは限りません。より信頼性の高い方法は、フィット実行中に機器の応答データを持つデータに対して、フィット関数のコンボリューションを実行することです。このチュートリアルでは、フィット中にコンボリューションを実行する方法を示します。

もし、使うデータがGaussと指数関数のコンボリューションの場合、組み込み関数であるPeak Functionsカテゴリ内にあるGaussModを使って直接データをフィットできます。

必要なOriginのバージョン:Origin 2016 SR0

学習する項目

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

  • 反復実行中にフィット情報にアクセスする
  • フィット中にコンボリューションを実行する

サンプルとステップ

背景

\Samples\Curve Fitting\FitConv.datをインポートしてこのサンプルを開始しましょう。

Tutorial Fitting With Convolution 001.png

ソースデータには、サンプルポイント、出力信号、インパルス応答が含まれています。この実験は、出力信号がガウス応答を持つ指数減少関数のコンボリューションであると見なしています。

Tutorial Fitting With Convolution 002.png

これで、出力信号と応答データを得たので、信号を次のモデルでフィットして、指数減少関数を得ることができます。

y = y_0 + \int_{-\infty}^{+\infty} Ae^{-tx} \otimes Response, dx

関数を定義する

明らかに、列1と列2は、それぞれ関数のxとyです。列3はインパルス応答でしょうか? フィット関数でこの列にアクセスし、サンプリングポイントから理論指数曲線を計算します。そして、FFTを使ってコンボリューションを実行します。

F9を押し、フィット関数オーガナイザを開き、以下のように関数を定義します。

関数名: FitConv
関数形式: ユーザ定義
独立変数: x
従属変数: y
パラメータの名前: y0, A, t
定義形式: Origin C
関数:

関数ボックスの隣にあるボタン(アイコン)をクリックし、コードビルダに関数を記述します。

#pragma warning(error : 15618)
#include <origin.h>
// ヘッダーファイルは必須です。
#include <ONLSF.H>
#include <fft_utils.h>
//
// 
void _nlsfTestConv(
// フィットパラメータ:
double y0, double A, double t,
// 独立変数:
double x,
// 従属変数:
double& y)
{
	// 編集部分の始まり
	NLFitContext *pCtxt = Project.GetNLFitContext();
        Worksheet wks;
        DataRange dr;
        int c1,c2;
        dr = pCtxt->GetSourceDataRange(); //元データ範囲を取得
        dr.GetRange(wks, c1, c2);  //元データワークシートを取得
	if ( pCtxt )
	{	
		// 個々の反復での出力信号のベクトル
		static vector vSignal;
		// パラメータが更新されると、コンボリューションの結果も再計算される
		BOOL bIsNewParamValues = pCtxt->IsNewParamValues();
		if ( bIsNewParamValues )
		{
			// ワークシートからサンプリングと応答データを読み取る
			Dataset dsSampling(wks, 0);
			Dataset dsResponse(wks, 2);
			int iSize = dsSampling.GetSize();
 
			vector vResponse, vSample;
 
			vResponse = dsResponse;
			vSample = dsSampling;
 
			vSignal.SetSize(iSize);
			vResponse.SetSize(iSize);
			vSample.SetSize(iSize);
 
			// 指数減少曲線を算出
			vSignal = A * exp( -t*vSample );
			// コンボリューションの実行
			int iRet = fft_fft_convolution(iSize, vSignal, vResponse);
                        //サンプリング間隔を掛けることでコンボリューションを修正
                        vSignal = (vSample[1]-vSample[0])*vSignal;
 
 
		}
 
		NLSFCURRINFO    stCurrInfo;
		pCtxt->GetFitCurrInfo(&stCurrInfo);
		// 反復のためにデータインデックスを入手
		int nCurrentIndex = stCurrInfo.nCurrDataIndex;
		// 評価したy値を入手
		y = vSignal[nCurrentIndex] + y0;
		// ここではxを利用していないため、関数をコンパイルするために使用
		x;
	}
	// 編集可能エリア終了
}

特定のxに対して、関数は対応するy値を返します。しかし、コンボリューションが実行されると、特定のデータポイントだけでなく、曲線全体に対して操作を実行する必要があります。Origin 8 SR2から、フィット内での主要情報を取得するために、NLFitContextクラスを導入しました。各反復計算で、NLFitContextを使って、フィットパラメータを監視しています。それらが更新されると、fft_fft_convolutionメソッドにより、FFTを使ってコンボリューションを計算します。結果はベクターデータvSignalに保存されます。各xに対して、NLSFCURRINFO内の現在のデータインデックスを使って、vSignalから評価したyを取得できます。

曲線をフィットする

フィット関数の本体で、アクティブワークシートから直接応答データを読み込みます。よって、ワークシートからフィットを実行します。

  1. 列Bを選択し、Ctrl + Yを押し、非線形フィットダイアログを開きます。
  2. フィット曲線ページのXデータ型 では入力Xに同じを選択します。
  3. 関数選択ページに戻り、定義したFitConv関数を選びます。
  4. パラメータをy0=0, A=10, t=1のように初期化します。
  5. フィットボタンをクリックし、結果を生成します。

このチュートリアルで説明した関数と同じようなフィット関数を使用する場合、NLFitを実行する際は、NLFitダイアログの設定タブで、フィット曲線Xデータ型入力データと同じを設定するようにしてください。