Problem with defining a simple linear operator

I need to define a linear operator, which should have very simple linearity:

myOp[Plus[f_, g_]] := myOp[f] + myOp[g]
myOp[a_ f_[x_, t_]] := a myOp[f[x, t]]


where f and g are considered functions of x and t, while a is a constant.

Testing

myOp[c h1[x, t] + c^2 h2[x, t]]


c myOp[h1[x,t]]+h2[x,t] myOp[c^2]

The first term behaves good, but why the second term has been given in this form? It is expected to give

c myOp[h1[x, t]]+c^2 myOp[h2[x, t]]

That is, myOp should only act on the function.

Any suggestions are welcome. Thank you in advance.

1 Answer

The simpler case myOp[c^2 h2[x, t]] has a similar problem using your current definitions:

myOp[c^2 h2[x, t]]


h2[x, t] myOp[c^2]

If you look at the FullForm of c^2, you will notice it expressed as Power[c, 2]. This means that the expression myOp[c^2 h2[x, t] really corresponds to myOp[Times[Power[c, 2], h2[x, t]]]. This matches your second definition of myOp, but between the Power and h2 expressions, which should be assigned to a, and which should be assigned to h in your definition pattern? The "wrong" choice of assignments is what leads to your unwanted result.

Instead, you may want to consider any expression with a built-in head (such as Power) as "constants" in your definition. You can filter those out by the context in which those symbols reside. In fact, built-in functions reside in the System context, whereas most of your user-defined ones will reside e.g. in the Global context.

Following Mr. Wizard's lead from a previous question, we can implement a helper function to distinguish them in your definition:

ClearAll[isBuiltIn]
isBuiltIn[s_] := Context[Evaluate@Head@s] === "System"


For instance: isBuiltIn[c^2] returns True.

So now we modify your definitions:

ClearAll[myOp]
myOp[Plus[f_, g_]] := myOp[f] + myOp[g]
myOp[a_?isBuiltIn f_[x_, t_]] := a myOp[f[x, t]]


and try this out:

myOp[c^2 h2[x, t]]


c^2 myOp[h2[x, t]]

and for your original case:

myOp[c h1[x, t] + c^2 h2[x, t]]


c myOp[h1[x, t]] + c^2 myOp[h2[x, t]]

• Thanks. The answer resolved the problem well. But for a slight extended (my real problem including D on a function), myOp[D[u0[x,t]+c u1[x,t]+c^2 u2[x,t],x]], it gives a looking-correct answer with a warning >Context::ssle: "Symbol, string, or HoldPattern[symbol] expected at position 1 in Context[...]" Any idea?
– lxy
Mar 22, 2019 at 2:12
• What about myOp[c h1[x, t] h2[x, t]]? I expect c myOp[h1[x, t] h2[x, t]] but it gives c h2[x, t] myOp[h1[x, t]]`. Apr 12, 2023 at 12:09