Пример #1
0
        public void InitialisationTest(int dim, SobolDirection direction)
        {
            var sobol = new SobolRsg(dim, direction);

            sobol.NextSequence();
            Assert.IsTrue(true);
        }
Пример #2
0
        private void DirectionInit(SobolDirection direction)
        {
            // initializes bits_ direction integers for each dimension
            // and store them into directionIntegers_[dimensionality_][bits_]
            //
            // In each dimension k with its associated primitive polynomial,
            // the first degree_[k] direction integers can be chosen freely
            // provided that only the l leftmost bits can be non-zero, and
            // that the l-th leftmost bit must be set
            int j;

            for (j = 0; j < Bits; j++)
            {
                directionIntegers[j][0] = (uint)(1 << (Bits - j - 1));
            }

            switch (direction)
            {
            case SobolDirection.Jaeckel:
                FillDirection(directionIntegers, dimensionality, JaeckelInitializers.Value);
                break;

            case SobolDirection.SobolLevitan:
                FillDirection(directionIntegers, dimensionality, SLinitializers.Value);
                break;

            case SobolDirection.SobolLevitanLemieux:
                FillDirection(directionIntegers, dimensionality, Linitializers.Value);
                break;

            case SobolDirection.JoeKuoD5:
                FillDirection(directionIntegers, dimensionality, JoeKuoD5Initializers.Value);
                break;

            case SobolDirection.JoeKuoD6:
                FillDirection(directionIntegers, dimensionality, JoeKuoD6Initializers.Value);
                break;

            case SobolDirection.JoeKuoD7:
                FillDirection(directionIntegers, dimensionality, JoeKuoD7Initializers.Value);
                break;

            case SobolDirection.Kuo:
                FillDirection(directionIntegers, dimensionality, KuoInitializers.Value);
                break;

            case SobolDirection.Kuo2:
                FillDirection(directionIntegers, dimensionality, Kuo2Initializers.Value);
                break;

            case SobolDirection.Kuo3:
                FillDirection(directionIntegers, dimensionality, Kuo3Initializers.Value);
                break;
            }
        }
Пример #3
0
        public void TestCallBachelier(int dim, SobolDirection direction)
        {
            var gaussianGen = RandomGenerators.GaussianSobol(direction).Build(dim);

            var chrono = new Stopwatch();

            chrono.Start();

            var       atmCalls    = new double[dim];
            var       strikeCall1 = new double[dim];
            var       strikeCall2 = new double[dim];
            var       strikePut1  = new double[dim];
            var       strikePut2  = new double[dim];
            const int nbPaths     = 1000000;

            for (int index = 0; index < nbPaths; index++)
            {
                var sample = gaussianGen.Next();
                for (int i = 0; i < dim; i++)
                {
                    var gaussian = sample[i];
                    atmCalls[i]    += Math.Max(0.0, gaussian);
                    strikeCall1[i] += Math.Max(0.0, gaussian - 1.0);
                    strikeCall2[i] += Math.Max(0.0, gaussian - 2.0);
                    strikePut1[i]  += Math.Max(0.0, -1.0 - gaussian);
                    strikePut2[i]  += Math.Max(0.0, -2.0 - gaussian);
                }
            }
            for (int i = 0; i < dim; i++)
            {
                atmCalls[i]    /= nbPaths;
                strikeCall1[i] /= nbPaths;
                strikeCall2[i] /= nbPaths;
                strikePut1[i]  /= nbPaths;
                strikePut2[i]  /= nbPaths;
            }

            chrono.Stop();
            Console.WriteLine("Elapsed " + chrono.Elapsed);

            var refAtmCalls    = atmCalls.Select(c => BachelierOption.Price(0.0, 0.0, 1.0, 1.0, 1)).ToArray();
            var refStrikeCall1 = atmCalls.Select(c => BachelierOption.Price(0.0, 1.0, 1.0, 1.0, 1)).ToArray();
            var refStrikeCall2 = atmCalls.Select(c => BachelierOption.Price(0.0, 2.0, 1.0, 1.0, 1)).ToArray();
            var refStrikePut1  = atmCalls.Select(c => BachelierOption.Price(0.0, -1.0, 1.0, 1.0, -1)).ToArray();
            var refStrikePut2  = atmCalls.Select(c => BachelierOption.Price(0.0, -2.0, 1.0, 1.0, -1)).ToArray();

            UnitTestUtils.EqualDoubleArray(atmCalls, refAtmCalls, 2.0e-5, true);
            UnitTestUtils.EqualDoubleArray(strikeCall1, refStrikeCall1, 8.0e-5, true);
            UnitTestUtils.EqualDoubleArray(strikeCall2, refStrikeCall2, 6.0e-4, true);
            UnitTestUtils.EqualDoubleArray(strikePut1, refStrikePut1, 8.0e-5, true);
            UnitTestUtils.EqualDoubleArray(strikePut2, refStrikePut2, 6.0e-4, true);
        }
