Re: D[...] change in 5.1

*To*: mathgroup at smc.vnet.net*Subject*: [mg58740] Re: D[...] change in 5.1*From*: Maxim <ab_def at prontomail.com>*Date*: Sun, 17 Jul 2005 03:03:55 -0400 (EDT)*References*: <db57qa$4ri$1@smc.vnet.net> <db7nug$mt8$1@smc.vnet.net>*Sender*: owner-wri-mathgroup at wolfram.com

On Fri, 15 Jul 2005 07:17:36 +0000 (UTC), Alexei Akolzin <akolzine at uiuc.edu> wrote: > I am sorry, here what I meant: > > In[1] := n /: D[n[i_], x[j_], NonConstants -> n] := (1/r)*(d[i, j] - > n[i]*n[j]); > > In[2] := D[n[k], x[l], NonConstants -> n] > Out[2] = (d[k, l] - n[k] n[l]) / r > > In[3] := D[1 + n[k], x[l], NonConstants -> n] > Out[3] = D[n, x[l], NonConstants -> n] > > In[4] := $Version > Out[4] = "5.1 for Linux x86 (64 bit) (January 27, 2005)" > > From my point of view Out[3] should be exactly equal to Out[2]. It was > in earlier versions, but it is not in 5.1! The difference gives all > kind of problems in more complicated expressions. I try to combat this > with Hold and ReleaseHold, but ran into a more peculiar problem, which > is even more puzzling to me: > > In[1] := n /: D[ n[i_], x[j_], NonConstants -> {n, r} ] := ( \[Delta][i, > j] - n[i] n[j]) / r; > In[2] := r /: D[ r, x[i_], NonConstants -> {n,r} ] := n[i]; > > In[3] := D[ \[Delta][i,j] BesselJ[0 , k r] , x[l], NonConstants -> > {n,r} ] > Out[3] = 0 > > In[4] := D[ \[Delta][i,j] BesselJ[0 , k r] , x[m], NonConstants -> > {n,r} ] > Out[4] = - k BesselJ[1,k r] n[m] \[Delta][i,j] > > In[8] := ?k > Global`k > > In[9]:= ? \[Delta] > Global`\[Delta] > > Now, Out[3] and Out[4] should be the simmilar. The only difference is > what simbol "m" ?or "l" is used in respective differentiation by x[m] > or x[l]. But again they are not. The problem disappears if I substitute > "\[Delta]", which I enter from keyboard as Esc d Esc, for example by > "d". > > Sincerely, > Alexei. > I think that if you want to specify the implicit dependency of n[i] on x[j], you should use NonConstants -> n[i], not NonConstants -> n, and the definition for D should look like this: x /: D[expr_, x[j_], NonConstants -> {___, n[i_], ___}] := ... However, as you noticed, D with the option NonConstants behaves very erratically in Mathematica 5.1 and 5.2: In[1]:= D[{a*y, k*y}, x, NonConstants -> y] Out[1]= {a*D[y, x, NonConstants -> {y}], 0} Just replacing a with k leads to a different outcome. One way to get around this is to redefine D as follows: In[2]:= Unprotect[D]; $DxjF = True; D[expr_, s___, x[j_], s2___] := D[expr, s, {x[j]}, s2] D[expr_, s___, {x[j_], ord_:1} /; IntegerQ[ord] && ord >= 0, s2___] /; $DxjF := Module[{ans = D[expr, s]}, Block[{$DxjF = False}, ans = Nest[ D[#, x[j]] /. {n[i_]'[x[j]] :> (d[i, j] - n[i][x[j]]*n[j][x[j]])/r[x[j]], r'[x[j]] :> n[j][x[j]]}&, Replace[ans, y : n[i_] | r :> y[x[j]], {0, -1}, Heads -> False], ord] /. (y : n[i_] | r)[x[j]] :> y ]; D[ans, s2] ] Then you get the same result as in version 5.0, regardless of whether you use d or \[Delta]: In[6]:= D[d[i, j]*BesselJ[0, k*r], x[m], x[l]] - D[d[i, j]*BesselJ[0, k*r], x[l], x[m]] // Simplify Out[6]= k*BesselJ[1, k*r]*d[i, j]*(d[l, m] - d[m, l])/r This definition can be modified to apply only when the NonConstants list contains n[_] or r. Also it can be extended to handle vector derivatives D[expr, {{x[1], x[2]}}]. Another change that was made to D in version 5.1 is that D[f[n][x], n] no longer gives 0. Now we can evaluate e.g. In[1]:= f[n_?NumericQ][x_] = n*x; FindFit[Range[2, 600, 2], f[n][x], n, x, Method -> Newton] // Timing Out[2]= {0.61*Second, {n -> 1.9999996}} In version 5.0 FindFit just generated Dot::dotsh errors. What seems to happen in versions 5.1/5.2 is that D[f[n][x], n] gives f'[n][x], which probably doesn't make much sense from the mathematical point of view, but this way Mathematica detects that it cannot evaluate the gradient symbolically and uses finite differences, obtaining something like (f[n + eps][x] - f[n][x])/eps, which is then evaluated numerically. However, I'm not sure what is the reason for this: In[3]:= g[n_?NumericQ, x_] = n*x; FindFit[Range[2, 600, 2], g[n, x], n, x, Method -> Newton] // Timing Out[4]= {11.906*Second, {n -> 1.9999996}} Using g[n, x] instead of f[n][x] turns out to be about 20 times slower, even though both f and g can be evaluated only for numerical values of n. Maxim Rytin m.r at inbox.ru