RuleBasedIntegration / Rubi

Rubi for Mathematica
http://rulebasedintegration.org
MIT License
225 stars 22 forks source link

How to directly get the TeXForm of every step? #34

Closed asukaminato0721 closed 4 years ago

asukaminato0721 commented 4 years ago

This is what now I do :

For example:

Int[x Sin[x],x]//Steps

image

click one step, then paste it to .nb, then //TeXForm to get the TeX code. (kind of monkey job)

I've tried FullForm, get nothing, // Trace gives back a lot of things, which seems a bit hard for me to pick out what I want.

So is it possible to add a command to automatically get code like

\begin{aligned}
\int f(x)\,dx&= ......\\
&= ......\\
......
\end{aligned}

to make it easier for following steps? For example , using MaTeX to get nice formula.

asukaminato0721 commented 4 years ago

After some test, this is a half-done job:

Steps[Int[Sin[x]/x^2, x], RubiPrintInformation -> False] //
      Flatten //
     Most //
    Select[Head@# =!= RubiRule &] //
   # /. RubiIntermediateResult[x_] -> x & //
  (*ToString@*TeXForm is also OK*)
  Map["=&" <> (Convert`TeX`ExpressionToTeX[HoldForm @@ #]) <> 
     "\\\\" &] //
 StringRiffle
asukaminato0721 commented 4 years ago

OK, I've done it.(I don't deal with the situations that Rubi failed to calculate the int)

This function returns a string.

SetAttributes[IntWithStepsOfTeXForm, {HoldFirst}];
IntWithStepsOfTeXForm[j_] := 
 With[{TeX2Str = Convert`TeX`ExpressionToTeX},
  Steps[j, RubiPrintInformation -> False] //
         Flatten //
        Most //
       Select[Head@# =!= RubiRule &] //
      # /. RubiIntermediateResult[x_] -> x & //
     (*ToString@*TeXForm is OK*)
     Map["=&" <> (TeX2Str[HoldForm @@ #]) <> "\\\\" &] //
    # /. {a___} -> {
        "\\begin{aligned}",
        TeX2Str@HoldForm@j,
        a,
        "\\end{aligned}"} & // StringRiffle
  ]

Usage:

image

Or

IntWithStepsOfTeXForm[Int[(x + 1)/Sqrt[x^2 + 1], x]] // Print

And then choose and copy to clipboard.

Maybe I will make a pr for this function in the future.

halirutan commented 4 years ago

Yep, this is exactly what I implemented RubiPrintInformation -> False for so that people can create their own functions for displaying integration steps.

asukaminato0721 commented 4 years ago

I make it better:

IntWithStepsOfTeXForm[formula_, j_]:=
With[{TeX2Str = Convert`TeX`ExpressionToTeX},
Steps[Int[formula, j], RubiPrintInformation -> False] // 
Flatten //
Most // 
Cases[RubiIntermediateResult[x_]:>"=&" <> (TeX2Str[HoldForm @@ x]) <>"\\\\"] //
{"\\begin{aligned}",TeX2Str@HoldForm@Int[formula, j], Sequence @@ #,"\\end{aligned}"} & //
 StringReplace[
  "\\, d" <> ToString[var] -> "\\, \\mathrm{d}" <> ToString[var]]// 
StringRiffle]

Now we can use it just like Integrate

image

asdasd1dsadsa commented 4 years ago

By the way, I modified it to be another display function which doesn't use TeXForm but TraditionalForm:

IntTraditional[expr_, var_] := Style[Grid[
    {"\[LongEqual]", TraditionalForm@#}& /@ Cases[
        Flatten@First@Steps[Int[expr, var], RubiPrintInformation -> False],
        RubiIntermediateResult[x_] :> HoldForm@@x
    ]// Prepend[{"",TraditionalForm@HoldForm@Int[expr,var]}]
, Alignment -> Left], FontFamily -> "Latin Modern Roman 10"];

SetAttributes[IntTraditional, HoldAll]

SyntaxInformation[IntTraditional] = {"LocalVariables" -> {"Integrate", {2, Infinity}}};

Subst /: MakeBoxes[HoldPattern@Subst[expr_,src_,tar_], TraditionalForm] := RowBox@{UnderscriptBox[StyleBox["Subs", FontSize -> Medium], RowBox[{MakeBoxes[src, TraditionalForm], "\[Rule]", MakeBoxes[tar, TraditionalForm]}]], MakeBoxes[expr, TraditionalForm]}
asukaminato0721 commented 4 years ago

By the way, I modified it to be another display function which doesn't use TeXForm but TraditionalForm:

IntTraditional[expr_, var_] := Style[Grid[
  {"\[LongEqual]", TraditionalForm@#}& /@ Cases[
      Flatten@First@Steps[Int[expr, var], RubiPrintInformation -> False],
      RubiIntermediateResult[x_] :> HoldForm@@x
  ]// Prepend[{"",TraditionalForm@HoldForm@Int[expr,var]}]
, Alignment -> Left], FontFamily -> "Latin Modern Roman 10"];

SetAttributes[IntTraditional, HoldAll]

SyntaxInformation[IntTraditional] = {"LocalVariables" -> {"Integrate", {2, Infinity}}};

Subst /: MakeBoxes[HoldPattern@Subst[expr_,src_,tar_], TraditionalForm] := RowBox@{UnderscriptBox[StyleBox["Subs", FontSize -> Medium], RowBox[{MakeBoxes[src, TraditionalForm], "\[Rule]", MakeBoxes[tar, TraditionalForm]}]], MakeBoxes[expr, TraditionalForm]}

Actually your don't need to HoldAll, because the Integrate doesn't have that.

Attributes[Integrate]

{Protected, ReadProtected}

Without HoldAll, you can write things like IntTraditional[list[[1]],x]. Or you should use IntTraditional[ Evaluate@list[[1]],x]

asukaminato0721 commented 4 years ago

Wow, amazing, After running your code, the effort is so nice! Thx.

Maybe it's because of this line? Subst /: MakeBoxes[HoldPattern@Subst[expr_,src_,tar_], TraditionalForm] := RowBox@{UnderscriptBox[StyleBox["Subs", FontSize -> Medium], RowBox[{MakeBoxes[src, TraditionalForm], "\[Rule]", MakeBoxes[tar, TraditionalForm]}]], MakeBoxes[expr, TraditionalForm]}

image

IntWithStepsOfTeXForm[expr_, var_] := 
 With[{TeX2Str = Convert`TeX`ExpressionToTeX}, 
  Steps[Int[expr, var], RubiPrintInformation -> False] // Flatten // 
       Most // Cases[
       RubiIntermediateResult[x_] :> 
        "=&" <> (TeX2Str[HoldForm @@ x]) <> 
         "\\\\"] // {"\\begin{aligned}", 
       TeX2Str@HoldForm@Int[expr, var], Sequence @@ #, 
       "\\end{aligned}"} & //
 StringReplace[{"\\, d" <> ToString[var] ->  "\\, \\mathrm{d}" <> ToString[var],  "\\int" -> "\\displaystyle \\int"}]//
   StringRiffle]
asdasd1dsadsa commented 4 years ago

Wow, amazing, After running your code, the effort is so nice! Thx.

Maybe it's because of this line? Subst /: MakeBoxes[HoldPattern@Subst[expr_,src_,tar_], TraditionalForm] := RowBox@{UnderscriptBox[StyleBox["Subs", FontSize -> Medium], RowBox[{MakeBoxes[src, TraditionalForm], "\[Rule]", MakeBoxes[tar, TraditionalForm]}]], MakeBoxes[expr, TraditionalForm]}

image

IntWithStepsOfTeXForm[expr_, var_] := 
 With[{TeX2Str = Convert`TeX`ExpressionToTeX}, 
  Steps[Int[expr, var], RubiPrintInformation -> False] // Flatten // 
       Most // Cases[
       RubiIntermediateResult[x_] :> 
        "=&" <> (TeX2Str[HoldForm @@ x]) <> 
         "\\\\"] // {"\\begin{aligned}", 
       TeX2Str@HoldForm@Int[expr, var], Sequence @@ #, 
       "\\end{aligned}"} & //
 StringReplace[{"\\, d" <> ToString[var] ->  "\\, \\mathrm{d}" <> ToString[var],  "\\int" -> "\\displaystyle \\int"}]//
   StringRiffle]

Yes, Convert`TeX`ExpressionToTeX MakeBoxes with TraditionalForm at first, so this definition for display affects the TeX output.

Gravifer commented 3 years ago

I made a PR (pull-request#44) for this thread. Modifications were made to the suggestions above, and I do hope this is not offensive to the original contributors.