線形フィット

Origin Cで線形フィットのルーチンを実行するには、ocmath_linear_fit 関数を使用します。この関数では、重み付き線形フィットを実行し、パラメータ値や統計情報を含むフィット結果を取得できます。

以下の手順で、この関数を使用し、Origin Cでの線形フィットを実行して結果を指定したウィンドウとワークシートに出力します。

線形フィットを実行

線形フィットを実行する前に、データをインポートします。ここでは、独立、従属変数ともに1つずつ必要です。

Origin Cのルーチンを始めます。3つのステップが必要です。

  1. cファイルを作成し、以下ように空の関数を追加します。この関数に、次のステップからコードをコピーします。
    #include <GetNBox.h> // GETN_ マクロに使用
    void linearfit()
    {
    }
  2. 線形フィットを実行するデータを取得します。独立/従属変数ともにベクトル変数を使用します。
    // XY データをワークシートウィンドウから取得
    Worksheet wks = Project.ActiveLayer();
    if(!wks)
        return;  // データ付きワークシートをアクティブにする必要がある
    WorksheetPage wp = wks.GetPage();
     
    DataRange dr;
    dr.Add("X", wks, 0, 0, -1, 0);  // x列
    dr.Add("Y", wks, 0, 1, -1, 1);  // y列
     
    vector vX;  
    dr.GetData(&vX, 0);  // x列のデータを取得しベクトルへ
     
    vector vY;
    dr.GetData(&vY, 1);  // y列のデータを取得しベクトルへ
  3. GetN ダイアログを表示して、フィットオプションをコントロールし、ocmath_linear_fit 関数を呼び出して、このオプションで線形フィットします。
    // GetNダイアログでフィットオプションを表示するためにGUI ツリーを用意
    GETN_TREE(trGUI)	
    GETN_BEGIN_BRANCH(Fit, _L("Fit Options")) 
    GETN_ID_BRANCH(IDST_LR_OPTIONS) GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
    	GETN_CHECK(FixIntercept, _L("Fix Intercept"), 0) 
    		GETN_ID(IDE_LR_FIX_INTCPT)
    	GETN_NUM(FixInterceptAt, _L("Fix Intercept at"), 0) 
    		GETN_ID(IDE_LR_FIX_INTCPT_AT)
    	GETN_CHECK(FixSlope, _L("Fix Slope"), 0) 
    		GETN_ID(IDE_LR_FIX_SLOPE)
    	GETN_NUM(FixSlopeAt, _L("Fix Slope at"), 1) 
    		GETN_ID(IDE_LR_FIX_SLOPE_AT)
    	GETN_CHECK(UseReducedChiSq, STR_FITTING_CHECKBOX_USE_RED_CHI_SQR, 1) 
    		GETN_ID(IDE_FIT_REDUCED_CHISQR)
    GETN_END_BRANCH(Fit)	
    if( !GetNBox(trGUI) )
    {
    	return; // キャンセルボタンが押される
    }	
    LROptions stLROptions;
    stLROptions = trGUI.Fit; // GUIツリーからstructに値を割り当て
    
    // 上の入力データとフィットオプションで線形フィットを実行
    int nSize = vX.GetSize();  // データサイズ
    FitParameter psFitParameter[2];  // 2つのパラメータ	 
    RegStats stRegStats;  // フィットの統計
    RegANOVA stRegANOVA;  // anova statistics	
    
    int nRet = ocmath_linear_fit(vX, vY, nSize, psFitParameter, NULL, 
                            0, &stLROptions, &stRegStats, &stRegANOVA);	
    if(nRet != STATS_NO_ERROR)
    {
        out_str("Error");
        return;
    }

結果をウィンドウに出力

計算が終了すると、フィット結果を特定のウィンドウに出力できます。ここで、パラメータの値は、ツリーとしてスクリプトウィンドウに出力し、統計情報は結果ログウィンドウに出力します。

void put_to_output_window(const FitParameter* psFitParameter, 
			const RegStats& stRegStats, const RegANOVA& stRegANOVA)
{	
	// スクリプトウィンドウ、結果ログ、ワークシートに分析結果を出力
	// フィットパラメータをスクリプトウィンドウに印字
	vector<string> vsParams = {"Intercept", "Slope"};
	for(int iPara = 0; iPara < vsParams.GetSize(); iPara++)
	{
	    printf("%s = %g\n", vsParams[iPara], psFitParameter[iPara].Value);
	}
	
	// 統計結果を結果ログに出力
	Tree trResults;
	TreeNode trResult = trResults.AddNode("LinearFit");
	TreeNode trStats = trResult.AddNode("Stats");
	trStats += stRegStats;  // フィットの統計をツリーノードに追加
	 
	TreeNode trANOVA = trResult.AddNode("ANOVA");
	trANOVA += stRegANOVA;  // anova 統計をツリーノードに追加
	 
	string strResult;
	tree_to_str(trResult, strResult);  // ツリーを文字列に変換
	
	Project.OutStringToResultsLog(strResult);  // 結果ログに出力
}

結果をワークシートに出力

フィット結果を、指定したワークシートに出力することもできます。そして、ワークシートウィンドウ内の一般的な列フォーマットか、ツリー表示フォーマットで結果を出力できます。

