// Computes (S(x + y) - S(x)) / y, i.e. the rate at which S(x + y) - S(x) changes with y

        private static double ReducedPochhammerSum(double x, double y)
        {
            double L  = MoreMath.ReducedLogOnePlus(1.0 / x, y);
            double xx = x * x;
            double xk = x;
            double f  = AdvancedIntegerMath.Bernoulli[1] / (2.0 * xk) * MoreMath.ReducedExpMinusOne(-L, y);

            for (int k = 2; k < AdvancedIntegerMath.Bernoulli.Length; k++)
            {
                double f_old = f;
                xk *= xx;
                f  += AdvancedIntegerMath.Bernoulli[k] / ((2 * k) * (2 * k - 1)) / xk * MoreMath.ReducedExpMinusOne((1 - 2 * k) * L, y);
                if (f == f_old)
                {
                    return(f);
                }
            }
            throw new NonconvergenceException();
        }
        protected override object HandleAngleConverting(object value)
        {
            double?doubleValueNullable = ParsingUtilities.ParseDoubleNullable(value);

            if (!doubleValueNullable.HasValue)
            {
                return(value);
            }
            double doubleValue = doubleValueNullable.Value;

            if (_truncateToMultipleOf16)
            {
                doubleValue = MoreMath.TruncateToMultipleOf16(doubleValue);
            }
            doubleValue = MoreMath.NormalizeAngleUsingType(doubleValue, _effectiveType);
            doubleValue = (doubleValue / 65536) * GetAngleUnitTypeMaxValue();

            return(doubleValue);
        }
Exemple #3
0
        private static Complex ComplexSqrt(Complex z)
        {
            // We could just call Pow(z, 0.5), but that is slow (involves multiple trig functions)
            // and looses a bit of symmetry (e.g. square roots of pure negative numbers may have tiny real parts because Pi is not exact)

            // Instead we expand (x + i y)^2 = a + i b to obtain a quadratic equations in x^2 and y^2. Solving (and thinking a bit about signs) yields
            //   x = \sqrt{\frac{m + a}{2}}
            //   y = \pm \sqrt{\frac{m - a}{2}}
            // where m = |a + i b| = \sqrt{a^2 + b^2}

            // Using this is very straightforward unless |b| << |a|, in which case m ~ |a| and there is a near-cancelation in one of the expressions.
            // In this case we pull out a factor a and use a series expansion of \sqrt{1 + w} - 1 where w = (b/a)^2.

            // In the end the whole algorithm is a little bit more complicated than I would like, but it is much faster than Pow(z, 0.5).

            double x, y;

            if (Math.Abs(z.Im) < Math.Abs(z.Re) / 8.0)
            {
                double s = Series1(MoreMath.Sqr(z.Im / z.Re));
                if (z.Re > 0.0)
                {
                    x = Math.Sqrt(z.Re * (s + 2.0) / 2.0);
                    y = Math.Sqrt(z.Re * s / 2.0);
                }
                else
                {
                    x = Math.Sqrt(-z.Re * s / 2.0);
                    y = Math.Sqrt(-z.Re * (s + 2.0) / 2.0);
                }
            }
            else
            {
                double m = MoreMath.Hypot(z.Re, z.Im);
                x = Math.Sqrt((m + z.Re) / 2.0);
                y = Math.Sqrt((m - z.Re) / 2.0);
            }
            if (z.Im < 0.0)
            {
                y = -y;
            }
            return(new Complex(x, y));
        }
