# Handling the numerical output of SageTeX with siunitx

Which one of the three methods below is correct to handle the numerical output of sagetex with siunitx? and how to do it correctly?

\documentclass{article}
\usepackage{sagetex,siunitx,mathtools}
\begin{document}
\begin{sagesilent}
from sage.calculus.calculus import at
f(x) = exp(x) * sin(2*x)
out1 = r"\num{%f}"%(numerical_approx(diff(f(x),x,2).subs(x=2))
out2 = numerical_approx(diff(f(x),x,2).subs(x=2))
\end{sagesilent}
%\num[round-precision=2]{numerical_approx(diff(f(x),x,2).subs(x=2)} or
\sagestr{out1} or
%\num[round-precision=3]{out2}
\end{document}


Of the 3 approaches you've given, only  \sagestr{out1} has a chance of working. That's because it's a 3 step compilation process: first run is LaTeX and this must compile without error, second is Sage, 3rd is LaTeX substituting Sage results into LaTeX code. The part in bold explains why the other 2 approaches won't work as is (possible with expl3 code, I would think, given some previous questions where it popped up. See frougon's answer here for example). First time through the LaTeX code and it is given \num[round-precision=2]{numerical_approx(diff(f(x),x,2).subs(x=2)} it will throw an error because Sage hasn't run so trying to run LaTeX on it is useless. Same with \num[round-precision=3]{out2}. Sage hasn't run on sagesilent so now you're trying to process out2 which is not a number. With the code as given the first time through with LaTeX and the document is empty. Second pass through Sage runs and out1 = r"\num{%f}"%(numerical_approx(diff(f(x),x,2).subs(x=2)) is calculated. Third pass through and sagestr is processed, gets the string represented by out1 and typesets it. Since you've loaded the siunitx package, it compiles without an error. What doesn't make sense to me is going to siunitx to format your number when it can be done without it. This opens up the possibility of having a number in Sage, such as 4.2499999995, get put into a \num as 4.25 and getting rounded up to 4.3. You can handle number formatting with just Sage.

Here is a modification of your code to illustrate some possibilities:

\documentclass{article}
\usepackage{sagetex,siunitx,mathtools}
\begin{document}
\begin{sagesilent}
from sage.calculus.calculus import at
f(x) = exp(x)*sin(2*x)
out = r"%f"%(n(diff(f(x),x,2).subs(x=2)))
out1 = r"%4.2f"%(n(diff(f(x),x,2).subs(x=2)))
out2 = r"%f"%(n(diff(f(x),x,2).subs(x=2),digits=5))
out3 = r"\num{%f}"%(n(diff(f(x),x,2).subs(x=2)))
\end{sagesilent}
\noindent    \sagestr{out} is the number with all its float digits or\\
\sagestr{out1} is the number with least 4 spaces, 2 digits for the decimal or\\
\sagestr{out2} there are 5 significant digits for float length number or\\
\sagestr{out3} puts the full float into macro for processing.
\end{document}


The output from Cocalc is: Try changing out1 = "%4.2f"%(n(diff(f(x),x,2).subs(x=2)))f"%(n(diff(f(x),x,2).subs(x=2))) to out1 = r"%4.4f"%(n(diff(f(x),x,2).subs(x=2))) and you'll see that the number is rounded up. In %4.2f a number like 1/2 will become .50 (taking up 3 spaces) and an extra space will be put in front. This can be used as in my Trig Table to get alignment of the data.

EDIT: Two things I forgot to mention. The first is that n() is an equivalent version of numerical_approximation(). See here in the documentation (near the top). The second is to address the error in your code. When I run it in Cocalc I see: The error tells me it's related to the line out2 = numerical_approx(diff(f(x),x,2).subs(x=2)) and since the ^ points to the beginning I suspect the line before that. When I click at the end of the line it shows me, in green, that the last ) matches up with ( from (diff. That means you're missing a parenthesis to match up with ( from (num. Change your code to out1 = r"\num{%f}"%(numerical_approx(diff(f(x),x,2).subs(x=2))) and it will run.

• Many thanks for your answer. I am away from PC to experiment but \num is just for testing since the real deal is to append the number with unit. I will take some time to go through it then get back in case of any inquiries.
– Diaa
Jan 12, 2021 at 23:57
• May I know why this line in my question doesn't work? out1 = r"\num{%f}"%(numerical_approx(diff(f(x),x,2).subs(x=2))
– Diaa
Jan 13, 2021 at 8:06
• I've added detail on that at the end of my answer. You are missing a parenthesis ) at the end.
– DJP
Jan 13, 2021 at 13:55