Last active
October 17, 2021 12:18
-
-
Save mikel-zhobro/472eb92b2c101b21f2f63256d921bfd4 to your computer and use it in GitHub Desktop.
Bisection Method (RootFinding, Monotonous Functions)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import ContinuousSet | |
| def bisection_method(f, value, interval, eps=1e-12): | |
| """ Finds the root of f(psi) - value | |
| Args: | |
| f ([function]): f(psi) | |
| value ([float]): value = f(psi0) | |
| interval ([ContinuousSet]): interval of psi to look into | |
| Returns: | |
| [float]: root of f(psi) - value | |
| """ | |
| min_r = interval.a | |
| max_r = interval.b | |
| increasing = f(min_r) <= value <= f(max_r) | |
| decreasing = f(min_r) >= value >= f(max_r) | |
| assert increasing or decreasing, 'Make sure that value exist in the given interval' | |
| start = min_r | |
| endd = max_r | |
| err = 1.0 | |
| while abs(err) > eps: | |
| psi = (start + endd) / 2.0 | |
| err = f(psi) - value | |
| if increasing: | |
| if err > 0.0: | |
| endd = psi | |
| else: | |
| start = psi | |
| else: | |
| if err > 0.0: | |
| start = psi | |
| else: | |
| endd = psi | |
| return psi | |
| def feasible_set_for_monotonic_function(f, FeasibleOutRange, InputRange): | |
| """Find feasible input range that satisfies the feasible_out_range | |
| Args: | |
| f ([function]): f(in) = out | |
| FeasibleOutRange ([ContinuousSet]): out in FeasibleOutRange | |
| InputRange ([ContinuousSet]): in in InputRange | |
| Returns: | |
| [ContinuousSet]: Feasible Input Range | |
| """ | |
| PossibleOutRange = ContinuousSet(f(InputRange.a), f(InputRange.b), InputRange.a_incl, InputRange.b_incl) | |
| FeasiblePossibleOutRange = FeasibleOutRange - PossibleOutRange | |
| assert not FeasiblePossibleOutRange.empty, 'No feasible region exists for output range {} in the input range {}'.format(FeasibleOutRange, InputRange) | |
| psi0 = bisection_method(f, value=FeasiblePossibleOutRange.a, interval=InputRange) | |
| psi1 = bisection_method(f, value=FeasiblePossibleOutRange.b, interval=InputRange) | |
| FeasibleInRange = InputRange - ContinuousSet(psi0, psi1) | |
| return FeasibleInRange | |
| f = lambda x: x**2 | |
| print(ContinuousSet(2.0,8.0, False)) | |
| print(feasible_set_for_monotonic_function(f, ContinuousSet(16.0, 128.0), ContinuousSet(2.0,8.0, False, False))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment