예제 #1
0
        /// <summary>
        /// Create finite difference d^(order) u(x + minH*h)
        /// </summary>
        /// <param name="order">Order of the finite difference</param>
        /// <param name="minH">Count of h of the finite difference</param>
        /// <exception cref="OverflowException">The exception is thrown when trying
        /// to create FiniteDifference with too large order and minH</exception>
        public static FiniteDifference GetFiniteDifferenceByOrderAndMinH(int order, int minH)
        {
            // check parameters
            if (order < 0)
            {
                return(null);
            }
            if (order > MaxOrder)
            {
                throw new OverflowException("Can not create FiniteDifference. Order is too large");
            }
            // set up FiniteDifference
            FiniteDifference result = new FiniteDifference();

            result.Order    = order;
            result.MinimumH = minH;
            result.MaximumH = checked (minH + order);
            // get coefficients from PascalTriangle
            result._coefficients = PascalTriangle.GetCoefficients(order).Select((x, i) =>
            { // cast uing to double and make non-even numbers negative
                if (i % 2 == 0)
                {
                    return((double)x);
                }
                return(-(double)x);
            }).Reverse().ToArray();
            return(result);
        }
예제 #2
0
 /// <summary>
 /// Convert a string representation of a FiniteDifference.
 /// A return value indicated whether the conversion succeeded
 /// </summary>
 /// <param name="s">A string containing a FiniteDifference to convert</param>
 /// <param name="result">When this method returns, contains the
 /// FiniteDifference equivalent of the FiniteDifference contained in s,
 /// if the conversion succeeded, or null if s does not contain valid FiniteDifference</param>
 public static bool TryParse(string s, out FiniteDifference result)
 {
     result = null;
     try
     {
         result = Parse(s);
         return(true);
     }
     catch (Exception e) when(e is OverflowException || e is FormatException)
     {
         return(false);
     }
 }
예제 #3
0
        /// <summary>
        /// Evaluate an expression of FiniteDifferences
        /// </summary>
        /// <param name="s">A string containing an expression to evaluate</param>
        /// <exception cref="FormatException">Invalid format of a expression. Message contains invalid part</exception>
        /// <exception cref="OverflowException">Format is valid but expression contains too large coefficients</exception>
        /// <returns>FiniteDifference that contains result of the expression</returns>
        public static FiniteDifference Evaluate(string s)
        {
            if (string.IsNullOrWhiteSpace(s))
            {
                return(null);
            }

            // split expression for summands and evaluate each of them and sum them
            FiniteDifference result = null;

            foreach (var summand in GetSummands(s))
            {
                try
                {
                    result += EvaluateSummand(summand);
                }
                // on exception - provide info about summand
                catch (FormatException e)
                { throw new FormatException(summand.Trim(), e); }
            }
예제 #4
0
        public static FiniteDifference operator *(double k, FiniteDifference difference)
        {
            // on multiplication by zero or not FiniteDifference - not FiniteDifference
            if (ReferenceEquals(difference, null) || k.IsZero())
            {
                return(null);
            }
            // copy difference
            FiniteDifference result = new FiniteDifference();

            result.MinimumH = difference.MinimumH;
            result.MaximumH = difference.MaximumH;
            result.Order    = difference.Order;
            // copy coefficients multiplied on k
            result._coefficients = new double[difference._coefficients.Length];
            for (int i = 0; i < result._coefficients.Length; i++)
            {
                result._coefficients[i] = k * difference._coefficients[i];
            }
            return(result);
        }
예제 #5
0
        public static FiniteDifference operator +(FiniteDifference left, FiniteDifference right)
        {
            // if one of the operands is null - return another
            if (ReferenceEquals(left, null))
            {
                return(right);
            }
            if (ReferenceEquals(right, null))
            {
                return(left);
            }
            // if both are not null

            // create FiniteDifference with wide range of h
            FiniteDifference result = new FiniteDifference();

            result.MinimumH = Math.Min(left.MinimumH, right.MinimumH);
            result.MaximumH = Math.Max(left.MaximumH, right.MaximumH);
            // create array for coefficients
            result._coefficients = new double[result.MaximumH - result.MinimumH + 1];

            // copy values from operands
            for (int i = left.MinimumH; i <= left.MaximumH; i++)
            {
                result[i] += left[i];
            }
            for (int i = right.MinimumH; i <= right.MaximumH; i++)
            {
                result[i] += right[i];
            }

            // cut order if got zero coefficients

            // move left divider until non-zero or end of array
            int l = result.MinimumH;

            while (result[l].IsZero())
            {
                // if all coefficients are zeros
                if (l == result.MaximumH)
                {
                    return(null);
                }
                else
                {
                    l++;
                }
            }

            // move right divider until non-zero
            int r = result.MaximumH;

            while (result[r].IsZero())
            {
                r--;
            }

            // change coefficients array
            double[] newCoefficients = new double[r - l + 1];
            Array.Copy(result._coefficients, l - result.MinimumH, newCoefficients, 0, newCoefficients.Length);
            result._coefficients = newCoefficients;

            // save result parameters
            result.MinimumH = l;
            result.MaximumH = r;
            result.Order    = r - l;

            return(result);
        }