Example #1
0
        /// <summary>
        /// Filters the surges in a sequence whose absolute values deviate from the specified positive value by a
        /// positive factor specified.
        /// </summary>
        /// <typeparam name="T">The type of elements in the incoming sequence.</typeparam>
        /// <typeparam name="C">The calculator for the sequence elements type.</typeparam>
        /// <param name="sequence">A calling sequence object.</param>
        /// <param name="centerValue">A nonnegative value. Sequence elements that deviate from this value by more than <paramref name="allowedDeviationFactor"/> will be filtered out.</param>
        /// <param name="allowedDeviationFactor">The allowed factor of absolute deviation.</param>
        /// <param name="deviationType">
        /// If deviation type is Downwards, values which are smaller than <paramref name="centerValue"/>
        /// by a factor of <paramref name="allowedDeviationFactor"/> will be filtered.
        /// If deviation type is Upwards, values which are bigger than <paramref name="centerValue"/>
        /// by a factor of <paramref name="allowedDeviationFactor"/> will be filtered.
        /// If deviation type is EitherSide, all values that differ from the <paramref name="centerValue"/>
        /// by a factor of <paramref name="allowedDeviationFactor"/> will be filtered.
        /// </param>
        /// <param name="filteredValues">A reference to a collection to store the filtered values. May be null.</param>
        /// <returns>The list containing all incoming values except for the filtered ones.</returns>
        public static List <T> filterSurgesByAbsoluteFactorDeviationFromValue <T, C>(this IEnumerable <T> sequence, T centerValue, double allowedDeviationFactor, DeviationType deviationType = DeviationType.EitherSide, ICollection <T> filteredValues = null) where C : ICalc <T>, new()
        {
            ICalc <T> calc = Numeric <T, C> .Calculator;

            (centerValue > Numeric <T, C> .Zero).Assert(new ArgumentException("The center value specified should be positive."));
            (allowedDeviationFactor > 0).Assert(new ArgumentException("The allowed deviation factor should be positive."));

            List <T> result = new List <T>();

            foreach (Numeric <T, C> current in sequence)
            {
                Numeric <T, C> absCurrent = WhiteMath <T, C> .Abs(current);

                Numeric <T, C> multipliedValue   = (Numeric <T, C>)allowedDeviationFactor * centerValue;
                Numeric <T, C> multipliedCurrent = (Numeric <T, C>)allowedDeviationFactor * absCurrent;

                if (deviationType == DeviationType.EitherSide && (absCurrent > multipliedValue || multipliedCurrent < centerValue) ||
                    deviationType == DeviationType.Upwards && absCurrent > multipliedValue ||
                    deviationType == DeviationType.Downwards && multipliedCurrent < centerValue)
                {
                    // Filter the surge.

                    if (filteredValues != null)
                    {
                        filteredValues.Add(current);
                    }
                }
                else
                {
                    result.Add(current);
                }
            }

            return(result);
        }
Example #2
0
        /// <summary>
        /// Adds relative (factor) surges from a symmetric distribution random generator to each value of a numeric sequence
        /// and returns the nosiy sequence in the form of a list.
        /// </summary>
        /// <typeparam name="T">The type of elements in the numeric sequence.</typeparam>
        /// <typeparam name="C">The calculator for the <typeparamref name="T"/> type.</typeparam>
        /// <param name="sequence">The calling numeric sequence object.</param>
        /// <param name="symmetricDistributionGenerator">A random generator providing values of some symmetric distribution.</param>
        /// <param name="deviationType">Which deviations (positive, negative or both) should be added to the sequence.</param>
        /// <returns></returns>
        public static List <T> addRelativeSurgesFromSymmetricDistribution <T, C>(this IEnumerable <T> sequence, IRandomUnbounded <T> symmetricDistributionGenerator, DeviationType deviationType) where C : ICalc <T>, new()
        {
            List <T> result = new List <T>(sequence.Count());

            foreach (Numeric <T, C> value in sequence)
            {
                if (deviationType == DeviationType.EitherSide)
                {
                    result.Add(value + value * symmetricDistributionGenerator.Next());
                }
                else if (deviationType == DeviationType.Downwards)
                {
                    result.Add(value - WhiteMath <T, C> .Abs(value * symmetricDistributionGenerator.Next()));
                }
                else
                {
                    result.Add(value + WhiteMath <T, C> .Abs(value * symmetricDistributionGenerator.Next()));
                }
            }

            return(result);
        }
