# 3.9.5.5 OriginC: Regression Analysis

## Version Info

Minimum Origin Version Required: Origin 8 SR0

## Linear Regression

#include <oc_nag.h>
//#include  <nag\OC_nag_ex.h> //not need, only oc_nag.h required.
void nag_linear_regression_ex1()
{
// data input directly by vector
vector vx = {1,0,4,7.5,2.5,0,10,5};
vector vy = {20,15.5,28.3,45,24.5,10,99,31.2};
vector vw = {1,1,1,1,1,1,1,1};

int  n;
n = vx.GetSize();

double a, b, err_a, err_b, rsq, rss, df;

g02cac(mean, n, vx, vy, vw, &a, &b, &err_a, &err_b, &rsq, &rss,
&df, NAGERR_DEFAULT);

// output intepretation: a+b*x  b is the slope, a is the intercept
{
printf("\nRegression constant a = %6.4f\n\n", a);
printf("Standard error of the regression constant a = %6.4f\n\n",err_a);
}

printf("Regression coefficient b = %6.4f\n\n", b);
printf("Standard error of the regression coefficient b = %6.4f\n\n",err_b);

printf("The regression coefficient of determination = %6.4f\n\n", rsq);
printf("The sum of squares of the residuals about the " "regression = %6.4f\n\n", rss);
printf("Number of degrees of freedom about the " "regression = %6.4f\n\n",df);

//Expected Result:
//Regression constant a = 7.5982

//Standard error of the regression constant a = 6.6858
//
//Regression coefficient b = 7.0905
//
//Standard error of the regression coefficient b = 1.3224
//
//The regression coefficient of determination = 0.8273
//
//The sum of squares of the residuals about the regression = 965.2454
//
//Number of degrees of freedom about the regression = 6.0000

}
#include <oc_nag.h>
//#include  <nag\OC_nag_ex.h>  //not need, only oc_nag.h required.
void nag_linear_regression_ex2()
{
// obtain regression data from an Origin Worksheet
Worksheet wks=Project.ActiveLayer();
if(!wks)
printf("no active worksheet found\n");
Dataset dsSrcX(wks,0); // assume that the x, y data and weight data are in the first three columns
Dataset dsSrcY(wks,1);
Dataset dsSrcW(wks,2);
int nSize;
vector vx(nSize);
vector vy(nSize);
vector vw(nSize);
vx=dsSrcX;
vy=dsSrcY;
vw=dsSrcW;

int  n;
n = vx.GetSize();

double a, b, err_a, err_b, rsq, rss, df;

g02cac(mean, n, vx, vy, vw, &a, &b, &err_a, &err_b, &rsq, &rss,
&df, NAGERR_DEFAULT);

// output intepretation: a+b*x  b is the slope, a is the intercept
{
printf("\nRegression constant a = %6.4f\n\n", a);
printf("Standard error of the regression constant a = %6.4f\n\n",err_a);
}

printf("Regression coefficient b = %6.4f\n\n", b);
printf("Standard error of the regression coefficient b = %6.4f\n\n",err_b);

printf("The regression coefficient of determination = %6.4f\n\n", rsq);
printf("The sum of squares of the residuals about the " "regression = %6.4f\n\n", rss);
printf("Number of degrees of freedom about the " "regression = %6.4f\n\n",df);

}

## Multiple Linear Regression

#include <oc_nag.h>
//#include  <nag\OC_nag_ex.h>  //not need, only oc_nag.h required.
void nag_regsn_mult_linear_ex()
{

int i, ip, rank, j, m, n;
double df;
Boolean svd;
char weight, meanc;
Nag_IncludeMean mean;
double b[20];
double cov[210], h[20], p[440];
double res[20], se[20];
double com_ar[495];
double wt[20];
matrix q;
q.SetSize(20, 21);
double *wtptr;
n = 12;
m = 4;
mean = Nag_MeanInclude;
wtptr =NULL;

// input data is only the first four columns, the design matrix
matrix x = 	{{1.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 0.0, 1.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 1.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 1.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 0.0, 1.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 1.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 0.0, 1.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 1.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 1.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 1.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};

double y[20] = {33.63, 39.62, 38.18, 41.46, 38.02, 35.83,
35.99, 36.58, 42.92, 37.80, 40.43, 37.89}; // the y data

int sx[20] = {1, 1, 1, 1};

printf("The  input data are as follows\n");
printf("n = 12, m = 4, tol = 0.000001e0\n");
printf("x\n");
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++)
printf("%2.1f, ",x[i][j]);
printf("\n");
}
printf("\ny\n");
for(i = 0; i < n; i ++)
{
printf("%5.3f, ", y[i]);
if((i + 1) % 7 == 0)
printf("\n");
}

ip = 0;
if (mean==Nag_MeanInclude)
ip += 1;
for (i=0; i<m; i++)
if (sx[i]>0) ip += 1;
tol = 0.00001e0;

