#include <iostream>
#include <fstream>
#include <vector>
#include <ginac/ginac.h>

using namespace std;
using namespace GiNaC;

numeric TentMapping(const numeric y, numeric &yy)
{
  static const numeric half(0.5);
  static const numeric two(2.0);
  static const numeric one(1.0);
  if(y<=half)
    {
      yy = two*y;
    }
  else
    {
      yy = two*(one-y);
    }
}

numeric TentProcess(const numeric initial_condition, const int T, vector<numeric> &y)
{
  y.resize(T);
  y[0] = initial_condition;
  for(int t=1; t<T; t++)
    {
      TentMapping(y[t-1],y[t]);
    }
}

int WriteToFile(const vector<numeric> &y)
{ 
  ofstream datafile("tent_deterministic_process.dat"); 
  if(!datafile)
    {
      cout << "Cannot open file.\n"; 
      return 1; 
    }
  datafile << "# Data file generated by example_2_3." << endl;    
  for(int i=0; i<(int)y.size()-1; i++)
    {
      datafile << i+1 << " " << y[i] << endl;
    }
  datafile.close();
  return 0; 
}

int GenerateGNUPlotScript()
{
  ofstream gnuplotscript("tent_deterministic_process");
  if(!gnuplotscript)
    {
      cout << "Cannot open file.\n"; 
      return 1;
    }
  gnuplotscript << "#!/usr/bin/gnuplot -persist" << endl;
  gnuplotscript << "unset label" << endl;
  gnuplotscript << "set xlabel 'Time' " << endl;
  gnuplotscript << "show xlabel" << endl;
  gnuplotscript << "set ylabel 'y_t'  " << endl;
  gnuplotscript << "show ylabel" << endl;
  gnuplotscript << "set title 'Realization of the tent-map deterministic autoregression (with y_1 = 1/(3*sqrt(2)))'  " << endl;
  gnuplotscript << "show title" << endl;
  gnuplotscript << "unset key" << endl;
  gnuplotscript << "plot \"tent_deterministic_process.dat\" using 1:2 with lines" << endl;
  gnuplotscript.close();
}

int main ()
{
  Digits = 200;// Arbitrary precision.
  int T = 200;// Number of observations.
  numeric initial_condition = ((numeric)0.333333)/sqrt((numeric)2.0);
  vector<numeric> y;
  TentProcess(initial_condition, T, y);
  WriteToFile(y);
  GenerateGNUPlotScript();
  system("chmod u+x tent_deterministic_process");
  system("./tent_deterministic_process");
  return 0;
}
