Multiplication sign in TeXForm?

8

How do I get Mathematica to produce TeX output that does not omit the multiplication signs?

For example, this expression:

(z03*z14*z32 + z01*z12*z43 + z14*(z01 + z03 + z12 + z32)*z43)

displays in Mathematica as:

(z14 z43 (z01+z03+z12+z32)+z01 z12 z43+z03 z14 z32)

And the output of TeXForm looks like this:

(z14 z43 (z01 + z03 + z12 + z32) + z01 z12 z43 + z03 z14 z32) // TeXForm

$ \text{z14} \text{z43} (\text{z01}+\text{z03}+\text{z12}+\text{z32})+\text{z01} \text{z12} \text{z43}+\text{z03} \text{z14} \text{z32}$

which is really hard to read because the spaces get ignored.

How do I get TeXForm to produce this instead?: $$ \text{z14}\times\text{z43}\times(\text{z01}+\text{z03}+\text{z12}+\text{z32})+\text{z01}\times\text{z12}\times\text{z43}+\text{z03}\times\text{z14}\times\text{z32} $$

Even better would be:

$$ \text{z14}.\text{z43}.(\text{z01}+\text{z03}+\text{z12}+\text{z32})+\text{z01}.\text{z12}.\text{z43}+\text{z03}.\text{z14}.\text{z32} $$

Worse come to worse, I could even settle for something like this: $$ \text{z14}\;\text{z43}\;(\text{z01}+\text{z03}+\text{z12}+\text{z32})+\text{z01}\;\text{z12}\;\text{z43}+\text{z03}\;\text{z14}\;\text{z32} $$

blondiepassesby

Posted 2013-12-19T03:42:21.633

Reputation: 293

Use a string and \[Times] instead of * for multiplication? – rm -rf – 2013-12-19T04:10:23.707

Answers

8

Here is a very robust (!!) method

expr = (z14 z43 (z01 + z03 + z12 + z32) + z01 z12 z43 + z03 z14 z32);
StringReplace[ToString[expr, TeXForm], " " :> "\\times"]

Using Ctrl+Shift+C to copy as plain text results in

$$\text{z14}\times\text{z43}\times(\text{z01}+\text{z03}+\text{z12}+\text{z32})+\text{z01}\times\text{z12}\times\text{z43}+\text{z03}\times\text{z14}\times\text{z32}$$

Edit

The above approach might serve you well in the simple setting the OP is representing, in general, this method is very likely to break, because it relies on that a multiplication is converted into a single space in TeXForm.

As questions in our latex tag suggest, there are several problems and subtilities with TeXForm and a general and always working answer can hardly be given at this point without further information.

halirutan

Posted 2013-12-19T03:42:21.633

Reputation: 109 574

This works, thanks – blondiepassesby – 2013-12-19T21:14:43.843

well, now that I am starting to use your trick more, I find that it is not that robust. It works most of the time, but fails when there is a greek letter in the expression: for some reason, Mathematica adds a space after greek letters in the TeXForm output, and that gets caught as a mutltiply by your strignreplace technique. Darn. – blondiepassesby – 2014-01-05T18:25:01.610

@blondiepassesby I thought you were aware that the italic very robust in my answer was more a warning sign than a statement?! I was really meant ironically, because I was afraid that it might not work in certain cases. – halirutan – 2014-01-06T00:16:09.497

Hmm. Not entirely sure that irony is that helpful or even encouraged on stackexchange answers, especially the kind that may or may not be picked by readers of your answers. I certainly didn't read it as such and accepted your answer at face value. In future, I'd recommend being as explicit as possible. – blondiepassesby – 2014-01-07T08:06:41.043

1@blondiepassesby First, I'm sorry that you haven't been able to pick up that it meant use it with caution. I thought it was obvious, that a string-replacement in the final texform will not work in all possible circumstances. You are free to unaccept my answer. But before you recommend something, I want you to recall that everyone answering here is very likely doing it in his free time, just for fun. If you want a general solution, free of irony, you just have to pay money and you'll get a totally serious answer/solution. – halirutan – 2014-01-07T11:21:57.627

5

We want cross? Let's use Cross!

expr /. Times -> Cross // TeXForm

$ \text{z14}\times (\text{z01}+\text{z03}+\text{z12}+\text{z32})\times \text{z43}+\text{z01}\times \text{z12}\times \text{z43}+\text{z03}\times \text{z14}\times \text{z32} $

ybeltukov

Posted 2013-12-19T03:42:21.633

Reputation: 41 907

Or, if the OP prefers, 'expr /. Times -> Dot // TeXForm' – A.G. – 2014-12-29T06:18:29.003

3

Row appears to work:

