3

What is the best way to find the roots of an equation with more than one root. I understand that no one method which can solve every equation, and that you have to use more than one, but I can't find a root finding algorithm that can solve for more than one root in even the simplest instance.

For example: y = x^2

Although a root solving algorithm to solve a basic equation like this is helpful, it would need to be something I could adapt to solve an equation with more than two roots.

One more thing to note is that the equations wouldn't be your typical polynomials, but could be something such as ln(x^2) + x - 15 = 0

What is a root finding algorithm that could solve for this, or how could you edit a root finding algorithm such as the Bisection/Newton/Brent method to solve this problem, (Assuming I'm correct in that Newton and Brent's method can only solve for one root).

user2280687
  • 203
  • 3
  • 9
  • [Several other algorithms are mentioned in this wiki article.](http://en.wikipedia.org/wiki/Root-finding_algorithm) – Dave Newman Apr 21 '13 at 19:41

3 Answers3

1

I'd say that there's no general method to find all the roots of a general equation. However, one can try and devise methodologies once sufficient conditions have been specified. Even simple quadratic equations ax2 + bx + c = 0 aren't completely trivial, because the existence of real roots depends on the sign of b2-4ac, which isn't immediately obvious. So there are lots of techniques to apply, e.g Newton-Raphson, but no general method for the general case, especially for equations like ln(x2)+x-15 = 0.

Stochastically
  • 7,616
  • 5
  • 30
  • 58
1

Bottom line: You need to isolate the roots yourself.

Details depend on the algorithm: If you're using bisection or Brent's method, you need to come up with a set of intervals each containing a unique root. If using the Newton's method, you need to come up with a set of starting estimates (since it converges to a root given a starting point, and with different starting points it may or may not converge to different roots).

ev-br
  • 24,968
  • 9
  • 65
  • 78
1

As everyone has said, it is impossible to provide a general algorithm to find all, or some of the roots (where some is greater than one.) And how many roots is some? You cannot find all of the roots in general, since many functions will have infinitely many roots.

Even methods like Newton do not always converge to a solution. I tend to like a good, fairly stable method that will converge to a solution under reasonable circumstances, such as a bracket where the function is known to change sign. You can find such a code that has good convergence behavior on single roots, yet still is protected to behave basically like a bisection scheme when the function is less well behaved.

So, given a decent root finding scheme, you can try simple things like deflation. Thus, consider a simple function, like a first kind Bessel function. I'll do all my examples using MATLAB, but any tool that has a stable well written rootfinder like fzero in MATLAB will suffice.

ezplot(@(x) besselj(0,x),[0,10])
grid on

enter image description here

f0 = @(x) besselj(0,x);
xroots(1) = fzero(f0,1)
xroots =
    2.4048

From the plot, we can see there is a second root around 5 or 6.

Now, deflate f0 for that root, creating a new function based on f0, but one that lacks a root at xroots(1).

f1 = @(x) f0(x)./(x-xroots(1));
ezplot(f1,[0,10])
grid on

enter image description here

Note that in this curve, the root of f0 at xroots(1) has now been zapped away, as if it did not exist. Can we find a second root?

xroots(2) = fzero(f1,2)
xroots =
    2.4048    5.5201

We can go on of course, but at some point this scheme will fail due to numerical issues. And that failure won't take too terribly long either.

A better scheme might be to (for 1-d problems) use a bracketing scheme, conjoined with a sampling methodology. I say better because it does not require modifying the initial function to deflate the roots. (For 2-d or higher, things get far more hairy of course.)

xlist = (0:1:10)';
flist = f0(xlist);

[xlist,flist]
ans =
         0    1.0000
    1.0000    0.7652
    2.0000    0.2239
    3.0000   -0.2601
    4.0000   -0.3971
    5.0000   -0.1776
    6.0000    0.1506
    7.0000    0.3001
    8.0000    0.1717
    9.0000   -0.0903
   10.0000   -0.2459

As you can see, the function has sign changes in the intervals [2,3], [5,6], and [8,9]. A rootfinder that can search in a bracket will do here.

fzero(f0,[2,3])
ans =
    2.4048

fzero(f0,[5,6])
ans =
    5.5201

fzero(f0,[8,9])
ans =
    8.6537

Just look for sign changes, then throw the known bracket into a root finder. This will give as many solutions as you can find brackets.

Be advised, there are serious problems with the above scheme. It will completely fail to find the double root of a simple function like f(x)=x^2, because no sign change exists. And if you choose too coarse of a sampling, then you may have an interval with TWO roots in it, but you won't see a sign change at the endpoints.

For example, consider the function f(x) = x^2-x, which has single roots at 0 and at 1. But if you sample that function at -1 and 2, you will find that it is positive at both points. There is no sign change, but there are two roots.

Again, NO method can be made perfect. You can ALWAYS devise a function that will cause any such numerical method to fail.

  • I don't really understand your post. Are you saying, to generate random starting points, and see if the sign changes between the starting points? If so how should you generate them? (not in the deflation section, I don't know if it is possible to do that in objective C (which is what I am using)) (Is it possible to do deflation in any of the following languages: Objective C, C++, or Java) – user2280687 Apr 22 '13 at 00:39
  • You CAN use this scheme, looking for sign changes. Generate a slew of points, sufficient that you catch sign crossings, but not too far apart that there are TWO sign changes between a pair of points. If that happens, then you will miss both included roots using this scheme. It is possible to do deflation in ANY language. But it is not a scheme I would advise in general. The point is that no method is a sure solution. No method can be a sure solution for your problem. –  Apr 22 '13 at 02:16
  • As an addendum, note that searching for sign crossings will fail on some functions. For example, consider f(x)=x^2. No sign crossing, so no root you will catch. –  Apr 22 '13 at 02:19
  • So how would you decide at what increment to check for sign crossings? Should I create an algorithm to decide? If so can you point me in the direction of what the algorithm should be? I would think that too small of increments would cause a delay in speed, and I understand the problem with too large of increments. Also I understand that there is no one algorithm, so I can have (a) backup method(s) if the first fails to provide any roots. – user2280687 Apr 22 '13 at 02:34
  • Sorry, but there is no perfect scheme. Root finding (like many numerical methods) can be as much an art as a science. It depends on your needs, on how much time you are willing to expend on the certainty of finding a root, of finding all roots in an interval. This is dependent on you, and on the functions you will be working with. –  Apr 22 '13 at 03:17