nag_regsn_mult_linear(mean, n, x, 20, m, sx, ip, y,
wtptr, &rss, &df, b, se, cov, res, h, q, 21, &svd, &rank, p, tol, com_ar, NAGERR_DEFAULT);

if (svd)
{	printf("\nModel not of full rank, rank = %4ld\n", rank);
ASSERT( rank == 4 );
}

printf("Residual sum of squares = %12.4e\n", rss);
printf("Degrees of freedom = %3.1f\n\n", df);

printf("Variable       Parameter           Estimate Standard error\n\n");  // the standard error
for (j=0; j<ip; j++)
printf("%6ld%20.4e%20.4e\n", j+1, b[j], se[j]);

printf("\n");
printf("Obs            Residuals           h\n\n");  // the residuals
for (i=0; i<n; i++)
printf("%6ld%20.4e%20.4e\n", i+1, res[i], h[i]);

}

## Nonlinear Regression

#include <OC_nag.h>

//Callback to calculate objective subfunction values, and (optionally) its Jacobian
void NAG_CALL objfun_callback(int m, int n, double p[], double f[],
double fjac[], int tdfjac,Nag_Comm *comm)
{
#define FJAC(I,J) fjac[(I)*tdfjac +(J)]

static vector x = {
8.0, 8.0, 10.0, 10.0, 10.0, 10.0, 12.0, 12.0, 12.0, 12.0, 14.0, 14.0,
14.0, 16.0, 16.0, 16.0, 18.0, 18.0, 20.0, 20.0, 20.0, 22.0, 22.0, 22.0,
24.0, 24.0, 24.0, 26.0, 26.0, 26.0, 28.0, 28.0, 30.0, 30.0, 30.0, 32.0,
32.0, 34.0, 36.0, 36.0, 38.0, 38.0, 40.0, 42.0};

double temp;
for(int i = 0; i < m; ++i)
{
//evaluate objective subfunction f(i+1) only if required
if(comm->needf == i+1 || comm->needf == 0)
{
temp = exp(-p[1] * (x[i] - 8.0));
f[i] = p[0] + (.49 - p[0]) * temp;
}
//evaluate the Jacobian if required
if(comm->flag == 2)
{
FJAC(i, 0) = 1.0 - temp;
FJAC(i, 1) = -(0.49 - p[0]) * (x[i] - 8.0) * temp;
}
}
}

//Callback to calculate nonlinear constraints and (optinally) its Jacobian
static void NAG_CALL confun_callback(int n, int ncnlin, int needc[], double p[],
double conf[], double cjac[], Nag_Comm *comm)
{
#define CJAC(I, J) cjac[(I)*n + (J)]

//First call to confun. Set all Jacobian elements to zero.
//Note that this will only work when options.obj_deriv = TRUE(default)
if(comm->first == true)
CJAC(0, 0) = CJAC(0, 1) = 0.0;

if(needc[0] > 0)
{
conf[0] = -.09 - p[0]*p[1] + 0.49*p[1];
if(comm->flag == 2)
{
CJAC(0, 0) = -p[1];
CJAC(0, 1) = -p[0] + .49;
}
}
}

void nag_opt_nlin_lsq_ex()
{
vector y = {0.49, 0.49, 0.48, 0.47, 0.48, 0.47, 0.46, 0.46, 0.45, 0.43, 0.45,
0.43, 0.43, 0.44, 0.43, 0.43, 0.46, 0.45, 0.42, 0.42, 0.43, 0.41,
0.41, 0.40, 0.42, 0.40, 0.40, 0.41, 0.40, 0.41, 0.41, 0.40, 0.40,
0.40, 0.38, 0.41, 0.40, 0.40, 0.41, 0.38, 0.40, 0.40, 0.39, 0.39};

int m = y.GetSize(), n = 2;
int tda = n, tdfjac = n;
int nclin = 1, ncnlin = 1;

vector p = {0.4, 0.0};//initial parameters
vector a = {1.0, 1.0};//linear constraints
vector bl = {0.4, -4.0, 1.0, 0.0}; //lower bounds
vector bu = {1.0e+25, 1.0e+25, 1.0e+25, 1.0e+25}; //upper bounds
vector f(m), fjac(m*n);
double objf;

Nag_E04_Opt options;
nag_opt_init(&options);
strcpy(options.outfile, "c:\\nag_opt_nlin_lsq_ex.txt");

NagError fail;

e04unc(m, n, nclin, ncnlin, a, tda, bl, bu, y, objfun_callback, confun_callback,
p, &objf, f, fjac, tdfjac, &options, NAGCOMM_NULL, &fail);

if(fail.code == NE_NOERROR)
{
printf("fitting paramters: %lf %lf \n", p[0], p[1]);
printf("value of objective function: %lf \n", objf);
}
else
{
printf("fitting failed, error code = %d", fail.code);
}

//Expected Result:
//fitting paramters: 0.419953 1.284845
//value of objective function: 0.014230
}