7
$\begingroup$

This is my code:

ClearAll[f, g]

f[x_] := x^3

g[h_, x_] := h[x] - h[x + 1]

g[f, x]
(* x^3 - (1 + x)^3 *)

g[g[f, x], x]
(* (x^3 - (1 + x)^3)[x] - (x^3 - (1 + x)^3)[1 + x] *)

r[x_] = g[f, x]
(* x^3 - (1 + x)^3 *)

g[r, x]
(* x^3 - 2 (1 + x)^3 + (2 + x)^3 *)

g[f,x] outputs what I'd expect. However, if I try g[g[f,x],x], I don't get the expected result.

I think I see why; g[f,x] is producing an equation, whereas I believe I need a function head?

The last two lines gives the correct result ( x^3 - 2 (1 + x)^3 + (2 + x)^3) by defining r[x] as the output of g[f,x] and then calculating g[r,x], but I am looking to reperform this recursively and so this solution doesn't easily work, and in any case is clunky. I'm sure there must be a neat elegant solution to allow me to use something like g[g[f,x],x] or NestList, but I'm not seeing it.

$\endgroup$

5 Answers 5

5
$\begingroup$

This is just an extension of @Domen's answer.

The semantics of what you're doing is Nest. You're nesting to create function composition that you can apply to an argument, but it's still nesting. You're wanting to nest your g function twice with an initial argument of f. So, as Domen showed, what you want is to get this expression to work:

Nest[g, f, 2][x]

Sometimes it's helpful to see the structure of things using dummy symbols, so look at this (or just clear all your symbols and look at what the above produces):

Nest[gg, ff, 2][x]
(* gg[gg[ff]][x] *)

So, what we need gg to be is a function that takes a function and returns another function. Again, Domen showed you two ways to do this, but another way that parallels directly the expression above is to use SubValues:

gg[fn_][arg_] := fn[arg] - fn[arg + 1]

Now evaluate that expression above again:

Nest[gg, ff, 2][x]
(* ff[x] - 2 ff[1 + x] + ff[2 + x] *)

And with your f:

f[x_] := x^3;

Nest[gg, f, 2][x]
(* x^3 - 2*(1 + x)^3 + (2 + x)^3 *)

But, you can also use CurryApplied to make your original g into the kind of function you need (so no need to redefine your functions at all):

g[h_, x_] := h[x] - h[x + 1];
f[x_] := x^3;

Nest[CurryApplied[g, 2], f, 2][x]
(* x^3 - 2*(1 + x)^3 + (2 + x)^3 *)

It might be instructive to look at

Nest[CurryApplied[g, 2], f, 2]
(* CurryApplied[g, 2][CurryApplied[g, 2][f]] *)
$\endgroup$
6
$\begingroup$

You have correctly identified the problem. In the first iteration, you give f as the first argument to g, and then you can apply f to x. However, the result is now an expression containing x, which cannot be applied to the argument anymore.

Here are two possible ways to redefine your functions.

  1. Using ReplaceAll.
ClearAll[f, g]

f[x_] := x^3;
g[h_, x_] := h - (h /. x -> x + 1);

g[f[x], x]
(* x^3 - (1 + x)^3 *)

g[g[f[x], x], x]
(* x^3 - 2 (1 + x)^3 + (2 + x)^3 *)

Nest[g[#, x] &, f[x], 5]
(* x^3 - 5 (1 + x)^3 + 10 (2 + x)^3 - 10 (3 + x)^3 + 5 (4 + x)^3 - (5 + x)^3 *)
  1. Using pure functions.
ClearAll[f, g]

f[x_] := x^3;
g[h_] := Function[Evaluate[(h[#] - h[# + 1])]];

g[f][x]
(* x^3 - (1 + x)^3 *)

g[g[f]][x]
(* x^3 - 2 (1 + x)^3 + (2 + x)^3 *)

Nest[g, f, 5][x]
(* x^3 - 5 (1 + x)^3 + 10 (2 + x)^3 - 10 (3 + x)^3 + 5 (4 + x)^3 - (5 + x)^3 *)
$\endgroup$
4
$\begingroup$

Or, maybe, as a convenient workaround:

g[g[f, #] &, #] &[x]

(* x^3 - 2 (1 + x)^3 + (2 + x)^3 *)

A 'slot free' version

(CurryApplied[g, 2]@CurryApplied[g, 2][f])[x]

(* x^3 - 2 (1 + x)^3 + (2 + x)^3 *) 

Or, as already pointed out by lericr, with Nest

Nest[CurryApplied[g, 2], f, 2][x]

(* x^3 - 2 (1 + x)^3 + (2 + x)^3 *) 

And

Nest[CurryApplied[g, 2], f, #][x] & /@ Range[5]

(* {

   x^3 - (1 + x)^3, 
   x^3 - 2 (1 + x)^3 + (2 + x)^3, 
   x^3 - 3 (1 + x)^3 + 3 (2 + x)^3 - (3 + x)^3, 
   x^3 - 4 (1 + x)^3 + 6 (2 + x)^3 - 4 (3 + x)^3 + (4 + x)^3, 
   x^3 - 5 (1 + x)^3 + 10 (2 + x)^3 - 10 (3 + x)^3 + 5 (4 + x)^3 - (5 + x)^3

} *)
$\endgroup$
3
$\begingroup$
  • Define g as an operator T which act on the function h.
Clear["Global`*"];
f[x_] := x^3;
T[h_][x_] := Minus@DifferenceDelta[h[x], x];
list = NestList[T, f, 3]
Through[list@x]

{f, T[f], T[T[f]], T[T[T[f]]]}

{x^3, -1 - 3 x - 3 x^2, 6 + 6 x, -6}

  • Since the definition is h[x]-h[x+1] instead of h[x+1]-h[x], it can not directly use DifferenceDelta[h[x],{x,n}] for n.
$\endgroup$
2
$\begingroup$

Another workaround is to use Composition as follows:

f[x_] := x^3;
g[h_] := Function[x, h[x] - h[x + 1]];

(g@*g)[f][x]

x^3 - 2 (1 + x)^3 + (2 + x)^3

Alternatively, use Fold with your definitions for f and g:

f[x_] := x^3;
g[h_, x_] := h[x] - h[x + 1];
G = Function[h, Function[x, g[h, x]]];

Fold[G, f, Array[g &, 2]][x]

x^3 - 2 (1 + x)^3 + (2 + x)^3

$\endgroup$

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.