#ifndef __FILE_MLEUSR_H_SEEN__
#define __FILE_MLEUSR_H_SEEN__
/* ----------------------------------------------------------------------------

Copyright (C) 2018.

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 "libmle.h"
#include "mle_base.h"
#include "spline_interpolator.h"
#include "tree_policy.h"

namespace mle {

  class tree_usrmod;

  typedef tree_usrmod usrmod_type;

  /*
  Parameters:
  rho[1] = alpha, autoregressive parameter of log endowment
  rho[2] = sigma, sdev of log endowment autoregression
  rho[3] = beta,  discount rate of crra utility function
  rho[4] = gamma, risk aversion of crra utility function
  */

  const INTEGER n_vars  = 1;       //Number of variables in data 
  //const INTEGER n_obs = 100;       //Number of observations in data 
  const INTEGER n_parms = 4;       //Number of parameters
  const INTEGER n_stats = 6;       //Number of stats, mean, sdev of cg, sr, br
  const INTEGER n_sim = 1000;      //Number of simulations, N  
  
  struct tree_usrmod_variables {
    INTEGER N;   // simulation length
    scl::realmat log_consumption;
    scl::realmat log_stock_price;
    scl::realmat log_marginal_rate_of_substitution;
    scl::realmat log_consumption_growth;
    scl::realmat geometric_stock_return;
    scl::realmat geometric_risk_free_rate;
    tree_usrmod_variables() { }
    tree_usrmod_variables(INTEGER num_sim)
    : N(num_sim),
      log_consumption(N,1,0.0),
      log_stock_price(N,1,0.0),
      log_marginal_rate_of_substitution(N,1,0.0),
      log_consumption_growth(N,1,0.0),
      geometric_stock_return(N,1,0.0),
      geometric_risk_free_rate(N,1,0.0)
    { }
    std::vector<std::string> get_tree_usrmod_variables(scl::realmat& mv);
  };
  
  class tree_usrmod : public libmle::usrmod_base {
  private:
    const scl::realmat data;
    const INT_32BIT simulation_seed;
    tree_usrmod_variables mv;
    scl::realmat prior_mean;
    scl::realmat prior_sdev;
    scl::spline_interpolator P;
    scl::spline_interpolator Q;
    scl::spline_interpolator p;    
    scl::spline_interpolator q;    
    scl::realmat rho;
    bool gen_sim(scl::realmat& sim, scl::realmat& stats);
  public:
    tree_usrmod(const scl::realmat& dat, INTEGER len_mod_parm,
      INTEGER len_mod_func, const std::vector<std::string>& mod_pfvec,
      const std::vector<std::string>& mod_alvec, std::ostream& detail);
    INTEGER len_rho() { return n_parms; }
    INTEGER len_stats() { return n_stats; }
    bool get_stats(scl::realmat& stats);
    void get_rho(scl::realmat& parms) { parms = rho; }
    void set_rho(const scl::realmat& parms) { rho = parms; }
    bool support(const scl::realmat& parms);
    scl::den_val prior(const scl::realmat& parms, const scl::realmat& stats);
    scl::den_val likelihood();
    void write_usrvar(const char* filename);
  };
}

#endif
