示例#1
0
 /// <summary>
 /// Create a ForcedRandomSeries with the given sample sequence and the seed as offset.
 /// The sequence is supposed to contain NxN points in random order.
 /// </summary>
 public ForcedRandomSeries(V2i[] series, int matrixSize, IRandomUniform rnd, bool jitter = true)
 {
     m_series     = series;
     m_matrixSize = matrixSize;
     m_norm       = 1.0 / m_matrixSize; // [0, 1)
     m_rnd        = rnd;
     m_jitter     = jitter;
     // random offset of sample pattern
     m_seed = new V2i(rnd.UniformInt(m_matrixSize), rnd.UniformInt(m_matrixSize));
 }
示例#2
0
        /// <summary>
        /// Returns a uniformly distributed double in the closed interval
        /// [0.0, 1.0]. Note, that two random values are used to make all 53
        /// bits random.
        /// </summary>
        public static double UniformDoubleFullClosed(this IRandomUniform rnd)
        {
            if (rnd.GeneratesFullDoubles)
            {
                return(rnd.UniformDoubleClosed());
            }
            long r = ((~0xfL & (long)rnd.UniformInt()) << 22)
                     | ((long)rnd.UniformInt() >> 5);

            return(r * (1.0 / 9007199254740991.0));
        }
示例#3
0
        /// <summary>
        /// Returns a uniformly distributed double in the open interval
        /// (0.0, 1.0). Note, that two random values are used to make all 53
        /// bits random.
        /// </summary>
        public static double UniformDoubleFullOpen(this IRandomUniform rnd)
        {
            if (rnd.GeneratesFullDoubles)
            {
                return(rnd.UniformDoubleOpen());
            }
            long r;

            do
            {
                r = ((~0xfL & (long)rnd.UniformInt()) << 22)
                    | ((long)rnd.UniformInt() >> 5);
            }while (r == 0);
            return(r * (1.0 / 9007199254740992.0));
        }
示例#4
0
 /// <summary>
 /// Randomly permute the specified number of elements in the supplied
 /// list starting at the specified index.
 /// </summary>
 public static void Randomize <T>(
     this IRandomUniform rnd, List <T> list, int start, int count)
 {
     for (int i = start; i < start + count; i++)
     {
         list.Swap(i, start + rnd.UniformInt(count));
     }
 }
示例#5
0
 /// <summary>
 /// Randomly permute the specified number of elements in the supplied
 /// array starting at the specified index.
 /// </summary>
 public static void Randomize <T>(
     this IRandomUniform rnd, T[] array, int start, int count)
 {
     for (int i = start, e = start + count; i < e; i++)
     {
         array.Swap(i, start + rnd.UniformInt(count));
     }
 }
示例#6
0
        /// <summary>
        /// Fills the specified array with random ints in the interval
        /// [0, 2^31-1].
        /// </summary>
        public static void FillUniform(this IRandomUniform rnd, int[] array)
        {
            long count = array.LongLength;

            for (long i = 0; i < count; i++)
            {
                array[i] = rnd.UniformInt();
            }
        }
示例#7
0
        /// <summary>
        /// Randomly permute the elements of the supplied list.
        /// </summary>
        public static void Randomize <T>(
            this IRandomUniform rnd, List <T> list)
        {
            int count = list.Count;

            for (int i = 0; i < count; i++)
            {
                list.Swap(i, rnd.UniformInt(count));
            }
        }
示例#8
0
        /// <summary>
        /// Returns a uniform int which is guaranteed not to be zero.
        /// </summary>
        public static int UniformIntNonZero(this IRandomUniform rnd)
        {
            int r;

            do
            {
                r = rnd.UniformInt();
            } while (r == 0);
            return(r);
        }
