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$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.