Bisection Method Not Working

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

What is an example value of tof you are using? And what value of mu are you using? Some advice for your code: Whenever you are doing physical problems, always annotate the lines with the units being used.
Also, the very first iteration I get this:
K>> sqrt(s/(2*a))
ans =
1.0600
K>> asin(sqrt(s/(2*a)))
ans =
1.5708 - 0.3448i
So you have a problem in your basic formulae since you are getting complex results.
Hi James,
a,s,c,high, and low are all in kilometers. tof and del_t are in seconds. A value for tof is tof = 1.7511e3 sec. The code above is a portion of a larger function so my apologies for neglecting to elaborate on that variable as it's usually passed in. I'll take a look at the imaginary results. Did you get that for the initial a value of an iterated later value? Thanks for taking a look
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.
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)

Asked:

on 22 Nov 2016

Edited:

on 22 Nov 2016

Community Treasure Hunt

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

Start Hunting!