Exemple #4
0
 /// <summary>
 /// Computes the dilogarathm function, also called Spence's function.
 /// </summary>
 /// <param name="x">The argument, which must be less than or equal to unity.</param>
 /// <returns>The value Li<sub>2</sub>(x).</returns>
 /// <remarks>
 /// <para>The dilogarithm can be defined by an infinite sum.</para>
 /// <img src="../images/DilogSum.png" />
 /// <para>The function gets is name from the similarity of this series to the expansion of ln(1-x), the
 /// difference being that the integer in the denominator is raised to the second power.</para>
 /// <para>Li<sub>2</sub>(x) is real for -&#x221E; &lt; x &#x2264; 1; for values outside this range,
 /// use the complex version <see cref="AdvancedComplexMath.DiLog"/>.</para>
 /// </remarks>
 /// <seealso cref="AdvancedComplexMath.DiLog" />
 /// <seealso href="http://en.wikipedia.org/wiki/Dilogarithm" />
 public static double DiLog(double x)
 {
     if (x > 1.0)
     {
         throw new ArgumentOutOfRangeException(nameof(x));
     }
     else if (x > 0.625)
     {
         // use Li(x) + Li(1-x) = \frac{\pi^2}{6} - \log x \log (1-x)
         // to map x near 1 to x near 0
         if (x == 1.0)
         {
             // Special case x = 1 exactly to avoid computing log(0).
             return(Math.PI * Math.PI / 6.0);
         }
         else
         {
             return(Math.PI * Math.PI / 6.0 - DiLog_Series(1.0 - x) - Math.Log(x) * MoreMath.LogOnePlus(-x));
         }
         // use series near 1
         //return (DiLog_Series_1(1.0 - x));
     }
     else if (x > -0.625)
     {
         // series near 0 (defining power series)
         return(DiLog_Series(x));
     }
     else if (x >= -1.0)
     {
         // Use Li(x) + Li(-x) = \frac{1}{2} Li(x^2)
         // to map negative x to positive x
         return(0.5 * DiLog(x * x) - DiLog(-x));
     }
     else if (x >= Double.NegativeInfinity)
     {
         // use formula for Li(1/x) to map to [-1,0]
         return(-Math.PI * Math.PI / 6.0 - 0.5 * MoreMath.Sqr(Math.Log(-x)) - DiLog(1.0 / x));
     }
     else
     {
         return(Double.NaN);
     }
 }
Exemple #5
0
        private double ComputeDeficit(double[] z, ref double[] r)
        {
            double r2 = 0.0;

            for (int i = 0; i < r.Length; i++)
            {
                r[i] = -g[i];
                for (int j = 0; j <= i; j++)
                {
                    r[i] -= h[i][j] * z[j];
                }
                for (int j = i; j < z.Length; j++)
                {
                    r[i] -= h[j][i] * z[j];
                }
                r2 += MoreMath.Sqr(r[i]);
            }
            return(r2);
        }
Exemple #6
0
        // Cumulants K_r = \frac{q E_{r-1}(q)}{p^r} (also Eulerian polynomials but not quite same
        // as raw moments). See Shenton & Bowman, "The Geometric Distribution's Central Moments
        // and Eulerian Numbers of the Second Kind", Far East J. Theo. Stat. 7 (1) 2002 1-17
        // (http://www.csm.ornl.gov/~bowman/fjts7.pdf)

        /// <inheritdoc />
        public override double Cumulant(int r)
        {
            if (r < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(r));
            }
            else if (r == 0)
            {
                return(0.0);
            }
            else if (r == 1)
            {
                return(q / p);
            }
            else
            {
                return(q * EulerianPolynomial(r - 1, q) / MoreMath.Pow(p, r));
            }
        }
        public void SumOfPowers()
        {
            // This test is difficult because the minimum is emphatically not quadratic.
            // We do get close to the minimum but we massivly underestimate our error.

            Func <IList <double>, double> function = (IList <double> x) => {
                double s = 0.0;
                for (int i = 0; i < x.Count; i++)
                {
                    s += MoreMath.Pow(Math.Abs(x[i]), i + 2);
                }
                return(s);
            };

            for (int n = 2; n < 8; n++)
            {
                Console.WriteLine(n);

                ColumnVector start = new ColumnVector(n);
                for (int i = 0; i < n; i++)
                {
                    start[i] = 1.0;
                }

                EvaluationSettings settings = new EvaluationSettings()
                {
                    AbsolutePrecision = 1.0E-8, EvaluationBudget = 32 * n * n * n
                };

                MultiExtremum minimum = MultiFunctionMath.FindLocalMinimum(function, start, settings);

                Console.WriteLine(minimum.EvaluationCount);
                Console.WriteLine("{0} {1}", minimum.Value, minimum.Precision);
                Console.WriteLine("|| {0} {1} ... || = {2}", minimum.Location[0], minimum.Location[1], minimum.Location.FrobeniusNorm());

                Assert.IsTrue(TestUtilities.IsNearlyEqual(minimum.Value, 0.0, new EvaluationSettings()
                {
                    AbsolutePrecision = 1.0E-4
                }));
                //Assert.IsTrue(TestUtilities.IsNearlyEqual(minimum.Location, new ColumnVector(n), new EvaluationSettings() { AbsolutePrecision = 1.0E-2 }));
            }
        }
