1
$\begingroup$

Background

I have a function, for example:

g=Function[{x,y},{x^2+y}]

And I want to compute $\frac{\partial g}{\partial x}$:

D[g[x,y],x]

which gives 2x.

This is correct. But lets say I am not satisfied with this for that the code g[x,y](which is a function application) is not consistent with the math notation $g$ in the derivative $\frac{\partial g}{\partial x}$.

What I want is to compute the derivative by

D[g,x]

(I understand the issue of notation abuse is subjective. I just use this as an example to show what I want to do)

What I have tried

I use a rule to match a function defined by Function, and replace it with a "function application":

rule = HoldPattern[f : Function[vars_, _]] :> f @@ vars

Then I can write

D[g/.rule,x]

This works.

Question

Is there any way to customize the D function for this special case so that I do not have to write /.rule, while preserving its behavior for other cases?

$\endgroup$
  • 1
    $\begingroup$ It's not clear what you're asking. Does g=x^2+y; D[g,x] count? $\endgroup$ – yohbs May 11 '17 at 20:44
  • $\begingroup$ Also, how would you represent $\partial g(y,x)/\partial x$, or $\partial g(y+sin(x),x^{2+y})/\partial x$? The partial derivative notation only makes sense in a very limited range of applications. The more robust notation is differentiating with respect to positional arguments, which is achieved in Mathematica by Derivative[1,0][g] (=differentiate g with respect to its first argument). $\endgroup$ – yohbs May 11 '17 at 20:48
  • $\begingroup$ @yohbs I want let g be function-like and callable through g[a,b]. $\endgroup$ – TheBusyTypist May 11 '17 at 20:48
  • $\begingroup$ @yohbs Those two examples you gave can be perfectly expressed by D[g[...,...],x] since in those cases we apply the function first and then compute the derivative, which is consistent with D's behavior. The suggestion of Derivative is what I want, except it requires more typing. $\endgroup$ – TheBusyTypist May 11 '17 at 20:52
  • 3
    $\begingroup$ D[g,x] is not meaningful without knowing which argument of g x is. The first? The second? Etc. There is no way to know that. In Function[{x,y}, ...], x is just a placeholder that is not supposed to be visible from the outside. It is also subject to renaming by localization mechanism. This is not notation abuse. It simply makes no sense, unless you declare that "$x$ is always the first variable". This is what we actually do in math/physics: we agree on the variables first. $\endgroup$ – Szabolcs May 12 '17 at 9:58
0
$\begingroup$

You may set an UpValue on Function by Unprotecting it. This carries some risk as you are modifying a built-in symbol. However, the pattern you are setting the UpValue for is incorrect syntax for D with Function which reduces the risk a bit.

Unprotect[Function];
Function /:
 D[HoldPattern[f : Function[vars_, __]], x_] := D[f @@ vars, x]
Protect[Function];

With

g = Function[{x, y}, x^2 + y];

Then

D[g, x]
2 x
D[g, y]
1

Hope this helps.

$\endgroup$
1
$\begingroup$

If you truly need this override the standard method is using a Condition that you'll disable inside the body of the function.

For example:

Unprotect[D];
Clear@D;
HoldPattern[D[Function[_, body_, ___], e___]] /; ! TrueQ[$inOveride] :=

    Block[{$inOveride = True},
   D[body, e]
   ];
Protect[D];

Then this works:

In[555]:= g = Function[{x, y}, x^2 + y];
D[g, x]

Out[556]= 2 x

Note that this could seriously damage the performance of any functionality that uses D in subtle ways.

When overriding built-ins it's also useful to know about Internal`InheritedBlock, but your case really doesn't require that.

$\endgroup$
1
$\begingroup$

If I understand correctly what you want from the discussion in the comments, you can use the operator form of Derivative:

Dx=Derivative[1,0]
g = Function[{x, y}, x^2 + y];
Dx[g]
(*output: Function[{x, y}, {2 x}]*)
$\endgroup$
0
$\begingroup$

Instead of overriding built-ins you could create your own "function" head that will have desired behavior.

myFunction // ClearAll
myFunction // Attributes = HoldAll;
myFunction[vars_, body_]@args___ := Function[vars, body]@args
myFunction /: Derivative[varsDer_ /; MemberQ[Flatten@{varsDer}, Except@0], _]@myFunction = 0 &;
myFunction /: Derivative[_, 1]@myFunction = 1 &;

Basic Examples

g = myFunction[{x, y}, x^2 + y]
(* myFunction[{x, y}, x^2 + y] *)

g is "callable":

g[a, b]
(* a^2 + b *)

and has expected derivatives, with implicit arguments:

D[g, x]
(* 2 x *)
D[g, y]
(* 1 *)
D[2 g + 5 x, x]
(* 5 + 4 x *)

and with explicit arguments:

D[g[x + 1, 7 x], x]
(* 7 + 2 (1 + x) *)

Possible Issues

Nested scopes

Built-in Function is a scoping construct and other scoping constructs rename Functions variables if that's necessary:

g = With[{a = x}, Function[x, a x]]
g[k]
(* Function[x$, x x$] *)
(* k x *)

myFunction is not treated as scoping construct:

g = With[{a = x}, myFunction[x, a x]]
g[k]
(* myFunction[x, x x] *)
(* k^2 *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.