example.cc
Go to the documentation of this file.
00001 //$$ example.cpp                             Example of use of matrix package
00002 
00003 #define WANT_STREAM                  // include.h will get stream fns
00004 #define WANT_MATH                    // include.h will get math fns
00005                                      // newmatap.h will get include.h
00006 
00007 #include "newmatap.h"                // need matrix applications
00008 
00009 #include "newmatio.h"                // need matrix output routines
00010 
00011 #ifdef use_namespace
00012 using namespace NEWMAT;              // access NEWMAT namespace
00013 #endif
00014 
00015 
00016 // demonstration of matrix package on linear regression problem
00017 
00018 
00019 void test1(Real* y, Real* x1, Real* x2, int nobs, int npred)
00020 {
00021    cout << "\n\nTest 1 - traditional, bad\n";
00022 
00023    // traditional sum of squares and products method of calculation
00024    // but not adjusting means; maybe subject to round-off error
00025 
00026    // make matrix of predictor values with 1s into col 1 of matrix
00027    int npred1 = npred+1;        // number of cols including col of ones.
00028    Matrix X(nobs,npred1);
00029    X.Column(1) = 1.0;
00030 
00031    // load x1 and x2 into X
00032    //    [use << rather than = when loading arrays]
00033    X.Column(2) << x1;  X.Column(3) << x2;
00034 
00035    // vector of Y values
00036    ColumnVector Y(nobs); Y << y;
00037 
00038    // form sum of squares and product matrix
00039    //    [use << rather than = for copying Matrix into SymmetricMatrix]
00040    SymmetricMatrix SSQ; SSQ << X.t() * X;
00041 
00042    // calculate estimate
00043    //    [bracket last two terms to force this multiplication first]
00044    //    [ .i() means inverse, but inverse is not explicity calculated]
00045    ColumnVector A = SSQ.i() * (X.t() * Y);
00046 
00047    // Get variances of estimates from diagonal elements of inverse of SSQ
00048    // get inverse of SSQ - we need it for finding D
00049    DiagonalMatrix D; D << SSQ.i();
00050    ColumnVector V = D.AsColumn();
00051 
00052    // Calculate fitted values and residuals
00053    ColumnVector Fitted = X * A;
00054    ColumnVector Residual = Y - Fitted;
00055    Real ResVar = Residual.SumSquare() / (nobs-npred1);
00056 
00057    // Get diagonals of Hat matrix (an expensive way of doing this)
00058    DiagonalMatrix Hat;  Hat << X * (X.t() * X).i() * X.t();
00059 
00060    // print out answers
00061    cout << "\nEstimates and their standard errors\n\n";
00062 
00063    // make vector of standard errors
00064    ColumnVector SE(npred1);
00065    for (int i=1; i<=npred1; i++) SE(i) = sqrt(V(i)*ResVar);
00066    // use concatenation function to form matrix and use matrix print
00067    // to get two columns
00068    cout << setw(11) << setprecision(5) << (A | SE) << endl;
00069 
00070    cout << "\nObservations, fitted value, residual value, hat value\n";
00071 
00072    // use concatenation again; select only columns 2 to 3 of X
00073    cout << setw(9) << setprecision(3) <<
00074      (X.Columns(2,3) | Y | Fitted | Residual | Hat.AsColumn());
00075    cout << "\n\n";
00076 }
00077 
00078 void test2(Real* y, Real* x1, Real* x2, int nobs, int npred)
00079 {
00080    cout << "\n\nTest 2 - traditional, OK\n";
00081 
00082    // traditional sum of squares and products method of calculation
00083    // with subtraction of means - less subject to round-off error
00084    // than test1
00085 
00086    // make matrix of predictor values
00087    Matrix X(nobs,npred);
00088 
00089    // load x1 and x2 into X
00090    //    [use << rather than = when loading arrays]
00091    X.Column(1) << x1;  X.Column(2) << x2;
00092 
00093    // vector of Y values
00094    ColumnVector Y(nobs); Y << y;
00095 
00096    // make vector of 1s
00097    ColumnVector Ones(nobs); Ones = 1.0;
00098 
00099    // calculate means (averages) of x1 and x2 [ .t() takes transpose]
00100    RowVector M = Ones.t() * X / nobs;
00101 
00102    // and subtract means from x1 and x1
00103    Matrix XC(nobs,npred);
00104    XC = X - Ones * M;
00105 
00106    // do the same to Y [use Sum to get sum of elements]
00107    ColumnVector YC(nobs);
00108    Real m = Sum(Y) / nobs;  YC = Y - Ones * m;
00109 
00110    // form sum of squares and product matrix
00111    //    [use << rather than = for copying Matrix into SymmetricMatrix]
00112    SymmetricMatrix SSQ; SSQ << XC.t() * XC;
00113 
00114    // calculate estimate
00115    //    [bracket last two terms to force this multiplication first]
00116    //    [ .i() means inverse, but inverse is not explicity calculated]
00117    ColumnVector A = SSQ.i() * (XC.t() * YC);
00118 
00119    // calculate estimate of constant term
00120    //    [AsScalar converts 1x1 matrix to Real]
00121    Real a = m - (M * A).AsScalar();
00122 
00123    // Get variances of estimates from diagonal elements of inverse of SSQ
00124    //    [ we are taking inverse of SSQ - we need it for finding D ]
00125    Matrix ISSQ = SSQ.i(); DiagonalMatrix D; D << ISSQ;
00126    ColumnVector V = D.AsColumn();
00127    Real v = 1.0/nobs + (M * ISSQ * M.t()).AsScalar();
00128                                             // for calc variance of const
00129 
00130    // Calculate fitted values and residuals
00131    int npred1 = npred+1;
00132    ColumnVector Fitted = X * A + a;
00133    ColumnVector Residual = Y - Fitted;
00134    Real ResVar = Residual.SumSquare() / (nobs-npred1);
00135 
00136    // Get diagonals of Hat matrix (an expensive way of doing this)
00137    Matrix X1(nobs,npred1); X1.Column(1)<<Ones; X1.Columns(2,npred1)<<X;
00138    DiagonalMatrix Hat;  Hat << X1 * (X1.t() * X1).i() * X1.t();
00139 
00140    // print out answers
00141    cout << "\nEstimates and their standard errors\n\n";
00142    cout.setf(ios::fixed, ios::floatfield);
00143    cout << setw(11) << setprecision(5)  << a << " ";
00144    cout << setw(11) << setprecision(5)  << sqrt(v*ResVar) << endl;
00145    // make vector of standard errors
00146    ColumnVector SE(npred);
00147    for (int i=1; i<=npred; i++) SE(i) = sqrt(V(i)*ResVar);
00148    // use concatenation function to form matrix and use matrix print
00149    // to get two columns
00150    cout << setw(11) << setprecision(5) << (A | SE) << endl;
00151    cout << "\nObservations, fitted value, residual value, hat value\n";
00152    cout << setw(9) << setprecision(3) <<
00153      (X | Y | Fitted | Residual | Hat.AsColumn());
00154    cout << "\n\n";
00155 }
00156 
00157 void test3(Real* y, Real* x1, Real* x2, int nobs, int npred)
00158 {
00159    cout << "\n\nTest 3 - Cholesky\n";
00160 
00161    // traditional sum of squares and products method of calculation
00162    // with subtraction of means - using Cholesky decomposition
00163 
00164    Matrix X(nobs,npred);
00165    X.Column(1) << x1;  X.Column(2) << x2;
00166    ColumnVector Y(nobs); Y << y;
00167    ColumnVector Ones(nobs); Ones = 1.0;
00168    RowVector M = Ones.t() * X / nobs;
00169    Matrix XC(nobs,npred);
00170    XC = X - Ones * M;
00171    ColumnVector YC(nobs);
00172    Real m = Sum(Y) / nobs;  YC = Y - Ones * m;
00173    SymmetricMatrix SSQ; SSQ << XC.t() * XC;
00174 
00175    // Cholesky decomposition of SSQ
00176    LowerTriangularMatrix L = Cholesky(SSQ);
00177 
00178    // calculate estimate
00179    ColumnVector A = L.t().i() * (L.i() * (XC.t() * YC));
00180 
00181    // calculate estimate of constant term
00182    Real a = m - (M * A).AsScalar();
00183 
00184    // Get variances of estimates from diagonal elements of invoice of SSQ
00185    DiagonalMatrix D; D << L.t().i() * L.i();
00186    ColumnVector V = D.AsColumn();
00187    Real v = 1.0/nobs + (L.i() * M.t()).SumSquare();
00188 
00189    // Calculate fitted values and residuals
00190    int npred1 = npred+1;
00191    ColumnVector Fitted = X * A + a;
00192    ColumnVector Residual = Y - Fitted;
00193    Real ResVar = Residual.SumSquare() / (nobs-npred1);
00194 
00195    // Get diagonals of Hat matrix (an expensive way of doing this)
00196    Matrix X1(nobs,npred1); X1.Column(1)<<Ones; X1.Columns(2,npred1)<<X;
00197    DiagonalMatrix Hat;  Hat << X1 * (X1.t() * X1).i() * X1.t();
00198 
00199    // print out answers
00200    cout << "\nEstimates and their standard errors\n\n";
00201    cout.setf(ios::fixed, ios::floatfield);
00202    cout << setw(11) << setprecision(5)  << a << " ";
00203    cout << setw(11) << setprecision(5)  << sqrt(v*ResVar) << endl;
00204    ColumnVector SE(npred);
00205    for (int i=1; i<=npred; i++) SE(i) = sqrt(V(i)*ResVar);
00206    cout << setw(11) << setprecision(5) << (A | SE) << endl;
00207    cout << "\nObservations, fitted value, residual value, hat value\n";
00208    cout << setw(9) << setprecision(3) <<
00209       (X | Y | Fitted | Residual | Hat.AsColumn());
00210    cout << "\n\n";
00211 }
00212 
00213 void test4(Real* y, Real* x1, Real* x2, int nobs, int npred)
00214 {
00215    cout << "\n\nTest 4 - QR triangularisation\n";
00216 
00217    // QR triangularisation method
00218  
00219    // load data - 1s into col 1 of matrix
00220    int npred1 = npred+1;
00221    Matrix X(nobs,npred1); ColumnVector Y(nobs);
00222    X.Column(1) = 1.0;  X.Column(2) << x1;  X.Column(3) << x2;  Y << y;
00223 
00224    // do Householder triangularisation
00225    // no need to deal with constant term separately
00226    Matrix X1 = X;                 // Want copy of matrix
00227    ColumnVector Y1 = Y;
00228    UpperTriangularMatrix U; ColumnVector M;
00229    QRZ(X1, U); QRZ(X1, Y1, M);    // Y1 now contains resids
00230    ColumnVector A = U.i() * M;
00231    ColumnVector Fitted = X * A;
00232    Real ResVar = Y1.SumSquare() / (nobs-npred1);
00233 
00234    // get variances of estimates
00235    U = U.i(); DiagonalMatrix D; D << U * U.t();
00236 
00237    // Get diagonals of Hat matrix
00238    DiagonalMatrix Hat;  Hat << X1 * X1.t();
00239 
00240    // print out answers
00241    cout << "\nEstimates and their standard errors\n\n";
00242    ColumnVector SE(npred1);
00243    for (int i=1; i<=npred1; i++) SE(i) = sqrt(D(i)*ResVar);
00244    cout << setw(11) << setprecision(5) << (A | SE) << endl;
00245    cout << "\nObservations, fitted value, residual value, hat value\n";
00246    cout << setw(9) << setprecision(3) << 
00247       (X.Columns(2,3) | Y | Fitted | Y1 | Hat.AsColumn());
00248    cout << "\n\n";
00249 }
00250 
00251 void test5(Real* y, Real* x1, Real* x2, int nobs, int npred)
00252 {
00253    cout << "\n\nTest 5 - singular value\n";
00254 
00255    // Singular value decomposition method
00256  
00257    // load data - 1s into col 1 of matrix
00258    int npred1 = npred+1;
00259    Matrix X(nobs,npred1); ColumnVector Y(nobs);
00260    X.Column(1) = 1.0;  X.Column(2) << x1;  X.Column(3) << x2;  Y << y;
00261 
00262    // do SVD
00263    Matrix U, V; DiagonalMatrix D;
00264    SVD(X,D,U,V);                              // X = U * D * V.t()
00265    ColumnVector Fitted = U.t() * Y;
00266    ColumnVector A = V * ( D.i() * Fitted );
00267    Fitted = U * Fitted;
00268    ColumnVector Residual = Y - Fitted;
00269    Real ResVar = Residual.SumSquare() / (nobs-npred1);
00270 
00271    // get variances of estimates
00272    D << V * (D * D).i() * V.t();
00273 
00274    // Get diagonals of Hat matrix
00275    DiagonalMatrix Hat;  Hat << U * U.t();
00276 
00277    // print out answers
00278    cout << "\nEstimates and their standard errors\n\n";
00279    ColumnVector SE(npred1);
00280    for (int i=1; i<=npred1; i++) SE(i) = sqrt(D(i)*ResVar);
00281    cout << setw(11) << setprecision(5) << (A | SE) << endl;
00282    cout << "\nObservations, fitted value, residual value, hat value\n";
00283    cout << setw(9) << setprecision(3) << 
00284       (X.Columns(2,3) | Y | Fitted | Residual | Hat.AsColumn());
00285    cout << "\n\n";
00286 }
00287 
00288 int main()
00289 {
00290    cout << "\nDemonstration of Matrix package\n";
00291    cout << "\nPrint a real number (may help lost memory test): " << 3.14159265 << "\n";
00292 
00293    // Test for any memory not deallocated after running this program
00294    Real* s1; { ColumnVector A(8000); s1 = A.Store(); }
00295 
00296    {
00297       // the data
00298 
00299 #ifndef ATandT
00300       Real y[]  = { 8.3, 5.5, 8.0, 8.5, 5.7, 4.4, 6.3, 7.9, 9.1 };
00301       Real x1[] = { 2.4, 1.8, 2.4, 3.0, 2.0, 1.2, 2.0, 2.7, 3.6 };
00302       Real x2[] = { 1.7, 0.9, 1.6, 1.9, 0.5, 0.6, 1.1, 1.0, 0.5 };
00303 #else             // for compilers that do not understand aggregrates
00304       Real y[9], x1[9], x2[9];
00305       y[0]=8.3; y[1]=5.5; y[2]=8.0; y[3]=8.5; y[4]=5.7;
00306       y[5]=4.4; y[6]=6.3; y[7]=7.9; y[8]=9.1;
00307       x1[0]=2.4; x1[1]=1.8; x1[2]=2.4; x1[3]=3.0; x1[4]=2.0;
00308       x1[5]=1.2; x1[6]=2.0; x1[7]=2.7; x1[8]=3.6;
00309       x2[0]=1.7; x2[1]=0.9; x2[2]=1.6; x2[3]=1.9; x2[4]=0.5;
00310       x2[5]=0.6; x2[6]=1.1; x2[7]=1.0; x2[8]=0.5;
00311 #endif
00312 
00313       int nobs = 9;                           // number of observations
00314       int npred = 2;                          // number of predictor values
00315 
00316       // we want to find the values of a,a1,a2 to give the best
00317       // fit of y[i] with a0 + a1*x1[i] + a2*x2[i]
00318       // Also print diagonal elements of hat matrix, X*(X.t()*X).i()*X.t()
00319 
00320       // this example demonstrates five methods of calculation
00321 
00322       Try
00323       {
00324          test1(y, x1, x2, nobs, npred);
00325          test2(y, x1, x2, nobs, npred);
00326          test3(y, x1, x2, nobs, npred);
00327          test4(y, x1, x2, nobs, npred);
00328          test5(y, x1, x2, nobs, npred);
00329       }
00330       CatchAll { cout << BaseException::what(); }
00331    }
00332 
00333 #ifdef DO_FREE_CHECK
00334    FreeCheck::Status();
00335 #endif
00336    Real* s2; { ColumnVector A(8000); s2 = A.Store(); }
00337    cout << "\n\nThe following test does not work with all compilers - see documentation\n";
00338    cout << "Checking for lost memory: "
00339       << (unsigned long)s1 << " " << (unsigned long)s2 << " ";
00340    if (s1 != s2) cout << " - error\n"; else cout << " - ok\n";
00341 
00342    return 0;
00343 
00344 }
00345 


rl_agent
Author(s): Todd Hester
autogenerated on Thu Jun 6 2019 22:00:13