Exemple #8
0
        public void ChangeModel(List <short[]> vertices, List <int[]> triangles)
        {
            ManualMode = false;

            var maxRadius = vertices.Max(v => MoreMath.GetDistanceBetween(v[0], v[2], 0, 0));
            var maxHeight = vertices.Max(v => v[1]);
            var minHeight = vertices.Min(v => v[1]);

            _cameraHeight = maxHeight + (float)(Math.Sqrt(2) * maxRadius);
            _cameraRadius = (float)maxRadius * 2f;

            _modelCenter = new Vector3(0, (maxHeight + minHeight) / 2, 0);
            _modelRadius = vertices.Max(v => (new Vector3(v[0], v[1], v[2]) - _modelCenter).Length);

            _zoom = -0.57735026919f; // 60 degree FOV

            lock (_modelLock)
            {
                // Create vertice point vectors
                _vertices = new Vector3[vertices.Count];
                for (int i = 0; i < _vertices.Length; i++)
                {
                    _vertices[i] = new Vector3(vertices[i][0], vertices[i][1], vertices[i][2]);
                }

                // Create triangle
                _triangles      = new int[triangles.Count][];
                _triangleColors = new Color[triangles.Count];
                for (int i = 0; i < _triangles.Length; i++)
                {
                    // Make sure vertices exist
                    _triangles[i] = triangles[i].Select(t => t >= _vertices.Length || t < 0 ? 0 : t).ToArray();
                    // Find triangle colors
                    var tri = _triangles[i];
                    _triangleColors[i] = ColorFromTri(_vertices[tri[0]], _vertices[tri[1]], _vertices[tri[2]]);
                }

                // Unselect all triangle and vertices
                _vertexSelected   = new bool[_vertices.Length];
                _triangleSelected = new bool[_triangles.Length];
            }
        }
        private void CoulombRecursionTest(int L, double eta, double rho)
        {
            SolutionPair sm = AdvancedMath.Coulomb(L - 1, eta, rho);
            SolutionPair s0 = AdvancedMath.Coulomb(L, eta, rho);
            SolutionPair sp = AdvancedMath.Coulomb(L + 1, eta, rho);

            double eps = 8.0 * TestUtilities.TargetPrecision;

            // Relating u_{L}' to u_{L-1} and u_{L}

            Assert.IsTrue(TestUtilities.IsSumNearlyEqual(
                              MoreMath.Hypot(L, eta) * sm.FirstSolutionValue,
                              -(L * L / rho + eta) * s0.FirstSolutionValue,
                              L * s0.FirstSolutionDerivative,
                              eps
                              ));

            Assert.IsTrue(TestUtilities.IsSumNearlyEqual(
                              MoreMath.Hypot(L, eta) * sm.SecondSolutionValue,
                              -(L * L / rho + eta) * s0.SecondSolutionValue,
                              L * s0.SecondSolutionDerivative,
                              eps
                              ));

            // Relating u_{L}' to u_{L} and u_{L+1}

            // Relating u_{L+1}, u_{L}, u_{L-1}

            Assert.IsTrue(TestUtilities.IsSumNearlyEqual(
                              (2 * L + 1) * (eta + L * (L + 1) / rho) * s0.FirstSolutionValue,
                              -(L + 1) * MoreMath.Hypot(L, eta) * sm.FirstSolutionValue,
                              L * MoreMath.Hypot(L + 1, eta) * sp.FirstSolutionValue,
                              eps
                              ));

            Assert.IsTrue(TestUtilities.IsSumNearlyEqual(
                              (2 * L + 1) * (eta + L * (L + 1) / rho) * s0.SecondSolutionValue,
                              -(L + 1) * MoreMath.Hypot(L, eta) * sm.SecondSolutionValue,
                              L * MoreMath.Hypot(L + 1, eta) * sp.SecondSolutionValue,
                              eps
                              ));
        }
        // This implements Fukushima's method of computing the Jacobian elliptic functions
        // sn, cn, and dn. The method is essentially to use range reduction to move u into
        // the range -K/2 < u < K/2, then repeatedly halve that value of u until it gets
        // small enough to apply the Maclaurin series for small m to compute sn, then
        // using the doubling formula to get back to the value of u required.

        /// <summary>
        /// Computes the Jacobian elliptic function sn.
        /// </summary>
        /// <param name="u">The argument.</param>
        /// <param name="k">The modulus, which must be between 0 and 1.</param>
        /// <returns>The value of sn(u,k).</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="k"/> lies outside [0, 1].</exception>
        /// <remarks>
        /// <para>Be aware that some authors use the parameter m = k^2 instead of the modulus k.</para>
        /// </remarks>
        /// <seealso href="https://en.wikipedia.org/wiki/Jacobi_elliptic_functions"/>
        /// <seealso href="http://mathworld.wolfram.com/JacobiEllipticFunctions.html"/>
        /// <seealso href="http://dlmf.nist.gov/22"/>
        public static double JacobiSn(double u, double k)
        {
            if (u < 0.0)
            {
                return(-JacobiSn(-u, k));
            }
            if ((k < 0.0) || (k > 1.0))
            {
                throw new ArgumentOutOfRangeException(nameof(k));
            }

            // For k=1, K is infinite and our reduction algorithm breaks down.
            // But even for k = 1-10^(-16), K~19.4 and the reduction works fine,
            // so we only need to do this at exactly k=1.
            if (k == 1.0)
            {
                return(Math.Tanh(u));
            }

            // Decompose u = u_0 K + u_1, where -K/2 < u_1 < K/2, and compute sn(u_1)
            long   u0; double u1;
            double sn = JacobiSn_ViaRangeReduction(u, k, out u0, out u1);

            // Transform to the appropriate quadrant
            switch (MoreMath.Mod(u0, 4))
            {
            case 0:
                return(sn);

            case 1:
                return(Math.Sqrt((1.0 - sn * sn) / (1.0 - MoreMath.Sqr(k * sn))));

            case 2:
                return(-sn);

            case 3:
                return(-Math.Sqrt((1.0 - sn * sn) / (1.0 - MoreMath.Sqr(k * sn))));

            default:
                throw new InvalidOperationException();
            }
        }
        protected override List <(float x, float y, float z)> GetGridlineIntersectionPositionsTopDownView()
        {
            if (_setting != PuGridlineSetting.SETTING1)
            {
                return(new List <(float x, float y, float z)>());
            }

            float marioY = Config.Stream.GetFloat(MarioConfig.StructAddress + MarioConfig.YOffset);

            long size    = (long)Math.Max(Size, 1);
            long spacing = (long)(puSize * size);

            long xOffset        = 0;
            long zOffset        = 0;
            long xOffsetReverse = 0;
            long zOffsetReverse = 0;

            if (_useMarioAsOrigin)
            {
                (int puXIndex, int puYIndex, int puZIndex) = PuUtilities.GetMarioPuIndexes();
                xOffset        = (long)MoreMath.NonNegativeModulus(puXIndex, size);
                zOffset        = (long)MoreMath.NonNegativeModulus(puZIndex, size);
                xOffsetReverse = size - xOffset;
                zOffsetReverse = size - zOffset;
            }

            long xMin = ((((long)Config.CurrentMapGraphics.MapViewXMin) / spacing) - 1) * spacing - puSize * xOffsetReverse;
            long xMax = ((((long)Config.CurrentMapGraphics.MapViewXMax) / spacing) + 1) * spacing + puSize * xOffset;
            long zMin = ((((long)Config.CurrentMapGraphics.MapViewZMin) / spacing) - 1) * spacing - puSize * zOffsetReverse;
            long zMax = ((((long)Config.CurrentMapGraphics.MapViewZMax) / spacing) + 1) * spacing + puSize * zOffset;

            List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();

            for (long x = xMin; x <= xMax; x += spacing)
            {
                for (long z = zMin; z <= zMax; z += spacing)
                {
                    vertices.Add((x, marioY, z));
                }
            }
            return(vertices);
        }
 /// <inheritdoc />
 public override double Cumulant(int r)
 {
     if (r < 0)
     {
         throw new ArgumentOutOfRangeException("r");
     }
     else if (r == 0)
     {
         return(0.0);
     }
     else if (r == 1)
     {
         return(Mean);
     }
     else
     {
         // K_{r+1} = \frac{(2 r)!}{2^r r! \mu^{2r+1} \lambda^r} = \frac{(2r - 1)!! \mu^{2r+1}}{\lambda^r}
         return(AdvancedIntegerMath.DoubleFactorial(2 * r - 3) * MoreMath.Pow(mu, 2 * r - 1) / MoreMath.Pow(lambda, r - 1));
     }
 }
        public void EllipticPiIntegration()
        {
            Interval i = Interval.FromEndpoints(0.0, Math.PI / 2.0);

            foreach (double k in TestUtilities.GenerateRealValues(1.0E-2, 1.0, 4))
            {
                double m = k * k;
                foreach (double n in TestUtilities.GenerateUniformRealValues(-2.0, 1.0, 4))
                {
                    Func <double, double> f = delegate(double t) {
                        double s2 = MoreMath.Sqr(Math.Sin(t));
                        return(1.0 / (1.0 - n * s2) / Math.Sqrt(1.0 - m * s2));
                    };

                    Assert.IsTrue(TestUtilities.IsNearlyEqual(
                                      FunctionMath.Integrate(f, i), AdvancedMath.EllipticPi(n, k)
                                      ));
                }
            }
        }
 internal PrincipalComponentAnalysis(double[] utStore, double[] wStore, double[] vStore, int rows, int cols)
 {
     Debug.Assert(utStore != null);
     Debug.Assert(wStore != null);
     Debug.Assert(vStore != null);
     Debug.Assert(rows > 0);
     Debug.Assert(cols > 0);
     this.rows    = rows;
     this.cols    = cols;
     this.utStore = utStore;
     this.wStore  = wStore;
     this.vStore  = vStore;
     // keep track of cumulative sum of squares, which is proportional to the cumulative explained variance
     wSquaredSum    = new double[wStore.Length];
     wSquaredSum[0] = MoreMath.Sqr(wStore[0]);
     for (int i = 1; i < wSquaredSum.Length; i++)
     {
         wSquaredSum[i] = wSquaredSum[i - 1] + MoreMath.Sqr(wStore[i]);
     }
 }
