17

I know that exist several packages, like fp that allow to make all kinds of computations.

But I do not understand the correct way to use them.

I need some simple examples of multiplication and division.

I would like compute some data and output them with a custom .sty file.

An Example is:

Italy = 800 000 km of roads (by wikipedia)

SRS = 14 839.9 km (the paths of the project)

SRSpercent = SRS / Italy * 100

And I would like that Italy and SRS as the input variables, SRSpercent as one of the output variables.

I need this so that I do not have to rewrite the numbers in the papers every day.

6
  • 1
    Hint: Though LaTeX can calculate, it is not very fast in doing so.
    – Johannes_B
    Commented Jun 6, 2015 at 17:43
  • This is not a problem for me. I have to compute few data, but these are different in each compilation. Commented Jun 6, 2015 at 17:45
  • 2
    You might want to specify the question a bit. Right now, it is very very broad.
    – Johannes_B
    Commented Jun 6, 2015 at 17:47
  • Ok. I rewrite the question with more details. Commented Jun 6, 2015 at 17:48
  • How many digits after the decimal point should be displayed?
    – Mico
    Commented Jun 6, 2015 at 18:54

4 Answers 4

17

Here's a solution that uses LuaLaTeX. No additional floating-point routines need be loaded. The output precision is controlled by the first argument of the string.format function; in the example below, the code is set to show 3 digits after the decimal marker.

enter image description here

