Computing with matrix differential operators
Here is a modification of your code that works. The problem was that you weren't combining the Composition
s for each matrix entry correctly in CircleTimes
: using Plus
with Composition
doesn't lead to a function which can be applied subsequently to another expression. You have to make each sum of compositions into a function itself.
First I'll copy the definitions that I didn't modify:
Clear[f, g, x];
I1 := {{0 &, (x # + D[#, x] &)}, {0 &, -D[#, x] &} }
I2 := {{0 &, x^2 # &}, {0 &, D[#, x] &}}
u = {f[x], g[x]};
CenterDot[a_, v_] := Inner[Through[#1[#2] &, Plus], a, v]
Now my modifications:
Clear[CircleTimes];
CircleTimes[a_, b_] :=
Inner[Composition[#1, #2] &, a, b,
Function[f, Total@Through[{##}[f]]] &]
CirclePlus[a_, b_] :=
MapThread[Function[f, Total@Through[{##}[f]]] &, {a, b}, 2]
The modification in CircleTimes
is that I specified the replacement of the Plus
operation in Inner
as Function[f, Total@Through[{##}[f]]] &
which is now itself a function that adds the individual operators after applying them to whatever argument f
you provide.
Next, the same issue with Plus
also arises in I3
. So I defined an addition of operators CirclePlus
in which the same trick is used as above, by combining the matrices of operators element-wise using MapThread
.
Now the tests:
CenterDot[I1, u]
(* ==> {x g[x] + Derivative[1][g][x], -Derivative[1][g][x]} *)
CenterDot[I2, u]
(* ==> {x^2 g[x], Derivative[1][g][x]} *)
CenterDot[CircleTimes[I1, I2], u]
(*
==> {x Derivative[1][g][x] + (g^\[Prime]\[Prime])[x], -(
g^\[Prime]\[Prime])[x]}
*)
I3 := CirclePlus[CircleTimes[I1, I2], CircleTimes[I2, I1]]
CenterDot[I3, u]
(*
==> {x Derivative[1][g][x] -
x^2 Derivative[1][g][x] + (g^\[Prime]\[Prime])[x], -2 (
g^\[Prime]\[Prime])[x]}
*)
Id := {{1 &, 0 &}, {0 &, 1 &}}
CenterDot[CirclePlus[Id, Id], u]
(* ==> {2, 2} *)
As you can see, the tests produce outcomes that look correct. Edit: the last example is from the comment, and I changed the code to accommodate such constant operators. Note that this is not the same as the identity which multiplies the test function by 1
. My understanding of the comment was that the desired operator was meant to replace the test function by 1
.
This is how I would define your functions, similar but I think simpler than @Jens answer:
ClearAll[CirclePlus, CircleTimes, CenterDot]
SetAttributes[CirclePlus, {Flat, Listable}]
CirclePlus[a__][x_] := Activate @* Through @* Inactive[Plus][a] @ x
CircleTimes[a_, b_] := Inner[Composition, a, b, CirclePlus]
CenterDot[a_, b_] := Inner[Compose, a, b]
For the OP example:
I1 := {{0&, (x # + D[#,x]&)}, {0&, -D[#,x]&}}
I2 := {{0&, x^2 #&}, {0&, D[#,x]&}}
u = {f[x], g[x]};
The same results as @Jens:
CenterDot[I1, u] //TeXForm
$\left\{g'(x)+x g(x),-g'(x)\right\}$
CenterDot[I2, u] //TeXForm
$\left\{x^2 g(x),g'(x)\right\}$
CenterDot[CircleTimes[I1, I2], u] //TeXForm
$\left\{g''(x)+x g'(x),-g''(x)\right\}$
I3 := CirclePlus[CircleTimes[I1, I2], CircleTimes[I2, I1]]
CenterDot[I3, u] //TeXForm
$\left\{g''(x)+x^2 \left(-g'(x)\right)+x g'(x),-2 g''(x)\right\}$
Id := {{1&, 0&}, {0&, 1&}}
CenterDot[CirclePlus[Id, Id], u] //TeXForm
$\{2,2\}$