Exemple #15
0
        // Abromowitz & Stegun 7.8.3
        // Cl_2(\pi - \theta) = \theta \log 2 - \sum_{k=1}^{\infty} \frac{|B_{2k}| (2^2k - 1) \theta^{2k+1}}{(2k!) (2k) (2k+1)}

        // Because of the additional factor 2^{2k} in numerator, this series converges much slower than the series around 0.
        // If we transition between the two of them at \pi/2, this series takes about 30 terms while the other takes only 10.
        // If we transition between the two of them at 2\pi/3, each takes about 15 terms.

        private static double ClausenNearPi(double t)
        {
            double f = Global.LogTwo;

            double t2 = t * t;
            double sk = 1.0; // tracks t^2k / k!

            for (int k = 1; k < AdvancedIntegerMath.Bernoulli.Length; k++)
            {
                double f_old = f;
                int    tk    = 2 * k;
                sk *= t2 / tk / (tk - 1);
                f  -= Math.Abs(AdvancedIntegerMath.Bernoulli[k]) * (MoreMath.Pow(4.0, k) - 1.0) * sk / tk / (tk + 1);
                if (f == f_old)
                {
                    return(t * f);
                }
            }
            throw new NonconvergenceException();
        }
Exemple #16
0
 /** Add +1/-1 with probability of p */
 static int mutateIntOne(int x, int min, int max, float p)
 {
     if (Random.value < p)
     {
         int y = x;
         if (Random.Range(0, 2) == 0)
         {
             y--;
         }
         else
         {
             y++;
         }
         return(MoreMath.Clamp(min, max, y));
     }
     else
     {
         return(x);
     }
 }
        public void ThreeHumpCamel()
        {
            // This function has three local minima, so not at all starting points should be expected to bring us to the global minimum at the origin.

            Func <IList <double>, double> function = (IList <double> x) => 2.0 * MoreMath.Pow(x[0], 2) - 1.05 * MoreMath.Pow(x[0], 4) + MoreMath.Pow(x[0], 6) / 6.0 + x[0] * x[1] + MoreMath.Pow(x[1], 2);

            ColumnVector start = new ColumnVector(1.0, 1.0);

            MultiExtremum minimum = MultiFunctionMath.FindLocalMinimum(function, start);

            Console.WriteLine("{0} ({1}) ?= 0.0", minimum.Value, minimum.Precision);
            Console.WriteLine("{0} {1}", minimum.Location[0], minimum.Location[1]);
            Assert.IsTrue(TestUtilities.IsNearlyEqual(minimum.Value, 0.0, new EvaluationSettings()
            {
                AbsolutePrecision = 2.0 * minimum.Precision
            }));
            Assert.IsTrue(TestUtilities.IsNearlyEqual(minimum.Location, new ColumnVector(2), new EvaluationSettings {
                AbsolutePrecision = 2.0 * Math.Sqrt(minimum.Precision)
            }));
        }
