/*@@@@@@@@@@@@@@@@@@@@@@@@ ExactValues.cpp @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 Random Option Pricing
 Summer 2002
 Authors: A. Korobchevsky
          S. Ferrando
 Ryerson University ALL RIGHTS RESERVED
 
 Purpose: Computes exact value of Discrete Binomial options
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

#include <cmath>

#include "../Und/Binom.h" 
#include "ExactValues.h" 




/*@@@@@@@@@@@@@@@@@@@@@@@@  calcResults  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 Function: calcResults
 Purpose: Compute the option price and it's standard error
 Param: Underlying - underlying function object
        Derivative - derivative function object
	double& - Option value (output param.)  
	double& - Standard error (output param.)
 Precondition: Underlying, Derivative and RNG parameters initialized
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

void ExactValues::calcResults(Underlying* binom, Derivative* ec, vector<double>& cv, vector<double>& se)
{ double sum_CT = 0;

// BEGIN Critical
  for (int k = 0; k <= binom->N; k++)
  { int* path = new int[binom->N];
    for (int i = 0; i < binom->N - k; i++) 
      path[i] = 0;      
    for (int i = binom->N - k; i < binom->N; i++) 
      path[i] = 1;    

    int comb = combinations(binom->N, k);
    for (int j = 1; j <= comb; j++)
    { double ST = S;
      ec->init();
      ec->update(ST); 

      for (int i = 0; i < binom->N; i++)
      { if (path[i] == 1) 
			 ST *= binom->U;
        else if (path[i] == 0) 
			 ST *= binom->D;
        ec->update(ST); 
      }

      double CT = ec->payOff(ST);
      sum_CT += CT * logProbability(1 - binom->P, binom->N, k) / comb;
      permutePath(path, binom->N);
    }
  }
// END Critical

  double call_value = sum_CT * exp(-binom->r * binom->T);
  for (int i = 0; i < 500; i++)
  { cv.push_back(call_value);
    se.push_back(0);
  }
} 
