private double density(double x)
        {
            // Based on the function randVMFMeanDir, available in the
            // SphericalDistributionsRand repository under BSD license,
            // originally written by Yu-Hui Chen,  University of Michigan.
            // https://github.com/yuhuichen1015/SphericalDistributionsRand

            int    p   = Dimension;
            double g1  = Gamma.Function((p - 1.0) / 2.0);
            double g2  = Gamma.Function(1.0 / 2.0);
            double bi  = Bessel.I(p / 2 - 1, kappa);
            double num = Math.Pow(kappa / 2.0, p / 2.0 - 1.0);
            double den = g1 * g2 * bi;
            double c   = num / den;

            double a = Math.Exp(kappa * x);
            double b = Math.Pow(1.0 - x * x, (p - 3.0) / 2.0);
            double y = c * a * b;

            return(y);
        }
예제 #2
0
        /// <summary>
        ///   Constructs a Von-Mises Fisher distribution with unit mean.
        /// </summary>
        ///
        /// <param name="mean">The mean direction vector (with unit length).</param>
        /// <param name="concentration">The concentration value κ (kappa).</param>
        ///
        public VonMisesFisherDistribution(double[] mean, double concentration)
            : base(mean.Length)
        {
            if (concentration < 0)
            {
                throw new ArgumentOutOfRangeException("concentration", "Concentration parameter kappa must be non-negative.");
            }

            if (!Norm.Euclidean(mean).IsRelativelyEqual(1, 1e-10))
            {
                throw new ArgumentOutOfRangeException("mean", "The mean vector must have unit length.");
            }

            this.mean  = mean;
            this.kappa = concentration;

            int    p   = Dimension;
            double num = Math.Pow(concentration, p / 2 - 1);
            double den = Math.Pow(2 * Math.PI, p / 2) * Bessel.I(p / 2 - 1, concentration);

            this.constant = num / den;
        }