Exemple #1
0
        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
        private void initialize()
        {
            // firstSeed is chosen based on clock() and used for the first rng
            ulong firstSeed = (ulong)DateTime.Now.Ticks; // (std::time(0));
            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 #3
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)) == 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 #4
0
 private SeedGenerator()
 {
     rng_ = new MersenneTwisterUniformRng(42UL);
     initialize();
 }
Exemple #5
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)) == 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 #6
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_);
            }

            if (!(dimensionality > 0))
            {
                throw new Exception("dimensionality must be greater than 0");
            }
            if (!(dimensionality <= PPMT_MAX_DIM))
            {
                throw new Exception("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;
                }
            }

            // in case one needs to check the directionIntegers used

            /* bool printDirectionIntegers = false;
             * if (printDirectionIntegers) {
             *     std::ofstream outStream("directionIntegers.txt");
             *     for (k=0; k<std::min(32UL,dimensionality_); k++) {
             *         outStream << std::endl << k+1       << "\t"
             *                                << degree[k] << "\t"
             *                                << ppmt[k]   << "\t";
             *         for (j=0; j<10; j++) {
             *             outStream << io::power_of_two(
             *                 directionIntegers_[k][j]) << "\t";
             *         }
             *     }
             *     outStream.close();
             * }
             */

            // initialize the Sobol integer/double vectors
            // first draw
            for (k = 0; k < dimensionality_; k++)
            {
                integerSequence_[k] = directionIntegers_[k][0];
            }
        }
Exemple #7
0
 private SeedGenerator() {
     rng_ = new MersenneTwisterUniformRng(42UL);
     initialize();
 }
Exemple #8
0
        public void testQRSolve()
        {
            // Testing QR solve...
               setup();

               double tol = 1.0e-12;
               MersenneTwisterUniformRng rng = new MersenneTwisterUniformRng( 1234 );
               Matrix bigM = new Matrix( 50, 100, 0.0 );
               for ( int i = 0; i < Math.Min( bigM.rows(), bigM.columns() ); ++i )
               {
              bigM[i, i] = i + 1.0;
               }
               Matrix[] testMatrices = { M1, M2, M3, Matrix.transpose(M3),
                                    M4, Matrix.transpose(M4), M5, I, M7, bigM, Matrix.transpose(bigM) };

               for ( int j = 0; j < testMatrices.Length; j++ )
               {
              Matrix A = testMatrices[j];
              Vector b = new Vector( A.rows() );

              for ( int k = 0; k < 10; ++k )
              {
                 for ( int i = 0; i < b.Count; ++i )
                 {
                    b[i] = rng.next().value;
                 }
                 Vector x = MatrixUtilities.qrSolve( A, b, true );

                 if ( A.columns() >= A.rows() )
                 {
                    if ( norm( A * x - b ) > tol )
                       Assert.Fail( "A*x does not match vector b (norm = "
                                  + norm( A * x - b ) + ")" );
                 }
                 else
                 {
                    // use the SVD to calculate the reference values
                    int n = A.columns();
                    Vector xr = new Vector( n, 0.0 );

                    SVD svd = new SVD( A );
                    Matrix V = svd.V();
                    Matrix U = svd.U();
                    Vector w = svd.singularValues();
                    double threshold = n * Const.QL_EPSILON;

                    for ( int i = 0; i < n; ++i )
                    {
                       if ( w[i] > threshold )
                       {
                          double u = 0;
                          int zero = 0;
                          for ( int kk = 0; kk < U.rows(); kk++ )
                             u += ( U[kk, i] * b[zero++] ) / w[i];

                          for ( int jj = 0; jj < n; ++jj )
                          {
                             xr[jj] += u * V[jj, i];
                          }
                       }
                    }

                    if ( norm( xr - x ) > tol )
                    {
                       Assert.Fail( "least square solution does not match (norm = "
                                  + norm( x - xr ) + ")" );

                    }
                 }
              }
               }
        }
Exemple #9
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, new List<ulong>(bits_));
            for (int i = 0; i < dimensionality; i++)
                directionIntegers_[i] = new InitializedList<ulong>(bits_);

            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 + ")");

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

            // in case one needs to check the directionIntegers used
            /* bool printDirectionIntegers = false;
               if (printDirectionIntegers) {
                   std::ofstream outStream("directionIntegers.txt");
                   for (k=0; k<std::min(32UL,dimensionality_); k++) {
                       outStream << std::endl << k+1       << "\t"
                                              << degree[k] << "\t"
                                              << ppmt[k]   << "\t";
                       for (j=0; j<10; j++) {
                           outStream << io::power_of_two(
                               directionIntegers_[k][j]) << "\t";
                       }
                   }
                   outStream.close();
               }
            */

            // initialize the Sobol integer/double vectors
            // first draw
            for (k=0; k<dimensionality_; k++) {
                integerSequence_[k]=directionIntegers_[k][0];
            }
        }
Exemple #10
0
 public DifferentialEvolution(Configuration configuration = null)
 {
     configuration_ = configuration ?? new Configuration();
     rng_           = new MersenneTwisterUniformRng(configuration_.seed);
 }