Origin Cで線形フィットのルーチンを実行するには、ocmath_linear_fit 関数を使用します。この関数では、重み付き線形フィットを実行し、パラメータ値や統計情報を含むフィット結果を取得できます。
以下の手順で、この関数を使用し、Origin Cでの線形フィットを実行して結果を指定したウィンドウとワークシートに出力します。
線形フィットを実行する前に、データをインポートします。ここでは、独立、従属変数ともに1つずつ必要です。
Origin Cのルーチンを始めます。3つのステップが必要です。
#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ダイアログでフィットオプションを表示するために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(); }