Exemple #18
0
 /// <summary>
 /// Computes the digamma function.
 /// </summary>
 /// <param name="x">The argument.</param>
 /// <returns>The value of &#x3C8;(x).</returns>
 /// <remarks>
 /// <para>The psi function, also called the digamma function, is the logrithmic derivative of the &#x393; function.</para>
 /// <img src="../images/DiGamma.png" />
 /// <para>Because it is defined as a <i>logarithmic</i> derivative, the digamma function does not overflow <see cref="System.Double"/>
 /// even for arguments for which <see cref="Gamma(double)"/> does.</para>
 /// <para>To evaluate the psi function for complex arguments, use <see cref="AdvancedComplexMath.Psi" />.</para>
 /// </remarks>
 /// <seealso cref="Gamma(double)"/>
 /// <seealso cref="AdvancedComplexMath.Psi"/>
 /// <seealso href="http://en.wikipedia.org/wiki/Digamma_function" />
 /// <seealso href="http://mathworld.wolfram.com/DigammaFunction.html" />
 public static double Psi(double x)
 {
     if (x < 0.25)
     {
         return(Psi(1.0 - x) - Math.PI / MoreMath.TanPi(x));
     }
     else if (x < 16.0)
     {
         return(Lanczos.Psi(x));
     }
     else if (x <= Double.PositiveInfinity)
     {
         // For large arguments, the Stirling asymptotic expansion is faster than the Lanzcos approximation
         return(Stirling.Psi(x));
     }
     else
     {
         return(Double.NaN);
     }
 }
 /// <inheritdoc />
 public override double ProbabilityMass(int k)
 {
     if (k < 0)
     {
         return(0.0);
     }
     else
     {
         // These are the same expression, but the form for small arguments is faster,
         // while the form for large arguments avoids overflow and cancellation errors.
         if (k < 16)
         {
             return(Math.Exp(-mu) * MoreMath.Pow(mu, k) / AdvancedIntegerMath.Factorial(k));
         }
         else
         {
             return(Stirling.PoissonProbability(mu, k));
         }
     }
 }
 /// <inheritdoc />
 public override double CentralMoment(int r)
 {
     if (r < 0)
     {
         throw new ArgumentOutOfRangeException(nameof(r));
     }
     else if (r == 0)
     {
         return(1.0);
     }
     else if ((r % 2) == 0)
     {
         // (r-1)!! \sigma^r
         return(AdvancedIntegerMath.DoubleFactorial(r - 1) * MoreMath.Pow(sigma, r));
     }
     else
     {
         return(0.0);
     }
 }
