/// \ingroup newmat ///@{ /// \file example.cpp /// Example of use of matrix package. /// Carry out a simple regression analysis using a number of different methods /// to illustrate matrix manipulation, solving equations, /// Cholesky decomposition, QR decomposition, Singular Value decomposition. #define WANT_STREAM // include.h will get stream fns #define WANT_MATH // include.h will get math fns // newmatap.h will get include.h #include "newmatap.h" // need matrix applications #include "newmatio.h" // need matrix output routines #ifdef use_namespace using namespace NEWMAT; // access NEWMAT namespace #endif // demonstration of matrix package on linear regression problem void test1(Real* y, Real* x1, Real* x2, int nobs, int npred) { cout << "\n\nTest 1 - traditional, bad\n"; // traditional sum of squares and products method of calculation // but not adjusting means; maybe subject to round-off error // make matrix of predictor values with 1s into col 1 of matrix int npred1 = npred+1; // number of cols including col of ones. Matrix X(nobs,npred1); X.column(1) = 1.0; // load x1 and x2 into X // [use << rather than = when loading arrays] X.column(2) << x1; X.column(3) << x2; // vector of Y values ColumnVector Y(nobs); Y << y; // form sum of squares and product matrix // [use << rather than = for copying Matrix into SymmetricMatrix] SymmetricMatrix SSQ; SSQ << X.t() * X; // calculate estimate // [bracket last two terms to force this multiplication first] // [ .i() means inverse, but inverse is not explicity calculated] ColumnVector A = SSQ.i() * (X.t() * Y); // Get variances of estimates from diagonal elements of inverse of SSQ // get inverse of SSQ - we need it for finding D DiagonalMatrix D; D << SSQ.i(); ColumnVector V = D.as_column(); // Calculate fitted values and residuals ColumnVector Fitted = X * A; ColumnVector Residual = Y - Fitted; Real ResVar = sum_square(Residual) / (nobs-npred1); // Get diagonals of Hat matrix (an expensive way of doing this) DiagonalMatrix Hat; Hat << X * (X.t() * X).i() * X.t(); // print out answers cout << "\nEstimates and their standard errors\n\n"; // make vector of standard errors ColumnVector SE(npred1); for (int i=1; i<=npred1; i++) SE(i) = sqrt(V(i)*ResVar); // use concatenation function to form matrix and use matrix print // to get two columns cout << setw(11) << setprecision(5) << (A | SE) << endl; cout << "\nObservations, fitted value, residual value, hat value\n"; // use concatenation again; select only columns 2 to 3 of X cout << setw(9) << setprecision(3) << (X.columns(2,3) | Y | Fitted | Residual | Hat.as_column()); cout << "\n\n"; } void test2(Real* y, Real* x1, Real* x2, int nobs, int npred) { cout << "\n\nTest 2 - traditional, OK\n"; // traditional sum of squares and products method of calculation // with subtraction of means - less subject to round-off error // than test1 // make matrix of predictor values Matrix X(nobs,npred); // load x1 and x2 into X // [use << rather than = when loading arrays] X.column(1) << x1; X.column(2) << x2; // vector of Y values ColumnVector Y(nobs); Y << y; // make vector of 1s ColumnVector Ones(nobs); Ones = 1.0; // calculate means (averages) of x1 and x2 [ .t() takes transpose] RowVector M = X.sum_columns() / nobs; // and subtract means from x1 and x2 Matrix XC(nobs,npred); XC = X - Ones * M; // do the same to Y [use sum to get sum of elements] ColumnVector YC(nobs); Real m = sum(Y) / nobs; YC = Y - Ones * m; // form sum of squares and product matrix // [use << rather than = for copying Matrix into SymmetricMatrix] SymmetricMatrix SSQ; SSQ << XC.t() * XC; // calculate estimate // [bracket last two terms to force this multiplication first] // [ .i() means inverse, but inverse is not explicity calculated] ColumnVector A = SSQ.i() * (XC.t() * YC); // calculate estimate of constant term // [AsScalar converts 1x1 matrix to Real] Real a = m - (M * A).as_scalar(); // Get variances of estimates from diagonal elements of inverse of SSQ // [ we are taking inverse of SSQ - we need it for finding D ] Matrix ISSQ = SSQ.i(); DiagonalMatrix D; D << ISSQ; ColumnVector V = D.AsColumn(); Real v = 1.0/nobs + (M * ISSQ * M.t()).as_scalar(); // for calc variance of const // Calculate fitted values and residuals int npred1 = npred+1; ColumnVector Fitted = X * A + a; ColumnVector Residual = Y - Fitted; Real ResVar = sum_square(Residual) / (nobs-npred1); // Get diagonals of Hat matrix (an expensive way of doing this) Matrix X1(nobs,npred1); X1.column(1)<