public static void ElementAddFill(this IList <MetaNum> self, MetaNum value)
 {
     for (var i = 0; i < self.Count; ++i)
     {
         self[i] = self[i] + value;
     }
 }
        public static int ArgMin(this IList <MetaNum> self)
        {
            if (self.Count == 0)
            {
                throw new InvalidCastException("No elements");
            }

            var i = 0;

            while (TypeTrait <MetaNum> .IsNaN(self[0]) && i < self.Count)
            {
                ++i;
            }

            if (i == self.Count)
            {
                throw new InvalidCastException("No elements");
            }

            MetaNum min    = self[i];
            int     argmin = i;

            for (++i; i < self.Count; ++i)
            {
                if (self[i] < min)
                {
                    min    = self[i];
                    argmin = i;
                }
            }

            return(argmin);
        }
        public static MetaNum Min(this IList <MetaNum> self)
        {
            if (self.Count == 0)
            {
                return(TypeTrait <MetaNum> .GetNaNOrRaiseException("No elements"));
            }

            var i = 0;

            while (TypeTrait <MetaNum> .IsNaN(self[0]) && i < self.Count - 1)
            {
                ++i;
            }

            MetaNum min = self[i];

            for (++i; i < self.Count; ++i)
            {
                if (self[i] < min)
                {
                    min = self[i];
                }
            }

            return(min);
        }
 public static void FillNaNFill(this IList <MetaNum> self, MetaNum fillValue)
 {
     for (var i = 0; i < self.Count; ++i)
     {
         if (TypeTrait <MetaNum> .IsNaN(self[i]))
         {
             self[i] = fillValue;
         }
     }
 }
        public static IList <MetaNum> ElementAdd(this IList <MetaNum> self, MetaNum value)
        {
            var result = new List <MetaNum>(self.Count);

            for (var i = 0; i < self.Count; ++i)
            {
                result.Add(self[i] + value);
            }

            return(result);
        }
        public static void CumulativeProductFill(this IList <MetaNum> self)
        {
            MetaNum product = (MetaNum)1;

            var i = 0;

            foreach (var value in self)
            {
                product  *= value;
                self[i++] = product;
            }
        }
        public static void CumulativeSumFill(this IList <MetaNum> self)
        {
            MetaNum sum = (MetaNum)0;

            var i = 0;

            foreach (var value in self)
            {
                sum      += value;
                self[i++] = sum;
            }
        }
        public static List <MetaNum> CumulativeProduct(this IList <MetaNum> self)
        {
            var     result  = new List <MetaNum>(self.Count);
            MetaNum product = (MetaNum)1;

            foreach (var value in self)
            {
                product *= value;
                result.Add(product);
            }

            return(result);
        }
        public static List <MetaNum> CumulativeSum(this IList <MetaNum> self)
        {
            var     result = new List <MetaNum>(self.Count);
            MetaNum sum    = (MetaNum)0;

            foreach (var value in self)
            {
                sum += value;
                result.Add(sum);
            }

            return(result);
        }
        public static MetaNum Mode(this IList <MetaNum> self, bool skipNaN = true)
        {
            if (self.Count == 0)
            {
                return(TypeTrait <MetaNum> .GetNaNOrRaiseException("No elements"));
            }

            var values = self.ToArray();

            Array.Sort(values);

            MetaNum currentValue = values[0];
            MetaNum bestValue    = currentValue;
            var     currentCount = 1;
            var     bestCount    = 1;

            int i = 1;

            if (skipNaN)
            {
                // After sort, NaNs should be collected to the first location of the sequence.
                while (TypeTrait <MetaNum> .IsNaN(values[i]))
                {
                    ++i;
                }
            }

            for (; i < values.Length; ++i)
            {
                if (currentValue == values[i])
                {
                    currentCount += 1;
                }
                else
                {
                    currentValue = values[i];
                    currentCount = 1;
                }

                if (currentCount > bestCount)
                {
                    bestCount = currentCount;
                    bestValue = currentValue;
                }
            }

            return(bestValue);
        }
        public static void CumulativeMaxFill(this IList <MetaNum> self)
        {
            if (self.Count == 0)
            {
                return;
            }

            MetaNum max = (MetaNum)self[0];

            for (var i = 0; i < self.Count; ++i)
            {
                if (self[i] > max)
                {
                    max = self[i];
                }
                self[i] = max;
            }
        }
        public static void CumulativeMinFill(this IList <MetaNum> self)
        {
            if (self.Count == 0)
            {
                return;
            }

            MetaNum min = (MetaNum)self[0];

            for (var i = 0; i < self.Count; ++i)
            {
                if (self[i] < min)
                {
                    min = self[i];
                }
                self[i] = min;
            }
        }
        public static List <MetaNum> FillNaN(this IList <MetaNum> self, MetaNum fillValue)
        {
            var result = new List <MetaNum>(self.Count);

            foreach (var value in self)
            {
                if (TypeTrait <MetaNum> .IsNaN(value))
                {
                    result.Add(fillValue);
                }
                else
                {
                    result.Add(value);
                }
            }

            return(result);
        }
        public static List <MetaFloat> Softmax(this IList <MetaNum> self)
        {
            MetaNum max = Max(self);

            var result = new List <MetaFloat>(self.Count);
            var denom  = (MetaFloat)0.0;

            for (var i = 0; i < self.Count; ++i)
            {
                var e = Math.Exp((double)(self[i] - max));
                result.Add((MetaFloat)e);
                denom += (MetaFloat)e;
            }

            for (var i = 0; i < result.Count; ++i)
            {
                result[i] /= denom;
            }

            return(result);
        }
        public static MetaNum Sum(this IList <MetaNum> self, bool skipNaN = true, int minCount = 0)
        {
            MetaNum sum   = (MetaNum)0.0;
            int     count = 0;

            foreach (var value in self)
            {
                if (skipNaN && TypeTrait <MetaNum> .IsNaN(value))
                {
                    continue;
                }
                sum += value;
                ++count;
            }

            if (count < minCount)
            {
                return(TypeTrait <MetaNum> .GetNaN());
            }

            return(sum);
        }
        public static MetaNum Product(this IList <MetaNum> self, bool skipNaN = true, int minCount = 0)
        {
            MetaNum product = (MetaNum)1;
            int     count   = 0;

            foreach (var value in self)
            {
                if (skipNaN && TypeTrait <MetaNum> .IsNaN(value))
                {
                    continue;
                }
                product *= value;
                ++count;
            }

            if (count < minCount)
            {
                return(TypeTrait <MetaNum> .GetNaN());
            }

            return(product);
        }
        public static List <MetaNum> CumulativeMin(this IList <MetaNum> self)
        {
            var result = new List <MetaNum>(self.Count);

            if (self.Count == 0)
            {
                return(result);
            }

            MetaNum min = (MetaNum)self[0];

            foreach (var value in self)
            {
                if (value < min)
                {
                    min = value;
                }
                result.Add(min);
            }

            return(result);
        }