예제 #1
0
        public static Vector Dirichlet(Vector pseudoCount, Vector result, IPolyrand random = null)
        {
            // If pseudo-count is sparse and its common value is not 0, we need
            // to process it as a dense vector so that samples from common value
            // are allowed to differ
            if (pseudoCount.IsSparse && ((SparseVector)pseudoCount).CommonValue != 0.0)
            {
                pseudoCount = DenseVector.Copy(pseudoCount);
            }

            if (pseudoCount.Max() < 1)
            {
                // To handle small counts, use Stuart's (1962) theorem:
                // gamma(a) has the same distribution as gamma(a+1)*exp(log(U)/a)
                Vector boost = Vector.Copy(pseudoCount);
                boost.SetToFunction(pseudoCount, a => System.Math.Log(NextDouble(random)) / a);
                double maxBoost = boost.Max();
                result.SetToFunction(pseudoCount, boost, (a, b) => Gamma(a + 1, random) * System.Math.Exp(b - maxBoost));
            }
            else
            {
                result.SetToFunction(pseudoCount, a => Gamma(a, random));
            }
            double sum = result.Sum();

            result.Scale(1.0 / sum);
            return(result);
        }
예제 #2
0
        public static double Beta(double trueCount, double falseCount, IPolyrand random = null)
        {
            double gFalse, gTrue;

            if (trueCount < 1 && falseCount < 1)
            {
                // To handle small counts, use Stuart's (1962) theorem:
                // gamma(a) has the same distribution as gamma(a+1)*exp(log(U)/a)
                double boost1 = System.Math.Log(NextDouble(random)) / trueCount;
                trueCount++;
                double boost2 = System.Math.Log(NextDouble(random)) / falseCount;
                falseCount++;
                if (boost1 > boost2)
                {
                    // divide by exp(boost1)
                    gTrue  = Rand.Gamma(trueCount, random);
                    gFalse = Rand.Gamma(falseCount, random) * System.Math.Exp(boost2 - boost1);
                }
                else
                {
                    // divide by exp(boost2)
                    gTrue  = Rand.Gamma(trueCount, random) * System.Math.Exp(boost1 - boost2);
                    gFalse = Rand.Gamma(falseCount, random);
                }
            }
            else
            {
                gTrue  = Rand.Gamma(trueCount, random);
                gFalse = Rand.Gamma(falseCount, random);
            }
            return(gTrue / (gTrue + gFalse));
        }
예제 #3
0
        /// <summary>
        /// Calulates the ratio of the count of positive to negative values.
        /// The test succeeds if the ratio approaches unity as the sample size approaches infinity
        /// </summary>
        /// <param name="samples">The sample count</param>
        public static double SignRatio(IPolyrand random, long samples, long radius)
        {
            var domain = closed(0 - math.abs(radius), 0 + math.abs(radius));
            var pos    = 0L;
            var neg    = 0L;
            var zed    = 0L;

            for (var i = 0; i < samples; i++)
            {
                var next = random.Next(domain);
                if (next > 0)
                {
                    pos++;
                }
                else if (next < 0)
                {
                    neg++;
                }
                else
                {
                    zed++;
                }
            }

            var ratio = (neg != 0 ?  (double)pos / (double)neg : 0d);

            // Should be zero or extremly close so combining it with the ratio should have
            // negligible impact. Otherwise, something is wrong and willb reflected in the
            // metric
            var eps    = (double)zed / (double)samples;
            var metric = ratio + eps;

            return(metric.Round(6));
        }
예제 #4
0
        public static double Normal(IPolyrand random = null)
        {
            double x1, x2;
            double w;

            /* We generate 2 values per iteration, saving one for the next call. */
            if (usePreviousSample)
            {
                usePreviousSample = false;
                return(previousSample);
            }
            /* Generate a random point inside the unit circle */
            do
            {
                x1 = 2.0 * NextDouble(random) - 1.0;
                x2 = 2.0 * NextDouble(random) - 1.0;
                w  = (x1 * x1) + (x2 * x2);
            } while ((w >= 1.0) || (w == 0.0));

            /* Apply the Box-Muller formula */
            w  = System.Math.Sqrt(-2.0 * System.Math.Log(w) / w);
            x1 = w * x1;
            x2 = w * x2;

            usePreviousSample = true;
            previousSample    = x2;
            return(x1);
        }
예제 #5
0
 public static IEnumerable <Perm> Perms(this IPolyrand random, int len)
 {
     while (true)
     {
         yield return(random.Perm(len));
     }
 }
예제 #6
0
파일: Markov.cs 프로젝트: 0xCM/arrows
        static void MarkovVec(this IPolyrand random, Span <double> dst)
        {
            var length = dst.Length;

            random.StreamTo(closed(1.0, length << 4), length, ref dst[0]);
            mathspan.fdiv(dst, dst.Avg() * length);
        }
