find all answers of an equation
15 views (last 30 days)
Star Strider on 21 Feb 2015
No plotting, simply a for loop:
f = @(x) (x-2).*(x-3).*x - exp(-0.2*x);
x = [-5:0.1:5];
for k1 = 1:length(x)
rt(k1) = fzero(f, x(k1));
rt = unique(round(rt*1E+8)/1E+8);
189.1722e-003 1.6777e+000 3.1475e+000
The unique call is necessary because fzero will find the same approximate root for similar values of ‘x’ as it loops. Due to the characteristic approximation errors of fzero and inherent floating-point approximation errors, it is necessary to use a modified version of the round function to correct those. The roots are therefore good to about 1E-8.
More Answers (1)
John D'Errico on 21 Feb 2015
Edited: John D'Errico on 21 Feb 2015
How will you KNOW that you have found all solutions?
Wanting something is nice. Of course, we can't always get what we want. Hmm. That brings to mind a song, but odds are you have no idea what the reference to The Rolling Stones means. Kids, whats the matter with kids these days... (oops, now another song running through my head.)
Essentially, you cannot know that you have found all solutions to a nonlinear problem quite so easily. Mathematics is unforgiving. It does not give up its gifts without some effort on your part. In fact, even a plot is not in general sufficient, but it helps.
You MIGHT try this...
x1 = vpasolve(exp(-0.2*x)-(x-2)*(x-3)*x);
Then having solved for one root, deflate that root.
x2 = vpasolve((exp(-0.2*x)-(x-2)*(x-3)*x)/(x - x1));
and so on...
x3 = vpasolve((exp(-0.2*x)-(x-2)*(x-3)*x)/(x - x1)/(x-x2));
The general idea is to divide by the root you just found. This produces a new function that no longer has a root there. It works ok, at least until you have a problem with a root of order greater than 1, but then those roots will always cause a problem.
Anyway, where will this stop? How do you know that you have found all solutions? Again, knowing is the problem.
Alternatively, you might also try this...
expapprox = taylor(exp(-0.2*x)-(x-2)*(x-3)*x,'order',12)
- x^11/1949062500000000 + x^10/35437500000000 - x^9/708750000000 + x^8/15750000000 - x^7/393750000 + x^6/11250000 - x^5/375000 + x^4/15000 - (751*x^3)/750 + (251*x^2)/50 - (31*x)/5 + 1
- 24.981498513455838504331503293085 - 77.635564933596272665477129914466*i
- 66.383256811003489391804191913618 - 33.088493220112188173092823906644*i
36.30488877539236675241567653391 + 76.669938475166864616233334038753*i
80.052655747290671195726852365387 + 31.634706205534754641970685588937*i
80.052655747290671195726852365387 - 31.634706205534754641970685588937*i
- 24.981498513455838504331503293085 + 77.635564933596272665477129914466*i
36.30488877539236675241567653391 - 76.669938475166864616233334038753*i
- 66.383256811003489391804191913618 + 33.088493220112188173092823906644*i
That vpasolve found 3 real roots to the approximate problem might be a clue, but it was only an approximation. And that approximation may have either missed a root, or introduced a spurious one. In fact, we see many complex roots that it found.
There are other tricks one can employ, although it is in general difficult to know how to find all solutions to a nonlinear problem. For example, you can evaluate your function at a sequence of points, looking for zero crossings. At any point where you find a zero crossing, this will be a bracket for fzero.
fun = @(x) (exp(-0.2*x)-(x-2).*(x-3).*x);
x = -10:.05:10;
>> ind = find(diff(sign(fun(x))))
204 234 263
So now we would just run fzero in a loop on those three brackets where we think a root might lie. In fact, the work we did above should convince you that fzero will succeed on those brackets.
So it looks like we may have found brackets around at least 3 roots. I say may here, because there are always things that can mess up such a scheme. For example, find the root of tan(x) in the interval [1.5,1.6]. In fact, this is a bracket, in the sense that tan(x) changes sign over that interval. But is there a root in there?
For a general function, there may be infinitely many solutions, or there may be solutions that are difficult to find. And depending on the method you use, it always helps to test those solutions to see if they really were solutions to your original problem. There are always many ways to solve any problem, but understanding the methods you will use is important. Can they fail? How will you know if they have failed? Finally, in the end, a plot really does help. Allow your eyes and your brain to help you out.