private void initialize()
        {
            // firstSeed is chosen based on clock() and used for the first rng
            ulong firstSeed = (ulong)DateTime.Now.Ticks;
            MersenneTwisterUniformRng first = new MersenneTwisterUniformRng(firstSeed);

            // secondSeed is as random as it could be
            // feel free to suggest improvements
            ulong secondSeed = first.nextInt32();

            MersenneTwisterUniformRng second = new MersenneTwisterUniformRng(secondSeed);

            // use the second rng to initialize the final one
            ulong        skip = second.nextInt32() % 1000;
            List <ulong> init = new InitializedList <ulong>(4);

            init[0] = second.nextInt32();
            init[1] = second.nextInt32();
            init[2] = second.nextInt32();
            init[3] = second.nextInt32();

            rng_ = new MersenneTwisterUniformRng(init);

            for (ulong i = 0; i < skip; i++)
            {
                rng_.nextInt32();
            }
        }
Exemple #2
0
        public static List <Func <Vector, double> > multiPathBasisSystem(int dim, int order, PolynomType polynomType)
        {
            List <Func <double, double> > b = pathBasisSystem(order, polynomType);

            List <Func <Vector, double> > ret = new List <Func <Vector, double> >();

            ret.Add((xx) => 1.0);

            for (int i = 1; i <= order; ++i)
            {
                List <Func <Vector, double> > a = w(dim, i, polynomType, b);

                foreach (var iter in a)
                {
                    ret.Add(iter);
                }
            }

            // remove-o-zap: now remove redundant functions.
            // usually we do have a lot of them due to the construction schema.
            // We use a more "hands on" method here.
            List <bool> rm = new InitializedList <bool>(ret.Count, true);

            Vector x = new Vector(dim), v = new Vector(ret.Count);
            MersenneTwisterUniformRng rng = new MersenneTwisterUniformRng(1234UL);

            for (int i = 0; i < 10; ++i)
            {
                int k;

                // calculate random x vector
                for (k = 0; k < dim; ++k)
                {
                    x[k] = rng.next().value;
                }

                // get return values for all basis functions
                for (k = 0; k < ret.Count; ++k)
                {
                    v[k] = ret[k](x);
                }

                // find duplicates
                for (k = 0; k < ret.Count; ++k)
                {
                    if (v.First(xx => (Math.Abs(v[k] - xx) <= 10 * v[k] * Const.QL_EPSILON)).IsEqual(v.First() + k))
                    {
                        // don't remove this item, it's unique!
                        rm[k] = false;
                    }
                }
            }

            int iter2 = 0;

            for (int i = 0; i < rm.Count; ++i)
            {
                if (rm[i])
                {
                    ret.RemoveAt(iter2);
                }
                else
                {
                    ++iter2;
                }
            }

            return(ret);
        }
Exemple #3
0
 public DifferentialEvolution(Configuration configuration = null)
 {
     configuration_ = configuration ?? new Configuration();
     rng_           = new MersenneTwisterUniformRng(configuration_.seed);
 }
