home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2400 / nlopr.cc next >
Text File  |  1990-12-28  |  9KB  |  525 lines

  1. /* ---------------------------------------------------------------------------
  2.  
  3. nlmdl: nlopr.cc
  4.  
  5. nlmdl is a C++ implementation of the statistical methods in A. Ronald 
  6. Gallant, "Nonlinear Statistical Models," New York: John Wiley and Sons, 
  7. 1987, ISBN 0-471-80260-3, using a matrix class realmat that is distributed 
  8. with it.  The header files nlmdl.h and realmat.h describe the use of the 
  9. program and matrix class, respectively.  
  10.  
  11. Copyright (C) 1990.
  12.  
  13. A. Ronald Gallant
  14. P.O. Box 5513 
  15. Raleigh NC 27650-5513 
  16. USA   
  17.  
  18. Permission to use, copy, modify, and distribute this software and its 
  19. documentation for any purpose and without fee is hereby granted, provided 
  20. that the above copyright notice appear in all copies and that both that 
  21. copyright notice and this permission notice appear in supporting 
  22. documentation.  
  23.  
  24. This software is provided "as is" without any expressed or implied warranty.
  25.  
  26. ------------------------------------------------------------------------------
  27.  
  28. This is the collection of operators used by nlmdl.  They act on s, of class 
  29. status, using m, of class model; s must have been filled in and the function 
  30. initialize(), of class model, must have been called before using any of these 
  31. operators.  
  32.  
  33. --------------------------------------------------------------------------- */
  34.  
  35. int line_search(char* msg)
  36. {
  37.   REAL    norm_D, norm_theta;
  38.   REAL    step_length;
  39.   REAL    save_obj = s.obj;
  40.   realmat save_theta = s.theta;
  41.   realmat ss(1,1);
  42.   
  43.   ss = T(s.D) * s.D;
  44.   norm_D = sqrt(ss[1]);
  45.  
  46.   ss = T(s.theta) * s.theta;
  47.   norm_theta = sqrt(ss[1]);
  48.  
  49.   if ( norm_D < s.tol*(norm_theta + s.eps) ) {
  50.     strcpy(msg,"Tolerence check passed.\n");
  51.     return 1;
  52.   }
  53.  
  54.   for (step_length=1; step_length >= 0.5; step_length -= 0.1) {
  55.  
  56.     s.theta = save_theta + step_length * s.D;
  57.  
  58.     (*opr_obj)();
  59.  
  60.     if (s.obj < save_obj) {
  61.       sprintf(msg,"Step length = %g \n",step_length);
  62.       return 0 ;
  63.     }
  64.   }
  65.  
  66.   for (step_length=0.5; step_length > 1.0e-13; step_length *= 0.5) {
  67.  
  68.     s.theta = save_theta + step_length * s.D;
  69.  
  70.     (*opr_obj)();
  71.  
  72.     if (s.obj < save_obj) {
  73.       sprintf(msg,"Step length = %g \n",step_length);
  74.       return 0;
  75.     }
  76.   }
  77.  
  78.   strcpy(msg,"A line search did not improve this estimate.\n");
  79.   s.obj = save_obj;
  80.   s.theta = save_theta;
  81.   return 1;
  82. }
  83.  
  84.  
  85. void SUR_obj()
  86. {
  87.   INTEGER t; 
  88.   realmat sse(1,1,(REAL)0 );
  89.   realmat varinv = invpsd(s.var,s.eps);
  90.  
  91.   for (t=1; t<=s.n; t++) 
  92.     sse = sse + T(m.e(t)) * varinv * m.e(t);
  93.  
  94.   s.obj = sse[1];
  95. }
  96.  
  97.  
  98. void SUR_mgn()
  99. {
  100.   INTEGER t; 
  101.   realmat sse;
  102.   realmat varinv = invpsd(s.var,s.eps);
  103.  
  104.   sse.resize(1,1,(REAL)0 );
  105.   s.V.resize(s.p, s.p, (REAL)0 );
  106.   s.D.resize(s.p, 1, (REAL)0 );
  107.  
  108.   for(t=1; t<=s.n; t++) {
  109.     sse = sse + T(m.e(t))    * varinv * m.e(t);
  110.     s.V = s.V + T(m.dele(t)) * varinv * m.dele(t);
  111.     s.D = s.D + T(m.dele(t)) * varinv * m.e(t);
  112.   }
  113.  
  114.   s.obj = sse[1];
  115.   s.V = invpsd(s.V,s.eps);
  116.   s.D = - s.V * s.D;
  117. }
  118.  
  119.  
  120. void SUR_var(int var_loop)
  121. {
  122.   INTEGER i,j,t;
  123.   REAL fn;
  124.   
  125.   if (rows(s.var)==0 || cols(s.var)==0) {
  126.     s.var.resize(s.M,s.M,(REAL)0 );
  127.     for (i=1; i<=s.M; i++) s.var.elem(i,i)=1.0;
  128.   }
  129.  
  130.   if (var_loop == 0) return;
  131.  
  132.   for (i=1; i<=s.M; i++) 
  133.   for (j=1; j<=s.M; j++) 
  134.     s.var.elem(i,j) = (REAL)0 ;
  135.  
  136.   for (t=1; t<=s.n; t++) 
  137.     s.var = s.var + m.e(t) * T(m.e(t));
  138.  
  139.   if (s.M == 1 && s.n > s.p) {
  140.     fn = s.n - s.p;
  141.     strcpy(s.df,"corrected");
  142.   }
  143.   else {
  144.     fn = s.n;
  145.     strcpy(s.df,"uncorrected");
  146.   }
  147.  
  148.   for (i=1; i<=s.M; i++) 
  149.   for (j=1; j<=s.M; j++) 
  150.     s.var.elem(i,j) = s.var.elem(i,j)/fn;
  151. }
  152.  
  153.  
  154. void SUR_V() 
  155.   INTEGER t; 
  156.   INTEGER tau; 
  157.   INTEGER i; 
  158.   REAL    x,weight;
  159.   realmat varinv = invpsd(s.var,s.eps);
  160.   
  161.   if (strcmp(s.vartype,"heteroskedastic") == 0 || s.MA > 0) {
  162.  
  163.     realmat I(s.p,s.p,(REAL)0 );
  164.     realmat I_tau;
  165.  
  166.     for (tau=0; tau<=s.MA; tau++) {
  167.  
  168.       I_tau.resize(s.p,s.p,(REAL)0 );
  169.  
  170.       for (t=tau+1; t<=s.n; t++)
  171.         I_tau = I_tau 
  172.                 + T(m.dele(t)) * varinv * m.e(t)  
  173.                   * T(m.e(t-tau)) * varinv * m.dele(t-tau);
  174.  
  175.       if (strcmp(s.weights,"Parzen") == 0 && tau > 0) {
  176.         x = tau/(REAL)s.MA;
  177.  
  178.         if ( x < 0.5 ) 
  179.           weight = 1.0 - 6.0*pow(x,2) + 6.0*pow(x,3);
  180.         else
  181.           weight = 2.0*pow((1.0 - x),3);
  182.       }
  183.       else {
  184.         weight = 1.0;
  185.       }
  186.  
  187.       I = I + weight*I_tau;
  188.  
  189.       if (tau > 0)
  190.         I = I + weight*T(I_tau);
  191.     }
  192.  
  193.     s.V = s.V * I * s.V;
  194.   }
  195.  
  196.   s.rank = 0;
  197.   for (i=1; i<=s.p; i++)
  198.     if (s.V.elem(i,i) > (REAL)0  ) s.rank++;
  199.  
  200.   return;
  201. }
  202.  
  203.  
  204. realmat qZ;
  205.  
  206. void opr_qZ(INTEGER t)
  207.  
  208. {
  209.   INTEGER alpha, i, ii;
  210.  
  211.   realmat q_tmp(s.M,1);
  212.   realmat Z_tmp(s.K,1);
  213.  
  214.   qZ.resize(s.M*s.K,1);
  215.  
  216.   q_tmp = m.e(t);
  217.   Z_tmp = m.Z(t);
  218.  
  219.   for (alpha=1; alpha<=s.M; alpha++) {
  220.   for (i=1; i<=s.K; i++)             {
  221.  
  222.     ii = s.K*(alpha-1) + i;
  223.  
  224.     qZ[ii] = q_tmp[alpha] * Z_tmp[i];
  225.   }
  226.   }
  227. }
  228.  
  229.  
  230. realmat QZ;
  231.  
  232. void opr_QZ(INTEGER t)
  233. {
  234.   INTEGER alpha, i, ii, k;
  235.  
  236.   realmat Q_tmp(s.M,s.p);
  237.   realmat Z_tmp(s.K,1);
  238.  
  239.   QZ.resize(s.M*s.K,s.p);
  240.  
  241.   Q_tmp = m.dele(t);
  242.   Z_tmp = m.Z(t);
  243.  
  244.   for (k=1; k<=s.p; k++)             {
  245.   for (alpha=1; alpha<=s.M; alpha++) {
  246.   for (i=1; i<=s.K; i++)             {
  247.  
  248.     ii = s.K*(alpha-1) + i;
  249.  
  250.     QZ.elem(ii,k) = Q_tmp.elem(alpha,k) * Z_tmp[i];
  251.   }
  252.   }
  253.   }
  254. }
  255.  
  256.  
  257. realmat qZ_mts;
  258.  
  259. void opr_qZ_mts()
  260.  
  261.   INTEGER t;
  262.   
  263.   qZ_mts.resize(s.M*s.K, 1, (REAL)0 );
  264.  
  265.   for (t=1; t<=s.n; t++) {
  266.  
  267.     opr_qZ(t);
  268.  
  269.     qZ_mts = qZ_mts + qZ;
  270.  
  271.   }
  272. }
  273.  
  274.  
  275. realmat QZ_mts;
  276.  
  277. void opr_QZ_mts()
  278.   INTEGER t;
  279.   
  280.   QZ_mts.resize(s.M*s.K, s.p, (REAL)0 );
  281.  
  282.   for (t=1; t<=s.n; t++) {
  283.  
  284.     opr_QZ(t);
  285.  
  286.     QZ_mts = QZ_mts + QZ;
  287.  
  288.   }
  289. }
  290.  
  291.  
  292. realmat ZZ;
  293.  
  294. void opr_ZZ()
  295. {
  296.   INTEGER t;
  297.  
  298.   ZZ.resize(s.K, s.K, (REAL)0 );
  299.  
  300.   for (t=1; t<=s.n; t++)
  301.     ZZ = ZZ + m.Z(t) * T(m.Z(t));
  302. }
  303.  
  304.  
  305. void TSLS_obj() 
  306. {
  307.  
  308.   INTEGER alpha, i, ii;
  309.   INTEGER beta,  j, jj;
  310.  
  311.   realmat varinv = invpsd(s.var,s.eps);
  312.  
  313.   opr_qZ_mts();
  314.   opr_ZZ();
  315.  
  316.   realmat ZZinv = invpsd(ZZ,s.eps);
  317.   s.obj = (REAL)0 ;
  318.  
  319.   for (alpha=1; alpha<=s.M; alpha++) {
  320.   for (i=1; i<=s.K; i++)             {
  321.   for (beta=1; beta<=s.M; beta++)    {
  322.   for (j=1; j<=s.K; j++)             {
  323.  
  324.     ii = s.K*(alpha-1) + i;
  325.     jj = s.K*(beta-1)  + j;
  326.  
  327.     s.obj += qZ_mts[ii] * qZ_mts[jj] 
  328.              * varinv.elem(alpha,beta) * ZZinv.elem(i,j);
  329.   }
  330.   }
  331.   }
  332.   }
  333. }
  334.  
  335.  
  336. void TSLS_mgn() 
  337.   INTEGER alpha, i, ii;
  338.   INTEGER beta,  j, jj;
  339.   INTEGER k,l;
  340.  
  341.   realmat varinv = invpsd(s.var,s.eps);
  342.  
  343.   opr_qZ_mts();
  344.   opr_QZ_mts();
  345.   opr_ZZ();
  346.  
  347.   realmat ZZinv = invpsd(ZZ,s.eps);
  348.  
  349.   s.obj = (REAL)0 ;
  350.   s.V.resize(s.p, s.p, (REAL)0 );
  351.   s.D.resize(s.p, 1, (REAL)0 );
  352.  
  353.   for (alpha=1; alpha<=s.M; alpha++) {
  354.   for (i=1; i<=s.K; i++)             {
  355.   for (beta=1; beta<=s.M; beta++)    {
  356.   for (j=1; j<=s.K; j++)             {
  357.  
  358.     ii = s.K*(alpha-1) + i;
  359.     jj = s.K*(beta-1)  + j;
  360.  
  361.     s.obj += qZ_mts[ii] * qZ_mts[jj] 
  362.              * varinv.elem(alpha,beta) * ZZinv.elem(i,j);
  363.  
  364.   for (k=1; k<=s.p; k++)             {
  365.  
  366.     s.D[k] += QZ_mts.elem(ii,k) * qZ_mts[jj] 
  367.               * varinv.elem(alpha,beta) * ZZinv.elem(i,j);
  368.  
  369.   for (l=1; l<=s.p; l++)             {
  370.  
  371.     s.V.elem(k,l) += QZ_mts.elem(ii,k) * QZ_mts.elem(jj,l) 
  372.                      * varinv.elem(alpha,beta) * ZZinv.elem(i,j);
  373.  
  374.   }
  375.   }
  376.   }
  377.   }
  378.   }
  379.   }
  380.  
  381.   s.V = invpsd(s.V,s.eps);
  382.  
  383.   s.D = - s.V * s.D;
  384.  
  385. }
  386.  
  387.  
  388. void TSLS_V() 
  389.   INTEGER i;
  390.  
  391.   s.rank = 0;
  392.   for (i=1; i<=s.p; i++)
  393.     if (s.V.elem(i,i) > (REAL)0  ) s.rank++;
  394.  
  395.   return;
  396. };
  397.  
  398.  
  399. void GMM_obj() 
  400.  
  401.   realmat sse(1,1);
  402.   realmat varinv = invpsd(s.var,s.eps);
  403.  
  404.   opr_qZ_mts();
  405.  
  406.   sse = T(qZ_mts) * varinv * qZ_mts ;
  407.  
  408.   s.obj = sse[1];
  409. }
  410.  
  411.  
  412. void GMM_mgn() { 
  413.  
  414.   realmat sse(1,1);
  415.   realmat varinv = invpsd(s.var,s.eps);
  416.  
  417.   opr_qZ_mts();
  418.   opr_QZ_mts();
  419.  
  420.   sse = T(qZ_mts) * varinv * qZ_mts ;
  421.  
  422.   s.obj = sse[1];
  423.  
  424.   s.D = T(QZ_mts) * varinv * qZ_mts ;
  425.  
  426.   s.V = T(QZ_mts) * varinv * QZ_mts ;
  427.  
  428.   s.V = invpsd(s.V,s.eps);
  429.  
  430.   s.D = - s.V * s.D;
  431.  
  432. }
  433.  
  434.  
  435. void GMM_var(int var_loop) 
  436. {
  437.   INTEGER l = s.M * s.K;
  438.   INTEGER t; 
  439.   INTEGER tau; 
  440.   INTEGER alpha, i, j, ii, jj; 
  441.   REAL    x,weight;
  442.  
  443.   strcpy(s.df,"uncorrected");
  444.  
  445.   if (rows(s.var)==0 || cols(s.var)==0) {
  446.  
  447.     s.var.resize(l,l,(REAL)0 );
  448.  
  449.     opr_ZZ();
  450.  
  451.     for (alpha=1; alpha<=s.M; alpha++) {
  452.     for (i=1; i<=s.K; i++)             {
  453.     for (j=1; j<=s.K; j++)             {
  454.  
  455.       ii = s.K*(alpha-1) + i;
  456.       jj = s.K*(alpha-1) + j;
  457.  
  458.       s.var.elem(ii,jj) = ZZ.elem(i,j);
  459.  
  460.     }
  461.     }
  462.     }
  463.   }
  464.   if (var_loop == 0) return;
  465.  
  466.   realmat I(l,l);
  467.   realmat I_tau(l,l);
  468.   realmat qZ_lag(l,1);
  469.  
  470.   for (tau=0; tau<=s.MA; tau++) {
  471.  
  472.     for (i=1; i<=l; i++)
  473.     for (j=1; j<=l; j++)
  474.       I_tau.elem(i,j)=(REAL)0 ;
  475.  
  476.     for (t=tau+1; t<=s.n; t++) {
  477.  
  478.       opr_qZ(t-tau);
  479.       qZ_lag = qZ;
  480.       opr_qZ(t);
  481.       
  482.       I_tau = I_tau + qZ * T(qZ_lag);
  483.     }
  484.  
  485.     if (strcmp(s.weights,"Parzen") == 0 && tau > 0) {
  486.       x = tau/(REAL)s.MA;
  487.       if ( x < 0.5 ) 
  488.         weight = 1.0 - 6.0*pow(x,2) + 6.0*pow(x,3);
  489.       else
  490.         weight = 2.0*pow((1.0 - x),3);
  491.         
  492.     }
  493.     else {
  494.       weight = 1.0;
  495.     }
  496.  
  497.     I = I + weight*I_tau;
  498.     if (tau > 0) {
  499.       I = I + weight*T(I_tau);
  500.     }
  501.   }
  502.  
  503.   s.var = I;
  504.  
  505.   return;
  506. }
  507.  
  508.  
  509. void GMM_V() 
  510.   INTEGER i;
  511.  
  512.   s.rank = 0;
  513.   for (i=1; i<=s.p; i++)
  514.     if (s.V.elem(i,i) > (REAL)0  ) s.rank++;
  515.  
  516.   return;
  517. }
  518.