Minimum Origin Version Required: Origin 8 SR6 or later
The following Origin C function, chiSqrSurf, calculates the Chi-Square space over two fit parameters. The parameter values are varied over a specified range of values, and the chi-square value is computed and stored in a matrix. The data is then plotted as a contour plot allowing user to examine the shape of the chi-square surface as a function of the parameter space.
#include <..\originlab\NLFitSession.h> #include <FDFTree.h> #include <ONLSF.h> BOOL chiSqrSurf(const vector& vX, const vector& vY, const vector& vParams, double dXFrom, double dXTo, int nXNumSteps, double dYFrom, double dYTo, int nYNumSteps, string strFunc = "Poly", int nVaryParamX = 0, int nVaryParamY = 1) { // Check input arguments if( nVaryParamX >= vParams.GetSize() || nVaryParamY >= vParams.GetSize() ) return error_report("VaryParamN argument beyond the parameter number"); // report error information to Code Builder Output window // Construct function tree from the specified function name string strFDF; if( !nlf_get_fdf_filename(strFunc, NULL, NULL, &strFDF) ) return error_report("Cannot find FDF file for " + strFunc + " Function"); Tree tr; if( !nlsf_FDF_to_tree(strFDF, &tr)) return error_report("Fail to load " + strFDF + " file to Tree."); // Construct NumericFunction object with function tree NumericFunction NF; NF.SetTree(tr); matrix mm; mm.SetSize(nYNumSteps, nXNumSteps); double dXInc = (dXTo - dXFrom) / (nXNumSteps- 1); double dYInc = (dYTo - dYFrom) / (nYNumSteps- 1); for(int ii = 0; ii < mm.GetNumRows(); ii++) { for(int jj = 0; jj < mm.GetNumCols(); jj++) { vParams[nVaryParamX] = dXFrom + ii * dXInc; vParams[nVaryParamY] = dYFrom + jj * dYInc; double dChisqr = 0; int nNumMissing = 0; for(int kk = 0; kk < vX.GetSize(); kk++) { double dY2 = NF.Evaluate(vX[kk], vParams); if( !is_missing_value(dY2) ) dChisqr += pow((dY2 - vY[kk]), 2); else nNumMissing++; } double dd = vX.GetSize() - 2 - nNumMissing; mm[ii][jj] = dChisqr / dd ; } } // prepare matrix window MatrixPage matPage; matPage.Create("origin"); MatrixLayer ml = matPage.Layers(0); MatrixObject mo = ml.MatrixObjects(0); Matrix& mat = mo.GetDataObject(); mo.SetXY(dXFrom, dYFrom, dXTo, dYTo); mat = mm; // plot a contour graph with matrix GraphPage gp; gp.Create("Contour"); GraphLayer gl = gp.Layers(0); if( gl.AddPlot(mo, IDM_PLOT_CONTOUR) >= 0 ) gl.Rescale(); return true; }
run.LoadOC(Originlab\nlsf_utils.c);
void chiSqrSurf_ex1() { GraphLayer gl = Project.ActiveLayer(); if(!gl) { MessageBox(NULL, "Please active a graph window with data plot"); return; } // Get XY data from the active graph window string strRange; DataPlot dp = gl.DataPlots(); dp.GetRangeString(strRange); DataRange dr; dp.GetDataRange(dr); vector vX, vY; DWORD dwRules = DRR_GET_DEPENDENT | DRR_NO_FACTORS; dr.GetData( dwRules, 0, NULL, NULL, &vY, &vX ); // The following 3 steps to access NLFitSession to get parameter init values // 1. Set fucntion string strFunc = "Poly"; NLFitSession FitSession; if(!FitSession.SetFunction(strFunc, NULL)) // set function, category name can be ignore { MessageBox(NULL, "Fail to set fitting function"); return; } // 2. Set the dataset if( !FitSession.SetData( vY, vX ) ) { MessageBox(NULL, "Fail to set data"); return; } // 3. get parameter init values if( !FitSession.ParamsInitValues() ) { MessageBox(NULL, "Fail to init parameter value"); return; } vector vParams; vector<int> vnOffset; FitSession.GetParamValuesAndOffsets(vParams, vnOffset); // Call ScaleMatrix function chiSqrSurf(vX, vY, vParams, 200, 300, 6, -3200, -2600, 6, strFunc); }