Example #3
0
        /// <summary>
        /// Filters the surges in a sequence whose absolute values deviate from the specified positive value by a
        /// nonnegative value specified.
        /// </summary>
        /// <typeparam name="T">The type of elements in the incoming sequence.</typeparam>
        /// <typeparam name="C">The calculator for the sequence elements type.</typeparam>
        /// <param name="sequence">A calling sequence object.</param>
        /// <param name="centerValue">Some value. Sequence elements that deviate from this value by more than <paramref name="allowedEpsilon"/> will be filtered out.</param>
        /// <param name="allowedEpsilon">The allowed nonnegative value of deviation from <paramref name="centerValue"/>.</param>
        /// <param name="deviationType">
        /// If deviation type is Downwards, values which are smaller than <paramref name="centerValue"/>
        /// by <paramref name="allowedEpsilon"/> will be filtered.
        /// If deviation type is Upwards, values which are bigger than <paramref name="centerValue"/>
        /// by <paramref name="allowedEpsilon"/> will be filtered.
        /// If deviation type is EitherSide, all values that differ from the <paramref name="centerValue"/>
        /// by <paramref name="allowedEpsilon"/> will be filtered.
        /// </param>
        /// <param name="filteredValues">A reference to a collection to store the filtered values. May be null.</param>
        /// <returns>The list containing all incoming values except for the filtered ones.</returns>
        public static List <T> filterSurgesByEpsilonDeviationFromValue <T, C>(this IEnumerable <T> sequence, T centerValue, T allowedEpsilon, DeviationType deviationType = DeviationType.EitherSide, ICollection <T> filteredValues = null) where C : ICalc <T>, new()
        {
            ICalc <T> calc = Numeric <T, C> .Calculator;

            (allowedEpsilon >= Numeric <T, C> .Zero).Assert(new ArgumentException("Allowed deviation epsilon should be a non-negative value."));

            List <T> result = new List <T>();

            foreach (Numeric <T, C> current in sequence)
            {
                if (deviationType == DeviationType.EitherSide && WhiteMath <T, C> .Abs(centerValue - current) < (Numeric <T, C>)allowedEpsilon ||
                    deviationType == DeviationType.Downwards && centerValue - current < allowedEpsilon ||
                    deviationType == DeviationType.Upwards && current - centerValue < allowedEpsilon)
                {
                    result.Add(current);
                }
                else if (filteredValues != null)
                {
                    filteredValues.Add(current);
                }
            }

            return(result);
        }
Example #4
0
        // ------------------- FACTORIZATION ----------------------------

        /// <summary>
        /// Preforms the LUP-factorization of a matrix (let it be A)
        /// in the form of:
        ///
        /// P*A = L*U.
        ///
        /// The P is an identity matrix with a plenty of row inversions.
        /// For the economy of space it is provided as a single-dimensional array of integers:
        ///
        /// (0, 1, 2, 3, ..., n).
        ///
        /// Element indices of this array stand for matrix rows, and elements value
        /// mean the position of '1' in a row.
        ///
        /// Requirements: works for any square and nonsingular matrix (having a non-zero determinant).
        /// If these requirements aren't met, either a MatrixSingularException or a MatrixSizeException
        /// would be thrown.
        /// </summary>
        /// <param name="C">The matrix C containing L + U - E. It is clear that both L and U can be easily extracted from this matrix.</param>
        /// <param name="P">The identity matrix with a plenty of row inversions in the form of array.</param>
        public void LUP_Factorization(out int[] P, out Matrix_SDA <T, C> C)
        {
            if (this.rows != this.columns)
            {
                throw new MatrixSizeException("The matrix is not square an thus cannot be factorized.");
            }

            int n = this.rows;  // размер матрицы

            C = new Matrix_SDA <T, C>(n, n);

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    C.setItemAt(i, j, this.getItemAt(i, j));
                }
            }

            P = new int[n];
            P.FillByAssign(delegate(int i) { return(i); });

            // ----- пошел ----------

            Numeric <T, C> pivot;
            Numeric <T, C> abs;

            int pivotIndex;

            for (int i = 0; i < n; i++)
            {
                pivot      = Numeric <T, C> .Zero;
                pivotIndex = -1;

                for (int row = i; row < n; row++)
                {
                    abs = WhiteMath <T, C> .Abs(this.getItemAt(row, i));

                    if (abs > pivot)
                    {
                        pivot      = abs;
                        pivotIndex = row;
                    }
                }

                if (pivot == Numeric <T, C> .Zero)
                {
                    throw new MatrixSingularityException("The matrix is singular. It cannot be factorized.");
                }

                if (pivotIndex != i)
                {
                    P.Swap(pivotIndex, i);
                    C.swapRows(pivotIndex, i);
                }

                try
                {
                    for (int j = i + 1; j < n; j++)
                    {
                        C.setItemAt(j, i, C.getItemAt(j, i) / C.getItemAt(i, i));

                        if (Numeric <T, C> .isInfinity(C.getItemAt(j, i)) || Numeric <T, C> .isNaN(C.getItemAt(j, i)))
                        {
                            throw new DivideByZeroException();
                        }

                        for (int k = i + 1; k < n; k++)
                        {
                            C.setItemAt(j, k, C.getItemAt(j, k) - C.getItemAt(j, i) * C.getItemAt(i, k));
                        }
                    }
                }
                catch (DivideByZeroException)
                {
                    throw new MatrixSingularityException("The matrix is singular. It cannot be factorized.");
                }
            }

            return;
        }