Exemple #21
0
        public void OdeNonlinear()
        {
            // y = \frac{y_0}{1 - y_0 (x - x_0)}
            Func <double, double, double> f = (double x, double y) => MoreMath.Sqr(y);

            int         count    = 0;
            OdeSettings settings = new OdeSettings()
            {
                RelativePrecision = 1.0E-8,
                EvaluationBudget  = 1024,
                Listener          = (OdeResult) => count++
            };
            OdeResult result = FunctionMath.IntegrateOde(f, 0.0, 1.0, 0.99, settings);

            Assert.IsTrue(TestUtilities.IsNearlyEqual(result.Y, 1.0 / (1.0 - 1.0 * (0.99 - 0.0)), result.Settings));

            Assert.IsTrue(count > 0);

            Console.WriteLine(result.EvaluationCount);
        }
 public void BinomialCoefficientSums()
 {
     foreach (int n in TestUtilities.GenerateIntegerValues(1, 100, 8))
     {
         double S0 = 0.0;
         double S1 = 0.0;
         double S2 = 0.0;
         int    k  = 0;
         foreach (double B in AdvancedIntegerMath.BinomialCoefficients(n))
         {
             S0 += B;
             S1 += k * B;
             S2 += k * k * B;
             k  += 1;
         }
         Assert.IsTrue(TestUtilities.IsNearlyEqual(S0, MoreMath.Pow(2, n)));
         Assert.IsTrue(TestUtilities.IsNearlyEqual(S1, MoreMath.Pow(2, n - 1) * n));
         Assert.IsTrue(TestUtilities.IsNearlyEqual(S2, MoreMath.Pow(2, n - 2) * n * (n + 1)));
     }
 }
