Services & Resources / Wolfram Forums / MathGroup Archive
-----

MathGroup Archive 2010

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

Search the Archive

Re: FindRoots?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg112129] Re: FindRoots?
  • From: "David Park" <djmpark at comcast.net>
  • Date: Wed, 1 Sep 2010 06:27:26 -0400 (EDT)

Now that Daniel has shown the way here is a slightly reformulated form of
his routine that provides a single convenient command that should handle
most cases. The precision of the real variables in the calculation can be
specified. I don't know if the Reduce options would ever come into play
here, but I allowed for them. I also allowed control of messages from Reduce
with the default being Quiet because most of the time we wouldn't want to
see the warnings. Finally I allowed a wrapper function for Reduce for cases
such as the zeros of zeta example. 

ClearAll[RealFunctionRoots];
RealFunctionRoots::usage = 
  "RealFunctionRoots[lhs \[Equal] rhs, {var, low, high}, precision, \
messages, wrapper] will return roots of the equation in the specified \
real domain.\nprecision specifies the precision of real variables to \
be used in the calculation and display, The default is \
MachinePrecision.\nmessages is a function, default Quiet, that \
controls messages from the routine.\nwrapper is a function, default \
Identity, that wraps the Reduce statement. It can be used to \
implement extra specification for the Reduce routine.\nOptions for \
Reduce may be passed.";

Options[RealFunctionRoots] = Options[Reduce];
SyntaxInformation[
   RealFunctionRoots] = {"ArgumentsPattern" -> {_, {_, _, _}, _., _., \
_., OptionsPattern[]}};
RealFunctionRoots[equation_, {x_, low_, high_}, 
  precision : (_Integer?Positive | MachinePrecision) : 
    MachinePrecision, messagewrapper : (_Function | _Symbol) : Quiet, 
  wrapperfunction_: Identity, opts : OptionsPattern[]] :=
 Module[{work, equationp, lowp, highp},
  {equationp, lowp, highp} = {equation, low, high} /. 
    r_Real :> SetPrecision[r, precision];
  work = messagewrapper@
    wrapperfunction@Reduce[{equationp, lowp <= x <= highp}, opts];
  work = {ToRules[work]};
  N[work, precision]] 

Here are some of the examples.

f1[x_] := Sin[4 x] - (x + 1)/8
Plot[f1[x], {x, -13, 12}]
RealFunctionRoots[f1[x] == 0, {x, -13, 12}, 30]
f1[x] /. % 

f2[x_] := If[x < 3/2, Sqrt[3/2 - x] - Exp[-4 x], 2 x Exp[-x]]
Plot[f2[x], {x, -25, 25},
 PlotRange -> {{-0.5, 2.0}, {-2, 2}}]
RealFunctionRoots[f2[x] == 0, {x, -25, 25}, 30]
f2[x] /. % 

f3[x_] := Exp[x - \[Pi]] - (1 - \[Pi] + x)
Plot[f3[x], {x, -3, 4},
 PlotRange -> Automatic]
RealFunctionRoots[f3[x] == 0, {x, -3, 4}, 40]
f3[x] /. % 

f4[x_] := (1.5 - Erf[x] - Erf[2 - x]) Exp[-Abs[x - 1]]
Plot[f4[x], {x, -400, 200},
 PlotRange -> {{0, 2}, Automatic}]
RealFunctionRoots[f4[x] == 0, {x, -400, 200}, 40]
f4[x] /. % 

f5[x_] := 
 3.2 - 3 Cos[x] - Exp[-(x - 8 \[Pi])^2] - Exp[-(x - 14 \[Pi])^2]
Plot[f5[x], {x, 0, 30 \[Pi]}, PlotRange -> {{0, 30 \[Pi]}, Automatic}]
RealFunctionRoots[f5[x] == 0, {x, 0, 30 \[Pi]}, 30]
f5[x] /. % 

f6[x_] := Piecewise[{{Sqrt[Abs[x] - 1.2], x <= 1.4}}, Indeterminate]
Plot[f6[x], {x, -8, 8}, PlotRange -> {Full, {-1, 1}},
 MaxRecursion -> 4,
 PlotPoints -> 25]
RealFunctionRoots[f6[x] == 0, {x, -8, 8}, 30]
f6[x] /. % 

We might try the zeta function and find it involves a constant and doesn't
return the desired roots.

RealFunctionRoots[Zeta[1/2 + I y] == 0, {y, 0, 257}]

