/// <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); }
/// <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); } }
/// <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); } }
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); }
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); }