Exemple #23
0
 /// <inheritdoc />
 public override double RawMoment(int r)
 {
     if (r < 0)
     {
         throw new ArgumentOutOfRangeException(nameof(r));
     }
     else if (r == 0)
     {
         return(1.0);
     }
     else if (r >= a)
     {
         return(Double.PositiveInfinity);
     }
     else
     {
         // Straightforward integration yields M_r = \frac{\alpha m^r}{\alpha - r}
         return(a / (a - r) * MoreMath.Pow(m, r));
     }
 }
 /// <summary>
 /// Gets a central moment of the distribution.
 /// </summary>
 /// <param name="r">The order of the moment.</param>
 /// <returns>The central moment C<sub>r</sub>.</returns>
 public override double CentralMoment(int r)
 {
     if (r < 0)
     {
         throw new ArgumentOutOfRangeException(nameof(r));
     }
     else if (r == 0)
     {
         return(1.0);
     }
     else if (r == 1)
     {
         return(0.0);
     }
     else
     {
         double mu = Mean;
         return(ExpectationValue((int k) => MoreMath.Pow(k - mu, r)));
     }
 }
Exemple #25
0
        public override MapObjectHoverData GetHoverDataTopDownView(bool isForObjectDrag, bool forceCursorPosition)
        {
            Point?relPosMaybe = MapObjectHoverData.GetPositionMaybe(isForObjectDrag, forceCursorPosition);

            if (!relPosMaybe.HasValue)
            {
                return(null);
            }
            Point relPos = relPosMaybe.Value;

            (float inGameX, float inGameY, float inGameZ) = GetArrowHeadPosition();
            (double controlX, double controlZ)            = MapUtilities.ConvertCoordsForControlTopDownView(inGameX, inGameZ, UseRelativeCoordinates);
            double dist = MoreMath.GetDistanceBetween(controlX, controlZ, relPos.X, relPos.Y);

            if (dist <= 20 || forceCursorPosition)
            {
                return(new MapObjectHoverData(this, inGameX, inGameY, inGameZ));
            }
            return(null);
        }
Exemple #26
0
        /// <inheritdoc />
        public override double GetRandomValue(Random rng)
        {
            // This is a rather weird transformation generator described in Michael et al, "Generating Random Variates
            // Using Transformations with Multiple Roots", The American Statistician 30 (1976) 88-90.

            double u   = rngGenerator.GetNext(rng);
            double y   = MoreMath.Sqr(rngGenerator.GetNext(rng));
            double muy = mu * y;
            double x   = mu * (1.0 + (muy - Math.Sqrt((4.0 * lambda + muy) * muy)) / (2.0 * lambda));
            double z   = rng.NextDouble();

            if (z <= mu / (mu + x))
            {
                return(x);
            }
            else
            {
                return(mu * mu / x);
            }
        }
        // update_walking_speed
        private static void UpdateWalkingSpeed(MutableMarioState marioState)
        {
            float maxTargetSpeed;
            float targetSpeed;

            bool slowSurface = false;

            if (slowSurface)
            {
                maxTargetSpeed = 24.0f;
            }
            else
            {
                maxTargetSpeed = 32.0f;
            }

            targetSpeed = marioState.IntendedMagnitude < maxTargetSpeed ? marioState.IntendedMagnitude : maxTargetSpeed;

            if (marioState.HSpeed <= 0.0f)
            {
                marioState.HSpeed += 1.1f;
            }
            else if (marioState.HSpeed <= targetSpeed)
            {
                marioState.HSpeed += 1.1f - marioState.HSpeed / 43.0f;
            }
            else
            {
                marioState.HSpeed -= 1.0f;
            }

            if (marioState.HSpeed > 48.0f)
            {
                marioState.HSpeed = 48.0f;
            }

            marioState.MarioAngle = MoreMath.NormalizeAngleUshort(
                marioState.IntendedAngle - CalculatorUtilities.ApproachInt(
                    MoreMath.NormalizeAngleShort(marioState.IntendedAngle - marioState.MarioAngle), 0, 0x800, 0x800));
            ApplySlopeAccel(marioState);
        }