% !TEX TS-program = lualatex   %% needs LuaLaTeX format
\documentclass{article}
\usepackage{luacode}  % for "\luaexec" macro 
\newcommand\mycalc[1]{%
     \luaexec{ tex.sprint ( string.format( "\%.3f" , #1 ) )}}

\begin{document}
\newcommand{\ItalyRoads}{800000}
\newcommand{\SRSroads}{14839.9}
\newcommand{\SRSpercent}{\mycalc{\SRSroads/\ItalyRoads*100}}

The value of \verb+\SRSpercent+ is \SRSpercent\%.
\end{document}
1
  • This is perfect. Thanks. And thanks to all other, the several solutions are interesting. Commented Jun 6, 2015 at 21:30
11

It's “simple” with xparse and siunitx. I define

  • \setvariable with three arguments: the variable name, the value and the unit

  • \printvariable with one argument and a *-form; the *-form prints just the value with \num, whereas the non-starred form prints value and unit with \SI

  • \getvalue that retrieves the value of the variable given as argument to be used in calculations with \fpeval that's just a user's level version of \fp_eval:n.

Here is a full example.

\documentclass{article}
\usepackage{siunitx} % also loads xparse and expl3

\ExplSyntaxOn
\NewDocumentCommand{\setvariable}{mmm}
 {
  \prop_gclear_new:c { g_giacomo_var_#1_prop }
  \prop_gput:cnn { g_giacomo_var_#1_prop } { value } { #2 }
  \prop_gput:cnn { g_giacomo_var_#1_prop } { unit } { #3 }
 }

\NewDocumentCommand{\printvariable}{sm}
 {
  \IfBooleanTF{#1}
   {
    \num { \__giacomo_get:nn { #2 } { value } }
   }
   {
    \exp_args:Nnx \SI { \__giacomo_get:nn { #2 } { value } }
        { \__giacomo_get:nn { #2 } { unit } }
   }
 }

% syntactic sugar
\DeclareExpandableDocumentCommand{\getvalue}{m}
 {
  \__giacomo_get:nn { #1 } { value }
 }
\cs_new:Npn \__giacomo_get:nn #1 #2
 {
  \prop_item:cn { g_giacomo_var_#1_prop } { #2 }
 }
\cs_set_eq:NN \fpeval \fp_eval:n
\ExplSyntaxOff

\setvariable{Italy}{800000}{\kilo\meter}
\setvariable{SRS}{14839.9}{\kilo\meter}

\begin{document}

According to Wikipedia, Italy has \printvariable{Italy} of roads.
The SRS project refers to \printvariable{SRS}, which is
\fpeval{round(\getvalue{SRS}*100/\getvalue{Italy}, 2)}\%.

\end{document}

Operations in \fpeval have quite a natural syntax; refer to the interface3.pdf manual for the full set.

enter image description here

Note

Added \exp_args:Nnx in front of \SI in the code, because otherwise conflicts may arise when the siunitx key exponent-to-prefix is set to true (see Setvariable and siunitx exponent-to-prefix producing error"prefix-only").

8

Here's a sagetex approach to implementing a variation on Mico's code. Since it uses Python, it can be easier to see what's going on. But you need Sage installed on your computer or use SagemathCloud if you don't want Sage installed on your computer.

\documentclass{article}
\usepackage{sagetex}
\begin{document}
\begin{sagesilent}
SRS = 14839.9
Italy = [800000, "59,433,744"]
output = r"\frac{100(%s)}{%d}"%(str(SRS.n(digits=6)),Italy[0])
\end{sagesilent}
Italy's population is \sagestr{Italy[1]}. The SRS percent is
$\sagestr{output}=\sage{((100*SRS)/Italy[0]).n(digits=4)}\%$.
\end{document}

The population of Italy is the second element in the list (represented as a string [s]). The first element is integer data [d] and SRS is floating point [f]. To control the output format, it helps to work with it as a string. You access string data and numerical data via \sagestr and \sage, respectively. Here is the result running in Sagemath Cloud: enter image description here

Sagemath Cloud is here. It's free to open an account.

7

Instead of pure LaTeX, I suggest mix LaTeX with R code in a "R-noweb" file (plain text file but with the .Rnw extension):

\documentclass{article}
\begin{document}
<<results='hide'>>=
Italy <- 800000 # km of road by Wikipedia
SRS <- 14839.9 # km the paths of the project
SRSpercent <- SRS / Italy * 100
@
The value of SRSpercent is \Sexpr{round(SRSpercent,2)} \%.
\end{document}

Compiled with:

Rscript -e "library(knitr); knit('my_sweave_file.Rnw')"
pdflatex my_sweave_file.tex

Or just "compile PDF" buttom from Rstudio, the result should be:

The value of SRSpercent is 1.85 %.

The may be not-so-clear advantages of these approach is that you can (a) use the variables for much more that simple arithmetic, (b) any R result (as verbatim text or figures) could be inserted automatically in the LaTeX document but moreover (c) R can produce some results in LaTeX format (chunks of LaTeX text, tables) and therefore indistinguishable of the LaTeX text.

Just a more complex example to explain what I mean:

MWE2

\documentclass[a5paper,landscape,twocolumn]{article}
\usepackage[margin=1cm]{geometry}
\usepackage{booktabs}
\usepackage[colorlinks]{hyperref}
\begin{document}

<<sourcedata,results="hide",echo=F,message=F>>=
library(Hmisc)
library(xtable)
Italy <- 800000
label(Italy) <-  "km of the Italian road network"
SRS <- 14839.9
label(SRS) <- "km of paved roads by the SRS project"
vkm <- c(Italy,SRS)
km <- data.frame(Italy,SRS) 
rownames(km) <- c("km")
@

\section{Source data}
Statistical data used in this report are only two measures in km of
roads from Italy and the SRS project: 
\begin{itemize}
\item
<<results="asis", echo=FALSE>>=
cat(vkm, sep="\n\\item ")
@
\end{itemize}
Is not too much, but it is only a example. Confused with so many data?
See table \ref{xtable}. 
<<showdata,warning=F,results="asis",echo=F,comment="">>=
print(xtable(km, digits=1, 
caption="Data used in this report.",label="xtable"),
booktabs=TRUE,caption.placement="top")
@
\section{Conclusions}
<<percentage,echo=F>>=
SRSpercent <- SRS / Italy * 100
label(SRSpercent) <- "SRS contribution"
@
In the \Sexpr{Italy}~\Sexpr{label(Italy)}, 
the roughly  \Sexpr{options(scipen=6)}\Sexpr{round(SRS,0)} 
\Sexpr{label(SRS)} mean a \Sexpr{label(SRSpercent)} of
\Sexpr{round(SRSpercent,2)}\%. Not enough clear? See figure
\ref{fig:figure} for a better understanding. 
\newpage
<<figure,echo=F,fig.cap="Extension of Italian network road in kilometers",fig.pos="h", fig.height=6>>=
pie(c(Italy-SRS,SRS),labels=c("Others","SRS"), col=c("green","red"))
@
\end{document}

And finally, not showed above (d) R can load data of external files, if you take care of all things that could change in a manuscript when source data has changed, and your replace these by R-generated values/text/tables/figures, you can update entirely a report without touch the LateX template, only compiling again, with the security of zero mistakes in the updates.

3
  • 1
    Just for folks who aren't familiar with R, you may want to mention how this program should be "compiled".
    – Mico
    Commented Jun 6, 2015 at 19:51
  • @Mico, Yes, I was just searching this on another of my answers to copy&paste.
    – Fran
    Commented Jun 6, 2015 at 19:54
  • tex.stackexchange.com/a/170625/69174 Here are an answer, @Mico. Commented Jun 8, 2015 at 8:30

Not the answer you're looking for? Browse other questions tagged .