home *** CD-ROM | disk | FTP | other *** search
- //$$ example.cxx Example of use of matrix package
-
- typedef double real; // all floating point double
-
- #include "include.hxx" // include standard files
-
- #include "newmatap.hxx" // need matrix applications
-
- real t3(real); // round to 3 decimal places
-
- // demonstration of matrix package on linear regression problem
-
- main()
- {
- // the data
- // you may need to read this data using cin if you are using a
- // compiler that doesn't understand aggregates
- real y[] = { 8.3, 5.5, 8.0, 8.5, 5.7, 4.4, 6.3, 7.9, 9.1 };
- real x1[] = { 2.4, 1.8, 2.4, 3.0, 2.0, 1.2, 2.0, 2.7, 3.6 };
- real x2[] = { 1.7, 0.9, 1.6, 1.9, 0.5, 0.6, 1.1, 1.0, 0.5 };
- int nobs = 9; // number of observations
- int npred = 2; // number of predictor values
- int npred1 = npred+1;
-
- // we want to find the values of a,a1,a2 to give the best
- // fit of y[i] with a0 + a1*x1[i] + a2*x2[i]
-
- // this example demonstrates three methods of calculation
-
- {
- // traditional sum of squares and products method of calculation
- // with subtraction of means
-
- // make matrix of predictor values
- Matrix X(nobs,npred);
-
- // load x1 and x2 into X
- // [use << rather than = with submatrices and/or loading arrays]
- X.Col(1) << x1; X.Col(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 = Ones.t() * X / nobs;
-
- // and subtract means from x1 and x1
- Matrix XC(nobs,npred);
- XC = X - Ones * M;
-
- // do the same to Y [need (1,1) to convert 1x1 matrix to scalar]
- ColumnVector YC(nobs);
- real m = Matrix(Ones.t() * Y)(1,1) / 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
- real a = m - Matrix(M * A)(1,1);
-
- // Get variances of estimates from diagonal elements of invoice of SSQ
- // [ we are taking inverse of SSQ; would have been better to use
- // CroutMatrix method - see documentation ]
- Matrix ISSQ = SSQ.i(); DiagonalMatrix D; D << ISSQ;
- ColumnVector V = D.CopyToColumn();
- real v = 1.0/nobs + Matrix(M * ISSQ * M.t())(1,1);
- // for calc variance const
-
- // Calculate fitted values and residuals
- ColumnVector Fitted = X * A + a;
- ColumnVector Residual = Y - Fitted;
- real ResVar = Residual.SumSquare() / (nobs-npred1);
-
- // print out answers
- cout << "\nEstimates and their standard errors\n\n";
- cout << a <<"\t"<< sqrt(v*ResVar) << "\n";
- for (int i=1; i<=npred; i++)
- cout << A(i) <<"\t"<< sqrt(V(i)*ResVar) << "\n";
- cout << "\nObservations, fitted value, residual value\n";
- for (i=1; i<=nobs; i++)
- cout << X(i,1) <<"\t"<< X(i,2) <<"\t"<< Y(i) <<"\t"<<
- t3(Fitted(i)) <<"\t"<< t3(Residual(i)) <<"\n";
- cout << "\n\n";
- }
-
- {
- // traditional sum of squares and products method of calculation
- // with subtraction of means - using Cholesky decomposition
-
- Matrix X(nobs,npred);
- X.Col(1) << x1; X.Col(2) << x2;
- ColumnVector Y(nobs); Y << y;
- ColumnVector Ones(nobs); Ones = 1.0;
- RowVector M = Ones.t() * X / nobs;
- Matrix XC(nobs,npred);
- XC = X - Ones * M;
- ColumnVector YC(nobs);
- real m = Matrix(Ones.t() * Y)(1,1) / nobs; YC = Y - Ones * m;
- SymmetricMatrix SSQ; SSQ << XC.t() * XC;
-
- // Cholesky decomposition of SSQ
- LowerTriangularMatrix L = Cholesky(SSQ);
-
- // calculate estimate
- ColumnVector A = L.t().i() * (L.i() * (XC.t() * YC));
-
- // calculate estimate of constant term
- real a = m - Matrix(M * A)(1,1);
-
- // Get variances of estimates from diagonal elements of invoice of SSQ
- DiagonalMatrix D; D << L.t().i() * L.i();
- ColumnVector V = D.CopyToColumn();
- real v = 1.0/nobs + (L.i() * M.t()).SumSquare();
-
- // Calculate fitted values and residuals
- ColumnVector Fitted = X * A + a;
- ColumnVector Residual = Y - Fitted;
- real ResVar = Residual.SumSquare() / (nobs-npred1);
-
- // print out answers
- cout << "\nEstimates and their standard errors\n\n";
- cout << a <<"\t"<< sqrt(v*ResVar) << "\n";
- for (int i=1; i<=npred; i++)
- cout << A(i) <<"\t"<< sqrt(V(i)*ResVar) << "\n";
- cout << "\nObservations, fitted value, residual value\n";
- for (i=1; i<=nobs; i++)
- cout << X(i,1) <<"\t"<< X(i,2) <<"\t"<< Y(i) <<"\t"<<
- t3(Fitted(i)) <<"\t"<< t3(Residual(i)) <<"\n";
- cout << "\n\n";
- }
-
- {
- // Householder triangularisation method
-
- // load data - 1s into col 1 of matrix
- Matrix X(nobs,npred1); ColumnVector Y(nobs);
- X.Col(1) << 1.0; X.Col(2) << x1; X.Col(3) << x2; Y << y;
-
- // do Householder triangularisation
- // no need to deal with constant term separately
- Matrix XT = X.t(); // Want data to be along rows
- RowVector YT = Y.t();
- LowerTriangularMatrix L; RowVector M;
- HHDecompose(XT, L); HHDecompose(XT, YT, M); // YT now contains resids
- ColumnVector A = L.t().i() * M.t();
- ColumnVector Fitted = X * A;
- real ResVar = YT.SumSquare() / (nobs-npred1);
-
- // get variances of estimates
- L << L.i();
- DiagonalMatrix D; D << L.t() * L;
-
- // print out answers
- cout << "\nEstimates and their standard errors\n\n";
- for (int i=1; i<=npred1; i++)
- cout << A(i) <<"\t"<< sqrt(D(i)*ResVar) << "\n";
- cout << "\nObservations, fitted value, residual value\n";
- for (i=1; i<=nobs; i++)
- cout << X(i,2) <<"\t"<< X(i,3) <<"\t"<< Y(i) <<"\t"<<
- t3(Fitted(i)) <<"\t"<< t3(YT(i)) <<"\n";
- cout << "\n\n";
- }
- }
-
- real t3(real r) { return int(r*1000) / 1000.0; }
-