private static Int32 Compare(fsIntegrationSegment a, fsIntegrationSegment b) { int compareResult = Compare(a.GetPriority(), b.GetPriority()); if (compareResult != 0) { return(compareResult); } compareResult = Compare(a.KronrodIntergralValue, b.KronrodIntergralValue); if (compareResult != 0) { return(compareResult); } compareResult = Compare(a.GaussIntergralValue, b.GaussIntergralValue); if (compareResult != 0) { return(compareResult); } compareResult = Compare(a.BeginArg, b.BeginArg); if (compareResult != 0) { return(compareResult); } compareResult = Compare(a.EndArg, b.EndArg); if (compareResult != 0) { return(compareResult); } return(0); }
public static fsValue Calculate(fsFunction function, fsValue beginArg, fsValue endArg, fsValue tolerance) { if (beginArg > endArg) { throw new Exception("fsDefiniteIntegral: provided limits are: beginAng > endArg"); } if (beginArg == endArg) { return(fsValue.Zero); } fsValue kronrodValue, gaussValue; EvalIntegrals(function, beginArg, endArg, out kronrodValue, out gaussValue); fsValue kronrodResult = kronrodValue; fsValue gaussResult = gaussValue; var queue = new SortedDictionary <fsIntegrationSegment, int> { { new fsIntegrationSegment(kronrodValue, gaussValue, beginArg, endArg), 0 } }; int iterationsCount = 0; while (fsValue.Abs(kronrodResult - gaussResult) > tolerance || fsValue.Abs(kronrodResult / gaussResult - 1) > tolerance) { if (++iterationsCount >= 1000) // If we made too many iterations { // and still don't have proper precision break; // then just return not precise answer. } fsIntegrationSegment currentSegment = queue.Last().Key; queue.Remove(currentSegment); beginArg = currentSegment.BeginArg; endArg = currentSegment.EndArg; if (IsNeighbouringNumbers(beginArg, endArg)) { continue; } kronrodResult -= currentSegment.KronrodIntergralValue; gaussResult -= currentSegment.GaussIntergralValue; EvalIntegrals(function, beginArg, 0.5 * (beginArg + endArg), out kronrodValue, out gaussValue); kronrodResult += kronrodValue; gaussResult += gaussValue; queue.Add(new fsIntegrationSegment(kronrodValue, gaussValue, beginArg, 0.5 * (beginArg + endArg)), 0); EvalIntegrals(function, 0.5 * (beginArg + endArg), endArg, out kronrodValue, out gaussValue); kronrodResult += kronrodValue; gaussResult += gaussValue; queue.Add(new fsIntegrationSegment(kronrodValue, gaussValue, 0.5 * (beginArg + endArg), endArg), 0); } return((kronrodResult + gaussResult) / 2); }