I'm trying to find a way of keeping an ordered list of subscripted integers which can be outputted in an aesthetically pleasing way to make analysis easier. The idea is to have a list of numbers that can be indexed by any label, not just by numbers.

Here's the code I have been using so far:

(* Loading Notation packages *)
Symbolize[ParsedBoxWrapper[SubscriptBox["_", "_"]]];

(* Creates a subscripted integer *)
fock[n_Integer, m_] := Subscript[n, m]

(* Creates a series of 0's indexed from 1 to nm *)
zeros[nm_] := TensorProduct @@ Table[fock[0, i], {i, nm}]

(* Adds one to any instances of an integer indexed by m in 'in' *)
c[in_, m_] := in /. Subscript[a_, m] -> Subscript[(a + 1), m];

Which can be applied as follows:

zeros[4] + c[zeros[4],3] + TensorProduct[zeros[3],fock[2,4]]

Producing output in TraditionalForm looking like:

$$ 0_1\!\!\otimes\!0_2\!\!\otimes\!0_3\!\!\otimes\!0_4+0_1\!\!\otimes\!0_2\!\!\otimes\!0_3\!\!\otimes\!2_4+0_1\!\!\otimes\!0_2\!\!\otimes\!1_3\!\!\otimes\!0_4 $$

which is a bit nasty to look at. Whereas I'd rather have it look like:

$$ 0_1 0_2 0_3 0_4+0_10_2 0_3 2_4+0_1 0_2 1_3 0_4 $$

To do so natively in Mathematica seems to require using Times instead of TensorProduct, however since Times has the property Orderless, the ordering of the indexes is now not maintained.

My question is how can I either: use the TensorProduct version without having to see the tensor product (either by using a different function; or by changing the symbol used by Mathetmatica) or use the Times version whilst maintaining ordering structure (I could not work out how to modify Times or create a function to perform such).


First of all, I don't see any need for the Notation package here. So I'll just omit that. Also, you need to replace -> by :> in the definition for c, otherwise a may be polluted by a global value.

The rest can be done as follows:

(*Creates a subscripted integer*)
fock[n_Integer, m_] := Subscript[n, m]

(*Creates a series of 0's indexed from 1 to nm*)

zeros[nm_] := myTensor @@ Table[fock[0, i], {i, nm}]

(*Adds one to any instances of an integer indexed by m in'in'*)

c[in_, m_] := in /. Subscript[a_, m] :> Subscript[(a + 1), m];

SetAttributes[myTensor, {Flat, OneIdentity}]

Format[myTensor[x__]] := Row[{x}]

zeros[4] + c[zeros[4], 3] + myTensor[zeros[3], fock[2, 4]]

$$0_1 0_2 0_3 0_4+0_10_2 0_3 2_4+0_1 0_2 1_3 0_4$$

Here I replaced TensorProduct by myTensor and defined its Attributes to mimic those of TensorProduct, but with a display format that contains no symbols between the factors.

|improve this answer|||||
  • $\begingroup$ Thanks, although how can I use the RuleDelayed operator in an expression like: cs[in_, m_] := in /. Table[Subscript[a_, i] -> Subscript[(a + 1), i], {i, m}]? If I do replace the -> with a :> all the indexes are left unevaluated to i. $\endgroup$ – SLesslyTall Jun 17 '15 at 7:56
  • $\begingroup$ You just have to override the attribute HoldAll of Table by wrapping the RuleDelayed in Evaluate. But a cleaner way in this case would be to define the rule as Subscript[a_, i_] /; 1 <= i <=m :> Subscript[(a + 1), i]. $\endgroup$ – Jens Jun 17 '15 at 16:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.