Defining a symbolic inner product
We can get a long way by directly declaring that the symbols in question are NumericQ
. For example, θ
is normally treated as non-scalar:
CircleDot[a, Times[θ, b]]
(* CircleDot[a, Times[b, θ]] *)
CircleDot[a, Times[Sin[θ], b]]
(* CircleDot[a, Times[b, Sin[θ]]] *)
NumericQ
is a protected symbol, but its built-in definition still permits direct assignment (in the same manner as other built-ins like N
and Format
). Thus, as speculated in the question, we can define θ
to be NumericQ
to make it act like a scalar:
NumericQ[θ] = True;
CircleDot[a, Times[θ, b]]
(* Times[θ, CircleDot[a, b]] *)
CircleDot[a, Times[Sin[θ], b]]
(* Times[CircleDot[a, b], Sin[θ]] *)
We can take away the numeric status by executing NumericQ[θ] =.
.
As noted in the question, we must take care when changing the meaning of symbols in this fashion. It is probably not a good idea to change a common symbol like i
since it NumericQ
status affects many built-in functions. Therefore, I suggest restricting such changes to letter forms that have no other function in your application, (e.g. Greek, double-struck, Gothic, Hebrew, etc).
Try adding this to your existing definitions:
(x_scalar a_)\[CircleDot]b_ := x (a\[CircleDot]b)
This specifies a definition similar to your last one that only applies when the Head
of $x$ is scalar
, an auxiliary operator we introduce.
Now, suppose that you want $t$ to be a scalar and $vec_i$ to be vectors:
(scalar[t] vec1) \[CircleDot] vec2 (* Out: vec1 \[CircleDot] vec2 scalar[t] *)
The auxiliary function scalar
need not have any definition. It is just there as a wrapper to indicate the "type" of $t$.
If you don't want to see the scalar
wrapper in your result, you can define a formatting rule for it:
Format[scalar[a_]] := a
The same expression above will then print as follows:
(scalar[t] vec1) \[CircleDot] vec2 (* Out: vec1 \[CircleDot] vec2 t *)
The scalar wrapper is retained, however:
InputForm[%] (* Out: vec1 \[CircleDot] vec2 * scalar[t] *)