Example #5
0
        // --------- this is the key to happiness

        private static T _PositiveLagrangeBound(IList <Numeric <T, C> > coefficients, Func <int, Numeric <T, C>, Numeric <T, C> > selector)
        {
            // нули в начале нам совсем не нужны.

            int minus = 1;

            while (coefficients[coefficients.Count - minus] == Numeric <T, C> .Zero)
            {
                minus++;

                if (minus > coefficients.Count)
                {
                    throw new ArgumentException("This polynom contains only zero coefficients. Cannot evaluate the finite roots interval.");
                }
                // todo - return INFINITY.
            }

            // ------- начальный коэффициент - меньше нуля?
            // заменяем функцию g(x) = -f(x) и сохраняем корни и нервы.

            if (selector(coefficients.Count - minus, coefficients[coefficients.Count - minus]) < Numeric <T, C> .Zero)
            {
                object     target = selector.Target;
                MethodInfo method = selector.Method;

                selector = delegate(int i, Numeric <T, C> obj) { return(-(Numeric <T, C>)method.Invoke(target, new object[] { i, obj })); };
            }

            // -----------------

            T nCoef = coefficients[coefficients.Count - minus];

            T cur;

            T one = calc.fromInt(1);
            T max = calc.zero;

            int  index = -1;        // индекс первого отрицательного коэффициента
            bool found = false;     // найдены ли отрицательные коэффициенты!

            for (int i = coefficients.Count - minus; i >= 0; i--)
            {
                cur = selector(i, coefficients[i]);

                if (!found && calc.mor(calc.zero, cur))
                {
                    found = true;
                    index = coefficients.Count - i - minus;
                }

                // -- здесь cur больше не нужна, а нужно только ее
                // абсолютное значение. его и используем.

                cur = WhiteMath <T, C> .Abs(cur);

                if (calc.mor(cur, max))
                {
                    max = cur;
                }
            }

            if (!found)
            {
                return(calc.zero);
            }

            return(calc.sum(one, WhiteMath <T, C> .Power(calc.div(max, WhiteMath <T, C> .Abs(nCoef)), calc.div(one, calc.fromInt(index)))));
        }
Example #6
0
        /// <summary>
        /// Returns the string representation of the polynomial function
        /// as an array of coefficients - or, in the functional form
        /// i.e. 'f(x) = ...'.
        /// </summary>
        /// <param name="type">The type of the string representation.</param>
        /// <returns>The string representation of the current object.</returns>
        public string ToString(PolynomStringRepresentationType type)
        {
            if (type == PolynomStringRepresentationType.Coefficients)
            {
                string coefString = "";

                for (int i = 0; i < coefficients.Length; i++)
                {
                    coefString += "|" + this.coefficients[i].ToString();
                }

                coefString += "|";

                return(coefString);
            }
            else
            {
                string functionString = "f(x) = ";

                Numeric <T, C> one = calc.fromInt(1);

                for (int i = coefficients.Length - 1; i > 0; i--)
                {
                    if (coefficients[i] != Numeric <T, C> .Zero)
                    {
                        functionString += string.Format("{0}{1}x{2}", (coefficients[i] >= calc.zero ? (i < coefficients.Length - 1?" + ":"") : (i < coefficients.Length - 1?" - ":"-")), (coefficients[i] != one ? WhiteMath <T, C> .Abs(coefficients[i]).ToString() : ""), (i == 1 ? "" : "^" + i.ToString()));
                    }
                }

                if (coefficients[0] != Numeric <T, C> .Zero)
                {
                    functionString += string.Format(" {0} {1} ", (coefficients[0] > Numeric <T, C> .Zero ? "+" : "-"), WhiteMath <T, C> .Abs(coefficients[0]));
                }

                return(functionString);
            }
        }