Exemple #4
0
        public SobolRsg(int dimensionality, ulong seed, DirectionIntegers directionIntegers)
        {
            dimensionality_  = dimensionality;
            sequenceCounter_ = 0;
            firstDraw_       = true;

            sequence_        = new Sample <List <double> >(new InitializedList <double>(dimensionality), 1.0);
            integerSequence_ = new InitializedList <ulong>(dimensionality);

            directionIntegers_ = new InitializedList <List <ulong> >(dimensionality);
            for (int i = 0; i < dimensionality; i++)
            {
                directionIntegers_[i] = new InitializedList <ulong>(bits_);
            }

            Utils.QL_REQUIRE(dimensionality > 0, () => "dimensionality must be greater than 0");
            Utils.QL_REQUIRE(dimensionality <= PPMT_MAX_DIM, () =>
                             "dimensionality " + dimensionality + " exceeds the number of available " +
                             "primitive polynomials modulo two (" + PPMT_MAX_DIM + ")");

            // initializes coefficient array of the k-th primitive polynomial
            // and degree of the k-th primitive polynomial
            List <uint> degree = new InitializedList <uint>(dimensionality_);
            List <long> ppmt   = new InitializedList <long>(dimensionality_);

            bool useAltPolynomials = false;

            if (directionIntegers == DirectionIntegers.Kuo || directionIntegers == DirectionIntegers.Kuo2 ||
                directionIntegers == DirectionIntegers.Kuo3 || directionIntegers == DirectionIntegers.SobolLevitan ||
                directionIntegers == DirectionIntegers.SobolLevitanLemieux)
            {
                useAltPolynomials = true;
            }

            // degree 0 is not used
            ppmt[0]   = 0;
            degree[0] = 0;
            int  k, index;
            uint currentDegree = 1;

            k     = 1;
            index = 0;

            uint altDegree = useAltPolynomials ? maxAltDegree : 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;
            }

            // 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

            // degenerate (no free direction integers) first dimension
            int j;

            for (j = 0; j < bits_; j++)
            {
                directionIntegers_[0][j] = (1UL << (bits_ - j - 1));
            }

            int maxTabulated = 0;

            // dimensions from 2 (k=1) to maxTabulated (k=maxTabulated-1) included
            // are initialized from tabulated coefficients
            switch (directionIntegers)
            {
            case DirectionIntegers.Unit:
                maxTabulated = dimensionality_;
                for (k = 1; k < maxTabulated; k++)
                {
                    for (int l = 1; l <= degree[k]; l++)
                    {
                        directionIntegers_[k][l - 1]   = 1UL;
                        directionIntegers_[k][l - 1] <<= (bits_ - l);
                    }
                }
                break;

            case DirectionIntegers.Jaeckel:
                // maxTabulated=32
                maxTabulated = initializers.Length + 1;
                for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++)
                {
                    j = 0;
                    // 0UL marks coefficients' end for a given dimension
                    while (initializers[k - 1][j] != 0UL)
                    {
                        directionIntegers_[k][j]   = initializers[k - 1][j];
                        directionIntegers_[k][j] <<= (bits_ - j - 1);
                        j++;
                    }
                }
                break;

            case DirectionIntegers.SobolLevitan:
                // maxTabulated=40
                maxTabulated = SLinitializers.Length + 1;
                for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++)
                {
                    j = 0;
                    // 0UL marks coefficients' end for a given dimension
                    while (SLinitializers[k - 1][j] != 0UL)
                    {
                        directionIntegers_[k][j]   = SLinitializers[k - 1][j];
                        directionIntegers_[k][j] <<= (bits_ - j - 1);
                        j++;
                    }
                }
                break;

            case DirectionIntegers.SobolLevitanLemieux:
                // maxTabulated=360
                maxTabulated = Linitializers.Length + 1;
                for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++)
                {
                    j = 0;
                    // 0UL marks coefficients' end for a given dimension
                    while (Linitializers[k - 1][j] != 0UL)
                    {
                        directionIntegers_[k][j]   = Linitializers[k - 1][j];
                        directionIntegers_[k][j] <<= (bits_ - j - 1);
                        j++;
                    }
                }
                break;

            case DirectionIntegers.JoeKuoD5:
                // maxTabulated=1898
                maxTabulated = JoeKuoD5initializers.Length + 1;
                for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++)
                {
                    j = 0;
                    // 0UL marks coefficients' end for a given dimension
                    while (JoeKuoD5initializers[k - 1][j] != 0UL)
                    {
                        directionIntegers_[k][j]   = JoeKuoD5initializers[k - 1][j];
                        directionIntegers_[k][j] <<= (bits_ - j - 1);
                        j++;
                    }
                }
                break;

            case DirectionIntegers.JoeKuoD6:
                // maxTabulated=1799
                maxTabulated = JoeKuoD6initializers.Length + 1;
                for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++)
                {
                    j = 0;
                    // 0UL marks coefficients' end for a given dimension
                    while (JoeKuoD6initializers[k - 1][j] != 0UL)
                    {
                        directionIntegers_[k][j]   = JoeKuoD6initializers[k - 1][j];
                        directionIntegers_[k][j] <<= (bits_ - j - 1);
                        j++;
                    }
                }
                break;

            case DirectionIntegers.JoeKuoD7:
                // maxTabulated=1898
                maxTabulated = JoeKuoD7initializers.Length + 1;
                for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++)
                {
                    j = 0;
                    // 0UL marks coefficients' end for a given dimension
                    while (JoeKuoD7initializers[k - 1][j] != 0UL)
                    {
                        directionIntegers_[k][j]   = JoeKuoD7initializers[k - 1][j];
                        directionIntegers_[k][j] <<= (bits_ - j - 1);
                        j++;
                    }
                }
                break;



            case DirectionIntegers.Kuo:
                // maxTabulated=4925
                maxTabulated = Kuoinitializers.Length + 1;
                for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++)
                {
                    j = 0;
                    // 0UL marks coefficients' end for a given dimension
                    while (Kuoinitializers[k - 1][j] != 0UL)
                    {
                        directionIntegers_[k][j]   = Kuoinitializers[k - 1][j];
                        directionIntegers_[k][j] <<= (bits_ - j - 1);
                        j++;
                    }
                }
                break;

            case DirectionIntegers.Kuo2:
                // maxTabulated=3946
                maxTabulated = Kuo2initializers.Length + 1;
                for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++)
                {
                    j = 0;
                    // 0UL marks coefficients' end for a given dimension
                    while (Kuo2initializers[k - 1][j] != 0UL)
                    {
                        directionIntegers_[k][j]   = Kuo2initializers[k - 1][j];
                        directionIntegers_[k][j] <<= (bits_ - j - 1);
                        j++;
                    }
                }
                break;

            case DirectionIntegers.Kuo3:
                // maxTabulated=4585
                maxTabulated = Kuo3initializers.Length + 1;
                for (k = 1; k < Math.Min(dimensionality_, maxTabulated); k++)
                {
                    j = 0;
                    // 0UL marks coefficients' end for a given dimension
                    while (Kuo3initializers[k - 1][j] != 0UL)
                    {
                        directionIntegers_[k][j]   = Kuo3initializers[k - 1][j];
                        directionIntegers_[k][j] <<= (bits_ - j - 1);
                        j++;
                    }
                }
                break;

            default:
                break;
            }

            // random initialization for higher dimensions
            if (dimensionality_ > maxTabulated)
            {
                MersenneTwisterUniformRng uniformRng = new MersenneTwisterUniformRng(seed);
                for (k = maxTabulated; k < dimensionality_; k++)
                {
                    for (int l = 1; l <= degree[k]; l++)
                    {
                        do
                        {
                            // u is in (0,1)
                            double u = uniformRng.next().value;
                            // the direction integer has at most the
                            // rightmost l bits non-zero
                            directionIntegers_[k][l - 1] = (ulong)(u * (1UL << l));
                        }while ((directionIntegers_[k][l - 1] & 1UL) == 0);
                        // iterate until the direction integer is odd
                        // that is it has the rightmost bit set

                        // shifting bits_-l bits to the left
                        // we are guaranteed that the l-th leftmost bit
                        // is set, and only the first l leftmost bit
                        // can be non-zero
                        directionIntegers_[k][l - 1] <<= (bits_ - l);
                    }
                }
            }

            // computation of directionIntegers_[k][l] for l>=degree_[k]
            // by recurrence relation
            for (k = 1; k < dimensionality_; k++)
            {
                uint gk = degree[k];
                for (int l = (int)gk; l < bits_; l++)
                {
                    // eq. 8.19 "Monte Carlo Methods in Finance" by P. Jдckel
                    ulong n = (directionIntegers_[k][(int)(l - gk)] >> (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_[k][(int)(l - z)];
                        }
                    }
                    // a[k][gk] is always set, so directionIntegers_[k][l-gk]
                    // will always enter
                    n ^= directionIntegers_[k][(int)(l - gk)];
                    directionIntegers_[k][l] = n;
                }
            }

            // initialize the Sobol integer/double vectors
            // first draw
            for (k = 0; k < dimensionality_; k++)
            {
                integerSequence_[k] = directionIntegers_[k][0];
            }
        }
 private SeedGenerator()
 {
     rng_ = new MersenneTwisterUniformRng(42UL);
     initialize();
 }