1
$\begingroup$

I would like to have a series of functions that depend one another, indexed by a number, and that are defined via a Do loop. However, Mathematica seems unable to replace the index in the loop. My trial code:

Do[
  If[i == 1,
    ff[i, x_, y_] := x + y;,
    ff[i, x_, y_] := (x - y)*ff[i - 1, x, y];
    ];
  , {i, 1, 2}];
ff[2, x, y]

Output: (x - y) ff[-1 + i, x, y]

Desired output is however: (x - y)(x + y)

This thing surprises me since if I manually define

ff[2, x_, y_] := (x - y)*ff[1, x, y];

then I get the desired output. It seems that the Do loop is not replacing inside the function.

Is this normal? :-o

$\endgroup$

1 Answer 1

4
$\begingroup$

In your Do loop use Set rather than SetDelayed for the RHS to be evaluated.

Clear["Global`*"]

Using RSolve to directly obtain a closed-form solution for the nth function

ff[n_, x_, y_] = 
 f[n] /. RSolve[{f[1] == x + y, f[n] == (x - y)*f[n - 1]}, f[n], n][[1]]

(* (x - y)^(-1 + n) (x + y) *)

Alternatively, using explicit recursion

f2[1] = x + y;
f2[n_] := f2[n] = (x - y)*f2[n - 1]

Generating a sequence from the recursion

seq = f2 /@ Range[5]

(* {x + y, (x - y) (x + y), (x - y)^2 (x + y), (x - y)^3 (x + y), 
    (x - y)^4 (x + y)} *)

Then using FindSequenceFunction to generalize from the sequence, the result is identical to that provided by RSolve

FindSequenceFunction[seq, n] === ff[n, x, y]

(* True *)
$\endgroup$
2
  • $\begingroup$ Thanks. Nice solution but I think it's too much writing for such a simple thing. All this is really weird in Mathematica (IMHO). In any standard programming language the set-delayed involves only the parameters of a function (the ones with underscore, here). The rest is replaced instantaneously. Sometimes Evaluate[..] helps, but here Evaluate[i-1] does not. I found a simplest solution with: Do[ If[i == 1, ff[i, x_, y_] := x + y;, pp = i; ff[i, x_, y_] := (x - y)*ff[pp - 1, x, y]; ]; , {i, 1, 2}]; ff[2, x, y] which I think it forces the i-replacement. $\endgroup$
    – Wizzerad
    May 4, 2021 at 17:57
  • $\begingroup$ I don't understand your objection. ff[n_, x_, y_] = f[n] /. RSolve[{f[1] == x + y, f[n] == (x - y)*f[n - 1]}, f[n], n][[1]] is shorter than your code, works for arbitrary n, and is more efficient. The remainder of the post was just to demonstrate an alternate approach. $\endgroup$
    – Bob Hanlon
    May 4, 2021 at 18:09

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.