/// <summary> /// Given one or more paths, the value of an option is returned. /// </summary> /// <param name="path"></param> /// <returns></returns> public override double Value(Path[] path) { if (path.Length != 1) { throw new ArgumentException("TODO: exactly one path required ({0} given)."); } int n = path[0].Count; if (n == 0) { throw new ArgumentException("TODO: the path cannot be empty."); } double price1 = 1.0; double averagePrice1 = 0.0; var p1 = path[0].Drift + path[0].Diffusion; UnaryFunction uf = Math.Exp; p1.Apply(uf); if (UseAntitheticVariance) { // see below for a SparseVectorized version double price2 = 1.0; double averagePrice2 = 0.0; SparseVector p2 = path[0].Drift - path[0].Diffusion; p2.Apply(uf); for (int i = 0; i < n; i++) { price1 *= p1.Data[i]; averagePrice1 += price1; price2 *= p2.Data[i]; averagePrice2 += price2; } averagePrice1 = _underlying * averagePrice1 / n; averagePrice2 = _underlying * averagePrice2 / n; return(Discount * ( Option.ExercisePayoff(_optionType, averagePrice1, _strike) + Option.ExercisePayoff(_optionType, averagePrice2, _strike) ) / 2.0); } // p1.AdjacentDifference(new BinaryFunction(mult)); // averagePrice1 = underlying * p1.Sum() / n for (int i = 0; i < n; i++) { price1 *= p1.Data[i]; averagePrice1 += price1; } averagePrice1 = _underlying * averagePrice1 / n; return(Discount * Option.ExercisePayoff(_optionType, averagePrice1, _strike)); }