source: tol/tol_pkg/MhCnstrLinRegArima/MhCnstrLinRegArima.tol @ 1b685f9

1941-docker-image-to-testdevel
Last change on this file since 1b685f9 was 1b685f9, checked in by Víctor de Buen <vdebuen@…>, 17 years ago

Fixed syntax error

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@1677 be4846ae-f051-483a-831f-b64e7d08527f

  • Property mode set to 100644
File size: 16.3 KB
Line 
1/////////////////////////////////////////////////////////////////////////////
2// MhCnstrLinRegArima TOL Package header
3/////////////////////////////////////////////////////////////////////////////
4
5
6NameBlock MhCnstrLinRegArima = [[
7Text _.autodoc.description = "Metropolis-Hastings "
8"simulation of a linear regression with ARIMA noise and linear inequality "
9"constraints:\n"+
10//Y = X*b + z
11//A*b <= a
12//Ar(B)*Dif(B):z = Ma(B):e
13//e ~ N(0, s^2)
14"\n[[LatexEquation(Y=X\cdot\beta+Z)]] [[BR]]"
15"\n[[LatexEquation(A\cdot\beta\leq a)]] [[BR]] "
16"\n[[LatexEquation(\phi\left(B\right)\triangle\left(B\right)Z_{t}="
17"\theta\left(B\right)E_{t})]] [[BR]]"
18"\n[[LatexEquation(E\sim N\left(0,\sigma^{2}I\right))]] [[BR]]"
19"\n[[LatexEquation(Y,Z,E\in\mathbb{R}^{m}; X\in\mathbb{R}^{m\times n}; "
20"a\in\mathbb{R}^{r}\wedge A\in\mathbb{R}^{r\times n};rank\left(X\right)"
21"=n; m>n>0; r\geq0; n,m,r\in\mathbb{N})]] [[BR]]"
22"The tarjet of this package is just to serve as example and test for "
23"some constrained Metropolis-Hastings simulation methods and related "
24"functions as Gelman diagnosis.\n"
25"For more details see ["
26"https://www.tol-project.org/export/HEAD/tolp/trunk/tol_pkg/MhCnstrLinRegArima/doc/MhCnstrLinRegArima.pdf "
27"mhCnstrLinRegArima.pdf] (Sorry only spanish doc).";
28Text _.autodoc.url = "";
29Set _.autodoc.keys = [["MCMC","Markov chain","Bayesian","Metropolis",
30  "Hastings","linear","regression","ARIMA","inequality","constraints",
31  "polytope"]];
32Set _.autodoc.authors = [[
33   "vdebuen@tol-project.org"]];
34
35//////////////////////////////////////////////////////////////////////////////
36Class @Simulator
37//////////////////////////////////////////////////////////////////////////////
38{
39  ////////////////////////////////////////////////////////////////////////////
40  //Definition members
41  ////////////////////////////////////////////////////////////////////////////
42  VMatrix _.Y;       //Output matrix
43  VMatrix _.X;       //Input matrix
44  VMatrix _.A;       //Coefficients of inequation
45  VMatrix _.a;       //Border of inequation
46  Real    _.s2;      //Residuals variance
47  Polyn   _.ar;      //Autoregressive polynomial
48  Polyn   _.ma;      //Moving average polynomial
49  Polyn   _.dif;     //Difference and deterministic structure
50  NameBlock _.armaL; //ARMA filter
51
52  ////////////////////////////////////////////////////////////////////////////
53  //Auxiliar members
54  ////////////////////////////////////////////////////////////////////////////
55  //Data length
56  Real _.m = 0;
57  //Number of variables
58  Real _.n = 0;
59  //Number of inequations
60  Real _.r = 0;
61  //Residuals standard deviation
62  Real _.s = ?;
63  //The expected best ratio of candidates aceptation
64  Real _.acceptRatioTarget=?;
65  //Diagonal matrix with square root of inverse of sum of squares of each row
66  //of _.A used to calculate distances to the polytope _.A*b <= _.a
67  VMatrix _.DAi = Rand(0,0,0,0);
68  //Current number of tried candidates
69  Real _.tryNumber = 0;
70  //Current number of accepted candidates
71  Real _.acceptNumber = 0;
72  //Current ratio of candidates aceptation (_.acceptNumber / _.tryNumber)
73  Real _.acceptRatio = 0;
74  //Last accepted candidate
75  VMatrix _.b = Rand(0,0,0,0);
76  //Current distance from _.b to polytope A*b<=a
77  Real _.distance = ?;
78  //Current ratio of hyperspheric candidate region with center in _.b
79  Real _.ratio = ?;
80  //Candidate density of last accepted candidate
81  Real _.log.Q = -1/0;
82  //Target density of last accepted candidate
83  Real _.log.P = -1/0;
84  //Maximum environment ratio
85  Real _.g = ?;
86
87  ////////////////////////////////////////////////////////////////////////////
88  //Configuration parameters
89  ////////////////////////////////////////////////////////////////////////////
90  //Initial value of maximum environment ratio
91  Real _.gInitial = 0.01;
92  //Tuner factor for _.g that will be divided or multipled for this number
93  //in order to get the target accept ratio
94  Real _.gFactor = 1.1;
95  //Valid interval for accept ratio will be defined as
96  //  _.acceptRatioTarget*_.acceptRangeFactor <=
97  //  _.acceptNumber / _.tryNumber <=
98  //  _.acceptRatioTarget*_.acceptRangeFactor
99  Real _.acceptRangeFactor = 1.10;
100  //Maximum number of tries before accept a candidate
101  Real _.maxIter = 10000;
102
103  ////////////////////////////////////////////////////////////////////////////
104  //Creates an instance of @Simulator
105  Static @Simulator New(
106    VMatrix Y,      //Output matrix
107    VMatrix X,      //Input matrix
108    VMatrix A,      //Coefficients of inequation
109    VMatrix a,      //Border of inequation
110    Real    s2,     //Residuals variance
111    Polyn   ar,     //Autoregressive polynomial
112    Polyn   ma,     //Moving average polynomial
113    Polyn   dif     //Difference and deterministic structure
114  )
115  ////////////////////////////////////////////////////////////////////////////
116  {
117    @Simulator aux =
118    [[
119      VMatrix _.Y = Y;
120      VMatrix _.X = X;
121      VMatrix _.A = A;
122      VMatrix _.a = a;
123      Real    _.s2 = s2;
124      Polyn   _.ar = ar;
125      Polyn   _.ma = ma;
126      Polyn   _.dif = dif;
127      Real    _.m = VRows(_.X);
128      Real    _.n = VColumns(_.X);
129      Real    _.r = VRows(_.A);
130      NameBlock _.armaL = ARMAProcess::FastCholeskiCovFactor(_.ar,_.ma,_.m)
131    ]]
132  };
133
134  ////////////////////////////////////////////////////////////////////////////
135  //Initializes a Markov chain
136  Real initialize(VMatrix b0)
137  ////////////////////////////////////////////////////////////////////////////
138  {
139    Text _MID = "@Simulator::initialize ";
140
141    Real ok = Case(
142    !_.m,
143    { WriteLn(_MID+"Invalid dimensions VRows(_.X)==0","E"); 0 },
144    !_.n,
145    { WriteLn(_MID+"Invalid dimensions VColumns(_.X)==0","E"); 0 },
146    VRows   (_.Y)!=_.m,
147    { WriteLn(_MID+"Invalid dimensions VRows(_.Y)!=VRows(_.X)","E"); 0 },
148    VColumns(_.Y)!=  1,
149    { WriteLn(_MID+"Invalid dimensions VColumns(_.Y)!=1","E"); 0 },
150    _.r & (VColumns(_.A)!=_.n),
151    { WriteLn(_MID+"Invalid dimensions VColumns(_.A)!=VColumns(_.X)","E"); 0 },
152    _.r & (VRows   (_.a)!=_.r),
153    { WriteLn(_MID+"Invalid dimensions VRows(_.a)!=VRows(_.A)","E"); 0 },
154    _.r & (VColumns(_.a)!=  1),
155    { WriteLn(_MID+"Invalid dimensions VColumns(_.a)!=1","E"); 0 },
156    VRows(b0)!= _.n,
157    { WriteLn(_MID+"Invalid dimensions VRows(_.b)!=VColumns(_.X)","E"); 0 },
158    VColumns(b0)!=  1,
159    { WriteLn(_MID+"Invalid dimensions VColumns(_.b)!=1","E"); 0 },
160    1==1,
161    { True });
162    If(!ok, False,
163    {
164      Real _.tryNumber := 0;
165      Real _.acceptNumber := 0;
166      Real _.acceptRatio := 0;
167      Real _.g := _.gInitial;
168      Real _.s := Sqrt(_.s2);
169      Real _.acceptRatioTarget := 0.234  + (0.5-0.234)*Exp(1-_.n);
170      VMatrix If(_.r,
171      _.DAi := Mat2VMat(SetCol(For(1,_.r,Real(Real j)
172      {
173        VMatrix Ai = SubRow(_.A,[[j]]);
174        VMatMoment(Ai,2)^(-0.5)
175      }))));
176      Real setStore(b0);
177      True
178    })
179  };
180
181  ////////////////////////////////////////////////////////////////////////////
182  //Stores an accepted candidate b_ and updates related members
183  Real setStore(VMatrix b_)
184  ////////////////////////////////////////////////////////////////////////////
185  {
186    VMatrix _.b := b_;
187    Real _.distance := If(!_.r, 1/0, eval.distance(_.b));
188    Real _.ratio := If(!_.r, 1/0, Min(_.g, _.distance));
189    Real _.log.Q := If(!_.r, 1, { -3*Log(_.ratio) });
190    Real _.log.P := eval.log.density(_.b);
191    True
192  };
193
194  ////////////////////////////////////////////////////////////////////////////
195  //Calculates distance from a point b_ to the polytope A*b<=a
196  Real eval.distance(VMatrix b_)
197  ////////////////////////////////////////////////////////////////////////////
198  {
199    If(!_.r,1/0,
200      VMatMin(Abs(_.A*b_-_.a) $* _.DAi))
201  };
202
203  ////////////////////////////////////////////////////////////////////////////
204  //Calculates the ratio of the spheric region of candidates for a given
205  //point b_
206  Real eval.ratio(VMatrix b_)
207  ////////////////////////////////////////////////////////////////////////////
208  {
209    If(!_.r,1/0,
210    {
211      Real dist = eval.distance(b_);
212      Min(_.g, dist)
213    })
214  };
215
216  ////////////////////////////////////////////////////////////////////////////
217  //Calculates candidate log of density Q(b0, b1).
218  //If there are no restrictions Q is symmetric, so the value itŽs indiferent
219  //In other case it is a uniform that depends just on position of b0 respect
220  //to the polytope A*b<=a
221  //
222  Real eval.candidate.log.density(VMatrix b0, VMatrix b1)
223  ////////////////////////////////////////////////////////////////////////////
224  {
225    If(!_.r, 1,
226    {
227      -3*Log(eval.ratio(b0))
228    })
229  };
230
231  Real _2pi = 2*Pi;
232
233  ////////////////////////////////////////////////////////////////////////////
234  //Generates a new candidate with
235  VMatrix new.candidate(Real void)
236  ////////////////////////////////////////////////////////////////////////////
237  {
238    Text _MID = "@Simulator::new.candidate ";
239    If(!_.r,
240    {
241      VMatrix u = Gaussian(_.n,1,0,_.s*_.g);
242      _.b + u           
243    },
244    {
245      Real h = _.ratio*(Rand(0,1)^(1/_.n));
246      VMatrix u = Gaussian(_.n,1,0,1);
247      VMatrix v = u/(VMatDat(MtMSqr(u),1,1)^0.5);
248      VMatrix w = v * h;
249      VMatrix c_ = _.b + w;
250      Real trace.all(Real void)
251      {
252        WriteLn("TRACE "+_MID+
253          "\n"<<Matrix VMat2Mat(Tra(_.b|c_|w))<<"\n"<<
254          "\t_.ratio="<< _.ratio<<
255          "\th="<< h<<
256          "\t||v||="<<Real(VMatDat(MtMSqr(v),1,1)^0.5)<<
257          "\t||w||="<<Real(VMatDat(MtMSqr(w),1,1)^0.5));
258        0
259      };
260    //Real trace.all(0);
261      c_
262    })
263  };
264
265  ////////////////////////////////////////////////////////////////////////////
266  //Applies difference polynomial to a matrix
267  VMatrix applyDif(VMatrix z)
268  ////////////////////////////////////////////////////////////////////////////
269  {
270    Real d = Degree(_.dif);
271    SubRow(DifEq(_.dif, z), Range(d+1,_.m, 1))
272  };
273
274  ////////////////////////////////////////////////////////////////////////////
275  //Filters a noise vector to get standarized residuals N(0,I)
276  VMatrix standarize(VMatrix z)
277  ////////////////////////////////////////////////////////////////////////////
278  {
279    _.armaL::filter(applyDif(z/_.s))
280  };
281
282  ////////////////////////////////////////////////////////////////////////////
283  //Evaluates logarithm of target density for a point b
284  Real eval.log.density(VMatrix b)
285  ////////////////////////////////////////////////////////////////////////////
286  {
287    VMatrix e = standarize(_.Y-_.X*b);
288    - 0.5 * VMatDat(MtMSqr(e),1,1)
289
290  };
291
292  ////////////////////////////////////////////////////////////////////////////
293  //Returns true if c matches all inequations A*c<=a
294  Real isFeasible(VMatrix c)
295  ////////////////////////////////////////////////////////////////////////////
296  {
297    If(!_.r, True, VMatMax(_.A*c-_.a)<=0)
298  };
299
300  ////////////////////////////////////////////////////////////////////////////
301  //Tries a new candidate and returns true if it is accepted
302  Real maxLikelihoodStep(Real maxIter)
303  ////////////////////////////////////////////////////////////////////////////
304  {
305    Text _MID = "@Simulator::maxLikelihoodStep ";
306    Real iter = 1;
307    Real advance = False;
308    While(iter<=maxIter,
309    {   
310      VMatrix c = new.candidate(0);
311      Real log.P.c = eval.log.density(c);
312      Real advance := log.P.c > _.log.P;
313      Real trace.all(Real void)
314      {
315        WriteLn("TRACE "+_MID+
316          "\t_.log.P=\t"<<_.log.P<<
317          "\tlog.P.c=\t"<<log.P.c<<
318          "\tadvance=\t"<<advance);
319         0
320      };
321    //Real trace.all(0);
322      If(advance, { setStore(c) });
323      Real iter := iter+1
324    });
325    iter
326  };
327
328  ////////////////////////////////////////////////////////////////////////////
329  //Tries a new candidate and returns true if it is accepted
330  Real try(Real checkFeasible)
331  ////////////////////////////////////////////////////////////////////////////
332  {
333    Text _MID = "@Simulator::try ";
334    Real _.tryNumber := _.tryNumber + 1;
335    VMatrix c = new.candidate(0);
336    Real feasible = If(!checkFeasible, True, isFeasible(c));
337    If(!feasible,
338    {
339      WriteLn(_MID+"Non feasible point","");
340      False
341    },
342    {
343      Real log.Q.c = eval.candidate.log.density(c,_.b);
344      Real log.P.c = eval.log.density(c);
345      Real log.w = Min(1,(log.P.c-_.log.P)+(_.log.Q-log.Q.c));
346      Real w = Exp(log.w);
347      Real r = Rand(0,1);
348      Real accept = r <= w;
349      Real _.acceptRatio := _.acceptNumber / _.tryNumber;
350      Real trace.all(Real void)
351      {
352        WriteLn("TRACE "+_MID+
353          "\n"<<Matrix VMat2Mat(Tra(_.b|c))<<"\n"<<
354          "\taccept=\t"<<accept<<
355          "\tacceptRatio=\t"<<_.acceptRatio<<If(!_.r,"",
356          "\t_.g=\t"<<_.g<<
357          "\t_.distance=\t"<<_.distance<<
358          "\t_.ratio=\t"<<_.ratio<<
359          "\t_.log.Q=\t"<<_.log.Q<<
360          "\tlog.Q.c=\t"<<log.Q.c)<<
361          "\t_.log.P=\t"<<_.log.P<<
362          "\tlog.P.c=\t"<<log.P.c<<
363          "\tw=\t"<<w);
364         0
365      };
366    //Real trace.all(0);
367      If(accept,
368      {
369        Real _.acceptNumber := _.acceptNumber + 1;
370        setStore(Copy(c))
371      });
372      Real mclra::tuner(0);
373      accept
374    })
375  };
376
377  ////////////////////////////////////////////////////////////////////////////
378  //Modifies _.g in order to _.acceptRatio goes closer than
379  //_.acceptRatioTarget
380  Real tuner(Real 0)
381  //////////////////////////////////////////////////////////////////////////
382  {
383    Case(
384    _.acceptRatio<_.acceptRatioTarget/_.acceptRangeFactor,
385    {
386      Real _.g := _.g/_.gFactor
387    },
388    _.acceptRatio>_.acceptRatioTarget*_.acceptRangeFactor,
389    {
390      Real _.g := _.g*_.gFactor
391    },
392    1==1,
393    {
394      _.g
395    });
396    Real trace.all(Real void)
397    {
398      WriteLn("["<<_.tryNumber+"]"+
399              "_.acceptRatio="<<_.acceptRatio+" "+
400              "_.g="<<_.g+" ");
401      0
402    };
403  //Real trace.all(0);
404    If(_.r,
405    {
406      Real _.ratio := Min(_.g, _.distance);
407      Real _.log.Q := -3*Log(_.ratio)
408    });
409    _.g
410  }
411 
412}
413
414/*
415//VBR: UNDER CONSTRUCTION
416////////////////////////////////////////////////////////////////////////////
417Class @Simulator.Std : @Simulator
418////////////////////////////////////////////////////////////////////////////
419{
420  Real _.sz;
421  VMatrix _.Dx;
422  VMatrix _.Dix;
423
424  //////////////////////////////////////////////////////////////////////////
425  Static @Simulator.Std New(@Simulator reg)
426  //////////////////////////////////////////////////////////////////////////
427  {
428    VMatrix Y = reg::applyDif(reg::_.Y);
429    VMatrix X = reg::applyDif(reg::_.X);
430    VMatrix A = reg::_.A;
431    VMatrix a = reg::_.a;
432    Real    s2 = reg::_.s2;
433    Polyn   ar = reg::_.ar;
434    Polyn   ma = reg::_.ma;
435    Polyn   dif = reg::_.dif;
436    Real    m = reg::_.m;
437    Real    n = reg::_.n;
438    Real    r = reg::_.r;
439
440    Real sz = Sqrt(s2);
441    Matrix dx = SetCol(For(1,n,Real(Real j)
442    {
443      VMatrix Xj = SubCol(X,[[j]]);
444      Sqrt(VMatDat(MtMSqr(Xj),1,1))
445    }));
446    Matrix dxi = RPow(dx,-1);
447    VMatrix Dx = Eye(n,n,0,Mat2VMat(dx));
448    VMatrix Dix = Eye(n,n,0,Mat2VMat(dxi));
449
450    @Simulator.Std aux =
451    [[
452      VMatrix _.Y = Y;
453      VMatrix _.X = X;
454      VMatrix _.A = A;
455      VMatrix _.a = a;
456      Real    _.s2 = 1;
457      Polyn   _.ar = ar;
458      Polyn   _.ma = ma;
459      Polyn   _.dif = 1;
460      NameBlock _.armaL = reg::_.armaL;
461      Real    _.m = m;
462      Real    _.n = n;
463      Real    _.r = r;
464      Real    _.sz = sz;
465      VMatrix _.Dx = Dx;
466      VMatrix _.Dix = Dix
467    ]]
468  };
469
470  //////////////////////////////////////////////////////////////////////////
471  VMatrix applyDif(VMatrix z)
472  //////////////////////////////////////////////////////////////////////////
473  {
474    z
475  };
476
477  ////////////////////////////////////////////////////////////////////////////
478  //Filters a noise vector to get standarized residuals N(0,I)
479  VMatrix standarize(VMatrix z)
480  ////////////////////////////////////////////////////////////////////////////
481  {
482    _.armaL::filter(z)
483  }
484
485}
486*/
487
488]];
489
490
491/*
492  ////////////////////////////////////////////////////////////////////////////
493  //Tries a new candidate and returns true if it is accepted
494  Real try.multiple(Real length)
495  ////////////////////////////////////////////////////////////////////////////
496  {
497    Text _MID = "@Simulator::try ";
498    Real _.tryNumber := _.tryNumber + 1;
499    Set c = For(1, length, new.candidate);
500       
501      Real log.Q.c = eval.candidate.log.density(c,_.b);
502      Real log.P.c = eval.log.density(c);
503      Real log.w = Min(1,(log.P.c-_.log.P)+(_.log.Q-log.Q.c));
504      Real w = Exp(log.w);
505      Real r = Rand(0,1);
506      Real accept = r <= w;
507
508      If(accept,
509      {
510        Real _.acceptNumber := _.acceptNumber + 1;
511        setStore(c)
512      });
513      accept
514    })
515  };
516
517/* */
518
Note: See TracBrowser for help on using the repository browser.