I'm here with another probably simple question. So I am taking derivatives of a function with respect to another variable not used in that function. So first I define that derivative

D[r[n, k, h, L, \[Mu]], lam] = v[n, k, h, L, \[Mu]], lam]/n


So this is all well and good but then when I actually try to use that derivative in the context of another function, whoopsies it seems like mathematica has forgotten

In[773]:= D[3*r[n, k, h, L, \[Mu]], lam]

Out[773]= 0


So I checked if the original derivative is still defined and lo and behold

In[774]:= D[r[n, k, h, L, \[Mu]], lam]

Out[774]= v/n


(where v is the function of v) How do I make mathematica do this pattern matching correctly? I'm sure this has been asked before but I didn't see quite where.

I thanks to daniel have figured that using

 D[f_ : 1 r[n, k, h, L, \[Mu]], lam] ^= v/n


Gives also the wrong answer in that D[r[n, k, h, L, [Mu]], lam] gives the exact same answer as D[3*r[n, k, h, L, [Mu]], lam] which is obviously wrong

Edit: I am still unable to get this to work correctly so I've uploaded my notebook to git. You can find my full code here: https://github.com/pjdog/mathematicaStuff/blob/main/danielsonderivatives.nb

• First, your definition will not work, because it tries to assigne the rule to D what is protected. You must use "UpSet": "^=". Further, MMA is a pattern matcher. If you want to match the pattern "3*r[..]" you must say: D[f_^ : 1 r[n, k, h, L, \[Mu]], lam] ^= v/n; – Daniel Huber Apr 28 at 19:40
• Because I'm an uneducated caveman I just unprotect D before using it in that way lol. I definitelly shouldnt do it that way. – Paul Hughes Apr 28 at 20:24
• ALso the code you wrote does not work correctly Daniel. The first ^ keeps the code from running – Paul Hughes Apr 29 at 21:28

You can add the option NonConstants -> {r} to tell D that r does, indeed, depend on non-explicit variables. This is the best way, I think—then you can use all of D's standard rules. Otherwise, you'd need to define pattern-matching to account for every single possible way r could occur in an expression, which is...a lot. (You could probably also replace r with an "internal" function which does explicitly depend on lam, but I'll take the NonConstants route here.)

But it's a bit finicky to get it to work as intended, especially when considering that you might have other nonconstants, and other variables with respect to which you might be taking the derivative.

(I'd also recommend using upvalues to associate the definition with r instead of D. I also recommend making the arguments patterns by appending a _, otherwise only the literal symbols n, k, etc. will work!)

Here, I check if you're taking the derivative with respect to any other symbols as well; if not, I give v/m, and otherwise I apply the $$\partial/\partial\lambda$$ derivative first, get v/m, and then take the remaining derivatives of that.

r /: D[r[n_, k_, h_, L_, \[Mu]_], p1___Symbol, lam, p2___Symbol, NonConstants -> {x___, r, y___}] :=
Switch[Hold[p1, p2],
Hold[], v/m,
_     , D[v/m, p1, p2, NonConstants -> {x, r, y}]
]


One could repeat this sort of procedure to account for nth-derivative syntax and vector derivatives—let me know if that would be useful!

You also might want to add r as a nonconstant to any evaluation of D. This requires modifying D.

Unprotect[D];Clear[D];

Block[{r},

D[expr_, p__, NonConstants -> {x___}] :=
D[expr, p, NonConstants -> {x, r}] /; FreeQ[{x}, r, {1}];

D[expr_, p__, NonConstants -> x_Symbol] :=
D[expr, p, NonConstants -> {x, r}] /; !MatchQ[x, r];

D[expr_, p : ((_List | _Symbol)..)] :=
D[expr, p, NonConstants -> {r}]

];

Protect[D];


Let me know if you'd like me to explain anything I use here!

• @PaulHughes ah, I see. That usually happens when the thing you're trying to assign upvalues to only occurs deeper than the first level of the expression. So, for example, a /: f[a] := 1 will work, but a /: f[g[a]] := 1 will give you that error. Here, even though r appeared deeper, the upvalue assignment to r succeeded because r was present as a head on the first level of the expression, namely as D[r[...], ...]. If you're not assigning derivatives to functions directly like that, you might have to add a definition to D after all! – thorimur Apr 29 at 19:14
• Feel free, though, to edit your question to include the more general cases that are behaving badly, and I'll try to edit my answer to help out when I have the chance :) – thorimur Apr 29 at 19:15
• also, replacing v with v[n, k, h, L, \[Mu]] (no underscores) should solve the first problem you mention! – thorimur Apr 29 at 19:17
• @PaulHughes you mean my code gives you that error? hmmm. copy-pasting my code to a fresh kernel, and adding the dependence on arguments for v works fine for me, no error messages. what version of mathematica are you in? and have you tried ClearAll[r] before evaluating? – thorimur Apr 29 at 23:56
• @PaulHughes try r /: D[r[n_, k_, h_, L_, \[Mu]_], p1___Symbol, lam, p2___Symbol, NonConstants -> spec_] := Switch[Hold[p1, p2], Hold[], v/m, _, D[v/m, p1, p2, NonConstants -> spec]]. What do you get then? – thorimur Apr 30 at 3:59