線形フィットOrigin Cで線形フィットのルーチンを実行するには、ocmath_linear_fit 関数を使用します。この関数では、重み付き線形フィットを実行し、パラメータ値や統計情報を含むフィット結果を取得できます。
以下の手順で、この関数を使用し、Origin Cでの線形フィットを実行して結果を指定したウィンドウとワークシートに出力します。
線形フィットを実行
線形フィットを実行する前に、データをインポートします。ここでは、独立、従属変数ともに1つずつ必要です。
Origin Cのルーチンを始めます。3つのステップが必要です。
- cファイルを作成し、以下ように空の関数を追加します。この関数に、次のステップからコードをコピーします。
#include <GetNBox.h> // GETN_ マクロに使用
void linearfit()
{
}
- 線形フィットを実行するデータを取得します。独立/従属変数ともにベクトル変数を使用します。
// 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列のデータを取得しベクトルへ
- 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();
}
|