Changeset 197
- Timestamp:
- 05/29/08 17:36:15 (3 months ago)
- Files:
-
- trunk/QLNet/Examples/EquityOption/EquityOption.cs (modified) (2 diffs)
- trunk/QLNet/QLNet/Math/randomnumbers/inversecumulativersg.cs (modified) (4 diffs)
- trunk/QLNet/QLNet/Math/randomnumbers/randomsequencegenerator.cs (modified) (3 diffs)
- trunk/QLNet/QLNet/Math/randomnumbers/rngtraits.cs (modified) (3 diffs)
- trunk/QLNet/QLNet/Math/randomnumbers/sobolrsg.cs (modified) (4 diffs)
- trunk/QLNet/QLNet/Pricingengines/vanilla/mceuropeanengine.cs (modified) (3 diffs)
- trunk/QLNet/QLNet/Pricingengines/vanilla/mcvanillaengine.cs (modified) (4 diffs)
- trunk/QLNet/Test2008/T_RNGTraits.cs (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/QLNet/Examples/EquityOption/EquityOption.cs
r195 r197 218 218 Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); 219 219 220 220 221 // Monte Carlo Method: MC (crude) 221 222 timeSteps = 1; … … 234 235 Console.WriteLine("{0,-" + widths[3] + ":0.000000}", "N/A"); 235 236 236 //// Monte Carlo Method: QMC (Sobol) 237 //method = "QMC (Sobol)"; 238 //Size nSamples = 32768; // 2^15 239 240 //boost::shared_ptr<PricingEngine> mcengine2; 241 //mcengine2 = MakeMCEuropeanEngine<LowDiscrepancy>(bsmProcess) 242 // .withSteps(timeSteps) 243 // .withSamples(nSamples); 244 //europeanOption.setPricingEngine(mcengine2); 245 //std::cout << std::setw(widths[0]) << std::left << method 246 // << std::fixed 247 // << std::setw(widths[1]) << std::left << europeanOption.NPV() 248 // << std::setw(widths[2]) << std::left << "N/A" 249 // << std::setw(widths[3]) << std::left << "N/A" 250 // << std::endl; 237 238 // Monte Carlo Method: QMC (Sobol) 239 method = "QMC (Sobol)"; 240 int nSamples = 32768; // 2^15 241 242 IPricingEngine mcengine2 = new MakeMCEuropeanEngine<LowDiscrepancy>(bsmProcess) 243 .withSteps(timeSteps) 244 .withSamples(nSamples) 245 .value(); 246 europeanOption.setPricingEngine(mcengine2); 247 Console.Write("{0,-" + widths[0] + "}", method); 248 Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); 249 Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A"); 250 Console.WriteLine("{0,-" + widths[3] + ":0.000000}", "N/A"); 251 251 252 252 //// Monte Carlo Method: MC (Longstaff Schwartz) trunk/QLNet/QLNet/Math/randomnumbers/inversecumulativersg.cs
r178 r197 45 45 \endcode 46 46 */ 47 public class InverseCumulativeRsg<USG, IC> : IRNG where USG : IRNG where IC : IValue , new(){47 public class InverseCumulativeRsg<USG, IC> : IRNG where USG : IRNG where IC : IValue { 48 48 //typedef Sample<std::vector<Real> > sample_type; 49 49 … … 51 51 private int dimension_; 52 52 private Sample<List<double>> x_; 53 private IC ICD_ = new IC();53 private IC ICD_; 54 54 55 55 public InverseCumulativeRsg(USG uniformSequenceGenerator) { … … 63 63 } 64 64 65 66 #region IRNG interface 65 67 //! returns next sample from the Gaussian distribution 66 68 public Sample<List<double>> nextSequence() { … … 75 77 public Sample<List<double>> lastSequence() { return x_; } 76 78 public int dimension() { return dimension_; } 79 80 public IRNG factory(int dimensionality, ulong seed) { throw new NotSupportedException(); } 81 #endregion 77 82 } 78 83 } trunk/QLNet/QLNet/Math/randomnumbers/randomsequencegenerator.cs
r192 r197 27 27 Sample<List<double>> nextSequence(); 28 28 Sample<List<double>> lastSequence(); 29 30 IRNG factory(int dimensionality, ulong seed); 29 31 } 30 32 … … 41 43 // typedef Sample<std::vector<Real> > sample_type; 42 44 private int dimensionality_; 43 public int dimension() { return dimensionality_; }44 45 45 46 private RNG rng_; … … 64 65 } 65 66 67 public List<ulong> nextInt32Sequence() { 68 for (int i = 0; i < dimensionality_; i++) { 69 int32Sequence_[i] = rng_.nextInt32(); 70 } 71 return int32Sequence_; 72 } 73 74 #region IRGN interface 66 75 public Sample<List<double>> nextSequence() { 67 76 sequence_.weight = 1.0; 68 for (int i =0; i<dimensionality_; i++) {77 for (int i = 0; i < dimensionality_; i++) { 69 78 Sample<double> x = rng_.next(); // typename RNG::sample_type x(rng_.next()); 70 79 sequence_.value[i] = x.value; 71 sequence_.weight *= x.weight;80 sequence_.weight *= x.weight; 72 81 } 73 82 return sequence_; 74 83 } 75 84 76 public List<ulong> nextInt32Sequence() { 77 for (int i=0; i<dimensionality_; i++) { 78 int32Sequence_[i] = rng_.nextInt32(); 79 } 80 return int32Sequence_; 85 public Sample<List<double>> lastSequence() { return sequence_; } 86 87 public int dimension() { return dimensionality_; } 88 89 public IRNG factory(int dimensionality, ulong seed) { 90 return new RandomSequenceGenerator<RNG>(dimensionality, seed); 81 91 } 82 public Sample<List<double>> lastSequence() { 83 return sequence_; 84 } 92 #endregion 85 93 } 86 94 } trunk/QLNet/QLNet/Math/randomnumbers/rngtraits.cs
r194 r197 30 30 } 31 31 32 public interface IRSG { 33 int allowsErrorEstimate { get; } 34 object make_sequence_generator(int dimension, ulong seed); 35 } 36 32 37 // random number traits 33 public class GenericPseudoRandom<URNG, IC> 34 where URNG : IRNGTraits, new() 35 where IC : IValue, new() { 38 public class GenericPseudoRandom<URNG, IC> : IRSG where URNG : IRNGTraits, new() where IC : IValue, new() { 36 39 // data 37 public static IC icInstance ;40 public static IC icInstance = new IC(); 38 41 39 42 //// typedefs … … 44 47 45 48 // more traits 46 public const int allowsErrorEstimate = 1;49 public int allowsErrorEstimate { get { return 1; } } 47 50 48 51 // factory 49 public static InverseCumulativeRsg<RandomSequenceGenerator<URNG>,IC>make_sequence_generator(int dimension, ulong seed) {52 public object make_sequence_generator(int dimension, ulong seed) { 50 53 RandomSequenceGenerator<URNG> g = new RandomSequenceGenerator<URNG>(dimension, seed); 51 54 return (icInstance != null ? new InverseCumulativeRsg<RandomSequenceGenerator<URNG>, IC>(g, icInstance) … … 65 68 // typedef GenericPseudoRandom<MersenneTwisterUniformRng, InverseCumulativePoisson> PoissonPseudoRandom; 66 69 public class PoissonPseudoRandom : GenericPseudoRandom<MersenneTwisterUniformRng, InverseCumulativePoisson> { } 70 71 72 public class GenericLowDiscrepancy<URSG, IC> : IRSG where URSG : IRNG, new() where IC : IValue, new() { 73 // typedefs 74 //typedef URSG ursg_type; 75 //typedef InverseCumulativeRsg<ursg_type,IC> rsg_type; 76 77 // data 78 public static IC icInstance = new IC(); 79 80 // more traits 81 public int allowsErrorEstimate { get { return 0; } } 82 83 // factory 84 public object make_sequence_generator(int dimension, ulong seed) { 85 URSG g = (URSG)new URSG().factory(dimension, seed); 86 return (icInstance != null ? new InverseCumulativeRsg<URSG, IC>(g, icInstance) 87 : new InverseCumulativeRsg<URSG, IC>(g)); 88 } 89 } 90 91 //! default traits for low-discrepancy sequence generation 92 //typedef GenericLowDiscrepancy<SobolRsg, InverseCumulativeNormal> LowDiscrepancy; 93 public class LowDiscrepancy : GenericLowDiscrepancy<SobolRsg, InverseCumulativeNormal> { } 67 94 } trunk/QLNet/QLNet/Math/randomnumbers/sobolrsg.cs
r173 r197 95 95 their discrepancy against known good values. 96 96 */ 97 public partial class SobolRsg {97 public partial class SobolRsg : IRNG { 98 98 //typedef Sample<List<double>> sample_type; 99 99 … … 114 114 Kuo, Kuo2, Kuo3 }; 115 115 116 // required for generics 117 public SobolRsg() { } 118 116 119 /*! \pre dimensionality must be <= PPMT_MAX_DIM */ 117 //public SobolRsg(int dimensionality, ulong seed = 0, DirectionIntegers directionIntegers = Jaeckel);118 120 public SobolRsg(int dimensionality) : this(dimensionality, 0, DirectionIntegers.Jaeckel) { } 121 public SobolRsg(int dimensionality, ulong seed) : this(dimensionality, seed, DirectionIntegers.Jaeckel) { } 119 122 public SobolRsg(int dimensionality, ulong seed, DirectionIntegers directionIntegers) { 120 123 dimensionality_ = dimensionality; … … 451 454 } 452 455 456 #region IRNG interface 453 457 public Sample<List<double>> nextSequence() { 454 458 List<ulong> v = nextInt32Sequence(); 455 459 // normalize to get a double in (0,1) 456 for (int k =0; k<dimensionality_; ++k)460 for (int k = 0; k < dimensionality_; ++k) 457 461 sequence_.value[k] = v[k] * normalizationFactor_; 458 462 return sequence_; … … 460 464 461 465 public Sample<List<double>> lastSequence() { return sequence_; } 462 466 463 467 public int dimension() { return dimensionality_; } 468 469 public IRNG factory(int dimensionality, ulong seed) { 470 return new SobolRsg(dimensionality, seed); 471 } 472 #endregion 464 473 } 465 474 } trunk/QLNet/QLNet/Pricingengines/vanilla/mceuropeanengine.cs
r196 r197 29 29 checking it against analytic results. 30 30 */ 31 public class MCEuropeanEngine<RNG, S> : MCVanillaEngine<SingleVariate, RNG, S> 31 public class MCEuropeanEngine<RNG, S> : MCVanillaEngine<SingleVariate, RNG, S> 32 where RNG : IRSG, new() 32 33 where S : IGeneralStatistics, new() { 33 34 … … 56 57 //! Monte Carlo European engine factory 57 58 // template <class RNG = PseudoRandom, class S = Statistics> 58 public class MakeMCEuropeanEngine<RNG> : MakeMCEuropeanEngine<RNG, Statistics> {59 public class MakeMCEuropeanEngine<RNG> : MakeMCEuropeanEngine<RNG, Statistics> where RNG : IRSG, new() { 59 60 public MakeMCEuropeanEngine(GeneralizedBlackScholesProcess process) : base(process) { } 60 61 } 61 62 62 public class MakeMCEuropeanEngine<RNG, S> where S : IGeneralStatistics, new() {63 public class MakeMCEuropeanEngine<RNG, S> where RNG : IRSG, new() where S : IGeneralStatistics, new() { 63 64 private GeneralizedBlackScholesProcess process_; 64 65 private bool antithetic_, controlVariate_; … … 95 96 if(samples_ != 0) 96 97 throw new ApplicationException("number of samples already set"); 97 if ( PseudoRandom.allowsErrorEstimate == 0)98 if (new RNG().allowsErrorEstimate == 0) 98 99 throw new ApplicationException("chosen random generator policy does not allow an error estimate"); 99 100 tolerance_ = tolerance; trunk/QLNet/QLNet/Pricingengines/vanilla/mcvanillaengine.cs
r196 r197 26 26 /*! \ingroup vanillaengines */ 27 27 public abstract class MCVanillaEngine<MC, RNG, S> : MCVanillaEngine<MC, RNG, S, VanillaOption> 28 where RNG : IRSG, new() 28 29 where S : IGeneralStatistics, new() { 29 30 protected MCVanillaEngine(StochasticProcess process, int timeSteps, int timeStepsPerYear, bool brownianBridge, … … 36 37 public abstract class MCVanillaEngine<MC, RNG, S, Inst> : McSimulation<MC, RNG, S>, 37 38 IGenericEngine<OneAssetOption.Arguments, OneAssetOption.Results> 38 where S : IGeneralStatistics, new() {39 where RNG : IRSG, new() where S : IGeneralStatistics, new() { 39 40 //typedef typename McSimulation<MC,RNG,S>::path_generator_type path_generator_type; 40 41 //typedef typename McSimulation<MC,RNG,S>::path_pricer_type path_pricer_type; … … 74 75 base.calculate(requiredTolerance_, requiredSamples_, maxSamples_); 75 76 results_.value = mcModel_.sampleAccumulator().mean(); 76 if ( PseudoRandom.allowsErrorEstimate != 0)77 if (new RNG().allowsErrorEstimate != 0) 77 78 results_.errorEstimate = mcModel_.sampleAccumulator().errorEstimate(); 78 79 } … … 95 96 int dimensions = process_.factors(); 96 97 TimeGrid grid = timeGrid(); 97 var generator = PseudoRandom.make_sequence_generator(dimensions * (grid.size() - 1), seed_);98 IRNG generator = (IRNG)new RNG().make_sequence_generator(dimensions * (grid.size() - 1), seed_); 98 99 return new PathGenerator<IRNG>(process_, grid, generator, brownianBridge_); 99 100 } trunk/QLNet/Test2008/T_RNGTraits.cs
r189 r197 34 34 //("Testing Gaussian pseudo-random number generation..."); 35 35 36 InverseCumulativeRsg<RandomSequenceGenerator<MersenneTwisterUniformRng>, InverseCumulativeNormal> rsg =37 PseudoRandom.make_sequence_generator(100, 1234);36 var rsg = (InverseCumulativeRsg<RandomSequenceGenerator<MersenneTwisterUniformRng>, InverseCumulativeNormal>) 37 new PseudoRandom().make_sequence_generator(100, 1234); 38 38 39 39 List<double> values = rsg.nextSequence().value; … … 57 57 58 58 PoissonPseudoRandom.icInstance = new InverseCumulativePoisson(); 59 var rsg = PoissonPseudoRandom.make_sequence_generator(100, 1234);59 IRNG rsg = (IRNG)new PoissonPseudoRandom().make_sequence_generator(100, 1234); 60 60 61 61 List<double> values = rsg.nextSequence().value; … … 78 78 79 79 PoissonPseudoRandom.icInstance = new InverseCumulativePoisson(4.0); 80 var rsg = PoissonPseudoRandom.make_sequence_generator(100, 1234);80 IRNG rsg = (IRNG)new PoissonPseudoRandom().make_sequence_generator(100, 1234); 81 81 82 82 List<double> values = rsg.nextSequence().value;