예제 #7
0
        // Samples Gamma assuming a >= 1.0
        // Reference: G. Marsaglia and W.W. Tsang, A simple method for generating gamma
        // variables, ACM Transactions on Mathematical Software, Vol. 26, No. 3,
        // Pages 363-372, September, 2000.
        // http://portal.acm.org/citation.cfm?id=358414
        private static double GammaShapeGE1(double a, IPolyrand random = null)
        {
            double d = a - 1.0 / 3, c = 1.0 / System.Math.Sqrt(9 * d);
            double v;

            while (true)
            {
                double x;
                do
                {
                    x = Normal(random);
                    v = 1 + c * x;
                } while (v <= 0);
                v = v * v * v;
                x = x * x;
                double u = NextDouble(random);
#if false
                // first version
                if (Math.Log(u) < 0.5 * x + d * (1 - v + Math.Log(v)))
                {
                    break;
                }
#else
                // faster version
                if ((u < 1 - .0331 * x * x) || (System.Math.Log(u) < 0.5 * x + d * (1 - v + System.Math.Log(v))))
                {
                    break;
                }
#endif
            }
            return(d * v);
        }
예제 #8
0
파일: Markov.cs 프로젝트: 0xCM/arrows
 public static ref BlockVector <N, T> MarkovVec <N, T>(this IPolyrand random, ref BlockVector <N, T> dst)
     where N : ITypeNat, new()
     where T : struct
 {
     random.MarkovVec(dst.Unsized);
     return(ref dst);
 }
예제 #9
0
파일: Enums.cs 프로젝트: 0xCM/arrows
        /// <summary>
        /// Produces a stream values sampled from an enum
        /// </summary>
        /// <param name="random">The random source</param>
        /// <typeparam name="E">The enum type</typeparam>
        public static IEnumerable <E> EnumStream <E>(this IPolyrand random, Func <E, bool> filter = null)
            where E : struct, Enum
        {
            IEnumerable <E> produce()
            {
                var names  = Enum.GetNames(typeof(E)).Mapi((index, name) => (index, name)).ToDictionary();
                var domain = closed(0, names.Count);
                var stream = random.Stream(domain);

                while (true)
                {
                    var name  = names[stream.First()];
                    var value = Enum.Parse <E>(name);
                    if (filter != null)
                    {
                        if (filter(value))
                        {
                            yield return(value);
                        }
                    }
                    else
                    {
                        yield return(value);
                    }
                }
            }

            return(stream(produce(), random.RngKind));
        }
예제 #10
0
 /// <summary>
 /// Produces a stream of random permutation of natural length N
 /// </summary>
 /// <param name="random">The random source</param>
 /// <param name="n">The length representative</param>
 /// <param name="rep">A primal type representative</param>
 /// <typeparam name="N">The length type</typeparam>
 /// <typeparam name="T">The primal symbol type</typeparam>
 public static IEnumerable <Perm <N> > Perms <N>(this IPolyrand random, N n = default)
     where N : ITypeNat, new()
 {
     while (true)
     {
         yield return(random.Perm(n));
     }
 }
예제 #11
0
파일: CpuVectors.cs 프로젝트: 0xCM/arrows
        public static Vec512 <T> CpuVec512 <T>(this IPolyrand random, Interval <T>?domain = null, Func <T, bool> filter = null)
            where T : unmanaged
        {
            var v1 = random.CpuVec256(domain, filter);
            var v2 = random.CpuVec256(domain, filter);

            return(Vec512.FromParts(v1, v2));
        }
예제 #12
0
파일: Spans.cs 프로젝트: 0xCM/arrows
        public static Span <T> Span <T>(this IPolyrand random, int length, Interval <T>?domain = null, Func <T, bool> filter = null)
            where T : struct
        {
            Span <T> dst = new T[length];

            random.StreamTo(domain.Configure(), length, ref head(dst), filter);
            return(dst);
        }
예제 #13
0
 static IEnumerable <T> UnfilteredStream <T>(this IPolyrand src, Interval <T> domain)
     where T : struct
 {
     while (true)
     {
         yield return(src.Next <T>(domain.Left, domain.Right));
     }
 }
예제 #14
0
파일: Random.x.cs 프로젝트: 0xCM/arrows
 /// <summary>
 /// Shuffles array content in-place
 /// </summary>
 /// <param name="random">The random source</param>
 /// <param name="src">The input/output array</param>
 /// <typeparam name="T">The element type</typeparam>
 public static T[] Shuffle <T>(this IPolyrand random, T[] src)
 {
     for (int i = 0; i < src.Length; i++)
     {
         swap(ref src[i], ref src[i + random.Next(0, src.Length - i)]);
     }
     return(src);
 }
예제 #15
0
파일: Gaussian.cs 프로젝트: 0xCM/arrows
 public static double Sample(double mean, double precision, IPolyrand random = null)
 {
     if (precision <= 0)
     {
         throw new ArgumentException("precision <= 0 (" + precision + ")");
     }
     return(Rand.Normal(random) / Math.Sqrt(precision) + mean);
 }
