# Creating recursive functions using SetDelayed and MapThread

EDIT: I have slightly modified the question to include recursive function.

I want to create some recursive functions using SetDelayed within MapThread.

MapThread[SetDelayed, {{c[x_],f[y_]}, {c[x] = Simplify[x^2 + 3*x - x*(2*x - 7) + c[x - 1]],f[y] = Simplify[E^y - 5*y^2 + y*(y - 1) + f[y + 1]]}}];


As expected it simplifies first then applies SetDelayedwith the LHS. But I like to have outputs like the followings

c[x_] := c[x] = Simplify[x^2 + 3 x - x (2 x - 7) + c[x - 1]]
f[y_] := f[y] = Simplify[E^y - 5 y^2 + y (y - 1) + f[y + 1]]


How is it possible to keep Simplify[] unevaluated in MapThread[]? For better understanding I have also attached a screen shot. As seen from the picture, the recursive function definition is also quite different while using MapThread[].

Using MapThread[] is the right idea; using it twice is a little wasteful, when you can use a three-argument function instead to set up the memoization:

Remove[c, f];
MapThread[(#1 := (#2 = #3)) &,
{{c[x_], f[x_]}, {c[x], f[x]},
{x^2 + 3 x - x (2 x - 7) + c[x - 1], E^x - 5 x^2 + x (x - 1) + f[x + 1]}}]


If the Simplify[] is necessary:

MapThread[(#1 := (#2 = Simplify[#3])) &,
{{c[x_], f[x_]}, {c[x], f[x]},
{x^2 + 3 x - x (2 x - 7) + c[x - 1], E^x - 5 x^2 + x (x - 1) + f[x + 1]}}]


and this approach is of course easily extensible:

MapThread[(#1 := (#2 = #3[#4])) &,
{{c[x_], f[x_]}, {c[x], f[x]}, {Expand, Simplify},
{x^2 + 3 x - x (2 x - 7) + c[x - 1], E^x - 5 x^2 + x (x - 1) + f[x + 1]}}]

• Thanks a lot. This is really the correct way of writing a code. – Soumyajit Roy Aug 30 '19 at 9:32

RSolve can provide the closed-form definitions of c and f

Clear["Global*"]


The recursive definitions for c and f are

cr = c0;
cr[x_Integer?Positive] := cr[x] = Simplify[
x^2 + 3 x - x (2 x - 7) + cr[x - 1]];
cr[x_Integer?Negative] := cr[x] = Simplify[
cr[x + 1] - (x + 1)^2 - 3 (x + 1) + (x + 1) (2 (x + 1) - 7)];

fr = f0;
fr[x_Integer?Positive] := fr[x] = Simplify[
fr[x - 1] - E^(x - 1) + 5 (x - 1)^2 - (x - 1) (x - 2)];
fr[x_Integer?Negative] := fr[x] = Simplify[
E^x - 5 x^2 + x (x - 1) + fr[x + 1]];


Using RSolve to obtain the closed-form expressions

sol = RSolve[{c[x] == x^2 + 3 x - x (2 x - 7) + c[x - 1],
f[x] == E^x - 5 x^2 + x (x - 1) + f[x + 1],
c == c0, f == f0}, {c[x], f[x]}, x][] //
FullSimplify;

c[x_] = c[x] /. sol

(* c0 - 1/6 x (1 + x) (-29 + 2 x) *)

f[x_] = f[x] /. sol

(* (1/(6 (-1 + E)))(6 - 6 E^x - 6 f0 + x (-1 + (9 - 8 x) x) +
E (6 f0 + (-1 + x) x (-1 + 8 x))) *)


Checking that the recursive and closed-forms are equivalent for integer arguments

And @@ Table[c[x] == cr[x] && f[x] == fr[x], {x, -20, 20}] // Simplify

(* True *)


Plotting with c0 == 0 and f0 == 0

Show[
Plot[
Evaluate[{c[x], f[x]} /. {c0 -> 0, f0 -> 0}],
{x, -5, 5},
PlotRange -> All,
PlotLegends -> Placed[{c, f}, {0.6, 0.8}]],
DiscretePlot[{
cr[x] /. {c0 -> 0, f0 -> 0},
fr[x] /. {c0 -> 0, f0 -> 0}},
{x, -5, 5},
PlotStyle ->
{Darker@Blue, {Thick, Orange, Dashed}}]] • Thank you for your answer. However, I do not want to solve the recursive function. Actually I have a list of expressions which have come from series of calculation and are stored in a variable, say exp. I want to use each of those expressions enclosed within Simplify[] to create recursive functions which will be used in subsequent calculation. I believe Simplify[] will make the expression of f[n] much simplified prior to using it for the calculation of f[n+1]. Hence, I posted a simple example only for seeking solution to the problem. – Soumyajit Roy Aug 29 '19 at 19:06

This could be a possible solution

ClearAll["Global*"]
Ex = {x^2 + 3 x - x (2 x - 7) + c[x - 1],
E^x - 5 x^2 + x (x - 1) + f[x + 1]}; 