Пример #4
0
        private static void FillDegreeAndPolynom(int dimensionality, SobolDirection direction,
                                                 out uint[] degree, out long[] ppmt)
        {
            // initializes coefficient array of the k-th primitive polynomial
            // and degree of the k-th primitive polynomial
            degree = new uint[dimensionality];
            ppmt   = new long[dimensionality];

            bool useAltPolynomials = direction == SobolDirection.Kuo ||
                                     direction == SobolDirection.Kuo2 ||
                                     direction == SobolDirection.Kuo3 ||
                                     direction == SobolDirection.SobolLevitan ||
                                     direction == SobolDirection.SobolLevitanLemieux;

            // degree 0 is not used
            ppmt[0]   = 0;
            degree[0] = 0;
            uint currentDegree = 1;
            uint altDegree     = useAltPolynomials ? MaxAltDegree : 0;
            int  k             = 1;
            int  index         = 0;

            for (; k < Math.Min(dimensionality, altDegree); k++, index++)
            {
                ppmt[k] = AltPrimitivePolynomials[currentDegree - 1][index];
                if (ppmt[k] == -1)
                {
                    ++currentDegree;
                    index   = 0;
                    ppmt[k] = AltPrimitivePolynomials[currentDegree - 1][index];
                }

                degree[k] = currentDegree;
            }

            for (; k < dimensionality; k++, index++)
            {
                ppmt[k] = PrimitivePolynomials[currentDegree - 1][index];
                if (ppmt[k] == -1)
                {
                    ++currentDegree;
                    index   = 0;
                    ppmt[k] = PrimitivePolynomials[currentDegree - 1][index];
                }
                degree[k] = currentDegree;
            }
        }
Пример #5
0
        public SobolRsg(int dimensionality, SobolDirection direction)
        {
            if (dimensionality < 0)
            {
                throw new ApplicationException("dimensionality must be greater than 0");
            }
            if (!(dimensionality <= PPMT_MAX_DIM))
            {
                throw new ApplicationException("dimensionality " + dimensionality + " exceeds the number of available "
                                               + "primitive polynomials modulo two (" + PPMT_MAX_DIM + ")");
            }

            this.dimensionality = dimensionality;
            sequenceCounter     = 0;
            firstDraw           = true;
            integerSequence     = new uint[dimensionality];

            sequence = new double[dimensionality];
            for (int i = 0; i < dimensionality; ++i)
            {
                sequence[i] = 1.0;
            }

            directionIntegers = new uint[Bits][];
            for (int i = 0; i < Bits; i++)
            {
                directionIntegers[i] = new uint[dimensionality];
            }

            uint[] degree;
            long[] ppmt;
            FillDegreeAndPolynom(this.dimensionality, direction, out degree, out ppmt);

            DirectionInit(direction);

            // computation of directionIntegers_[k][l] for l>=degree_[k]
            // by recurrence relation
            for (int k = 1; k < this.dimensionality; k++)
            {
                uint gk = degree[k];
                for (var l = (int)gk; l < Bits; l++)
                {
                    // eq. 8.19 "Monte Carlo Methods in Finance" by P. Jдckel
                    uint n = (directionIntegers[(int)(l - gk)][k] >> (int)gk);
                    // a[k][j] are the coefficients of the monomials in ppmt[k]
                    // The highest order coefficient a[k][0] is not actually
                    // used in the recurrence relation, and the lowest order
                    // coefficient a[k][gk] is always set: this is the reason
                    // why the highest and lowest coefficient of
                    // the polynomial ppmt[k] are not included in its encoding,
                    // provided that its degree is known.
                    // That is: a[k][j] = ppmt[k] >> (gk-j-1)
                    for (uint z = 1; z < gk; z++)
                    {
                        // XORed with a selection of (unshifted) direction
                        // integers controlled by which of the a[k][j] are set
                        if ((((ulong)ppmt[k] >> (int)(gk - z - 1)) & 1UL) != 0)
                        {
                            n ^= directionIntegers[(int)(l - z)][k];
                        }
                    }
                    // a[k][gk] is always set, so directionIntegers_[k][l-gk]
                    // will always enter
                    n ^= directionIntegers[(int)(l - gk)][k];
                    directionIntegers[l][k] = n;
                }
            }

            // initialize the Sobol integer/double vectors
            // first draw
            for (int k = 0; k < this.dimensionality; k++)
            {
                integerSequence[k] = directionIntegers[0][k];
            }
        }
Пример #6
0
 public GaussSobolGeneratorFactory(SobolDirection sobolDirection)
 {
     this.sobolDirection = sobolDirection;
 }
Пример #7
0
 public static IRandomGeneratorFactory GaussianSobol(SobolDirection sobolDirection)
 {
     return(new GaussSobolGeneratorFactory(sobolDirection));
 }