Re(2): Re: Commutators and Operator Powers in Mathematica
- To: mathgroup at smc.vnet.net
- Subject: [mg16751] Re(2): [mg16692] Re: Commutators and Operator Powers in Mathematica
- From: Andrzej Kozlowski <andrzej at tuins.ac.jp>
- Date: Wed, 24 Mar 1999 02:23:57 -0500
- Sender: owner-wri-mathgroup at wolfram.com
I agree that your approach (particularly the latest version that I just got from you) is is easier to use and would be preferable in most practical situations. But just for the skae of "pure knowledge" let me try to defend mine. First of all the second objectsion. I do not think entering bracket[L0,L1][f][t,x] is the correct way to use my definition. If f is a pure function of two variables, you have to do something like this: g=Function[s,differentialOperate[bracket[L0,L1],f[#,t]&][s]//Simplify] then indeed In[15]:= g[x] Out[15]= 3/2 2 (1,0) -a x f[x, t] - 2 b x f [x, t] This is certainly not very satisfactory, but it does work! As for your first point: yes I realize that adding rules to Plus etc may be dangarous although I have never met with any problem. But one can also deal with that: we define two functions to turn on and off these new rules: fnAlgebraOn:=(Unprotect[{Plus, Times,Power}]; Plus/: ((f_) + (g_))[x_] := f[x] + g[x]; Times/: ((k_?NumberQ )(f_))[x_] := k f[x]; Times/: ((f_) (g_))[x_] := f[x] g[x]; Power/:(f_^n_)[x_]:=f[x]^n ; Protect[{Plus,Times,Power}];) fnAlgebraOff:=(Unprotect[{Plus, Times,Power}]; Map[(SubValues[#]={})&,{Plus,Times,Power}];Protect[{Plus,Times,Power}]) Now, fnAlgebraOn will turn on the new rules and fnAlgebraOff will turn them off. One can even define all the operator functions to perform a fnAlgebraOn before acting and fnAlgebraOff when they finish so that you would be even more unlikely to come across any unintended side effects. Still, I do not think all this changes the fact that your approach is clearly better in practice. On Mon, Mar 22, 1999, Daniel Lichtblau <danl at wolfram.com> wrote: >Andrzej Kozlowski wrote: >> >> I was about to sent my answer when I noticed that Daniel Lichtblau had >> beaten me to it and I could not hope to improve on his solution. So I >> stopped writing mine but then I still found one thing about his answer >> that was not entirely satisfactory from my point of view. I like to work >> with pure functions rather than expressions involving some arbitrarily >> chosen variables like x etc. I find this approach both aesthetically more >> satisfactory and also better corresponding to the way I think of >> structures such as function and operator algerbas etc. So I re-wrote >> Daniel's package to eliminate the need to refer to any "vars" and decided >> to post it in case there are other people who share my bias in this matter. >> >> I first attatch new rules to Plus, Times and Power to allow algebraic >> operations on pure functions: >> >> Unprotect[{Plus, Times,Power}]; >> Plus/: ((f_) + (g_))[x_] := f[x] + g[x]; >> Times/: ((k_?NumberQ )(f_))[x_] := k f[x]; >> Times/: ((f_) (g_))[x_] := f[x] g[x]; >> Power/:(f_^n_)[x_]:=f[x]^n ; >> Protect[{Plus,Times,Power}]; >> >> Next we re-write Daniel's definitions eliminating all vars: >> >> In[2]:= >> differentialOperate[a_, fn_] /; FreeQ[a, D] := a*fn >> differentialOperate[L1_ + L2_, fn_] := >> differentialOperate[L1, fn] + differentialOperate[L2,fn] >> differentialOperate[a_*L_,fn_] /; FreeQ[a, D] := >> a*differentialOperate[L,fn] >> differentialOperate[D^(n_.),fn_] := Derivative[n][fn] >> differentialOperate[L1_**L2_,fn_] := >> differentialOperate[L1, differentialOperate[L2,fn]] >> differentialOperate[L1_**L2_**L3__, fn_] := >> differentialOperate[L1, differentialOperate[L2**L3,fn]] >> differentialOperate[bracket[L1_,L2_],fn_] := Expand[ >> differentialOperate[L1, differentialOperate[L2,fn]] - >> differentialOperate[L2, differentialOperate[L1,fn]]] >> differentialOperate[L1_^(n_.), fn_] := >> Nest[Expand[differentialOperate[L1,#]]&,fn, n] >> >> Now we define our operators using pure functions as coefficients: >> >> In[3]:= >> L0 = #&; >> L1 = (a*#^(3/2)&)*D +( b*#^2&)*D^2; >> >> Now, given a function f, we can define the >> >> In[11]:= >> bracket[L0,L1][f]:= >> Function[t,differentialOperate[bracket[L0,L1],f][t]//Simplify] >> >> This indeed is the right function, e.g. >> >> In[12]:= >> bracket[L0,L1][f][t] >> Out[12]= >> 3/2 2 >> -a t f[t] - 2 b t f'[t] >> > >This variable-free approach can be useful but let me point out a few >possible pitfalls. First, by attaching rules to Plus et al there is >always the danger of unintended side effects during evaluation. Next, >you now do not have a way to handle multivariate functions very well, >because a "variable" will be implied. For example, you get > >In[50]:= bracket[L0,L1][f][t,x] > > 3/2 2 >Out[50]= -(a t f[t]) - 2 b t f'[t] > >In[51]:= bracket[L0,L1][f][x,t] > > 3/2 2 >Out[51]= -(a x f[x]) - 2 b x f'[x] > >whereas using the admittedly imperfect code I sent one has: > >In[13]:= differentialOperate[bracket[L0,L1], f[t,x], x] > > 3/2 2 (0,1) >Out[13]= -(a x f[t, x]) - 2 b x f [t, x] > >and something similar if we instead specify 't' to be the variable of >interest. Moreover nested functions present no problem: > >In[14]:= differentialOperate[bracket[L0,L1], f[g[x],x,t], x] > > 3/2 2 (0,1,0) >Out[14]= -(a x f[g[x], x, t]) - 2 b x f [g[x], x, t] - > > 2 (1,0,0) >> 2 b x g'[x] f [g[x], x, t] > >One aspect to my code I do not like is the fact that takind mixed >derivatives with respect to different variables is at best awkward. So >amybe it would be better to carry this in the D[...] parts of the >differential operators as a pure function? This is something I need to >ponder. > >Daniel Lichtblau >Wolfram Research > > > >> On Sat, Mar 20, 1999, Daniel Lichtblau <danl at wolfram.com> wrote: >> >> >Alan Lewis wrote: >> >> >> >> I am looking for any links or suggestions on implementing >> >> commutation relations and powers of differential operators >> >> in mathematica. >> >> >> >> As an example, I have two operators L0 and L1 that act on arbitrary >> >> (well say infinitely differentiable) functions f[x] >> >> >> >> L0 simply multiplies f[x] by x. >> >> L1 = a x^(3/2) D[f[x],x] + b x^2 D[f[x],{x,2}] >> >> >> >> where a,b are constants independent of x. The second line is not >> >> meant to be working math. code but is just meant to explain the action >> >> of this differential operator. >> >> >> >> Now what I want to do is be able to evaluate repeated commutators >> >> and powers of these operators. For example, the first commutator >> >> should evaluate to: >> >> >> >> [L0,L1]f[x] = x L1 f[x] - L1 (x f[x]) = >> >> >> >> -a x^(3/2) f[x] - 2 b x^2 D[f[x],x] >> >> >> >> I would also like to evaluate powers such as >> >> L1^n, meaning the operator acts on f[x] n times. Repeated >> >> commutators are expressions like >> >> >> >> [L1,[L0,L1]] or [L0,[L0,L1]], etc. >> >> >> >> The action of L1 is just an example, but the general class of operators >> >> I am interested in are always the sum of a first and second derivative >> >> with simple expressions like the above in front of the derivative. >> >> And L0 is always multiplication by x. >> >> >> >> Thanks in advance for any suggestions, >> >> Alan >> > >> > >> >Here is some code to tangle with differential operators. >> > >> >differentialOperate[a_, expr_, var_] /; FreeQ[a, D] := a*expr >> >differentialOperate[L1_ + L2_, expr_, var_] := >> > differentialOperate[L1, expr, var] + differentialOperate[L2, expr, >> >var] >> >differentialOperate[a_*L_, expr_, var_] /; FreeQ[a, D] := >> > a*differentialOperate[L, expr, var] >> >differentialOperate[D^(n_.), expr_, var_] := D[expr, {var, n}] >> >differentialOperate[L1_**L2_, expr_, var_] := >> > differentialOperate[L1, differentialOperate[L2, expr, var], var] >> >differentialOperate[L1_**L2_**L3__, expr_, var_] := >> > differentialOperate[L1, differentialOperate[L2**L3, expr, var], var] >> >differentialOperate[bracket[L1_,L2_], expr_, var_] := Expand[ >> > differentialOperate[L1, differentialOperate[L2, expr, var], var] - >> > differentialOperate[L2, differentialOperate[L1, expr, var], var]] >> >differentialOperate[L1_^(n_.), expr_, var_] := >> > Nest[Expand[differentialOperate[L1,#,var]]&, expr, n] >> > >> > >> >For your examples, one has >> > >> >L0 = x; >> >L1 = a*x^(3/2)*D + b*x^2*D^2; >> > >> >Then >> > >> >In[12]:= differentialOperate[bracket[L0,L1], f[x], x] >> > >> > 3/2 2 >> >Out[12]= -(a x f[x]) - 2 b x f'[x] >> > >> > >> >In[21]:= e1 = Expand[differentialOperate[L1, f[x], x]] >> > >> > 3/2 2 >> >Out[21]= a x f'[x] + b x f''[x] >> > >> >In[22]:= e2 = Expand[differentialOperate[L1, e1, x]] >> > >> > 3/2 2 2 >> > 3 a b x f'[x] 3 a x f'[x] 2 2 >> >Out[22]= ---------------- + ------------- + 2 b x f''[x] + >> > 4 2 >> > >> > 5/2 2 3 2 3 (3) >> >> 5 a b x f''[x] + a x f''[x] + 4 b x f [x] + >> > >> > 7/2 (3) 2 4 (4) >> >> 2 a b x f [x] + b x f [x] >> > >> >In[23]:= differentialOperate[L1^2, f[x], x] == e2 >> > >> >Out[23]= True >> > >> > >> >A slightly cruder version of this may all be found in a notebook I >> >prepared for the 1998 Worldwide Mathematica Users Conference, a copy of >> >which can be found at: >> > >> >http://www.wolfram.com/conference98/schedule/symbolic_FAQ.html >> > >> >in the section "Some noncommutative algebraic manipulation". There is >> >also some code therein to do algebraic simplification in a commutator >> >algebra which may be of relevance. >> > >> > >> >Daniel Lichtblau >> >Wolfram Research >> >> Andrzej Kozlowski >> Toyama International University >> JAPAN >> http://sigma.tuins.ac.jp/ >> http://eri2.tuins.ac.jp/ > Andrzej Kozlowski Toyama International University JAPAN http://sigma.tuins.ac.jp/ http://eri2.tuins.ac.jp/