0
$\begingroup$

This question is related to Mathematica and Math. I am trying to set up equation most effectively to find roots at optimum speed. The following equation is an example of original complicated equation that has similar properties:

equation (1):

$ (1+ \frac{(a+ \frac{x-b}{\sqrt{x+c}})}{x+d} )* (1+ \frac{(a- \frac{x+b}{\sqrt{x-c}})}{x-d} ) -e*f*x^2+g= 0 $

I was able to solve for roots of x (more than 4 roots) in above form using NSolve command. But for one particular constant parameters such as c with a nonzero value , the NSolve is stuck in search mode.

ClearAll;
f[a_,b_,c_,d_,e_,f_,g_]=(1+(a+(x-b)/Sqrt[x+c])/(x+d))*(1+(a+(x+b)/Sqrt[x-c])/(x-d))-e*f*x^2+g;
solution=Table[x/.NSolve[f[0.1,0.1,0.2,1,2,0.5,ii]==0,x],{ii,0,5}]

I noticed that the equation (1) is not in polynomial form because of square-roots in it and denominators. I though I should expand the equation and square it twice to get rid of square-roots. Below is an another example equation to illustrate the point of square-root elimination (not from the same equation as above):

equation(2):

$x^2*a + \sqrt{x+c}-b*(x+d)=0$

rearanging and squaring:

$ \sqrt{x+c}=b*(x+d)-x^2*a $

${x+c}=(b*(x+d)-x^2*a)^2 $

equation(3):

$-(b*(x+d))^2+2*b*(x+d)*x^2*a+{x+c}-(x^2*a)^2=0 $

The equation (3) is in polynomial form. But its number of roots has increased. Therefore its number of roots is not the same as in number of roots in altered equation (2). Therefore if I search for roots my answer will be different due to which equation form I use (1 or 2). So I have few questions:

A) Equation (1) has four distinct denominators in it. Before using NSolve should I keep those denominators or eliminate them? Which one gives me a correct answer? My understanding is that root finding applies for numerators only therefore denominators should be eliminated.

B) Equation (1) is not in polynomial form because of square-roots present. When using NSolve, should I use equation (2) "form" or equation (3) "form" as a correct approach to get "correct" answer.

C) Any suggestions on how to optimize equation to speed up the root finding. Any options in NSolve that should be disabled? Perhaps there is another approach instead NSolve? I noticed that equation (3) helps speeding up NSolve but gives me more roots and I have not clue if that is correct or not?

My approach is to get roots numerically because original equation is too complicated for symbolic approach.

Mathematica V.9

Thanks in advance.

$\endgroup$
  • 1
    $\begingroup$ What are the variables? What are constants? Although pretty-printed in LaTeX, Mathematica code would be much more useful. Are a, b, c, d numerical numbers or symbolic? With symbolic parameters, you should Solve. With numerical parameters, you can try FindRoot to perform Newton search with several not too bad starting values. For better speed, check the documentation on how to provide the derivative of the system to solve with the option Jacobian. $\endgroup$ – Henrik Schumacher Jul 5 '17 at 15:43
  • 2
    $\begingroup$ By the way: The equation (1) is nicely factorized. Find the roots of each factor separately. $\endgroup$ – Henrik Schumacher Jul 5 '17 at 15:49
  • $\begingroup$ @Henrik Schumacher, Thanks for comments. I updated the post to clarify your questions. I added Mathematica code to illustrate my approach of solving equation for roots. My original equation is too complicated to be solved using Solve. I am better off doing it by hand which is tedious and prone to mistakes or numerically. 'FindRoot' finds only one root. I usually get both real and complex roots. I have never heard of option Jacobian. I will look into it. I updated equation (1). Original is not nicely factorized. $\endgroup$ – Aschoolar Jul 5 '17 at 22:23
  • 1
    $\begingroup$ So, NSolve resolves all your problems. Number crunching is so fast, no preprocessing needed. By the way, you can enforce computing only the real solutions with solution = Table[x /. NSolve[f[0.1, 0.1, 0.2, 1, 2, 0.5, ii] == 0, x, Reals], {ii, 0, 5}]. $\endgroup$ – Henrik Schumacher Jul 5 '17 at 22:52
3
$\begingroup$

A way to speed up calculations by a factor of almost 100:

  1. NSolve with inexact coefficients runs into problems

    Table[x /. 
       NSolve[f[0.1, 0.1, 0.2, 1, 2, 0.5, ii] == 0, x, Reals], {ii, 0, 
          5}] // Timing
    
    (*    Solve::ratnz: Solve was unable to solve the system with 
          inexact coefficients. The answer was obtained by solving a 
          corresponding exact system and numericizing the result. >>   *)
    
  2. Rationalize works, but is even very slow

    Table[x /. 
      NSolve[Rationalize[f[0.1, 0.1, 0.2, 1, 2, 0.5, ii], 0] == 0, x, 
        Reals], {ii, 0, 5}] // Timing
    
    (*     {51.25, {{1.98221}, {2.15013}, {0.231335, 0.476794, 
                2.32108}, {0.215009, 0.583343, 2.49073}, {0.209054, 0.652955, 
                2.65666}, {0.206106, 0.702943, 2.81773}}}     *)
    
  3. Solving not only for Reals, but for all solutions and then deleting complex solutions, is by a factor of 90 faster!

    Table[DeleteCases[
        x /. NSolve[f[0.1, 0.1, 0.2, 1, 2, 0.5, ii] == 0, 
                x], _Complex], {ii, 0, 5}] // Timing
    
    (*     {0.578, {{1.98221}, {2.15013}, {2.32108, 0.476794, 
             0.231335}, {2.49073, 0.583343, 0.215009}, {2.65666, 0.652955, 
             0.209054}, {2.81773, 0.702943, 0.206106}}}     *)
    
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.