I have two functions Sup
and Sdown
that take a string of letters with allowed characters "Z","W","P","H"
and returns a "sum" of strings with signs:
Sup[simple_String]:=
Block[{char=Characters[simple],z=0,w=0,n},
n=Count[char,"Z"|"P"];
Sum[
Which[
char[[i]]=="P",
z++;w++;0,
char[[i]]=="W",
w++;0,
char[[i]]=="Z",
z++;
Sigg[n,z,w]*StringJoin@@(Join[char[[;;i-1]],{"W"},char[[i+1;;]]]),
True,
0
],{i,Length[char]}
]
]
and
Sdown[simple_String]:=
Block[{char=Characters[simple],z=0,w=0,n},
n=Count[char,"Z"|"P"];
Sum[
Which[
char[[i]]=="P",
z++;w++;0,
char[[i]]=="Z",
z++;0,
char[[i]]=="W",
w++;
Sigg[n,z+1,w]*StringJoin@@(Join[char[[;;i-1]],{"Z"},char[[i+1;;]]]),
True,
0
],{i,Length[char]}
]
]
The sign is simply given by
Sigg[n_,z_,w_]:=If[EvenQ[n+w-z],1,-1]
As expected, this gives me i.e.
In[1]= Sdown["WPWPHH"]
Out[1]= -"WPZPHH" + "ZPWPHH"
Now, I want Sup
and Sdown
to be linear operators that can act on stuff like Out[1]
, so I do this:
Sup/:Sup[Plus[x__]]:=Plus@@(Sup/@x)
Sup/:Sup[Times[i_Integer,s_String]]:=Expand[i*Sup[s]]
and the same for Sdown
. But when I try to Sup[Sdown["WPWPHH"]]
I get
In[2]= Sup[Sdown["WPWPHH"]]
Out[2]= 2 + "WPWPHH"
instead of 2"WPWPHH"
as I would expect. The FullForm
of Out[1]
is Plus[Times[-1,"WPZPHH"],"ZPWPHH"]
so when I do
In[3]= Plus @@ (Sup /@ {Times[-1, "WPZPHH"], "ZPWPHH"})
I get
Out[3]= 2 "WPWPHH"
like expected. What's going on here? Can you help me find the error? Also, if there is a better way of implementing this linearity, please let me know :)