Exemple #28
0
        /// <summary>
        /// Computes the exponential integral.
        /// </summary>
        /// <param name="n">The order parameter.</param>
        /// <param name="x">The argument, which must be non-negative.</param>
        /// <returns>The value of E<sub>n</sub>(x).</returns>
        /// <remarks>
        /// <para>The exponential integral is defined as:</para>
        /// <img src="../images/EIntegral.png" />
        /// <para>It is related to the incomplete Gamma function for negative, integer shape parameters by &#x393;(-k, x) = Ei<sub>k+1</sub>(x) / x<sup>k</sup>.</para>
        /// <para>In hydrology, E<sub>1</sub>(x) is sometimes called the Well function.</para>
        /// </remarks>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="x"/> is negative.</exception>
        public static double IntegralE(int n, double x)
        {
            if (x < 0.0)
            {
                throw new ArgumentOutOfRangeException("x");
            }

            // special case x = 0
            if (x == 0.0)
            {
                if (n <= 1)
                {
                    return(Double.PositiveInfinity);
                }
                else
                {
                    return(1.0 / (n - 1));
                }
            }

            if (n < 0)
            {
                // negative n is expressible using incomplete Gamma
                return(AdvancedMath.Gamma(1 - n, x) / MoreMath.Pow(x, 1 - n));
            }
            else if (n == 0)
            {
                // special case n=0
                return(Math.Exp(-x) / x);
            }
            else if (x < 2.0)
            {
                // use series for x < 1
                return(IntegralE_Series(n, x));
            }
            else
            {
                // use continued fraction for x > 1
                return(IntegralE_ContinuedFraction(n, x));
            }
        }
        /// <summary>
        /// Computes a Stirling number of the second kind.
        /// </summary>
        /// <param name="n">The upper argument, which must be non-negative.</param>
        /// <param name="k">The lower argument, which must lie between 0 and n.</param>
        /// <returns>The value of the Stirling number of the second kind.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="n"/> is negative, or <paramref name="k"/>
        /// lies outside [0, n].</exception>
        /// <seealso href="https://en.wikipedia.org/wiki/Stirling_numbers_of_the_second_kind"/>
        public static double StirlingNumber2(int n, int k)
        {
            if (n < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(n));
            }
            if ((k < 0) || (k > n))
            {
                throw new ArgumentOutOfRangeException(nameof(k));
            }

            if ((k == 1) || (k == n))
            {
                return(1.0);
            }
            else if (k == 0)
            {
                return(0.0);
                // The exceptional value 1 for n = k = 0 will already have been returned by the previous case.
            }
            else if (k == 2)
            {
                return(Math.Round(MoreMath.Pow(2.0, n - 1) - 1.0));
            }
            else if (k == (n - 1))
            {
                return(AdvancedIntegerMath.BinomialCoefficient(n, 2));
            }
            else
            {
                double[] s = Stirling2_Recursive(n, k);
                return(s[k]);
            }

            // There is a formula for Stirling numbers
            //   { n \brace k } = \frac{1}{k!} \sum{j=0}^{k} (-1)^j { k \choose j} (k - j)^n
            // which would be faster than recursion, but it has large cancelations between
            // terms. We could try to use it when all values are less than 2^52, for which
            // double arithmetic is exact for integers. For k!, that means k < 18. For
            // largest term in sum for all k, that means n < 14.
        }
        public void StylblinskiTang()
        {
            Func <IList <double>, double> fStyblinskiTang = (IList <double> x) => {
                double fst = 0.0;
                for (int i = 0; i < x.Count; i++)
                {
                    double x1 = x[i];
                    double x2 = MoreMath.Sqr(x1);
                    fst += x2 * (x2 - 16.0) + 5.0 * x1;
                }
                return(fst / 2.0);
            };

            // solution coordinate is root of 5 - 32 x + 4 x^3 = 0 with negative second derivative.
            // There are two such roots.
            double root1 = -2.9035340277711770951;
            double root2 = 2.7468027709908369925;

            // tested up to n=16, works with slightly decreasing accuracy of Location
            for (int n = 2; n < 8; n++)
            {
                Console.WriteLine(n);

                ColumnVector start = new ColumnVector(n);
                //ColumnVector start = new ColumnVector(-1.0, -2.0, -3.0, -4.0, -5.0, -6.0);

                MultiExtremum minimum = MultiFunctionMath.FindLocalMinimum(fStyblinskiTang, start);

                Console.WriteLine(minimum.EvaluationCount);
                Console.WriteLine(minimum.Value);
                for (int i = 0; i < minimum.Dimension; i++)
                {
                    Console.WriteLine(minimum.Location[i]);
                    Assert.IsTrue(
                        TestUtilities.IsNearlyEqual(minimum.Location[i], root1, Math.Sqrt(Math.Sqrt(TestUtilities.TargetPrecision))) ||
                        TestUtilities.IsNearlyEqual(minimum.Location[i], root2, Math.Sqrt(Math.Sqrt(TestUtilities.TargetPrecision)))
                        );
                }
                Assert.IsTrue(TestUtilities.IsNearlyEqual(minimum.Value, fStyblinskiTang(minimum.Location)));
            }
        }