4

Suppose I've got the following document:

\documentclass{article}

\newcommand\mass{30}
\newcommand\acc{9.8}

\newcommand\force{\the\numexpr \mass * \acc \relax} % F=m*a

\begin{document}
  \section{Exerted force}
    F = \force N
\end{document}

It creates three 'variables': mass, acc and force, which is the product of the first two.

This specific example (mass = 30, acc = 9.8) prints F = 270.8N, as is intended.

The multiplication is performed by the \numexpr command. This works whenever mass and acc are both regular numbers. If the mass or acc is a variable (i.e. \newcommand\mass{m}) the document fails to build, as \numexpr can only perform operations on numbers.

Is there a way to perform algebraic operations on variables, such that when mass = 30g and acc = g, it will print F = 30g^2? I know this does not make sense physically, but I think the point is clear.

A few other examples:

  • mass = m, acc = 9.8 -> F = m*9.8 or F = 9.8*m
  • mass = m, acc = g -> F = m*g or F = g*m
  • mass = x, acc = x -> F = x^2

EDIT: As @PhelypeOleinik kindly pointed out, \numexpr only works on integers. So while 9.8 * 30 = 294, it gives 270.8 as result, because 30 * 9 = 270 and it appends the .8.

kotek
  • 115
  • 3
    you shouldn't use LaTeX here. – Johannes_B Feb 18 '19 at 13:16
  • 2
    You should note, however, that 30×9.8 is 294, not 270.8. You get 270.8 because \numexpr does integer multiplication and 30*9 is 270 and the .8 is appended to the result. If you did \newcommand\acc{9.banana} you'd get 270.banana (and no error :). Use \dimexpr for “real” (real in a variable type context) variables. – Phelype Oleinik Feb 18 '19 at 13:16
  • @PhelypeOleinik oops, didn't know that! I should have bothered to verify the results. – kotek Feb 18 '19 at 13:18
  • 1
    @kotek Have a look at the LaTeX3 interfaces. There are several programming goodies implemented there. The one that might interest you most is Part XXII The l3fp package. That one provides an excellent floating point interface to LaTeX. It doesn't have a symbolic calculation module, like what you're asking, but with the tools provided one may be able to implement something (given enough time and patience :). – Phelype Oleinik Feb 18 '19 at 13:25
  • 2
    The sagetex package can do this. See the accepted answer here. The package gives you access to a computer algebra system and Python programming. Documentation on sagetex is here. Not part of distribution, best access is through free Cocalc account. Sage documentation here – DJP Feb 18 '19 at 15:00
  • @DJP Thanks. That might be even better than my solution using pythontex and sympy. Consider posting this as an answer. – kotek Feb 18 '19 at 18:00

2 Answers2

5

You can use the pythontex package to embed python in your LaTeX document and then use the python sympy package for symbolic computation like this:

\documentclass{article}

\usepackage{pythontex}

\begin{pycode}
from sympy import *

m = sqrt(3)
a = symbols('g')
f = m * a
\end{pycode}

\begin{document}
  \section{Exerted force}
    F = $\pyc{print(latex(f))}$
\end{document}

This requires that you have installed LaTeX, python3, the pythontex package for LaTeX and the sympy package for python. Also, some knowledge of python doesn't hurt.

Short explanation of the code:

\usepackage{pythontex} imports the required package.

\begin{pycode} begins a block of python code.

Let's look at the following block of python code:

from sympy import *

m = sqrt(3)
a = symbols('g')
f = m * a

This imports the sympy library, sets m equal to the square root of 3 and a to a variable g. It then multiplies m and a and stores the result in f. Note that the sqrt() function used to take the square root of 3 is a function from the sympy library and not from the math library. This means that m is exactly equal to sqrt(3) and is not an approximation.

$\pyc{latex(f)}$ then prints whatever latex(f) returns. The value of f is now equal to sqrt(3) * g. By passing it through the latex() function it gets printed using LaTeX notation, so the dollar signs are necessary to enter math mode.

This can be built by first calling latex, then pythontex and then latex again.

In the end the document will look like this:

Result

Some resources on sympy and pythontex:

kotek
  • 115
2

Here is code using the sagetex package that you requested:

\documentclass{article}
\usepackage{sagetex}
\begin{document}
\begin{sagesilent}
m = 30.0
a = 9.8
Force = m*a
var('g')
mass = 30*g
\end{sagesilent}
\section{Exerted force}
    F = $\sage{Force.n(digits=5)}$ N \\\\
If the mass is $\sage{mass}$ then it's square is $\sage{mass^2}$.
\begin{sagesilent}
var('m')
acc = 9.8
\end{sagesilent}

$F = \sage{m*acc.n(digits=2)}$\\
\begin{sagesilent}
var('a')
m=a
\end{sagesilent}
If the mass, $m$, is equal to the acceleration, $a$ then 
$F = \sage{m*a}$.

Sage even works with square roots:
\begin{sagesilent}
var('g')
m=sqrt(3)
\end{sagesilent}
$F = \sage{m*g}$ which, if you want decimals, is about     $F=\sage{m.n(digits=4)*g}$
\end{document}

The output, running in Cocalc (mentioned in my comment above), is: enter image description here

In Sage, x is a variable by default. Any other variables have to be defined as done in the code, for example var('g'). The sagesilent environment is like scratch paper. It is made up of the Python and Sage commands that will do the calculations. Use the format \sage{} to get the result. Since it's numerical, it's done in math mode (between dollar signs). Sage will tend to give lots of digits. The .n(digits=5) will force the answer to be 5 significant figures.

DJP
  • 12,451