示例#9
0
        /// <summary>
        /// Creates clusters for all points which are within an epsilon
        /// distance from each other. This algorithm uses a hash-grid and
        /// only works fast if the supplied epsilon is small enough that
        /// not too many points fall within each cluster. Thus it is ideal
        /// for merging vertices in meshes and point sets, that are different
        /// due to numerical inaccuracies.
        /// </summary>
        public PointEpsilonClustering(V3d[] pa, double epsilon, IRandomUniform rnd = null)
        {
            rnd = rnd ?? new RandomSystem();
            var count = pa.Length;

            Alloc(count);
            var ca = m_indexArray;
            var dict = new IntDict <int>(count, stackDuplicateKeys: true);
            int rndBits = 0; int bit = 0;
            var ha   = new int[8];
            var eps2 = epsilon * epsilon;

            for (int i = 0; i < count; i++)
            {
                var p  = pa[i]; p.HashCodes8(epsilon, ha);
                int ci = ca[i]; if (ca[ci] != ci)
                {
                    do
                    {
                        ci = ca[ci];
                    } while (ca[ci] != ci); ca[i] = ci;
                }
                for (int hi = 0; hi < 8; hi++)
                {
                    foreach (var j in dict.ValuesWithKey(ha[hi]))
                    {
                        int cj = ca[j]; if (ca[cj] != cj)
                        {
                            do
                            {
                                cj = ca[cj];
                            } while (ca[cj] != cj); ca[j] = cj;
                        }
                        if (ci == cj || V3d.DistanceSquared(p, pa[j]) >= eps2)
                        {
                            continue;
                        }
                        bit >>= 1; if (bit == 0)
                        {
                            rndBits = rnd.UniformInt(); bit = 1 << 30;
                        }
                        if ((rndBits & bit) != 0)
                        {
                            ca[ci] = cj; ca[i] = cj; ci = cj;
                        }
                        else
                        {
                            ca[cj] = ci; ca[j] = ci;
                        }
                    }
                }
                dict[ha[0]] = i;
            }
            Init();
        }
示例#10
0
        /// <summary>
        /// Merge clusters of exactly equal points. The supplied epsilon is used to define a
        /// grid as acceleration data structure and the algorithm is only fast if not too many
        /// points fall within the supplied epsilon.
        /// </summary>
        public PointEqualClustering(V3d[] pa, double eps, IRandomUniform rnd = null)
        {
            rnd = rnd ?? new RandomSystem();
            var count = pa.Length;

            Alloc(count);
            var ca = m_indexArray;
            var dict = new IntDict <int>(count, stackDuplicateKeys: true);
            int rndBits = 0; int bit = 0;

            for (int i = 0; i < count; i++)
            {
                var p = pa[i]; var hc = p.HashCode1(eps);
                int ci = ca[i]; if (ca[ci] != ci)
                {
                    do
                    {
                        ci = ca[ci];
                    } while (ca[ci] != ci); ca[i] = ci;
                }
                foreach (var j in dict.ValuesWithKey(hc))
                {
                    int cj = ca[j]; if (ca[cj] != cj)
                    {
                        do
                        {
                            cj = ca[cj];
                        } while (ca[cj] != cj); ca[j] = cj;
                    }
                    if (ci == cj || p != pa[j])
                    {
                        continue;
                    }
                    bit >>= 1; if (bit == 0)
                    {
                        rndBits = rnd.UniformInt(); bit = 1 << 30;
                    }
                    if ((rndBits & bit) != 0)
                    {
                        ca[ci] = cj; ca[i] = cj; ci = cj;
                    }
                    else
                    {
                        ca[cj] = ci; ca[j] = ci;
                    }
                }
                dict[hc] = i;
            }
            Init();
        }
示例#11
0
        /// <summary>
        /// Creates an unordered array of subsetCount int indices that
        /// constitute a subset of all ints in the range [0, count-1].
        /// O(subsetCount) for subsetCount &lt;&lt; count.
        /// NOTE: It is assumed that subsetCount is significantly smaller
        /// than count. If this is not the case, use
        /// CreateRandomSubsetOfSize instead.
        /// WARNING: As subsetCount approaches count execution time
        /// increases significantly.
        /// </summary>
        public static int[] CreateSmallRandomSubsetIndexArray(
            this IRandomUniform rnd, int subsetCount, int count)
        {
            Requires.That(subsetCount >= 0 && subsetCount <= count);
            var subsetIndices = new IntSet(subsetCount);

            for (int i = 0; i < subsetCount; i++)
            {
                int index;
                do
                {
                    index = rnd.UniformInt(count);
                }while (!subsetIndices.TryAdd(index));
            }
            return(subsetIndices.ToArray());
        }
示例#12
0
 /// <summary>
 /// Supply random bits one at a time. The currently unused bits are
 /// maintained in the supplied reference parameter. Before the first
 /// call randomBits must be 0.
 /// </summary>
 public static bool RandomBit(
     this IRandomUniform rnd, ref int randomBits)
 {
     if (randomBits <= 1)
     {
         randomBits = rnd.UniformInt();
         bool bit = (randomBits & 1) != 0;
         randomBits = 0x40000000 | (randomBits >> 1);
         return(bit);
     }
     else
     {
         bool bit = (randomBits & 1) != 0;
         randomBits >>= 1;
         return(bit);
     }
 }
