Question

I want to teach mathematica that Subscript[w, i] differentiated by Subscript[w, j] is KroneckerDelta[i, j].

I tried

Unprotect[D]; D[Subscript[x_, i_], Subscript[x_, j_]] := 
                                            KroneckerDelta[i, j]; Protect[D]

And this works with D[Subscript[w, i], Subscript[w, j]], but not with more complex expressions, e.g. D[Times[k, Subscript[w, i]], Subscript[w, j]]

I understand from the answer to this question: How to define a function that commutes with D in Mathematica that mathematica isn't matching my rule, but I don't understand why. Why does Mathematica not use the product rule, and then invoke my rule?

Was it helpful?

Solution

I think I see now what is happening.

Mathematica does not recursively define the D operator using the chain rule, presumably because this is too slow. It does some pattern matching on subexpressions to see if they contain the variable of differentiation, and subexpressions which don't are treated as constants; so my pattern for D is never applied.

The way around this turns out to be to tell Mathematica explicitly that

Subscript[w, i]

is not a constant.

My pattern now looks like this

Unprotect[D]; 
D[Subscript[x_, i_], Subscript[x_, j_], 
    NonConstants -> {___, Subscript[x_, i_], ___} ] := KroneckerDelta[i, j]; 
Protect[D]   

And I have to apply it this way:

D[k * Subscript[w, i], Subscript[w, j], NonConstants -> Subscript[w, i]]

OTHER TIPS

Mathematica does not have "mathematical maturity" which means it is not a competent graduate student who can look at your request, figure out what you actually meant and give you what you should get. In particular, pattern matching is "structural", which means it just literally matches exactly the structure of what the rules say. That means it doesn't realize that you probably meant k to be a constant and thus understand that the derivative of a constant times a function should be the constant times the derivative.

You can add more and more rules to try to simulate mathematical maturity, but many typical users don't have all the skills needed to exactly correctly write all the rules needed. You can include:

Unprotect[D];
D[Times[k_, Subscript[w_, i_]], Subscript[x_, j_]] := k*KroneckerDelta[i, j];
Protect[D];
D[Times[k, Subscript[w, i]], Subscript[x_, j_]]

but that is assuming that k is free of Subscript[w, i]] and you may want to enhance that rule with a condition ensuring that. This still doesn't deal with k+KroneckerDelta[i, j] or k*KroneckerDelta[i, j]+m, etc.

First of all, it's usually a bad idea to Unprotect symbols in Mathematica in order to add DownValues. In addition to the reasons Bill gave, this forces D to check that the arguments you give it doesn't match your patterns, before it can do its normal work. That can slow the system down.

You can often get away with UpValues (via UpSetDelayed) instead of DownValues. That doesn't require that you Unprotect, and it causes your rules to fire only when they apply.

In this case, though, I think you just want a custom differentiator on top of D:

myD[f_, Subscript[x_, i_]] := 
  With[{vars = DeleteDuplicates[Cases[f, Subscript[x, _], {0, Infinity}]]}, 
    Sum[D[f, v]*KroneckerDelta[i, v[[2]]], {v, vars}]
  ]

(if I'm not missing something crucial.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top