public static bool FindMinimum(fsFunction function, fsValue beginArg, fsValue endArg, int iterationsCount, out fsValue beginRes, out fsValue endRes) { beginRes = new fsValue(); endRes = new fsValue(); if (beginArg.Defined == false || endArg.Defined == false) { return(false); } fsValue len = endArg - beginArg; if (len <= new fsValue(0)) { throw new Exception("Wrong interval for ternary search"); } var eps = new fsValue(1e-8); fsValue left = beginArg; fsValue right = endArg; for (int i = 0; i < iterationsCount; ++i) { fsValue middle = 0.5 * (left + right); fsValue mid1 = middle - eps * (right - left); fsValue mid2 = middle + eps * (right - left); fsValue val1 = function.Eval(mid1); fsValue val2 = function.Eval(mid2); if (!val1.Defined) { throw new Exception("Function given to TernaryMethod not defind in point " + mid1.Value); } if (!val2.Defined) { throw new Exception("Function given to TernaryMethod not defind in point " + mid2.Value); } if (val1 > val2) { left = mid1; } else { right = mid2; } } beginRes = left; endRes = right; return(true); }
static private void EvalIntegrals(fsFunction function, fsValue beginArg, fsValue endArg, out fsValue kronrodResult, out fsValue gaussResult) { fsValue c0 = 0.5 * (endArg + beginArg); fsValue c1 = 0.5 * (endArg - beginArg); kronrodResult = fsValue.Zero; gaussResult = fsValue.Zero; for (int i = 0; i <= 60; ++i) { fsValue fValue = function.Eval(c0 + c1 * X[i]); kronrodResult += WKronrod[i] * fValue; gaussResult += WGauss[i] * fValue; } kronrodResult *= c1; gaussResult *= c1; }
public static bool FindRootRange(fsFunction function, fsValue beginArg, fsValue endArg, int iterationsCount, out fsValue beginRes, out fsValue endRes) { beginRes = new fsValue(); endRes = new fsValue(); if (beginArg.Defined == false || endArg.Defined == false) { return(false); } fsValue len = endArg - beginArg; var eps = new fsValue(1e-8); if (len.Value < 0) { eps = -eps; } if (fsValue.Abs(len) < new fsValue(1)) { eps = eps * fsValue.Abs(len); } fsValue beginValue = function.Eval(beginArg + eps); fsValue endValue = function.Eval(endArg - eps); if (beginValue.Defined == false || endValue.Defined == false) { return(false); } if (beginValue == endValue) { if (beginValue.Value == 0) { if (function.Eval(beginArg).Value == 0) { beginRes = endRes = endArg; return(true); } beginRes = beginArg + eps; endRes = beginArg + eps; return(true); } if (function.Eval(endArg).Value == 0) { beginRes = endRes = endArg; return(true); } return(false); } fsValue beginSign = fsValue.Sign(beginValue, eps); fsValue endSign = fsValue.Sign(endValue, eps); if ((beginSign * endSign).Value > 0) { return(false); } fsValue left = beginArg; fsValue right = endArg; for (int i = 0; i < iterationsCount; ++i) { fsValue middle = 0.5 * (left + right); fsValue value = function.Eval(middle); if (!value.Defined) { throw new Exception("Function given to BisectionMethod not defind in point " + middle.Value); } fsValue midSign = fsValue.Sign(value, eps); if (midSign.Value == 0 || midSign == endSign) { right = middle; } else { left = middle; } } beginRes = left; endRes = right; return(true); }
public static fsValue FindBreakInUnimodalFunction(fsFunction function, fsValue beginArg, fsValue endArg, int iterationsCount) { if (beginArg.Defined == false || endArg.Defined == false) { return(new fsValue()); } fsValue len = endArg - beginArg; var eps = new fsValue(1e-8); if (len.Value < 0) { eps = -eps; } fsValue beginValue = function.Eval(beginArg); fsValue endValue = function.Eval(endArg); if (fsValue.Sign(beginValue, eps) * fsValue.Sign(endValue, eps) == new fsValue(-1)) { throw new Exception("Search limits represent different signs of values already"); } beginValue = function.Eval(beginArg + eps); endValue = function.Eval(endArg - eps); if (fsValue.Sign(beginValue, eps) * fsValue.Sign(endValue, eps) == new fsValue(-1)) { throw new Exception("Search limits represent different signs of values already"); } if (beginValue.Defined == false || endValue.Defined == false) { return(new fsValue()); } fsValue initialSign = fsValue.Sign(beginValue, eps); fsValue left = beginArg; fsValue right = endArg; for (int i = 0; i < iterationsCount; ++i) { fsValue middle = 0.5 * (left + right); fsValue mid1 = middle - eps * (right - left); fsValue mid2 = middle + eps * (right - left); fsValue val1 = function.Eval(mid1); fsValue val2 = function.Eval(mid2); if (!val1.Defined) { throw new Exception("Function given to FindBreakInUnimodalFunction not defind in point " + mid1.Value); } if (!val2.Defined) { throw new Exception("Function given to FindBreakInUnimodalFunction not defind in point " + mid2.Value); } if (fsValue.Sign(val1, eps) != initialSign) { return(mid1); } if (fsValue.Sign(val2, eps) != initialSign) { return(mid2); } if (fsValue.Sign(val1 - val2, eps) == initialSign) { left = middle; } else { right = middle; } } return(new fsValue()); }