Then, if we were smart enough to think of Exist and Resolves, we could use
the wrapper version:

RealFunctionRoots[Zeta[1/2 + I y] == 0, {y, 0, 257}, 30, Quiet, 
 Resolve[Exists[C[1], #]] &]
Zeta[1/2 + I y] /. % // Chop[#, 10.^-27] & 

Here is a type of equation that one gets in single reaction chemical
equilibrium equations, where y is the reaction extent and 0 and 1 are the
extent boundaries for positive reactant concentrations. Using FindRoot on
such functions is quite iffy because the solution is often very close to a
boundary point and there are often non-useful roots on the other side.

RealFunctionRoots[(4 y^2)/((2 - 2 y)^2 (2 - y)) == 100000, {y, 0, 
  1}, 30]
(4 y^2)/((2 - 2 y)^2 (2 - y)) == 100000 /. % 

Just playing around of course. So don't worry Andrzej, us kiddies will stay
in the sandbox and out of the way of the real professionals.


David Park
djmpark at comcast.net
http://home.comcast.net/~djmpark/  


From: Daniel Lichtblau [mailto:danl at wolfram.com] 


David Park wrote:
> Install Ted Ersek's package RootSearch from:
> 
> http://library.wolfram.com/infocenter/MathSource/4482/ 
> 
> I don't know why Wolfram doesn't acquire the rights to this package and
> incorporate it as part of regular Mathematica. Finding all the roots of a
> real function on a 1-dimensional domain is the most common case of root
> finding, and it is the one thing regular Mathematica is very poor at.
Ted's
> package is quite robust and returns all the roots in order.
> 
> 
> David Park
> djmpark at comcast.net
> http://home.comcast.net/~djmpark/  
> 
> 
> 
> From: Sam Takoy [mailto:sam.takoy at yahoo.com] 
> 
> Hi,
> 
> Is there a command for numerically finding all roots of a function in a 
> given interval. If not, what's the best way of accomplishing this task?
> 
> Many thanks in advance,
> 
> Sam

If I instead define RootSearch to use Reduce, as below, it handles quite 
well all the examples from the Examples section of 
RootSearchExamples.nb. I show them below. I modified one to use 
Piecewise instead of a condition, and for the last I use Reduce directly 
to get an expanded form of the solution set.

I think Mathematica is quite good at this sort of thing, actually.

Daniel Lichtblau
Wolfram Research

-------------------------------

In[33]:= RootSearch[
   eqn_, {x_, lo_, hi_}] := {ToRules[Reduce[{eqn, lo <= x <= hi}]]}

In[34]:= f1[x_] := Sin[4 x] - (x + 1)/8
RootSearch[f1[x] == 0, {x, -13, 12}]

Out[35]= {{x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, -8.3482893782997216496}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, -8.1289315341182707392}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, -6.8629511940895252882}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, -6.4714706256130258036}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, -5.3539165396979340111}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, -4.8374622685220237568}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, -3.8363831890811367726}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, -3.21161777565464349626}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, -2.3149160596763252331}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, -1.58922633877627429127}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, -0.79190196071777069054}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, 0.032351189053103634282}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, 0.73087710353047892233}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, 1.65538160232955244046}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, 2.2515547207396359640}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, 3.2828240626757282491}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, 3.7673870629720211202}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, 4.9206885635879098258}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, 5.2724915094753945872}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, 6.5961054327905341135}]}, {x ->
    Root[{1 - 8 Sin[4 #1] + #1 &, 6.7398184613474433969}]}}

In[36]:= f2[x_] := If[x < 3/2, Sqrt[3/2 - x] - Exp[-4 x], 2* x Exp[-x]]
RootSearch[f2[x] == 0, {x, -25, 25}]

Out[37]= {{x ->
    Root[{-Sqrt[2] +
        E^(4 #1) Sqrt[3 - 2 #1] &, -0.055200564731044670903}]}, {x ->
    Root[{-Sqrt[2] + E^(4 #1) Sqrt[3 - 2 #1] &,
      1.49999385548561363888}]}}

In[38]:= RootSearch[Exp[x - \[Pi]] == 1 - \[Pi] + x, {x, -3, 4}]

Out[38]= {{x -> \[Pi]}}

In[39]:= f4[x_] := (1.5 - Erf[x] - Erf[2 - x]) Exp[-Abs[x - 1]]
RootSearch[f4[x] == 0, {x, -400, 200}]

During evaluation of In[39]:= Reduce::ratnz: Reduce was unable to solve 
the system with inexact coefficients. The answer was obtained by solving 
a corresponding exact system and numericizing the result. >>

Out[40]= {{x -> 0.517891}, {x -> 1.48211}}

In[41]:= f5[x_] :=
  3.2 - 3*Cos[x] - Exp[-(x - 8 \[Pi])^2] - Exp[-(x - 14 \[Pi])^2]
s5 = RootSearch[f5[x] == 0, {x, 0, 30 \[Pi]}]

During evaluation of In[41]:= Reduce::ratnz: Reduce was unable to solve 
the system with inexact coefficients. The answer was obtained by solving 
a corresponding exact system and numericizing the result. >>

Out[42]= {{x -> 24.5432}, {x -> 25.7223}, {x -> 43.3928}, {x ->
    44.5718}}

In[43]:= f6[x_] :=
  Piecewise[{{ Sqrt[Abs[x] - 1.2], x <= 1.4}}, Indeterminate]
RootSearch[f6[x] == 0, {x, -8, 8}]

During evaluation of In[43]:= Reduce::ratnz: Reduce was unable to solve 
the system with inexact coefficients. The answer was obtained by solving 
a corresponding exact system and numericizing the result. >>

Out[44]= {{x -> -1.2}, {x -> 1.2}}

In[45]:= RootSearch[Zeta[1/2 + I y] == 0, {y, 0, 237}]

Out[45]= {ToRules[
   C[1] \[Element] Integers && 1 <= C[1] <= 100 &&
    y == -(1/2) I (-1 + 2 ZetaZero[C[1]])]}

In[48]:= explicitsol =
  Resolve[Exists[C[1],
    Reduce[{Zeta[1/2 + I y] == 0, 0 <= y <= 237}, y]]]

Out[48]= y == Im[ZetaZero[1]] || y == Im[ZetaZero[2]] ||
  y == Im[ZetaZero[3]] || y == Im[ZetaZero[4]] ||
  y == Im[ZetaZero[5]] || y == Im[ZetaZero[6]] ||
  y == Im[ZetaZero[7]] || y == Im[ZetaZero[8]] ||
  y == Im[ZetaZero[9]] || y == Im[ZetaZero[10]] ||
  y == Im[ZetaZero[11]] || y == Im[ZetaZero[12]] ||
  y == Im[ZetaZero[13]] || y == Im[ZetaZero[14]] ||
  y == Im[ZetaZero[15]] || y == Im[ZetaZero[16]] ||
  y == Im[ZetaZero[17]] || y == Im[ZetaZero[18]] ||
  y == Im[ZetaZero[19]] || y == Im[ZetaZero[20]] ||
  y == Im[ZetaZero[21]] || y == Im[ZetaZero[22]] ||
  y == Im[ZetaZero[23]] || y == Im[ZetaZero[24]] ||
  y == Im[ZetaZero[25]] || y == Im[ZetaZero[26]] ||
  y == Im[ZetaZero[27]] || y == Im[ZetaZero[28]] ||
  y == Im[ZetaZero[29]] || y == Im[ZetaZero[30]] ||
  y == Im[ZetaZero[31]] || y == Im[ZetaZero[32]] ||
  y == Im[ZetaZero[33]] || y == Im[ZetaZero[34]] ||
  y == Im[ZetaZero[35]] || y == Im[ZetaZero[36]] ||
  y == Im[ZetaZero[37]] || y == Im[ZetaZero[38]] ||
  y == Im[ZetaZero[39]] || y == Im[ZetaZero[40]] ||
  y == Im[ZetaZero[41]] || y == Im[ZetaZero[42]] ||
  y == Im[ZetaZero[43]] || y == Im[ZetaZero[44]] ||
  y == Im[ZetaZero[45]] || y == Im[ZetaZero[46]] ||
  y == Im[ZetaZero[47]] || y == Im[ZetaZero[48]] ||
  y == Im[ZetaZero[49]] || y == Im[ZetaZero[50]] ||
  y == Im[ZetaZero[51]] || y == Im[ZetaZero[52]] ||
  y == Im[ZetaZero[53]] || y == Im[ZetaZero[54]] ||
  y == Im[ZetaZero[55]] || y == Im[ZetaZero[56]] ||
  y == Im[ZetaZero[57]] || y == Im[ZetaZero[58]] ||
  y == Im[ZetaZero[59]] || y == Im[ZetaZero[60]] ||
  y == Im[ZetaZero[61]] || y == Im[ZetaZero[62]] ||
  y == Im[ZetaZero[63]] || y == Im[ZetaZero[64]] ||
  y == Im[ZetaZero[65]] || y == Im[ZetaZero[66]] ||
  y == Im[ZetaZero[67]] || y == Im[ZetaZero[68]] ||
  y == Im[ZetaZero[69]] || y == Im[ZetaZero[70]] ||
  y == Im[ZetaZero[71]] || y == Im[ZetaZero[72]] ||
  y == Im[ZetaZero[73]] || y == Im[ZetaZero[74]] ||
  y == Im[ZetaZero[75]] || y == Im[ZetaZero[76]] ||
  y == Im[ZetaZero[77]] || y == Im[ZetaZero[78]] ||
  y == Im[ZetaZero[79]] || y == Im[ZetaZero[80]] ||
  y == Im[ZetaZero[81]] || y == Im[ZetaZero[82]] ||
  y == Im[ZetaZero[83]] || y == Im[ZetaZero[84]] ||
  y == Im[ZetaZero[85]] || y == Im[ZetaZero[86]] ||
  y == Im[ZetaZero[87]] || y == Im[ZetaZero[88]] ||
  y == Im[ZetaZero[89]] || y == Im[ZetaZero[90]] ||
  y == Im[ZetaZero[91]] || y == Im[ZetaZero[92]] ||
  y == Im[ZetaZero[93]] || y == Im[ZetaZero[94]] ||
  y == Im[ZetaZero[95]] || y == Im[ZetaZero[96]] ||
  y == Im[ZetaZero[97]] || y == Im[ZetaZero[98]] ||
  y == Im[ZetaZero[99]] || y == Im[ZetaZero[100]]

In[49]:= N[explicitsol]

Out[49]= y == 14.1347 || y == 21.022 || y == 25.0109 || y == 30.4249 ||
   y == 32.9351 || y == 37.5862 || y == 40.9187 || y == 43.3271 ||
  y == 48.0052 || y == 49.7738 || y == 52.9703 || y == 56.4462 ||
  y == 59.347 || y == 60.8318 || y == 65.1125 || y == 67.0798 ||
  y == 69.5464 || y == 72.0672 || y == 75.7047 || y == 77.1448 ||
  y == 79.3374 || y == 82.9104 || y == 84.7355 || y == 87.4253 ||
  y == 88.8091 || y == 92.4919 || y == 94.6513 || y == 95.8706 ||
  y == 98.8312 || y == 101.318 || y == 103.726 || y == 105.447 ||
  y == 107.169 || y == 111.03 || y == 111.875 || y == 114.32 ||
  y == 116.227 || y == 118.791 || y == 121.37 || y == 122.947 ||
  y == 124.257 || y == 127.517 || y == 129.579 || y == 131.088 ||
  y == 133.498 || y == 134.757 || y == 138.116 || y == 139.736 ||
  y == 141.124 || y == 143.112 || y == 146.001 || y == 147.423 ||
  y == 150.054 || y == 150.925 || y == 153.025 || y == 156.113 ||
  y == 157.598 || y == 158.85 || y == 161.189 || y == 163.031 ||
  y == 165.537 || y == 167.184 || y == 169.095 || y == 169.912 ||
  y == 173.412 || y == 174.754 || y == 176.441 || y == 178.377 ||
  y == 179.916 || y == 182.207 || y == 184.874 || y == 185.599 ||
  y == 187.229 || y == 189.416 || y == 192.027 || y == 193.08 ||
  y == 195.265 || y == 196.876 || y == 198.015 || y == 201.265 ||
  y == 202.494 || y == 204.19 || y == 205.395 || y == 207.906 ||
  y == 209.577 || y == 211.691 || y == 213.348 || y == 214.547 ||
  y == 216.17 || y == 219.068 || y == 220.715 || y == 221.431 ||
  y == 224.007 || y == 224.983 || y == 227.421 || y == 229.337 ||
  y == 231.25 || y == 231.987 || y == 233.693 || y == 236.524




  • Prev by Date: Re: FindRoots?
  • Next by Date: Re: Working with Log
  • Previous by thread: Re: FindRoots?
  • Next by thread: Re: FindRoots?