5

I am trying to solve a system of equations which is dependent to an parameter alpha. So I iterate over alpha via a Table call and try to back substitute the solution found in iteration i into the FindRoot call. My example leads to an infinite recursion.

sols = {x -> 0, y -> 0}
Table[ {sol = FindRoot[{alpha x == 0, y x = 3 }, sol[[1, 2]], {alpha, 1, 10}]

Heike’s suggestion works perfectly for one parameter.

I tried to extend this for two parameters, but I failed.

sols = {x -> 0, y -> 0}
eqns := {alpha x == 0, y x = 3}
Table[sol = FindRoot[eqns, {x, sol[[1, 2]], y, sol[[3, 4]]}], {alpha, 1, 10}]

how can I access the solution of y correctly?

Verbeia
  • 34,233
  • 9
  • 109
  • 224
Martin
  • 51
  • 1
  • 2
  • two syntax errors in your current code: First, sol does not have part [[3,4]]. The parts for the values of x and y are sol[[1,2]] and sol[[2,2]], respectively. Second, the second argument of FindRoot should be list of lists, e.g., {{x,0.},{y,.5}}. – kglr Mar 15 '12 at 03:52

3 Answers3

6

You can use FoldList or NestList to use the solution of a step as the starting value for the next step. Please check the documentation on these two functions for detailed examples of how they are used.

  FoldList[FindRoot[{#2 x == 1, y x == #2/2},{{x, #1[[1, 2]]}, {y, #1[[2, 2]]}}] &,
  {x -> 0.5, y -> 0.5}, Range@10]

It gives:

{{x -> 0.5, y -> 0.5}, {x -> 1., y -> 0.5}, {x -> 0.5, y -> 2.}, 
  {x -> 0.333333, y -> 4.5}, {x -> 0.25, y -> 8.}, {x -> 0.2, y -> 12.5}, 
  {x -> 0.166667, y -> 18.}, {x -> 0.142857, y -> 24.5}, 
  {x -> 0.125, y -> 32.}, {x -> 0.111111, y -> 40.5}, {x -> 0.1, y -> 50.}}

NestList is a little more complicated:

  NestList[
  {#[[1]] + 1, FindRoot[{(#[[1]] + 1)  x == 1, y x == (#[[1]] + 1)/2}, 
  {{x, #[[2, 1, 2]]}, {y, #[[2, 2, 2]]}}]} &, 
  {0, {x -> 0.5, y -> 0.5}}, 10]

which produces

 {{0, {x -> 0.5, y -> 0.5}}, {1, {x -> 1., y -> 0.5}}, {2, {x -> 0.5,y -> 2.}}, 
   {3, {x -> 0.333333, y -> 4.5}}, {4, {x -> 0.25, y -> 8.}}, 
   {5, {x -> 0.2, y -> 12.5}}, {6, {x -> 0.166667, y -> 18.}}, 
   {7, {x -> 0.142857, y -> 24.5}}, {8, {x -> 0.125, y -> 32.}}, 
   {9, {x -> 0.111111, y -> 40.5}}, {10, {x -> 0.1, y -> 50.}}}

You can get the second parts of the rows by adding the following code at the end:

  NestList[...] // Last /@ # &
kglr
  • 394,356
  • 18
  • 477
  • 896
3

When you put

sols={};

then calling

 FindRoot[alpha x == 1, Drop[sols, Length[sols]]

you get

FindRoot::fdss: "Search specification {} should be a list with 1 to 5 elements."

because the second argument in FindRoot does not have one of the expected forms :
neither FindRoot[alpha x == 1, x] nor FindRoot[alpha x == 1, {x,x0}], where x0 denotes the point where FindRoot starts to find a numerical solution. Consequentely you get this message

$RecursionLimit::reclim: Recursion depth of 256 exceeded

because the variable does not have a value, even FindRoot doesn't know with respect to which variable to solve equations.

Edit

When you deal with two variables to be found, you can proceed along this route :

sol  = {x -> 0.5, y -> 0.5};
sols = Table[ FindRoot[ {alpha x == 1, y x == alpha/2}, 
                       {{x, sol[[1, 2]]}, {y, sol[[2, 2]]}}],
              {alpha, 1, 10}];
sols 
{{x -> 1.,      y -> 0.5 }, {x -> 0.5, y -> 2.  }, {x -> 0.333333, y -> 4.5}, 
{x -> 0.25,     y -> 8.  }, {x -> 0.2, y -> 12.5}, {x -> 0.166667, y -> 18.}, 
{x -> 0.142857, y -> 24.5}, {x -> 0.125, y -> 32.},
{x -> 0.111111, y -> 40.5}, {x -> 0.1,   y -> 50.}}

Otherwise, putting initial values where e.g. sol = {x -> 0, y -> 0}; FindRoot fails because the system is singular. In order to track evaluating of an expression, it recommended to use Trace, e.g. :

Table[ FindRoot[ { alpha x == 1, y x == alpha/2 }, 
       {{ x, sol[[1, 2]] }, { y, sol[[2, 2]] }}  ],
       {alpha, 1, 10}] // Trace
Artes
  • 57,212
  • 12
  • 157
  • 245
0

You could do something like this

sol = {x -> 0};
sols = Table[sol = FindRoot[alpha x == 1, {x, sol[[1, 2]]}], {alpha, 1, 10}]
Heike
  • 35,858
  • 3
  • 108
  • 157