Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Special Operators Definition in Mathematica

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 small 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?

like image 712
Phil Avatar asked Dec 21 '22 11:12

Phil


2 Answers

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]
like image 195
Simon Avatar answered Dec 29 '22 08:12

Simon


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: enter image description here (the palette inserts various boxes where necessary). It just looks horrible when I cut and paste due to the explicit string representation of everything.

EDIT: That is: type "Needs["Notation"]`, causing a palette to appear. Click on the first button, whereupon this

enter image description here

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 enter image description here

and, when evaluated, defines what you want. Alternatively, after the Needs bit, just cut and paste what I gave above.

like image 25
acl Avatar answered Dec 29 '22 10:12

acl