3.9.2.1.1 Fit on multiple datasets with one function, parameters shared

Version Info

Minimum Origin Version Required: Origin 8.1 SR0

Need to do before Running Examples

Prior to running the following example, the nlsf_utils.c file need to be loaded and compiled. This can be done from script with the following command:

run.LoadOC(Originlab\nlsf_utils.c);

Examples

  1. New a worksheet and import \Samples\Curve Fitting\Gaussian.dat.
  2. Copy the following example codes to a c file and compile.
  3. Run test_NLFitSession in Command Window. The fitting Y data will be putted to worksheet new columns and will print out the fitting result to Command Window.
#include <..\Originlab\NLFitSession.h>

#define ERR_RETURN(_ERR_MSG) { \
    out_str(_ERR_MSG); \
    return; \
}
 
void test_NLFitSession()
{
    Worksheet   wks = Project.ActiveLayer();
    if( !wks )
        return; 
 
    XYRange drInput;
    drInput.Add(wks, 0, "X");
    drInput.Add(wks, 1, "Y");
    drInput.Add();
    drInput.Add(wks, 0, "X");
    drInput.Add(wks, 2, "Y");    
    int nNumData = drInput.GetNumData(DRR_GET_DEPENDENT);
 
    vector vX1, vY1, vX2, vY2;
    drInput.GetData(vY1, vX1, NULL, 0);
    drInput.GetData(vY2, vX2, NULL, 1);
 
    NLFitSession nlfSession;
 
    // Set Function
    if ( !nlfSession.SetFunction("Gauss") )
        ERR_RETURN("Fail to set function!");
 
    // Set Data and only need to set the last dataset with global fit mode, as to allow share parameters
    if ( !nlfSession.SetData(vY1, vX1, NULL, 0, nNumData) )
        ERR_RETURN("Fail to set data for the first dataset!")
 
    if ( !nlfSession.SetData(vY2, vX2, NULL, 1, nNumData, DATA_MODE_GLOBAL) )
        ERR_RETURN("Fail to set data for the second dataset!")
 
    // Parameter initialization
    if ( !nlfSession.ParamsInitValues() )
        ERR_RETURN("Fail to init parameters values!")
 
    // Share xc parameter
    int nSharedParamIndex = 1; // 1, the index of xc in function, must be DATA_MODE_GLOBAL datamode, or else will fail to share parameters
    nlfSession.SetParamShare(nSharedParamIndex);
 
    // Show parameters before fitting
    nlfSession.GetChiSqr(); // call GetChiSqr order to set parameter settings on internal fit object
    show_params(nlfSession, nNumData, "Before ftting");

    // Set lower bound for the second dataset "Y0" parameter - "Y0 >= 3"
    // NLFitSession::SetParamBounds supported from Origin 8.5.1 version
    int nParam = 0; // Y0
    int nLimitControl = 0; // 0 for "<="
    double dLimitValue = 3;     
    bool bIsLower = true; // lower bound
    int nDataset = 1; // the second dataset
    nlfSession.SetParamBounds(nParam, nLimitControl, dLimitValue, bIsLower, nDataset);
 
    // Do fit
    int nFitOutcome;
    bool bRet = nlfSession.Fit(&nFitOutcome); //if success    
 
    string strOutcome = nlfSession.GetFitOutCome(nFitOutcome);
    out_str("Outcome of the fitting session : " + strOutcome);
 
    if( bRet )
    {
        // Show parameters after fitting
        show_params(nlfSession, nNumData, "After ftting");
 
        // Get fit parameter results
        vector vFitY1(vX1.GetSize()), vFitY2(vX2.GetSize());
        nlfSession.GetYFromX(vX1, vFitY1, vX1.GetSize(), 0);
        nlfSession.GetYFromX(vX2, vFitY2, vX1.GetSize(), 1);  
 
        // Put fitting data into new column in worksheet
        append_column_data(wks, vFitY1, "Fit 1");        
        append_column_data(wks, vFitY2, "Fit 2");  
    }
}
 
 
 
void append_column_data(Worksheet& wks, vector& vData, LPCSTR lpcstrLongName)
{
    int nCol = wks.AddCol();
    if( NULL != lpcstrLongName )
        wks.Columns(nCol).SetLongName(lpcstrLongName);
 
    Dataset ds(wks, nCol);
    ds = vData;
} 
 
 
void show_params(NLFitSession& nlfSession, int nNumData, LPCSTR lpcscTitle)
{
    vector<double>  vParamValues;
    vector<int>     vParamOffsets;
    vector<string>  vsParamNames;
 
    //get parameters values and names
    nlfSession.GetParamValuesAndOffsets(vParamValues, vParamOffsets);
    nlfSession.GetParamNamesInFunction(vsParamNames);
 
    //output paramter values with names;
    for ( int iData = 0; iData  < nNumData; iData++ )
    {
        printf("%s, parameters of the Dataset%d:\n", lpcscTitle, iData + 1);
        for ( int nParam = vParamOffsets[iData], ii = 0; nParam < vParamOffsets[iData + 1]; nParam++, ii++ )
        {
            printf("%s = %lf\n", vsParamNames[ii], vParamValues[nParam]);
        }
    }
}