예제 #16
0
파일: Markov.cs 프로젝트: 0xCM/arrows
        static BlockVector <double> MarkovVec(this IPolyrand random, int length, double min, double max)
        {
            var dst = Z0.Span256.AllocBlocks <double>(Z0.Span256.MinBlocks <double>(length));

            random.StreamTo(closed(min, max), length, ref dst[0]);
            mathspan.fdiv(dst.Unblocked, dst.Avg() * length);
            return(dst);
        }
예제 #17
0
        /// <summary>
        /// Defines a sample stream for a biniomian distribution
        /// </summary>
        /// <param name="random">The random source</param>
        /// <param name="n">The number of trials</param>
        /// <param name="p">The probability of success of a given trial</param>
        public static IEnumerable <int> SampleBinomial(this IPolyrand random, int n, double p)
        {
            var sysrand = SysRand.Derive(random);

            while (true)
            {
                yield return(MlStats.SampleFromBinomial(sysrand, n, p));
            }
        }
예제 #18
0
        public static IEnumerable <double> SamplePareto(this IPolyrand random, double shape, double lowerBound)
        {
            var dist = new Dist.Pareto(shape, lowerBound);

            while (true)
            {
                yield return(dist.Sample(random));
            }
        }
예제 #19
0
        public static IEnumerable <double> SampleBeta2(this IPolyrand random, double alpha, double beta)
        {
            var sysrand = SysRand.Derive(random);

            while (true)
            {
                yield return(MlStats.SampleFromBeta(sysrand, alpha, beta));
            }
        }
예제 #20
0
        public static IEnumerable <double> SampleBeta(this IPolyrand random, double trueCount, double falseCount)
        {
            var dist = new Dist.Beta(trueCount, falseCount);

            while (true)
            {
                yield return(dist.Sample(random));
            }
        }
예제 #21
0
        public static IEnumerable <double> SampleGamma(this IPolyrand random, double shape, double rate)
        {
            var dist = Dist.Gamma.FromShapeAndRate(shape, rate);

            while (true)
            {
                yield return(dist.Sample(random));
            }
        }
예제 #22
0
        public static IEnumerable <bool> SampleBernoulli(this IPolyrand random, double p)
        {
            var dist = new Dist.Bernoulli(p);

            while (true)
            {
                yield return(dist.Sample(random));
            }
        }
예제 #23
0
        public static IEnumerable <double> SampleTruncatedGaussian(this IPolyrand random, double mean, double σ, double lower, double upper)
        {
            var dist = new Dist.TruncatedGaussian(Dist.Gaussian.FromMeanAndVariance(mean, σ * σ), lower, upper);

            while (true)
            {
                yield return(dist.Sample(random));
            }
        }
예제 #24
0
        public static IEnumerable <double> SampleGaussian(this IPolyrand random, double mean, double σ)
        {
            var dist = Dist.Gaussian.FromMeanAndVariance(mean, σ * σ);

            while (true)
            {
                yield return(dist.Sample(random));
            }
        }
예제 #25
0
        /// <summary>
        /// Defines a sample stream for a poisson distribution which represents the probability of
        /// a given number of independent events occurring over a period of time at a constant rate
        /// </summary>
        /// <param name="random">The random source</param>
        /// <param name="lambda">The constant rate of occurrence</param>
        public static IEnumerable <int> SamplePoisson(this IPolyrand random, double lambda)
        {
            var sysrand = SysRand.Derive(random);

            while (true)
            {
                yield return(MlStats.SampleFromPoisson(sysrand, lambda));
            }
        }
예제 #26
0
파일: Bernoulli.cs 프로젝트: 0xCM/arrows
        public static bool Sample(double probTrue, IPolyrand random = null)
        {
            if (probTrue < 0 || probTrue > 1)
            {
                throw new ArgumentOutOfRangeException(nameof(probTrue), $"{nameof(probTrue)} = {probTrue} is not in [0,1]");
            }

            return(Rand.Double(random) < probTrue);
        }
예제 #27
0
파일: Markov.cs 프로젝트: 0xCM/arrows
        public static BlockVector <N, T> MarkovVec <N, T>(this IPolyrand random)
            where N : ITypeNat, new()
            where T : struct
        {
            var dst = BlockVector.Alloc <N, T>();

            random.MarkovVec(dst.Unsized);
            return(dst);
        }
예제 #28
0
파일: BlockVector.cs 프로젝트: 0xCM/arrows
        public static BlockVector <N, T> BlockVec <N, T>(this IPolyrand random, N n = default)
            where T : struct
            where N : ITypeNat, new()
        {
            var dst = BlockVector.Alloc <N, T>();

            random.Fill(ref dst);
            return(dst);
        }
예제 #29
0
        public static IEnumerable <float> SampleLaplace(this IPolyrand random, float mean, float scale)
        {
            var sysrand = SysRand.Derive(random);

            while (true)
            {
                yield return(MlStats.SampleFromLaplacian(sysrand, mean, scale));
            }
        }
예제 #30
0
        public static Vector <N, T> Vector <N, T>(this IPolyrand random, N n = default)
            where T : unmanaged
            where N : ITypeNat, new()
        {
            var dst = Z0.Vector.Alloc <N, T>();

            random.Fill(ref dst);
            return(dst);
        }