Esempio n. 1
0
        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]);
                    }
                }
            }
        }
Esempio n. 2
0
        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]);
                            }
                        }
                    }
                }
            }
        }