// finance++

// BEGIN inputParamaters
struct IP_Binom
{
  double S0;
  unsigned int N;
  vector<double> dt;
  double U;
  double D;
  double r;
};

typedef struct IP_Binom IP_Binom;
// END inputParamaters

// BEGIN binomHead
/* Binom *********************/
class Binom 
{
 protected:
  static const unsigned int Q = 2;
  static const int I = 1;
  static const int J = 1;
  static const int K = 0;
  static const bool recomb = true;

  vector< vector<double> > M;
  vector< vector<double> > P;
  vector< double > disc;

  double S0;
  unsigned int N;
  vector<double> dt;
// END binomHead

// BEGIN binomCalc
 public:
  Binom(IP_Binom inIP)
    {
      // ensure that constraints are met in the input parameters

      if(inIP.dt.size() != 1)
	{
	  fprintf(stderr, "Binom invalid dt size %d, must be 1.\n", inIP.dt.size());
	  return;
	}
      
      double interest = pow(M_E, inIP.r * inIP.dt[0]);
      
      if(! (0 < inIP.D < (interest - 1) < inIP.U) )
	{
	  fprintf(stderr, "Binom invalid D and U values.\n");
	  return;
	}

      S0 = inIP.S0;
      N = inIP.N;
      dt = vector<double>(1);
      dt[0] = inIP.dt[0];

      vector<double> vd = vector<double>(2);

      // fill in the M vector

      vd[0] = inIP.D;
      vd[1] = inIP.U;

      M.push_back(vd);

      // fill in the P vector
      
      vd = vector<double>(2);
      vd[0] = (inIP.U - interest) / (inIP.U - inIP.D);
      vd[1] = 1 - vd[0];

      P.push_back(vd);

      disc = vector<double>(1);
      disc[0] = pow(M_E, (-inIP.r) * dt[0]);
    }
// END binomCalc
};




