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(); } }
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(); }
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; }
private SeedGenerator() { rng_ = new MersenneTwisterUniformRng(42UL); initialize(); }
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); }
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]; } }
private SeedGenerator() { rng_ = new MersenneTwisterUniformRng(42UL); initialize(); }
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 ) + ")" ); } } } } }
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]; } }
public DifferentialEvolution(Configuration configuration = null) { configuration_ = configuration ?? new Configuration(); rng_ = new MersenneTwisterUniformRng(configuration_.seed); }