private void GenerateDimensionNumbers(int dimension) { var di = _directionNumbers.GetInfoForDimension(dimension + 1); // Read in parameters var d = (uint)di.Dimension; var s = di.S; var a = di.A; var m = new uint[s + 1]; for (uint i = 1; i <= s; i++) { m[i] = di.DirectionNumbers[i - 1]; } // Compute direction numbers V[1] to V[L], scaled by pow(2,32) if (_bitsRequired <= s) { for (var i = 1; i <= _bitsRequired; i++) { _v[dimension][i] = m[i] << (32 - i); } } else { for (var i = 1; i <= s; i++) { _v[dimension][i] = m[i] << (32 - i); } for (var i = s + 1; i <= _bitsRequired; i++) { _v[dimension][i] = _v[dimension][i - s] ^ (_v[dimension][i - s] >> (int)s); for (uint k = 1; k <= s - 1; k++) { _v[dimension][i] ^= (((a >> (int)(s - 1 - k)) & 1) * _v[dimension][i - k]); } } } }
protected void InitDimensions() { var nDimensions = _numberOfDimensions + _seed; //Max number of bits needed _bitsRequired = (uint)Ceiling(Log(_numberOfPaths + 1.0) / Log(2.0)); //Direction numbers _v = new uint[nDimensions][]; for (var i = 0; i < (nDimensions); i++) { _v[i] = new uint[_bitsRequired]; } for (var dim = 0; dim < nDimensions; dim++) { var v = _v[dim]; //First dim special case if (dim == 0) { for (var i = 0; i < _bitsRequired; i++) { v[i] = 1u << (31 - i); } } else { var di = _directionNumbers.GetInfoForDimension(dim + 1); var degree = (int)di.S; if (_bitsRequired < degree) { for (var i = 0; i < _bitsRequired; i++) { v[i] = di.DirectionNumbers[i] << (31 - i); } } else { for (var i = 0; i < degree; i++) { v[i] = di.DirectionNumbers[i] << (31 - i); } // The remaining direction numbers are computed as described in // the Bratley and Fox paper. // v[i] = a[1]v[i-1] ^ a[2]v[i-2] ^ ... ^ a[v-1]v[i-d+1] ^ v[i-d] ^ v[i-d]/2^d for (var i = degree; i < _bitsRequired; i++) { // First do the v[i-d] ^ v[i-d]/2^d part v[i] = v[i - degree] ^ (v[i - degree] >> degree); // Now do the a[1]v[i-1] ^ a[2]v[i-2] ^ ... part // Note that the coefficients a[] are zero or one and for compactness in // the input tables they are stored as bits of a single integer. To extract // the relevant bit we use right shift and mask with 1. // For example, for a 10 degree polynomial there are ten useful bits in a, // so to get a[2] we need to right shift 7 times (to get the 8th bit into // the LSB) and then mask with 1. for (var j = 1; j < degree; j++) { v[i] ^= ((((uint)di.A >> (int)(degree - 1u - j)) & 1) * v[i - j]); } } } } } }