expr = (z03*z14*z32 + z01*z12*z43 + z14*(z01 + z03 + z12 + z32)*z43);
expr /. Times :> (Row[{##}, "\[Times]"] &) // TeXForm

Copying as plain text as halirutan did and wrapping in $ symbols:

$\text{z14}\times \text{z01}+\text{z03}+\text{z12}+\text{z32}\times \text{z43}+\text{z01}\times \text{z12}\times \text{z43}+\text{z03}\times \text{z14}\times \text{z32}$


  • Note: This code fails in recent versions due to a bug: Incompatibility of Row and TeXForm.
    kguler discovered that the bug may be circumvented by setting:

    BoxForm`$UseTemplateSlotSequenceForRow = False;
    

Mr.Wizard

Posted 2013-12-19T03:42:21.633

Reputation: 259 163

Hmm, does this really work for you? Here, I get this output.

– halirutan – 2013-12-19T23:41:11.517

1@halirutan In version 7, yes, it does. I already voted for your answer. (Does a space always represent multiplication in TeX?) – Mr.Wizard – 2013-12-20T02:21:26.263

2

TeXForm works by creating TraditionalForm boxes, and then converting those boxes into a TeX string. This means there are two methods to change the TeXForm format of an expression:

  1. Change the TraditionalForm output
  2. Change the conversion code that converts TraditionalForm boxes into TeX.

I like changing the TraditionalForm output instead of changing the conversion code, because boxes don't carry context. There may be multiple expressions that produce similar boxes, and if you try to write conversion code after the expression has been turned into boxes you may be affecting expressions that you don't want to modify. It's a little bit like trying to repair a car after an accident vs preventing the accident in the first place.

So, the first step is to figure out how to change the TraditionalForm of products. Without going into details, this is actually difficult to do, because a variety of different expressions will produce expression that look like space separated terms. So, rather than try to add formatting rules for all of these different expressions, it is much simpler to look for the signature of a product of terms, which is:

RowBox[{a, " ", b, " ", c, ..}]

and then replace all the spaces with the symbol of your choice (in fact, TraditionalForm already does something like this when it tries to reorder products into a more "TraditionalForm" like order).

Therefore, we want to add a TraditionalForm formatting rule that post-processes the TraditionalForm boxes after all other formatting has take place. The way I will implement this is to add a rule that gets fired before any other formatting has occurred. This rule will create the normal TraditionalForm boxes, and then convert any products into "$\times$" separated products. For this purpose, it will be convenient to make use of my Initial wrapper, which I repeat here for convenience:

Initial /: Verbatim[TagSetDelayed][Initial[sym_], lhs_, rhs_] := With[
    {
    new=Block[{sym},
        TagSetDelayed[sym,lhs,rhs];
        First @ Language`ExtendedDefinition[sym]
    ],
    protect=Unprotect[sym]
    },

    sym;
    Quiet@MakeBoxes[sym[],TraditionalForm];

    Unprotect[sym];
    Replace[
        new,
        Rule[values_,n:Except[{}]] :> (
            values[sym] = DeleteDuplicates @ Join[n, values[sym]]
        ),
        {2}
    ];
    Protect@protect;
]

Using the Initial wrapper, the following MakeBoxes rule will fire before all others:

Initial[TraditionalForm] /: MakeBoxes[e_, TraditionalForm] /; TrueQ@$TeX := Block[{$TeX = False},
    ReplaceAll[
        MakeBoxes[e, TraditionalForm],
        RowBox[b_?productQ] :> RuleCondition @ Replace[RowBox[b], " "->"\[Times]", {2}]
    ]
]
productQ[b_] := Length[b]>1 && MatchQ[b[[2 ;; -2 ;; 2]], {" "..}]

Let's see this in action:

$TeX = False;
x+2y //TraditionalForm

enter image description here

Versus:

$TeX = True;
x+2y //TraditionalForm

enter image description here

All that remains is to modify the TeXForm code to block $TeX to True when creating the TraditionalForm boxes. This can again be done using the Initial wrapper:

Initial[Convert`TeX`ExpressionToTeX] /: 
    Convert`TeX`ExpressionToTeX[e__] /; !TrueQ@$TeX := Block[
        {$TeX = True},
        Convert`TeX`ExpressionToTeX[e]
    ]

Let's take a look at an example:

x+2y //TeXForm

$x+2\times y$

Perfect. For your more complicated example:

(z03*z14*z32 + z01*z12*z43 + z14*(z01 + z03 + z12 + z32)*z43) //TeXForm

$\text{z14}\times \text{z43}\times (\text{z01}+\text{z03}+\text{z12}+\text{z32})+\text{z01}\times \text{z12}\times \text{z43}+\text{z03}\times \text{z14}\times \text{z32}$

Here is the above code in one block:

Initial /: Verbatim[TagSetDelayed][Initial[sym_], lhs_, rhs_] := With[
    {
    new=Block[{sym},
        TagSetDelayed[sym,lhs,rhs];
        First @ Language`ExtendedDefinition[sym]
    ],
    protect=Unprotect[sym]
    },

    sym;
    Quiet@MakeBoxes[sym[],TraditionalForm];

    Unprotect[sym];
    Replace[
        new,
        Rule[values_,n:Except[{}]] :> (
            values[sym] = DeleteDuplicates @ Join[n, values[sym]]
        ),
        {2}
    ];
    Protect@protect;
]

Initial[TraditionalForm] /: MakeBoxes[e_, TraditionalForm] /; TrueQ@$TeX := Block[{$TeX = False},
    ReplaceAll[
        MakeBoxes[e, TraditionalForm],
        RowBox[b_?productQ] :> RuleCondition @ Replace[RowBox[b], " "->"\[Times]", {2}]
    ]
]
productQ[b_] := Length[b]>1 && MatchQ[b[[2 ;; -2 ;; 2]], {" "..}]

Initial[Convert`TeX`ExpressionToTeX] /: 
    Convert`TeX`ExpressionToTeX[e__] /; !TrueQ@$TeX := Block[
        {$TeX = True},
        Convert`TeX`ExpressionToTeX[e]
    ]

Carl Woll

Posted 2013-12-19T03:42:21.633

Reputation: 112 778