# How to obtain the gradient of a function as a function?

The Grad function allows me to get the gradient of a function like this:

In:=
Grad[#1 + #2^2 &[x, y], {x, y}]
Out:=
{1, 2 y}


The gradient is expressed in terms of the symbols x and y that I provided. However I would like to get the gradient in this form, as a function:

{1, 2 #2}&


Operations such as this that act on functions, rather than variables, are known in mathematics as operators. Gradient is an operator.

Being an anti-obfuscatorian by nature, I recommend

f[x_, y_] = Grad[Function[{x, y}, x + y^2][x, y], {x, y}];


or

g[x_, y_] = Grad[#1 + #2^2 &[x, y], {x, y}];


Then

Through[{f, g}[u, v]]


{{1, 2 v}, {1, 2 v}}

Evaluate@Grad[#1 + #2^2, {#1, #2}] &
(*  {1, 2 #2} &  *)


Or for pure obfuscatory fun:

I'd like to reinstate to my first answer (see edit history),

Evaluate@Grad[#1 + #2^2 &[#1, #2], {#1, #2}] &


even though #1 + #2^2 &[#1, #2], which equals #1 + #2^2 and seemed redundant, because it has the right general form,

Evaluate@Grad[f[#1, #2], {#1, #2}] &


or equivalently in nonletterese,

• This doesn't work if the function isn't expressed as a pure function but for example like this: myF[x_, y_] := x + y^2 – user Dec 26 '15 at 3:50
• @MichaelE2 tis the season for obfuscatory fun :) – ubpdqn Dec 26 '15 at 4:24
• @user Not sure what "this" meant in your case, but Evaluate@Grad[myF[#1, #2], {#1, #2}] & works for me. – Michael E2 Dec 26 '15 at 4:39
• @MichaelE2 I meant that Evaluate@Grad[myF, {#1, #2}] & doesn't work... – user Dec 26 '15 at 4:42
• @user No, it wouldn't, but that's not equivalent, is it? I mean for Grad you can't supply a pure function or function head, but have to also supply its inputs. -- Even with Derivative you have to supply inputs to get what you want: Evaluate@{Derivative[1, 0][myF][#1, #2], Derivative[0, 1][myF][#1, #2]} & – Michael E2 Dec 26 '15 at 4:46

Perhaps:

grd[f_, v_][n_] := Grad[f @@ v, v] /. Thread[v -> n]


Testing various functions:-

q = #1^2 - #2^3 &;
r[x_, y_] := x^2 Sin[y];
s = Function[{u, v}, u^2 + 3 v^4];
test1 = grd[q, {x, y}];
test2 = grd[r, {x, y}];
test3 = grd[s, {x, y}];
test1[{a, b}]
test2[{a, b}]
test3[{a, b}]


and if you want it to behave f[x,y]$\mapsto$ g[x,y] rather than g[{x,y}]:

grad[f_, v_][n__] := grd[f, v][{n}]


I created two functions to do this job.
1.

In:=
MapIndexed[
Function[
{x, y},
(
Derivative @@ Normal[
SparseArray[#2[[1]] -> #1, Length@y]
]
)[x] &
][#1, #2],
#2] &[
#1 + #2^2 &,
{1, 1}
]
Out:=
{1 &, 2 #2 &}


The first argument is the function and the second argument is a list of the degrees of derivatives to be taken with respect to corresponding slot.

2.

In:=
Function[#2, Evaluate[Grad[#1 @@ #2, #2]]] &[#1 + #2^2 &, {x, y}]
Out:=
Function[{x, y}, {1, 2 y}]


In this approach the function is given a list of arbitrary symbols.