#ifndef __FILE_SVMNT_H_SEEN__
#define __FILE_SVMNT_H_SEEN__ 

/*-----------------------------------------------------------------------------

Copyright (C) 2012, 2013

A. Ronald Gallant
Post Office Box 659
Chapel Hill NC 27514-0659
USA   

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

-----------------------------------------------------------------------------*/

#include "libscl.h"

//#define USE_FOC_MOMENT_CONDITIONS
#undef USE_FOC_MOMENT_CONDITIONS

// Both data and particle have one row; time t is the column index.
// The total number of observations available is assumed to be data.ncol().
// Of these, n <= data.ncol() are used to compute the mean of data and bound t.

class svmnt : public scl::moment_function_base { 
private:
  const scl::realmat* data;
  const scl::realmat* particle;
  INTEGER n;  // maximum value of t index
  INTEGER L;  // how many lags to use in computing moments, L >= 0
  scl::realmat theta;
public:
  svmnt() : data(0), particle(0), n(0), L(0), theta(4,1) 
    {  theta[1] = 0.9; theta[2] = 0.9; theta[3] = 0.5;  theta[4] = 0.01; }
  svmnt(scl::realmat* datptr, scl::realmat* partptr, INTEGER Tmax,INTEGER lags) 
    : data(datptr), particle(partptr), n(Tmax), L(lags), theta(3,1) 
    { theta[1] = 0.9; theta[2] = 0.9; theta[3] = 0.5;  theta[4] = 0.01; 
      if (Tmax > data->ncol()) scl::error("Error, svmnt, Tmax too large");
      #if defined USE_FOC_MOMENT_CONDITIONS
      if (L!=0) scl::error("Error, svmnt, lags must be 0 for foc moment cond"); 
      #endif
    }  
  bool set_data(const scl::realmat* datptr);
  bool set_particle(const scl::realmat* part);
  bool set_sample_size(INTEGER Tmax);  // changes n
  bool set_L(INTEGER lags)             // changes L
    { L = lags; 
      #if defined USE_FOC_MOMENT_CONDITIONS
      if (L!=0) scl::error("Error, svmnt, lags must be 0 for foc moment cond"); 
      #endif
      return true; 
    }
  bool set_theta(const scl::realmat& parm); 
  INTEGER get_T0()  { return L+2; }
  INTEGER get_d() 
    { 
      #if defined USE_FOC_MOMENT_CONDITIONS
      return 4;
      #else
      return L+4; 
      #endif
    }
  scl::realmat operator() (INTEGER t); // returns moment conditions at time t
};

#endif
