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);   
}