Exemplo n.º 1
0
        /// <summary>
        /// Sobol sequence.
        /// </summary>
        public static IEnumerable <Rational> SobolR(PolyGF2 primitivePolynomial, params int[] initialValues)
        {
            var   v = SobolDirectionVectors(64, primitivePolynomial, initialValues);
            ulong s = 0;
            var   d = ((System.Numerics.BigInteger) 1) << 64;

            foreach (var r in Sequences.Ruler())
            {
                s ^= v[r];
                yield return(new Rational(s, d));
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Sobol sequence.
        /// </summary>
        public static IEnumerable <Decimal> SobolM(PolyGF2 primitivePolynomial, params int[] initialValues)
        {
            var   v = SobolDirectionVectors(64, primitivePolynomial, initialValues);
            ulong s = 0;
            var   d = ((System.Numerics.BigInteger) 1) << 64;

            foreach (var r in Sequences.Ruler())
            {
                s ^= v[r];
                yield return(s / 18446744073709551616M);
            }
        }
Exemplo n.º 3
0
        public void SobolInitialValues(int max)
        {
            int d = 2;
            var g = new Generator("SobolInitialValue");
            var v = new bool[max + 1][];

            v[0]    = new bool[max];
            v[0][0] = true;

            foreach (var p in PolyGF2.GetAllPrimitive().Take(max - 1))
            {
                v[d - 1] = new bool[max];
                int s = p.Degree;
                var m = new int[s];
                var V = new SquareMatrixGF2(d);

                while (true)
                {
                    for (int i = 0; i < s; i++)
                    {
                        m[i] = g.Int32(2 << i) | 1;
                    }
                    var dv = Subrandom.SobolDirectionVectors(max, p, m);

                    for (int i = 0; i < max; i++)
                    {
                        v[d - 1][i] = dv[i] > (ulong)long.MaxValue;
                    }

                    for (int row = 0; row < d; row++)
                    {
                        for (int col = 0; col < d; col++)
                        {
                            V[row, col] = v[row][col];
                        }
                    }
                    bool det = V.GetDeterminant();
                    if (det)
                    {
                        break;
                    }
                }

                Trace.Write($"{d}\t{s}\t{p.GetCode() / 2 ^ (1UL << (s-1))}\t");
                for (int i = 0; i < s; i++)
                {
                    Trace.Write($"{m[i]} ");
                }
                Trace.WriteLine("");
                d++;
            }
        }
Exemplo n.º 4
0
        public void SobolRationalTest()
        {
            var p = new PolyGF2(3, 1, 0);
            var m = new[] { 1, 3, 7 };

            foreach (var item in Subrandom.SobolR(p, m).Take(1000))
            {
                System.Diagnostics.Trace.WriteLine(item);
            }

            var g = new Generator("SobolRationalTest");

            Test(g, () => Subrandom.SobolR(p, m));
        }
Exemplo n.º 5
0
        internal static ulong[] SobolDirectionVectors(int d, PolyGF2 primitivePolynomial, int[] initialValues)
        {
            if (initialValues == null)
            {
                throw new ArgumentNullException(nameof(initialValues));
            }

            int n = initialValues.Length;

            if (n != primitivePolynomial.Degree)
            {
                throw new ArgumentException("The number of initial values must be the same as the degree of the primitive polynomial.");
            }

            PolyGF2 factor;
            long    order;

            if (!primitivePolynomial.IsPrimitive(out factor, out order))
            {
                ulong q = (1UL << primitivePolynomial.Degree) - 1UL;
                var   o = new PolyGF2((int)order, 0);

                if (factor != PolyGF2.Zero)
                {
                    throw new ArgumentException($"Polynomial is not primitive because it is divisible by {factor} = ({primitivePolynomial}) / ({primitivePolynomial / factor}).");
                }
                else
                {
                    throw new ArgumentException($"Polynomial is not primitive because it only has order {order} and not {q}. ({o}) / ({primitivePolynomial}) = ({o / primitivePolynomial})");
                }
            }

            // Validate initial values.

            var  v   = new ulong[d];
            long max = 1;
            var  m   = initialValues;

            for (int i = 0; i < n; i++)
            {
                max <<= 1;

                if (m[i] < 0)
                {
                    throw new ArgumentException($"Initial values cannot be negative. {m[i]} is definitely negative.");
                }

                if (m[i] >= max)
                {
                    throw new ArgumentException($"The i-th initial value (starting with i=0) must be less than 2^i. ${m[i]} should be less than {max}.");
                }

                if ((m[i] & 1) == 0)
                {
                    throw new ArgumentException($"Initial values must be odd. {m[i]} is even.");
                }

                v[i] = (ulong)m[i] << (63 - i);
            }

            // Compute remaining direction vectors.
            var exponents = new HashSet <int>(primitivePolynomial.Exponents);

            for (int i = n; i < d; i++)
            {
                ulong sum = v[i - n] >> n;

                for (int j = 1; j <= n; j++)
                {
                    if (exponents.Contains(n - j))
                    {
                        sum ^= v[i - j];
                    }
                }

                v[i] = sum;
            }

            return(v);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Sobol sequence.
        /// </summary>
        public static IEnumerable <Rational> SobolR(int polynomialCode, params int[] initialValues)
        {
            var primitivePolynomial = PolyGF2.FromCode(2UL * (ulong)polynomialCode ^ 1UL ^ (1UL << initialValues.Length));

            return(SobolR(primitivePolynomial, initialValues));
        }
Exemplo n.º 7
0
 /// <summary>
 /// Creates a <see cref="Sobol"/> with specified initial
 /// values and primitive polynomial coefficients packed into
 /// bits, with leading and trailing coefficient omitted.
 /// </summary>
 /// <param name="polynomialCode">Bit 0 corresponds to x^1.</param>
 /// <param name="initialValues">Initial values.</param>
 public Sobol(int polynomialCode, params int[] initialValues)
     : this(PolyGF2.FromCode(2UL * (ulong)polynomialCode ^ 1UL ^ (1UL << initialValues.Length))
            .Exponents.ToArray(), initialValues)
 {
 }