# 3.9.2.1.6 ChiSquare Space

## Version Info

Minimum Origin Version Required: Origin 8 SR6 or later

## Calculating and Plotting Chi-Square Space

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.

• Parameters
vX
[input]X data range.
xY
[input]Y data range.
vParams
[input]Parameters of the specified fitting function.
dXFrom
[input]The starting value of the first varied parameter, and this varied parameter is considered as X axis of the matrix.
dXTo
[input]The end value of the first varied parameter.
nXNumSteps
[input]The number of steps for the first varied parameter.
dYFrom
[input]The starting value of the second varied parameter, and this varied parameter is considered as Y axis of the matrix.
dYTo
[input]The end value of the second varied parameter.
nYNumSteps
[input]The number of steps for the second varied parameter.
strFunc
[input]The name of the fitting function.
nVaryParamX
[input]The zero-basic index of the first varied parameter.
nVaryParamY
[input]The zero-basic index of the second varied parameter.
• Source Code
#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;
}

## How to Use the chiSqrSurf Function

1. Create a new worksheet and import the data <Origin Installation Directory>\Samples\Curve Fitting\Exponential Decay.dat.
2. Highlight column B and select menu Plot: Line: Line to make a line plot.
3. Run the following LabTalk script to load and compile the desired Origin C file, "nlsf_utils.c".
run.LoadOC(Originlab\nlsf_utils.c);
4. Copy and compile the above chiSqrSurf function and the following function in Code Builder, and then run "chiSqrSurf_ex1" in Command Window.
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);
}