以下の2つの方法は、Datasheet::SetReportTree メソッドを使用してツリー変数によるワークシートに結果を出力します。異なる点は、ワークシート作成時のWP_SHEET_HIERARCHYオプションで、2番目の変数はAddLayerメソッドを使用しているのがわかります。

通常のワークシートに結果を出力

void output_to_wks(WorksheetPage wp, const FitParameter* psFitParameter)
{
	// レポートツリーを用意		
	int nID = 100; // ノードは固有のノードIDが必要
	Tree tr;
	tr.Report.ID = nID++;
	TreeNode trReport = tr.Report;
	trReport.SetAttribute(TREE_Table, GETNBRANCH_TRANSPOSE);		
	
	// 1列
	trReport.P1.ID = nID++;
	trReport.P1.SetAttribute(STR_LABEL_ATTRIB, "Parameter"); // 列ラベル
	trReport.P1.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_X);
	
	// 2列
	trReport.P2.ID = nID++;
	trReport.P2.SetAttribute(STR_LABEL_ATTRIB, "Value"); // 列ラベル
	trReport.P2.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);
	
	// 3列
	trReport.P3.ID = nID++;
	trReport.P3.SetAttribute(STR_LABEL_ATTRIB, "Prob>|t|"); // 列ラベル
	trReport.P3.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);	
	
	// 表中に表示するためのベクトルを用意
	vector<string> vsParamNames = {"Intercept", "Slope"};  // パラメータ名
	vector vValues, vProbs;  // パラメータ値とprob
	for(int nParam = 0; nParam < vsParamNames.GetSize(); nParam++)
	{
	    vValues.Add(psFitParameter[nParam].Value);
	    vProbs.Add(psFitParameter[nParam].Prob);
	}
	
	// ツリーノードにベクトルを割り当て
	trReport.P1.strVals = vsParamNames;
	trReport.P2.dVals = vValues;
	trReport.P3.dVals = vProbs;
	
	// レポートツリーをワークシートに
	int iLayer = wp.AddLayer("Linear Fit Params"); 
	Worksheet wksResult = wp.Layers(iLayer);		 
	if(!wksResult.IsValid() || wksResult.SetReportTree(trReport) < 0)
	{
	    printf("Fail to set report tree.\n");
	    return;
	}
	wksResult.AutoSize();	
}

ツリー形式のワークシートに結果を出力

void output_to_tree_view_wks(WorksheetPage& wp, const RegStats& stRegStats)
{
	Tree tr;
	int nID = 100; // 各ノードは固有のノードIDが必要
	uint nTableFormat = GETNBRANCH_OPEN	
						| GETNBRANCH_HIDE_COL_HEADINGS 
						| GETNBRANCH_HIDE_ROW_HEADINGS 
						| GETNBRANCH_FIT_COL_WIDTH 
						| GETNBRANCH_FIT_ROW_HEIGHT;
	
	// ルートテーブルノードを用意
	tr.Report.ID = nID++; // Report ツリーノードを追加し、ノードIDを割り当て
	TreeNode trReport = tr.Report; 
	// テーブルノードに表属性が必要
	trReport.SetAttribute(TREE_Table, nTableFormat); 
	// ルートテーブルのタイトル
	trReport.SetAttribute(STR_LABEL_ATTRIB, "Linear Fit Stats"); 
	
	// 統計テーブルノードを用意
	trReport.Table.ID = nID++; // Table ツリーノードとノードIDを割り当て
	TreeNode trTable = trReport.Table;
	// テーブルノードに表属性が必要
	trTable.SetAttribute(TREE_Table, nTableFormat|GETNBRANCH_TRANSPOSE); 
	// 統計表のタイトル
	trTable.SetAttribute(STR_LABEL_ATTRIB, "Regression Statistics"); 
	
	// 結果ノードを用意
	trTable.Stats.ID = nID++; // Stats ツリーノードを追加してノードidを割り当て
	TreeNode trStats = trTable.Stats;		
	trStats += stRegStats; // sturct から結果をツリーノードに追加をサポート
	
	// ラベル設定。表の行ヘッダにこれらのテキストが表示
	trStats.N.SetAttribute(STR_LABEL_ATTRIB, "Number of Points");
	trStats.DOF.SetAttribute(STR_LABEL_ATTRIB, "Degrees of Freedom");
	trStats.SSR.SetAttribute(STR_LABEL_ATTRIB, "Residual Sum of Squares");
	trStats.AdjRSq.SetAttribute(STR_LABEL_ATTRIB, "Adj.R-Square");
	
	// 他のノードを非表示にする
	trStats.ReducedChiSq.Show = false;
	trStats.Correlation.Show = false;
	trStats.Rvalue.Show = false;
	trStats.RSqCOD.Show = false;
	trStats.RMSESD.Show = false;
	trStats.NormResiduals.Show = false;
	
	// 階層フォーマットとして新しいワークシートを作成するコントロール
	DWORD   dwOptions = WP_SHEET_HIERARCHY | CREATE_NO_DEFAULT_TEMPLATE; 
	int iLayer = wp.AddLayer("Linear Fit Stats", dwOptions); 
	
	Worksheet wksResult = wp.Layers(iLayer);		 
	if(!wksResult.IsValid() || wksResult.SetReportTree(trReport) < 0)
	{
	    printf("Fail to set report tree.\n");
	    return;
	}
	wksResult.AutoSize();
}