MathGroup Archive 2009

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Solve / NSolve

  • To: mathgroup at
  • Subject: [mg95386] Re: Solve / NSolve
  • From: Daniel Lichtblau <danl at>
  • Date: Sat, 17 Jan 2009 05:29:27 -0500 (EST)
  • References: <gkgouo$3sg$> <gkppsb$dot$>

On Jan 16, 5:08 am, SigmundV <sigmu... at> wrote:
> Thanks to Andrzej and Jean-Marc for the discussion on the differences
> between Solve and NSolve. Have any of you tried to run the code i
> provided (including the missing function definition which I provided
> later)? I'm aware that Solve and NSolve do not use the same algorithm
> to solve an equation, but it does not seem "logical" to me that they
> don't give the same solution to the same system of algebraic
> equations. What could be the reason for this? I'm also concerned witht
> he speed. Solve is much faster than NSolve for my problem. How come?
> In addition to the code I provided earlier, I just tried with another
> example of a system of two algebraic equations:
> {1.1 x^2 + y^2 == 1.0, x + 1.1 y == 0.0}
> Solve[%, {x, y}] // Timing
> NSolve[%%, {x, y}] // Timing
> When evaluating this cell you'll see that Solve is substantially
> faster than NSolve, but they yield the same solution. However, in my
> first example they do not yield the same solution in all cases.
> Hopefully some of you can shed some light on all this. It could also
> be me comparing apples and oranges. Let me hear your thoughts on all
> this.
> Kind regards,
> Sigmund

This is a bit of a tangle. One thing you probably do not realize is
that people using version 7 get different behavior from you.
Specifically, the Solve variant will give a slew of error messages due
to badness in your Drop code. I isolated a simple example that shows
this difference, and I'll cover it below because it also serves, to an
extent, to show why NSolve is safer for a problem like this even in
absence of such error messages.

polys = {100*(-0.11 + x)^2 + 25*(-0.21 + y)^2 - 1,
       (-1.8774107494749928*(-0.11 + x))/10^13 -
         10.971072010497574*(-0.21 + y)};

Mathematica 6:
In[12]:= Solve[polys==0, {x, y}]
Out[12]= {{x -> 0.0785768, y -> 0.21}, {x -> 0.139692, y -> 0.21}}

Mathematica 7:
In[13]:= Solve[polys==0, {x, y}]
Out[13]= {{x -> 0.109135, y -> 0.21}, {x -> 0.109135, y -> 0.21}}

Observe that the latter claims a double root whereas the x coordinates
in the former are well separated.

So let me say a bit about what Solve does. It starts by rationalizing
all coefficients and computing an exact Groebner basis. In both
versions this is similarly handled, although the rationalization is
different in a way that is irrelevant for the present discussion. It
then feeds a univariate polynomial to a numerical root finder. In
version 6 and prior this was Jenkins-Traub. In version 7 I believe
this is no longer the case, at least by default.

Here is the univariate polynomial produced by one of the versions. I
will show the resulting roots in both versions.

upoly = -1.049020730058627*^75*y + 2.4976684049014928*^75*y^2 +

Mathematica 6:
In[17]:= InputForm[Roots[upoly==0, y]]
Out[17]//InputForm= y == 0.20999999999999952 || y ==

Mathematica 7:
In[16]:= InputForm[Roots[upoly==0, y]]
Out[16]//InputForm= y == 0.21000000000000002 || y ==

In the first case the roots are separated slightly, and in the second
they are not. This extremely small difference is what messes up later
computations of x; the small root difference gets magnified by some
large coefficients in the polynomial(s) that relate x to y, so the x
values get separated in version 6. Clearly when the y values are
identical this will not happen.

I do not view this as a bug in the new root finding code. It may well
be a bug fix, in that the code now only tries to return digits that
are justifiable by the input precision. The bad handling, if any, is
in Solve, in rationalizing and then finding a Groebner basis. Reason
being, this can make numerator coefficients huge, thus introducing
numeric instability. Huge coefficients pose no problem in principle,
when doing exact computation (the domain of Solve). For approximate
computation this introduces all sorts of trouble with cancellation
error downstream (e.g. in numeric handling of Roots).

As for speed, I can say a bit. This particular equation set is fast to
handle, and Solve manages to beat NSolve in timing. That is by no
means always the case, and is quite rare for most polynomial systems
that come my way. Moreover even in version 6, the Solve solution is
garbage (check the residuals), hence your bad pictures. It is just not
garbage with spurious multiplicity, hence does not run afoul of the
Drop code. In contrast, the NSolve solution gives small residuals.
Probably worth spending a bit more time in that code, if it is better
suited to handle the problem.

Daniel Lichtblau
Wolfram Research

  • Prev by Date: Re: Re: Solve / NSolve
  • Next by Date: Re: Finding a sine wave
  • Previous by thread: Re: Re: Solve / NSolve
  • Next by thread: About solution of complex system of DEs - to administrator -this is