How do you define a special operator in Mathematica, for example a special type of additive or multiplicative operator? I did that in the past but I can't recall where I put the code. I tried defining this filled sma开发者_如何学Goll circle operator on two matrices :
A_\[FilledSmallCircle] B_ :=
Which[(MatrixQ[A] || VectorQ[A]) && (MatrixQ[B] || VectorQ[B]),
A.B, ! (MatrixQ[A] || VectorQ[A]) && (MatrixQ[B] || VectorQ[B]),
A@B, (MatrixQ[A] || VectorQ[A]) && ! (MatrixQ[B] || VectorQ[B]),
Transpose[B@Transpose[A]]];
But it does not work. What am I doing wrong?
So you are trying to make an operator with an infix action. If you compare it to the built-in infix operators +
, *
, **
, \[CircleTimes]
, etc... you'' see that they are all interpreted into their FullForm
: Plus
, Times
, NonCommutativeMultiply
, CircleTimes
, respectively.
You should probably try to create something similar. So start with
BigDot[A_, B_] := Which[
(MatrixQ[A] || VectorQ[A]) && (MatrixQ[B] || VectorQ[B]), A.B,
!(MatrixQ[A] || VectorQ[A]) && (MatrixQ[B] || VectorQ[B]), A@B,
(MatrixQ[A] || VectorQ[A]) && !(MatrixQ[B] || VectorQ[B]), Transpose[B@Transpose[A]],
True, HoldForm[BigDot[A, B]]];
Note that I added the last line as a catch-all for when neither A nor B are a matrix or a vector.
Then create the infix notation part. The hard way would be to make some MakeExpression
and MakeBoxes
definitions. The easy way is to use the NotationPackage
Needs["Notation`"]
InfixNotation[ParsedBoxWrapper["\[FilledSmallCircle]"], BigDot]
Try (just cut and paste this):
Needs["Notation`"]
Notation[ParsedBoxWrapper[
RowBox[{"A_", " ", "\[FilledSmallCircle]", " ",
"B_"}]] \[DoubleLongLeftRightArrow] ParsedBoxWrapper[
RowBox[{"Which", "[",
RowBox[{
RowBox[{
RowBox[{"(",
RowBox[{
RowBox[{"MatrixQ", "[", "A_", "]"}], "||",
RowBox[{"VectorQ", "[", "A_", "]"}]}], ")"}], "&&",
RowBox[{"(",
RowBox[{
RowBox[{"MatrixQ", "[", "B_", "]"}], "||",
RowBox[{"VectorQ", "[", "B_", "]"}]}], ")"}]}], ",",
RowBox[{"A_", " ", ".", "B_"}], ",",
RowBox[{
RowBox[{"!",
RowBox[{"(",
RowBox[{
RowBox[{"MatrixQ", "[", "A_", "]"}], "||",
RowBox[{"VectorQ", "[", "A_", "]"}]}], ")"}]}], "&&",
RowBox[{"(",
RowBox[{
RowBox[{"MatrixQ", "[", "B_", "]"}], "||",
RowBox[{"VectorQ", "[", "B_", "]"}]}], ")"}]}], ",",
RowBox[{"A_", "[", "B_", "]"}], ",",
RowBox[{
RowBox[{"(",
RowBox[{
RowBox[{"MatrixQ", "[", "A_", "]"}], "||",
RowBox[{"VectorQ", "[", "A_", "]"}]}], ")"}], "&&",
RowBox[{"!",
RowBox[{"(",
RowBox[{
RowBox[{"MatrixQ", "[", "B_", "]"}], "||",
RowBox[{"VectorQ", "[", "B_", "]"}]}], ")"}]}]}], ",",
RowBox[{"Transpose", "[",
RowBox[{"B_", "[",
RowBox[{"Transpose", "[", "A_", "]"}], "]"}], "]"}]}], "]"}]]]
Now I've entered this with the Notation
palette, so actually it looks like this on screen:
EDIT: That is: type "Needs["Notation
"]`, causing a palette to appear. Click on the first button, whereupon this
appears. Inside the first yellow box type A_ \[FilledSmallCircle] B_
, and in the second,
Which[(MatrixQ[A_]||VectorQ[A_])&&(MatrixQ[B_]||VectorQ[B_]),A_ .B_,!(MatrixQ[A_]||VectorQ[A_])&&(MatrixQ[B_]||VectorQ[B_]),A_[B_],(MatrixQ[A_]||VectorQ[A_])&&!(MatrixQ[B_]||VectorQ[B_]),Transpose[B_[Transpose[A_]]]]
The result looks like this
and, when evaluated, defines what you want. Alternatively, after the Needs
bit, just cut and paste what I gave above.
Mathematica has some operators without builtin definitions like CirclePlus and CircleTimes that you can define. I'm iPhoning now so I can't check, but I assume FilledSmallCircle is just a character and not an operator. It's less trivial to define that as an operator, but you might want to check the Notation package.
精彩评论