Esempio n. 1
0
        /// <summary>
        /// Given a set of values <c>Ln(a1), Ln(a2), ... Ln(an)</c>,
        /// return <c>Ln(a1+a2+...+an)</c>. This is especially useful
        /// when working with log probabilities and likelihoods.
        /// </summary>
        /// <param name="terms"></param>
        public static Float LnSum(IEnumerable <Float> terms)
        {
            // Two passes to find the overall max is a *lot* simpler,
            // but potentially more computationally intensive.
            Float  max   = Float.NegativeInfinity;
            Double soFar = 0;

            foreach (Float term in terms)
            {
                // At this point, all *prior* terms, Math.Exp(x - max).
                if (Float.IsNegativeInfinity(term))
                {
                    continue;
                }
                if (!(term > max))
                {
                    soFar += Math.Exp(term - max);
                }
                else
                {
                    soFar = Math.Exp(max - term) * soFar + 1;
                    max   = term;
                }
            }
            return((Float)Math.Log(soFar) + max);
        }
Esempio n. 2
0
        /// <summary>
        /// The new Half instance will convert the parameter into 16-bit half-precision floating-point.
        /// </summary>
        /// <param name="f">32-bit single-precision floating-point number.</param>
        /// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
        public Half(Single f, bool throwOnError)
            : this(f)
        {
            if (throwOnError)
            {
                // handle cases that cause overflow rather than silently ignoring it
                if (f > Half.MaxValue)
                {
                    throw new ArithmeticException("Half: Positive maximum value exceeded.");
                }
                if (f < -Half.MaxValue)
                {
                    throw new ArithmeticException("Half: Negative minimum value exceeded.");
                }

                // handle cases that make no sense
                if (Single.IsNaN(f))
                {
                    throw new ArithmeticException("Half: Input is not a number (NaN).");
                }
                if (Single.IsPositiveInfinity(f))
                {
                    throw new ArithmeticException("Half: Input is positive infinity.");
                }
                if (Single.IsNegativeInfinity(f))
                {
                    throw new ArithmeticException("Half: Input is negative infinity.");
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// computes the "softmax" function: log sum_i exp x_i
        /// </summary>
        /// <param name="inputs">Array of numbers to softmax</param>
        /// <param name="count">the number of input array elements to process</param>
        /// <returns>the softmax of the numbers</returns>
        /// <remarks>may have slightly lower roundoff error if inputs are sorted, smallest first</remarks>
        public static Float SoftMax(Float[] inputs, int count)
        {
            Contracts.AssertValue(inputs);
            Contracts.Assert(0 < count & count <= inputs.Length);

            int   maxIdx = 0;
            Float max    = Float.NegativeInfinity;

            for (int i = 0; i < count; i++)
            {
                if (inputs[i] > max)
                {
                    maxIdx = i;
                    max    = inputs[i];
                }
            }

            if (Float.IsNegativeInfinity(max))
            {
                return(Float.NegativeInfinity);
            }

            if (count == 1)
            {
                return(max);
            }

            //else if (leng == 2) {
            //  return SoftMax(inputs[0], inputs[1]);
            //}

            double intermediate = 0.0;
            Float  cutoff       = max - LogTolerance;

            for (int i = 0; i < count; i++)
            {
                if (i == maxIdx)
                {
                    continue;
                }
                if (inputs[i] > cutoff)
                {
                    intermediate += Math.Exp(inputs[i] - max);
                }
            }

            if (intermediate > 0.0)
            {
                return((Float)(max + Math.Log(1.0 + intermediate)));
            }
            return(max);
        }
Esempio n. 4
0
        /// <summary>
        /// computes the "softmax" function: log sum_i exp x_i
        /// </summary>
        /// <param name="inputs">Span of numbers to softmax</param>
        /// <returns>the softmax of the numbers</returns>
        /// <remarks>may have slightly lower roundoff error if inputs are sorted, smallest first</remarks>
        public static Float SoftMax(ReadOnlySpan <float> inputs)
        {
            int   maxIdx = 0;
            Float max    = Float.NegativeInfinity;

            for (int i = 0; i < inputs.Length; i++)
            {
                if (inputs[i] > max)
                {
                    maxIdx = i;
                    max    = inputs[i];
                }
            }

            if (Float.IsNegativeInfinity(max))
            {
                return(Float.NegativeInfinity);
            }

            if (inputs.Length == 1)
            {
                return(max);
            }

            double intermediate = 0.0;
            Float  cutoff       = max - LogTolerance;

            for (int i = 0; i < inputs.Length; i++)
            {
                if (i == maxIdx)
                {
                    continue;
                }
                if (inputs[i] > cutoff)
                {
                    intermediate += Math.Exp(inputs[i] - max);
                }
            }

            if (intermediate > 0.0)
            {
                return((Float)(max + Math.Log(1.0 + intermediate)));
            }
            return(max);
        }
Esempio n. 5
0
        /// <summary>
        /// computes "softmax" function of two arguments: log (exp x + exp y)
        /// </summary>
        public static Float SoftMax(Float lx, Float ly)
        {
            Float max;
            Float negDiff;

            if (lx > ly)
            {
                max     = lx;
                negDiff = ly - lx;
            }
            else
            {
                max     = ly;
                negDiff = lx - ly;
            }
            if (Float.IsNegativeInfinity(max) || negDiff < -LogTolerance)
            {
                return(max);
            }
            else
            {
                return((Float)(max + Math.Log(1.0 + Math.Exp(negDiff))));
            }
        }
Esempio n. 6
0
 /// <summary>
 /// Returns a value indicating whether the specified number evaluates to negative infinity
 /// </summary>
 /// <param name="number">a floating point number</param>
 /// <returns>a boolean</returns>
 public static bool IsNegativeInfinity(Real number)
 {
     return(Numeric.IsNegativeInfinity((Numeric)number));
 }