示例#13
0
 /// <summary>
 /// Randomly permute the first count elements of the
 /// supplied array. This does work with counts of up
 /// to about 2^50.
 /// </summary>
 public static void Randomize <T>(
     this IRandomUniform rnd, T[] array, long count)
 {
     if (count <= (long)int.MaxValue)
     {
         int intCount = (int)count;
         for (int i = 0; i < intCount; i++)
         {
             array.Swap(i, rnd.UniformInt(intCount));
         }
     }
     else
     {
         for (long i = 0; i < count; i++)
         {
             array.Swap(i, rnd.UniformLong(count));
         }
     }
 }
示例#14
0
        /// <summary>
        /// Creates an unordered array of subsetCount int indices that
        /// constitute a subset of all ints in the range [0, count-1].
        /// O(subsetCount) for subsetCount &lt;&lt; count.
        /// NOTE: It is assumed that subsetCount is significantly smaller
        /// than count. If this is not the case, use
        /// CreateRandomSubsetOfSize instead.
        /// WARNING: As subsetCount approaches count execution time
        /// increases significantly.
        /// </summary>
        public static int[] CreateSmallRandomSubsetIndexArray(
            this IRandomUniform rnd, int subsetCount, int count)
        {
            if (!(subsetCount >= 0 && subsetCount <= count))
            {
                throw new ArgumentOutOfRangeException(nameof(subsetCount));
            }
            var subsetIndices = new IntSet(subsetCount);

            for (int i = 0; i < subsetCount; i++)
            {
                int index;
                do
                {
                    index = rnd.UniformInt(count);
                }while (!subsetIndices.TryAdd(index));
            }
            return(subsetIndices.ToArray());
        }
示例#15
0
        /// <summary>
        /// Creates clusters of planes within a certain epsilon from each other
        /// (euclidean distance between normal vectors and between offsets).
        /// This algorithm uses a 4d hash-grid and only works fast if the supplied
        /// epsilons are small enough that not too many planes fall within each cluster.
        /// Thus it is ideal for merging planes with small variations in orientation and
        /// offset due to numerical inaccuracies.
        /// </summary>
        public PlaneEpsilonClustering(
            int count, TArray pa,
            Func <TArray, int, V3d> getNormal,
            Func <TArray, int, double> getDist,
            double epsNormal, double epsDist,
            double deltaEpsFactor = 0.25, IRandomUniform rnd = null)
        {
            rnd = rnd ?? new RandomSystem();
            Alloc(count);
            var ca = m_indexArray;
            var dict = new IntDict <int>(count, stackDuplicateKeys: true);
            int rndBits = 0; int bit = 0;
            var ha   = new int[16];
            var ne2  = epsNormal * epsNormal;
            var de2  = epsDist * epsDist;
            var deps = (ne2 + de2) * deltaEpsFactor * deltaEpsFactor;

            for (int i = 0; i < count; i++)
            {
                var ni = getNormal(pa, i); var di = getDist(pa, i);
                ni.HashCodes16(di, epsNormal, epsDist, ha);
                int ci = ca[i]; if (ca[ci] != ci)
                {
                    do
                    {
                        ci = ca[ci];
                    } while (ca[ci] != ci); ca[i] = ci;
                }
                double dmin = double.MaxValue;
                for (int hi = 0; hi < 16; hi++)
                {
                    foreach (var j in dict.ValuesWithKey(ha[hi]))
                    {
                        int cj = ca[j]; if (ca[cj] != cj)
                        {
                            do
                            {
                                cj = ca[cj];
                            } while (ca[cj] != cj); ca[j] = cj;
                        }
                        if (ci == cj)
                        {
                            continue;
                        }
                        var dd = Fun.Square(di - getDist(pa, j)); if (dd >= de2)
                        {
                            continue;
                        }
                        var dn = V3d.DistanceSquared(ni, getNormal(pa, j)); if (dn >= ne2)
                        {
                            continue;
                        }
                        var d = dn + dd; if (d < dmin)
                        {
                            dmin = d;
                        }
                        bit >>= 1; if (bit == 0)
                        {
                            rnd.UniformInt(); bit = 1 << 30;
                        }
                        if ((rndBits & bit) != 0)
                        {
                            ca[ci] = cj; ca[i] = cj; ci = cj;
                        }
                        else
                        {
                            ca[cj] = ci; ca[j] = ci;
                        }
                    }
                }
                if (dmin > deps)
                {
                    dict[ha[0]] = i;              // only sparsely populate hashtable for performance reasons
                }
            }
            Init();
        }