#include <iostream.h>
#include <string>
#include <sstream>
#include <fstream>
#include <stdio.h>
#include <math.h>

#define DEBUG 0

double *a;
double *q;
double *rate;
double *o;
double *b;
double *mean;

int tree(int n)
{
  return (int(n)+1)*int(n)/2;
  
}

int StrToInt(const std::string &str)
{
  std::istringstream is (str);
  int i;
  is >> i;

  return i;
}

double StrToDouble(const std::string &str)
{
  std::istringstream is (str);
  double i; 
  is >> i;
  return i;

}

double Readin(int con)
{
  std::string A;
  char *buf;
  char *temp;
  std::ifstream inFile("1990_1997s.csv");
  double n=0;

  if (inFile.fail())
    {
      cerr << "unable to open file input.dat for reading" << endl;
      exit(1);
    }
  double d = 0;
  while(std::getline(inFile,A))
    {
      d++;
      char *tok;
      int counter=0;
      buf=(char*)malloc(A.length()*sizeof(char));
      
      A.copy(buf,std::string::npos);
      
      tok = strtok(buf,",");
      while(tok != NULL)
        {
          if(d==1 and counter == 0)
            {
	      
	      n = StrToDouble(tok);
		  
	      for(int i =0; i < int(n); i++)
		{
		  if(con == 1)
		    {
		      mean[i] = 0;
		    }
		  else
		    {
		      o[i]=0;
		    }

		}
	      
	    }
          if(counter >= 1 && counter <=int(n))
            {
	      if(con == 1)
		{
		  mean[counter-1] =  mean[counter-1] + (StrToDouble(tok));
		  //  cout<<mean[counter-1]<<endl;
		}
	      if(con == 2)
		{
		  o[counter-1] = o[counter-1] + pow(StrToDouble(tok)-mean[counter-1],2); 
		  //  cout<<counter-1<<" "<<o[counter-1]<<endl;
		}
	    }
	  
	  tok = strtok(NULL,",");
          counter++;
        }
    }
  return d;
}

int main()
{
  std::string A;
  std::ifstream inFile("1990_1997s.csv");
  std::ofstream outFile("testing.csv");
  
  double n=0;
  char *buf;
  char *temp;
  int size=0;
  //int n;
  cout<<"What value of n? ";
  cin>> n;
  o =  (double*)malloc(int(n)*sizeof(double));
  mean = (double*)malloc(int(n)*sizeof(double));
  double N = Readin(1);
  for(int i = 0; i < n; i++)
    {
      mean[i] =  mean[i]/N;
      //  cout<< mean[i]<<endl;
    }
  N = Readin(2);
  for(int i = 0; i < n; i ++)
    {
      o[i]= sqrt((1/(N-1))*o[i]);
      cout << o[i] <<endl;
    }


  if (inFile.fail())
    {
      cerr << "unable to open file input.dat for reading" << endl;
      exit(1);
    }
  int d = 0;
  while(std::getline(inFile,A))
    {
      d++;
      cout<< d << ":" << endl;
      char *tok;
      int counter=0;
      buf=(char*)malloc(A.length()*sizeof(char));

      A.copy(buf,std::string::npos);

      tok = strtok(buf,",");
      while(tok != NULL)
        {
          if(counter==0)
            {
	      //      n=StrToDouble(tok);
	      a=(double*)malloc(int(n)*sizeof(double));
      	      int num = tree(int(n)+1);
	      rate=(double*)malloc((num)*sizeof(double));
	      q=(double*)malloc(int(n)*sizeof(double));
	      b=(double*)malloc(int(n)*sizeof(double));
            }
          else if(counter>=1 && counter <=int(n))
            {
              a[counter-1]=StrToDouble(tok);
              if(DEBUG)
                {
                  cout << "a[" << counter-1 << "]=" << a[counter-1] << endl;
                }
	      b[counter-1]=exp((-a[counter-1]/100*100)*counter);
	      //if(DEBUG)
	      //{
	      cout << "b[" << counter-1 << "]=" << b[counter-1] << endl;
		//}

	    }
  	  
	  tok = strtok(NULL,",");
          counter++;
        }



      //      for (int i =0; i < n; i++) {c[i]=0;}
      rate[0] = a[0]/100*100;
      for(int j = 1; j< int(n); j++)
	{
	  double ratesum=0;
	  for (int i = 0; i < j; i++)
	    {
	      ratesum = ratesum - rate[tree(i+1)-1];
	      //	  cout<< "ratesum: " <<ratesum <<endl;
	    }
	  double volprod = 1;
	  for (int i = 1; i < (j)+1; i ++)
	    {
	      double volsum = 0;
	      for (int k = 0; k < i; k++)
		{
		  volsum = volsum + o[j-1-k];
		  if (DEBUG)
		    {
		      cout<< "volsum[" << i << "," << k << "]: "<< volsum <<endl;
		    }
		}
	      volprod = volprod * (1 + exp( 2 * volsum));
	      
	      if (DEBUG)
		{
		  cout<< "volprod[" << i << "]: " << volprod <<endl;;
		}
	    }
	  q[j-1] = exp(ratesum)*volprod;
	  if (DEBUG)
	    {
	      cout<< "q[" << j << "]: " << q[j-1] << endl;
	    }
	  for(int k = 0; k < j+1; k++)
	    {
	      if(k == 0)
		{
		  
		  //int k = 0;
		  rate[tree(j+1)-1-k] = log(q[j-1]/(pow(2, j)*b[j]));
		  //cout<<rate[tree(j+1)-1-k] - 2*((j)*o[j-1])<<endl;
		  //rate[tree(j+1)-1-k] = rate[tree(j+1)-1-k] - 2*(j)*o[j-1];
		  //cout<<rate[tree(j+1)-1-k]<<endl;
		  //cout<<2*(j)*o[j-1]<<endl;
	  	}
	      if(k > 0 )
		{
		  rate[tree(j+1)-1-k] = rate[tree(j+1)-1] - 2*(k)*o[j-1];
		}
	      //  cout<< tree(j+1)-1-k<<endl; 
	      // cout<<o[j-1]<<endl;
	      if(k==j)
		{
		  // cout<< "rate[" << j << "," << j-k << "]: " << rate[tree(j+1)-1-k] << endl;
		  if(d>1 &&  j==1)
		    {
		      outFile<<endl;
		    }
		  if(j ==1)
		    {
		      outFile<< int(n)<< ","<<a[0]/100*100;
		    }	
		  outFile<<","<<rate[tree(j+1)-1-k];
		  if(j==int(n-1))
		    {
	outFile<<",0";
		      for(int s=1; s < int(n); s++)
			{
			outFile<<","<< 2*o[s];
			}
		    }
		}
	    }
	}
  
      //clear everything
      delete [] a;
      delete [] b;
      delete [] q;
      delete [] rate;
      delete [] buf;
      delete [] tok;

	
      //      delete [] root;

    }

  return 0;
}

