2
$\begingroup$

The following is a simplified version of a more detailed problem.

I have two coupled recursion equations of two variables, x and y. One equation also depends on a parameter, c:

F[x_, y_] := x + y - c
G[x_, y_] := y/x

Starting with initial conditions, {x[0],y[0]}, I want to iterate these equations to convergence (in the real problem they always converge) for each of a range of c values (c=1, c=2, c=3, .... c=cmax). So, the result I want is a list of ordered pairs, {{x1,y1},{x2,y2},....}, where {xi,yi} are the values that x and y converge to for c=i.

If I globally define e.g. c=1 and assume that e.g. {x[0],y[0]}={3,2}, I can get a result like this (assuming convergence within 10 iterations just for demonstration):

c = 1;
F[x_, y_] := x + y - c
G[x_, y_] := y/x
Iter[x_, y_] := Nest[Apply[Through[{F, G}@##] &], {x, y}, 10] // N
Iter[3, 2]

Presumably I could use this approach in a For loop over c values to get what I want but I would rather write a function that can be threaded over a list of c values. The idea is that for each c value input, the function iterates x and y to convergence, so x and y vary while c is constant. I tried to do this by locally defining c using With, like so:

F[x_, y_] := x + y - c
G[x_, y_] := y/x
Iter[i_, x_, y_] := 
 With[{c = i}, Nest[Apply[Through[{F, G}@##] &], {x, y}, 10] // N]
Iter[1, 3, 2]

but for some reason this doesn't set c to i. Using Module instead of With doesn't work either. Is there a better approach to this kind of thing or maybe just some syntactic error here?

$\endgroup$

2 Answers 2

2
$\begingroup$

Probably this:

Iter[i_, x_, y_] := With[{c = i},
  F[x1_, y1_] := x1 + y1 - c;
  G[x1_, y1_] := y1/x1; 
  Nest[Apply[Through[{F, G}@##] &], {x, y}, 10] // N]
Iter[1, 3, 2]

{-4.13656, 0.0134278}

$\endgroup$
2
$\begingroup$

One (less desirable) fix is to use Block rather than With:

F[x_, y_] := x + y - c;
G[x_, y_] := y/x;
Iter[i_, x_, y_] := Block[{c = i}, Nest[Apply[Through[{F, G}@##] &], {x, y}, 10] // N];

(This is less desirable because it's still vulnerable to side effects.)

A more fully functional style would be to parameterize F:

F[c_][x_, y_] := x + y - c;
G[x_, y_] := y/x;
Iter[c_, x_, y_] := Nest[Apply[Through[{F[c], G}@##] &], {x, y}, 10] // N;

(Also, side note, you might like Comap or ComapApply--it would simplify your Apply+Through strategy.)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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