Bisection Method Not Working

4 views (last 30 days)
Alex Walts
Alex Walts on 22 Nov 2016
Edited: James Tursa on 22 Nov 2016
I'm attempting to solve a simple problem using the bisection method, but I can't get it to work properly. Bascially, it's an orbital mechanics problem where 'a' is a distance, and 'del_t' is a time of flight traveled with that distance. I am solving for the value of 'a' given 'del_t'. The values of the upper ('high') and lower ('low') bounds are unknown, so my values right now are guesses. Since 'a' is a distance, the lower bound cannot obviously be lower than 0. Note that the ii and jj counters are just troubleshooting tools that I've used to see which if conditions are running and how many times. For some reason, the loop runs infinitely with the value of 'a' capping out at the value of 'high'. It's probably something small and any help would be greatly appreciated!
a = 5000;
s = 1.123675421589143e+04
c = 8.795508431782857e+03
high = 30000;
low = 0;
del_t = 10000;
ii = 1;
jj = 1;
while abs(tof-del_t) > 10e-3
del_t = ((a^(3/2))/sqrt(mu))*((2*asin(sqrt(s/(2*a))))-...
(2*asin(sqrt((s-c)/(2*a))))-(sin(2*asin(sqrt(s/(2*a))))-...
sin(2*asin(sqrt((s-c)/(2*a))))));
if del_t < tof
low = a;
ii = ii+1;
else
high = a;
jj = jj+1;
end
a = (low+high)/2;
end
  4 Comments
James Tursa
James Tursa on 22 Nov 2016
I got the complex result at the very first iteration using the first values of a and s shown in your code. So the problem is immediate.
Alex Walts
Alex Walts on 22 Nov 2016
Try this instead. Same issue though with it never solving.
c = 9.674486239589160e+03;
s = 1.167624311979458e+04;
tof = 1.1257e+03;
f = @(x) ((x^(3/2))/sqrt(mu))*((2*asin(sqrt(s/(2*x))))-...
(2*asin(sqrt((s-c)/(2*x))))-(sin(2*asin(sqrt(s/(2*x))))-...
sin(2*asin(sqrt((s-c)/(2*x))))));
low = 0;
high = 10e10;
del_t = 0;
while abs(del_t-tof) > 1e-3
a = (low+high)/2;
if f(a) < tof
low = a;
else
high = a;
end
del_t = f(a);
end

Sign in to comment.

Answers (1)

James Tursa
James Tursa on 22 Nov 2016
Edited: James Tursa on 22 Nov 2016
It is not clear to me that your initial guesses are even bracketing your desired tof. So there will be no hope that your bisection method will converge. E.g.,
>> a = (low+high)/2
a =
5.0000e+10
>> f(a)
ans =
875.1905
>> f(high)
ans =
875.1905
>> tof
tof =
1.1257e+03
Also, your function f appears to be monotonically decreasing, not increasing, so your high & low are reversed. E.g., making a couple of changes I can get convergence:
mu = 3.986004418e5; % km^3/s^2
a = 5000;
c = 9.674486239589160e+03;
s = 1.167624311979458e+04;
tof = 1.1257e+03;
f = @(x) ((x^(3/2))/sqrt(mu))*((2*asin(sqrt(s/(2*x))))-...
(2*asin(sqrt((s-c)/(2*x))))-(sin(2*asin(sqrt(s/(2*x))))-...
sin(2*asin(sqrt((s-c)/(2*x))))));
low = 7500;
high = 20000;
if( (f(low)-tof)*(f(high)-tof) > 0 )
error('Initial guesses do not bracket desired tof');
end
del_t = 0;
while abs(del_t-tof) > 1e-3
a = (low+high)/2;
fa = f(a);
if( imag(fa) )
disp(a);
disp(fa);
error('f(a) is complex');
end
if fa < tof
high = a;
else
low = a;
end
del_t = fa;
end
(But, again, I would advise that you annotate all of your lines with constants on them like I have annotated the first line)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!