Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/util/newmat/garch.cpp @ 4565

Last change on this file since 4565 was 4565, checked in by patrick, 19 years ago

orxonox/trunk: added the newmat library to the project. needs some translation in directory, temp under util/newmat. is needed by the collision detection engine to perform lin alg operations such as eigenvector decomposition. perhaps we will make our own library to do that later.

File size: 6.3 KB
Line 
1
2#define WANT_STREAM
3#define WANT_MATH
4#define WANT_FSTREAM
5
6#include "newmatap.h"
7#include "newmatio.h"
8#include "newmatnl.h"
9
10#ifdef use_namespace
11using namespace RBD_LIBRARIES;
12#endif
13
14// This is a demonstration of a special case of the Garch model
15// Observe two series X and Y of length n
16// and suppose
17//    Y(i) = beta * X(i) + epsilon(i)
18// where epsilon(i) is normally distributed with zero mean and variance =
19//    h(i) = alpha0 + alpha1 * square(epsilon(i-1)) + beta1 * h(i-1).
20// Then this program is supposed to estimate beta, alpha0, alpha1, beta1
21// The Garch model is supposed to model something like an instability
22// in the stock or options market following an unexpected result.
23// alpha1 determines the size of the instability and beta1 determines how
24// quickly is dies away.
25// We should, at least, have an X of several columns and beta as a vector
26
27inline Real square(Real x) { return x*x; }
28
29// the class that defines the GARCH log-likelihood
30
31class GARCH11_LL : public LL_D_FI
32{
33   ColumnVector Y;                 // Y values
34   ColumnVector X;                 // X values
35   ColumnVector D;                 // derivatives of loglikelihood
36   SymmetricMatrix D2;             // - approximate second derivatives
37   int n;                          // number of observations
38   Real beta, alpha0, alpha1, beta1;
39                                   // the parameters
40
41public:
42
43   GARCH11_LL(const ColumnVector& y, const ColumnVector& x)
44      : Y(y), X(x), n(y.Nrows()) {}
45                                   // constructor - load Y and X values
46
47   void Set(const ColumnVector& p) // set parameter values
48   {
49      para = p;
50      beta = para(1); alpha0 = para(2);
51      alpha1 = para(3); beta1 = para(4);
52   }
53
54   bool IsValid();                 // are parameters valid
55   Real LogLikelihood();           // return the loglikelihood
56   ReturnMatrix Derivatives();     // derivatives of log-likelihood
57   ReturnMatrix FI();              // Fisher Information matrix
58};
59
60bool GARCH11_LL::IsValid()
61{ return alpha0>0 && alpha1>0 && beta1>0 && (alpha1+beta1)<1.0; }
62
63Real GARCH11_LL::LogLikelihood()
64{
65//   cout << endl << "                           ";
66//   cout << setw(10) << setprecision(5) << beta;
67//   cout << setw(10) << setprecision(5) << alpha0;
68//   cout << setw(10) << setprecision(5) << alpha1;
69//   cout << setw(10) << setprecision(5) << beta1;
70//   cout << endl;
71   ColumnVector H(n);              // residual variances
72   ColumnVector U = Y - X * beta;  // the residuals
73   ColumnVector LH(n);     // derivative of log-likelihood wrt H
74                           // each row corresponds to one observation
75   LH(1)=0;
76   Matrix Hderiv(n,4);     // rectangular matrix of derivatives
77                           // of H wrt parameters
78                           // each row corresponds to one observation
79                           // each column to one of the parameters
80
81   // Regard Y(1) as fixed and don't include in likelihood
82   // then put in an expected value of H(1) in place of actual value
83   //   which we don't know. Use
84   // E{H(i)} = alpha0 + alpha1 * E{square(epsilon(i-1))} + beta1 * E{H(i-1)}
85   // and  E{square(epsilon(i-1))} = E{H(i-1)} = E{H(i)}
86   Real denom = (1-alpha1-beta1);
87   H(1) = alpha0/denom;    // the expected value of H
88   Hderiv(1,1) = 0;
89   Hderiv(1,2) = 1.0 / denom;
90   Hderiv(1,3) = alpha0 / square(denom);
91   Hderiv(1,4) = Hderiv(1,3);
92   Real LL = 0.0;          // the log likelihood
93   Real sum1 = 0;          // for forming derivative wrt beta
94   Real sum2 = 0;          // for forming second derivative wrt beta
95   for (int i=2; i<=n; i++)
96   {
97      Real u1 = U(i-1); Real h1 = H(i-1);
98      Real h = alpha0 + alpha1*square(u1) + beta1*h1; // variance of this obsv.
99      H(i) = h; Real u = U(i);
100      LL += log(h) + square(u) / h;        // -2 * log likelihood
101      // Hderiv are derivatives of h with respect to the parameters
102      // need to allow for h1 depending on parameters
103      Hderiv(i,1) = -2*u1*alpha1*X(i-1) + beta1*Hderiv(i-1,1);  // beta
104      Hderiv(i,2) = 1 + beta1*Hderiv(i-1,2);                    // alpha0
105      Hderiv(i,3) = square(u1) + beta1*Hderiv(i-1,3);           // alpha1
106      Hderiv(i,4) = h1 + beta1*Hderiv(i-1,4);                   // beta1
107      LH(i) = -0.5 * (1/h - square(u/h));
108      sum1 += u * X(i)/ h;
109      sum2 += square(X(i)) / h;
110   }
111   D = Hderiv.t()*LH;         // derivatives of likelihood wrt parameters
112   D(1) += sum1;              // add on deriv wrt beta from square(u) term
113//   cout << setw(10) << setprecision(5) << D << endl;
114
115   // do minus expected value of second derivatives
116   if (wg)                    // do only if second derivatives wanted
117   {
118      Hderiv.Row(1) = 0.0;
119      Hderiv = H.AsDiagonal().i() * Hderiv;
120      D2 << Hderiv.t() * Hderiv;  D2 = D2 / 2.0;
121      D2(1,1) += sum2;
122//      cout << setw(10) << setprecision(5) << D2 << endl;
123//      DiagonalMatrix DX; EigenValues(D2,DX);
124//      cout << setw(10) << setprecision(5) << DX << endl;
125
126   }
127   return -0.5 * LL;
128}
129
130ReturnMatrix GARCH11_LL::Derivatives()
131{ return D; }
132
133ReturnMatrix GARCH11_LL::FI()
134{
135   if (!wg) cout << endl << "unexpected call of FI" << endl;
136   return D2;
137}
138
139
140
141int main()
142{
143   // get data
144   ifstream fin("garch.dat");
145   if (!fin) { cout << "cannot find garch.dat\n"; exit(1); }
146   int n; fin >> n;            // series length
147   // Y contains the dependant variable, X the predictor variable
148   ColumnVector Y(n), X(n);
149   int i;
150   for (i=1; i<=n; i++) fin >> Y(i) >> X(i);
151   cout << "Read " << n << " data points - begin fit\n\n";
152   // now do the fit
153   ColumnVector H(n);
154   GARCH11_LL garch11(Y,X);                  // loglikehood "object"
155   MLE_D_FI mle_d_fi(garch11,100,0.0001);    // mle "object"
156   ColumnVector Para(4);                     // to hold the parameters
157   Para << 0.0 << 0.1 << 0.1 << 0.1;         // starting values
158      // (Should change starting values to a more intelligent formula)
159   mle_d_fi.Fit(Para);                       // do the fit
160   ColumnVector SE;
161   mle_d_fi.GetStandardErrors(SE);
162   cout << "\n\n";
163   cout << "estimates and standard errors\n";
164   cout << setw(15) << setprecision(5) << (Para | SE) << endl << endl;
165   SymmetricMatrix Corr;
166   mle_d_fi.GetCorrelations(Corr);
167   cout << "correlation matrix\n";
168   cout << setw(10) << setprecision(2) << Corr << endl << endl;
169   cout << "inverse of correlation matrix\n";
170   cout << setw(10) << setprecision(2) << Corr.i() << endl << endl;
171   return 0;
172}
173
174
175
Note: See TracBrowser for help on using the repository browser.